diff --git a/Audio/Chain/BufferChain.h b/Audio/Chain/BufferChain.h index 17cab6918..123e4e297 100644 --- a/Audio/Chain/BufferChain.h +++ b/Audio/Chain/BufferChain.h @@ -15,6 +15,8 @@ @interface BufferChain : NSObject { InputNode *inputNode; ConverterNode *converterNode; + + AudioStreamBasicDescription _inputFormat; NSURL *streamURL; id userInfo; @@ -63,4 +65,7 @@ - (id)controller; +- (ConverterNode *)converter; +- (AudioStreamBasicDescription)inputFormat; + @end diff --git a/Audio/Chain/BufferChain.m b/Audio/Chain/BufferChain.m index 478d14adb..0533a5e7a 100644 --- a/Audio/Chain/BufferChain.m +++ b/Audio/Chain/BufferChain.m @@ -63,7 +63,7 @@ if (![inputNode openWithSource:source]) return NO; - if (![converterNode setupWithInputFormat:propertiesToASBD([inputNode properties]) outputFormat:outputFormat]) + if (![converterNode setupWithInputFormat:(_inputFormat = propertiesToASBD([inputNode properties])) outputFormat:outputFormat]) return NO; [self setRGInfo:rgi]; @@ -82,7 +82,7 @@ return NO; DLog(@"Input Properties: %@", [inputNode properties]); - if (![converterNode setupWithInputFormat:propertiesToASBD([inputNode properties]) outputFormat:outputFormat]) + if (![converterNode setupWithInputFormat:(_inputFormat = propertiesToASBD([inputNode properties])) outputFormat:outputFormat]) return NO; [self setRGInfo:rgi]; @@ -199,4 +199,14 @@ return controller; } +- (ConverterNode *)converter +{ + return converterNode; +} + +- (AudioStreamBasicDescription)inputFormat +{ + return _inputFormat; +} + @end diff --git a/Audio/Chain/ConverterNode.h b/Audio/Chain/ConverterNode.h index 9077e2ad7..21170933a 100644 --- a/Audio/Chain/ConverterNode.h +++ b/Audio/Chain/ConverterNode.h @@ -22,6 +22,11 @@ void *callbackBuffer; size_t callbackBufferSize; + BOOL stopping; + BOOL convertEntered; + BOOL ACInputEntered; + BOOL ACFloatEntered; + float sampleRatio; float volumeScale; diff --git a/Audio/Chain/ConverterNode.m b/Audio/Chain/ConverterNode.m index 2758a5d3f..a1cbc6c6b 100644 --- a/Audio/Chain/ConverterNode.m +++ b/Audio/Chain/ConverterNode.m @@ -43,6 +43,11 @@ void PrintStreamDesc (AudioStreamBasicDescription *inDesc) floatBufferSize = 0; callbackBuffer = NULL; callbackBufferSize = 0; + + stopping = NO; + convertEntered = NO; + ACInputEntered = NO; + ACFloatEntered = NO; [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.volumeScaling" options:0 context:nil]; } @@ -169,14 +174,16 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, OSStatus err = noErr; int amountToWrite; int amountRead; - - if ([converter shouldContinue] == NO || [converter endOfStream] == YES) + + if (converter->stopping || [converter shouldContinue] == NO || [converter endOfStream] == YES) { ioData->mBuffers[0].mDataByteSize = 0; *ioNumberDataPackets = 0; return noErr; } + + converter->ACInputEntered = YES; amountToWrite = (*ioNumberDataPackets)*(converter->inputFormat.mBytesPerPacket); @@ -188,6 +195,8 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, { ioData->mBuffers[0].mDataByteSize = 0; *ioNumberDataPackets = 0; + + converter->ACInputEntered = NO; return 100; //Keep asking for data } @@ -196,7 +205,9 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, ioData->mBuffers[0].mDataByteSize = amountRead; ioData->mBuffers[0].mNumberChannels = (converter->inputFormat.mChannelsPerFrame); ioData->mNumberBuffers = 1; - + + converter->ACInputEntered = NO; + return err; } @@ -210,13 +221,15 @@ static OSStatus ACFloatProc(AudioConverterRef inAudioConverter, OSStatus err = noErr; int amountToWrite; - if ([converter shouldContinue] == NO) + if (converter->stopping || [converter shouldContinue] == NO) { ioData->mBuffers[0].mDataByteSize = 0; *ioNumberDataPackets = 0; return noErr; } + + converter->ACFloatEntered = YES; amountToWrite = (*ioNumberDataPackets) * (converter->dmFloatFormat.mBytesPerPacket); @@ -232,10 +245,15 @@ static OSStatus ACFloatProc(AudioConverterRef inAudioConverter, ioData->mNumberBuffers = 1; if (amountToWrite == 0) + { + converter->ACFloatEntered = NO; return 100; + } converter->floatOffset += amountToWrite; + converter->ACFloatEntered = NO; + return err; } @@ -258,9 +276,15 @@ static OSStatus ACFloatProc(AudioConverterRef inAudioConverter, int amountReadFromFC; int amountRead = 0; + if (stopping) + return 0; + + convertEntered = YES; + tryagain2: - if ([self shouldContinue] == NO || [self endOfStream] == YES) + if (stopping || [self shouldContinue] == NO || [self endOfStream] == YES) { + convertEntered = NO; return amountRead; } @@ -287,6 +311,12 @@ tryagain2: ioData.mNumberBuffers = 1; tryagain: + if (stopping) + { + convertEntered = NO; + return 0; + } + err = AudioConverterFillComplexBuffer(converterFloat, ACInputProc, (__bridge void * _Nullable)(self), &ioNumberPackets, &ioData, NULL); amountReadFromFC += ioNumberPackets * floatFormat.mBytesPerPacket; if (err == 100) @@ -301,6 +331,7 @@ tryagain2: else if (err != noErr && err != kAudioConverterErr_InvalidInputSize) { DLog(@"Error: %i", err); + convertEntered = NO; return amountRead; } @@ -335,6 +366,12 @@ tryagain2: ioData.mBuffers[0].mNumberChannels = outputFormat.mChannelsPerFrame; ioData.mNumberBuffers = 1; + if (stopping) + { + convertEntered = NO; + return 0; + } + err = AudioConverterFillComplexBuffer(converter, ACFloatProc, (__bridge void *)(self), &ioNumberPackets, &ioData, NULL); amountRead += ioNumberPackets * outputFormat.mBytesPerPacket; if (err == 100) @@ -345,7 +382,8 @@ tryagain2: { DLog(@"Error: %i", err); } - + + convertEntered = NO; return amountRead; } @@ -414,6 +452,11 @@ static float db_to_scale(float db) { //Make the converter OSStatus stat = noErr; + + stopping = NO; + convertEntered = NO; + ACInputEntered = NO; + ACFloatEntered = NO; inputFormat = inf; outputFormat = outf; @@ -514,6 +557,11 @@ static float db_to_scale(float db) - (void)inputFormatDidChange:(AudioStreamBasicDescription)format { DLog(@"FORMAT CHANGED"); + stopping = YES; + while (convertEntered || ACInputEntered || ACFloatEntered) + { + usleep(500); + } [self cleanUp]; [self setupWithInputFormat:format outputFormat:outputFormat]; } diff --git a/Audio/Chain/InputNode.m b/Audio/Chain/InputNode.m index a89c4dc43..c7e4e5722 100644 --- a/Audio/Chain/InputNode.m +++ b/Audio/Chain/InputNode.m @@ -122,17 +122,21 @@ if (shouldSeek == YES) { OutputNode *output = [[controller controller] output]; - BOOL isPaused = [output isPaused]; - if ( !isPaused ) [output pause]; - DLog(@"SEEKING!"); - seekError = [decoder seek:seekFrame] < 0; - if ( !isPaused ) [output resumeWithFade]; + ConverterNode *converter = [[[controller controller] bufferChain] converter]; + DLog(@"SEEKING! Resetting Buffer"); + + [self resetBuffer]; + [output reset]; + [converter resetBuffer]; + [converter inputFormatDidChange:[[[controller controller] bufferChain] inputFormat]]; + + DLog(@"Reset buffer!"); + + DLog(@"SEEKING!"); + seekError = [decoder seek:seekFrame] < 0; + shouldSeek = NO; DLog(@"Seeked! Resetting Buffer"); - - [self resetBuffer]; - - DLog(@"Reset buffer!"); initialBufferFilled = NO; } diff --git a/Audio/Chain/OutputNode.h b/Audio/Chain/OutputNode.h index c3d87a8c5..2b51c7aa7 100644 --- a/Audio/Chain/OutputNode.h +++ b/Audio/Chain/OutputNode.h @@ -30,6 +30,7 @@ - (void)process; - (void)close; - (void)seek:(double)time; +- (void)reset; - (int)readData:(void *)ptr amount:(int)amount; @@ -42,7 +43,6 @@ - (void)pause; - (void)resume; -- (void)resumeWithFade; - (BOOL)isPaused; diff --git a/Audio/Chain/OutputNode.m b/Audio/Chain/OutputNode.m index 88aa37d61..9662752ff 100644 --- a/Audio/Chain/OutputNode.m +++ b/Audio/Chain/OutputNode.m @@ -51,10 +51,11 @@ [output resume]; } -- (void)resumeWithFade +- (void)reset { - paused = NO; - [output resumeWithFade]; + [output setup]; + if (!paused) + [output start]; } - (int)readData:(void *)ptr amount:(int)amount diff --git a/Audio/Output/OutputCoreAudio.h b/Audio/Output/OutputCoreAudio.h index 1ca251735..ea08304e6 100644 --- a/Audio/Output/OutputCoreAudio.h +++ b/Audio/Output/OutputCoreAudio.h @@ -43,7 +43,6 @@ - (void)pause; - (void)resume; - (void)stop; -- (void)resumeWithFade; - (void)setVolume:(double) v; diff --git a/Audio/Output/OutputCoreAudio.m b/Audio/Output/OutputCoreAudio.m index 991ae7ee2..33b7d3a44 100644 --- a/Audio/Output/OutputCoreAudio.m +++ b/Audio/Output/OutputCoreAudio.m @@ -44,10 +44,6 @@ static void Sound_Renderer(void *userData, AudioQueueRef queue, AudioQueueBuffer if (output->stopping == YES) { - // *shrug* At least this will stop it from trying to emit data post-shutdown - memset(readPointer, 0, amountToRead); - buffer->mAudioDataByteSize = amountToRead; - AudioQueueEnqueueBuffer(queue, buffer, 0, NULL); return; } @@ -260,6 +256,8 @@ static void Sound_Renderer(void *userData, AudioQueueRef queue, AudioQueueBuffer { if (outputUnit || audioQueue) [self stop]; + + stopping = NO; AudioComponentDescription desc; OSStatus err; @@ -375,6 +373,8 @@ static void Sound_Renderer(void *userData, AudioQueueRef queue, AudioQueueBuffer - (void)start { + AudioQueueSetParameter(audioQueue, kAudioQueueParam_VolumeRampTime, 0); + AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, volume); AudioQueueStart(audioQueue, NULL); } @@ -389,6 +389,9 @@ static void Sound_Renderer(void *userData, AudioQueueRef queue, AudioQueueBuffer } if (audioQueue && buffers) { + AudioQueuePause(audioQueue); + AudioQueueStop(audioQueue, true); + for (UInt32 i = 0; i < numberOfBuffers; ++i) { if (buffers[i]) @@ -414,23 +417,12 @@ static void Sound_Renderer(void *userData, AudioQueueRef queue, AudioQueueBuffer - (void)pause { - AudioQueueSetParameter(audioQueue, kAudioQueueParam_VolumeRampTime, 0); - AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, 0); AudioQueuePause(audioQueue); } - (void)resume { AudioQueueStart(audioQueue, NULL); - AudioQueueSetParameter(audioQueue, kAudioQueueParam_VolumeRampTime, 0); - AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, volume); -} - -- (void)resumeWithFade -{ - AudioQueueStart(audioQueue, NULL); - AudioQueueSetParameter(audioQueue, kAudioQueueParam_VolumeRampTime, 0.4); - AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, volume); } @end