title: Corrupt recording with repeating audio in IOS
body: <p>My application records streaming audio on iPhone. My problem is that a small percent (~2%) of the recordings are corrupted. They appear to have some audio buffers duplicated. </p>
  
  <p>For example listen to <a href="https://s3.amazonaws.com/evature-static/corrupt_recording.flac" rel="nofollow">this file</a>.</p>
  
  <hr>
  
  <p><strong>Edit:</strong> A surprising thing is that looking closely at the data using Audacity shows the repeating parts are very very similar but not identical. Since FLAC (the format I use for encoding the audio) is a loss-less compression, I guess this is not a bug in the streaming/encoding but the problem originates at the data that comes from the microphone!</p>
  
  <hr>
  
  <p>Below is the code I use to setup the audio recording streaming - is there anything wrong with it?</p>
  
  <pre><code>// see functions implementation below
  - (void)startRecording
  {
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
                 , ^{
          [self setUpRecordQueue];
          [self setUpRecordQueueBuffers];
          [self primeRecordQueueBuffers];
          AudioQueueStart(recordQueue, NULL);
      });
  }
  
  
  
  // this is called only once before any recording takes place
  - (void)setUpAudioFormat
  {
      AudioSessionInitialize(
                             NULL,
                             NULL,
                             nil,
                             (__bridge  void *)(self)
                             );
  
          UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
          AudioSessionSetProperty(
                              kAudioSessionProperty_AudioCategory,
                              sizeof(sessionCategory),
                              &amp;sessionCategory
                              );
  
          AudioSessionSetActive(true);
  
      audioFormat.mFormatID         = kAudioFormatLinearPCM;
      audioFormat.mSampleRate       = SAMPLE_RATE;//16000.0;
      audioFormat.mChannelsPerFrame = CHANNELS;//1;
      audioFormat.mBitsPerChannel   = 16;
      audioFormat.mFramesPerPacket  = 1;
      audioFormat.mBytesPerFrame    = audioFormat.mChannelsPerFrame * sizeof(SInt16);
      audioFormat.mBytesPerPacket   = audioFormat.mBytesPerFrame * audioFormat.mFramesPerPacket;
      audioFormat.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
  
      bufferNumPackets = 2048;  // must be power of 2 for FFT!
      bufferByteSize = [self byteSizeForNumPackets:bufferNumPackets];
  }
  
  // I suspect the duplicate buffers arrive here:
  static void recordCallback(
                         void* inUserData,
                         AudioQueueRef inAudioQueue,
                         AudioQueueBufferRef inBuffer,
                         const AudioTimeStamp* inStartTime,
                         UInt32 inNumPackets,
                         const AudioStreamPacketDescription* inPacketDesc)
  {
       Recorder* recorder = (__bridge Recorder*) inUserData;
      if (inNumPackets &gt; 0)
      {
          // append the buffer to FLAC encoder
          [recorder recordedBuffer:inBuffer-&gt;mAudioData byteSize:inBuffer-&gt;mAudioDataByteSize packetsNum:inNumPackets];
      }
  
      AudioQueueEnqueueBuffer(inAudioQueue, inBuffer, 0, NULL);
  
  }
  
  
  - (void)setUpRecordQueue
  {
       OSStatus errorStatus = AudioQueueNewInput(
                     &amp;audioFormat,
                     recordCallback,
                     (__bridge void *)(self),                // userData
                     CFRunLoopGetMain(),  // run loop
                     NULL,                // run loop mode
                     0,                   // flags
                     &amp;recordQueue);
         UInt32 trueValue = true;
        AudioQueueSetProperty(recordQueue,kAudioQueueProperty_EnableLevelMetering,&amp;trueValue,sizeof (UInt32));
  }
  
  - (void)setUpRecordQueueBuffers
  {
      for (int t = 0; t &lt; NUMBER_AUDIO_DATA_BUFFERS; ++t)
      {
           OSStatus errorStatus = AudioQueueAllocateBuffer(
                               recordQueue,
                               bufferByteSize,
                               &amp;recordQueueBuffers[t]);
      }
  }
  
  - (void)primeRecordQueueBuffers
  {
      for (int t = 0; t &lt; NUMBER_AUDIO_DATA_BUFFERS; ++t)
      {
          OSStatus errorStatus = AudioQueueEnqueueBuffer(
                              recordQueue,
                              recordQueueBuffers[t],
                              0,
                              NULL);
      }
  }
  </code></pre>