forked from sbooth/SFBAudioEngine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRingBuffer.h
172 lines (136 loc) · 5.77 KB
/
RingBuffer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
* Copyright (C) 2013 Stephen F. Booth <[email protected]>
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of Stephen F. Booth nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <CoreAudio/CoreAudioTypes.h>
#include <memory>
/*! @file RingBuffer.h @brief An audio ring buffer */
/*! @brief \c SFBAudioEngine's encompassing namespace */
namespace SFB {
/*! @brief %Audio functionality */
namespace Audio {
/*!
* @brief A ring buffer implementation supporting non-interleaved audio.
*
* This class is thread safe when used from one reader thread
* and one writer thread (single producer, single consumer model).
*
* The read and write routines are based on JACK's ringbuffer implementation
* but are modified for non-interleaved audio.
*/
class RingBuffer
{
public:
// ========================================
/*! @name Creation and Destruction */
//@{
/*! @brief A \c std::unique_ptr for \c RingBuffer objects */
typedef std::unique_ptr<RingBuffer> unique_ptr;
/*!
* @brief Create a new \c RingBuffer
* @note Allocate() must be called before the object may be used.
*/
RingBuffer();
/*! @brief Destroy the \c RingBuffer and release all associated resources. */
~RingBuffer();
/*! @cond */
/*! @internal This class is non-copyable */
RingBuffer(const RingBuffer& rhs) = delete;
/*! @internal This class is non-assignable */
RingBuffer& operator=(const RingBuffer& rhs) = delete;
/*! @endcond */
//@}
// ========================================
/*! @name Buffer management */
//@{
/*!
* @brief Allocate space for audio data.
* @note Only interleaved formats are supported.
* @note This method is not thread safe.
* @param format The format of the audio that will be written to and read from this buffer.
* @param capacityFrames The desired capacity, in frames
* @return \c true on success, \c false on error
*/
bool Allocate(const AudioStreamBasicDescription& format, size_t capacityFrames);
/*!
* @brief Allocate space for audio data.
* @note This method is not thread safe.
* @param channelCount The number of interleaved channels
* @param bytesPerFrame The number of bytes per audio frame
* @param capacityFrames The desired capacity, in frames
* @return \c true on success, \c false on error
*/
bool Allocate(UInt32 channelCount, UInt32 bytesPerFrame, size_t capacityFrames);
/*!
* @brief Free the resources used by this \c RingBuffer
* @note This method is not thread safe.
*/
void Deallocate();
/*!
* @brief Reset this \c RingBuffer to its default state.
* @note This method is not thread safe.
*/
void Reset();
/*! @brief Get the capacity of this RingBuffer in frames */
inline size_t GetCapacityFrames() const { return mCapacityFrames; }
/*! @brief Get the number of frames available for reading */
size_t GetFramesAvailableToRead() const;
/*! @brief Get the free space available for writing in frames */
size_t GetFramesAvailableToWrite() const;
//@}
// ========================================
/*! @name Reading and writing audio */
//@{
/*!
* @brief Read audio from the \c RingBuffer, advancing the read pointer.
* @param bufferList An \c AudioBufferList to receive the audio
* @param frameCount The desired number of frames to read
* @return The number of frames actually read
*/
size_t ReadAudio(AudioBufferList *bufferList, size_t frameCount);
/*!
* @brief Write audio to the \c RingBuffer, advancing the write pointer.
* @param bufferList An \c AudioBufferList containing the audio to copy
* @param frameCount The desired number of frames to write
* @return The number of frames actually written
*/
size_t WriteAudio(const AudioBufferList *bufferList, size_t frameCount);
//@}
private:
UInt32 mNumberChannels; // The number of interleaved channels
UInt32 mBytesPerFrame; // The number of bytes per audio frames
unsigned char **mBuffers; // The channel pointers and buffers, allocated in one chunk of memory
size_t mCapacityFrames; // Frame capacity per channel
size_t mCapacityFramesMask;
size_t mCapacityBytes; // Byte capacity per frame
volatile size_t mWritePointer; // In frames
volatile size_t mReadPointer;
};
}
}