5

I have a pair of bluetooth headphones with microphone input. The microphone is not used, but when it is, both input and output is forced to 8000kHz.

My AVAudioEngine instance connects to the headset in 8000kHz mode, unless I enter the system settings and specify that I do not want to use the headset for input (which has to be done every time the headset is connected).

I have noticed that other applications can play back at the expected 44100kHz without issues. There are no input nodes in my AVAudioEngine graph.

How can I make AVAudioEngine prefer connecting at reasonable sample rates?

Henrik
  • 3,908
  • 27
  • 48
  • This is related to https://stackoverflow.com/questions/31501961 and https://stackoverflow.com/questions/26728250. – Henrik Sep 22 '17 at 16:11

1 Answers1

4

After my failed bounty I wrote to Apple DTS, and got a wonderful response (including the code sample below that I translated from Objective-C).

The function below will connect to the default audio device in output-only mode, instead of the inout/output mode that is the default behavior. Remember to call it before engine start!

func setOutputDeviceFor(_ engine: AVAudioEngine) -> Bool {
    var addr = AudioObjectPropertyAddress(
        mSelector: kAudioHardwarePropertyDefaultOutputDevice,
        mScope: kAudioObjectPropertyScopeGlobal,
        mElement: kAudioObjectPropertyElementMaster)

    var deviceID: AudioObjectID = 0
    var size = UInt32(MemoryLayout.size(ofValue: deviceID))
    let err = AudioObjectGetPropertyData(
        AudioObjectID(kAudioObjectSystemObject),
        &addr,
        0,
        nil,
        &size,
        &deviceID)

    if (noErr == err && kAudioDeviceUnknown != deviceID) {
        do {
            try engine.outputNode.auAudioUnit.setDeviceID(deviceID)
        } catch {
            print(error)
            return false
        }
        return true
    } else {
        print("ERROR: couldn't get default output device, ID = \(deviceID), err = \(err)")
        return false
    }
}
Henrik
  • 3,908
  • 27
  • 48
  • Hey Henrik, did the Apple engineers tell you why or where exactly this code connects in output-only mode? Does this mean that when not explicitly connecting to the output device the engine will connect to both, default input and default output? – Gary Nov 26 '17 at 13:03
  • I did not get any details as to why the default is as it is. But yes, by default it connects to both. The reason the above code connects only to the output element is because it does not specify an input, only "kAudioHardwarePropertyDefaultOutputDevice". – Henrik Nov 26 '17 at 16:51