[Portaudio] WaitForSingleObject() Timed out in WriteStream()
Ross Bencina
rossb-lists at audiomulch.com
Fri Jul 16 03:48:36 EDT 2010
Or you could just use pa_ringbuffer.c which is tested, and has the necessary
memory barriers to be safe on multicore systems (volatile is not enough
Robert, see archives for discussion)...
Ross
----- Original Message -----
From: "Robert Bielik" <robert.bielik at xponaut.se>
To: "Portaudio Mailing List" <portaudio at music.columbia.edu>
Sent: Friday, July 16, 2010 5:34 PM
Subject: Re: [Portaudio] WaitForSingleObject() Timed out in WriteStream()
> Since there's no need to use RT OS for recording (obvisously), here's a
> simple lock-free buffer fifo that would do the trick, with usage example
> (Haven't compiled it or tested it, so use at your own discretion):
>
> ------------------------------
> #ifndef __AUDIO_BUFFER_MANAGER_H__
> #define __AUDIO_BUFFER_MANAGER_H__
>
> #include "pa_util.h"
> #include <assert.h>
>
> class CAudioBufferManager {
> public:
> CAudioBufferManager(unsigned bufSize, unsigned bufCount)
> : m_bufCountMask(bufCount-1)
> , m_bufSize(bufSize)
> , m_buffers(0)
> {
> // Will assert on bufCount not being a power of 2, due to impl I
> don't accept that
> assert( ! ((bufCount)&(bufCountMask)) );
> }
> ~CAudioBufferManager() {
> if (m_buffers) {
> for (unsigned i=0;i<bufCount;++i) {
> if (m_buffers[i] != 0) {
> PaUtil_FreeMemory(m_buffers[i]);
> m_buffers[i] = 0;
> }
> }
> PaUtil_FreeMemory(m_buffers);
> m_buffers = 0;
> }
> }
>
> // Keep initialization from the constructor, so we can act if there's a
> problem
> bool Initialize() {
> // Assert if we call this twice
> assert( m_buffers == 0);
> // Allocate buffer array
> m_buffers =
> (void**)PaUtil_AllocateMemory((m_bufCountMask+1)*sizeof(void*));
> if (m_buffers == 0) {
> // Out of memory
> return false;
> }
>
> for (unsigned i=0;i<bufCount;++i) {
> m_buffers[i] = PaUtil_AllocateMemory(m_bufSize);
> if (m_buffers[i] == 0) {
> // Out of memory
> goto error;
> }
> }
>
> return true;
>
> error:
> // Cleanup
> for (unsigned i=0;i<bufCount;++i) {
> if (m_buffers[i] != 0) {
> PaUtil_FreeMemory(m_buffers[i]);
> m_buffers[i] = 0;
> }
> }
> PaUtil_FreeMemory(m_buffers);
> m_buffers = 0;
> return false;
> }
>
> bool HasFreeBuffers() const {
> return (m_posWrite - m_posRead) < m_bufCountMask;
> }
> bool HasFilledBuffers() const {
> return (m_posWrite != m_posRead);
> }
> void* GetWriteBuffer() {
> if (m_posWrite - m_posRead == m_bufCountMask) {
> // No more buffers to get
> return 0;
> }
> void* p = m_buffers[m_posWrite&m_bufCountMask];
> return p;
> }
> const void* GetReadBuffer() {
> if (m_posWrite == m_posRead) {
> // No more buffers to get
> return 0;
> }
> void* p = m_buffers[m_posRead&m_bufCountMask];
> return p;
> }
>
> void AdvanceWrite() {
> ++m_posWrite;
> }
> void AdvanceRead() {
> ++m_posRead;
> }
>
> private:
> volatile unsigned m_posWrite;
> volatile unsigned m_posRead;
> void** m_buffers;
> const unsigned m_bufCountMask;
> const unsigned m_bufSize;
> };
>
>
> /* Example usage:
>
> In PA callback:
>
> <CODE>
>
> // m_bufferToRecordInto is of type void*
> if (m_bufferToRecordInto == 0) {
> m_bufferToRecordInto = m_audioBufferManager.GetWriteBuffer();
> }
>
> if (m_bufferToRecordInto != 0) {
> // TODO: Record samples into the buffer after appropriately casting
> m_bufferToRecordInto // to correct type
>
> // When the buffer is filled (which can be several PA callbacks)
> if (bufferIsFilled) {
> m_audioBufferManager.AdvanceWrite();
> m_bufferToRecordInto = 0;
> }
> }
> </CODE>
>
>
>
> In I/O thread (higher prio than default thread prio):
>
> <CODE>
> while (threadShouldLoop) {
>
> void* pBuffer = m_audioBufferManager.GetReadBuffer();
> if (pBuffer == 0) {
> Sleep(50);
> continue;
> }
>
> // TODO: Write samples from the buffer to disk
>
> // We're finished with this buffer
> m_audioBufferManager.AdvanceRead();
> }
> </CODE>
>
> bufSize should be approx 200 ms worth of audio, and bufCount perhaps 16
> buffers.
>
> */
>
> #endif // __AUDIO_BUFFER_MANAGER_H__
> ----------------------
>
> HTH
> /Rob
> _______________________________________________
> Portaudio mailing list
> Portaudio at music.columbia.edu
> http://music.columbia.edu/mailman/listinfo/portaudio
More information about the Portaudio
mailing list