/[pcsx2_0.9.7]/trunk/3rdparty/SoundTouch/FIFOSampleBuffer.cpp
ViewVC logotype

Contents of /trunk/3rdparty/SoundTouch/FIFOSampleBuffer.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations) (download)
Mon Sep 6 11:19:43 2010 UTC (9 years, 4 months ago) by william
File size: 8543 byte(s)
Exported ./upsream/trunk @r3730 from http://pcsx2.googlecode.com/svn/trunk/
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: 2009-02-27 19:24:42 +0200 (Fri, 27 Feb 2009) $
19 // File revision : $Revision: 4 $
20 //
21 // $Id: FIFOSampleBuffer.cpp 68 2009-02-27 17:24:42Z 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 <stdlib.h>
47 #include <memory.h>
48 #include <string.h>
49 #include <assert.h>
50 #include <stdexcept>
51
52 #include "FIFOSampleBuffer.h"
53
54 using namespace soundtouch;
55
56 // Constructor
57 FIFOSampleBuffer::FIFOSampleBuffer(int numChannels)
58 {
59 assert(numChannels > 0);
60 sizeInBytes = 0; // reasonable initial value
61 buffer = NULL;
62 bufferUnaligned = NULL;
63 samplesInBuffer = 0;
64 bufferPos = 0;
65 channels = (uint)numChannels;
66 ensureCapacity(32); // allocate initial capacity
67 }
68
69
70 // destructor
71 FIFOSampleBuffer::~FIFOSampleBuffer()
72 {
73 delete[] bufferUnaligned;
74 bufferUnaligned = NULL;
75 buffer = NULL;
76 }
77
78
79 // Sets number of channels, 1 = mono, 2 = stereo
80 void FIFOSampleBuffer::setChannels(int numChannels)
81 {
82 uint usedBytes;
83
84 assert(numChannels > 0);
85 usedBytes = channels * samplesInBuffer;
86 channels = (uint)numChannels;
87 samplesInBuffer = usedBytes / channels;
88 }
89
90
91 // if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and
92 // zeroes this pointer by copying samples from the 'bufferPos' pointer
93 // location on to the beginning of the buffer.
94 void FIFOSampleBuffer::rewind()
95 {
96 if (buffer && bufferPos)
97 {
98 memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer);
99 bufferPos = 0;
100 }
101 }
102
103
104 // Adds 'numSamples' pcs of samples from the 'samples' memory position to
105 // the sample buffer.
106 void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint nSamples)
107 {
108 memcpy(ptrEnd(nSamples), samples, sizeof(SAMPLETYPE) * nSamples * channels);
109 samplesInBuffer += nSamples;
110 }
111
112
113 // Increases the number of samples in the buffer without copying any actual
114 // samples.
115 //
116 // This function is used to update the number of samples in the sample buffer
117 // when accessing the buffer directly with 'ptrEnd' function. Please be
118 // careful though!
119 void FIFOSampleBuffer::putSamples(uint nSamples)
120 {
121 uint req;
122
123 req = samplesInBuffer + nSamples;
124 ensureCapacity(req);
125 samplesInBuffer += nSamples;
126 }
127
128
129 // Returns a pointer to the end of the used part of the sample buffer (i.e.
130 // where the new samples are to be inserted). This function may be used for
131 // inserting new samples into the sample buffer directly. Please be careful!
132 //
133 // Parameter 'slackCapacity' tells the function how much free capacity (in
134 // terms of samples) there _at least_ should be, in order to the caller to
135 // succesfully insert all the required samples to the buffer. When necessary,
136 // the function grows the buffer size to comply with this requirement.
137 //
138 // When using this function as means for inserting new samples, also remember
139 // to increase the sample count afterwards, by calling the
140 // 'putSamples(numSamples)' function.
141 SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity)
142 {
143 ensureCapacity(samplesInBuffer + slackCapacity);
144 return buffer + samplesInBuffer * channels;
145 }
146
147
148 // Returns a pointer to the beginning of the currently non-outputted samples.
149 // This function is provided for accessing the output samples directly.
150 // Please be careful!
151 //
152 // When using this function to output samples, also remember to 'remove' the
153 // outputted samples from the buffer by calling the
154 // 'receiveSamples(numSamples)' function
155 SAMPLETYPE *FIFOSampleBuffer::ptrBegin()
156 {
157 assert(buffer);
158 return buffer + bufferPos * channels;
159 }
160
161
162 // Ensures that the buffer has enought capacity, i.e. space for _at least_
163 // 'capacityRequirement' number of samples. The buffer is grown in steps of
164 // 4 kilobytes to eliminate the need for frequently growing up the buffer,
165 // as well as to round the buffer size up to the virtual memory page size.
166 void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
167 {
168 SAMPLETYPE *tempUnaligned, *temp;
169
170 if (capacityRequirement > getCapacity())
171 {
172 // enlarge the buffer in 4kbyte steps (round up to next 4k boundary)
173 sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint)-4096;
174 assert(sizeInBytes % 2 == 0);
175 tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
176 if (tempUnaligned == NULL)
177 {
178 throw std::runtime_error("Couldn't allocate memory!\n");
179 }
180 // Align the buffer to begin at 16byte cache line boundary for optimal performance
181 temp = (SAMPLETYPE *)(((ulong)tempUnaligned + 15) & (ulong)-16);
182 if (samplesInBuffer)
183 {
184 memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE));
185 }
186 delete[] bufferUnaligned;
187 buffer = temp;
188 bufferUnaligned = tempUnaligned;
189 bufferPos = 0;
190 }
191 else
192 {
193 // simply rewind the buffer (if necessary)
194 rewind();
195 }
196 }
197
198
199 // Returns the current buffer capacity in terms of samples
200 uint FIFOSampleBuffer::getCapacity() const
201 {
202 return sizeInBytes / (channels * sizeof(SAMPLETYPE));
203 }
204
205
206 // Returns the number of samples currently in the buffer
207 uint FIFOSampleBuffer::numSamples() const
208 {
209 return samplesInBuffer;
210 }
211
212
213 // Output samples from beginning of the sample buffer. Copies demanded number
214 // of samples to output and removes them from the sample buffer. If there
215 // are less than 'numsample' samples in the buffer, returns all available.
216 //
217 // Returns number of samples copied.
218 uint FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint maxSamples)
219 {
220 uint num;
221
222 num = (maxSamples > samplesInBuffer) ? samplesInBuffer : maxSamples;
223
224 memcpy(output, ptrBegin(), channels * sizeof(SAMPLETYPE) * num);
225 return receiveSamples(num);
226 }
227
228
229 // Removes samples from the beginning of the sample buffer without copying them
230 // anywhere. Used to reduce the number of samples in the buffer, when accessing
231 // the sample buffer with the 'ptrBegin' function.
232 uint FIFOSampleBuffer::receiveSamples(uint maxSamples)
233 {
234 if (maxSamples >= samplesInBuffer)
235 {
236 uint temp;
237
238 temp = samplesInBuffer;
239 samplesInBuffer = 0;
240 return temp;
241 }
242
243 samplesInBuffer -= maxSamples;
244 bufferPos += maxSamples;
245
246 return maxSamples;
247 }
248
249
250 // Returns nonzero if the sample buffer is empty
251 int FIFOSampleBuffer::isEmpty() const
252 {
253 return (samplesInBuffer == 0) ? 1 : 0;
254 }
255
256
257 // Clears the sample buffer
258 void FIFOSampleBuffer::clear()
259 {
260 samplesInBuffer = 0;
261 bufferPos = 0;
262 }

  ViewVC Help
Powered by ViewVC 1.1.22