summaryrefslogtreecommitdiff
path: root/Libraries/LibAudio
diff options
context:
space:
mode:
authorRobin Burchell <robin+git@viroteck.net>2019-07-18 13:24:01 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-07-18 13:45:10 +0200
commita2fbfb6cefadefe98502ab87f2cae002b33d2319 (patch)
tree16dd1b1c4a7be0081306ab8e8cb733d4debb210e /Libraries/LibAudio
parent7de79d3bbbde63b121eb60f7a35715ef5b5a5ee7 (diff)
downloadserenity-a2fbfb6cefadefe98502ab87f2cae002b33d2319.zip
AWavLoader: Support 24 bit wav files (mono & stereo)
Diffstat (limited to 'Libraries/LibAudio')
-rw-r--r--Libraries/LibAudio/AWavLoader.cpp55
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();
}