0

I'm trying to disable AGC and bypass voice filter for the AudioUnit but it fails to set these two properties:

    private func setupAudioUnit() {
        
        var componentDesc:AudioComponentDescription = AudioComponentDescription(
            componentType: OSType(kAudioUnitType_Output),
            componentSubType: OSType(kAudioUnitSubType_RemoteIO), // Always this for iOS.
            componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
            componentFlags: 0,
            componentFlagsMask: 0)
        
        var osErr: OSStatus = 0
        
        // Get an audio component matching our description.
        let component: AudioComponent! = AudioComponentFindNext(nil, &componentDesc)
        assert(component != nil, "Couldn't find a default component")
        
        // Create an instance of the AudioUnit
        var tempAudioUnit: AudioUnit?
        osErr = AudioComponentInstanceNew(component, &tempAudioUnit)
        self.audioUnit = tempAudioUnit
        
        assert(osErr == noErr, "*** AudioComponentInstanceNew err \(osErr)")
        
        // Enable I/O for input.
        var one: UInt32 = 1
        var off: UInt32 = 0
        
        osErr = AudioUnitSetProperty(audioUnit,
            kAudioOutputUnitProperty_EnableIO,
            kAudioUnitScope_Input,
            inputBus,
            &one,
            UInt32(MemoryLayout<UInt32>.size))
        
        /// Bypass Voice Processing
        osErr = AudioUnitSetProperty(audioUnit,
            kAUVoiceIOProperty_BypassVoiceProcessing,
            kAudioUnitScope_Global,
            inputBus,
            &one,
            UInt32(MemoryLayout<UInt32>.size))
        print("AudioUnitSetProperty returned code:\(osErr)")
        
        /// Disable AGC
        osErr = AudioUnitSetProperty(audioUnit,
            kAUVoiceIOProperty_VoiceProcessingEnableAGC,
            kAudioUnitScope_Global,
            inputBus,
            &off,
            UInt32(MemoryLayout<UInt32>.size))
        print("AudioUnitSetProperty returned code:\(osErr)")
        assert(osErr == noErr, "*** AudioUnitSetProperty err \(osErr)")
        
        // Set format to 32 bit, floating point, linear PCM
        var streamFormatDesc:AudioStreamBasicDescription = AudioStreamBasicDescription(
            mSampleRate:        Double(sampleRate),
            mFormatID:          kAudioFormatLinearPCM,
            mFormatFlags:       kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved, // floating point data - docs say this is fastest
            mBytesPerPacket:    4,
            mFramesPerPacket:   1,
            mBytesPerFrame:     4,
            mChannelsPerFrame:  UInt32(self.numberOfChannels),
            mBitsPerChannel:    4 * 8,
            mReserved: 0
        )
        
        // Set format for input and output busses
        osErr = AudioUnitSetProperty(audioUnit,
            kAudioUnitProperty_StreamFormat,
            kAudioUnitScope_Input, outputBus,
            &streamFormatDesc,
            UInt32(MemoryLayout<AudioStreamBasicDescription>.size))
        assert(osErr == noErr, "*** AudioUnitSetProperty err \(osErr)")
        
        osErr = AudioUnitSetProperty(audioUnit,
            kAudioUnitProperty_StreamFormat,
            kAudioUnitScope_Output,
            inputBus,
            &streamFormatDesc,
            UInt32(MemoryLayout<AudioStreamBasicDescription>.size))
        assert(osErr == noErr, "*** AudioUnitSetProperty err \(osErr)")


        // Set up our callback.
        var inputCallbackStruct = AURenderCallbackStruct(inputProc: recordingCallback, inputProcRefCon: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()))
        osErr = AudioUnitSetProperty(audioUnit,
            AudioUnitPropertyID(kAudioOutputUnitProperty_SetInputCallback),
            AudioUnitScope(kAudioUnitScope_Global),
            inputBus,
            &inputCallbackStruct,
            UInt32(MemoryLayout<AURenderCallbackStruct>.size))
        assert(osErr == noErr, "*** AudioUnitSetProperty err \(osErr)")
        
        // Ask CoreAudio to allocate buffers for us on render. (This is true by default but just to be explicit about it...)
        osErr = AudioUnitSetProperty(audioUnit,
            AudioUnitPropertyID(kAudioUnitProperty_ShouldAllocateBuffer),
            AudioUnitScope(kAudioUnitScope_Output),
            inputBus,
            &one,
            UInt32(MemoryLayout<UInt32>.size))
        assert(osErr == noErr, "*** AudioUnitSetProperty err \(osErr)")
    }
}

Here I get invalid property response:

/// Bypass Voice Processing
osErr = AudioUnitSetProperty(audioUnit,
    kAUVoiceIOProperty_BypassVoiceProcessing,
    kAudioUnitScope_Global,
    inputBus,
    &one,
    UInt32(MemoryLayout<UInt32>.size))
print("AudioUnitSetProperty returned code:\(osErr)")
// AudioUnitSetProperty returned code:-10879

/// Disable AGC
osErr = AudioUnitSetProperty(audioUnit,
    kAUVoiceIOProperty_VoiceProcessingEnableAGC,
    kAudioUnitScope_Global,
    inputBus,
    &off,
    UInt32(MemoryLayout<UInt32>.size))
print("AudioUnitSetProperty returned code:\(osErr)")
// AudioUnitSetProperty returned code:-10879

Am I doing something wrong?

Maysam
  • 7,246
  • 13
  • 68
  • 106

1 Answers1

1

I haven't worked with CoreAudio on iOS, or the Voice Processing AU, but looks like the issue is the subtype you've specified.

The properties in question appear to be specific to the subtype of kAudioUnitSubType_VoiceProcessingIO, but you are instantiating the subtype kAudioUnitSubType_RemoteIO. If you use the former subtype, then the properties should be valid.

user1325158
  • 194
  • 3
  • 9