声音触发器。用于自动化场景检测器 在使用AI智能体时我们遇到很多已经运行结束就是还不知道的情况下我们可以设置一段脚本让运行完声音一直提醒我们让第一时间我们知道才写的这段脚本很完美你们尝试一下。这段代码实现了一个基于音频相似度检测的自动复读系统。简单来说它的作用是监听环境声音当检测到特定的“触发音”时自动播放一段指定的 MP3 音频复读。以下是代码的详细功能模块总结 核心用途这是一个声音触发器。它通常用于自动化场景例如游戏辅助听到游戏内的特定提示音如“检查员来了”自动播放语音提醒或执行操作。语音交互听到特定的唤醒词或指令后自动播放回复语音。自动化监控监控特定频率或类型的声音事件。⚙️ 功能模块详解模板录制与学习功能程序启动后首先会进入“录制模式”。实现利用 sounddevice 录制一段用户发出的声音作为“模板”。目的确立“我要找的声音”是什么样子的作为后续比对的基准。实时监听与特征比对功能在后台循环监听麦克风输入。核心算法滑动窗口在录音流中截取片段。相关系数使用 np.corrcoef 计算录音片段与模板声音的皮尔逊相关系数。阈值判定如果相似度超过设定的 THRESHOLD (代码中设为 0.45)则判定为匹配成功。自动复读功能一旦检测到匹配的声音触发播放线程。实现使用 pygame.mixer 播放指定的本地 MP3 文件代码路径指向 D:\trae\检查员提示音_Freesound.mp3。逻辑播放 REPEAT_COUNT (10次)且在播放期间暂停新的检测防止重复触发。 关键技术点音频处理库使用 sounddevice 进行低延迟的音频流录制numpy 进行信号处理和数学计算。多线程主线程保持程序运行。监听线程负责后台检测。播放线程负责播放音频避免阻塞监听。抗噪与优化设置了音量阈值 (volume 0.05) 忽略静音片段节省计算资源。滑动步长设为 1000加快比对速度。 总结这就好比一个“声音回声筒”你先教它认一个声音然后它一直竖着耳朵听一旦在环境里听到这个声音它就会大声把另一个预设好的 MP3 文件播放出来。# -*- coding: utf-8 -*-importwarnings warnings.filterwarnings(ignore)importosimporttimeimportthreadingimportpygameimportnumpyasnpimportsounddeviceassd# 配置区域 TEMPLATE_RECORD_SECONDS1REPEAT_COUNT10# 阈值设为 0.45 (刚才测到了 0.53所以 0.45 很安全)THRESHOLD0.45# is_repeatingFalsetarget_templateNonedefrecord_template():globaltarget_templateprint(\n*50)print( 准备录制模板)print(请按 Enter 键然后播放提示音...)input()SAMPLE_RATE44100print( 正在录制... (发出你要识别的声音))audiosd.rec(int(TEMPLATE_RECORD_SECONDS*SAMPLE_RATE),samplerateSAMPLE_RATE,channels1,dtypefloat32)sd.wait()target_templateaudio[:,0]print(f✅ 模板录制成功长度:{len(target_template)}个采样点)print(*50\n)time.sleep(1)defplay_task():globalis_repeatingtry:print(f\n 开始复读任务...)pygame.mixer.init(frequency44100,size-16,channels1)pygame.mixer.music.load(rD:\trae\检查员提示音_Freesound.mp3)foriinrange(REPEAT_COUNT):print(f 播放第{i1}/{REPEAT_COUNT}次...)pygame.mixer.music.play()whilepygame.mixer.music.get_busy():time.sleep(3)print( ✅ 复读完成)exceptExceptionase:print(f ❌ 播放错误:{e})finally:pygame.mixer.quit()is_repeatingFalsedeflisten_loop():globalis_repeating record_template()template_lenlen(target_template)print(f 正在监听... (阈值:{THRESHOLD}))whileTrue:ifis_repeating:time.sleep(0.5)continuetry:RECORD_SECONDS2SAMPLE_RATE44100audiosd.rec(int(RECORD_SECONDS*SAMPLE_RATE),samplerateSAMPLE_RATE,channels1,dtypefloat32)sd.wait()recordingaudio[:,0]# 音量检测volumenp.max(np.abs(recording))ifvolume0.05:continue# --- 核心修改滑动窗口比对 ---max_similarity0.0# 如果录音比模板长我们就滑动查找iflen(recording)template_len:# 滑动步长设为 1000加快计算速度step1000foriinrange(0,len(recording)-template_len,step):# 截取一段rec_partrecording[i:itemplate_len]# 计算相关系数corrnp.corrcoef(rec_part,target_template)simabs(corr[0,1])# 记录最高相似度ifsimmax_similarity:max_similaritysimelse:# 如果录音太短直接比对补零或截断min_lenmin(len(recording),template_len)corrnp.corrcoef(recording[:min_len],target_template[:min_len])max_similarityabs(corr[0,1])print(f 音量:{volume:.2f}| 最高相似度:{max_similarity:.3f})ifmax_similarityTHRESHOLD:print(f\n⚡ 发现匹配声音(相似度{max_similarity:.3f}) 触发复读)is_repeatingTruetthreading.Thread(targetplay_task)t.daemonTruet.start()exceptExceptionase:print(f 错误:{e})time.sleep(1)if__name____main__:print( 程序启动...)ifnotos.path.exists(rD:\trae\检查员提示音_Freesound.mp3):print(❌ MP3文件不存在)exit()listener_threadthreading.Thread(targetlisten_loop,daemonTrue)listener_thread.start()try:whileTrue:time.sleep(1)exceptKeyboardInterrupt:print(\n 退出。)补充# -*- coding: utf-8 -*-importwarnings warnings.filterwarnings(ignore)importosimporttimeimportthreadingimportpygameimportnumpyasnpimportsounddeviceassd# 配置区域 TEMPLATE_RECORD_SECONDS1REPEAT_COUNT10# 阈值设为 0.45 (刚才测到了 0.53所以 0.45 很安全)THRESHOLD0.45# is_repeatingFalsetarget_templateNonedefrecord_template():globaltarget_templateprint(\n*50)print( 准备录制模板)print(请按 Enter 键然后播放提示音...)input()SAMPLE_RATE44100print( 正在录制... (发出你要识别的声音))audiosd.rec(int(TEMPLATE_RECORD_SECONDS*SAMPLE_RATE),samplerateSAMPLE_RATE,channels1,dtypefloat32)sd.wait()target_templateaudio[:,0]print(f✅ 模板录制成功长度:{len(target_template)}个采样点)print(*50\n)time.sleep(1)defplay_task():globalis_repeatingtry:print(f\n 开始复读任务...)pygame.mixer.init(frequency44100,size-16,channels1)pygame.mixer.music.load(rD:\trae\检查员提示音_Freesound.mp3)foriinrange(REPEAT_COUNT):print(f 播放第{i1}/{REPEAT_COUNT}次...)pygame.mixer.music.play()whilepygame.mixer.music.get_busy():time.sleep(3)print( ✅ 复读完成)exceptExceptionase:print(f ❌ 播放错误:{e})finally:pygame.mixer.quit()is_repeatingFalsedeflisten_loop():globalis_repeating record_template()template_lenlen(target_template)print(f 正在监听... (阈值:{THRESHOLD}))whileTrue:ifis_repeating:time.sleep(0.1)continuetry:RECORD_SECONDS2SAMPLE_RATE44100audiosd.rec(int(RECORD_SECONDS*SAMPLE_RATE),samplerateSAMPLE_RATE,channels1,dtypefloat32)sd.wait()recordingaudio[:,0]# 音量检测volumenp.max(np.abs(recording))ifvolume0.05:continue# --- 核心修改滑动窗口比对 ---max_similarity0.0# 如果录音比模板长我们就滑动查找iflen(recording)template_len:# 滑动步长设为 1000加快计算速度step100foriinrange(0,len(recording)-template_len,step):# 截取一段rec_partrecording[i:itemplate_len]# 计算相关系数corrnp.corrcoef(rec_part,target_template)simabs(corr[0,1])# 记录最高相似度ifsimmax_similarity:max_similaritysimelse:# 如果录音太短直接比对补零或截断min_lenmin(len(recording),template_len)corrnp.corrcoef(recording[:min_len],target_template[:min_len])max_similarityabs(corr[0,1])print(f 音量:{volume:.2f}| 最高相似度:{max_similarity:.3f})ifmax_similarityTHRESHOLD:print(f\n⚡ 发现匹配声音(相似度{max_similarity:.3f}) 触发复读)is_repeatingTruetthreading.Thread(targetplay_task)t.daemonTruet.start()exceptExceptionase:print(f 错误:{e})time.sleep(1)if__name____main__:print( 程序启动...)ifnotos.path.exists(rD:\trae\检查员提示音_Freesound.mp3):print(❌ MP3文件不存在)exit()listener_threadthreading.Thread(targetlisten_loop,daemonTrue)listener_thread.start()try:whileTrue:time.sleep(1)exceptKeyboardInterrupt:print(\n 退出。)