播放本地音频的代码
首先要在芯片存储区建立存储区域,这个加到partitions.csvz最后

spiffs, data, spiffs, 0xD00000, 1M下来就是在CMakeLists.txt中增加自动烧录配置
# 配置 SPIFFS 自动烧录(关键代码)
spiffs_create_partition_image(spiffs data FLASH_IN_PROJECT)音频文件放在data文件夹下面
![]()
这个文件夹是我置顶的烧录到映像区域的文件
下面这个是头文件和配置硬件,我用的是ns416
8
// *************************************************************/#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s_std.h"
#include "driver/gpio.h"
#include "esp_err.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "esp_vfs.h"
#include "esp_spiffs.h" // 添加SPIFFS支持// -------------------------- 配置参数(根据硬件修改) --------------------------
#define I2S_BCLK GPIO_NUM_15 // I2S时钟线引脚
#define I2S_WS GPIO_NUM_16 // I2S声道选择线(LRCK)引脚
#define I2S_DOUT GPIO_NUM_7 // I2S数据输出引脚
#define PLAY_BUFFER_SIZE 2048 // 播放缓冲区大小(2KB,可按需调整)
#define WAV_SAMPLE_RATE 16000 // 目标WAV采样率(16kHz,需与播放文件匹配)
#define WAV_BIT_DEPTH 16 // 目标WAV位深(16bit,需与播放文件匹配)/***************************************************************/下面是播放和测试分区文件的代码
头文件
/*******************************************************/void list_spiffs_files();int init_ok = 0;esp_err_t spiffs_init();// 新增:WAV播放相关配置(需与你的WAV文件匹配)static const int WAV_BUFFER_SIZE = 2048; // 播放缓冲区大小(2KB,可调整)static const int WAV_HEADER_SIZE = 44; // 标准WAV文件头大小(固定44字节)// 新增:核心函数声明(读取WAV并播放)bool read_wav_and_play(const char* wav_path); // 读取WAV文件并调用Write播放/*******************************************************/类文件
void AudioCodec::OutputData(std::vector<int16_t>& data) {//Write(data.data(), data.size());ESP_LOGE(TAG, "++++++++++++OutputData+++++++++++++");// 确保先初始化(只在首次调用时执行)if (this->spiffs_init() != ESP_OK) {return; // 初始化失败则退出}// 2. 调用核心函数:读取WAV并播放(路径替换为你的WAV文件名)const char* wav_path = "/spiffs/hi_idf_audio.wav"; // SPIFFS中的WAV路径this->read_wav_and_play(wav_path);
}
/****************************************************************************/
// -------------------------- SPIFFS初始化 --------------------------
esp_err_t AudioCodec::spiffs_init(void) {if (this->init_ok) return ESP_OK; // 已初始化直接返回// SPIFFS配置(指定spiffs分区)esp_vfs_spiffs_conf_t conf = {.base_path = "/spiffs",.partition_label = "spiffs",.max_files = 5,.format_if_mount_failed = true};// 执行初始化esp_err_t ret = esp_vfs_spiffs_register(&conf);if (ret != ESP_OK) {ESP_LOGE(TAG, "SPIFFS初始化失败: %s", esp_err_to_name(ret));return ret;}this->init_ok = 1; // 标记为已初始化ESP_LOGI(TAG, "SPIFFS初始化成功");// 每次调用都打印文件清单DIR *dir = opendir("/spiffs");if (!dir) {ESP_LOGE(TAG, "无法打开SPIFFS目录");return ret;}struct dirent *entry;int count = 0;ESP_LOGI(TAG, "=== 文件清单 ===");while ((entry = readdir(dir))) {if (entry->d_name[0] == '.') continue; // 跳过.和..ESP_LOGI(TAG, "文件: %s", entry->d_name);count++;}closedir(dir);ESP_LOGI(TAG, "共%d个文件 ====", count);return ESP_OK;
}// 核心函数:读取SPIFFS中的WAV文件,调用Write播放
bool AudioCodec::read_wav_and_play(const char* wav_path) {// 1. 打开WAV文件(SPIFFS路径,只读模式)FILE* wav_fp = fopen(wav_path, "rb");if (wav_fp == NULL) {ESP_LOGE(TAG, "打开WAV失败: %s", wav_path);return false;}// 2. 跳过WAV文件头(前44字节是格式信息,不是PCM数据)if (fseek(wav_fp, WAV_HEADER_SIZE, SEEK_SET) != 0) {ESP_LOGE(TAG, "跳过WAV头失败");fclose(wav_fp);return false;}// 3. 分配缓冲区(栈外分配,避免栈溢出)int16_t* wav_buffer = (int16_t*)malloc(WAV_BUFFER_SIZE);if (wav_buffer == NULL) {ESP_LOGE(TAG, "分配WAV缓冲区失败");fclose(wav_fp);return false;}// 4. 循环读取WAV数据并播放(核心逻辑)size_t read_samples = 0; // 每次读取的PCM样本数(16bit=1个样本)bool play_success = true;while (1) {// 读取数据:fread返回字节数,转成样本数(1样本=2字节)read_samples = fread(wav_buffer, sizeof(int16_t), WAV_BUFFER_SIZE / sizeof(int16_t), wav_fp);if (read_samples == 0) {// 读取到文件末尾,播放完成ESP_LOGI(TAG, "WAV播放完成");break;}// 调用Write函数,将PCM数据写入I2S(播放)int written_samples = Write(wav_buffer, read_samples);if (written_samples != read_samples) {ESP_LOGE(TAG, "播放数据丢失:读取%d样本,写入%d样本", read_samples, written_samples);play_success = false;break;}// (可选)打印播放进度(调试用)ESP_LOGD(TAG, "播放进度:已读%d样本", read_samples);}// 5. 释放资源free(wav_buffer);fclose(wav_fp);return play_success;
}/****************************************************************************/
大体就是这样,因为嵌入别的代码的一部分,不能直接使用,可以借鉴。
