Search code examples
iosswiftcore-audioaudiounitequalizer

Core Audio Swift Equalizer adjusts all bands at once?


I am having trouble setting up a kAudioUnitSubType_NBandEQ in Swift. Here is my code to initialize the EQ:

  var cd:AudioComponentDescription = AudioComponentDescription(componentType: OSType(kAudioUnitType_Effect),componentSubType: OSType(kAudioUnitSubType_NBandEQ),componentManufacturer: OSType(kAudioUnitManufacturer_Apple),componentFlags: 0,componentFlagsMask: 0)

    // Add the node to the graph
    status = AUGraphAddNode(graph, &cd, &MyAppNode)
    println(status)

     // Once the graph has been opened get an instance of the equalizer
    status = AUGraphNodeInfo(graph, self.MyAppNode, nil, &MyAppUnit)
    println(status)

    var eqFrequencies: [UInt32] = [ 32, 250, 500, 1000, 2000, 16000 ]

    status = AudioUnitSetProperty(
        self.MyAppUnit,
        AudioUnitPropertyID(kAUNBandEQProperty_NumberOfBands),
        AudioUnitScope(kAudioUnitScope_Global),
        0,
        eqFrequencies,
        UInt32(eqFrequencies.count*sizeof(UInt32))
    )
    println(status)

    status = AudioUnitInitialize(self.MyAppUnit)
    println(status)

    var ioUnitOutputElement:AudioUnitElement = 0
    var samplerOutputElement:AudioUnitElement = 0

    AUGraphConnectNodeInput(graph, sourceNode, sourceOutputBusNumber, self.MyAppNode, 0)

    AUGraphConnectNodeInput(graph, self.MyAppNode, 0, destinationNode, destinationInputBusNumber)

and then to apply changes in the frequency gains my code is as follows:

if (MyAppUnit == nil) {return}
    else{

        var bandValue0 :Float32 = tenBands.objectAtIndex(0) as! Float32
        var bandValue1 :Float32 = tenBands.objectAtIndex(1) as! Float32
        var bandValue2 :Float32 = tenBands.objectAtIndex(2) as! Float32
        var bandValue3 :Float32 = tenBands.objectAtIndex(3) as! Float32
        var bandValue4 :Float32 = tenBands.objectAtIndex(4) as! Float32
        var bandValue5 :Float32 = tenBands.objectAtIndex(5) as! Float32

        AudioUnitSetParameter(self.MyAppUnit, 0, AudioUnitScope(kAudioUnitScope_Global), 0, bandValue0, 0);
        AudioUnitSetParameter(self.MyAppUnit, 1, AudioUnitScope(kAudioUnitScope_Global), 0, bandValue1, 0);
        AudioUnitSetParameter(self.MyAppUnit, 2, AudioUnitScope(kAudioUnitScope_Global), 0, bandValue2, 0);
        AudioUnitSetParameter(self.MyAppUnit, 3, AudioUnitScope(kAudioUnitScope_Global), 0, bandValue3, 0);
        AudioUnitSetParameter(self.MyAppUnit, 4, AudioUnitScope(kAudioUnitScope_Global), 0, bandValue4, 0);
        AudioUnitSetParameter(self.MyAppUnit, 5, AudioUnitScope(kAudioUnitScope_Global), 0, bandValue5, 0);
}

Can anyone point out what I am doing wrong here? I think it is related to the second variable in AudioUnitSetParameter. I have tried AudioUnitParameterID(0), and AudioUnitParameterID(kAUNBandEQParam_Gain + 1) for this Value but those don't seem to work at all. Any help is appreciated!


Solution

  • Comment adding as answer because comments are insufficient.

    The following Code is in Objective-c but it should help identify your problem.

    There are a number of places this might fail. Firstly, you should check the status of the AudioUnitSetParameter, and indeed all the AudioUnit Calls as this will give you a clearer point of where you're code is failing.

    I've done this successfully in Objective-C and have a test app i can make available, if you need it, which shows the complete graph setup and setting the bands and gains by moving a slider ... back to your specific question. The following works just fine for me, this might help you rule out a particular section.

    You can try and obtain the current "gain", this will indicate if your bands are set up correctly.

      - (AudioUnitParameterValue)gainForBandAtPosition:(uint)bandPosition
      {
          AudioUnitParameterValue gain;
          AudioUnitParameterID parameterID = kAUNBandEQParam_Gain + bandPosition;
          OSStatus status = AudioUnitGetParameter(equalizerUnit,
                                                 parameterID,
                                      kAudioUnitScope_Global,
                                                           0,
                                                     &gain);
    
        if (status != noErr) {
        @throw [NSException exceptionWithName:@"gettingParamGainErrorException"
                                       reason:[NSString stringWithFormat:@"OSStatus Error on getting EQ Gain! Status returned %d).", (int)status]
                                     userInfo:nil];
        }
    
        return gain;
      }
    

    then setting the gain can be done in the following way;

      - (void)setGain:(AudioUnitParameterValue)gain forBandAtPosition:(uint)bandPosition
      {
          AudioUnitParameterID parameterID = kAUNBandEQParam_Gain + bandPosition;
          OSStatus status = AudioUnitSetParameter(equalizerUnit,
                                                    parameterID,
                                         kAudioUnitScope_Global,
                                                              0,
                                                           gain,
                                                            0);
    
        if (status != noErr) {
        @throw [NSException exceptionWithName:@"settingParamGainAudioErrorException"
                                       reason:[NSString stringWithFormat:@"OSStatus Error on setting EQ gain! Status returned %d).", (int)status]
                                     userInfo:nil];
        }
    
      }
    

    Finally, what value are you trying to set, the valid range (if I'm not mistaken) is -125.0 to 25.0