当前位置: 首页 > news >正文

声音触发器。用于自动化场景检测器

在使用AI智能体时,我们遇到很多已经运行结束,就是还不知道的情况下,我们可以设置一段脚本,让运行完声音一直提醒我们,让第一时间我们知道,才写的这段脚本,很完美,你们尝试一下。

这段代码实现了一个基于音频相似度检测的自动复读系统。
简单来说,它的作用是:监听环境声音,当检测到特定的“触发音”时,自动播放一段指定的 MP3 音频(复读)。
以下是代码的详细功能模块总结:
🎯 核心用途
这是一个声音触发器。它通常用于自动化场景,例如:
游戏辅助:听到游戏内的特定提示音(如“检查员来了”),自动播放语音提醒或执行操作。
语音交互:听到特定的唤醒词或指令后,自动播放回复语音。
自动化监控:监控特定频率或类型的声音事件。
⚙️ 功能模块详解

  1. 模板录制与学习
    功能:程序启动后,首先会进入“录制模式”。
    实现:利用 sounddevice 录制一段用户发出的声音作为“模板”。
    目的:确立“我要找的声音”是什么样子的,作为后续比对的基准。
  2. 实时监听与特征比对
    功能:在后台循环监听麦克风输入。
    核心算法:
    滑动窗口:在录音流中截取片段。
    相关系数:使用 np.corrcoef 计算录音片段与模板声音的皮尔逊相关系数。
    阈值判定:如果相似度超过设定的 THRESHOLD (代码中设为 0.45),则判定为匹配成功。
  3. 自动复读
    功能:一旦检测到匹配的声音,触发播放线程。
    实现:使用 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_SECONDS=1REPEAT_COUNT=10# 阈值设为 0.45 (刚才测到了 0.53,所以 0.45 很安全)THRESHOLD=0.45# ===========================================is_repeating=Falsetarget_template=Nonedefrecord_template():globaltarget_templateprint("\n"+"="*50)print("🎤 准备录制模板")print("请按 Enter 键,然后播放提示音...")input()SAMPLE_RATE=44100print("🔴 正在录制... (发出你要识别的声音)")audio=sd.rec(int(TEMPLATE_RECORD_SECONDS*SAMPLE_RATE),samplerate=SAMPLE_RATE,channels=1,dtype='float32')sd.wait()target_template=audio[:,0]print(f"✅ 模板录制成功!长度:{len(target_template)}个采样点")print("="*50+"\n")time.sleep(1)defplay_task():globalis_repeatingtry:print(f"\n🔊 开始复读任务...")pygame.mixer.init(frequency=44100,size=-16,channels=1)pygame.mixer.music.load(r"D:\trae\检查员提示音_Freesound.mp3")foriinrange(REPEAT_COUNT):print(f" 播放第{i+1}/{REPEAT_COUNT}次...")pygame.mixer.music.play()whilepygame.mixer.music.get_busy():time.sleep(3)print(" ✅ 复读完成")exceptExceptionase:print(f" ❌ 播放错误:{e}")finally:pygame.mixer.quit()is_repeating=Falsedeflisten_loop():globalis_repeating record_template()template_len=len(target_template)print(f"👂 正在监听... (阈值:{THRESHOLD})")whileTrue:ifis_repeating:time.sleep(0.5)continuetry:RECORD_SECONDS=2SAMPLE_RATE=44100audio=sd.rec(int(RECORD_SECONDS*SAMPLE_RATE),samplerate=SAMPLE_RATE,channels=1,dtype='float32')sd.wait()recording=audio[:,0]# 音量检测volume=np.max(np.abs(recording))ifvolume<0.05:continue# --- 核心修改:滑动窗口比对 ---max_similarity=0.0# 如果录音比模板长,我们就滑动查找iflen(recording)>template_len:# 滑动步长设为 1000,加快计算速度step=1000foriinrange(0,len(recording)-template_len,step):# 截取一段rec_part=recording[i:i+template_len]# 计算相关系数corr=np.corrcoef(rec_part,target_template)sim=abs(corr[0,1])# 记录最高相似度ifsim>max_similarity:max_similarity=simelse:# 如果录音太短,直接比对(补零或截断)min_len=min(len(recording),template_len)corr=np.corrcoef(recording[:min_len],target_template[:min_len])max_similarity=abs(corr[0,1])print(f"🔊 音量:{volume:.2f}| 最高相似度:{max_similarity:.3f}")ifmax_similarity>THRESHOLD:print(f"\n⚡ 发现匹配声音!(相似度{max_similarity:.3f}) 触发复读!")is_repeating=Truet=threading.Thread(target=play_task)t.daemon=Truet.start()exceptExceptionase:print(f" 🎤 错误:{e}")time.sleep(1)if__name__=="__main__":print("🚀 程序启动...")ifnotos.path.exists(r"D:\trae\检查员提示音_Freesound.mp3"):print("❌ MP3文件不存在")exit()listener_thread=threading.Thread(target=listen_loop,daemon=True)listener_thread.start()try:whileTrue:time.sleep(1)exceptKeyboardInterrupt:print("\n👋 退出。")

补充

