Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 ////////////////////////////////////////////////////////////////////////////////
2 ///
3 /// Sample rate transposer. Changes sample rate by using linear interpolation
4 /// together with anti-alias filtering (first order interpolation with anti-
5 /// alias filtering should be quite adequate for this application)
6 ///
7 /// Author : Copyright (c) Olli Parviainen
8 /// Author e-mail : oparviai 'at' iki.fi
9 /// SoundTouch WWW: http://www.surina.net/soundtouch
10 ///
11 ////////////////////////////////////////////////////////////////////////////////
12 //
13 // Last changed : $Date: 2014-04-06 10:57:21 -0500 (Sun, 06 Apr 2014) $
14 // File revision : $Revision: 4 $
15 //
16 // $Id: RateTransposer.cpp 195 2014-04-06 15:57:21Z oparviai $
17 //
18 ////////////////////////////////////////////////////////////////////////////////
19 //
20 // License :
21 //
22 // SoundTouch audio processing library
23 // Copyright (c) Olli Parviainen
24 //
25 // This library is free software; you can redistribute it and/or
26 // modify it under the terms of the GNU Lesser General Public
27 // License as published by the Free Software Foundation; either
28 // version 2.1 of the License, or (at your option) any later version.
29 //
30 // This library is distributed in the hope that it will be useful,
31 // but WITHOUT ANY WARRANTY; without even the implied warranty of
32 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33 // Lesser General Public License for more details.
34 //
35 // You should have received a copy of the GNU Lesser General Public
36 // License along with this library; if not, write to the Free Software
37 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 //
39 ////////////////////////////////////////////////////////////////////////////////
41 #include <memory.h>
42 #include <assert.h>
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include "RateTransposer.h"
46 #include "InterpolateLinear.h"
47 #include "InterpolateCubic.h"
48 #include "InterpolateShannon.h"
49 #include "AAFilter.h"
51 using namespace soundtouch;
53 // Define default interpolation algorithm here
54 TransposerBase::ALGORITHM TransposerBase::algorithm = TransposerBase::CUBIC;
57 // Constructor
58 RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
59 {
60 bUseAAFilter = true;
62 // Instantiates the anti-alias filter
63 pAAFilter = new AAFilter(64);
64 pTransposer = TransposerBase::newInstance();
65 }
69 RateTransposer::~RateTransposer()
70 {
71 delete pAAFilter;
72 delete pTransposer;
73 }
77 /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
78 void RateTransposer::enableAAFilter(bool newMode)
79 {
80 bUseAAFilter = newMode;
81 }
84 /// Returns nonzero if anti-alias filter is enabled.
85 bool RateTransposer::isAAFilterEnabled() const
86 {
87 return bUseAAFilter;
88 }
91 AAFilter *RateTransposer::getAAFilter()
92 {
93 return pAAFilter;
94 }
98 // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
99 // iRate, larger faster iRates.
100 void RateTransposer::setRate(float newRate)
101 {
102 double fCutoff;
104 pTransposer->setRate(newRate);
106 // design a new anti-alias filter
107 if (newRate > 1.0f)
108 {
109 fCutoff = 0.5f / newRate;
110 }
111 else
112 {
113 fCutoff = 0.5f * newRate;
114 }
115 pAAFilter->setCutoffFreq(fCutoff);
116 }
119 // Adds 'nSamples' pcs of samples from the 'samples' memory position into
120 // the input of the object.
121 void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
122 {
123 processSamples(samples, nSamples);
124 }
127 // Transposes sample rate by applying anti-alias filter to prevent folding.
128 // Returns amount of samples returned in the "dest" buffer.
129 // The maximum amount of samples that can be returned at a time is set by
130 // the 'set_returnBuffer_size' function.
131 void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
132 {
133 uint count;
135 if (nSamples == 0) return;
137 // Store samples to input buffer
138 inputBuffer.putSamples(src, nSamples);
140 // If anti-alias filter is turned off, simply transpose without applying
141 // the filter
142 if (bUseAAFilter == false)
143 {
144 count = pTransposer->transpose(outputBuffer, inputBuffer);
145 return;
146 }
148 assert(pAAFilter);
150 // Transpose with anti-alias filter
151 if (pTransposer->rate < 1.0f)
152 {
153 // If the parameter 'Rate' value is smaller than 1, first transpose
154 // the samples and then apply the anti-alias filter to remove aliasing.
156 // Transpose the samples, store the result to end of "midBuffer"
157 pTransposer->transpose(midBuffer, inputBuffer);
159 // Apply the anti-alias filter for transposed samples in midBuffer
160 pAAFilter->evaluate(outputBuffer, midBuffer);
161 }
162 else
163 {
164 // If the parameter 'Rate' value is larger than 1, first apply the
165 // anti-alias filter to remove high frequencies (prevent them from folding
166 // over the lover frequencies), then transpose.
168 // Apply the anti-alias filter for samples in inputBuffer
169 pAAFilter->evaluate(midBuffer, inputBuffer);
171 // Transpose the AA-filtered samples in "midBuffer"
172 pTransposer->transpose(outputBuffer, midBuffer);
173 }
174 }
177 // Sets the number of channels, 1 = mono, 2 = stereo
178 void RateTransposer::setChannels(int nChannels)
179 {
180 assert(nChannels > 0);
182 if (pTransposer->numChannels == nChannels) return;
183 pTransposer->setChannels(nChannels);
185 inputBuffer.setChannels(nChannels);
186 midBuffer.setChannels(nChannels);
187 outputBuffer.setChannels(nChannels);
188 }
191 // Clears all the samples in the object
192 void RateTransposer::clear()
193 {
194 outputBuffer.clear();
195 midBuffer.clear();
196 inputBuffer.clear();
197 }
200 // Returns nonzero if there aren't any samples available for outputting.
201 int RateTransposer::isEmpty() const
202 {
203 int res;
205 res = FIFOProcessor::isEmpty();
206 if (res == 0) return 0;
207 return inputBuffer.isEmpty();
208 }
211 //////////////////////////////////////////////////////////////////////////////
212 //
213 // TransposerBase - Base class for interpolation
214 //
216 // static function to set interpolation algorithm
217 void TransposerBase::setAlgorithm(TransposerBase::ALGORITHM a)
218 {
219 TransposerBase::algorithm = a;
220 }
223 // Transposes the sample rate of the given samples using linear interpolation.
224 // Returns the number of samples returned in the "dest" buffer
225 int TransposerBase::transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src)
226 {
227 int numSrcSamples = src.numSamples();
228 int sizeDemand = (int)((float)numSrcSamples / rate) + 8;
229 int numOutput;
230 SAMPLETYPE *psrc = src.ptrBegin();
231 SAMPLETYPE *pdest = dest.ptrEnd(sizeDemand);
233 #ifndef USE_MULTICH_ALWAYS
234 if (numChannels == 1)
235 {
236 numOutput = transposeMono(pdest, psrc, numSrcSamples);
237 }
238 else if (numChannels == 2)
239 {
240 numOutput = transposeStereo(pdest, psrc, numSrcSamples);
241 }
242 else
243 #endif // USE_MULTICH_ALWAYS
244 {
245 assert(numChannels > 0);
246 numOutput = transposeMulti(pdest, psrc, numSrcSamples);
247 }
248 dest.putSamples(numOutput);
249 src.receiveSamples(numSrcSamples);
250 return numOutput;
251 }
254 TransposerBase::TransposerBase()
255 {
256 numChannels = 0;
257 rate = 1.0f;
258 }
261 TransposerBase::~TransposerBase()
262 {
263 }
266 void TransposerBase::setChannels(int channels)
267 {
268 numChannels = channels;
269 resetRegisters();
270 }
273 void TransposerBase::setRate(float newRate)
274 {
275 rate = newRate;
276 }
279 // static factory function
280 TransposerBase *TransposerBase::newInstance()
281 {
282 #ifdef SOUNDTOUCH_INTEGER_SAMPLES
283 // Notice: For integer arithmetics support only linear algorithm (due to simplest calculus)
284 return ::new InterpolateLinearInteger;
285 #else
286 switch (algorithm)
287 {
288 case LINEAR:
289 return new InterpolateLinearFloat;
291 case CUBIC:
292 return new InterpolateCubic;
294 case SHANNON:
295 return new InterpolateShannon;
297 default:
298 assert(false);
299 return NULL;
300 }
301 #endif
302 }