1/********************************************************************************************************************************** 2 * 3 * OpenAL cross platform audio library 4 * Copyright (c) 2004, Apple Computer, Inc., Copyright (c) 2012, Apple Inc. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without modification, are permitted provided 7 * that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote 13 * products derived from this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 18 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 19 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 20 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21 * 22 **********************************************************************************************************************************/ 23 24#include <AudioToolbox/AudioToolbox.h> 25 26#ifndef __OpenAL_Aspen__oalRingBuffer__ 27#define __OpenAL_Aspen__oalRingBuffer__ 28 29// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 30#pragma mark _____OALRingBuffer_____ 31// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 32// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 34// OALRingBuffer: 35// This class implements an audio ring buffer. Multi-channel data can be either 36// interleaved or deinterleaved. 37// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 38// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 39 40enum { 41 kOALRingBufferError_WayBehind = -2, // both fetch times are earlier than buffer start time 42 kOALRingBufferError_SlightlyBehind = -1, // fetch start time is earlier than buffer start time (fetch end time OK) 43 kOALRingBufferError_OK = 0, 44 kOALRingBufferError_SlightlyAhead = 1, // fetch end time is later than buffer end time (fetch start time OK) 45 kOALRingBufferError_WayAhead = 2, // both fetch times are later than buffer end time 46 kOALRingBufferError_TooMuch = 3, // fetch start time is earlier than buffer start time and fetch end time is later than buffer end time 47 kOALRingBufferError_CPUOverload = 4 // the reader is unable to get enough CPU cycles to capture a consistent snapshot of the time bounds 48}; 49 50typedef SInt32 OALRingBufferError; 51typedef SInt64 SampleTime; 52 53const UInt32 kGeneralRingTimeBoundsQueueSize = 32; 54const UInt32 kGeneralRingTimeBoundsQueueMask = kGeneralRingTimeBoundsQueueSize - 1; 55 56class OALRingBuffer { 57public: 58 OALRingBuffer(); 59 OALRingBuffer(UInt32 bytesPerFrame, UInt32 capacityFrames); 60 ~OALRingBuffer(); 61 62 void Allocate(UInt32 bytesPerFrame, UInt32 capacityFrames); 63 void Deallocate(); 64 void Clear(); 65 bool Store(const Byte *data, UInt32 nFrames, SInt64 frameNumber); 66 OSStatus Fetch(Byte *data, UInt32 nFrames, SInt64 frameNumber); 67 Byte* GetFramePtr(SInt64 frameNumber, UInt32 &outNFrames); 68 69 void GetTimeBounds(SInt64 &start, SInt64&end) { start = mStartFrame; end = mEndFrame; } 70 71protected: 72 UInt32 FrameOffset(SInt64 frameNumber) { return (mStartOffset + UInt32(frameNumber - mStartFrame) * mBytesPerFrame) % mCapacityBytes; } 73 74protected: 75 Byte * mBuffer; 76 UInt32 mBytesPerFrame; 77 UInt32 mCapacityFrames; 78 UInt32 mCapacityBytes; 79 UInt32 mStartOffset; 80 SInt64 mStartFrame; 81 SInt64 mEndFrame; 82}; 83 84#endif /* defined(__OpenAL_Aspen__oalRingBuffer__) */