LCOV - code coverage report
Current view: top level - media/libsoundtouch/src - RateTransposer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 90 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 20 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 15:57:21 +0000 (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             : ////////////////////////////////////////////////////////////////////////////////
      40             : 
      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"
      50             : 
      51             : using namespace soundtouch;
      52             : 
      53             : // Define default interpolation algorithm here
      54             : TransposerBase::ALGORITHM TransposerBase::algorithm = TransposerBase::CUBIC;
      55             : 
      56             : 
      57             : // Constructor
      58           0 : RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
      59             : {
      60           0 :     bUseAAFilter = true;
      61             : 
      62             :     // Instantiates the anti-alias filter
      63           0 :     pAAFilter = new AAFilter(64);
      64           0 :     pTransposer = TransposerBase::newInstance();
      65           0 : }
      66             : 
      67             : 
      68             : 
      69           0 : RateTransposer::~RateTransposer()
      70             : {
      71           0 :     delete pAAFilter;
      72           0 :     delete pTransposer;
      73           0 : }
      74             : 
      75             : 
      76             : 
      77             : /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
      78           0 : void RateTransposer::enableAAFilter(bool newMode)
      79             : {
      80           0 :     bUseAAFilter = newMode;
      81           0 : }
      82             : 
      83             : 
      84             : /// Returns nonzero if anti-alias filter is enabled.
      85           0 : bool RateTransposer::isAAFilterEnabled() const
      86             : {
      87           0 :     return bUseAAFilter;
      88             : }
      89             : 
      90             : 
      91           0 : AAFilter *RateTransposer::getAAFilter()
      92             : {
      93           0 :     return pAAFilter;
      94             : }
      95             : 
      96             : 
      97             : 
      98             : // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
      99             : // iRate, larger faster iRates.
     100           0 : void RateTransposer::setRate(float newRate)
     101             : {
     102             :     double fCutoff;
     103             : 
     104           0 :     pTransposer->setRate(newRate);
     105             : 
     106             :     // design a new anti-alias filter
     107           0 :     if (newRate > 1.0f) 
     108             :     {
     109           0 :         fCutoff = 0.5f / newRate;
     110             :     } 
     111             :     else 
     112             :     {
     113           0 :         fCutoff = 0.5f * newRate;
     114             :     }
     115           0 :     pAAFilter->setCutoffFreq(fCutoff);
     116           0 : }
     117             : 
     118             : 
     119             : // Adds 'nSamples' pcs of samples from the 'samples' memory position into
     120             : // the input of the object.
     121           0 : void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
     122             : {
     123           0 :     processSamples(samples, nSamples);
     124           0 : }
     125             : 
     126             : 
     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           0 : void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
     132             : {
     133             :     uint count;
     134             : 
     135           0 :     if (nSamples == 0) return;
     136             : 
     137             :     // Store samples to input buffer
     138           0 :     inputBuffer.putSamples(src, nSamples);
     139             : 
     140             :     // If anti-alias filter is turned off, simply transpose without applying
     141             :     // the filter
     142           0 :     if (bUseAAFilter == false) 
     143             :     {
     144           0 :         count = pTransposer->transpose(outputBuffer, inputBuffer);
     145           0 :         return;
     146             :     }
     147             : 
     148           0 :     assert(pAAFilter);
     149             : 
     150             :     // Transpose with anti-alias filter
     151           0 :     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.
     155             : 
     156             :         // Transpose the samples, store the result to end of "midBuffer"
     157           0 :         pTransposer->transpose(midBuffer, inputBuffer);
     158             : 
     159             :         // Apply the anti-alias filter for transposed samples in midBuffer
     160           0 :         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.
     167             : 
     168             :         // Apply the anti-alias filter for samples in inputBuffer
     169           0 :         pAAFilter->evaluate(midBuffer, inputBuffer);
     170             : 
     171             :         // Transpose the AA-filtered samples in "midBuffer"
     172           0 :         pTransposer->transpose(outputBuffer, midBuffer);
     173             :     }
     174             : }
     175             : 
     176             : 
     177             : // Sets the number of channels, 1 = mono, 2 = stereo
     178           0 : void RateTransposer::setChannels(int nChannels)
     179             : {
     180           0 :     assert(nChannels > 0);
     181             : 
     182           0 :     if (pTransposer->numChannels == nChannels) return;
     183           0 :     pTransposer->setChannels(nChannels);
     184             : 
     185           0 :     inputBuffer.setChannels(nChannels);
     186           0 :     midBuffer.setChannels(nChannels);
     187           0 :     outputBuffer.setChannels(nChannels);
     188             : }
     189             : 
     190             : 
     191             : // Clears all the samples in the object
     192           0 : void RateTransposer::clear()
     193             : {
     194           0 :     outputBuffer.clear();
     195           0 :     midBuffer.clear();
     196           0 :     inputBuffer.clear();
     197           0 : }
     198             : 
     199             : 
     200             : // Returns nonzero if there aren't any samples available for outputting.
     201           0 : int RateTransposer::isEmpty() const
     202             : {
     203             :     int res;
     204             : 
     205           0 :     res = FIFOProcessor::isEmpty();
     206           0 :     if (res == 0) return 0;
     207           0 :     return inputBuffer.isEmpty();
     208             : }
     209             : 
     210             : 
     211             : //////////////////////////////////////////////////////////////////////////////
     212             : //
     213             : // TransposerBase - Base class for interpolation
     214             : // 
     215             : 
     216             : // static function to set interpolation algorithm
     217           0 : void TransposerBase::setAlgorithm(TransposerBase::ALGORITHM a)
     218             : {
     219           0 :     TransposerBase::algorithm = a;
     220           0 : }
     221             : 
     222             : 
     223             : // Transposes the sample rate of the given samples using linear interpolation. 
     224             : // Returns the number of samples returned in the "dest" buffer
     225           0 : int TransposerBase::transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src)
     226             : {
     227           0 :     int numSrcSamples = src.numSamples();
     228           0 :     int sizeDemand = (int)((float)numSrcSamples / rate) + 8;
     229             :     int numOutput;
     230           0 :     SAMPLETYPE *psrc = src.ptrBegin();
     231           0 :     SAMPLETYPE *pdest = dest.ptrEnd(sizeDemand);
     232             : 
     233             : #ifndef USE_MULTICH_ALWAYS
     234           0 :     if (numChannels == 1)
     235             :     {
     236           0 :         numOutput = transposeMono(pdest, psrc, numSrcSamples);
     237             :     }
     238           0 :     else if (numChannels == 2) 
     239             :     {
     240           0 :         numOutput = transposeStereo(pdest, psrc, numSrcSamples);
     241             :     } 
     242             :     else 
     243             : #endif // USE_MULTICH_ALWAYS
     244             :     {
     245           0 :         assert(numChannels > 0);
     246           0 :         numOutput = transposeMulti(pdest, psrc, numSrcSamples);
     247             :     }
     248           0 :     dest.putSamples(numOutput);
     249           0 :     src.receiveSamples(numSrcSamples);
     250           0 :     return numOutput;
     251             : }
     252             : 
     253             : 
     254           0 : TransposerBase::TransposerBase()
     255             : {
     256           0 :     numChannels = 0;
     257           0 :     rate = 1.0f;
     258           0 : }
     259             : 
     260             : 
     261           0 : TransposerBase::~TransposerBase()
     262             : {
     263           0 : }
     264             : 
     265             : 
     266           0 : void TransposerBase::setChannels(int channels)
     267             : {
     268           0 :     numChannels = channels;
     269           0 :     resetRegisters();
     270           0 : }
     271             : 
     272             : 
     273           0 : void TransposerBase::setRate(float newRate)
     274             : {
     275           0 :     rate = newRate;
     276           0 : }
     277             : 
     278             : 
     279             : // static factory function
     280           0 : 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           0 :     switch (algorithm)
     287             :     {
     288             :         case LINEAR:
     289           0 :             return new InterpolateLinearFloat;
     290             : 
     291             :         case CUBIC:
     292           0 :             return new InterpolateCubic;
     293             : 
     294             :         case SHANNON:
     295           0 :             return new InterpolateShannon;
     296             : 
     297             :         default:
     298           0 :             assert(false);
     299             :             return NULL;
     300             :     }
     301             : #endif
     302             : }

Generated by: LCOV version 1.13