2

When a mic is plugged in, my app continues recording from the built in mic (I would like to use the plugged in mic). I am using:

[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];

I am hoping to avoid queue services or anything deeper for something so simple.

After doing some research (with apples documentation) I can't find a way to do this with queues either...

After further research I can't figure out how to do this at all. It is not mentioned in any apple documentation or any constants, etc. There is an app called "FiRe" that does it so I know it's possible.

John
  • 1,519
  • 3
  • 13
  • 24
  • Strange, from what I am reading here http://stackoverflow.com/questions/4002133/forcing-iphone-microphone-as-audio-input I would expect it by default to make the switch automatically. – P i Jun 11 '11 at 01:58
  • Indeed it should, though you might need to stop recording and resume it to recognize the route change – russbishop Dec 30 '11 at 20:56

1 Answers1

0

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;
}
oehman
  • 249
  • 4
  • 12