diff --git a/components/esp-box/example/main/esp_box_example.cpp b/components/esp-box/example/main/esp_box_example.cpp index 2e919e06e..e8f9cb33b 100644 --- a/components/esp-box/example/main/esp_box_example.cpp +++ b/components/esp-box/example/main/esp_box_example.cpp @@ -18,7 +18,7 @@ static std::recursive_mutex lvgl_mutex; static void draw_circle(int x0, int y0, int radius); static void clear_circles(); -static size_t load_audio(); +static bool load_audio(size_t &out_size, size_t &out_sample_rate); static void play_click(espp::EspBox &box); extern "C" void app_main(void) { @@ -209,9 +209,17 @@ extern "C" void app_main(void) { lv_task.start(); // load the audio file (wav file bundled in memory) - size_t wav_size = load_audio(); + size_t wav_size = 0; + size_t wav_sample_rate = 0; + if (!load_audio(wav_size, wav_sample_rate)) { + logger.error("Failed to load audio file!"); + return; + } logger.info("Loaded {} bytes of audio", wav_size); + logger.info("Setting audio sample rate to {} Hz", wav_sample_rate); + box.audio_sample_rate(wav_sample_rate); + // unmute the audio and set the volume to 60% box.mute(false); box.volume(60.0f); @@ -374,10 +382,10 @@ static void clear_circles() { circles.clear(); } -static size_t load_audio() { +static bool load_audio(size_t &out_size, size_t &out_sample_rate) { // if the audio_bytes vector is already populated, return the size if (audio_bytes.size() > 0) { - return audio_bytes.size(); + return true; } // load the audio data. these are configured in the CMakeLists.txt file @@ -387,7 +395,21 @@ static size_t load_audio() { // cppcheck-suppress syntaxError extern const uint8_t click_wav_end[] asm("_binary_click_wav_end"); audio_bytes = std::vector(click_wav_start, click_wav_end); - return audio_bytes.size(); + // ensure we have at least a wav header + if (audio_bytes.size() < 44) { + audio_bytes.clear(); + return false; + } + // get the sample rate from the wav header (bytes 24-27) + uint32_t sample_rate = *(reinterpret_cast(&audio_bytes[24])); + // set the audio sample rate accordingly + // decode the wav file header (first 44 bytes) and remove it + if (audio_bytes.size() > 44) { + audio_bytes.erase(audio_bytes.begin(), audio_bytes.begin() + 44); + } + out_size = audio_bytes.size(); + out_sample_rate = sample_rate; + return true; } static void play_click(espp::EspBox &box) { diff --git a/components/m5stack-tab5/example/main/m5stack_tab5_example.cpp b/components/m5stack-tab5/example/main/m5stack_tab5_example.cpp index fa8664837..141f5c97c 100644 --- a/components/m5stack-tab5/example/main/m5stack_tab5_example.cpp +++ b/components/m5stack-tab5/example/main/m5stack_tab5_example.cpp @@ -27,7 +27,7 @@ static std::recursive_mutex lvgl_mutex; static void draw_circle(int x0, int y0, int radius); static void clear_circles(); -static size_t load_audio(); +static bool load_audio(size_t &out_size, size_t &out_sample_rate); static void play_click(espp::M5StackTab5 &tab5); extern "C" void app_main(void) { @@ -321,10 +321,17 @@ extern "C" void app_main(void) { }}); lv_task.start(); - // load the audio and play it once as a test - logger.info("Loading audio..."); - auto num_bytes_loaded = load_audio(); - logger.info("Loaded {} bytes of audio", num_bytes_loaded); + // load the audio file (wav file bundled in memory) + size_t wav_size = 0; + size_t wav_sample_rate = 0; + if (!load_audio(wav_size, wav_sample_rate)) { + logger.error("Failed to load audio file!"); + return; + } + logger.info("Loaded {} bytes of audio", wav_size); + + logger.info("Setting audio sample rate to {} Hz", wav_sample_rate); + tab5.audio_sample_rate(wav_sample_rate); // unmute the audio and set the volume to 60% tab5.mute(false); @@ -512,10 +519,10 @@ static void clear_circles() { circles.clear(); } -static size_t load_audio() { +static bool load_audio(size_t &out_size, size_t &out_sample_rate) { // if the audio_bytes vector is already populated, return the size if (audio_bytes.size() > 0) { - return audio_bytes.size(); + return true; } // load the audio data. these are configured in the CMakeLists.txt file @@ -525,7 +532,21 @@ static size_t load_audio() { // cppcheck-suppress syntaxError extern const uint8_t click_wav_end[] asm("_binary_click_wav_end"); audio_bytes = std::vector(click_wav_start, click_wav_end); - return audio_bytes.size(); + // ensure we have at least a wav header + if (audio_bytes.size() < 44) { + audio_bytes.clear(); + return false; + } + // get the sample rate from the wav header (bytes 24-27) + uint32_t sample_rate = *(reinterpret_cast(&audio_bytes[24])); + // set the audio sample rate accordingly + // decode the wav file header (first 44 bytes) and remove it + if (audio_bytes.size() > 44) { + audio_bytes.erase(audio_bytes.begin(), audio_bytes.begin() + 44); + } + out_size = audio_bytes.size(); + out_sample_rate = sample_rate; + return true; } static void play_click(espp::M5StackTab5 &tab5) { diff --git a/components/t-deck/example/main/t_deck_example.cpp b/components/t-deck/example/main/t_deck_example.cpp index 48fa5597b..5bd27d87f 100644 --- a/components/t-deck/example/main/t_deck_example.cpp +++ b/components/t-deck/example/main/t_deck_example.cpp @@ -14,7 +14,7 @@ static std::recursive_mutex lvgl_mutex; static void draw_circle(int x0, int y0, int radius); static void clear_circles(); -static size_t load_audio(); +static bool load_audio(size_t &out_size, size_t &out_sample_rate); static void play_click(espp::TDeck &tdeck); LV_IMG_DECLARE(mouse_cursor_icon); @@ -180,9 +180,17 @@ extern "C" void app_main(void) { lv_task.start(); // load the audio file (wav file bundled in memory) - size_t wav_size = load_audio(); + size_t wav_size = 0; + size_t wav_sample_rate = 0; + if (!load_audio(wav_size, wav_sample_rate)) { + logger.error("Failed to load audio file!"); + return; + } logger.info("Loaded {} bytes of audio", wav_size); + logger.info("Setting audio sample rate to {} Hz", wav_sample_rate); + tdeck.audio_sample_rate(wav_sample_rate); + // unmute the audio and set the volume to 20% tdeck.mute(false); tdeck.volume(20.0f); @@ -223,10 +231,10 @@ static void clear_circles() { circles.clear(); } -static size_t load_audio() { +static bool load_audio(size_t &out_size, size_t &out_sample_rate) { // if the audio_bytes vector is already populated, return the size if (audio_bytes.size() > 0) { - return audio_bytes.size(); + return true; } // load the audio data. these are configured in the CMakeLists.txt file @@ -236,7 +244,21 @@ static size_t load_audio() { // cppcheck-suppress syntaxError extern const uint8_t click_wav_end[] asm("_binary_click_wav_end"); audio_bytes = std::vector(click_wav_start, click_wav_end); - return audio_bytes.size(); + // ensure we have at least a wav header + if (audio_bytes.size() < 44) { + audio_bytes.clear(); + return false; + } + // get the sample rate from the wav header (bytes 24-27) + uint32_t sample_rate = *(reinterpret_cast(&audio_bytes[24])); + // set the audio sample rate accordingly + // decode the wav file header (first 44 bytes) and remove it + if (audio_bytes.size() > 44) { + audio_bytes.erase(audio_bytes.begin(), audio_bytes.begin() + 44); + } + out_size = audio_bytes.size(); + out_sample_rate = sample_rate; + return true; } static void play_click(espp::TDeck &tdeck) {