# -*- coding: utf-8 -*-importwarnings warnings.filterwarnings("ignore")importosimporttimeimportthreadingimportpygameimportnumpyasnpimportsounddeviceassd# ================= 配置区域 =================TEMPLATE_RECORD_SECONDS=1REPEAT_COUNT=10# 阈值设为 0.45 (刚才测到了 0.53,所以 0.45 很安全)THRESHOLD=0.45# ===========================================is_repeating=Falsetarget_template=Nonedefrecord_template():globaltarget_templateprint("\n"+"="*50)print("🎤 准备录制模板")print("请按 Enter 键,然后播放提示音...")input()SAMPLE_RATE=44100print("🔴 正在录制... (发出你要识别的声音)")audio=sd.rec(int(TEMPLATE_RECORD_SECONDS*SAMPLE_RATE),samplerate=SAMPLE_RATE,channels=1,dtype='float32')sd.wait()target_template=audio[:,0]print(f"✅ 模板录制成功!长度:{len(target_template)}个采样点")print("="*50+"\n")time.sleep(1)defplay_task():globalis_repeatingtry:print(f"\n🔊 开始复读任务...")pygame.mixer.init(frequency=44100,size=-16,channels=1)pygame.mixer.music.load(r"D:\trae\检查员提示音_Freesound.mp3")foriinrange(REPEAT_COUNT):print(f" 播放第{i+1}/{REPEAT_COUNT}次...")pygame.mixer.music.play()whilepygame.mixer.music.get_busy():time.sleep(3)print(" ✅ 复读完成")exceptExceptionase:print(f" ❌ 播放错误:{e}")finally:pygame.mixer.quit()is_repeating=Falsedeflisten_loop():globalis_repeating record_template()template_len=len(target_template)print(f"👂 正在监听... (阈值:{THRESHOLD})")whileTrue:ifis_repeating:time.sleep(0.1)continuetry:RECORD_SECONDS=2SAMPLE_RATE=44100audio=sd.rec(int(RECORD_SECONDS*SAMPLE_RATE),samplerate=SAMPLE_RATE,channels=1,dtype='float32')sd.wait()recording=audio[:,0]# 音量检测volume=np.max(np.abs(recording))ifvolume<0.05:continue# --- 核心修改:滑动窗口比对 ---max_similarity=0.0# 如果录音比模板长,我们就滑动查找iflen(recording)>template_len:# 滑动步长设为 1000,加快计算速度step=100foriinrange(0,len(recording)-template_len,step):# 截取一段rec_part=recording[i:i+template_len]# 计算相关系数corr=np.corrcoef(rec_part,target_template)sim=abs(corr[0,1])# 记录最高相似度ifsim>max_similarity:max_similarity=simelse:# 如果录音太短,直接比对(补零或截断)min_len=min(len(recording),template_len)corr=np.corrcoef(recording[:min_len],target_template[:min_len])max_similarity=abs(corr[0,1])print(f"🔊 音量:{volume:.2f}| 最高相似度:{max_similarity:.3f}")ifmax_similarity>THRESHOLD:print(f"\n⚡ 发现匹配声音!(相似度{max_similarity:.3f}) 触发复读!")is_repeating=Truet=threading.Thread(target=play_task)t.daemon=Truet.start()exceptExceptionase:print(f" 🎤 错误:{e}")time.sleep(1)if__name__=="__main__":print("🚀 程序启动...")ifnotos.path.exists(r"D:\trae\检查员提示音_Freesound.mp3"):print("❌ MP3文件不存在")exit()listener_thread=threading.Thread(target=listen_loop,daemon=True)listener_thread.start()try:whileTrue:time.sleep(1)exceptKeyboardInterrupt:print("\n👋 退出。")
http://www.jsqmd.com/news/567387/

相关文章:

  • 北斗高精度数据解算:破解城市峡谷/长基线/无网区难题,从毫米级定位到自动化交付——(GAMIT/GLOBK底层核心解算技术方法)
  • 忍者像素绘卷效果实测:云端画布UI在微信小程序WebView渲染性能
  • LeetCode HOT100 - 买卖股票的最佳时机含冷冻期
  • ROS2编译报错CMake未找到diagnostic_updater:从诊断工具缺失到精准安装
  • Phi-4-mini-reasoning保姆级教程:模型量化INT4部署可行性实测
  • 别再手动调了!用Visio这个隐藏的字体设置窗口,一键切换泳道图标题横竖排
  • Pixel Language Portal保姆级教程:Hunyuan-MT-7B自定义词典注入+像素UI术语高亮配置
  • comsol 拓扑优化,流动传热拓扑优化,流固耦合拓扑优化。 伴随拓扑优化提供matlab和p...
  • 艾奇GEO:跨境企业AI搜索没海外流量?5大底层逻辑破解获客困局 - 小白条111
  • Youtu-Parsing模型C盘空间优化部署:清理与迁移实战指南
  • 汽修店数字化转型的“最优解”:聚泰汽修管理软件深度解析
  • 转行Agent,学什么程度才能拿到offer
  • Qwen-Image-Edit解决修图难题:去除水印、更换风格、智能美化一键完成
  • GOTS有机认证为何能称为纺织品领域的“金字招牌”
  • 我是自动化程序的博客
  • 突破原神帧率限制:游戏流畅度提升50%的高性能优化指南
  • 艾奇GEO:深度解析教育机构AI搜索课程没曝光的常见核心原因与实用解决方法 - 小白条111
  • 4个实战步骤:TradingAgents-CN多智能体交易系统本地化部署指南
  • 电刺激能否恢复视力?电极阵列或有助于受损视神经的再生
  • 测试转Agent,三个月才发现自己是先天Agent圣体
  • Live2D AI虚拟助手:5分钟为网站添加智能动画角色
  • 艾奇GEO:企业AI内容没曝光?4大核心病因+5步破局指南 - 小白条111
  • 前端代码分割与懒加载:让你的应用飞起来
  • 原神智能助手:提升游戏效率的开源工具箱
  • 强化学习学习路径
  • 3步解锁小红书无水印素材采集:XHS-Downloader效率提升指南
  • 如何通过4个步骤彻底掌控微信聊天记录:WeChatMsg完全指南
  • 2026年艾奇GEO售后渠道深度解析:从落地到保障的全链路支持 - 小白条111
  • 神经暗网计划:用脑电波传输反抗代码
  • lvgl_v8之布局代码使用示例