借助DS用python帮你编写脚本(辅助开发测试)

article/2025/7/15 11:05:40

最近在做一个音频采集识别项目,采集20HZ到20KHZ各个频带最大分贝数(DB),需要用到各个频段的测试音频来验证程序的正确性。

借助Deepseek,原本对python编程没有学过,也能轻松学会。

提问:python生成测试音频文件,需要python专门的编译工具软件吗

以下是DS的回答:

我们使用Python生成测试音频文件,只需要安装几个库即可,不需要专门的编译工具软件。

具体步骤如下:

1. 安装必要的Python库:

- numpy:用于生成音频数据

- soundfile:用于写入WAV文件

2. 可以通过pip安装:

```

pip install numpy soundfile

```

3. 编写Python脚本生成测试音频(如之前提供的脚本)

4. 运行脚本生成WAV文件。

注意:soundfile库在写入WAV文件时,需要依赖libsndfile库。在Windows和macOS上,soundfile通常会自带预编译的库。在Linux上,可能需要安装系统库,例如:

Ubuntu/Debian: `sudo apt-get install libsndfile1`

因此,除了安装Python库,一般不需要其他专门的编译工具软件(除非在Linux上需要安装系统库)。

下面再提供一个完整的测试音频生成脚本,该脚本生成一个包含多个频率成分的音频文件,每个频率成分持续一段时间,便于分段测试。

不需要专门的编译工具软件,只需安装几个 Python 库即可生成测试音频文件。以下是完整的解决方案:

一、所需工具和库

基础要求:

Python 3.6+(官网下载)

pip(Python包管理器,通常随Python安装)

必要库:

bash

pip install numpy scipy soundfile matplotlib

numpy:数值计算库

scipy:科学计算库(用于信号处理)

soundfile:音频文件读写库

matplotlib(可选):用于可视化音频波形

二、完整测试音频生成脚本

python

"""

audio_generator.py - 测试音频生成工具

用于验证ESP32音频分析系统

"""

import numpy as np

import soundfile as sf

import matplotlib.pyplot as plt

import argparse

import sys

def generate_sine_wave(freq, duration=5, sample_rate=48000, amplitude=0.8):

    """生成单频正弦波"""

    t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)

    return amplitude * np.sin(2 * np.pi * freq * t)

def generate_test_audio(output_file, sample_rate=48000, duration=10):

    """生成多频带测试音频"""

    print(f"生成测试音频: {output_file} (采样率: {sample_rate}Hz, 时长: {duration}秒)")   

    t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)

    signal = np.zeros_like(t)   

    # 不同频带的测试信号(带时间标记)

    signals = [

        {"freq": 50, "start": 0.0, "end": 2.0, "label": "超低频(50Hz)"},

        {"freq": 250, "start": 2.0, "end": 4.0, "label": "低频(250Hz)"},

        {"freq": 1000, "start": 4.0, "end": 6.0, "label": "中低频(1kHz)"},

        {"freq": 2500, "start": 6.0, "end": 8.0, "label": "中频(2.5kHz)"},

        {"freq": 5000, "start": 8.0, "end": 10.0, "label": "中高频(5kHz)"},

        {"freq": 10000, "start": 10.0, "end": 12.0, "label": "高频(10kHz)"},

        {"freq": 15000, "start": 12.0, "end": 14.0, "label": "超高频(15kHz)"},

        {"freq": 18000, "start": 14.0, "end": 16.0, "label": "极高频(18kHz)"}

    ]   

    # 组合信号

    for s in signals:

        start_idx = int(s["start"] * sample_rate)

        end_idx = int(s["end"] * sample_rate)

        segment = generate_sine_wave(s["freq"], s["end"]-s["start"], sample_rate)

        signal[start_idx:end_idx] += segment[:end_idx-start_idx]   

    # 归一化防止削波

    signal = 0.8 * signal / np.max(np.abs(signal))   

    # 保存为WAV文件

    sf.write(output_file, signal, sample_rate, subtype='PCM_16')

    print(f"成功生成测试音频: {output_file}")   

    return signal

