From c5bf0d94f9ba347c9d11d7d03d3c6094b67cab85 Mon Sep 17 00:00:00 2001 From: Mark Thompson <129641948+NotherNgineer@users.noreply.github.com> Date: Wed, 7 Feb 2024 14:37:49 -0600 Subject: [PATCH] Skip over INFO chunk in WAV files (#1862) --- firmware/application/io_wave.cpp | 37 ++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/firmware/application/io_wave.cpp b/firmware/application/io_wave.cpp index 2b6cd862..a7837d34 100644 --- a/firmware/application/io_wave.cpp +++ b/firmware/application/io_wave.cpp @@ -27,8 +27,10 @@ bool WAVFileReader::open(const std::filesystem::path& path) { size_t i = 0; char ch; const uint8_t tag_INAM[4] = {'I', 'N', 'A', 'M'}; + const uint8_t tag_data[4] = {'d', 'a', 't', 'a'}; + struct data_t data_header; char title_buffer[32]{0}; - uint32_t riff_size, data_end, title_size; + uint32_t riff_size, inam_search_start, title_size; size_t search_limit = 0; // Already open ? @@ -45,17 +47,34 @@ bool WAVFileReader::open(const std::filesystem::path& path) { auto error = file_.open(path); if (!error.is_valid()) { - file_.read((void*)&header, sizeof(header)); // Read header (RIFF and WAVE) + if (!file_.read((void*)&header, sizeof(header)).is_ok()) // Read header (RIFF and WAVE) + return false; - // TODO: Work needed here to process RIFF file format correctly, i.e. properly skip over LIST & INFO chunks - riff_size = header.cksize + 8; - data_start = header.fmt.cksize + 28; - data_size_ = header.data.cksize; - data_end = data_start + data_size_ + 1; + // Assuming here that RIFF & WAV & fmt chunk ID's are all correct... + riff_size = 8 + header.cksize; + + // check for the "data" chunk ID + if (memcmp(header.data.ckID, tag_data, 4) == 0) { + data_start = 20 + header.fmt.cksize + 8; + data_size_ = header.data.cksize; + inam_search_start = data_start + data_size_; + } else { + // data header wasn't where we guessed; skip over one unexpected chunk (perhaps LIST/INFO/INAM) + inam_search_start = 20 + header.fmt.cksize; + file_.seek(20 + header.fmt.cksize + 8 + header.data.cksize); + if (!file_.read((void*)&data_header, sizeof(data_header)).is_ok()) + return false; + + if (memcmp(data_header.ckID, tag_data, 4) == 0) { + data_start = 20 + header.fmt.cksize + 8 + header.data.cksize + 8; + data_size_ = data_header.cksize; + } else + return false; + } // Look for INAM (title) tag - if (data_end < riff_size) { - file_.seek(data_end); + if (inam_search_start < riff_size) { + file_.seek(inam_search_start); while (file_.read((void*)&ch, 1).is_ok()) { if (ch == tag_INAM[i++]) { if (i == 4) {