python - (几乎完成)低于音频阈值时关闭流的Python程序

标签 python macos audio

我已经制作了一个打印最大振幅或音量的程序,然后制作了一个仅在阈值高于2300时才打印音量的程序,现在我想制作一个在阈值低于 2300时关闭流的程序持续2秒钟,所以不是紧随其后,而是在2秒钟内,如果阈值在2秒钟内没有再次升高,则仅。这是我所拥有的:

import pyaudio
import struct
import audioop
import time

INITIAL_THRESHOLD = 0.010
FORMAT = pyaudio.paInt16 
SHORT_NORMALIZE = (1.0/32768.0)
CHANNELS = 2
RATE = 44100  
INPUT_BLOCK_TIME = 0.05
INPUT_FRAMES_PER_BLOCK = int(RATE*INPUT_BLOCK_TIME) 
OVERSENSITIVE = 15.0/INPUT_BLOCK_TIME                    
UNDERSENSITIVE = 120.0/INPUT_BLOCK_TIME 
MAX_BLOCKS = 0.15/INPUT_BLOCK_TIME


class TEST(object):
    def __init__(self):
        self.pa = pyaudio.PyAudio()
        self.stream = self.open_mic_stream()
        self.tap_threshold = INITIAL_THRESHOLD
        self.noisycount = MAX_BLOCKS+1 
        self.quietcount = 0 
        self.errorcount = 0

    def stop(self):
        self.stream.close()

    def find_input_device(self):
        device_index = None            
        for i in range( self.pa.get_device_count() ):     
            devinfo = self.pa.get_device_info_by_index(i)   
            print( "Device %d: %s"%(i,devinfo["name"]) )

            for keyword in ["mic","input"]:
                if keyword in devinfo["name"].lower():
                    print( "Found an input: device %d - %s"%(i,devinfo["name"]) )
                    device_index = i
                    return device_index

        if device_index == None:
            print( "No preferred input found; using default input device." )

        return device_index

    def open_mic_stream( self ):
        device_index = self.find_input_device()

        stream = self.pa.open(   format = FORMAT,
                                 channels = CHANNELS,
                                 rate = RATE,
                                 input = True,
                                 input_device_index = device_index,
                                 frames_per_buffer = INPUT_FRAMES_PER_BLOCK)

        return stream


    def listen(self):
        try:
            chunk = self.stream.read(INPUT_FRAMES_PER_BLOCK)
        except IOError, e: 
            self.errorcount += 1
            print( "(%d) Error recording: %s"%(self.errorcount,e) )
            self.noisycount = 1
            return


        while True:
            mx = audioop.max(chunk, 2)
            if mx > 2300:               #print the volume level whenever the volume is above 2300
                    print(mx)

            elif mx < 2300:             #If the volume is below 2300:
                time.sleep(2)           #Wait two seconds
                if mx > 2300:           #If after two seconds the volume is back up, repeat
                    continue
                elif mx < 2300:         #If after two seconds the volume is still down, break the loop
                    break


        print("You're Done")
        self.stream.close()
        print("Stream Closed")


if __name__ == "__main__":
    tt = TEST()

    for i in range(1000):
        tt.listen()

所要做的就是要么一遍又一遍地打印初始音量,要么立即关闭流。这取决于我启动程序时是否有声音。

最佳答案

编辑:

虽然我的答案中列出的方法概述了中断循环的方法,但您的程序无法正常运行的真正原因并不是由于循环,而是因为您实际读取音频输入的代码部分甚至不在循环中。

您需要在每次循环时读取输入流,否则,在调用listen方法时,您将继续检查该值。

def listen(self):
    while True:
        try:
            chunk = self.stream.read(INPUT_FRAMES_PER_BLOCK)
        except IOError, e: 
            self.errorcount += 1
            print( "(%d) Error recording: %s"%(self.errorcount,e) )
            self.noisycount = 1
            return

        mx = audioop.max(chunk, 2)
        if mx > 2300:               #print the volume level whenever the volume is above 2300
                print(mx)

        elif mx < 2300:             #If the volume is below 2300:
            time.sleep(2)           #Wait two seconds
            if mx > 2300:           #If after two seconds the volume is back up, repeat
                continue

您需要在那两秒钟内收听,而不是被动地等待。
    start = -1
    while True:
        try:
            chunk = self.stream.read(INPUT_FRAMES_PER_BLOCK)
        except IOError, e: 
            self.errorcount += 1
            print( "(%d) Error recording: %s"%(self.errorcount,e) )
            self.noisycount = 1
            return
        mx = audioop.max(chunk, 2)
        if mx > 2300:               #print the volume level whenever the volume is above 2300
                print(mx)
                start = -1

        elif mx < 2300:             #If the volume is below 2300:
            if start < 0:           # INITIALIZE
                start = time.time()
            else:
                if time.time() - start >= 2: #Wait two seconds
                    break

关于python - (几乎完成)低于音频阈值时关闭流的Python程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21468235/

相关文章:

winapi - 在Windows 7中模拟PC Speaker?

python - 将装饰器应用于装饰器

当我运行脚本时,Python 3.6 不是默认的

regex - sed 替换命令在 Mac 上不起作用

image - 在图像上使用特定大小的单元格绘制网格

c++ - 管理 MP3 的播放速度和位置

actionscript-3 - 闪光枪模拟

python - 取消嵌套(分解) Pandas 系列

python - python中根据key值组合字典

ios - 为什么安装XCode后RVM找不到编译器和 'make'工具?