def plot_audio_waveform(signal, sample_rate, output_image=None):

    """可视化音频波形(可选)"""

    plt.figure(figsize=(12, 6))

    plt.title("测试音频波形")

    plt.plot(np.arange(len(signal)) / sample_rate, signal)

    plt.xlabel("时间 (秒)")

    plt.ylabel("振幅")

    plt.grid(True)   

    if output_image:

        plt.savefig(output_image)

        print(f"波形图保存至: {output_image}")

    else:

        plt.show()

def main():

    parser = argparse.ArgumentParser(description='ESP32音频分析系统测试音频生成工具')

    parser.add_argument('-o', '--output', default='audio_test.wav', help='输出WAV文件名')

    parser.add_argument('-s', '--sample-rate', type=int, default=48000, help='采样率 (默认48000)')

    parser.add_argument('-d', '--duration', type=int, default=16, help='音频时长(秒) (默认16)')

    parser.add_argument('-p', '--plot', metavar='IMAGE', help='生成波形图(可选)')

    args = parser.parse_args()   

    try:

        signal = generate_test_audio(args.output, args.sample_rate, args.duration)       

        if args.plot:

            plot_audio_waveform(signal, args.sample_rate, args.plot)           

        print("\n使用说明:")

        print("1. 将此音频文件复制到手机/电脑")

        print("2. 在安静环境中播放音频")

        print("3. 将ESP32的麦克风靠近扬声器")

        print("4. 监控串口输出,验证各频段检测结果")       

    except Exception as e:

        print(f"错误: {e}", file=sys.stderr)

        sys.exit(1)

if __name__ == "__main__":

    main()

三、使用说明

安装依赖库:

bash

pip install numpy scipy soundfile matplotlib

生成测试音频:

bash

# 基本用法

python audio_generator.py

# 自定义输出文件

python audio_generator.py -o custom_test.wav

# 生成波形图

python audio_generator.py -p waveform.png

输出文件:

audio_test.wav:16秒测试音频,包含8个频段

waveform.png(可选):音频波形可视化

四、音频内容说明

生成的测试音频包含以下分段信号:

时间段(秒)  频率(Hz)  频带类别    预期检测频带

0-2 50  超低频 12-100Hz

2-4 250 低频  100-500Hz

4-6 1000    中低频 500-2000Hz

6-8 2500    中频  2000-3000Hz

8-10    5000    中高频 3000-8000Hz

10-12   10000   高频  8000-12000Hz

12-14   15000   超高频 12000-16000Hz

14-16   18000   极高频 16000-20000Hz

五、验证方法

播放音频:

使用任何媒体播放器(VLC、Windows Media Player等)

确保扬声器/耳机质量可以播放18kHz高频

监控ESP32输出:

每秒应看到对应频带的峰值升高

示例输出:

[0-2秒] 12-100Hz频带值显著高于其他

[2-4秒] 100-500Hz频带值显著高于其他...

特殊验证技巧:

python

# 生成纯18kHz测试音

python -c "import numpy as np; import soundfile as sf; t=np.linspace(0,5,240000); sf.write('18khz.wav', 0.8*np.sin(2*np.pi*18000*t), 48000)"

播放此文件时,应只有16000-20000Hz频带有显著输出

六、常见问题解决

高频无法播放:

使用频谱分析APP(如Spectroid)检查手机扬声器输出

更换高质量耳机/扬声器

库安装失败:

bash

# Windows用户尝试

python -m pip install --upgrade pip

pip install wheel

pip install numpy scipy soundfile

# macOS/Linux用户

pip3 install numpy scipy soundfile

音频生成失败:

确保有足够的磁盘空间

尝试降低采样率:python audio_generator.py -s 44100

这个方案完全基于Python标准工具链,无需任何专业音频设备或商业软件,即可生成用于验证ESP32音频分析系统的测试文件。

上述是DS的回答,但上述的生成的完整脚本,因为带有中文注解,在WINDOS执行脚本,会执行出错,需要多一个提问,即可生成完整可执行的脚本。

