diff --git a/Audio/Chain/ConverterNode.mm b/Audio/Chain/ConverterNode.mm index ac6d654f9..e9b238a4b 100644 --- a/Audio/Chain/ConverterNode.mm +++ b/Audio/Chain/ConverterNode.mm @@ -446,22 +446,19 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes // when the end of stream is reached. Convert function instead processes what it can, // and returns 0 samples when it has nothing more to process at the end of stream. while([self shouldContinue] == YES) { - [self followWorkgroup]; - int amountConverted; while(paused) { usleep(500); } - [self startWorkslice]; @autoreleasepool { + [self startWorkslice]; amountConverted = [self convert:writeBuf amount:CHUNK_SIZE]; + [self endWorkslice]; } - [self endWorkslice]; if(!amountConverted) { if(paused) { continue; } else if(streamFormatChanged) { - [self leaveWorkgroup]; [self cleanUp]; [self setupWithInputFormat:newInputFormat withInputConfig:newInputChannelConfig outputFormat:outputFormat outputConfig:outputChannelConfig isLossless:rememberedLossless]; continue; diff --git a/Audio/Chain/InputNode.m b/Audio/Chain/InputNode.m index a3d2a2993..021a90ea5 100644 --- a/Audio/Chain/InputNode.m +++ b/Audio/Chain/InputNode.m @@ -157,7 +157,6 @@ static void *kInputNodeContext = &kInputNodeContext; while([self shouldContinue] == YES && [self endOfStream] == NO) { if(shouldSeek == YES) { - [self leaveWorkgroup]; BufferChain *bufferChain = [[controller controller] bufferChain]; ConverterNode *converter = [bufferChain converter]; DLog(@"SEEKING! Resetting Buffer"); @@ -183,15 +182,13 @@ static void *kInputNodeContext = &kInputNodeContext; } if(amountInBuffer < CHUNK_SIZE) { - [self followWorkgroup]; - int framesToRead = CHUNK_SIZE - amountInBuffer; int framesRead; - [self startWorkslice]; @autoreleasepool { + [self startWorkslice]; framesRead = [decoder readAudio:((char *)inputBuffer) + bytesInBuffer frames:framesToRead]; + [self endWorkslice]; } - [self endWorkslice]; if(framesRead > 0 && !seekError) { amountInBuffer += framesRead; diff --git a/Audio/Chain/Node.h b/Audio/Chain/Node.h index c0bdadacf..09684cd8d 100644 --- a/Audio/Chain/Node.h +++ b/Audio/Chain/Node.h @@ -29,7 +29,7 @@ BOOL shouldContinue; BOOL endOfStream; // All data is now in buffer BOOL initialBufferFilled; - BOOL isRealtime, isRealtimeError; // If was successfully set realtime, or if error + BOOL isRealtime, isRealtimeError, isDeadlineError; // If was successfully set realtime, or if error AudioStreamBasicDescription nodeFormat; uint32_t nodeChannelConfig; diff --git a/Audio/Chain/Node.m b/Audio/Chain/Node.m index 2ed4bd2d4..fa100d826 100644 --- a/Audio/Chain/Node.m +++ b/Audio/Chain/Node.m @@ -222,6 +222,7 @@ BOOL SetPriorityRealtimeAudio(mach_port_t mach_thread_id) { wg = workgroup; if(wg && !isRealtimeError) { int result = os_workgroup_join(wg, &wgToken); + isDeadlineError = NO; if(result == 0) return; if(result == EALREADY) { DLog(@"Thread already in workgroup"); @@ -251,13 +252,13 @@ BOOL SetPriorityRealtimeAudio(mach_port_t mach_thread_id) { - (void)startWorkslice { if(@available(macOS 11, *)) { - if(wg && !isRealtimeError) { + if(wg && !isRealtimeError && !isDeadlineError) { const uint64_t currentTime = mach_absolute_time(); const uint64_t deadline = currentTime + intervalMachLength; int result = os_workgroup_interval_start(wg, currentTime, deadline, nil); if(result != 0) { DLog(@"Deadline error = %d", result); - isRealtimeError = YES; + isDeadlineError = YES; } } } @@ -265,11 +266,11 @@ BOOL SetPriorityRealtimeAudio(mach_port_t mach_thread_id) { - (void)endWorkslice { if(@available(macOS 11, *)) { - if(wg && !isRealtimeError) { + if(wg && !isRealtimeError && !isDeadlineError) { int result = os_workgroup_interval_finish(wg, nil); if(result != 0) { DLog(@"Deadline end error = %d", result); - isRealtimeError = YES; + isDeadlineError = YES; } } }