2012-04-24 10 views
7

Estoy intentando conectar una AudioUnidad de AudioFilaPlayer a una Unidad de Audio Integrada AU3DMixer, pero no estoy teniendo éxito.¿Cómo conecto una AudioUnidad de AudioFilePlayer a un 3DMixer?

Esto es lo que estoy haciendo:

  1. crear un AUGraph con NewAUGraph()

  2. Abrir la gráfica

  3. inicializar el gráfico

  4. añadir 3 nodos:

    • outputNode: kAudioUnitSubType_RemoteIO
    • mixerNode: kAudioUnitSubType_AU3DMixerEmbedded
    • filePlayerNode: kAudioUnitSubType_AudioFilePlayer
  5. conectar los nodos:

    • filePlayerNode -> mixerNode
    • mixerNode -> outputNode
  6. configurar la unidad de audio filePlayer para reproducir el archivo requerido

  7. Iniciar el gráfico

Esto no funciona: no acompañó AUGraphInitialize con el error 10868 (kAudioUnitErr_FormatNotSupported). Creo que el problema se debe a la falta de correspondencia del formato de audio entre filePlayer y el mezclador. Creo que esto porque: - Si comento a conectar el filePlayerNode al mixerNode (AUGraphConnectNodeInput(_graph, filePlayerNode, 0, mixerNode, 0)) y comento el paso 6, no se informan errores. - Si reemplazo el paso 3 conectando el filePlayerNode directamente al outputNode (AUGraphConnectNodeInput(_graph, filePlayerNode, 0, outputNode, 0)), se reproduce el audio.

¿Qué pasos me faltan al conectar el filePlayerNode al mixerNode?

Aquí está el código completo. Se basa en el código de muestra de Apple y en otras muestras que he encontrado en las redes internas. (AUGraphStart se llama este último):

