@@ -143,32 +143,52 @@ class FlacAudioFormatReader : public AudioFormatReader
143143 void * clientData)
144144 {
145145 auto * reader = static_cast <FlacAudioFormatReader*> (clientData);
146- if (reader == nullptr || frame == nullptr || buffer == nullptr || reader-> currentReadState == nullptr )
146+ if (reader == nullptr || frame == nullptr || buffer == nullptr )
147147 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
148148
149- auto & state = *reader->currentReadState ;
150149 const int samplesAvailable = (int ) frame->header .blocksize ;
151- const int samplesRemaining = state.numSamples - state.samplesWritten ;
152- const int samplesToCopy = jmin (samplesAvailable, samplesRemaining);
150+ const int numChannels = reader->numChannels ;
153151
154- if (samplesToCopy <= 0 )
155- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
152+ if (reader->currentReadState != nullptr )
153+ {
154+ auto & state = *reader->currentReadState ;
155+ const int samplesRemaining = state.numSamples - state.samplesWritten ;
156+ const int samplesToCopy = jmin (samplesAvailable, samplesRemaining);
157+
158+ if (samplesToCopy <= 0 )
159+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
160+
161+ const int numChannelsToCopy = jmin (state.numDestChannels , numChannels);
162+
163+ for (int ch = 0 ; ch < numChannelsToCopy; ++ch)
164+ {
165+ if (state.destChannels [ch] == nullptr )
166+ continue ;
156167
157- const int numChannelsToCopy = jmin (state.numDestChannels , reader->numChannels );
168+ float * dest = state.destChannels [ch] + state.startOffset + state.samplesWritten ;
169+ const FLAC__int32* src = buffer[ch];
158170
159- for (int ch = 0 ; ch < numChannelsToCopy; ++ch)
171+ for (int i = 0 ; i < samplesToCopy; ++i)
172+ dest[i] = flacIntToFloat (src[i], reader->bitsPerSample );
173+ }
174+
175+ state.samplesWritten += samplesToCopy;
176+ }
177+ else if (numChannels > 0 && samplesAvailable > 0 )
160178 {
161- if (state. destChannels [ch] == nullptr )
162- continue ;
179+ const size_t startIndex = reader-> interleavedSamples . size ();
180+ reader-> interleavedSamples . resize (startIndex + ( size_t ) samplesAvailable * ( size_t ) numChannels) ;
163181
164- float * dest = state.destChannels [ch] + state.startOffset + state.samplesWritten ;
165- const FLAC__int32* src = buffer[ch];
182+ float * dest = reader->interleavedSamples .data () + startIndex;
166183
167- for (int i = 0 ; i < samplesToCopy; ++i)
168- dest[i] = flacIntToFloat (src[i], reader->bitsPerSample );
184+ for (int i = 0 ; i < samplesAvailable; ++i)
185+ {
186+ const size_t baseIndex = (size_t ) i * (size_t ) numChannels;
187+ for (int ch = 0 ; ch < numChannels; ++ch)
188+ dest[baseIndex + (size_t ) ch] = flacIntToFloat (buffer[ch][i], reader->bitsPerSample );
189+ }
169190 }
170191
171- state.samplesWritten += samplesToCopy;
172192 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
173193 }
174194
@@ -219,6 +239,7 @@ class FlacAudioFormatReader : public AudioFormatReader
219239
220240 FLAC__StreamDecoder* decoder = nullptr ;
221241 ReadState* currentReadState = nullptr ;
242+ std::vector<float > interleavedSamples;
222243 bool isOpen = false ;
223244
224245 YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacAudioFormatReader)
@@ -227,7 +248,7 @@ class FlacAudioFormatReader : public AudioFormatReader
227248FlacAudioFormatReader::FlacAudioFormatReader (InputStream* sourceStream)
228249 : AudioFormatReader (sourceStream, " FLAC audio" )
229250{
230- usesFloatingPointData = false ;
251+ usesFloatingPointData = true ;
231252
232253 if (sourceStream == nullptr )
233254 return ;
@@ -256,7 +277,17 @@ FlacAudioFormatReader::FlacAudioFormatReader (InputStream* sourceStream)
256277 if (! FLAC__stream_decoder_process_until_end_of_metadata (decoder))
257278 return ;
258279
280+ if (! FLAC__stream_decoder_process_until_end_of_stream (decoder))
281+ return ;
282+
283+ if (numChannels > 0 )
284+ lengthInSamples = (int64) (interleavedSamples.size () / (size_t ) numChannels);
285+
259286 isOpen = sampleRate > 0 && numChannels > 0 && bitsPerSample > 0 ;
287+
288+ FLAC__stream_decoder_finish (decoder);
289+ FLAC__stream_decoder_delete (decoder);
290+ decoder = nullptr ;
260291}
261292
262293FlacAudioFormatReader::~FlacAudioFormatReader ()
@@ -274,7 +305,7 @@ bool FlacAudioFormatReader::readSamples (float* const* destChannels,
274305 int64 startSampleInFile,
275306 int numSamples)
276307{
277- if (! isOpen || decoder == nullptr )
308+ if (! isOpen)
278309 return false ;
279310
280311 if (numSamples <= 0 )
@@ -283,64 +314,51 @@ bool FlacAudioFormatReader::readSamples (float* const* destChannels,
283314 if (startSampleInFile < 0 )
284315 return false ;
285316
286- int64 availableSamples = lengthInSamples > 0 ? (lengthInSamples - startSampleInFile) : numSamples;
287- const int samplesToRead = ( int ) jmax<int64> ( 0 , jmin<int64> (availableSamples, numSamples)) ;
317+ if (lengthInSamples <= 0 || interleavedSamples. empty ())
318+ return false ;
288319
289- if (samplesToRead <= 0 )
320+ if (startSampleInFile < 0 || startSampleInFile >= lengthInSamples )
290321 return false ;
291322
292- if (! FLAC__stream_decoder_seek_absolute (decoder, (FLAC__uint64) startSampleInFile))
323+ const auto numChannelsToRead = jmin (numDestChannels, numChannels);
324+ const auto availableSamples = (int64) lengthInSamples - startSampleInFile;
325+ const auto samplesToCopy = (int ) jmin<int64> (availableSamples, numSamples);
326+
327+ if (samplesToCopy <= 0 )
293328 return false ;
294329
295- ReadState state;
296- state.destChannels = destChannels;
297- state.numDestChannels = numDestChannels;
298- state.startOffset = startOffsetInDestBuffer;
299- state.numSamples = samplesToRead;
300- state.samplesWritten = 0 ;
301- currentReadState = &state;
330+ HeapBlock<float *> offsetDestChannels;
331+ offsetDestChannels.malloc (numDestChannels);
302332
303- while (state.samplesWritten < samplesToRead)
304- {
305- if (! FLAC__stream_decoder_process_single (decoder))
306- break ;
333+ for (int ch = 0 ; ch < numDestChannels; ++ch)
334+ offsetDestChannels[ch] = destChannels[ch] + startOffsetInDestBuffer;
307335
308- const auto decoderState = FLAC__stream_decoder_get_state (decoder);
309- if (decoderState == FLAC__STREAM_DECODER_END_OF_STREAM)
310- break ;
311- }
336+ const size_t interleavedOffset = (size_t ) startSampleInFile * (size_t ) numChannels;
337+ const float * interleavedStart = interleavedSamples.data () + interleavedOffset;
312338
313- currentReadState = nullptr ;
339+ using SourceFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
340+ using DestFormat = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
314341
315- const int numChannelsToCopy = jmin (numDestChannels, numChannels);
316- const int missingSamples = samplesToRead - state.samplesWritten ;
342+ AudioData::deinterleaveSamples (AudioData::InterleavedSource<SourceFormat> { interleavedStart, (int ) numChannels },
343+ AudioData::NonInterleavedDest<DestFormat> { offsetDestChannels.getData (), numChannelsToRead },
344+ samplesToCopy);
317345
318- if (missingSamples > 0 )
346+ if (numDestChannels > numChannelsToRead )
319347 {
320- for (int ch = 0 ; ch < numChannelsToCopy; ++ch)
321- if (destChannels[ch] != nullptr )
322- zeromem (destChannels[ch] + startOffsetInDestBuffer + state.samplesWritten ,
323- sizeof (float ) * (size_t ) missingSamples);
348+ for (int ch = numChannelsToRead; ch < numDestChannels; ++ch)
349+ if (offsetDestChannels[ch] != nullptr )
350+ zeromem (offsetDestChannels[ch], sizeof (float ) * (size_t ) samplesToCopy);
324351 }
325352
326- if (numSamples > samplesToRead )
353+ if (samplesToCopy < numSamples )
327354 {
328- const int remainder = numSamples - samplesToRead ;
355+ const auto remaining = numSamples - samplesToCopy ;
329356 for (int ch = 0 ; ch < numDestChannels; ++ch)
330- if (destChannels[ch] != nullptr )
331- zeromem (destChannels[ch] + startOffsetInDestBuffer + samplesToRead,
332- sizeof (float ) * (size_t ) remainder);
333- }
334-
335- if (numDestChannels > numChannelsToCopy)
336- {
337- for (int ch = numChannelsToCopy; ch < numDestChannels; ++ch)
338- if (destChannels[ch] != nullptr )
339- zeromem (destChannels[ch] + startOffsetInDestBuffer,
340- sizeof (float ) * (size_t ) numSamples);
357+ if (offsetDestChannels[ch] != nullptr )
358+ zeromem (offsetDestChannels[ch] + samplesToCopy, sizeof (float ) * (size_t ) remaining);
341359 }
342360
343- return state. samplesWritten > 0 ;
361+ return true ;
344362}
345363
346364// ==============================================================================
0 commit comments