提问:把上文中提到的完整测试音频生成脚本,把中文部分脚本转成英文脚本。

DS回答:

We are going to translate the entire script to English, including comments, strings, and variable names (where appropriate). However, we will keep the function and variable names in English but without translating them if they are already in a technical context. The main goal is to have the script in English for better international readability.

Steps:

1. Translate the comments to English.

2. Translate the strings (like print statements) to English.

3. Keep function and variable names in English (they are already in English).

4. The structure and logic of the code remain the same.

Let's do it step by step.

Here's the fully translated English version of the test audio generation script:

python

"""

audio_generator.py - Test Audio Generator

For validating ESP32 audio analysis systems

"""

import numpy as np

import soundfile as sf

import matplotlib.pyplot as plt

import argparse

import sys

def generate_sine_wave(freq, duration=5, sample_rate=48000, amplitude=0.8):

    """Generate a sine wave at specified frequency"""

    t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)

    return amplitude * np.sin(2 * np.pi * freq * t)

def generate_test_audio(output_file, sample_rate=48000, duration=10):

    """Generate multi-band test audio"""

    print(f"Generating test audio: {output_file} (Sample rate: {sample_rate}Hz, Duration: {duration} seconds)")   

    t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)

    signal = np.zeros_like(t)   

    # Test signals for different frequency bands (with timing markers)

    signals = [

        {"freq": 50, "start": 0.0, "end": 2.0, "label": "Sub-bass (50Hz)"},

        {"freq": 250, "start": 2.0, "end": 4.0, "label": "Bass (250Hz)"},

        {"freq": 1000, "start": 4.0, "end": 6.0, "label": "Low-mid (1kHz)"},

        {"freq": 2500, "start": 6.0, "end": 8.0, "label": "Mid-range (2.5kHz)"},

        {"freq": 5000, "start": 8.0, "end": 10.0, "label": "Upper-mid (5kHz)"},

        {"freq": 10000, "start": 10.0, "end": 12.0, "label": "Presence (10kHz)"},

        {"freq": 15000, "start": 12.0, "end": 14.0, "label": "Brilliance (15kHz)"},

        {"freq": 18000, "start": 14.0, "end": 16.0, "label": "Ultra-high (18kHz)"}

    ]   

    # Combine signals

    for s in signals:

        start_idx = int(s["start"] * sample_rate)

        end_idx = int(s["end"] * sample_rate)

        segment = generate_sine_wave(s["freq"], s["end"]-s["start"], sample_rate)

        signal[start_idx:end_idx] += segment[:end_idx-start_idx]   

    # Normalize to prevent clipping

    signal = 0.8 * signal / np.max(np.abs(signal))   

    # Save as WAV file

    sf.write(output_file, signal, sample_rate, subtype='PCM_16')

    print(f"Test audio successfully generated: {output_file}")   

    return signal

def plot_audio_waveform(signal, sample_rate, output_image=None):

    """Visualize audio waveform (optional)"""

    plt.figure(figsize=(12, 6))

    plt.title("Test Audio Waveform")

    plt.plot(np.arange(len(signal)) / sample_rate, signal)

    plt.xlabel("Time (seconds)")

    plt.ylabel("Amplitude")

    plt.grid(True)   

    if output_image:

        plt.savefig(output_image)

        print(f"Waveform saved to: {output_image}")

    else:

        plt.show()

def main():

    parser = argparse.ArgumentParser(description='Test Audio Generator for ESP32 Audio Analysis Systems')

    parser.add_argument('-o', '--output', default='audio_test.wav', help='Output WAV filename')

    parser.add_argument('-s', '--sample-rate', type=int, default=48000, help='Sample rate (default 48000)')

    parser.add_argument('-d', '--duration', type=int, default=16, help='Audio duration in seconds (default 16)')

    parser.add_argument('-p', '--plot', metavar='IMAGE', help='Generate waveform plot (optional)')

    args = parser.parse_args()   

    try:

        signal = generate_test_audio(args.output, args.sample_rate, args.duration)       

        if args.plot:

            plot_audio_waveform(signal, args.sample_rate, args.plot)           

        print("\nUsage instructions:")

        print("1. Copy this audio file to your phone/computer")

        print("2. Play the audio in a quiet environment")

        print("3. Position ESP32's microphone near the speaker")

        print("4. Monitor serial output to verify band detection")       

    except Exception as e:

        print(f"Error: {e}", file=sys.stderr)

        sys.exit(1)

