mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-20 08:29:04 +02:00
add AudioRingMixBuffer
This commit is contained in:
parent
95a7b38ea4
commit
02e62938a4
2 changed files with 236 additions and 19 deletions
|
@ -26,6 +26,7 @@
|
||||||
static const QString RING_BUFFER_OVERFLOW_DEBUG { "AudioRingBuffer::writeData has overflown the buffer. Overwriting old data." };
|
static const QString RING_BUFFER_OVERFLOW_DEBUG { "AudioRingBuffer::writeData has overflown the buffer. Overwriting old data." };
|
||||||
static const QString DROPPED_SILENT_DEBUG { "AudioRingBuffer::addSilentSamples dropping silent samples to prevent overflow." };
|
static const QString DROPPED_SILENT_DEBUG { "AudioRingBuffer::addSilentSamples dropping silent samples to prevent overflow." };
|
||||||
|
|
||||||
|
template<>
|
||||||
AudioRingBufferTemplate<int16_t>::AudioRingBufferTemplate(int numFrameSamples, int numFramesCapacity) :
|
AudioRingBufferTemplate<int16_t>::AudioRingBufferTemplate(int numFrameSamples, int numFramesCapacity) :
|
||||||
_numFrameSamples(numFrameSamples),
|
_numFrameSamples(numFrameSamples),
|
||||||
_frameCapacity(numFramesCapacity),
|
_frameCapacity(numFramesCapacity),
|
||||||
|
@ -41,22 +42,26 @@ AudioRingBufferTemplate<int16_t>::AudioRingBufferTemplate(int numFrameSamples, i
|
||||||
|
|
||||||
static QString repeatedOverflowMessage = LogHandler::getInstance().addRepeatedMessageRegex(RING_BUFFER_OVERFLOW_DEBUG);
|
static QString repeatedOverflowMessage = LogHandler::getInstance().addRepeatedMessageRegex(RING_BUFFER_OVERFLOW_DEBUG);
|
||||||
static QString repeatedDroppedMessage = LogHandler::getInstance().addRepeatedMessageRegex(DROPPED_SILENT_DEBUG);
|
static QString repeatedDroppedMessage = LogHandler::getInstance().addRepeatedMessageRegex(DROPPED_SILENT_DEBUG);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
AudioRingBufferTemplate<int16_t>::~AudioRingBufferTemplate() {
|
AudioRingBufferTemplate<int16_t>::~AudioRingBufferTemplate() {
|
||||||
delete[] _buffer;
|
delete[] _buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
void AudioRingBufferTemplate<int16_t>::clear() {
|
void AudioRingBufferTemplate<int16_t>::clear() {
|
||||||
_endOfLastWrite = _buffer;
|
_endOfLastWrite = _buffer;
|
||||||
_nextOutput = _buffer;
|
_nextOutput = _buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
void AudioRingBufferTemplate<int16_t>::reset() {
|
void AudioRingBufferTemplate<int16_t>::reset() {
|
||||||
clear();
|
clear();
|
||||||
_overflowCount = 0;
|
_overflowCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
void AudioRingBufferTemplate<int16_t>::resizeForFrameSize(int numFrameSamples) {
|
void AudioRingBufferTemplate<int16_t>::resizeForFrameSize(int numFrameSamples) {
|
||||||
delete[] _buffer;
|
delete[] _buffer;
|
||||||
_numFrameSamples = numFrameSamples;
|
_numFrameSamples = numFrameSamples;
|
||||||
|
@ -73,14 +78,17 @@ void AudioRingBufferTemplate<int16_t>::resizeForFrameSize(int numFrameSamples) {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
int AudioRingBufferTemplate<int16_t>::readSamples(Sample* destination, int maxSamples) {
|
int AudioRingBufferTemplate<int16_t>::readSamples(Sample* destination, int maxSamples) {
|
||||||
return readData((char*)destination, maxSamples * SampleSize) / SampleSize;
|
return readData((char*)destination, maxSamples * SampleSize) / SampleSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
int AudioRingBufferTemplate<int16_t>::writeSamples(const Sample* source, int maxSamples) {
|
int AudioRingBufferTemplate<int16_t>::writeSamples(const Sample* source, int maxSamples) {
|
||||||
return writeData((char*)source, maxSamples * SampleSize) / SampleSize;
|
return writeData((char*)source, maxSamples * SampleSize) / SampleSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
int AudioRingBufferTemplate<int16_t>::readData(char *data, int maxSize) {
|
int AudioRingBufferTemplate<int16_t>::readData(char *data, int maxSize) {
|
||||||
// only copy up to the number of samples we have available
|
// only copy up to the number of samples we have available
|
||||||
int maxSamples = maxSize / SampleSize;
|
int maxSamples = maxSize / SampleSize;
|
||||||
|
@ -104,6 +112,7 @@ int AudioRingBufferTemplate<int16_t>::readData(char *data, int maxSize) {
|
||||||
return numReadSamples * SampleSize;
|
return numReadSamples * SampleSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
int AudioRingBufferTemplate<int16_t>::writeData(const char* data, int maxSize) {
|
int AudioRingBufferTemplate<int16_t>::writeData(const char* data, int maxSize) {
|
||||||
// only copy up to the number of samples we have capacity for
|
// only copy up to the number of samples we have capacity for
|
||||||
int maxSamples = maxSize / SampleSize;
|
int maxSamples = maxSize / SampleSize;
|
||||||
|
@ -137,6 +146,7 @@ int AudioRingBufferTemplate<int16_t>::writeData(const char* data, int maxSize) {
|
||||||
return numWriteSamples * SampleSize;
|
return numWriteSamples * SampleSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
int AudioRingBufferTemplate<int16_t>::samplesAvailable() const {
|
int AudioRingBufferTemplate<int16_t>::samplesAvailable() const {
|
||||||
if (!_endOfLastWrite) {
|
if (!_endOfLastWrite) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -149,6 +159,7 @@ int AudioRingBufferTemplate<int16_t>::samplesAvailable() const {
|
||||||
return sampleDifference;
|
return sampleDifference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
int16_t* AudioRingBufferTemplate<int16_t>::shiftedPositionAccomodatingWrap(Sample* position, int numSamplesShift) const {
|
int16_t* AudioRingBufferTemplate<int16_t>::shiftedPositionAccomodatingWrap(Sample* position, int numSamplesShift) const {
|
||||||
// NOTE: It is possible to shift out-of-bounds if (|numSamplesShift| > 2 * _bufferLength), but this should not occur
|
// NOTE: It is possible to shift out-of-bounds if (|numSamplesShift| > 2 * _bufferLength), but this should not occur
|
||||||
if (numSamplesShift > 0 && position + numSamplesShift >= _buffer + _bufferLength) {
|
if (numSamplesShift > 0 && position + numSamplesShift >= _buffer + _bufferLength) {
|
||||||
|
@ -162,6 +173,7 @@ int16_t* AudioRingBufferTemplate<int16_t>::shiftedPositionAccomodatingWrap(Sampl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
int AudioRingBufferTemplate<int16_t>::addSilentSamples(int silentSamples) {
|
int AudioRingBufferTemplate<int16_t>::addSilentSamples(int silentSamples) {
|
||||||
// NOTE: This implementation is nearly identical to writeData save for s/memcpy/memset, refer to comments there
|
// NOTE: This implementation is nearly identical to writeData save for s/memcpy/memset, refer to comments there
|
||||||
int numWriteSamples = std::min(silentSamples, _sampleCapacity);
|
int numWriteSamples = std::min(silentSamples, _sampleCapacity);
|
||||||
|
@ -186,6 +198,7 @@ int AudioRingBufferTemplate<int16_t>::addSilentSamples(int silentSamples) {
|
||||||
return numWriteSamples;
|
return numWriteSamples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
float AudioRingBufferTemplate<int16_t>::getFrameLoudness(const Sample* frameStart) const {
|
float AudioRingBufferTemplate<int16_t>::getFrameLoudness(const Sample* frameStart) const {
|
||||||
// FIXME: This is a bad measure of loudness - normal estimation uses sqrt(sum(x*x))
|
// FIXME: This is a bad measure of loudness - normal estimation uses sqrt(sum(x*x))
|
||||||
float loudness = 0.0f;
|
float loudness = 0.0f;
|
||||||
|
@ -203,6 +216,7 @@ float AudioRingBufferTemplate<int16_t>::getFrameLoudness(const Sample* frameStar
|
||||||
return loudness;
|
return loudness;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
float AudioRingBufferTemplate<int16_t>::getFrameLoudness(ConstIterator frameStart) const {
|
float AudioRingBufferTemplate<int16_t>::getFrameLoudness(ConstIterator frameStart) const {
|
||||||
if (frameStart.isNull()) {
|
if (frameStart.isNull()) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
@ -210,6 +224,7 @@ float AudioRingBufferTemplate<int16_t>::getFrameLoudness(ConstIterator frameStar
|
||||||
return getFrameLoudness(&(*frameStart));
|
return getFrameLoudness(&(*frameStart));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
int AudioRingBufferTemplate<int16_t>::writeSamples(ConstIterator source, int maxSamples) {
|
int AudioRingBufferTemplate<int16_t>::writeSamples(ConstIterator source, int maxSamples) {
|
||||||
int samplesToCopy = std::min(maxSamples, _sampleCapacity);
|
int samplesToCopy = std::min(maxSamples, _sampleCapacity);
|
||||||
int samplesRoomFor = _sampleCapacity - samplesAvailable();
|
int samplesRoomFor = _sampleCapacity - samplesAvailable();
|
||||||
|
@ -231,6 +246,7 @@ int AudioRingBufferTemplate<int16_t>::writeSamples(ConstIterator source, int max
|
||||||
return samplesToCopy;
|
return samplesToCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
int AudioRingBufferTemplate<int16_t>::writeSamplesWithFade(ConstIterator source, int maxSamples, float fade) {
|
int AudioRingBufferTemplate<int16_t>::writeSamplesWithFade(ConstIterator source, int maxSamples, float fade) {
|
||||||
int samplesToCopy = std::min(maxSamples, _sampleCapacity);
|
int samplesToCopy = std::min(maxSamples, _sampleCapacity);
|
||||||
int samplesRoomFor = _sampleCapacity - samplesAvailable();
|
int samplesRoomFor = _sampleCapacity - samplesAvailable();
|
||||||
|
@ -251,3 +267,192 @@ int AudioRingBufferTemplate<int16_t>::writeSamplesWithFade(ConstIterator source,
|
||||||
|
|
||||||
return samplesToCopy;
|
return samplesToCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
AudioRingBufferTemplate<float>::AudioRingBufferTemplate(int numFrameSamples, int numFramesCapacity) :
|
||||||
|
_numFrameSamples(numFrameSamples),
|
||||||
|
_frameCapacity(numFramesCapacity),
|
||||||
|
_sampleCapacity(numFrameSamples * numFramesCapacity),
|
||||||
|
_bufferLength(numFrameSamples * (numFramesCapacity + 1))
|
||||||
|
{
|
||||||
|
if (numFrameSamples) {
|
||||||
|
_buffer = new Sample[_bufferLength];
|
||||||
|
memset(_buffer, 0, _bufferLength * SampleSize);
|
||||||
|
_nextOutput = _buffer;
|
||||||
|
_endOfLastWrite = _buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString repeatedOverflowMessage = LogHandler::getInstance().addRepeatedMessageRegex(RING_BUFFER_OVERFLOW_DEBUG);
|
||||||
|
static QString repeatedDroppedMessage = LogHandler::getInstance().addRepeatedMessageRegex(DROPPED_SILENT_DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
AudioRingBufferTemplate<float>::~AudioRingBufferTemplate() {
|
||||||
|
delete[] _buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void AudioRingBufferTemplate<float>::clear() {
|
||||||
|
_endOfLastWrite = _buffer;
|
||||||
|
_nextOutput = _buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void AudioRingBufferTemplate<float>::reset() {
|
||||||
|
clear();
|
||||||
|
_overflowCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void AudioRingBufferTemplate<float>::resizeForFrameSize(int numFrameSamples) {
|
||||||
|
delete[] _buffer;
|
||||||
|
_numFrameSamples = numFrameSamples;
|
||||||
|
_sampleCapacity = numFrameSamples * _frameCapacity;
|
||||||
|
_bufferLength = numFrameSamples * (_frameCapacity + 1);
|
||||||
|
|
||||||
|
if (numFrameSamples) {
|
||||||
|
_buffer = new Sample[_bufferLength];
|
||||||
|
memset(_buffer, 0, _bufferLength * SampleSize);
|
||||||
|
} else {
|
||||||
|
_buffer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int AudioRingBufferTemplate<float>::readSamples(Sample* destination, int maxSamples) {
|
||||||
|
return readData((char*)destination, maxSamples * SampleSize) / SampleSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int AudioRingBufferTemplate<float>::appendSamples(Sample* destination, int maxSamples, bool append) {
|
||||||
|
if (append) {
|
||||||
|
return appendData((char*)destination, maxSamples * SampleSize) / SampleSize;
|
||||||
|
} else {
|
||||||
|
return readData((char*)destination, maxSamples * SampleSize) / SampleSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int AudioRingBufferTemplate<float>::writeSamples(const Sample* source, int maxSamples) {
|
||||||
|
return writeData((char*)source, maxSamples * SampleSize) / SampleSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int AudioRingBufferTemplate<float>::readData(char *data, int maxSize) {
|
||||||
|
// only copy up to the number of samples we have available
|
||||||
|
int maxSamples = maxSize / SampleSize;
|
||||||
|
int numReadSamples = std::min(maxSamples, samplesAvailable());
|
||||||
|
|
||||||
|
if (_nextOutput + numReadSamples > _buffer + _bufferLength) {
|
||||||
|
// we're going to need to do two reads to get this data, it wraps around the edge
|
||||||
|
int numSamplesToEnd = (_buffer + _bufferLength) - _nextOutput;
|
||||||
|
|
||||||
|
// read to the end of the buffer
|
||||||
|
memcpy(data, _nextOutput, numSamplesToEnd * SampleSize);
|
||||||
|
|
||||||
|
// read the rest from the beginning of the buffer
|
||||||
|
memcpy(data + (numSamplesToEnd * SampleSize), _buffer, (numReadSamples - numSamplesToEnd) * SampleSize);
|
||||||
|
} else {
|
||||||
|
memcpy(data, _nextOutput, numReadSamples * SampleSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
shiftReadPosition(numReadSamples);
|
||||||
|
|
||||||
|
return numReadSamples * SampleSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int AudioRingBufferTemplate<float>::appendData(char *data, int maxSize) {
|
||||||
|
// only copy up to the number of samples we have available
|
||||||
|
int maxSamples = maxSize / SampleSize;
|
||||||
|
int numReadSamples = std::min(maxSamples, samplesAvailable());
|
||||||
|
|
||||||
|
Sample* dest = reinterpret_cast<Sample*>(data);
|
||||||
|
Sample* output = _nextOutput;
|
||||||
|
if (_nextOutput + numReadSamples > _buffer + _bufferLength) {
|
||||||
|
// we're going to need to do two reads to get this data, it wraps around the edge
|
||||||
|
int numSamplesToEnd = (_buffer + _bufferLength) - _nextOutput;
|
||||||
|
|
||||||
|
// read to the end of the buffer
|
||||||
|
for (int i = 0; i < numSamplesToEnd; i++) {
|
||||||
|
*dest++ = *output++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the rest from the beginning of the buffer
|
||||||
|
output = _buffer;
|
||||||
|
for (int i = 0; i < (numReadSamples - numSamplesToEnd); i++) {
|
||||||
|
*dest++ = *output++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < numReadSamples; i++) {
|
||||||
|
*dest++ = *output++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shiftReadPosition(numReadSamples);
|
||||||
|
|
||||||
|
return numReadSamples * SampleSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int AudioRingBufferTemplate<float>::writeData(const char* data, int maxSize) {
|
||||||
|
// only copy up to the number of samples we have capacity for
|
||||||
|
int maxSamples = maxSize / SampleSize;
|
||||||
|
int numWriteSamples = std::min(maxSamples, _sampleCapacity);
|
||||||
|
int samplesRoomFor = _sampleCapacity - samplesAvailable();
|
||||||
|
|
||||||
|
if (numWriteSamples > samplesRoomFor) {
|
||||||
|
// there's not enough room for this write. erase old data to make room for this new data
|
||||||
|
int samplesToDelete = numWriteSamples - samplesRoomFor;
|
||||||
|
_nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete);
|
||||||
|
_overflowCount++;
|
||||||
|
|
||||||
|
qCDebug(audio) << qPrintable(RING_BUFFER_OVERFLOW_DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_endOfLastWrite + numWriteSamples > _buffer + _bufferLength) {
|
||||||
|
// we're going to need to do two writes to set this data, it wraps around the edge
|
||||||
|
int numSamplesToEnd = (_buffer + _bufferLength) - _endOfLastWrite;
|
||||||
|
|
||||||
|
// write to the end of the buffer
|
||||||
|
memcpy(_endOfLastWrite, data, numSamplesToEnd * SampleSize);
|
||||||
|
|
||||||
|
// write the rest to the beginning of the buffer
|
||||||
|
memcpy(_buffer, data + (numSamplesToEnd * SampleSize), (numWriteSamples - numSamplesToEnd) * SampleSize);
|
||||||
|
} else {
|
||||||
|
memcpy(_endOfLastWrite, data, numWriteSamples * SampleSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
_endOfLastWrite = shiftedPositionAccomodatingWrap(_endOfLastWrite, numWriteSamples);
|
||||||
|
|
||||||
|
return numWriteSamples * SampleSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int AudioRingBufferTemplate<float>::samplesAvailable() const {
|
||||||
|
if (!_endOfLastWrite) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sampleDifference = _endOfLastWrite - _nextOutput;
|
||||||
|
if (sampleDifference < 0) {
|
||||||
|
sampleDifference += _bufferLength;
|
||||||
|
}
|
||||||
|
return sampleDifference;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
float* AudioRingBufferTemplate<float>::shiftedPositionAccomodatingWrap(Sample* position, int numSamplesShift) const {
|
||||||
|
// NOTE: It is possible to shift out-of-bounds if (|numSamplesShift| > 2 * _bufferLength), but this should not occur
|
||||||
|
if (numSamplesShift > 0 && position + numSamplesShift >= _buffer + _bufferLength) {
|
||||||
|
// this shift will wrap the position around to the beginning of the ring
|
||||||
|
return position + numSamplesShift - _bufferLength;
|
||||||
|
} else if (numSamplesShift < 0 && position + numSamplesShift < _buffer) {
|
||||||
|
// this shift will go around to the end of the ring
|
||||||
|
return position + numSamplesShift + _bufferLength;
|
||||||
|
} else {
|
||||||
|
return position + numSamplesShift;
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,7 +24,7 @@ const int DEFAULT_RING_BUFFER_FRAME_CAPACITY = 10;
|
||||||
template <class T>
|
template <class T>
|
||||||
class AudioRingBufferTemplate {
|
class AudioRingBufferTemplate {
|
||||||
using Sample = T;
|
using Sample = T;
|
||||||
static size_t SampleSize = sizeof(Sample);
|
static const int SampleSize = sizeof(Sample);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioRingBufferTemplate(int numFrameSamples, int numFramesCapacity = DEFAULT_RING_BUFFER_FRAME_CAPACITY);
|
AudioRingBufferTemplate(int numFrameSamples, int numFramesCapacity = DEFAULT_RING_BUFFER_FRAME_CAPACITY);
|
||||||
|
@ -49,6 +49,14 @@ public:
|
||||||
/// Returns number of read samples
|
/// Returns number of read samples
|
||||||
int readSamples(Sample* destination, int maxSamples);
|
int readSamples(Sample* destination, int maxSamples);
|
||||||
|
|
||||||
|
/// Append up to maxSamples into destination (will only read up to samplesAvailable())
|
||||||
|
/// If append == false, behaves as readSamples
|
||||||
|
/// Returns number of appended samples
|
||||||
|
int appendSamples(Sample* destination, int maxSamples, bool append = true);
|
||||||
|
|
||||||
|
/// Skip up to maxSamples (will only skip up to samplesAvailable())
|
||||||
|
void skipSamples(int maxSamples) { shiftReadPosition(std::min(maxSamples, samplesAvailable())); }
|
||||||
|
|
||||||
/// Write up to maxSamples from source (will only write up to sample capacity)
|
/// Write up to maxSamples from source (will only write up to sample capacity)
|
||||||
/// Returns number of written samples
|
/// Returns number of written samples
|
||||||
int writeSamples(const Sample* source, int maxSamples);
|
int writeSamples(const Sample* source, int maxSamples);
|
||||||
|
@ -62,6 +70,10 @@ public:
|
||||||
/// Returns number of read bytes
|
/// Returns number of read bytes
|
||||||
int readData(char* destination, int maxSize);
|
int readData(char* destination, int maxSize);
|
||||||
|
|
||||||
|
/// Append up to maxSize into destination
|
||||||
|
/// Returns number of read bytes
|
||||||
|
int appendData(char* destination, int maxSize);
|
||||||
|
|
||||||
/// Write up to maxSize from source
|
/// Write up to maxSize from source
|
||||||
/// Returns number of written bytes
|
/// Returns number of written bytes
|
||||||
int writeData(const char* source, int maxSize);
|
int writeData(const char* source, int maxSize);
|
||||||
|
@ -148,19 +160,19 @@ using AudioRingBuffer = AudioRingBufferTemplate<int16_t>;
|
||||||
using AudioRingMixBuffer = AudioRingBufferTemplate<float>;
|
using AudioRingMixBuffer = AudioRingBufferTemplate<float>;
|
||||||
|
|
||||||
// inline the iterator:
|
// inline the iterator:
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator::ConstIterator() :
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator::ConstIterator() :
|
||||||
_bufferLength(0),
|
_bufferLength(0),
|
||||||
_bufferFirst(NULL),
|
_bufferFirst(NULL),
|
||||||
_bufferLast(NULL),
|
_bufferLast(NULL),
|
||||||
_at(NULL) {}
|
_at(NULL) {}
|
||||||
|
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator::ConstIterator(Sample* bufferFirst, int capacity, Sample* at) :
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator::ConstIterator(Sample* bufferFirst, int capacity, Sample* at) :
|
||||||
_bufferLength(capacity),
|
_bufferLength(capacity),
|
||||||
_bufferFirst(bufferFirst),
|
_bufferFirst(bufferFirst),
|
||||||
_bufferLast(bufferFirst + capacity - 1),
|
_bufferLast(bufferFirst + capacity - 1),
|
||||||
_at(at) {}
|
_at(at) {}
|
||||||
|
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator& AudioRingBufferTemplate<int16_t>::ConstIterator::operator=(const ConstIterator& rhs) {
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator& AudioRingBufferTemplate<int16_t>::ConstIterator::operator=(const ConstIterator& rhs) {
|
||||||
_bufferLength = rhs._bufferLength;
|
_bufferLength = rhs._bufferLength;
|
||||||
_bufferFirst = rhs._bufferFirst;
|
_bufferFirst = rhs._bufferFirst;
|
||||||
_bufferLast = rhs._bufferLast;
|
_bufferLast = rhs._bufferLast;
|
||||||
|
@ -168,41 +180,41 @@ inline AudioRingBufferTemplate<int16_t>::ConstIterator& AudioRingBufferTemplate<
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator& AudioRingBufferTemplate<int16_t>::ConstIterator::operator++() {
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator& AudioRingBufferTemplate<int16_t>::ConstIterator::operator++() {
|
||||||
_at = (_at == _bufferLast) ? _bufferFirst : _at + 1;
|
_at = (_at == _bufferLast) ? _bufferFirst : _at + 1;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::ConstIterator::operator++(int) {
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::ConstIterator::operator++(int) {
|
||||||
ConstIterator tmp(*this);
|
ConstIterator tmp(*this);
|
||||||
++(*this);
|
++(*this);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator& AudioRingBufferTemplate<int16_t>::ConstIterator::operator--() {
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator& AudioRingBufferTemplate<int16_t>::ConstIterator::operator--() {
|
||||||
_at = (_at == _bufferFirst) ? _bufferLast : _at - 1;
|
_at = (_at == _bufferFirst) ? _bufferLast : _at - 1;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::ConstIterator::operator--(int) {
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::ConstIterator::operator--(int) {
|
||||||
ConstIterator tmp(*this);
|
ConstIterator tmp(*this);
|
||||||
--(*this);
|
--(*this);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const int16_t& AudioRingBufferTemplate<int16_t>::ConstIterator::operator[] (int i) {
|
template<> inline const int16_t& AudioRingBufferTemplate<int16_t>::ConstIterator::operator[] (int i) {
|
||||||
return *atShiftedBy(i);
|
return *atShiftedBy(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::ConstIterator::operator+(int i) {
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::ConstIterator::operator+(int i) {
|
||||||
return ConstIterator(_bufferFirst, _bufferLength, atShiftedBy(i));
|
return ConstIterator(_bufferFirst, _bufferLength, atShiftedBy(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::ConstIterator::operator-(int i) {
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::ConstIterator::operator-(int i) {
|
||||||
return ConstIterator(_bufferFirst, _bufferLength, atShiftedBy(-i));
|
return ConstIterator(_bufferFirst, _bufferLength, atShiftedBy(-i));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int16_t* AudioRingBufferTemplate<int16_t>::ConstIterator::atShiftedBy(int i) {
|
template<> inline int16_t* AudioRingBufferTemplate<int16_t>::ConstIterator::atShiftedBy(int i) {
|
||||||
i = (_at - _bufferFirst + i) % _bufferLength;
|
i = (_at - _bufferFirst + i) % _bufferLength;
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
i += _bufferLength;
|
i += _bufferLength;
|
||||||
|
@ -210,7 +222,7 @@ inline int16_t* AudioRingBufferTemplate<int16_t>::ConstIterator::atShiftedBy(int
|
||||||
return _bufferFirst + i;
|
return _bufferFirst + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamples(Sample* dest, int numSamples) {
|
template<> inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamples(Sample* dest, int numSamples) {
|
||||||
auto samplesToEnd = _bufferLast - _at + 1;
|
auto samplesToEnd = _bufferLast - _at + 1;
|
||||||
|
|
||||||
if (samplesToEnd >= numSamples) {
|
if (samplesToEnd >= numSamples) {
|
||||||
|
@ -225,7 +237,7 @@ inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamples(Sample*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamplesWithFade(Sample* dest, int numSamples, float fade) {
|
template<> inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamplesWithFade(Sample* dest, int numSamples, float fade) {
|
||||||
Sample* at = _at;
|
Sample* at = _at;
|
||||||
for (int i = 0; i < numSamples; i++) {
|
for (int i = 0; i < numSamples; i++) {
|
||||||
*dest = (float)*at * fade;
|
*dest = (float)*at * fade;
|
||||||
|
@ -234,7 +246,7 @@ inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamplesWithFade
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamplesWithUpmix(Sample* dest, int numSamples, int numExtraChannels) {
|
template<> inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamplesWithUpmix(Sample* dest, int numSamples, int numExtraChannels) {
|
||||||
Sample* at = _at;
|
Sample* at = _at;
|
||||||
for (int i = 0; i < numSamples/2; i++) {
|
for (int i = 0; i < numSamples/2; i++) {
|
||||||
|
|
||||||
|
@ -253,7 +265,7 @@ inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamplesWithUpmi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamplesWithDownmix(Sample* dest, int numSamples) {
|
template<> inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamplesWithDownmix(Sample* dest, int numSamples) {
|
||||||
Sample* at = _at;
|
Sample* at = _at;
|
||||||
for (int i = 0; i < numSamples/2; i++) {
|
for (int i = 0; i < numSamples/2; i++) {
|
||||||
|
|
||||||
|
@ -268,11 +280,11 @@ inline void AudioRingBufferTemplate<int16_t>::ConstIterator::readSamplesWithDown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::nextOutput() const {
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::nextOutput() const {
|
||||||
return ConstIterator(_buffer, _bufferLength, _nextOutput);
|
return ConstIterator(_buffer, _bufferLength, _nextOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::lastFrameWritten() const {
|
template<> inline AudioRingBufferTemplate<int16_t>::ConstIterator AudioRingBufferTemplate<int16_t>::lastFrameWritten() const {
|
||||||
return ConstIterator(_buffer, _bufferLength, _endOfLastWrite) - _numFrameSamples;
|
return ConstIterator(_buffer, _bufferLength, _endOfLastWrite) - _numFrameSamples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue