@@ -138,21 +138,6 @@ bool WaveAudioFormatReader::readSamples (float* const* destChannels,
138138 const auto bytesPerSample = bitsPerSample / 8 ;
139139 const auto bytesPerFrame = numChannels * bytesPerSample;
140140
141- // Read the data
142- const auto framesToRead = (drwav_uint64) numSamples;
143- const auto bytesToRead = framesToRead * bytesPerFrame;
144-
145- if (bytesToRead > tempBufferSize)
146- {
147- tempBufferSize = bytesToRead;
148- tempBuffer.allocate (bytesToRead, false );
149- }
150-
151- const auto framesRead = drwav_read_pcm_frames (&wav, framesToRead, tempBuffer.getData ());
152-
153- if (framesRead == 0 )
154- return false ;
155-
156141 // Create output channel pointers offset by the start position
157142 HeapBlock<float *> offsetDestChannels;
158143 offsetDestChannels.malloc (numDestChannels);
@@ -162,68 +147,114 @@ bool WaveAudioFormatReader::readSamples (float* const* destChannels,
162147 offsetDestChannels[ch] = destChannels[ch] + startOffsetInDestBuffer;
163148 }
164149
165- // Use AudioData::deinterleaveSamples to convert and deinterleave in one step
166- if (bitsPerSample == 8 )
150+ drwav_uint64 framesRead;
151+
152+ // Handle A-law and μ-law formats using dr_wav's specialized float conversion
153+ if (wav.translatedFormatTag == DR_WAVE_FORMAT_ALAW || wav.translatedFormatTag == DR_WAVE_FORMAT_MULAW)
167154 {
168- using SourceFormat = AudioData::Format<AudioData::UInt8, AudioData::LittleEndian>;
169- using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
155+ // For companded formats, use dr_wav's direct float conversion which handles the decompanding properly
156+ const auto framesToRead = (drwav_uint64) numSamples;
157+ const auto floatsToRead = framesToRead * numChannels;
170158
171- AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const uint8*> (tempBuffer.getData ()), (int ) numChannels },
172- AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels.getData (), numDestChannels },
173- (int ) framesRead);
174- }
175- else if (bitsPerSample == 16 )
176- {
177- using SourceFormat = AudioData::Format<AudioData::Int16, AudioData::LittleEndian>;
178- using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
159+ if (floatsToRead * sizeof (float ) > tempBufferSize)
160+ {
161+ tempBufferSize = floatsToRead * sizeof (float );
162+ tempBuffer.allocate (tempBufferSize, false );
163+ }
179164
180- AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const uint16 *> (tempBuffer.getData ()), ( int ) numChannels },
181- AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels. getData (), numDestChannels },
182- ( int ) framesRead);
183- }
184- else if (bitsPerSample == 24 )
185- {
186- using SourceFormat = AudioData::Format<AudioData::Int24 , AudioData::LittleEndian >;
165+ framesRead = drwav_read_pcm_frames_f32 (&wav, framesToRead, reinterpret_cast <float *> (tempBuffer.getData ()));
166+
167+ if (framesRead == 0 )
168+ return false ;
169+
170+ // Deinterleave the float data directly
171+ using SourceFormat = AudioData::Format<AudioData::Float32 , AudioData::NativeEndian >;
187172 using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
188173
189- AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const char *> (tempBuffer.getData ()), (int ) numChannels },
174+ AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const float *> (tempBuffer.getData ()), (int ) numChannels },
190175 AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels.getData (), numDestChannels },
191176 (int ) framesRead);
192177 }
193- else if (bitsPerSample == 32 )
178+ else
194179 {
195- if (usesFloatingPointData)
180+ // For all other formats, use the existing approach with raw data and AudioData conversion
181+ const auto framesToRead = (drwav_uint64) numSamples;
182+ const auto bytesToRead = framesToRead * bytesPerFrame;
183+
184+ if (bytesToRead > tempBufferSize)
196185 {
197- using SourceFormat = AudioData::Format<AudioData::Float32, AudioData::LittleEndian>;
186+ tempBufferSize = bytesToRead;
187+ tempBuffer.allocate (bytesToRead, false );
188+ }
189+
190+ framesRead = drwav_read_pcm_frames (&wav, framesToRead, tempBuffer.getData ());
191+
192+ if (framesRead == 0 )
193+ return false ;
194+
195+ // Use AudioData::deinterleaveSamples to convert and deinterleave in one step
196+ if (bitsPerSample == 8 )
197+ {
198+ using SourceFormat = AudioData::Format<AudioData::UInt8, AudioData::LittleEndian>;
198199 using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
199200
200- AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const float *> (tempBuffer.getData ()), (int ) numChannels },
201+ AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const uint8 *> (tempBuffer.getData ()), (int ) numChannels },
201202 AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels.getData (), numDestChannels },
202203 (int ) framesRead);
203204 }
204- else
205+ else if (bitsPerSample == 16 )
205206 {
206- using SourceFormat = AudioData::Format<AudioData::Int32 , AudioData::LittleEndian>;
207+ using SourceFormat = AudioData::Format<AudioData::Int16 , AudioData::LittleEndian>;
207208 using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
208209
209- AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const uint32 *> (tempBuffer.getData ()), (int ) numChannels },
210+ AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const uint16 *> (tempBuffer.getData ()), (int ) numChannels },
210211 AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels.getData (), numDestChannels },
211212 (int ) framesRead);
212213 }
213- }
214- else if (bitsPerSample == 64 && usesFloatingPointData)
215- {
216- // Handle 64-bit double precision float samples using AudioData
217- using SourceFormat = AudioData::Format<AudioData::Float64, AudioData::LittleEndian>;
218- using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
219-
220- AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const double *> (tempBuffer.getData ()), (int ) numChannels },
221- AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels.getData (), numDestChannels },
222- (int ) framesRead);
223- }
224- else
225- {
226- return false ;
214+ else if (bitsPerSample == 24 )
215+ {
216+ using SourceFormat = AudioData::Format<AudioData::Int24, AudioData::LittleEndian>;
217+ using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
218+
219+ AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const char *> (tempBuffer.getData ()), (int ) numChannels },
220+ AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels.getData (), numDestChannels },
221+ (int ) framesRead);
222+ }
223+ else if (bitsPerSample == 32 )
224+ {
225+ if (usesFloatingPointData)
226+ {
227+ using SourceFormat = AudioData::Format<AudioData::Float32, AudioData::LittleEndian>;
228+ using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
229+
230+ AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const float *> (tempBuffer.getData ()), (int ) numChannels },
231+ AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels.getData (), numDestChannels },
232+ (int ) framesRead);
233+ }
234+ else
235+ {
236+ using SourceFormat = AudioData::Format<AudioData::Int32, AudioData::LittleEndian>;
237+ using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
238+
239+ AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const uint32*> (tempBuffer.getData ()), (int ) numChannels },
240+ AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels.getData (), numDestChannels },
241+ (int ) framesRead);
242+ }
243+ }
244+ else if (bitsPerSample == 64 && usesFloatingPointData)
245+ {
246+ // Handle 64-bit double precision float samples using AudioData
247+ using SourceFormat = AudioData::Format<AudioData::Float64, AudioData::LittleEndian>;
248+ using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
249+
250+ AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { reinterpret_cast <const double *> (tempBuffer.getData ()), (int ) numChannels },
251+ AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels.getData (), numDestChannels },
252+ (int ) framesRead);
253+ }
254+ else
255+ {
256+ return false ;
257+ }
227258 }
228259
229260 return true ;
0 commit comments