2026寒假练 - 基于ESP32-S3 Sense制作语音点歌音乐盒
该项目使用了Ardunio、Edge Impulse,实现了语音点歌音乐盒的设计,它的主要功能为:语音识别关键词控制ep32播放暂停和切歌,用电位器控制音量大小,oled显示歌曲名、音量大小和播放进度,RGB灯带随音乐做律动。
标签
ADC
开发板
进击的野猪
更新2026-03-24
23

基于ESP32-S3的语音控制音乐播放器项目总结报告

一、所选任务介绍

本项目选择实现一个基于ESP32-S3的语音控制音乐播放器系统。任务的核心要求包括:预置不少于3段旋律序列并通过扬声器或蜂鸣器播放;使用RGB灯带实现与音乐节拍联动的律动灯效;通过麦克风关键词识别实现播放、暂停、下一首、音量大、音量小等至少3条语音指令;使用OLED显示屏实时显示曲目编号、播放进度百分比和当前音量信息。

本任务是一个典型的嵌入式人工智能应用,融合了语音识别技术、音频处理技术、多任务调度和硬件驱动开发等多个技术领域。通过这个项目,可以全面锻炼嵌入式系统开发能力,特别是将AI模型部署到资源受限的微控制器上的实践能力。

二、项目介绍

本项目设计并实现了一款智能语音控制音乐播放器。系统以ESP32-S3芯片为核心控制器,搭载PDM麦克风用于语音采集,使用有源蜂鸣器作为发声元件,配合10RGB LED实现音乐律动光效,并通过0.96英寸OLED显示屏提供用户界面。

系统主要功能模块包括:

  1. 语音识别模块:通过I2S接口采集麦克风音频数据,经过预处理后送入Edge Impulse训练好的神经网络模型进行推理,识别出播放暂停变化(下一首)三条语音指令。
  2. 音乐播放模块:预置三首不同风格的旋律(《鸟之诗》、《小星星》、《兰花草》),通过PWM驱动的蜂鸣器播放。每首歌曲的音符频率、时长、强度和对应的RGB颜色都预先定义在数据结构中。
  3. LED律动模块:根据当前播放音符的音强和PWM占空比,动态控制RGB LED的点亮数量和亮度,实现与音乐节拍同步的视觉效果。
  4. 显示模块OLED屏幕实时显示歌曲名称、播放进度百分比和当前音量大小。

三、硬件介绍

本项目使用的主要硬件如下:

  1. ESP32-S3开发板:项目核心控制器,集成Xtensa® 32-bit LX7双核处理器,主频高达240MHz,内置512KB SRAM和多种外设接口。特别重要的是其内置的神经网络加速器和支持PSRAM扩展,为运行语音识别模型提供了必要的算力和内存支持。
  2. PDM麦克风:用于采集环境声音信号,将用户的语音指令转换为数字信号供ESP32-S3处理。采用PDM接口,仅需两根数据线即可传输高质量音频数据。
  3. 有源蜂鸣器:作为音乐播放的执行元件,通过PWM波驱动发出不同频率的声音。虽然音质不如扬声器,但控制简单,适合本项目的演示需求。
  4. RGB LED灯带10WS2812B智能LED串联而成,每颗LED可独立显示256级亮度的RGB色彩,用于实现音乐律动光效。
  5. 0.96英寸OLED显示屏:采用SSD1306驱动芯片,128×64分辨率,通过I2C接口与主控通信,用于显示系统状态信息。
  6. 电位器:连接在ADC引脚上,用于模拟音量调节功能,用户可通过旋转电位器实时调整播放音量。

四、方案框图和项目设计思路

4.1 系统框图

4.2 设计思路

本项目的设计遵循模块化、低延迟、高可靠性的原则。核心设计思路如下:

  1. 双任务架构:利用ESP32-S3的双核特性,将音频采集任务固定在Core 0上运行,确保音频数据不丢失;主循环在Core 1上处理语音推理和音乐播放,实现任务的并行处理。
  2. VAD(语音活动检测)状态机:为提高识别准确率和降低功耗,设计了基于能量阈值的VAD状态机。系统持续检测环境声音能量,仅在检测到有效语音时才开始录音,避免将静音或噪声送入神经网络推理。
  3. 动态阈值校准:在系统启动时自动采集环境噪声进行校准,计算出动态阈值。这使得系统能够适应不同环境下的背景噪声,提高语音检测的鲁棒性。
  4. 数据居中处理:采集到语音片段后,通过计算在音频缓冲区中前后填充静音,将有效语音数据居中。这符合Edge Impulse模型训练时的数据分布,能显著提高识别准确率。
  5. 音乐播放与LED律动联动:每首歌曲的音符都预先定义了频率、时长、强度和颜色。播放时根据音符强度动态调节PWM占空比,同时控制RGB LED的点亮数量和颜色,实现视听联觉效果。

五、代码介绍

5.1 开发环境和编程语言

本项目使用 Arduino IDE 作为主要开发环境,编程语言为 C++。选择Arduino IDE的原因是其丰富的库支持和便捷的调试功能,能够快速验证硬件功能和算法逻辑。

5.2 主要使用的库

  • Edge Impulse Inferencing SDK:提供神经网络模型的推理接口,负责将音频特征输入模型并获取分类结果。
  • Adafruit NeoPixel:控制RGB LED灯带,实现LED的亮度和颜色设置。
  • Adafruit SSD1306/GFX:驱动OLED显示屏,提供图形和文本显示功能。
  • ESP32 I2S:配置和操作I2S接口,从PDM麦克风采集音频数据。
  • ESP32 LEDC:配置PWM通道,驱动蜂鸣器发声。

5.3 软件流程图

5.4 关键代码解析

5.4.1 VAD状态机实现

VAD状态机是本项目的核心算法之一,它根据音频能量值在四个状态之间切换:

static void process_vad(int16_t* chunk, size_t chunk_size) {
    int32_t energy = calculate_energy(chunk, chunk_size);
    int32_t threshold = energy_calibrator.get_threshold();
 
    switch (vad_state) {
        case STATE_SILENCE:
            if (energy > threshold) {
                // 检测到可能的语音开始,进入预语音状态
                vad_state = STATE_PRE_VOICE;
                voice_start_time = current_time;
                // 保存预触发数据...
            }
            break;
           
        case STATE_VOICE:
            if (energy < threshold * 0.3) {
                // 能量低于阈值,开始计数静音时长
                if (silence_start_time == 0)
                    silence_start_time = current_time;
                else if (current_time - silence_start_time > SILENCE_DURATION_MS)
                    vad_state = STATE_POST_VOICE;  // 静音足够长,结束语音
            } else {
                silence_start_time = 0;  // 重置静音计时
            }
            // 继续录音...
            break;
    }
}

这段代码通过能量比较和计时器实现了鲁棒的语音端点检测。静音阈值设置为语音阈值的30%,并需要持续300ms才判定语音结束,有效避免了语音中的短暂停顿导致错误切分。

5.4.2 音频数据居中处理

为了匹配训练数据的分布,采集到的语音片段需要前后填充静音,使有效语音居中:

if (recording_pos < total_samples) {
    size_t padding_total = total_samples - recording_pos;
    size_t pad_left = padding_total / 2;
    size_t pad_right = padding_total - pad_left;
   
    // 将原有语音数据向后移动,留出左侧填充空间
    memmove(audio_buffer + pad_left, audio_buffer, recording_pos * sizeof(int16_t));
    // 填充左侧静音
    memset(audio_buffer, 0, pad_left * sizeof(int16_t));
    // 填充右侧静音
    memset(audio_buffer + pad_left + recording_pos, 0, pad_right * sizeof(int16_t));
}

