title: Synchronising with Core Audio Thread
body: <p>I am using the render callback of the ioUnit to store the audio data into a circular buffer:</p>
  
  <pre><code>OSStatus ioUnitRenderCallback(
                            void *inRefCon,
                            AudioUnitRenderActionFlags *ioActionFlags,
                            const AudioTimeStamp *inTimeStamp,
                            UInt32 inBusNumber,
                            UInt32 inNumberFrames,
                            AudioBufferList *ioData)
  {
      OSStatus err = noErr;
  
      AMNAudioController *This = (__bridge AMNAudioController*)inRefCon;
  
      err = AudioUnitRender(This.encoderMixerNode-&gt;unit,
                            ioActionFlags,
                            inTimeStamp,
                            inBusNumber,
                            inNumberFrames,
                            ioData);
  
      // Copy the audio to the encoder buffer
      TPCircularBufferCopyAudioBufferList(&amp;(This-&gt;encoderBuffer), ioData, inTimeStamp, kTPCircularBufferCopyAll, NULL);
  
      return err;
  }
  </code></pre>
  
  <p>I then want to read the bytes out of the circular buffer, feed them to libLame and then to libShout.
  I have tried starting a thread and using NSCondition to make it wait until data is available but this causes all sorts of issues due to using locks on the Core Audio callback.</p>
  
  <p>What would be the recommended way to do this?</p>
  
  <p>Thanks in advance.</p>
  
  <hr>
  
  <h2>More detail on how I implemented Adam's answer</h2>
  
  <p>I ended up taking Adam's advice and implemented it like so.</p>
  
  <p><strong>Producer</strong></p>
  
  <p>I use TPCircularBufferProduceBytes in the Core Audio Render callback to add the bytes to the circular buffer. In my case I have non-interleaved audio data so I ended up using two circular buffers.</p>
  
  <p><strong>Consumer</strong></p>
  
  <ol>
  <li>I spawn a new thread using pthread_create</li>
  <li>Within the new thread create a new CFTimer and add it to the current
  CFRunLoop (an interval of 0.005 seconds appears to work well)</li>
  <li>I tell the current CFRunLoop to run</li>
  <li>Within my timer callback I encode the audio and send it to the server (returning quickly if no data is buffered)</li>
  <li>I also have a buffer size of 5MB which appears to work well (2MB was giving me overruns). This does seem a bit high :/</li>
  </ol>