if __name__ == "__main__":

    main()

将上述脚本复制到一个文本文档,然后保存成py后缀名的python脚本,放在相当应的目录下,在此目录下运行CMD命令,按照DS的提示的python脚本,即可生成想要的对应音频文件。


http://www.hkcw.cn/article/FaAyKgcUwD.shtml

相关文章

【图像处理基石】如何进行图像畸变校正?

图像畸变校正常用于计算机视觉、摄影测量学和机器人导航等领域,能够修正因镜头光学特性或传感器排列问题导致的图像失真。下面我将介绍几种常用的图像畸变校正算法,并提供Python实现和测试用例。 常用算法及Python实现 1. 径向畸变校正 径向畸变是最常…

技术创新如何赋能音视频直播行业?

在全球音视频直播行业的快速发展中,技术的持续创新始终是推动行业进步的核心动力。作为大牛直播SDK的开发者,我很荣幸能分享我们公司如何从产品的维度出发,精准把握市场需求,并不断推动产品的发展,以满足不断变化的行业…

我的世界服务端搭建

文章目录 我的世界服务端搭建使用forge搭建服务端确保服务器的 Java 环境安装1.20.1服务端配置文件修改启动游戏服务器 Minecraft server.properties 文件解析**基础设置****世界设置****网络与安全****性能优化****高级功能****配置文件示例****注意事项**Minecraft 白名单系统…

官宣正式分手 特朗普马斯克说了什么临别感言

官宣正式“分手” 特朗普马斯克都说了什么“临别感言”当地时间5月30日,美国总统特朗普和美国企业家、政府效率部负责人埃隆马斯克在白宫举行新闻发布会。特朗普称赞“政府效率部”成就在发布会上,特朗普对马斯克领导的“政府效率部”所达成的成就表示称赞,他称“政府效率部…

STM32通过rt_hw_hard_fault_exception中的LR寄存器追溯程序问题​

