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];
    }
}
totalitarian
  • 3,606
  • 6
  • 32
  • 55
  • Can you put log of `session.availableInputs`? – iphonic Jun 30 '14 at 08:02
  • is adapter1 input-only? – Rhythmic Fistman Jun 30 '14 at 14:00
  • Yeah it can only input audio to the iOS device – totalitarian Jun 30 '14 at 14:06
  • Did you check if the error parameters were showing something? – Larme Jun 30 '14 at 15:04
  • Yes there are no errors – totalitarian Jun 30 '14 at 16:24
  • 1
    I think there is something mixed up in the code you posted, maybe during formatting. The last statement contains setPreferredInput twice, so the syntax looks wrong here: [setPreferredInput:(AVAudioSessionPortDescription *)inPort error:(nil)outError session setPreferredInput:destPort error:nil]; – Daniel S. Jul 20 '14 at 17:02
  • I have the same problem with two USB microphones, which are, as seen from the perspective of the iPhone, more or less the same as guitar connectors. It's the same story there: One of the mics acts only as an input device while the other one also acts as an output device. Thus, I can't use the latter mic together with the Speaker (and not with earphones, for that matter). – Daniel S. Jul 20 '14 at 17:06
  • Did you ever figure this out? – Surz Jun 27 '17 at 18:17

1 Answers1

2

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?

Rhythmic Fistman
  • 34,352
  • 5
  • 87
  • 159
  • 1
    Thanks for the write up. No I do need it through the device speakers. At least you are backing up my findings, that the route I am trying to achieve is not possible – totalitarian Jul 01 '14 at 22:08
  • 1
    I agree that it is probably not (currently) possible. I have an app that I would "prefer" to take input through the device microphone, and push output audio through BlueTooth to an external stereo system. Hope one of us can find a correct solution, sounds like they may be similar issues. – TheTwoNotes Oct 13 '14 at 18:50
  • How could this be configured for a USB input and headset output? – Surz Jun 27 '17 at 19:30