@@ -1108,6 +1108,13 @@ bool PerformSeek() noexcept
11081108 continue ;
11091109 }
11101110
1111+ os_log_debug (log_, " Dequeued %{public}@" , decoderState->decoder_ );
1112+ }
1113+ }
1114+
1115+ if (decoderState) {
1116+ // Before decoding starts determine the decoder and ring buffer format compatibility
1117+ if (!(decoderState->flags_ .load (std::memory_order_acquire) & static_cast <unsigned int >(DecoderState::Flags::decodingStarted))) {
11111118 // Start decoding immediately if the join will be gapless (same sample rate, channel count, and channel layout)
11121119 if (auto renderFormat = decoderState->converter_ .outputFormat ; [renderFormat isEqual: [sourceNode_ outputFormatForBus: 0 ]]) {
11131120 // Allocate the buffer that is the intermediary between the decoder state and the ring buffer
@@ -1125,44 +1132,42 @@ bool PerformSeek() noexcept
11251132 // decoding can't start until the processing graph is reconfigured which occurs after
11261133 // all active decoders complete
11271134 flags_.fetch_or (static_cast <unsigned int >(Flags::formatMismatch), std::memory_order_acq_rel);
1128-
1129- os_log_debug (log_, " Dequeued %{public}@" , decoderState->decoder_ );
11301135 }
1131- }
11321136
1133- // If there a format mismatch the processing graph requires reconfiguration before decoding can begin
1134- if (decoderState && (flags_.load (std::memory_order_acquire) & static_cast <unsigned int >(Flags::formatMismatch))) {
1135- // Wait until all other decoders complete processing before reconfiguring the graph
1136- const auto okToReconfigure = [&] {
1137- std::lock_guard lock{activeDecodersLock_};
1138- return activeDecoders_.size () == 1 ;
1139- }();
1137+ // If there is a format mismatch the processing graph requires reconfiguration before decoding can begin
1138+ if ((flags_.load (std::memory_order_acquire) & static_cast <unsigned int >(Flags::formatMismatch))) {
1139+ // Wait until all other decoders complete processing before reconfiguring the graph
1140+ const auto okToReconfigure = [&] {
1141+ std::lock_guard lock{activeDecodersLock_};
1142+ return activeDecoders_.size () == 1 ;
1143+ }();
11401144
1141- if (okToReconfigure) {
1142- flags_.fetch_and (~static_cast <unsigned int >(Flags::formatMismatch) & ~static_cast <unsigned int >(Flags::drainRequired), std::memory_order_release);
1145+ if (okToReconfigure) {
1146+ flags_.fetch_and (~static_cast <unsigned int >(Flags::formatMismatch) & ~static_cast <unsigned int >(Flags::drainRequired), std::memory_order_release);
11431147
1144- os_log_debug (log_, " Non-gapless join for %{public}@" , decoderState->decoder_ );
1148+ os_log_debug (log_, " Non-gapless join for %{public}@" , decoderState->decoder_ );
11451149
1146- auto renderFormat = decoderState->converter_ .outputFormat ;
1147- if (NSError *error = nil ; !ConfigureProcessingGraphAndRingBufferForFormat (renderFormat, &error)) {
1148- decoderState->flags_ .fetch_or (static_cast <unsigned int >(DecoderState::Flags::isCanceled), std::memory_order_acq_rel);
1149- SubmitDecodingErrorEvent (error);
1150- continue ;
1151- }
1152-
1153- // Allocate the buffer that is the intermediary between the decoder state and the ring buffer
1154- if (auto format = buffer.format ; format.channelCount != renderFormat.channelCount || format.sampleRate != renderFormat.sampleRate ) {
1155- buffer = [[AVAudioPCMBuffer alloc ] initWithPCMFormat: renderFormat frameCapacity: ringBufferChunkSize];
1156- if (!buffer) {
1157- os_log_error (log_, " Error creating AVAudioPCMBuffer with format %{public}@ and frame capacity %d" , StringDescribingAVAudioFormat (renderFormat), ringBufferChunkSize);
1150+ auto renderFormat = decoderState->converter_ .outputFormat ;
1151+ if (NSError *error = nil ; !ConfigureProcessingGraphAndRingBufferForFormat (renderFormat, &error)) {
11581152 decoderState->flags_ .fetch_or (static_cast <unsigned int >(DecoderState::Flags::isCanceled), std::memory_order_acq_rel);
1159- SubmitDecodingErrorEvent ([ NSError errorWithDomain: SFBAudioPlayerErrorDomain code: SFBAudioPlayerErrorCodeInternalError userInfo: nil ] );
1153+ SubmitDecodingErrorEvent (error );
11601154 continue ;
11611155 }
1156+
1157+ // Allocate the buffer that is the intermediary between the decoder state and the ring buffer
1158+ if (auto format = buffer.format ; format.channelCount != renderFormat.channelCount || format.sampleRate != renderFormat.sampleRate ) {
1159+ buffer = [[AVAudioPCMBuffer alloc ] initWithPCMFormat: renderFormat frameCapacity: ringBufferChunkSize];
1160+ if (!buffer) {
1161+ os_log_error (log_, " Error creating AVAudioPCMBuffer with format %{public}@ and frame capacity %d" , StringDescribingAVAudioFormat (renderFormat), ringBufferChunkSize);
1162+ decoderState->flags_ .fetch_or (static_cast <unsigned int >(DecoderState::Flags::isCanceled), std::memory_order_acq_rel);
1163+ SubmitDecodingErrorEvent ([NSError errorWithDomain: SFBAudioPlayerErrorDomain code: SFBAudioPlayerErrorCodeInternalError userInfo: nil ]);
1164+ continue ;
1165+ }
1166+ }
11621167 }
1168+ else
1169+ decoderState = nullptr ;
11631170 }
1164- else
1165- decoderState = nullptr ;
11661171 }
11671172
11681173 if (decoderState && !(flags_.load (std::memory_order_acquire) & static_cast <unsigned int >(Flags::drainRequired))) {
0 commit comments