这种处理方式确保了输入到神经网络的数据格式统一,显著提高了识别准确率。

5.4.3 音乐播放任务

音乐播放任务负责定时更新当前播放的音符,并控制蜂鸣器和LED

void music_player_task() {
    // 读取电位器获取音量调节值
    int raw = analogRead(ADC_PIN);
    float volume_rate = (raw - 128) / (4095.0 - 128);
   
    // 计算当前音符的PWM占空比
    float intensity = currentSong[current_note_index].intensity * volume_rate;
    int duty = map(intensity, 0, 127, 0, 4095);
   
    // 更新LED律动效果
    SpectrumBars(currentSong[current_note_index].intensity,
                 value, currentSong[current_note_index].color);
   
    // 播放当前音符
    playTone(currentSong[current_note_index].frequency, noteDuration, duty);
   
    // 更新OLED显示
    oledDisplay(song_name, current_note_index, songLength, volume);
}

六、功能展示图及说明

6.1 实物展示

系统硬件连接完成后,整体结构紧凑。ESP32-S3开发板作为主控,连接了PDM麦克风、蜂鸣器、10RGB LEDOLED屏幕。电位器通过杜邦线连接到ADC引脚。

6.2 语音识别功能展示

当系统启动并完成校准后,OLED屏幕显示就绪信息。用户说出播放指令时,串口监视器输出:

同时蜂鸣器开始播放预置音乐,RGB LED随节拍闪烁,OLED屏幕更新为播放界面。

 

6.3 音乐播放界面展示

