title: How do I connect an AudioFilePlayer AudioUnit to a 3DMixer?
body: <p>I am trying to connect an AudioFilePlayer AudioUnit to an AU3DMixerEmbedded Audio Unit, but I'm having no success.</p>
  
  <p>Here's what I'm doing:</p>
  
  <ol>
  <li><p>create an <code>AUGraph</code> with <code>NewAUGraph()</code></p></li>
  <li><p>Open the graph</p></li>
  <li><p>Initalize the graph</p></li>
  <li><p>Add 3 nodes:</p>
  
  <ul>
  <li>outputNode: <code>kAudioUnitSubType_RemoteIO</code></li>
  <li>mixerNode: <code>kAudioUnitSubType_AU3DMixerEmbedded</code></li>
  <li>filePlayerNode: <code>kAudioUnitSubType_AudioFilePlayer</code></li>
  </ul></li>
  <li><p>Connect the nodes:</p>
  
  <ul>
  <li>filePlayerNode -> mixerNode</li>
  <li>mixerNode -> outputNode</li>
  </ul></li>
  <li><p>Configure the filePlayer Audio Unit to play the required file</p></li>
  <li><p>Start the graph</p></li>
  </ol>
  
  <p>This doesn't work: it balks at AUGraphInitialize with error 10868 (kAudioUnitErr_FormatNotSupported). I think the problem is due to audio format mismatch between the filePlayer and the mixer. I think this because:
  - If I comment out connecting the filePlayerNode to the mixerNode (<code>AUGraphConnectNodeInput(_graph, filePlayerNode, 0, mixerNode, 0)</code>) and comment out step 6 then no errors are reported.
  - If I replace step 3 with connecting the filePlayerNode directly to the outputNode (<code>AUGraphConnectNodeInput(_graph, filePlayerNode, 0, outputNode, 0)</code>) then the audio plays.</p>
  
  <p>What steps am I missing in connecting the filePlayerNode to the mixerNode?</p>
  
  <p>Here's the code in full. It's based on Apple's sample code and other samples I've found from the interwebs. (<code>AUGraphStart</code> is called latter):</p>
  
  <pre><code>- (id)init
  {
      self = [super init];
      if (self != nil)
      {
          {
              //create a new AUGraph
              CheckError(NewAUGraph(&amp;_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, &amp;outputAudioDesc, &amp;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, &amp;mixerAudioDesc, &amp;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, &amp;fileplayerAudioDesc, &amp;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, &amp;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, &amp;fileAU), "AUGraphNodeInfo failed");
  
              // get and store the audio data format from the file
              UInt32 propSize = sizeof(inputFormat);
              CheckError(AudioFileGetProperty(inputFile, kAudioFilePropertyDataFormat, &amp;propSize, &amp;inputFormat), "couldn't get file's data format");            
  
              CheckError(AudioUnitSetProperty(fileAU, kAudioUnitProperty_ScheduledFileIDs, kAudioUnitScope_Global, 0, &amp;(inputFile), sizeof((inputFile))), "AudioUnitSetProperty[kAudioUnitProperty_ScheduledFileIDs] failed");
  
              UInt64 nPackets;
              UInt32 propsize = sizeof(nPackets);
              CheckError(AudioFileGetProperty(inputFile, kAudioFilePropertyAudioDataPacketCount, &amp;propsize, &amp;nPackets), "AudioFileGetProperty[kAudioFilePropertyAudioDataPacketCount] failed");
  
              // tell the file player AU to play the entire file
              ScheduledAudioFileRegion rgn;
              memset (&amp;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,&amp;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, &amp;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 (&amp;startTime, 0, sizeof(startTime));
              startTime.mFlags = kAudioTimeStampSampleTimeValid;
              startTime.mSampleTime = -1;
              CheckError(AudioUnitSetProperty(fileAU, kAudioUnitProperty_ScheduleStartTimeStamp, kAudioUnitScope_Global, 0, &amp;startTime, sizeof(startTime)), "AudioUnitSetProperty[kAudioUnitProperty_ScheduleStartTimeStamp]");
  
              // file duration
              //double duration = (nPackets * _player.inputFormat.mFramesPerPacket) / _player.inputFormat.mSampleRate;
          }            
  
  
      }
      return self;
  }
  </code></pre>