diff options
author | Robin Burchell <robin+git@viroteck.net> | 2019-07-18 13:24:01 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-07-18 13:45:10 +0200 |
commit | a2fbfb6cefadefe98502ab87f2cae002b33d2319 (patch) | |
tree | 16dd1b1c4a7be0081306ab8e8cb733d4debb210e /Libraries/LibAudio | |
parent | 7de79d3bbbde63b121eb60f7a35715ef5b5a5ee7 (diff) | |
download | serenity-a2fbfb6cefadefe98502ab87f2cae002b33d2319.zip |
AWavLoader: Support 24 bit wav files (mono & stereo)
Diffstat (limited to 'Libraries/LibAudio')
-rw-r--r-- | Libraries/LibAudio/AWavLoader.cpp | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/Libraries/LibAudio/AWavLoader.cpp b/Libraries/LibAudio/AWavLoader.cpp index e33200964f..5695246ec4 100644 --- a/Libraries/LibAudio/AWavLoader.cpp +++ b/Libraries/LibAudio/AWavLoader.cpp @@ -83,8 +83,8 @@ RefPtr<ABuffer> AWavLoader::parse_wav(ByteBuffer& buffer) u16 bits_per_sample; stream >> bits_per_sample; CHECK_OK("Bits per sample"); // incomplete read check - ok = ok && (bits_per_sample == 8 || bits_per_sample == 16); - ASSERT(bits_per_sample == 8 || bits_per_sample == 16); + ok = ok && (bits_per_sample == 8 || bits_per_sample == 16 || bits_per_sample == 24); + ASSERT(bits_per_sample == 8 || bits_per_sample == 16 || bits_per_sample == 24); CHECK_OK("Bits per sample"); // value check // Read chunks until we find DATA @@ -190,6 +190,54 @@ static void read_samples_from_stream(BufferStream& stream, Vector<ASample>& samp } } +static void read_24bit_samples_from_stream(BufferStream& stream, Vector<ASample>& samples, int num_channels, int source_rate) +{ + AResampleHelper resampler(source_rate, 44100); + + auto read_norm_sample = [&stream]() { + u8 byte = 0; + stream >> byte; + u32 sample1 = byte; + stream >> byte; + u32 sample2 = byte; + stream >> byte; + u32 sample3 = byte; + + i32 value = 0; + value = sample1 << 8; + value |= (sample2 << 16); + value |= (sample3 << 24); + return float(value) / std::numeric_limits<i32>::max(); + }; + + float norm_l = 0; + float norm_r = 0; + + switch (num_channels) { + case 1: + while (!stream.handle_read_failure()) { + resampler.prepare(); + while (resampler.read_sample()) { + norm_l = read_norm_sample(); + } + samples.append(ASample(norm_l)); + } + break; + case 2: + while (!stream.handle_read_failure()) { + resampler.prepare(); + while (resampler.read_sample()) { + norm_l = read_norm_sample(); + norm_r = read_norm_sample(); + } + samples.append(ASample(norm_l, norm_r)); + } + break; + default: + ASSERT_NOT_REACHED(); + } +} + // ### can't const this because BufferStream is non-const // perhaps we need a reading class separate from the writing one, that can be // entirely consted. @@ -208,6 +256,9 @@ RefPtr<ABuffer> ABuffer::from_pcm_data(ByteBuffer& data, int num_channels, int b case 16: read_samples_from_stream<i16>(stream, fdata, num_channels, source_rate); break; + case 24: + read_24bit_samples_from_stream(stream, fdata, num_channels, source_rate); + break; default: ASSERT_NOT_REACHED(); } |