播放过程中,OLED屏幕显示:

  • 第一行:歌曲名称(如"Lan Hua Cao"
  • 第二行:音量百分比(如"volume: 6.8%"
  • 第三行:播放进度百分比(如"progress: 20.6%"
  • 底部进度条:直观显示播放位置

6.4 LED律动效果

RGB LED根据当前音符的频率和强度呈现出不同的颜色和亮度。例如:

  • 高音C5显示金色(COLOR_SUN_GOLD
  • 中音A4显示天空蓝(COLOR_SKY_BLUE
  • 低音B3显示海蓝色(COLOR_SEA_BLUE

LED点亮的数量与音符强度成正比,强度越高,点亮的LED数量越多,形成类似频谱分析仪的视觉效果。

七、项目中遇到的难题及解决方法

7.1 语音识别准确率低

问题描述:初期测试时,语音识别准确率不足50%,经常将环境噪声误识别为有效指令,或对同一个人多次说同一指令识别结果不一致。

解决方法

  1. 增加动态阈值校准:在系统启动时采集50次环境噪声样本,计算出底噪平均值和峰值,动态调整VAD阈值。
  2. 优化VAD状态机:增加预语音状态和静音计时器,避免短暂噪音触发录音。
  3. 数据居中处理:采集到的语音片段在送入模型前进行前后填充静音,使有效语音居中,匹配训练数据分布。
  4. 提高置信度阈值:将识别置信度阈值从0.5提高到0.7,只有超过70%置信度的结果才执行指令。
  5. 统一代码:录制关键词的代码和做语音识别的代码在接收语音的部分基本一样,让训练模型的关键词音频与语音识别的关键词音频基本保持一致。

经过优化后,在安静环境下识别准确率提升至95%以上。

7.2 切歌时播放进度显示异常

问题描述:执行下一首指令时,新歌曲的播放进度不从0开始,而是延续上一首的进度值。

解决方法:经代码审查发现,切歌时只更新了current_song_index和重新加载歌曲数据,但未重置totalTimePlayed变量。修复方法是在CMD_CHANGE处理分支中添加:

case CMD_CHANGE:
    current_song_index = (current_song_index + 1) % SONG_NUM;
    load_song(current_song_index);
    current_note_index = 0;
    totalTimePlayed = 0;  // 重置播放进度
    if (music_state == MUSIC_PLAYING) {
        next_note_time = millis();
    }
    break;

同时,在playTone函数中也添加了音符索引变化的检测,确保计时状态正确重置。

八、心得体会

通过本次项目实践,我对嵌入式AI系统的开发流程有了深刻的理解和体会。

首先,系统架构设计至关重要。在项目初期,我采用了单线程轮询方式处理所有任务,导致音频采集不连续、语音识别响应慢等问题。后来重新设计为双任务架构,将实时性要求高的音频采集任务放在独立核心运行,大大提高了系统的稳定性和响应速度。这让我深刻体会到,对于复杂的嵌入式系统,合理的任务划分和资源分配是成功的关键。

其次,数据处理决定AI应用的上限。在语音识别准确率优化过程中,我发现模型本身的质量固然重要,但数据预处理同样关键。VAD算法的鲁棒性、数据居中对齐、动态阈值校准等数据处理环节的优化,对最终识别准确率的提升效果甚至超过更换更复杂的模型。这让我认识到,在资源受限的嵌入式平台上,巧妙的数据处理往往比追求复杂模型更有效。

第三,调试工具和方法的重要性。项目中遇到的切歌进度异常问题,单凭肉眼观察很难定位。通过在关键位置添加串口打印、使用状态机记录变量变化,最终找到了问题根源。这让我学会了系统化的调试方法:复现问题缩小范围观察变量定位原因验证修复。

最后,开源生态的力量。本项目大量使用了开源库和Edge Impulse平台,大大缩短了开发周期。特别是Edge Impulse提供的自动化特征提取和模型部署功能,让没有深厚AI背景的嵌入式开发者也能快速构建智能应用。这让我看到了未来嵌入式AI开发的发展方向——更低的门槛、更高的效率、更丰富的应用场景。

通过这个项目,我不仅掌握了ESP32-S3的开发技巧、语音识别技术的实际应用,更重要的是培养了解决复杂工程问题的思维方式和动手能力。未来,我计划在此基础上增加更多功能,如无线音乐更新、多语言指令识别等,让这个智能音乐播放器更加完善。

 

附件下载
寒假一起练.zip
libraries里是库文件,music_box里是完整代码
团队介绍
仅进击的野猪一人
评论
0 / 100
查看更多
猜你喜欢
制作FPGA电子琴1. 存储一段音乐,并可以进行音乐播放, 2. 可以自己通过板上的按键进行弹奏,支持两个按键同时按下(和弦)并且声音不能失真,板上的按键只有13个,可以通过有上方的“上“、”下”两个按键对音程进行扩展
john
2422
2026寒假练 - 基于ESP32-S3 Sense实现语音点歌音乐盒该项目使用了ESP32-S3 Sense开发板、蜂鸣器、RGB灯带、OLED显示屏、旋转电位计模块,实现了智能语音控制音乐播放系统的设计,它的主要功能为:通过语音指令实现音乐播放、切换、音量调节等功能,配合RGB灯带律动效果和OLED实时显示,打造融合听觉与视觉体验的智能音乐盒系统。支持4首预置曲目播放,通过麦克风关键词识别实现播放、暂停、上/下一首、音量增减等至少5条语音控制指令;RGB灯带可根据音乐节拍呈现动态律动灯效;OLED屏幕实时显示当前曲目编号、播放进度百分比及音量等级;同时支持旋转电位器音量调节,提供多样化的交互方式。
郑睿祺
29
2026寒假练 - 基于ESP32-S3实现语音点歌音乐盒该项目使用了Seeed Studio XIAO ESP32S3 开发板,Arduino语言,实现了语音点歌音乐盒的设计,它的主要功能为:将麦克风的音频数据读出,并通过对语音数据的边缘AI解析,也可以通过网页的控制,在蜂鸣器,LED灯带和OLED上以播放旋律和界面显示的方式制作了一个语音点歌音乐盒。。
一两风
77
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号