I realize this is an old question but figured someone might benefit from this anyways.
Maybe I am not understanding your problem really. Do you want to be able to record using the built in mic and then seamlessly switch to record from headset when its plugged in? Or do you simply struggle to record from headset?
I use this code to debug routing issues myself. Just play around with your app, plug in the headset and watch what is logged out in the console. You should make sure the headset you connect causes a "HeadsetInOut" route change. If it is only a "Headphones" it will play sound in headset but record from built in mic.
I have had no issues at all using AudioQueues to record from headset.
void interruptionListener( void * inClientData,
UInt32 inInterruptionState)
{
if (inInterruptionState == kAudioSessionBeginInterruption) {
// handle interruption
}
else if (inInterruptionState == kAudioSessionEndInterruption) {
// handle interruption
}
}
void propListener( void * inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void * inData)
{
FooBar *self = (__bridge FooBar*)inClientData;
if (inID == kAudioSessionProperty_AudioRouteChange) {
CFDictionaryRef routeDictionary = (CFDictionaryRef)inData;
CFNumberRef reason = (CFNumberRef)CFDictionaryGetValue(routeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_Reason));
SInt32 reasonVal;
CFNumberGetValue(reason, kCFNumberSInt32Type, &reasonVal);
if (reasonVal != kAudioSessionRouteChangeReason_CategoryChange) {
// Check the old route
CFStringRef oldRoute = (CFStringRef)CFDictionaryGetValue(routeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_OldRoute));
if (oldRoute) {
NSLog(@"Changed audio route from route:");
CFShow(oldRoute);
} else {
NSLog(@"Error getting old audio route.\n");
}
CFStringRef newRoute;
UInt32 size; size = sizeof(CFStringRef);
OSStatus error = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute);
if (error) {
NSLog(@"Error getting new audio route: %ld\n", error);
}
else {
NSLog(@"Changed audio route to:\n");
CFShow(newRoute);
if (CFStringCompare(newRoute, CFSTR("HeadsetInOut"), 0) == kCFCompareEqualTo)
{
// you can do some recording, yay.
}
}
if (reasonVal == kAudioSessionRouteChangeReason_OldDeviceUnavailable)
{
NSLog(@"kAudioSessionRouteChangeReason_OldDeviceUnavailable");
}
}
}
}
-(id) init
{
self = [super init];
if (self) {
OSStatus error = AudioSessionInitialize(NULL, NULL, interruptionListener, (__bridge void *)(self));
if (error)
{
NSLog(@"Error initializing audio session: %ld\n", error);
} else {
error = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, (__bridge void *)(self));
if (error) {
NSLog(@"Error adding audio session property listener (route change): %ld\n", error);
}
UInt32 inputAvailable = 0;
UInt32 size = sizeof(inputAvailable);
error = AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &inputAvailable);
if (error) {
NSLog(@"Error getting input availability: %ld\n", error);
}
error = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, propListener, (__bridge void *)(self));
if (error) {
NSLog(@"Error adding audio session property listener (input availability): %ld\n", error);
}
// Activate the session
error = AudioSessionSetActive(true);
if (error) {
NSLog(@"Failed to activate audio session: %ld\n", error);
}
}
}
return self;
}