You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于PyAudio与OpenSesame的录音:阈值触发后需持续录制至超时

解决阈值触发后继续录制直到超时的问题

你的代码核心问题是检测到响度超过阈值时直接用break跳出了录制循环,导致录制提前停止。要实现触发后继续录制到超时,只需添加一个触发标志,仅在第一次触发时记录响应信息,不中断循环,直到超时时间结束。

修改步骤:

  1. 初始化一个triggered标志,标记是否已经检测到过阈值触发
  2. 移除阈值判断里的break,改为仅在未触发时记录响应数据
  3. 调整循环逻辑,只有超时才终止录制

修改后的完整代码:

import pyaudio
import struct
import math 
import wave

timeout = 5000
sound_threshold = 0.001

CHUNK = 1024
SHORT_NORMALIZE = (1.0/32768.0)
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()

def get_rms(block):
    """计算均方根作为响度指标"""
    count = len(block)/2
    format = "%dh" % (count)
    shorts = struct.unpack(format, block)
    sum_squares = 0.0
    for sample in shorts:
        n = sample * SHORT_NORMALIZE
        sum_squares += n*n
    return math.sqrt(sum_squares / count)

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

print("* recording")
frames = []

start_time = clock.time()
triggered = False  # 新增:标记是否已检测到阈值触发

# 初始化默认响应为超时
var.response_time = timeout
var.response = u'timeout'
var.loudness = None
var.in_clock_time = None
var.start = start_time

while True:
    # 超时判断放在最前面,到点就终止
    elapsed = clock.time() - start_time
    if elapsed >= timeout:
        var.in_clock_time = clock.time()
        break   
    
    try:
        block = stream.read(CHUNK)
        frames.append(block)
    except IOError as e:
        print(e)
    
    loudness = get_rms(block)
    print(loudness)
    
    # 仅在未触发过且响度超过阈值时记录响应
    if not triggered and loudness > sound_threshold:
        triggered = True
        var.response_time = elapsed
        var.response = u'detected'
        var.in_clock_time = clock.time()
        var.loudness = loudness

print(var.response)
print(var.response_time)
print("* done recording")

stream.stop_stream()
stream.close()
p.terminate()

wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()

关键修改说明:

  • 新增triggered变量,确保只记录第一次触发阈值的时间,避免重复更新
  • 将响应变量的初始化移到循环外,默认设为超时状态,触发时再覆盖
  • 移除阈值判断中的break,让循环仅在超时条件满足时终止,保证录制全程不中断
  • 调整超时判断的位置,确保每次循环先检查是否超时,避免录制时间超出设定值

内容的提问来源于stack exchange,提问作者user1969717

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 23:22:44