#ifndef CARingBuffer_h
#define CARingBuffer_h
#if ENABLE(WEB_AUDIO) && USE(MEDIATOOLBOX)
#include <runtime/ArrayBuffer.h>
#include <wtf/Lock.h>
#include <wtf/Vector.h>
typedef struct AudioBufferList AudioBufferList;
namespace WebCore {
class CARingBuffer {
public:
CARingBuffer();
~CARingBuffer();
enum Error {
Ok,
TooMuch, CPUOverload, };
void allocate(uint32_t m_channelCount, size_t bytesPerFrame, size_t frameCount);
void deallocate();
Error store(const AudioBufferList*, size_t frameCount, uint64_t startFrame);
Error fetch(AudioBufferList*, size_t frameCount, uint64_t startFrame);
void getCurrentFrameBounds(uint64_t &startTime, uint64_t &endTime);
uint32_t channelCount() const { return m_channelCount; }
private:
size_t frameOffset(uint64_t frameNumber) { return (frameNumber & m_frameCountMask) * m_bytesPerFrame; }
void clipTimeBounds(uint64_t& startRead, uint64_t& endRead);
uint64_t currentStartFrame() const;
uint64_t currentEndFrame() const;
void setCurrentFrameBounds(uint64_t startFrame, uint64_t endFrame);
RefPtr<ArrayBuffer> m_buffers;
uint32_t m_channelCount;
size_t m_bytesPerFrame;
uint32_t m_frameCount;
uint32_t m_frameCountMask;
size_t m_capacityBytes;
struct TimeBounds {
TimeBounds()
: m_startFrame(0)
, m_endFrame(0)
, m_updateCounter(0)
{
}
volatile uint64_t m_startFrame;
volatile uint64_t m_endFrame;
volatile uint32_t m_updateCounter;
};
Vector<TimeBounds> m_timeBoundsQueue;
Lock m_currentFrameBoundsLock;
std::atomic<int32_t> m_timeBoundsQueuePtr;
};
}
#endif // ENABLE(WEB_AUDIO) && USE(MEDIATOOLBOX)
#endif // CARingBuffer_h