| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,226 +0,0 @@ |
| 1 |
-//////////////////////////////////////////////////////////////////////////////// |
|
| 2 |
-/// |
|
| 3 |
-/// A buffer class for temporarily storaging sound samples, operates as a |
|
| 4 |
-/// first-in-first-out pipe. |
|
| 5 |
-/// |
|
| 6 |
-/// Samples are added to the end of the sample buffer with the 'putSamples' |
|
| 7 |
-/// function, and are received from the beginning of the buffer by calling |
|
| 8 |
-/// the 'receiveSamples' function. The class automatically removes the |
|
| 9 |
-/// outputted samples from the buffer, as well as grows the buffer size |
|
| 10 |
-/// whenever necessary. |
|
| 11 |
-/// |
|
| 12 |
-/// Author : Copyright (c) Olli Parviainen |
|
| 13 |
-/// Author e-mail : oparviai 'at' iki.fi |
|
| 14 |
-/// SoundTouch WWW: http://www.surina.net/soundtouch |
|
| 15 |
-/// |
|
| 16 |
-//////////////////////////////////////////////////////////////////////////////// |
|
| 17 |
-// |
|
| 18 |
-// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $ |
|
| 19 |
-// File revision : $Revision: 4 $ |
|
| 20 |
-// |
|
| 21 |
-// $Id: FIFOSampleBuffer.cpp 160 2012-11-08 18:53:01Z oparviai $ |
|
| 22 |
-// |
|
| 23 |
-//////////////////////////////////////////////////////////////////////////////// |
|
| 24 |
-// |
|
| 25 |
-// License : |
|
| 26 |
-// |
|
| 27 |
-// SoundTouch audio processing library |
|
| 28 |
-// Copyright (c) Olli Parviainen |
|
| 29 |
-// |
|
| 30 |
-// This library is free software; you can redistribute it and/or |
|
| 31 |
-// modify it under the terms of the GNU Lesser General Public |
|
| 32 |
-// License as published by the Free Software Foundation; either |
|
| 33 |
-// version 2.1 of the License, or (at your option) any later version. |
|
| 34 |
-// |
|
| 35 |
-// This library is distributed in the hope that it will be useful, |
|
| 36 |
-// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 37 |
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
| 38 |
-// Lesser General Public License for more details. |
|
| 39 |
-// |
|
| 40 |
-// You should have received a copy of the GNU Lesser General Public |
|
| 41 |
-// License along with this library; if not, write to the Free Software |
|
| 42 |
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 43 |
-// |
|
| 44 |
-//////////////////////////////////////////////////////////////////////////////// |
|
| 45 |
- |
|
| 46 |
-#include <stdexcept> |
|
| 47 |
-#include <cstring> |
|
| 48 |
-#include "FIFOSampleBuffer.h" |
|
| 49 |
- |
|
| 50 |
-using namespace soundtouch; |
|
| 51 |
- |
|
| 52 |
-// Constructor |
|
| 53 |
-FIFOSampleBuffer::FIFOSampleBuffer(int32_t numChannels) |
|
| 54 |
-{
|
|
| 55 |
- assert(numChannels > 0); |
|
| 56 |
- this->sizeInBytes = 0; // reasonable initial value |
|
| 57 |
- this->buffer = nullptr; |
|
| 58 |
- this->bufferUnaligned.reset(); |
|
| 59 |
- this->samplesInBuffer = 0; |
|
| 60 |
- this->bufferPos = 0; |
|
| 61 |
- this->channels = numChannels; |
|
| 62 |
- this->ensureCapacity(32); // allocate initial capacity |
|
| 63 |
-} |
|
| 64 |
- |
|
| 65 |
-// Sets number of channels, 1 = mono, 2 = stereo |
|
| 66 |
-void FIFOSampleBuffer::setChannels(int32_t numChannels) |
|
| 67 |
-{
|
|
| 68 |
- assert(numChannels > 0); |
|
| 69 |
- uint32_t usedBytes = this->channels * this->samplesInBuffer; |
|
| 70 |
- this->channels = numChannels; |
|
| 71 |
- this->samplesInBuffer = usedBytes / this->channels; |
|
| 72 |
-} |
|
| 73 |
- |
|
| 74 |
-// if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and |
|
| 75 |
-// zeroes this pointer by copying samples from the 'bufferPos' pointer |
|
| 76 |
-// location on to the beginning of the buffer. |
|
| 77 |
-void FIFOSampleBuffer::rewind() |
|
| 78 |
-{
|
|
| 79 |
- if (this->buffer && this->bufferPos) |
|
| 80 |
- {
|
|
| 81 |
- memmove(this->buffer, this->ptrBegin(), sizeof(SAMPLETYPE) * this->channels * this->samplesInBuffer); |
|
| 82 |
- this->bufferPos = 0; |
|
| 83 |
- } |
|
| 84 |
-} |
|
| 85 |
- |
|
| 86 |
-// Adds 'numSamples' pcs of samples from the 'samples' memory position to |
|
| 87 |
-// the sample buffer. |
|
| 88 |
-void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint32_t nSamples) |
|
| 89 |
-{
|
|
| 90 |
- memcpy(this->ptrEnd(nSamples), samples, sizeof(SAMPLETYPE) * nSamples * this->channels); |
|
| 91 |
- this->samplesInBuffer += nSamples; |
|
| 92 |
-} |
|
| 93 |
- |
|
| 94 |
-// Increases the number of samples in the buffer without copying any actual |
|
| 95 |
-// samples. |
|
| 96 |
-// |
|
| 97 |
-// This function is used to update the number of samples in the sample buffer |
|
| 98 |
-// when accessing the buffer directly with 'ptrEnd' function. Please be |
|
| 99 |
-// careful though! |
|
| 100 |
-void FIFOSampleBuffer::putSamples(uint32_t nSamples) |
|
| 101 |
-{
|
|
| 102 |
- uint32_t req = this->samplesInBuffer + nSamples; |
|
| 103 |
- this->ensureCapacity(req); |
|
| 104 |
- this->samplesInBuffer += nSamples; |
|
| 105 |
-} |
|
| 106 |
- |
|
| 107 |
-// Returns a pointer to the end of the used part of the sample buffer (i.e. |
|
| 108 |
-// where the new samples are to be inserted). This function may be used for |
|
| 109 |
-// inserting new samples into the sample buffer directly. Please be careful! |
|
| 110 |
-// |
|
| 111 |
-// Parameter 'slackCapacity' tells the function how much free capacity (in |
|
| 112 |
-// terms of samples) there _at least_ should be, in order to the caller to |
|
| 113 |
-// succesfully insert all the required samples to the buffer. When necessary, |
|
| 114 |
-// the function grows the buffer size to comply with this requirement. |
|
| 115 |
-// |
|
| 116 |
-// When using this function as means for inserting new samples, also remember |
|
| 117 |
-// to increase the sample count afterwards, by calling the |
|
| 118 |
-// 'putSamples(numSamples)' function. |
|
| 119 |
-SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint32_t slackCapacity) |
|
| 120 |
-{
|
|
| 121 |
- this->ensureCapacity(this->samplesInBuffer + slackCapacity); |
|
| 122 |
- return &this->buffer[this->samplesInBuffer * this->channels]; |
|
| 123 |
-} |
|
| 124 |
- |
|
| 125 |
-// Returns a pointer to the beginning of the currently non-outputted samples. |
|
| 126 |
-// This function is provided for accessing the output samples directly. |
|
| 127 |
-// Please be careful! |
|
| 128 |
-// |
|
| 129 |
-// When using this function to output samples, also remember to 'remove' the |
|
| 130 |
-// outputted samples from the buffer by calling the |
|
| 131 |
-// 'receiveSamples(numSamples)' function |
|
| 132 |
-SAMPLETYPE *FIFOSampleBuffer::ptrBegin() |
|
| 133 |
-{
|
|
| 134 |
- assert(this->buffer); |
|
| 135 |
- return &this->buffer[this->bufferPos * this->channels]; |
|
| 136 |
-} |
|
| 137 |
- |
|
| 138 |
-// Ensures that the buffer has enought capacity, i.e. space for _at least_ |
|
| 139 |
-// 'capacityRequirement' number of samples. The buffer is grown in steps of |
|
| 140 |
-// 4 kilobytes to eliminate the need for frequently growing up the buffer, |
|
| 141 |
-// as well as to round the buffer size up to the virtual memory page size. |
|
| 142 |
-void FIFOSampleBuffer::ensureCapacity(uint32_t capacityRequirement) |
|
| 143 |
-{
|
|
| 144 |
- if (capacityRequirement > this->getCapacity()) |
|
| 145 |
- {
|
|
| 146 |
- // enlarge the buffer in 4kbyte steps (round up to next 4k boundary) |
|
| 147 |
- this->sizeInBytes = (capacityRequirement * this->channels * sizeof(SAMPLETYPE) + 4095) & static_cast<uint32_t>(-4096); |
|
| 148 |
- assert(!(this->sizeInBytes % 2)); |
|
| 149 |
- auto tempUnaligned = std::unique_ptr<SAMPLETYPE[]>(new SAMPLETYPE[(this->sizeInBytes + 16) / sizeof(SAMPLETYPE)]); |
|
| 150 |
- // Align the buffer to begin at 16byte cache line boundary for optimal performance |
|
| 151 |
- SAMPLETYPE *temp = reinterpret_cast<SAMPLETYPE *>(SOUNDTOUCH_ALIGN_POINTER_16(tempUnaligned.get())); |
|
| 152 |
- if (samplesInBuffer) |
|
| 153 |
- memcpy(temp, this->ptrBegin(), samplesInBuffer * this->channels * sizeof(SAMPLETYPE)); |
|
| 154 |
- this->buffer = temp; |
|
| 155 |
- this->bufferUnaligned = std::move(tempUnaligned); |
|
| 156 |
- this->bufferPos = 0; |
|
| 157 |
- } |
|
| 158 |
- else |
|
| 159 |
- // simply rewind the buffer (if necessary) |
|
| 160 |
- this->rewind(); |
|
| 161 |
-} |
|
| 162 |
- |
|
| 163 |
-// Returns the current buffer capacity in terms of samples |
|
| 164 |
-uint32_t FIFOSampleBuffer::getCapacity() const |
|
| 165 |
-{
|
|
| 166 |
- return this->sizeInBytes / (this->channels * sizeof(SAMPLETYPE)); |
|
| 167 |
-} |
|
| 168 |
- |
|
| 169 |
-// Returns the number of samples currently in the buffer |
|
| 170 |
-uint32_t FIFOSampleBuffer::numSamples() const |
|
| 171 |
-{
|
|
| 172 |
- return this->samplesInBuffer; |
|
| 173 |
-} |
|
| 174 |
- |
|
| 175 |
-// Output samples from beginning of the sample buffer. Copies demanded number |
|
| 176 |
-// of samples to output and removes them from the sample buffer. If there |
|
| 177 |
-// are less than 'numsample' samples in the buffer, returns all available. |
|
| 178 |
-// |
|
| 179 |
-// Returns number of samples copied. |
|
| 180 |
-uint32_t FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint32_t maxSamples) |
|
| 181 |
-{
|
|
| 182 |
- uint32_t num = maxSamples > this->samplesInBuffer ? this->samplesInBuffer : maxSamples; |
|
| 183 |
- |
|
| 184 |
- memcpy(output, this->ptrBegin(), this->channels * sizeof(SAMPLETYPE) * num); |
|
| 185 |
- return this->receiveSamples(num); |
|
| 186 |
-} |
|
| 187 |
- |
|
| 188 |
-// Removes samples from the beginning of the sample buffer without copying them |
|
| 189 |
-// anywhere. Used to reduce the number of samples in the buffer, when accessing |
|
| 190 |
-// the sample buffer with the 'ptrBegin' function. |
|
| 191 |
-uint32_t FIFOSampleBuffer::receiveSamples(uint32_t maxSamples) |
|
| 192 |
-{
|
|
| 193 |
- if (maxSamples >= this->samplesInBuffer) |
|
| 194 |
- {
|
|
| 195 |
- uint32_t temp = this->samplesInBuffer; |
|
| 196 |
- this->samplesInBuffer = 0; |
|
| 197 |
- return temp; |
|
| 198 |
- } |
|
| 199 |
- |
|
| 200 |
- this->samplesInBuffer -= maxSamples; |
|
| 201 |
- this->bufferPos += maxSamples; |
|
| 202 |
- |
|
| 203 |
- return maxSamples; |
|
| 204 |
-} |
|
| 205 |
- |
|
| 206 |
-// Returns nonzero if the sample buffer is empty |
|
| 207 |
-bool FIFOSampleBuffer::isEmpty() const |
|
| 208 |
-{
|
|
| 209 |
- return !this->samplesInBuffer; |
|
| 210 |
-} |
|
| 211 |
- |
|
| 212 |
-// Clears the sample buffer |
|
| 213 |
-void FIFOSampleBuffer::clear() |
|
| 214 |
-{
|
|
| 215 |
- this->samplesInBuffer = 0; |
|
| 216 |
- this->bufferPos = 0; |
|
| 217 |
-} |
|
| 218 |
- |
|
| 219 |
-/// allow trimming (downwards) amount of samples in pipeline. |
|
| 220 |
-/// Returns adjusted amount of samples |
|
| 221 |
-uint32_t FIFOSampleBuffer::adjustAmountOfSamples(uint32_t numSmpls) |
|
| 222 |
-{
|
|
| 223 |
- if (numSmpls < this->samplesInBuffer) |
|
| 224 |
- this->samplesInBuffer = numSmpls; |
|
| 225 |
- return this->samplesInBuffer; |
|
| 226 |
-} |
* [2SF] Used more up-to-date asmjit, despite the ugly looking code.
| ... | ... |
@@ -59,7 +59,7 @@ FIFOSampleBuffer::FIFOSampleBuffer(int32_t numChannels) |
| 59 | 59 |
this->samplesInBuffer = 0; |
| 60 | 60 |
this->bufferPos = 0; |
| 61 | 61 |
this->channels = numChannels; |
| 62 |
- this->ensureCapacity(32); // allocate initial capacity |
|
| 62 |
+ this->ensureCapacity(32); // allocate initial capacity |
|
| 63 | 63 |
} |
| 64 | 64 |
|
| 65 | 65 |
// Sets number of channels, 1 = mono, 2 = stereo |
| ... | ... |
@@ -218,9 +218,9 @@ void FIFOSampleBuffer::clear() |
| 218 | 218 |
|
| 219 | 219 |
/// allow trimming (downwards) amount of samples in pipeline. |
| 220 | 220 |
/// Returns adjusted amount of samples |
| 221 |
-uint32_t FIFOSampleBuffer::adjustAmountOfSamples(uint32_t numSamples) |
|
| 221 |
+uint32_t FIFOSampleBuffer::adjustAmountOfSamples(uint32_t numSmpls) |
|
| 222 | 222 |
{
|
| 223 |
- if (numSamples < this->samplesInBuffer) |
|
| 224 |
- this->samplesInBuffer = numSamples; |
|
| 223 |
+ if (numSmpls < this->samplesInBuffer) |
|
| 224 |
+ this->samplesInBuffer = numSmpls; |
|
| 225 | 225 |
return this->samplesInBuffer; |
| 226 | 226 |
} |
| ... | ... |
@@ -62,11 +62,6 @@ FIFOSampleBuffer::FIFOSampleBuffer(int32_t numChannels) |
| 62 | 62 |
this->ensureCapacity(32); // allocate initial capacity |
| 63 | 63 |
} |
| 64 | 64 |
|
| 65 |
-// destructor |
|
| 66 |
-FIFOSampleBuffer::~FIFOSampleBuffer() |
|
| 67 |
-{
|
|
| 68 |
-} |
|
| 69 |
- |
|
| 70 | 65 |
// Sets number of channels, 1 = mono, 2 = stereo |
| 71 | 66 |
void FIFOSampleBuffer::setChannels(int32_t numChannels) |
| 72 | 67 |
{
|
| ... | ... |
@@ -58,7 +58,7 @@ FIFOSampleBuffer::FIFOSampleBuffer(int32_t numChannels) |
| 58 | 58 |
this->bufferUnaligned.reset(); |
| 59 | 59 |
this->samplesInBuffer = 0; |
| 60 | 60 |
this->bufferPos = 0; |
| 61 |
- this->channels = static_cast<uint32_t>(numChannels); |
|
| 61 |
+ this->channels = numChannels; |
|
| 62 | 62 |
this->ensureCapacity(32); // allocate initial capacity |
| 63 | 63 |
} |
| 64 | 64 |
|
| ... | ... |
@@ -72,7 +72,7 @@ void FIFOSampleBuffer::setChannels(int32_t numChannels) |
| 72 | 72 |
{
|
| 73 | 73 |
assert(numChannels > 0); |
| 74 | 74 |
uint32_t usedBytes = this->channels * this->samplesInBuffer; |
| 75 |
- this->channels = static_cast<uint32_t>(numChannels); |
|
| 75 |
+ this->channels = numChannels; |
|
| 76 | 76 |
this->samplesInBuffer = usedBytes / this->channels; |
| 77 | 77 |
} |
| 78 | 78 |
|
| ... | ... |
@@ -15,10 +15,10 @@ |
| 15 | 15 |
/// |
| 16 | 16 |
//////////////////////////////////////////////////////////////////////////////// |
| 17 | 17 |
// |
| 18 |
-// Last changed : $Date: 2006/02/05 16:44:06 $ |
|
| 19 |
-// File revision : $Revision: 1.11 $ |
|
| 18 |
+// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $ |
|
| 19 |
+// File revision : $Revision: 4 $ |
|
| 20 | 20 |
// |
| 21 |
-// $Id: FIFOSampleBuffer.cpp,v 1.11 2006/02/05 16:44:06 Olli Exp $ |
|
| 21 |
+// $Id: FIFOSampleBuffer.cpp 160 2012-11-08 18:53:01Z oparviai $ |
|
| 22 | 22 |
// |
| 23 | 23 |
//////////////////////////////////////////////////////////////////////////////// |
| 24 | 24 |
// |
| ... | ... |
@@ -45,35 +45,35 @@ |
| 45 | 45 |
|
| 46 | 46 |
#include <stdexcept> |
| 47 | 47 |
#include <cstring> |
| 48 |
- |
|
| 49 | 48 |
#include "FIFOSampleBuffer.h" |
| 50 | 49 |
|
| 51 | 50 |
using namespace soundtouch; |
| 52 | 51 |
|
| 53 | 52 |
// Constructor |
| 54 |
-FIFOSampleBuffer::FIFOSampleBuffer(uint32_t numChannels) |
|
| 53 |
+FIFOSampleBuffer::FIFOSampleBuffer(int32_t numChannels) |
|
| 55 | 54 |
{
|
| 56 |
- sizeInBytes = 0; // reasonable initial value |
|
| 57 |
- buffer = NULL; //new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE)]; |
|
| 58 |
- bufferUnaligned = NULL; |
|
| 59 |
- samplesInBuffer = 0; |
|
| 60 |
- bufferPos = 0; |
|
| 61 |
- channels = numChannels; |
|
| 55 |
+ assert(numChannels > 0); |
|
| 56 |
+ this->sizeInBytes = 0; // reasonable initial value |
|
| 57 |
+ this->buffer = nullptr; |
|
| 58 |
+ this->bufferUnaligned.reset(); |
|
| 59 |
+ this->samplesInBuffer = 0; |
|
| 60 |
+ this->bufferPos = 0; |
|
| 61 |
+ this->channels = static_cast<uint32_t>(numChannels); |
|
| 62 |
+ this->ensureCapacity(32); // allocate initial capacity |
|
| 62 | 63 |
} |
| 63 | 64 |
|
| 64 | 65 |
// destructor |
| 65 | 66 |
FIFOSampleBuffer::~FIFOSampleBuffer() |
| 66 | 67 |
{
|
| 67 |
- if (bufferUnaligned) |
|
| 68 |
- delete[] bufferUnaligned; |
|
| 69 | 68 |
} |
| 70 | 69 |
|
| 71 | 70 |
// Sets number of channels, 1 = mono, 2 = stereo |
| 72 |
-void FIFOSampleBuffer::setChannels(uint32_t numChannels) |
|
| 71 |
+void FIFOSampleBuffer::setChannels(int32_t numChannels) |
|
| 73 | 72 |
{
|
| 74 |
- uint32_t usedBytes = channels * samplesInBuffer; |
|
| 75 |
- channels = numChannels; |
|
| 76 |
- samplesInBuffer = usedBytes / channels; |
|
| 73 |
+ assert(numChannels > 0); |
|
| 74 |
+ uint32_t usedBytes = this->channels * this->samplesInBuffer; |
|
| 75 |
+ this->channels = static_cast<uint32_t>(numChannels); |
|
| 76 |
+ this->samplesInBuffer = usedBytes / this->channels; |
|
| 77 | 77 |
} |
| 78 | 78 |
|
| 79 | 79 |
// if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and |
| ... | ... |
@@ -81,19 +81,19 @@ void FIFOSampleBuffer::setChannels(uint32_t numChannels) |
| 81 | 81 |
// location on to the beginning of the buffer. |
| 82 | 82 |
void FIFOSampleBuffer::rewind() |
| 83 | 83 |
{
|
| 84 |
- if (bufferPos) |
|
| 84 |
+ if (this->buffer && this->bufferPos) |
|
| 85 | 85 |
{
|
| 86 |
- memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer); |
|
| 87 |
- bufferPos = 0; |
|
| 86 |
+ memmove(this->buffer, this->ptrBegin(), sizeof(SAMPLETYPE) * this->channels * this->samplesInBuffer); |
|
| 87 |
+ this->bufferPos = 0; |
|
| 88 | 88 |
} |
| 89 | 89 |
} |
| 90 | 90 |
|
| 91 | 91 |
// Adds 'numSamples' pcs of samples from the 'samples' memory position to |
| 92 | 92 |
// the sample buffer. |
| 93 |
-void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint32_t numsamples) |
|
| 93 |
+void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint32_t nSamples) |
|
| 94 | 94 |
{
|
| 95 |
- memcpy(ptrEnd(numsamples), samples, sizeof(SAMPLETYPE) * numsamples * channels); |
|
| 96 |
- samplesInBuffer += numsamples; |
|
| 95 |
+ memcpy(this->ptrEnd(nSamples), samples, sizeof(SAMPLETYPE) * nSamples * this->channels); |
|
| 96 |
+ this->samplesInBuffer += nSamples; |
|
| 97 | 97 |
} |
| 98 | 98 |
|
| 99 | 99 |
// Increases the number of samples in the buffer without copying any actual |
| ... | ... |
@@ -102,11 +102,11 @@ void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint32_t numsamples |
| 102 | 102 |
// This function is used to update the number of samples in the sample buffer |
| 103 | 103 |
// when accessing the buffer directly with 'ptrEnd' function. Please be |
| 104 | 104 |
// careful though! |
| 105 |
-void FIFOSampleBuffer::putSamples(uint32_t numsamples) |
|
| 105 |
+void FIFOSampleBuffer::putSamples(uint32_t nSamples) |
|
| 106 | 106 |
{
|
| 107 |
- uint32_t req = samplesInBuffer + numsamples; |
|
| 107 |
+ uint32_t req = this->samplesInBuffer + nSamples; |
|
| 108 | 108 |
this->ensureCapacity(req); |
| 109 |
- samplesInBuffer += numsamples; |
|
| 109 |
+ this->samplesInBuffer += nSamples; |
|
| 110 | 110 |
} |
| 111 | 111 |
|
| 112 | 112 |
// Returns a pointer to the end of the used part of the sample buffer (i.e. |
| ... | ... |
@@ -123,8 +123,8 @@ void FIFOSampleBuffer::putSamples(uint32_t numsamples) |
| 123 | 123 |
// 'putSamples(numSamples)' function. |
| 124 | 124 |
SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint32_t slackCapacity) |
| 125 | 125 |
{
|
| 126 |
- this->ensureCapacity(samplesInBuffer + slackCapacity); |
|
| 127 |
- return buffer + samplesInBuffer * channels; |
|
| 126 |
+ this->ensureCapacity(this->samplesInBuffer + slackCapacity); |
|
| 127 |
+ return &this->buffer[this->samplesInBuffer * this->channels]; |
|
| 128 | 128 |
} |
| 129 | 129 |
|
| 130 | 130 |
// Returns a pointer to the beginning of the currently non-outputted samples. |
| ... | ... |
@@ -134,9 +134,10 @@ SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint32_t slackCapacity) |
| 134 | 134 |
// When using this function to output samples, also remember to 'remove' the |
| 135 | 135 |
// outputted samples from the buffer by calling the |
| 136 | 136 |
// 'receiveSamples(numSamples)' function |
| 137 |
-SAMPLETYPE *FIFOSampleBuffer::ptrBegin() const |
|
| 137 |
+SAMPLETYPE *FIFOSampleBuffer::ptrBegin() |
|
| 138 | 138 |
{
|
| 139 |
- return buffer + bufferPos * channels; |
|
| 139 |
+ assert(this->buffer); |
|
| 140 |
+ return &this->buffer[this->bufferPos * this->channels]; |
|
| 140 | 141 |
} |
| 141 | 142 |
|
| 142 | 143 |
// Ensures that the buffer has enought capacity, i.e. space for _at least_ |
| ... | ... |
@@ -145,34 +146,35 @@ SAMPLETYPE *FIFOSampleBuffer::ptrBegin() const |
| 145 | 146 |
// as well as to round the buffer size up to the virtual memory page size. |
| 146 | 147 |
void FIFOSampleBuffer::ensureCapacity(uint32_t capacityRequirement) |
| 147 | 148 |
{
|
| 148 |
- if (capacityRequirement > getCapacity()) |
|
| 149 |
+ if (capacityRequirement > this->getCapacity()) |
|
| 149 | 150 |
{
|
| 150 | 151 |
// enlarge the buffer in 4kbyte steps (round up to next 4k boundary) |
| 151 |
- sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & -4096; |
|
| 152 |
- assert(!(sizeInBytes % 2)); |
|
| 153 |
- SAMPLETYPE *tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)]; |
|
| 154 |
- SAMPLETYPE *temp = reinterpret_cast<SAMPLETYPE *>((reinterpret_cast<intptr_t>(tempUnaligned) + 15) & -16); |
|
| 155 |
- memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE)); |
|
| 156 |
- delete[] bufferUnaligned; |
|
| 157 |
- buffer = temp; |
|
| 158 |
- bufferUnaligned = tempUnaligned; |
|
| 159 |
- bufferPos = 0; |
|
| 152 |
+ this->sizeInBytes = (capacityRequirement * this->channels * sizeof(SAMPLETYPE) + 4095) & static_cast<uint32_t>(-4096); |
|
| 153 |
+ assert(!(this->sizeInBytes % 2)); |
|
| 154 |
+ auto tempUnaligned = std::unique_ptr<SAMPLETYPE[]>(new SAMPLETYPE[(this->sizeInBytes + 16) / sizeof(SAMPLETYPE)]); |
|
| 155 |
+ // Align the buffer to begin at 16byte cache line boundary for optimal performance |
|
| 156 |
+ SAMPLETYPE *temp = reinterpret_cast<SAMPLETYPE *>(SOUNDTOUCH_ALIGN_POINTER_16(tempUnaligned.get())); |
|
| 157 |
+ if (samplesInBuffer) |
|
| 158 |
+ memcpy(temp, this->ptrBegin(), samplesInBuffer * this->channels * sizeof(SAMPLETYPE)); |
|
| 159 |
+ this->buffer = temp; |
|
| 160 |
+ this->bufferUnaligned = std::move(tempUnaligned); |
|
| 161 |
+ this->bufferPos = 0; |
|
| 160 | 162 |
} |
| 161 | 163 |
else |
| 162 | 164 |
// simply rewind the buffer (if necessary) |
| 163 |
- rewind(); |
|
| 165 |
+ this->rewind(); |
|
| 164 | 166 |
} |
| 165 | 167 |
|
| 166 | 168 |
// Returns the current buffer capacity in terms of samples |
| 167 | 169 |
uint32_t FIFOSampleBuffer::getCapacity() const |
| 168 | 170 |
{
|
| 169 |
- return sizeInBytes / (channels * sizeof(SAMPLETYPE)); |
|
| 171 |
+ return this->sizeInBytes / (this->channels * sizeof(SAMPLETYPE)); |
|
| 170 | 172 |
} |
| 171 | 173 |
|
| 172 | 174 |
// Returns the number of samples currently in the buffer |
| 173 | 175 |
uint32_t FIFOSampleBuffer::numSamples() const |
| 174 | 176 |
{
|
| 175 |
- return samplesInBuffer; |
|
| 177 |
+ return this->samplesInBuffer; |
|
| 176 | 178 |
} |
| 177 | 179 |
|
| 178 | 180 |
// Output samples from beginning of the sample buffer. Copies demanded number |
| ... | ... |
@@ -182,9 +184,9 @@ uint32_t FIFOSampleBuffer::numSamples() const |
| 182 | 184 |
// Returns number of samples copied. |
| 183 | 185 |
uint32_t FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint32_t maxSamples) |
| 184 | 186 |
{
|
| 185 |
- uint32_t num = maxSamples > samplesInBuffer ? samplesInBuffer : maxSamples; |
|
| 187 |
+ uint32_t num = maxSamples > this->samplesInBuffer ? this->samplesInBuffer : maxSamples; |
|
| 186 | 188 |
|
| 187 |
- memcpy(output, ptrBegin(), channels * sizeof(SAMPLETYPE) * num); |
|
| 189 |
+ memcpy(output, this->ptrBegin(), this->channels * sizeof(SAMPLETYPE) * num); |
|
| 188 | 190 |
return this->receiveSamples(num); |
| 189 | 191 |
} |
| 190 | 192 |
|
| ... | ... |
@@ -193,15 +195,15 @@ uint32_t FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint32_t maxSample |
| 193 | 195 |
// the sample buffer with the 'ptrBegin' function. |
| 194 | 196 |
uint32_t FIFOSampleBuffer::receiveSamples(uint32_t maxSamples) |
| 195 | 197 |
{
|
| 196 |
- if (maxSamples >= samplesInBuffer) |
|
| 198 |
+ if (maxSamples >= this->samplesInBuffer) |
|
| 197 | 199 |
{
|
| 198 |
- uint32_t temp = samplesInBuffer; |
|
| 199 |
- samplesInBuffer = 0; |
|
| 200 |
+ uint32_t temp = this->samplesInBuffer; |
|
| 201 |
+ this->samplesInBuffer = 0; |
|
| 200 | 202 |
return temp; |
| 201 | 203 |
} |
| 202 | 204 |
|
| 203 |
- samplesInBuffer -= maxSamples; |
|
| 204 |
- bufferPos += maxSamples; |
|
| 205 |
+ this->samplesInBuffer -= maxSamples; |
|
| 206 |
+ this->bufferPos += maxSamples; |
|
| 205 | 207 |
|
| 206 | 208 |
return maxSamples; |
| 207 | 209 |
} |
| ... | ... |
@@ -209,12 +211,21 @@ uint32_t FIFOSampleBuffer::receiveSamples(uint32_t maxSamples) |
| 209 | 211 |
// Returns nonzero if the sample buffer is empty |
| 210 | 212 |
bool FIFOSampleBuffer::isEmpty() const |
| 211 | 213 |
{
|
| 212 |
- return !samplesInBuffer; |
|
| 214 |
+ return !this->samplesInBuffer; |
|
| 213 | 215 |
} |
| 214 | 216 |
|
| 215 | 217 |
// Clears the sample buffer |
| 216 | 218 |
void FIFOSampleBuffer::clear() |
| 217 | 219 |
{
|
| 218 |
- samplesInBuffer = 0; |
|
| 219 |
- bufferPos = 0; |
|
| 220 |
+ this->samplesInBuffer = 0; |
|
| 221 |
+ this->bufferPos = 0; |
|
| 222 |
+} |
|
| 223 |
+ |
|
| 224 |
+/// allow trimming (downwards) amount of samples in pipeline. |
|
| 225 |
+/// Returns adjusted amount of samples |
|
| 226 |
+uint32_t FIFOSampleBuffer::adjustAmountOfSamples(uint32_t numSamples) |
|
| 227 |
+{
|
|
| 228 |
+ if (numSamples < this->samplesInBuffer) |
|
| 229 |
+ this->samplesInBuffer = numSamples; |
|
| 230 |
+ return this->samplesInBuffer; |
|
| 220 | 231 |
} |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,220 @@ |
| 1 |
+//////////////////////////////////////////////////////////////////////////////// |
|
| 2 |
+/// |
|
| 3 |
+/// A buffer class for temporarily storaging sound samples, operates as a |
|
| 4 |
+/// first-in-first-out pipe. |
|
| 5 |
+/// |
|
| 6 |
+/// Samples are added to the end of the sample buffer with the 'putSamples' |
|
| 7 |
+/// function, and are received from the beginning of the buffer by calling |
|
| 8 |
+/// the 'receiveSamples' function. The class automatically removes the |
|
| 9 |
+/// outputted samples from the buffer, as well as grows the buffer size |
|
| 10 |
+/// whenever necessary. |
|
| 11 |
+/// |
|
| 12 |
+/// Author : Copyright (c) Olli Parviainen |
|
| 13 |
+/// Author e-mail : oparviai 'at' iki.fi |
|
| 14 |
+/// SoundTouch WWW: http://www.surina.net/soundtouch |
|
| 15 |
+/// |
|
| 16 |
+//////////////////////////////////////////////////////////////////////////////// |
|
| 17 |
+// |
|
| 18 |
+// Last changed : $Date: 2006/02/05 16:44:06 $ |
|
| 19 |
+// File revision : $Revision: 1.11 $ |
|
| 20 |
+// |
|
| 21 |
+// $Id: FIFOSampleBuffer.cpp,v 1.11 2006/02/05 16:44:06 Olli Exp $ |
|
| 22 |
+// |
|
| 23 |
+//////////////////////////////////////////////////////////////////////////////// |
|
| 24 |
+// |
|
| 25 |
+// License : |
|
| 26 |
+// |
|
| 27 |
+// SoundTouch audio processing library |
|
| 28 |
+// Copyright (c) Olli Parviainen |
|
| 29 |
+// |
|
| 30 |
+// This library is free software; you can redistribute it and/or |
|
| 31 |
+// modify it under the terms of the GNU Lesser General Public |
|
| 32 |
+// License as published by the Free Software Foundation; either |
|
| 33 |
+// version 2.1 of the License, or (at your option) any later version. |
|
| 34 |
+// |
|
| 35 |
+// This library is distributed in the hope that it will be useful, |
|
| 36 |
+// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 37 |
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
| 38 |
+// Lesser General Public License for more details. |
|
| 39 |
+// |
|
| 40 |
+// You should have received a copy of the GNU Lesser General Public |
|
| 41 |
+// License along with this library; if not, write to the Free Software |
|
| 42 |
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 43 |
+// |
|
| 44 |
+//////////////////////////////////////////////////////////////////////////////// |
|
| 45 |
+ |
|
| 46 |
+#include <stdexcept> |
|
| 47 |
+#include <cstring> |
|
| 48 |
+ |
|
| 49 |
+#include "FIFOSampleBuffer.h" |
|
| 50 |
+ |
|
| 51 |
+using namespace soundtouch; |
|
| 52 |
+ |
|
| 53 |
+// Constructor |
|
| 54 |
+FIFOSampleBuffer::FIFOSampleBuffer(uint32_t numChannels) |
|
| 55 |
+{
|
|
| 56 |
+ sizeInBytes = 0; // reasonable initial value |
|
| 57 |
+ buffer = NULL; //new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE)]; |
|
| 58 |
+ bufferUnaligned = NULL; |
|
| 59 |
+ samplesInBuffer = 0; |
|
| 60 |
+ bufferPos = 0; |
|
| 61 |
+ channels = numChannels; |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+// destructor |
|
| 65 |
+FIFOSampleBuffer::~FIFOSampleBuffer() |
|
| 66 |
+{
|
|
| 67 |
+ if (bufferUnaligned) |
|
| 68 |
+ delete[] bufferUnaligned; |
|
| 69 |
+} |
|
| 70 |
+ |
|
| 71 |
+// Sets number of channels, 1 = mono, 2 = stereo |
|
| 72 |
+void FIFOSampleBuffer::setChannels(uint32_t numChannels) |
|
| 73 |
+{
|
|
| 74 |
+ uint32_t usedBytes = channels * samplesInBuffer; |
|
| 75 |
+ channels = numChannels; |
|
| 76 |
+ samplesInBuffer = usedBytes / channels; |
|
| 77 |
+} |
|
| 78 |
+ |
|
| 79 |
+// if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and |
|
| 80 |
+// zeroes this pointer by copying samples from the 'bufferPos' pointer |
|
| 81 |
+// location on to the beginning of the buffer. |
|
| 82 |
+void FIFOSampleBuffer::rewind() |
|
| 83 |
+{
|
|
| 84 |
+ if (bufferPos) |
|
| 85 |
+ {
|
|
| 86 |
+ memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer); |
|
| 87 |
+ bufferPos = 0; |
|
| 88 |
+ } |
|
| 89 |
+} |
|
| 90 |
+ |
|
| 91 |
+// Adds 'numSamples' pcs of samples from the 'samples' memory position to |
|
| 92 |
+// the sample buffer. |
|
| 93 |
+void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint32_t numsamples) |
|
| 94 |
+{
|
|
| 95 |
+ memcpy(ptrEnd(numsamples), samples, sizeof(SAMPLETYPE) * numsamples * channels); |
|
| 96 |
+ samplesInBuffer += numsamples; |
|
| 97 |
+} |
|
| 98 |
+ |
|
| 99 |
+// Increases the number of samples in the buffer without copying any actual |
|
| 100 |
+// samples. |
|
| 101 |
+// |
|
| 102 |
+// This function is used to update the number of samples in the sample buffer |
|
| 103 |
+// when accessing the buffer directly with 'ptrEnd' function. Please be |
|
| 104 |
+// careful though! |
|
| 105 |
+void FIFOSampleBuffer::putSamples(uint32_t numsamples) |
|
| 106 |
+{
|
|
| 107 |
+ uint32_t req = samplesInBuffer + numsamples; |
|
| 108 |
+ this->ensureCapacity(req); |
|
| 109 |
+ samplesInBuffer += numsamples; |
|
| 110 |
+} |
|
| 111 |
+ |
|
| 112 |
+// Returns a pointer to the end of the used part of the sample buffer (i.e. |
|
| 113 |
+// where the new samples are to be inserted). This function may be used for |
|
| 114 |
+// inserting new samples into the sample buffer directly. Please be careful! |
|
| 115 |
+// |
|
| 116 |
+// Parameter 'slackCapacity' tells the function how much free capacity (in |
|
| 117 |
+// terms of samples) there _at least_ should be, in order to the caller to |
|
| 118 |
+// succesfully insert all the required samples to the buffer. When necessary, |
|
| 119 |
+// the function grows the buffer size to comply with this requirement. |
|
| 120 |
+// |
|
| 121 |
+// When using this function as means for inserting new samples, also remember |
|
| 122 |
+// to increase the sample count afterwards, by calling the |
|
| 123 |
+// 'putSamples(numSamples)' function. |
|
| 124 |
+SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint32_t slackCapacity) |
|
| 125 |
+{
|
|
| 126 |
+ this->ensureCapacity(samplesInBuffer + slackCapacity); |
|
| 127 |
+ return buffer + samplesInBuffer * channels; |
|
| 128 |
+} |
|
| 129 |
+ |
|
| 130 |
+// Returns a pointer to the beginning of the currently non-outputted samples. |
|
| 131 |
+// This function is provided for accessing the output samples directly. |
|
| 132 |
+// Please be careful! |
|
| 133 |
+// |
|
| 134 |
+// When using this function to output samples, also remember to 'remove' the |
|
| 135 |
+// outputted samples from the buffer by calling the |
|
| 136 |
+// 'receiveSamples(numSamples)' function |
|
| 137 |
+SAMPLETYPE *FIFOSampleBuffer::ptrBegin() const |
|
| 138 |
+{
|
|
| 139 |
+ return buffer + bufferPos * channels; |
|
| 140 |
+} |
|
| 141 |
+ |
|
| 142 |
+// Ensures that the buffer has enought capacity, i.e. space for _at least_ |
|
| 143 |
+// 'capacityRequirement' number of samples. The buffer is grown in steps of |
|
| 144 |
+// 4 kilobytes to eliminate the need for frequently growing up the buffer, |
|
| 145 |
+// as well as to round the buffer size up to the virtual memory page size. |
|
| 146 |
+void FIFOSampleBuffer::ensureCapacity(uint32_t capacityRequirement) |
|
| 147 |
+{
|
|
| 148 |
+ if (capacityRequirement > getCapacity()) |
|
| 149 |
+ {
|
|
| 150 |
+ // enlarge the buffer in 4kbyte steps (round up to next 4k boundary) |
|
| 151 |
+ sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & -4096; |
|
| 152 |
+ assert(!(sizeInBytes % 2)); |
|
| 153 |
+ SAMPLETYPE *tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)]; |
|
| 154 |
+ SAMPLETYPE *temp = reinterpret_cast<SAMPLETYPE *>((reinterpret_cast<intptr_t>(tempUnaligned) + 15) & -16); |
|
| 155 |
+ memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE)); |
|
| 156 |
+ delete[] bufferUnaligned; |
|
| 157 |
+ buffer = temp; |
|
| 158 |
+ bufferUnaligned = tempUnaligned; |
|
| 159 |
+ bufferPos = 0; |
|
| 160 |
+ } |
|
| 161 |
+ else |
|
| 162 |
+ // simply rewind the buffer (if necessary) |
|
| 163 |
+ rewind(); |
|
| 164 |
+} |
|
| 165 |
+ |
|
| 166 |
+// Returns the current buffer capacity in terms of samples |
|
| 167 |
+uint32_t FIFOSampleBuffer::getCapacity() const |
|
| 168 |
+{
|
|
| 169 |
+ return sizeInBytes / (channels * sizeof(SAMPLETYPE)); |
|
| 170 |
+} |
|
| 171 |
+ |
|
| 172 |
+// Returns the number of samples currently in the buffer |
|
| 173 |
+uint32_t FIFOSampleBuffer::numSamples() const |
|
| 174 |
+{
|
|
| 175 |
+ return samplesInBuffer; |
|
| 176 |
+} |
|
| 177 |
+ |
|
| 178 |
+// Output samples from beginning of the sample buffer. Copies demanded number |
|
| 179 |
+// of samples to output and removes them from the sample buffer. If there |
|
| 180 |
+// are less than 'numsample' samples in the buffer, returns all available. |
|
| 181 |
+// |
|
| 182 |
+// Returns number of samples copied. |
|
| 183 |
+uint32_t FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint32_t maxSamples) |
|
| 184 |
+{
|
|
| 185 |
+ uint32_t num = maxSamples > samplesInBuffer ? samplesInBuffer : maxSamples; |
|
| 186 |
+ |
|
| 187 |
+ memcpy(output, ptrBegin(), channels * sizeof(SAMPLETYPE) * num); |
|
| 188 |
+ return this->receiveSamples(num); |
|
| 189 |
+} |
|
| 190 |
+ |
|
| 191 |
+// Removes samples from the beginning of the sample buffer without copying them |
|
| 192 |
+// anywhere. Used to reduce the number of samples in the buffer, when accessing |
|
| 193 |
+// the sample buffer with the 'ptrBegin' function. |
|
| 194 |
+uint32_t FIFOSampleBuffer::receiveSamples(uint32_t maxSamples) |
|
| 195 |
+{
|
|
| 196 |
+ if (maxSamples >= samplesInBuffer) |
|
| 197 |
+ {
|
|
| 198 |
+ uint32_t temp = samplesInBuffer; |
|
| 199 |
+ samplesInBuffer = 0; |
|
| 200 |
+ return temp; |
|
| 201 |
+ } |
|
| 202 |
+ |
|
| 203 |
+ samplesInBuffer -= maxSamples; |
|
| 204 |
+ bufferPos += maxSamples; |
|
| 205 |
+ |
|
| 206 |
+ return maxSamples; |
|
| 207 |
+} |
|
| 208 |
+ |
|
| 209 |
+// Returns nonzero if the sample buffer is empty |
|
| 210 |
+bool FIFOSampleBuffer::isEmpty() const |
|
| 211 |
+{
|
|
| 212 |
+ return !samplesInBuffer; |
|
| 213 |
+} |
|
| 214 |
+ |
|
| 215 |
+// Clears the sample buffer |
|
| 216 |
+void FIFOSampleBuffer::clear() |
|
| 217 |
+{
|
|
| 218 |
+ samplesInBuffer = 0; |
|
| 219 |
+ bufferPos = 0; |
|
| 220 |
+} |