Forcing iPhone Microphone as Audio Input

后端 未结 5 1373
深忆病人
深忆病人 2020-12-03 08:16

I am developing an iOS application (targetted specifically for iPhone, at the moment) that requires the application to record audio only from iPhone internal microph

5条回答
  •  情歌与酒
    2020-12-03 09:03

    Looks like its really not possible.

    My goal is to send output to bluetooth headsets and record input from it too. As far I can see, my best options are: "PlayAndRecord + AllowBluetoothInput" property (iphone 4, nokia BH-214 headset)

    IMPORTANT thing is that according to the apple documentation, you always have to RE-override your audio category when audio route changes!

    THIS IS MY ROUTE CHANGE LISTENER method, that prints: RouteChangeReasons, outputRoute, audioRout:

    void RouteChangeListener(void                    *inClientData,
                         AudioSessionPropertyID  inID,
                         UInt32                  inDataSize,
                         const void              *inData) {
    
    
    if (inID == kAudioSessionProperty_AudioRouteChange) {
    
        NSLog(@"]-----------------[ Audio Route Change ]--------------------[");
    
        // ************************************************************************************************
        // Check route change reason **********************************************************************
        // ************************************************************************************************
        CFDictionaryRef routeDict = (CFDictionaryRef)inData;
        NSNumber* reasonValue = (NSNumber*)CFDictionaryGetValue(routeDict, CFSTR(kAudioSession_AudioRouteChangeKey_Reason));
        int reason = [reasonValue intValue];
    
        if (reason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {
            NSLog(@"] Logic: audio route change reason: OldDeviceUnavailable");
        }else if (reason == kAudioSessionRouteChangeReason_NewDeviceAvailable ) {
            NSLog(@"] Logic: audio route change reason: NewDeviceAvailable");
        }else if (reason == kAudioSessionRouteChangeReason_Unknown ) {
            NSLog(@"] Logic: audio route change reason: Unknown");
        }else if (reason == kAudioSessionRouteChangeReason_CategoryChange ) {
            NSLog(@"] Logic: audio route change reason: CategoryChange");
        }else if (reason == kAudioSessionRouteChangeReason_Override ) {
            NSLog(@"] Logic: audio route change reason: Override");
        }else if (reason == kAudioSessionRouteChangeReason_WakeFromSleep ) {
            NSLog(@"] Logic: audio route change reason: WakeFromSleep");
        }else if (reason == kAudioSessionRouteChangeReason_NoSuitableRouteForCategory ) {
            NSLog(@"] Logic: audio route chang reasone: NoSuitableRouteForCategory");
        }
    
        // ************************************************************************************************
        // Check output type ******************************************************************************
        // ************************************************************************************************
        CFDictionaryRef currentRouteDescriptionDictionary = nil;
        UInt32 dataSize = sizeof(currentRouteDescriptionDictionary);
        AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &dataSize, ¤tRouteDescriptionDictionary);
        if (currentRouteDescriptionDictionary) {
            CFArrayRef outputs = CFDictionaryGetValue(currentRouteDescriptionDictionary, kAudioSession_AudioRouteKey_Outputs);
            if(CFArrayGetCount(outputs) > 0) {
                CFDictionaryRef currentOutput = CFArrayGetValueAtIndex(outputs, 0);
                CFStringRef outputType = CFDictionaryGetValue(currentOutput, kAudioSession_AudioRouteKey_Type);
    
                if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_AirPlay, 0) == kCFCompareEqualTo) ) {                // if Airplay
                    NSLog(@"] Logic: output changed to Airplay");
                }
                else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_BluetoothA2DP, 0) == kCFCompareEqualTo) ) {     // if Bluetooth A2DP
                    NSLog(@"] Logic: output changed to A2DP");
    
                    // Mix with others category
                    UInt32 doSetProperty = 1;
                    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof(doSetProperty),&doSetProperty);
    
                    // Bluetooth support enable
                    UInt32 allowBluetoothInput = 1;
                    AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,sizeof (allowBluetoothInput),&allowBluetoothInput);
    
    
                }
                else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_BluetoothHFP, 0) == kCFCompareEqualTo) ) {     // if Bluetooth HFP
                    NSLog(@"] Logic: output changed to HFP");
                    // Mix with others category
                    UInt32 doSetProperty = 1;
                    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof(doSetProperty),&doSetProperty);
    
                    // Bluetooth support enable
                    UInt32 allowBluetoothInput = 1;
                    AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,sizeof (allowBluetoothInput),&allowBluetoothInput);
                }
                else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_LineOut, 0) == kCFCompareEqualTo) ) {           // if Line Out
                    NSLog(@"] Logic: output changed to Line Out");
                }
                else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_Headphones, 0) == kCFCompareEqualTo) ) {        // if Headphones
                    NSLog(@"] Logic: output changed to Headphone");
    
                    // Mix with others category
                    UInt32 doSetProperty = 1;
                    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof(doSetProperty),&doSetProperty);
    
                    // Bluetooth support disable
                    UInt32 allowBluetoothInput = 0;
                    AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,sizeof (allowBluetoothInput),&allowBluetoothInput);
    
                }
                else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_BuiltInSpeaker, 0) == kCFCompareEqualTo) ) {    // if Built In Speaker
                    NSLog(@"] Logic: output changed to Built In Speaker");
    
                    // Mix with others category
                    UInt32 doSetProperty = 1;
                    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof(doSetProperty),&doSetProperty);
    
                }
                else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_USBAudio, 0) == kCFCompareEqualTo) ) {          // if USB audio
                    NSLog(@"] Logic: output changed to USB Audio");
                }
                else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_HDMI, 0) == kCFCompareEqualTo) ) {              // if HDMI
                    NSLog(@"] Logic: output changed to HDMI");
                }
                else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_BuiltInReceiver, 0) == kCFCompareEqualTo) ) {   // if Built in Reciever
                    NSLog(@"] Logic: output changed to Built in Reciever");
    
                    // Mix with others category
                    UInt32 doSetProperty = 1;
                    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof(doSetProperty),&doSetProperty);
                }
                else {                                                                                                          // Unknown audio type
                    NSLog(@"] Logic: WARNING: Unknown audio type: %@",(NSString*)outputType);
                }
            }
    
    
    
        }
    
        // ************************************************************************************************
        // Check audio route ******************************************************************************
        // ************************************************************************************************
        UInt32 routeSize = sizeof(CFStringRef);
        CFStringRef route;
        AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &routeSize, &route);
        NSLog(@"] Logic: the audio route is: %@",(NSString*)route);
    
    
        // ************************************************************************************************
        NSLog(@"]--------------------------[  ]-----------------------------[");        
    
    }
    

    }

提交回复
热议问题