2012-04-24 11 views
7

Sto provando a connettere AudioUnità AudioFilePlayer a un'unità audio AU3DMixer incorporata, ma non sto avendo successo.Come collegare un AudioFilePlayer AudioUnit a un 3DMixer?

Ecco quello che sto facendo:

  1. creare un AUGraph con NewAUGraph()

  2. Aprire il grafico

  3. inizializzare il grafico

  4. Aggiungi 3 nodi:

    • outputNode: kAudioUnitSubType_RemoteIO
    • mixerNode: kAudioUnitSubType_AU3DMixerEmbedded
    • filePlayerNode: kAudioUnitSubType_AudioFilePlayer
  5. connettere i nodi:

    • filePlayerNode -> mixerNode
    • mixerNode -> outputNode
  6. configurare l'unità Audio filePlayer per riprodurre il file richiesto

  7. Avviare il grafico

Questo non funziona: si esita a AUGraphInitialize con l'errore 10868 (kAudioUnitErr_FormatNotSupported). Penso che il problema sia dovuto alla mancata corrispondenza del formato audio tra filePlayer e il mixer. Penso che questo: - Se commento la connessione di filePlayerNode al MixNode (AUGraphConnectNodeInput(_graph, filePlayerNode, 0, mixerNode, 0)) e commentare il passaggio 6 quindi non vengono segnalati errori. - Se sostituisco il passaggio 3 con il collegamento di filePlayerNode direttamente a outputNode (AUGraphConnectNodeInput(_graph, filePlayerNode, 0, outputNode, 0)), l'audio viene riprodotto.

Quali passaggi mi mancano nel collegamento di filePlayerNode al mixerNode?

Ecco il codice completo. È basato sul codice di esempio di Apple e su altri campioni che ho trovato dagli interwebs. (AUGraphStart si chiama quest'ultimo):

- (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

Amo il tuo uso dei blocchi '{...}' per racchiudere le variabili intermedie e organizzare il codice ... –

+0

Scatto lungo, ma sto avendo lo stesso problema. Qual è stato il formato accettabile alla fine? –

+1

grazie per il codice. :). btw funziona per me. Ho appena aggiunto AUGraphStart (grafico) –

risposta

3

non vedo nel codice in cui si imposta la kAudioUnitProperty_StreamFormat appropriata per le unità audio. Dovrai anche controllare i codici dei risultati dell'errore per vedere se l'impostazione del formato del flusso che scegli sia effettivamente supportata dall'unità audio che si sta configurando. In caso contrario, prova un altro formato.

0

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

provare a fare in questo modo se si può help.Just per informazioni sinistra il nodo è inserito nel nodo giusto. così in prima linea il nodo giocatore viene immesso nel nodo del mixer, ora il nodo del mixer contiene sia il player che il mixer, quindi aggiungi il nodo del mixer al nodo di output.

Problemi correlati