1. 问题现象 程序运行导致rt_hw_hard_fault_exception 如图 显示错误相关代码 struct exception_stack_frame {uint32_t r0;uint32_t r1;uint32_t r2;uint32_t r3;uint32_t r12; uint32_t lr; // 链接寄存器 (LR)uint32_t pc; // 程序计数器 (PC)uint32_t psr; // 程序状态…

AgenticSeek,开源本地通用AI Agent,自主执行任务

AgenticSeek是一款完全本地化的开源AI助手,作为Manus的开源替代品,专为保护用户隐私而设计。它能够在本地设备上执行多种任务,包括网页浏览、代码编写和复杂项目的规划,确保所有操作和数据均在用户的设备上完成。 AgenticSeek是什…

深入理解 Java 反射机制:动态编程的核心利器

一、反射机制的本质与核心价值 在 Java 的世界里,反射机制(Reflection)被视为连接静态编译与动态执行的桥梁。当程序运行时,反射允许我们在内存中动态获取类的完整结构信息,并对类的成员(字段、方法、构造…

群晖synology nas安装curl教程

在群晖nas系统上发现没有curl这个命令,想通过opkg进行安装,发现opkg这个套件也没有,本章教程介绍如何安装opkg,并通过opkg 安装上curl命令工具,nas的系统版本是:x86_64 GNU/Linux synology_apollolake_918+ 一、安装opkg wget -O - http://bin.entware.net/x64-k3.2/inst…

非接触式数据引擎:RFID重塑锂电注液工艺实时交互生态

非接触式数据引擎:RFID重塑锂电注液工艺实时交互生态 浙江某锂电行业注液机上存在问题: 1.在锂电池制造的核心环节中,注液工艺直接影响电芯的电化学性能与安全稳定性。随着行业对电池一致性、生产效率及追溯能力的需求升级。 2.按设定的抽…

Shell基础命令

一、设置修改主机名称 1.文件方式(重启生效) 2.命令方式(立即生效) hostnamectl set-hostname myname 二、网络管理nmcli (NetworkManager command-line interface) nmcli 1、查看网卡 2、设置网卡 dhcp网络工作模式 静态网…

【JVM】Java程序运行时数据区

运行时数据区 运行时数据区是Java程序执行过程中管理的内存区域 Java 运行时数据区组成(JVM 内存结构) Java 虚拟机(JVM)的运行时数据区由以下核心部分组成: 线程私有:程序计数器、Java虚拟机栈、本地方…

力扣面试150题--二叉树的层平均值

Day 54 题目描述 思路 初次做法(笨):使用两个队列,一个队列存放树的节点,一个队列存放对应节点的高度,使用x存放上一个节点,highb存放上一个节点的高度,sum存放当前层的节点值之和…

机器学习与深度学习01--线性回归

目录 1.什么是线性回归2.如何用数学方式描述简单线性回归模型3.什么是最小二乘法,他有什么作用 1.什么是线性回归 线性回归是⼀种⼴泛⽤于统计学和机器学习中的回归分析⽅法,⽤于建⽴⾃变量(特征)与因变量(⽬标&#…

004时装购物系统技术解析:构建智能时尚消费平台

时装购物系统技术解析:构建智能时尚消费平台 在电商行业蓬勃发展的当下,时装购物系统凭借其便捷性与多样性,成为消费者选购时尚单品的重要渠道。该系统通过商品信息、订单管理等核心模块,结合前台展示与后台录入功能,…

无线通信模块简介

QuecPython 是运行在无线通信模块上的开发框架。对于首次接触物联网开发的用户而言,无线通信模块可能是一个相对陌生的概念。本文主要针对无线通信和蜂窝网络本身,以及模块的概念、特性和开发方式进行简要的介绍。 无线通信和蜂窝网络 物联网对无线通信…

从认识AI开始-----解密门控循环单元(GRU):对LSTM的再优化

前言 在此之前,我已经详细介绍了RNN和LSTM,RNN虽然在处理序列数据中发挥了重要的作用,但它在实际使用中存在长期依赖问题,处理不了长序列,因为RNN对信息的保存只依赖一个隐藏状态,当序列过长,隐…

历年西北工业大学计算机保研上机真题

2025西北工业大学计算机保研上机真题 2024西北工业大学计算机保研上机真题 2023西北工业大学计算机保研上机真题 在线测评链接:https://pgcode.cn/school 计算整数乘积 题目描述 给定 n n n 组数,每组两个整数,输出这两个整数的乘积。 …

ansible-playbook 进阶 接上一章内容

1.异常中断 做法1:强制正常 编写 nginx 的 playbook 文件 01-zuofa .yml - hosts : web remote_user : root tasks : - name : create new user user : name nginx-test system yes uid 82 shell / sbin / nologin - name : test new user shell : gete…

基于cornerstone3D的dicom影像浏览器 第二十七章 设置vr相机,复位视图

文章目录 前言一、VR视图设置相机位置1. 相机位置参数2. 修改mprvr.js3. 调用流程1) 修改Toolbar3D.vue2) 修改View3d.vue3) 修改DisplayerArea3D.vue 二、所有视图复位1.复位流程说明2. 调用流程1) Toolbar3D中添加"复位"按钮,发送reset事件2) View3d.vu…

以色列防长:哈马斯要么接受美方提案 要么面临毁灭

当地时间5月30日,以色列国防部长卡茨通过其个人社交媒体账号发表声明称,在以军强大的军事压力之下,巴勒斯坦伊斯兰抵抗运动(哈马斯)将被迫接受选择:接受美方提出加沙停火提案,或者被以色列消灭。△以色列国防部长卡茨(资料图)卡茨在声明中表示,当前以军正全力在加沙地…