How to set iOS app to use usb audio for input and

2019-04-18 16:17发布

问题:

I have 2 different makes of guitar adapters that connect to my iphone using the lightning connector

When adapter 1 is plugged in, the device becomes a usb audio mic and it plays the sound through my iPhone's speakers as the adapter does not contain a headphone socket

When adapter 2 is plugged in, the device becomes a usb audio mic but plays the sound through the headphone socket on the adapter.

I'm trying to write an app that work with adapter 2, but rather than output the sound to the adapter's headphone socket, I want to route it through the iPhone's speakers.

The code below should work, but what i'm finding is that calling AVAudioSessionPortOverride with the AVAudioSessionPortOverrideSpeaker option and the audio session’s category is AVAudioSessionCategoryPlayAndRecord causes audio to use the built-in speaker and microphone regardless of other settings, basically ignoring setPreferredInput

I can't quite understand how adapter 1 manages to take input from usb audio and output to speaker but my app can't because of the restrictions above. Anyone know of a solution?

AVAudioSession* session = [AVAudioSession sharedInstance];
//Set the audioSession category. Needs to be Record or PlayAndRecord to use audioRouteOverride:
[session    setCategory:AVAudioSessionCategoryPlayAndRecord 
            withOptions:AVAudioSessionCategoryOptionMixWithOthers 
            error:nil];

//set the audioSession override
[session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker 
error:nil];

//activate the audio session
[session setActive:YES error:nil];

//set input to usb
for (AVAudioSessionPortDescription *destPort in session.availableInputs){
    if ([destPort.portType isEqualToString:AVAudioSessionPortUSBAudio]) {
        [setPreferredInput:(AVAudioSessionPortDescription *)inPort
                error:(nil)outError
                session setPreferredInput:destPort error:nil];
    }
}

回答1:

I think you can only achieve input via USB device and output through the speakers when the USB device has no audio output component.

I can't find any documentation that says exactly this, but my reasoning is as follows:

Mixing and matching audio devices is done via the generalised version of AVAudioSessionCategoryPlayAndRecord, the so called multi-route category (AVAudioSessionCategoryMultiRoute) and its documentation in AVAudioSession.h says that

  1. Input is limited to the last-in input port.
  2. AVAudioSessionPortBuiltInSpeaker is only allowed to be used when there are no other eligible outputs connected

Point 1 is not a problem, but point 2 disallows your adapter 2 scenario.

NB This would allow adapter 1 & 2 to both work with USB input and line-out or headphones. Would that be of any use to you?



回答2:

This is a bit of a long shot, but have you tried..

[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil]

..instead of overrideOutputAudioPort:?