2011-05-09 14 views
15

¿Es posible redirigir la salida de audio al altavoz del teléfono y seguir utilizando la entrada de auriculares del micrófono?Redirigir la salida de audio al altavoz del teléfono y la entrada de micrófono a los auriculares

Si redirijo la ruta de audio al altavoz del teléfono en lugar de a los auriculares, también redirige el micrófono. Esto tiene sentido, pero parece que no puedo simplemente redireccionar la entrada del micrófono. ¿Algunas ideas?

Aquí está el código que estoy usando para redirigir el audio al altavoz:

UInt32 doChangeDefaultRoute = true;   
propertySetError = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute); 
NSAssert(propertySetError == 0, @"Failed to set audio session property: OverrideCategoryDefaultToSpeaker"); 
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; 
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride); 
+1

Probablemente sepa esto, pero cuando habilita el altavoz también habilita el micrófono en el teléfono. Sin embargo, en el iPod, si habilita el altavoz, aún podrá obtener el sonido del micrófono de los auriculares. Prob previsto ya que no hay micrófono en el ipod. Obtuve brevemente una aplicación ios 4.3 sdk para obtener el micrófono de la salida de auriculares y altavoces, inicie el AUgraph nuevamente después del cambio de ruta, pero sucedió intermitentemente y ahora no sucede en absoluto (ios 4.3+ xcode 4+) – zeAttle

Respuesta

4

No se ve como si fuera posible, me temo.

Desde el Audio Session Programming Guide - kAudioSessionProperty_OverrideAudioRoute

Si un auricular está enchufado en el momento de configurar el valor de esta propiedad a kAudioSessionOverrideAudioRoute_Speaker, el sistema cambia el direccionamiento de audio para la entrada como para la salida: entrada viene desde el micrófono incorporado; la salida va al altavoz incorporado.

duplicado Posible de this question

+0

It podría valer la pena seguir los mismos pasos que Tommy en [esta pregunta] (http://stackoverflow.com/questions/4002133/forcing-iphone-microphone-as-audio-input) para encontrar 'AVCaptureDevice's disponibles –

6

Esto es posible, pero es exigente con la forma en que lo creó.

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; 
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride); 

Es muy importante utilizar AVAudioSessionCategoryPlayAndRecord o la ruta dejará de ir al altavoz. Una vez que haya establecido la ruta de anulación para la sesión de audio, puede usar una instancia de AVAudioPlayer y enviar alguna salida al altavoz.

Espero que funcione para otros como lo hizo para mí. La documentación sobre esto está dispersa, pero la aplicación de Skype demuestra que es posible. Persevera, mis amigos! :)

Parte de la documentación de Apple aquí: http://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/AudioSessionServicesReference/Reference/reference.html

hacer una búsqueda en la página de kAudioSessionProperty_OverrideAudioRoute

2

Lo que puede hacer es forzar la salida de audio a los altavoces en todo caso:

De UI Hacker - iOS: Force audio output to speakers while headphones are plugged in

@interface AudioRouter : NSObject 

+ (void) initAudioSessionRouting; 
+ (void) switchToDefaultHardware; 
+ (void) forceOutputToBuiltInSpeakers; 

@end 

y

#import "AudioRouter.h" 
#import <AudioToolbox/AudioToolbox.h> 
#import <AVFoundation/AVFoundation.h> 

@implementation AudioRouter 

#define IS_DEBUGGING NO 
#define IS_DEBUGGING_EXTRA_INFO NO 

+ (void) initAudioSessionRouting { 

    // Called once to route all audio through speakers, even if something's plugged into the headphone jack 
    static BOOL audioSessionSetup = NO; 
    if (audioSessionSetup == NO) { 

     // set category to accept properties assigned below 
     NSError *sessionError = nil; 
     [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error: &sessionError]; 

     // Doubly force audio to come out of speaker 
     UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; 
     AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride); 

     // fix issue with audio interrupting video recording - allow audio to mix on top of other media 
     UInt32 doSetProperty = 1; 
     AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty); 

     // set active 
     [[AVAudioSession sharedInstance] setDelegate:self]; 
     [[AVAudioSession sharedInstance] setActive: YES error: nil]; 

     // add listener for audio input changes 
     AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, onAudioRouteChange, nil); 
     AudioSessionAddPropertyListener (kAudioSessionProperty_AudioInputAvailable, onAudioRouteChange, nil); 

    } 

    // Force audio to come out of speaker 
    [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil]; 


    // set flag 
    audioSessionSetup = YES; 
} 

+ (void) switchToDefaultHardware { 
    // Remove forcing to built-in speaker 
    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None; 
    AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride); 
} 

+ (void) forceOutputToBuiltInSpeakers { 
    // Re-force audio to come out of speaker 
    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; 
    AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride); 


} 

void onAudioRouteChange (void* clientData, AudioSessionPropertyID inID, UInt32 dataSize, const void* inData) { 

    if(IS_DEBUGGING == YES) { 
     NSLog(@"==== Audio Harware Status ===="); 
     NSLog(@"Current Input: %@", [AudioRouter getAudioSessionInput]); 
     NSLog(@"Current Output: %@", [AudioRouter getAudioSessionOutput]); 
     NSLog(@"Current hardware route: %@", [AudioRouter getAudioSessionRoute]); 
     NSLog(@"=============================="); 
    } 

    if(IS_DEBUGGING_EXTRA_INFO == YES) { 
     NSLog(@"==== Audio Harware Status (EXTENDED) ===="); 
     CFDictionaryRef dict = (CFDictionaryRef)inData; 
     CFNumberRef reason = CFDictionaryGetValue(dict, kAudioSession_RouteChangeKey_Reason); 
     CFDictionaryRef oldRoute = CFDictionaryGetValue(dict, kAudioSession_AudioRouteChangeKey_PreviousRouteDescription); 
     CFDictionaryRef newRoute = CFDictionaryGetValue(dict, kAudioSession_AudioRouteChangeKey_CurrentRouteDescription); 
     NSLog(@"Audio old route: %@", oldRoute); 
     NSLog(@"Audio new route: %@", newRoute); 
     NSLog(@"========================================="); 
    } 



} 

+ (NSString*) getAudioSessionInput { 
    UInt32 routeSize; 
    AudioSessionGetPropertySize(kAudioSessionProperty_AudioRouteDescription, &routeSize); 
    CFDictionaryRef desc; // this is the dictionary to contain descriptions 

    // make the call to get the audio description and populate the desc dictionary 
    AudioSessionGetProperty (kAudioSessionProperty_AudioRouteDescription, &routeSize, &desc); 

    // the dictionary contains 2 keys, for input and output. Get output array 
    CFArrayRef outputs = CFDictionaryGetValue(desc, kAudioSession_AudioRouteKey_Inputs); 

    // the output array contains 1 element - a dictionary 
    CFDictionaryRef diction = CFArrayGetValueAtIndex(outputs, 0); 

    // get the output description from the dictionary 
    CFStringRef input = CFDictionaryGetValue(diction, kAudioSession_AudioRouteKey_Type); 
    return [NSString stringWithFormat:@"%@", input]; 
} 

+ (NSString*) getAudioSessionOutput { 
    UInt32 routeSize; 
    AudioSessionGetPropertySize(kAudioSessionProperty_AudioRouteDescription, &routeSize); 
    CFDictionaryRef desc; // this is the dictionary to contain descriptions 

    // make the call to get the audio description and populate the desc dictionary 
    AudioSessionGetProperty (kAudioSessionProperty_AudioRouteDescription, &routeSize, &desc); 

    // the dictionary contains 2 keys, for input and output. Get output array 
    CFArrayRef outputs = CFDictionaryGetValue(desc, kAudioSession_AudioRouteKey_Outputs); 

    // the output array contains 1 element - a dictionary 
    CFDictionaryRef diction = CFArrayGetValueAtIndex(outputs, 0); 

    // get the output description from the dictionary 
    CFStringRef output = CFDictionaryGetValue(diction, kAudioSession_AudioRouteKey_Type); 
    return [NSString stringWithFormat:@"%@", output]; 
} 

+ (NSString*) getAudioSessionRoute { 
    /* 
    returns the current session route: 
    * ReceiverAndMicrophone 
    * HeadsetInOut 
    * Headset 
    * HeadphonesAndMicrophone 
    * Headphone 
    * SpeakerAndMicrophone 
    * Speaker 
    * HeadsetBT 
    * LineInOut 
    * Lineout 
    * Default 
    */ 

    UInt32 rSize = sizeof (CFStringRef); 
    CFStringRef route; 
    AudioSessionGetProperty (kAudioSessionProperty_AudioRoute, &rSize, &route); 

    if (route == NULL) { 
     NSLog(@"Silent switch is currently on"); 
     return @"None"; 
    } 
    return [NSString stringWithFormat:@"%@", route]; 
} 

@end 
Cuestiones relacionadas