From ce30f0de57f57d7a1c31917c4c56ef804741ed7e Mon Sep 17 00:00:00 2001 From: Thong Nguyen Date: Mon, 10 Feb 2014 13:25:17 +0000 Subject: [PATCH] New AudioGraph creation code mostly done. EQ working on iOS and OSX --- ExampleApp/ExampleApp/AppDelegate.m | 4 +- ExampleAppMac/ExampleAppMac/AppDelegate.m | 6 +- StreamingKit/StreamingKit/STKAudioPlayer.h | 1 + StreamingKit/StreamingKit/STKAudioPlayer.m | 94 ++++++++++------------ 4 files changed, 47 insertions(+), 58 deletions(-) diff --git a/ExampleApp/ExampleApp/AppDelegate.m b/ExampleApp/ExampleApp/AppDelegate.m index 04f016a..9d2938e 100644 --- a/ExampleApp/ExampleApp/AppDelegate.m +++ b/ExampleApp/ExampleApp/AppDelegate.m @@ -33,9 +33,7 @@ audioPlayer = [[STKAudioPlayer alloc] initWithOptions:(STKAudioPlayerOptions){ .flushQueueOnSeek = YES, .enableVolumeMixer = NO, .equalizerBandFrequencies = {50, 100, 200, 400, 800, 1600, 2600, 16000} }]; audioPlayer.meteringEnabled = YES; - audioPlayer.volume = 1.0; - - [audioPlayer setGain:24 forEqualizerBand:0]; + audioPlayer.volume = 0.1; AudioPlayerView* audioPlayerView = [[AudioPlayerView alloc] initWithFrame:self.window.bounds]; diff --git a/ExampleAppMac/ExampleAppMac/AppDelegate.m b/ExampleAppMac/ExampleAppMac/AppDelegate.m index e215d62..1bfc81a 100644 --- a/ExampleAppMac/ExampleAppMac/AppDelegate.m +++ b/ExampleAppMac/ExampleAppMac/AppDelegate.m @@ -40,11 +40,11 @@ [[self.window contentView] addSubview:playFromHTTPButton]; [[self.window contentView] addSubview:meter]; - audioPlayer = [[STKAudioPlayer alloc] initWithOptions:(STKAudioPlayerOptions){ .equalizerBandFrequencies = {50, 100, 200, 400, 800, 1600, 2600, 16000} } ]; + audioPlayer = [[STKAudioPlayer alloc] initWithOptions:(STKAudioPlayerOptions){ .enableVolumeMixer = YES, .equalizerBandFrequencies = {0, 50, 100, 200, 400, 800, 1600, 2600, 16000} } ]; audioPlayer.delegate = self; audioPlayer.meteringEnabled = YES; - audioPlayer.volume = 1.0; - + audioPlayer.volume = 0.1; + [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(tick:) userInfo:nil repeats:YES]; } diff --git a/StreamingKit/StreamingKit/STKAudioPlayer.h b/StreamingKit/StreamingKit/STKAudioPlayer.h index f0c766c..8c58712 100644 --- a/StreamingKit/StreamingKit/STKAudioPlayer.h +++ b/StreamingKit/StreamingKit/STKAudioPlayer.h @@ -254,6 +254,7 @@ typedef void(^STKFrameFilter)(UInt32 channelsPerFrame, UInt32 bytesPerFrame, UIn /// Return values are between -60 (low) and 0 (high). -(float) averagePowerInDecibelsForChannel:(NSUInteger)channelNumber; +/// Sets the gain value (from -96 low to +24 high) for an equalizer band (0 based index) -(void) setGain:(float)gain forEqualizerBand:(int)bandIndex; @end diff --git a/StreamingKit/StreamingKit/STKAudioPlayer.m b/StreamingKit/StreamingKit/STKAudioPlayer.m index 90b5071..31a48ee 100644 --- a/StreamingKit/StreamingKit/STKAudioPlayer.m +++ b/StreamingKit/StreamingKit/STKAudioPlayer.m @@ -90,6 +90,13 @@ static void PopulateOptionsWithDefault(STKAudioPlayerOptions* options) return;\ } +#define CHECK_STATUS_AND_RETURN_VALUE(call, value) \ + if ((status = (call))) \ + { \ + [self unexpectedError:STKAudioPlayerErrorAudioSystemError]; \ + return value;\ + } + typedef enum { STKAudioPlayerInternalStateInitialised = 0, @@ -144,6 +151,7 @@ STKAudioPlayerInternalState; #pragma mark STKAudioPlayer static AudioComponentDescription mixerDescription; +static AudioComponentDescription nbandUnitDescription; static AudioComponentDescription outputUnitDescription; static AudioComponentDescription convertUnitDescription; static AudioStreamBasicDescription canonicalAudioStreamBasicDescription; @@ -298,6 +306,13 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn .componentFlagsMask = 0, .componentManufacturer = kAudioUnitManufacturer_Apple }; + + nbandUnitDescription = (AudioComponentDescription) + { + .componentType = kAudioUnitType_Effect, + .componentSubType = kAudioUnitSubType_NBandEQ, + .componentManufacturer=kAudioUnitManufacturer_Apple + }; } -(STKAudioPlayerOptions) options { @@ -1872,55 +1887,19 @@ static BOOL GetHardwareCodecClassDesc(UInt32 formatId, AudioClassDescription* cl Float64 graphSampleRate = 44100.0; CHECK_STATUS_AND_RETURN(AudioUnitSetProperty(mixerUnit, kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, 0, &graphSampleRate, sizeof(graphSampleRate))); - - status = AudioUnitSetProperty(mixerUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &canonicalAudioStreamBasicDescription, sizeof(canonicalAudioStreamBasicDescription)); - - if (status) - { - AUNode convertNode; - AudioComponentInstance convertUnit; - AudioStreamBasicDescription format; - UInt32 size = sizeof(format); - - // Converter -> Mixer -> Output - - CHECK_STATUS_AND_RETURN(AudioUnitGetProperty(mixerUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &format, &size)); - CHECK_STATUS_AND_RETURN(AUGraphAddNode(audioGraph, &convertUnitDescription, &convertNode)); - CHECK_STATUS_AND_RETURN(AUGraphNodeInfo(audioGraph, convertNode, &mixerDescription, &convertUnit)); - CHECK_STATUS_AND_RETURN(AudioUnitSetProperty(convertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &canonicalAudioStreamBasicDescription, sizeof(canonicalAudioStreamBasicDescription))); - CHECK_STATUS_AND_RETURN(AudioUnitSetProperty(convertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &format, sizeof(format))); - CHECK_STATUS_AND_RETURN(AUGraphConnectNodeInput(audioGraph, convertNode, 0, mixerNode, 0)); - CHECK_STATUS_AND_RETURN(AUGraphConnectNodeInput(audioGraph, mixerNode, 0, outputNode, 0)); - CHECK_STATUS_AND_RETURN(AudioUnitGetProperty(mixerUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &format, &size)); - CHECK_STATUS_AND_RETURN(AudioUnitSetParameter(mixerUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, 0, 1.0, 0)); - - mixerInputNode = convertNode; - mixerOutputNode = mixerNode; - } - else - { - mixerInputNode = mixerNode; - mixerOutputNode = mixerNode; - } + CHECK_STATUS_AND_RETURN(AudioUnitSetParameter(mixerUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, 0, 1.0, 0)); } -(void) createEqUnit { + OSStatus status; + if (self->options.equalizerBandFrequencies[0] == 0) { return; } - OSStatus status; - - AudioComponentDescription eqDescription = (AudioComponentDescription) - { - .componentType = kAudioUnitType_Effect, - .componentSubType = kAudioUnitSubType_NBandEQ, - .componentManufacturer=kAudioUnitManufacturer_Apple - }; - - CHECK_STATUS_AND_RETURN(AUGraphAddNode(audioGraph, &eqDescription, &eqNode)); + CHECK_STATUS_AND_RETURN(AUGraphAddNode(audioGraph, &nbandUnitDescription, &eqNode)); CHECK_STATUS_AND_RETURN(AUGraphNodeInfo(audioGraph, eqNode, NULL, &eqUnit)); while (self->options.equalizerBandFrequencies[eqBandCount] != 0) @@ -1947,8 +1926,10 @@ static BOOL GetHardwareCodecClassDesc(UInt32 formatId, AudioClassDescription* cl { return; } + + OSStatus status; - AudioUnitSetParameter(eqUnit, kAUNBandEQParam_Gain + bandIndex, kAudioUnitScope_Global, 0, gain, 0); + CHECK_STATUS_AND_RETURN(AudioUnitSetParameter(eqUnit, kAUNBandEQParam_Gain + bandIndex, kAudioUnitScope_Global, 0, gain, 0)); } -(AUNode) createConverterNode:(AudioStreamBasicDescription)srcFormat desFormat:(AudioStreamBasicDescription)desFormat @@ -1957,10 +1938,10 @@ static BOOL GetHardwareCodecClassDesc(UInt32 formatId, AudioClassDescription* cl AUNode convertNode; AudioComponentInstance convertUnit; - status = AUGraphAddNode(audioGraph, &convertUnitDescription, &convertNode); - status = AUGraphNodeInfo(audioGraph, convertNode, &mixerDescription, &convertUnit); - status = AudioUnitSetProperty(convertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat, sizeof(srcFormat)); - status = AudioUnitSetProperty(convertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &desFormat, sizeof(desFormat)); + CHECK_STATUS_AND_RETURN_VALUE(AUGraphAddNode(audioGraph, &convertUnitDescription, &convertNode), 0); + CHECK_STATUS_AND_RETURN_VALUE(status = AUGraphNodeInfo(audioGraph, convertNode, &mixerDescription, &convertUnit), 0); + CHECK_STATUS_AND_RETURN_VALUE(AudioUnitSetProperty(convertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat, sizeof(srcFormat)), 0); + CHECK_STATUS_AND_RETURN_VALUE(AudioUnitSetProperty(convertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &desFormat, sizeof(desFormat)), 0); return convertNode; } @@ -2007,9 +1988,9 @@ static BOOL GetHardwareCodecClassDesc(UInt32 formatId, AudioClassDescription* cl AUNode converterNode = [self createConverterNode:canonicalAudioStreamBasicDescription desFormat:format]; - CHECK_STATUS_AND_RETURN(AUGraphConnectNodeInput(audioGraph, converterNode, 0, firstNode, 0)); + CHECK_STATUS_AND_RETURN(AUGraphSetNodeInputCallback(audioGraph, converterNode, 0, &callbackStruct)); - CHECK_STATUS_AND_RETURN(AUGraphSetNodeInputCallback(audioGraph, converterNode, 0, &callbackStruct)); + status = AUGraphConnectNodeInput(audioGraph, converterNode, 0, firstNode, 0); } else { @@ -2075,6 +2056,13 @@ static BOOL GetHardwareCodecClassDesc(UInt32 formatId, AudioClassDescription* cl status = AUGraphIsRunning(audioGraph, &isRunning); + if (status) + { + [self unexpectedError:STKAudioPlayerErrorAudioSystemError]; + + return NO; + } + if (isRunning) { return NO; @@ -2108,22 +2096,24 @@ static BOOL GetHardwareCodecClassDesc(UInt32 formatId, AudioClassDescription* cl status = AUGraphIsRunning(audioGraph, &isRunning); - if (!isRunning) + if (status) + { + [self unexpectedError:STKAudioPlayerErrorAudioSystemError]; + } + else if (!isRunning) { return; } status = AUGraphStop(audioGraph); - [self resetPcmBuffers]; - if (status) { [self unexpectedError:STKAudioPlayerErrorAudioSystemError]; - - return; } + [self resetPcmBuffers]; + stopReason = stopReasonIn; self.internalState = STKAudioPlayerInternalStateStopped; }