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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (hide annotations) (download)
Mon Sep 6 11:19:43 2010 UTC (9 years, 5 months ago) by william
File size: 8543 byte(s)
Exported ./upsream/trunk @r3730 from http://pcsx2.googlecode.com/svn/trunk/
1 william 8 ////////////////////////////////////////////////////////////////////////////////
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