title: ExtAudioFileWrite producing unusable m4a aac files
body: <p>I am trying to convert a mono linear pcm file to an aac file. After much struggle I finally got it out output using the below settings, but now the file won't play. I really don't know where to look - all of the examples I have found are similar to what I already have.</p>
  
  <p>All of the samples I have seen have destFormat.mBytesPerPacket = 0 but I can't get it to write then (I get a -66567 on the write, which resolves to kExtAudioFileError_MaxPacketSizeUnknown).</p>
  
  <pre><code>ExtAudioFileRef sourceFile = 0;
  ExtAudioFileRef destinationFile = 0;
  OSStatus        error = noErr;
  
  AudioStreamBasicDescription srcFormat, destFormat;
  UInt32 size = sizeof(srcFormat);
  error = ExtAudioFileOpenURL((CFURLRef)self.track.location, &amp;sourceFile);
  if(error != noErr)
      NSLog(@"conversion error: %i", error);
  error = noErr;
  
  ExtAudioFileGetProperty(sourceFile, kExtAudioFileProperty_FileDataFormat, &amp;size, &amp;srcFormat);
  
  destFormat.mFormatID = kAudioFormatMPEG4AAC;
  destFormat.mSampleRate = 22000;
  destFormat.mFormatFlags = 0;
  destFormat.mBytesPerPacket = 2; // must have a value or won't write apparently
  destFormat.mFramesPerPacket = 0;
  destFormat.mBytesPerFrame = 0;
  destFormat.mChannelsPerFrame = 1;
  destFormat.mBitsPerChannel = 0;
  destFormat.mReserved = 0;
  
  //create the output file
  
  NSString *destURL = [self.track.location absoluteString];
  NSLog(@"source url: %@", destURL);
  destURL = [destURL substringToIndex:([destURL length] - 3)]; //remove caf extension
  NSLog(@"source url with no extension: %@", destURL);
  destURL = [NSString stringWithFormat:@"%@m4a",destURL]; //add acc extension
  NSLog(@"dest url with correct extension: %@", destURL);
  NSURL *destinationURL = [NSURL URLWithString:destURL];
  
  size = sizeof(destFormat);
  AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, nil, &amp;size, &amp;destFormat);
  
  error = ExtAudioFileCreateWithURL((CFURLRef)destinationURL, kAudioFileM4AType, &amp;destFormat, NULL, kAudioFileFlags_EraseFile, &amp;destinationFile);
  if(error != noErr)
      NSLog(@"conversion error: %i", error);
  error = noErr;
  
  //canonical format
  AudioStreamBasicDescription clientFormat;
  clientFormat.mFormatID = kAudioFormatLinearPCM;
  clientFormat.mSampleRate = 22000;
  int sampleSize = sizeof(AudioSampleType);
  clientFormat.mFormatFlags = kAudioFormatFlagsCanonical;
  clientFormat.mBitsPerChannel = 8 * sampleSize;
  clientFormat.mChannelsPerFrame = 1;
  clientFormat.mFramesPerPacket = 1;
  clientFormat.mBytesPerPacket = sampleSize;
  clientFormat.mBytesPerFrame = sampleSize;
  clientFormat.mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
  
  //set the intermediate format to canonical on the source file for conversion (?)
  ExtAudioFileSetProperty(sourceFile, kExtAudioFileProperty_ClientDataFormat, size, &amp;clientFormat);
  
  //get the converter
  AudioConverterRef audioConverter;
  size = sizeof(audioConverter);
  error = ExtAudioFileGetProperty(destinationFile, kExtAudioFileProperty_AudioConverter, &amp;size, &amp;audioConverter);
  if(error != noErr)
      NSLog(@"error getting converter: %i", error);
  error = noErr;
  
  /*UInt32 bitRate = 64000;   
  error = AudioConverterSetProperty(audioConverter, kAudioConverterEncodeBitRate, sizeof(bitRate), &amp;bitRate);
  if(error != noErr)
      NSLog(@"error setting bit rate: %i", error);
  error = noErr;*/
  
  // set up buffers
  UInt32 bufferByteSize = 32768;
  char srcBuffer[bufferByteSize];
  
  NSLog(@"converting...");
  
  int i=0;
  while (true) {
      i++;
      AudioBufferList fillBufList;
      fillBufList.mNumberBuffers = 1;
      fillBufList.mBuffers[0].mNumberChannels = 1;
      fillBufList.mBuffers[0].mDataByteSize = bufferByteSize;
      fillBufList.mBuffers[0].mData = srcBuffer;
  
      // client format is always linear PCM - so here we determine how many frames of lpcm
      // we can read/write given our buffer size
      UInt32 numFrames = bufferByteSize / clientFormat.mBytesPerFrame;
  
      error = ExtAudioFileRead(sourceFile, &amp;numFrames, &amp;fillBufList); 
      if(error != noErr)
          NSLog(@"read error: %i run: %i", error, i);
  
      if (!numFrames) {
          // this is our termination condition
          error = noErr;
          break;
      }
  
      //this is the actual conversion
      error = ExtAudioFileWrite(destinationFile, numFrames, &amp;fillBufList);
  
      if(error != noErr)
          NSLog(@"conversion error: %i run: %i", error, i);
  }
  
  if (destinationFile) ExtAudioFileDispose(destinationFile);
  if (sourceFile) ExtAudioFileDispose(sourceFile);
  </code></pre>