diff options
author | Nick Miller <nick.miller.83@gmail.com> | 2021-06-05 17:14:55 -0700 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-06-09 17:30:08 +0430 |
commit | 23d5b99fbfefc92cb4bbef4999cb1da49b0ae61c (patch) | |
tree | 99165374d7c121ee1525b420b8954f5192a935d2 | |
parent | 2a3090d29290222bcd04203111cf3d63afce5451 (diff) | |
download | serenity-23d5b99fbfefc92cb4bbef4999cb1da49b0ae61c.zip |
LibAudio: Make Loader::seek() treat its input as a sample index
This fixes a bug where if you try to play a Wave file a second
time (or loop with `aplay -l`), the second time will be pure
noise.
The function `Audio::Loader::seek` is meant to seek to a specific
audio sample, e.g. seek(0) should go to the first audio sample.
However, WavLoader was interpreting seek(0) as the beginning
of the file or stream, which contains non-audio header data.
This fixes the bug by capturing the byte offset of the start of the
audio data, and offseting the raw file/stream seek by that amount.
-rw-r--r-- | Userland/Libraries/LibAudio/Loader.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibAudio/WavLoader.cpp | 14 | ||||
-rw-r--r-- | Userland/Libraries/LibAudio/WavLoader.h | 6 |
3 files changed, 17 insertions, 6 deletions
diff --git a/Userland/Libraries/LibAudio/Loader.h b/Userland/Libraries/LibAudio/Loader.h index 0050d6acd3..34e65509d4 100644 --- a/Userland/Libraries/LibAudio/Loader.h +++ b/Userland/Libraries/LibAudio/Loader.h @@ -27,7 +27,8 @@ public: virtual RefPtr<Buffer> get_more_samples(size_t max_bytes_to_read_from_input = 128 * KiB) = 0; virtual void reset() = 0; - virtual void seek(const int position) = 0; + + virtual void seek(const int sample_index) = 0; virtual int loaded_samples() = 0; virtual int total_samples() = 0; diff --git a/Userland/Libraries/LibAudio/WavLoader.cpp b/Userland/Libraries/LibAudio/WavLoader.cpp index c65a39c536..e12d04cd2c 100644 --- a/Userland/Libraries/LibAudio/WavLoader.cpp +++ b/Userland/Libraries/LibAudio/WavLoader.cpp @@ -83,13 +83,14 @@ RefPtr<Buffer> WavLoaderPlugin::get_more_samples(size_t max_bytes_to_read_from_i return buffer; } -void WavLoaderPlugin::seek(const int position) +void WavLoaderPlugin::seek(const int sample_index) { - if (position < 0 || position > m_total_samples) + dbgln_if(AWAVLOADER_DEBUG, "seek sample_index {}", sample_index); + if (sample_index < 0 || sample_index >= m_total_samples) return; - m_loaded_samples = position; - size_t byte_position = position * m_num_channels * (pcm_bits_per_sample(m_sample_format) / 8); + m_loaded_samples = sample_index; + size_t byte_position = m_byte_offset_of_data_samples + sample_index * m_num_channels * (pcm_bits_per_sample(m_sample_format) / 8); // AK::InputStream does not define seek. if (m_file) { @@ -105,12 +106,14 @@ bool WavLoaderPlugin::parse_header() return false; bool ok = true; + size_t bytes_read = 0; auto read_u8 = [&]() -> u8 { u8 value; *m_stream >> value; if (m_stream->handle_any_error()) ok = false; + bytes_read += 1; return value; }; @@ -119,6 +122,7 @@ bool WavLoaderPlugin::parse_header() *m_stream >> value; if (m_stream->handle_any_error()) ok = false; + bytes_read += 2; return value; }; @@ -127,6 +131,7 @@ bool WavLoaderPlugin::parse_header() *m_stream >> value; if (m_stream->handle_any_error()) ok = false; + bytes_read += 4; return value; }; @@ -245,6 +250,7 @@ bool WavLoaderPlugin::parse_header() bytes_per_sample, m_total_samples); + m_byte_offset_of_data_samples = bytes_read; return true; } diff --git a/Userland/Libraries/LibAudio/WavLoader.h b/Userland/Libraries/LibAudio/WavLoader.h index 9a768fdea2..3fa84c6ff9 100644 --- a/Userland/Libraries/LibAudio/WavLoader.h +++ b/Userland/Libraries/LibAudio/WavLoader.h @@ -44,7 +44,10 @@ public: virtual RefPtr<Buffer> get_more_samples(size_t max_bytes_to_read_from_input = 128 * KiB) override; virtual void reset() override { return seek(0); } - virtual void seek(const int position) override; + + // sample_index 0 is the start of the raw audio sample data + // within the file/stream. + virtual void seek(const int sample_index) override; virtual int loaded_samples() override { return m_loaded_samples; } virtual int total_samples() override { return m_total_samples; } @@ -66,6 +69,7 @@ private: u32 m_sample_rate { 0 }; u16 m_num_channels { 0 }; PcmSampleFormat m_sample_format; + size_t m_byte_offset_of_data_samples { 0 }; int m_loaded_samples { 0 }; int m_total_samples { 0 }; |