media/libsoundtouch/src/RateTransposer.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

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 }

mercurial