From 3cc97b55745b49b88d74db37c46a46c002a4d71b Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Thu, 13 Feb 2025 01:05:15 -0800 Subject: [PATCH] Audio: General cleanup and empty chunk checking Upstream functions which return empty chunks on error do not return nil, so the caller should check for an empty duration instead. Signed-off-by: Christopher Snowhill --- Audio/Chain/ConverterNode.m | 5 +++-- Audio/Chain/DSP/DSPEqualizerNode.m | 18 ++++++++++++++++-- Audio/Chain/DSP/DSPFSurroundNode.m | 18 ++++++++++++++++-- Audio/Chain/DSP/DSPHRTFNode.m | 18 +++++++++++++++--- Audio/Chain/DSP/DSPRubberbandNode.m | 18 ++++++++++++++++-- 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/Audio/Chain/ConverterNode.m b/Audio/Chain/ConverterNode.m index 38cc1bae6..754549bdc 100644 --- a/Audio/Chain/ConverterNode.m +++ b/Audio/Chain/ConverterNode.m @@ -101,13 +101,14 @@ void scale_by_volume(float *buffer, size_t count, float volume) { @autoreleasepool { AudioChunk *chunk = nil; chunk = [self convert]; - if(!chunk) { + if(!chunk || ![chunk duration]) { if([self endOfStream] == YES) { break; } if(paused || !streamFormatChanged) { continue; } + usleep(500); } else { [self writeChunk:chunk]; chunk = nil; @@ -472,7 +473,7 @@ static float db_to_scale(float db) { } - (void)dealloc { - DLog(@"Decoder dealloc"); + DLog(@"Converter dealloc"); [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.volumeScaling" context:kConverterNodeContext]; diff --git a/Audio/Chain/DSP/DSPEqualizerNode.m b/Audio/Chain/DSP/DSPEqualizerNode.m index fc7983df8..44858ac5a 100644 --- a/Audio/Chain/DSP/DSPEqualizerNode.m +++ b/Audio/Chain/DSP/DSPEqualizerNode.m @@ -16,6 +16,8 @@ #import "BufferChain.h" +#import "Logging.h" + #import "AudioPlayer.h" extern void scale_by_volume(float *buffer, size_t count, float volume); @@ -152,6 +154,7 @@ static OSStatus eqRenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioA } - (void)dealloc { + DLog(@"Equalizer dealloc"); [self cleanUp]; [self removeObservers]; } @@ -320,13 +323,14 @@ static OSStatus eqRenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioA @autoreleasepool { AudioChunk *chunk = nil; chunk = [self convert]; - if(!chunk) { + if(!chunk || ![chunk duration]) { if([self endOfStream] == YES) { break; } if(paused) { continue; } + usleep(500); } else { [self writeChunk:chunk]; chunk = nil; @@ -354,13 +358,23 @@ static OSStatus eqRenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioA return nil; } + if(!inputFormat.mSampleRate || + !inputFormat.mBitsPerChannel || + !inputFormat.mChannelsPerFrame || + !inputFormat.mBytesPerFrame || + !inputFormat.mFramesPerPacket || + !inputFormat.mBytesPerPacket) { + processEntered = NO; + return nil; + } + if((enableEqualizer && !equalizerInitialized) || memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 || inputChannelConfig != lastInputChannelConfig) { lastInputFormat = inputFormat; lastInputChannelConfig = inputChannelConfig; [self fullShutdown]; - if(![self setup]) { + if(enableEqualizer && ![self setup]) { processEntered = NO; return nil; } diff --git a/Audio/Chain/DSP/DSPFSurroundNode.m b/Audio/Chain/DSP/DSPFSurroundNode.m index 3d881b6f6..00e53f007 100644 --- a/Audio/Chain/DSP/DSPFSurroundNode.m +++ b/Audio/Chain/DSP/DSPFSurroundNode.m @@ -11,6 +11,8 @@ #import "DSPFSurroundNode.h" +#import "Logging.h" + #import "FSurroundFilter.h" #define OCTAVES 5 @@ -51,6 +53,7 @@ static void * kDSPFSurroundNodeContext = &kDSPFSurroundNodeContext; } - (void)dealloc { + DLog(@"FreeSurround dealloc"); [self cleanUp]; [self removeObservers]; } @@ -139,13 +142,14 @@ static void * kDSPFSurroundNodeContext = &kDSPFSurroundNodeContext; @autoreleasepool { AudioChunk *chunk = nil; chunk = [self convert]; - if(!chunk) { + if(!chunk || ![chunk duration]) { if([self endOfStream] == YES) { break; } if(paused) { continue; } + usleep(500); } else { [self writeChunk:chunk]; chunk = nil; @@ -173,13 +177,23 @@ static void * kDSPFSurroundNodeContext = &kDSPFSurroundNodeContext; return nil; } + if(!inputFormat.mSampleRate || + !inputFormat.mBitsPerChannel || + !inputFormat.mChannelsPerFrame || + !inputFormat.mBytesPerFrame || + !inputFormat.mFramesPerPacket || + !inputFormat.mBytesPerPacket) { + processEntered = NO; + return nil; + } + if((enableFSurround && !fsurround) || memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 || inputChannelConfig != lastInputChannelConfig) { lastInputFormat = inputFormat; lastInputChannelConfig = inputChannelConfig; [self fullShutdown]; - if(![self setup]) { + if(enableFSurround && ![self setup]) { processEntered = NO; return nil; } diff --git a/Audio/Chain/DSP/DSPHRTFNode.m b/Audio/Chain/DSP/DSPHRTFNode.m index 68ff41c45..644727d38 100644 --- a/Audio/Chain/DSP/DSPHRTFNode.m +++ b/Audio/Chain/DSP/DSPHRTFNode.m @@ -127,6 +127,7 @@ static void unregisterMotionListener(void) { } - (void)dealloc { + DLog(@"HRTF dealloc"); [self cleanUp]; [self removeObservers]; } @@ -264,13 +265,14 @@ static void unregisterMotionListener(void) { @autoreleasepool { AudioChunk *chunk = nil; chunk = [self convert]; - if(!chunk) { + if(!chunk || ![chunk duration]) { if([self endOfStream] == YES) { break; } if(paused) { continue; } + usleep(500); } else { [self writeChunk:chunk]; chunk = nil; @@ -298,13 +300,23 @@ static void unregisterMotionListener(void) { return nil; } + if(!inputFormat.mSampleRate || + !inputFormat.mBitsPerChannel || + !inputFormat.mChannelsPerFrame || + !inputFormat.mBytesPerFrame || + !inputFormat.mFramesPerPacket || + !inputFormat.mBytesPerPacket) { + processEntered = NO; + return nil; + } + if((enableHrtf && !hrtf) || memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 || inputChannelConfig != lastInputChannelConfig) { lastInputFormat = inputFormat; lastInputChannelConfig = inputChannelConfig; [self fullShutdown]; - if(![self setup]) { + if(enableHrtf && ![self setup]) { processEntered = NO; return nil; } @@ -316,7 +328,7 @@ static void unregisterMotionListener(void) { } AudioChunk *chunk = [self readChunkAsFloat32:4096]; - if(!chunk) { + if(!chunk || ![chunk duration]) { processEntered = NO; return nil; } diff --git a/Audio/Chain/DSP/DSPRubberbandNode.m b/Audio/Chain/DSP/DSPRubberbandNode.m index 67d4b10d4..060270154 100644 --- a/Audio/Chain/DSP/DSPRubberbandNode.m +++ b/Audio/Chain/DSP/DSPRubberbandNode.m @@ -11,6 +11,8 @@ #import "DSPRubberbandNode.h" +#import "Logging.h" + #import static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; @@ -60,6 +62,7 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; } - (void)dealloc { + DLog(@"Rubber Band dealloc"); [self cleanUp]; [self removeObservers]; } @@ -343,13 +346,14 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; @autoreleasepool { AudioChunk *chunk = nil; chunk = [self convert]; - if(!chunk) { + if(!chunk || ![chunk duration]) { if([self endOfStream] == YES) { break; } if(paused) { continue; } + usleep(500); } else { [self writeChunk:chunk]; chunk = nil; @@ -381,13 +385,23 @@ static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext; return nil; } + if(!inputFormat.mSampleRate || + !inputFormat.mBitsPerChannel || + !inputFormat.mChannelsPerFrame || + !inputFormat.mBytesPerFrame || + !inputFormat.mFramesPerPacket || + !inputFormat.mBytesPerPacket) { + processEntered = NO; + return nil; + } + if((enableRubberband && !ts) || memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 || inputChannelConfig != lastInputChannelConfig) { lastInputFormat = inputFormat; lastInputChannelConfig = inputChannelConfig; [self fullShutdown]; - if(![self setup]) { + if(enableRubberband && ![self setup]) { processEntered = NO; return nil; }