00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00045
00046 #include <stdlib.h>
00047 #include <memory.h>
00048 #include <string.h>
00049 #include <assert.h>
00050 #include <stdexcept>
00051
00052 #include "FIFOSampleBuffer.h"
00053
00054 using namespace soundtouch;
00055
00056
00057 FIFOSampleBuffer::FIFOSampleBuffer(uint numChannels)
00058 {
00059 sizeInBytes = 0;
00060 buffer = NULL;
00061 bufferUnaligned = NULL;
00062 samplesInBuffer = 0;
00063 bufferPos = 0;
00064 channels = numChannels;
00065 }
00066
00067
00068
00069 FIFOSampleBuffer::~FIFOSampleBuffer()
00070 {
00071 delete[] bufferUnaligned;
00072 }
00073
00074
00075
00076 void FIFOSampleBuffer::setChannels(const uint numChannels)
00077 {
00078 uint usedBytes;
00079
00080 usedBytes = channels * samplesInBuffer;
00081 channels = numChannels;
00082 samplesInBuffer = usedBytes / channels;
00083 }
00084
00085
00086
00087
00088
00089 void FIFOSampleBuffer::rewind()
00090 {
00091 if (bufferPos)
00092 {
00093 memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer);
00094 bufferPos = 0;
00095 }
00096 }
00097
00098
00099
00100
00101 void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint numSamples)
00102 {
00103 memcpy(ptrEnd(numSamples), samples, sizeof(SAMPLETYPE) * numSamples * channels);
00104 samplesInBuffer += numSamples;
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114 void FIFOSampleBuffer::putSamples(uint numSamples)
00115 {
00116 uint req;
00117
00118 req = samplesInBuffer + numSamples;
00119 ensureCapacity(req);
00120 samplesInBuffer += numSamples;
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity)
00137 {
00138 ensureCapacity(samplesInBuffer + slackCapacity);
00139 return buffer + samplesInBuffer * channels;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 SAMPLETYPE *FIFOSampleBuffer::ptrBegin() const
00151 {
00152 return buffer + bufferPos * channels;
00153 }
00154
00155
00156
00157
00158
00159
00160 void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
00161 {
00162 SAMPLETYPE *tempUnaligned, *temp;
00163
00164 if (capacityRequirement > getCapacity())
00165 {
00166
00167 sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & -4096;
00168 assert(sizeInBytes % 2 == 0);
00169 tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
00170 if (tempUnaligned == NULL)
00171 {
00172 throw std::runtime_error("Couldn't allocate memory!\n");
00173 }
00174 temp = (SAMPLETYPE *)(((ulong)tempUnaligned + 15) & -16);
00175 memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE));
00176 delete[] bufferUnaligned;
00177 buffer = temp;
00178 bufferUnaligned = tempUnaligned;
00179 bufferPos = 0;
00180 }
00181 else
00182 {
00183
00184 rewind();
00185 }
00186 }
00187
00188
00189
00190 uint FIFOSampleBuffer::getCapacity() const
00191 {
00192 return sizeInBytes / (channels * sizeof(SAMPLETYPE));
00193 }
00194
00195
00196
00197 uint FIFOSampleBuffer::numSamples() const
00198 {
00199 return samplesInBuffer;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208 uint FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint maxSamples)
00209 {
00210 uint num;
00211
00212 num = (maxSamples > samplesInBuffer) ? samplesInBuffer : maxSamples;
00213
00214 memcpy(output, ptrBegin(), channels * sizeof(SAMPLETYPE) * num);
00215 return receiveSamples(num);
00216 }
00217
00218
00219
00220
00221
00222 uint FIFOSampleBuffer::receiveSamples(uint maxSamples)
00223 {
00224 if (maxSamples >= samplesInBuffer)
00225 {
00226 uint temp;
00227
00228 temp = samplesInBuffer;
00229 samplesInBuffer = 0;
00230 return temp;
00231 }
00232
00233 samplesInBuffer -= maxSamples;
00234 bufferPos += maxSamples;
00235
00236 return maxSamples;
00237 }
00238
00239
00240
00241 int FIFOSampleBuffer::isEmpty() const
00242 {
00243 return (samplesInBuffer == 0) ? 1 : 0;
00244 }
00245
00246
00247
00248 void FIFOSampleBuffer::clear()
00249 {
00250 samplesInBuffer = 0;
00251 bufferPos = 0;
00252 }