- (id)init 
{ 
    self = [super init]; 
    if (self != nil) 
    { 
     { 
      //create a new AUGraph 
      CheckError(NewAUGraph(&_graph), "NewAUGraph failed");   
      // opening the graph opens all contained audio units but does not allocate any resources yet    
      CheckError(AUGraphOpen(_graph), "AUGraphOpen failed");     
      // now initialize the graph (causes resources to be allocated) 
      CheckError(AUGraphInitialize(_graph), "AUGraphInitialize failed");      
     } 

     AUNode outputNode; 
     { 
      AudioComponentDescription outputAudioDesc = {0}; 
      outputAudioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;    
      outputAudioDesc.componentType = kAudioUnitType_Output; 
      outputAudioDesc.componentSubType = kAudioUnitSubType_RemoteIO; 
      // adds a node with above description to the graph 
      CheckError(AUGraphAddNode(_graph, &outputAudioDesc, &outputNode), "AUGraphAddNode[kAudioUnitSubType_DefaultOutput] failed"); 
     } 

     AUNode mixerNode; 
     { 
      AudioComponentDescription mixerAudioDesc = {0}; 
      mixerAudioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;         
      mixerAudioDesc.componentType = kAudioUnitType_Mixer; 
      mixerAudioDesc.componentSubType = kAudioUnitSubType_AU3DMixerEmbedded; 
      mixerAudioDesc.componentFlags = 0; 
      mixerAudioDesc.componentFlagsMask = 0; 
      // adds a node with above description to the graph 
      CheckError(AUGraphAddNode(_graph, &mixerAudioDesc, &mixerNode), "AUGraphAddNode[kAudioUnitSubType_AU3DMixerEmbedded] failed");    
     } 

     AUNode filePlayerNode;    
     { 
      AudioComponentDescription fileplayerAudioDesc = {0};    
      fileplayerAudioDesc.componentType = kAudioUnitType_Generator; 
      fileplayerAudioDesc.componentSubType = kAudioUnitSubType_AudioFilePlayer; 
      fileplayerAudioDesc.componentManufacturer = kAudioUnitManufacturer_Apple; 
      // adds a node with above description to the graph 
      CheckError(AUGraphAddNode(_graph, &fileplayerAudioDesc, &filePlayerNode), "AUGraphAddNode[kAudioUnitSubType_AudioFilePlayer] failed"); 
     } 

     //Connect the nodes 
     { 
      // connect the output source of the file player AU to the input source of the output node    
//   CheckError(AUGraphConnectNodeInput(_graph, filePlayerNode, 0, outputNode, 0), "AUGraphConnectNodeInput");       

      CheckError(AUGraphConnectNodeInput(_graph, filePlayerNode, 0, mixerNode, 0), "AUGraphConnectNodeInput"); 
      CheckError(AUGraphConnectNodeInput(_graph, mixerNode, 0, outputNode, 0), "AUGraphConnectNodeInput");          
     } 



     // configure the file player 
     // tell the file player unit to load the file we want to play 
     { 
      //????? 
      AudioStreamBasicDescription inputFormat; // input file's data stream description 
      AudioFileID inputFile; // reference to your input file    

      // open the input audio file and store the AU ref in _player 
      CFURLRef songURL = (__bridge CFURLRef)[[NSBundle mainBundle] URLForResource:@"monoVoice" withExtension:@"aif"]; 
      CheckError(AudioFileOpenURL(songURL, kAudioFileReadPermission, 0, &inputFile), "AudioFileOpenURL failed"); 

      //create an empty MyAUGraphPlayer struct 
      AudioUnit fileAU; 

      // get the reference to the AudioUnit object for the file player graph node 
      CheckError(AUGraphNodeInfo(_graph, filePlayerNode, NULL, &fileAU), "AUGraphNodeInfo failed"); 

      // get and store the audio data format from the file 
      UInt32 propSize = sizeof(inputFormat); 
      CheckError(AudioFileGetProperty(inputFile, kAudioFilePropertyDataFormat, &propSize, &inputFormat), "couldn't get file's data format");    

      CheckError(AudioUnitSetProperty(fileAU, kAudioUnitProperty_ScheduledFileIDs, kAudioUnitScope_Global, 0, &(inputFile), sizeof((inputFile))), "AudioUnitSetProperty[kAudioUnitProperty_ScheduledFileIDs] failed"); 

      UInt64 nPackets; 
      UInt32 propsize = sizeof(nPackets); 
      CheckError(AudioFileGetProperty(inputFile, kAudioFilePropertyAudioDataPacketCount, &propsize, &nPackets), "AudioFileGetProperty[kAudioFilePropertyAudioDataPacketCount] failed"); 

      // tell the file player AU to play the entire file 
      ScheduledAudioFileRegion rgn; 
      memset (&rgn.mTimeStamp, 0, sizeof(rgn.mTimeStamp)); 
      rgn.mTimeStamp.mFlags = kAudioTimeStampSampleTimeValid; 
      rgn.mTimeStamp.mSampleTime = 0; 
      rgn.mCompletionProc = NULL; 
      rgn.mCompletionProcUserData = NULL; 
      rgn.mAudioFile = inputFile; 
      rgn.mLoopCount = 1; 
      rgn.mStartFrame = 0; 
      rgn.mFramesToPlay = nPackets * inputFormat.mFramesPerPacket; 

      CheckError(AudioUnitSetProperty(fileAU, kAudioUnitProperty_ScheduledFileRegion, kAudioUnitScope_Global, 0,&rgn, sizeof(rgn)), "AudioUnitSetProperty[kAudioUnitProperty_ScheduledFileRegion] failed"); 

      // prime the file player AU with default values 
      UInt32 defaultVal = 0; 
      CheckError(AudioUnitSetProperty(fileAU, kAudioUnitProperty_ScheduledFilePrime, kAudioUnitScope_Global, 0, &defaultVal, sizeof(defaultVal)), "AudioUnitSetProperty[kAudioUnitProperty_ScheduledFilePrime] failed"); 

      // tell the file player AU when to start playing (-1 sample time means next render cycle) 
      AudioTimeStamp startTime; 
      memset (&startTime, 0, sizeof(startTime)); 
      startTime.mFlags = kAudioTimeStampSampleTimeValid; 
      startTime.mSampleTime = -1; 
      CheckError(AudioUnitSetProperty(fileAU, kAudioUnitProperty_ScheduleStartTimeStamp, kAudioUnitScope_Global, 0, &startTime, sizeof(startTime)), "AudioUnitSetProperty[kAudioUnitProperty_ScheduleStartTimeStamp]"); 

      // file duration 
      //double duration = (nPackets * _player.inputFormat.mFramesPerPacket)/_player.inputFormat.mSampleRate; 
     }    


    } 
    return self; 
} 
+4

Me encanta el uso de los bloques '{...}' para envolver las variables intermedias y organizar el código ... –

+0

Posesión remota, pero estoy teniendo el mismo problema. ¿Cuál era el formato aceptable al final? –

+1

gracias por el código. :). Por cierto, funciona para mí. Acabo de agregar AUGraphStart (gráfico) –

Respuesta

3

no veo en el código donde se establece el kAudioUnitProperty_StreamFormat apropiado para las unidades de audio. También deberá verificar los códigos de resultado de error para ver si la configuración de formato de flujo que elige es realmente compatible con la unidad de audio que se está configurando. Si no, pruebe con otro formato.

0

(AUGraphConnectNodeInput (_graph, filePlayerNode, 0, mixerNode, 0)) (AUGraphConnectNodeInput (_graph, mixerNode, 0, outputNode, 0))

trate de hacer de esta manera si se puede help.Just para obtener información de la izquierda el nodo se ingresa en el nodo derecho. de modo que en la primera línea, el nodo reproductor se ingresa al nodo mezclador, ahora el nodo mezclador contiene tanto el reproductor como el mezclador, así que agregue el nodo mezclador al nodo de salida.

Cuestiones relacionadas