ESP32替换字符switch case实现按名称调用播放大量WAV文件方案咨询
方案1:直接传入文件名调用(最灵活,符合你要的playWAV(filename)需求)
直接修改playWAV函数的参数类型,不需要维护映射关系,新增WAV文件只要丢进SD卡对应目录即可直接调用:
// 函数第一个参数改为const char*类型,传入不带后缀的文件名 void playWAV (const char* effectName, int bg1248_general_volume) { Serial.println("Entered playWAV"); // 拼接完整SD卡路径 char filePath[64]; snprintf(filePath, sizeof(filePath), "/wav/%s.wav", effectName); file = new AudioFileSourceSD(filePath); // 新增文件存在判断,避免传错文件名导致程序崩溃 if (!file->isOpen()) { Serial.printf("文件不存在:%s\n", filePath); delete file; return; } float volumeGain = ((float)bg1248_general_volume / 100.0) * 39.0; Serial.print("volumeGain:"); Serial.println(volumeGain); id3 = new AudioFileSourceID3(file); out = new AudioOutputI2S(0, 0); // Output to builtInDAC out->SetPinout(12, 0, 2); out->SetOutputModeMono(true); out->SetGain(volumeGain); wav = new AudioGeneratorWAV(); wav->begin(id3, out); }
调用方式完全符合你的预期,原来的playWAV('a', 100)直接改成:
playWAV("alarm", 100);
后续新增WAV文件不需要修改函数内部代码,只要把xxx.wav放入SD卡的/wav目录,直接调用playWAV("xxx", 音量)即可。
方案2:枚举+映射数组(更严谨,避免写错文件名)
如果担心拼写字符串出错,可以用枚举做统一管理,编译期就能检查参数合法性:
- 先全局定义音频枚举和对应文件名映射:
// 定义所有音频效果的枚举,新增文件只要在这里加项即可,支持上千个都没问题 enum AudioEffect { EFFECT_ALARM, EFFECT_ALARM_HIGH, EFFECT_ALARM_LOW, EFFECT_ERROR, EFFECT_ERROR1, EFFECT_NO_READ, // 在这里新增71个新的音频枚举项即可 EFFECT_MAX // 用来做边界校验 }; // 枚举和文件名的映射表,顺序要和上面的枚举完全对应 const char* g_effectFileMap[] = { "alarm", "alarmhigh", "alarmlow", "error", "error1", "noread", // 对应上面枚举的顺序补充文件名即可 };
- 修改
playWAV函数:
void playWAV (AudioEffect effect, int bg1248_general_volume) { Serial.println("Entered playWAV"); // 先做参数合法校验 if (effect < 0 || effect >= EFFECT_MAX) { Serial.println("无效的音频效果参数"); return; } // 拼接路径 char filePath[64]; snprintf(filePath, sizeof(filePath), "/wav/%s.wav", g_effectFileMap[effect]); file = new AudioFileSourceSD(filePath); if (!file->isOpen()) { Serial.printf("文件不存在:%s\n", filePath); delete file; return; } // 后面的音量设置、播放逻辑和原来完全一致 float volumeGain = ((float)bg1248_general_volume / 100.0) * 39.0; Serial.print("volumeGain:"); Serial.println(volumeGain); id3 = new AudioFileSourceID3(file); out = new AudioOutputI2S(0, 0); out->SetPinout(12, 0, 2); out->SetOutputModeMono(true); out->SetGain(volumeGain); wav = new AudioGeneratorWAV(); wav->begin(id3, out); }
调用示例:
playWAV(EFFECT_ALARM, 100);
你之前用enum报case重复的错误,大概率是枚举项定义了重复的数值,按上面的方式顺序定义枚举、不手动赋值的话,编译器会自动从0开始递增赋值,不会出现重复问题。
额外注意事项
你当前代码里new出来的AudioFileSourceSD、AudioFileSourceID3、AudioOutputI2S、AudioGeneratorWAV对象,要记得在播放完成后手动delete释放内存,ESP32的堆内存很小,长期不释放会出现内存泄漏导致程序崩溃。
内容的提问来源于stack exchange,提问作者Krystal Shaw
相关产品推荐
相关产品推荐

