2013-09-05 63 views
0

这是一个从后遵循: Python record audio on detected soundPython的功能无法正常运行

我有大部分排序,但现在仍然有一个错误?

程序运行一次后保存一个录音并将其录入DB,返回打印等待语音打印。不管音量多大,它不会再次录制,你必须跳出该节目?

我已删除了听()函数,所以现在回到基本从一开始就在寻找一种方式来录制完成后开始,等待下一个音频

这里本代码:

import pyaudio 
import math 
import struct 
import wave 
import datetime 
import os 
import sys 
import MySQLdb 

utc_datetime = datetime.datetime.utcnow() 
FileTime = utc_datetime.strftime("%Y-%m-%d-%H%M") 

#Assuming Energy threshold upper than 30 dB 
Threshold = 30 

SHORT_NORMALIZE = (1.0/32768.0) 
chunk = 1024 
FORMAT = pyaudio.paInt16 
CHANNELS = 2 
RATE = 16000 
swidth = 2 
Max_Seconds = 5 
TimeoutSignal=((RATE/chunk * Max_Seconds) + 2) 
silence = True 
FileNameTmp = '/var/www/Recordings/'+FileTime+'.wav' 
FileNameWWW = 'Recordings/'+FileTime+'.wav' 
Time=0 
all =[] 


p = pyaudio.PyAudio() 

stream = p.open(format = FORMAT, 
    channels = CHANNELS, 
    rate = RATE, 
    input = True, 
    output = True, 
    frames_per_buffer = chunk) 


# SQL DB Connection 
db = MySQLdb.connect("localhost","root","*****","radiolink") 
cursor = db.cursor() 


def GetStream(chunk): 
    return stream.read(chunk) 



def rms(frame): 
     count = len(frame)/swidth 
     format = "%dh"%(count) 
     shorts = struct.unpack(format, frame) 

     sum_squares = 0.0 
     for sample in shorts: 
      n = sample * SHORT_NORMALIZE 
      sum_squares += n*n 
     rms = math.pow(sum_squares/count,0.5); 

     return rms * 1000 


# Define What to Do When WriteSpeech is Called 
def WriteSpeech(WriteData): 
    stream.stop_stream() 
    stream.close() 
    p.terminate() 
    wf = wave.open(FileNameTmp, 'wb') 
    wf.setnchannels(CHANNELS) 
    wf.setsampwidth(p.get_sample_size(FORMAT)) 
    wf.setframerate(RATE) 
    wf.writeframes(WriteData) 
    wf.close() 



def KeepRecord(TimeoutSignal, LastBlock): 


    all.append(LastBlock) 
    for i in range(0, TimeoutSignal): 
     try: 
      data = GetStream(chunk) 
     except: 
      continue 

     all.append(data) 

    print "end record after timeout"; 
    data = ''.join(all) 
    print "Creating File " +FileNameTmp; 

    WriteSpeech(data) 
    print "Entering Record into DB"; 
    File = FileNameWWW 
    query =""" 
     INSERT INTO recordings 
     (`id`, `time`,`filename`,`active`,`status`) 
     VALUES 
     (NULL,NOW(), %s,1,1) """ 


    cursor.execute(query,(File)) 
    db.commit() 
    silence = True 
    Time=0 




print "Listening......" 
print "Waiting for Speech" 
while silence: 

    try: 

     input = GetStream(chunk) 

    except: 

     continue 


    rms_value = rms(input) 

    if (rms_value > Threshold): 

     silence=False 

     LastBlock=input 

     print "Recording...." 
     KeepRecord(TimeoutSignal, LastBlock) 

Time = Time + 1 
if (Time > TimeoutSignal): 
    print "Waiting No Speech Detected" 
    sys.exit() 

我肯定失去了一些东西简单在这里先谢谢了

亚历

+0

可能有可能不相关,但我不认为调用'listen()'会做你认为它的工作。如果你打算长时间运行,即使它能够工作,它也会因无限递归而最终崩溃。 – Brian

回答

0

我强烈建议你阅读WH在跟随但是,看起来WriteSpeech停止并且关闭stream,从未重新打开。这可能被你的try/except块掩盖了。

while silence: 
    try: 
     input = GetStream(chunk) 
    except: 
     continue 

这个现在说,

  1. 尝试从流中读取。
  2. 如果出现异常,请返回到循环的顶部。
  3. 重复步骤1-2,广告nauseum

要解决这个问题,你可以尝试重新打开内流除了块。


我写之前我想回答你的问题

在被downvoted不实际提供问题的答案的风险的咆哮,我认为你需要在此之前重组一些代码可以解决。接下来的意图是完全有建设性的,请让我知道它是否以其他方式出现。

你的listen()函数有几个recursive调用自己,这似乎并不是你想要的。这不像jumpgoto命令将控制转移到您的代码的那一部分。这实际上创建了另一个堆栈框架,用于单独执行您的listen()函数。这对整个代码有几个影响。

  1. 所有局部变量都得到每个堆栈帧的listen()局部范围内的重新定义。这会导致内存使用量急剧增加。例如,您实际上在内存中有很多很多种变量SHORT_NORMALIZE

  2. 您定义的闭包(函数中的函数)正在为每个listen()的本地范围重新定义。同样的问题。

  3. 在这样的部分:以listen()初始呼叫曾经被执行,因为你没有退出条件(return)后

    listen() 
    Time = Time + 1 
    
    if (Time > TimeoutSignal): 
        print "Waiting No Speech Detected" 
        listen() 
    

    没有在任何地方listen

所以,我的建议,试图解决这个问题,然后运行到性能/稳定性问题的道路前:

  1. 包装所有的代码里面listen()(但不是变量声明)像while True:

  2. while循环无处不在,你现在有listen()listen函数本身内部,continue替换此。这将告诉python不要从循环中执行更多的代码,而只是转向下一个循环迭代,从而使执行回到循环的顶部。

  3. 添加退出条件,这个主循环:

    if exit: 
        print 'Terminating normally' 
        break 
    
  4. 不要在底部KeepRecord呼叫listen()。只是让它完成执行。执行完成后将返回到listen,因为这是对KeepRecord的调用。

  5. 找到一种方法将Time = Time + 1部分移动到其他地方,以便实际执行。即使在步骤1-4之后,这些代码仍然永远不会执行。

一旦你实现了这个,验证你的当前结果是否相同。在重组此代码的某处,您可能确实解决了您的问题。我会将你的代码复制到一个新脚本中,并在那个脚本中工作来保存你现在拥有的。

P.S.

如果这是您第一次进入编码领域,您不应该感到羞耻,并且不愿意发表该文章并寻求帮助。你在这里有很多乐趣,并且作为编程的第一次尝试,它确实令人印象深刻。

+0

我看到你来自哪里,但你必须明白,每个人都开始在某处编写代码我对Python很陌生,并且尽我所能去为每个人编写一个功能强大的程序,我希望我现在不会以每个人的身份发布只是似乎在投票这个职位,因为他们都投了我最后的帖子,问问题是否可以完成。我想要实现的是解决我的问题。而不是在代码格式化方面开始咆哮!附:谢谢布莱恩我会试着拿你要说的话 – ZeroG

+0

我不是故意让你失望。我只是想在你走下这条路之前把这些事情弄清楚,并且感到沮丧。我的意图是真的让你退后一步,在驱动你疯狂之前解决这个问题。我真的对不起,如果它只是想帮助 – Brian

+0

@zerog,它不是代码格式。这在逻辑上不会做你认为的事情。 – Brian