Re: Buffer overrun management with TPCircularBuffer.. best way to do so?
Re: Buffer overrun management with TPCircularBuffer.. best way to do so?
- Subject: Re: Buffer overrun management with TPCircularBuffer.. best way to do so?
- From: Ross Bencina <email@hidden>
- Date: Sun, 04 May 2014 12:36:03 +1000
On 4/05/2014 11:55 AM, Douglas Carmichael wrote:
Are the semaphore-handling functions available as library functions in OS X?
Yes, they are a standard Unix synchronisation primitive:
https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man2/sem_open.2.html
How would I get the size of one frame for the device and number of bytes in the TPCircularBuffer?
No idea. The codec frame size will be related to your decoding routines.
I think someone already posted how to get the number of free bytes in
TPCircularBuffer -- I've never used it.
I usually use the PortAudio ring buffer, which has a function to query
for the available space.
http://portaudio.com/docs/v19-doxydocs-dev/pa__ringbuffer_8h.html
Ross.
--Douglas
On May 3, 2014, at 7:41 PM, Ross Bencina <email@hidden> wrote:
Hi,
On 4/05/2014 6:34 AM, Kyle Sluder wrote:
Perhaps I should have avoided the term semaphore. You don't want to
actually use a real semaphore because you must not block the render
callback thread.
I think a semaphore is exactly what is needed.
A semaphore will not block when signaled, especially if the signaling thread has higher priority than the waiting thread. This is guaranteed by the documentation.
The schema is:
The producer thread produces data until the ringbuffer is full. Then it waits on the semaphore until the consumer signals the semaphore. Essentially something like:
// producer
for(;;){
while (!ringbuffer.isFull()) produceData();
semaphore->wait();
}
The consumer (in this case, the render callback) siphons data out of the ring buffer. When the available free space in the ring buffer exceeds some threshold (e.g. the free space becomes greater than one codec frame) the consumer signals the semaphore.
// consumer
readDataFromRingbuffer();
if (ringBuffer.fillLevel() < fillThreshold)
semaphore->signal();
To avoid redundant signaling you should only signal the semaphore once for every time threshold is crossed.
--------
Would I need to pass the semaphore down to the rendering callback
along with the TPCircularBuffer?
Yes.
How would I do that?
You're passing a pointer to the render callback right? Well pass a pointer to a struct that contains all the data you need:
struct StreamData {
TPCircularBuffer ringbuffer;
sem_t semaphore;
int fillThreshold;
... etc ...
};
Pass a StreamData * to the render callback.
Ross.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden