media/libsoundtouch/src/RateTransposer.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libsoundtouch/src/RateTransposer.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,302 @@
     1.4 +////////////////////////////////////////////////////////////////////////////////
     1.5 +/// 
     1.6 +/// Sample rate transposer. Changes sample rate by using linear interpolation 
     1.7 +/// together with anti-alias filtering (first order interpolation with anti-
     1.8 +/// alias filtering should be quite adequate for this application)
     1.9 +///
    1.10 +/// Author        : Copyright (c) Olli Parviainen
    1.11 +/// Author e-mail : oparviai 'at' iki.fi
    1.12 +/// SoundTouch WWW: http://www.surina.net/soundtouch
    1.13 +///
    1.14 +////////////////////////////////////////////////////////////////////////////////
    1.15 +//
    1.16 +// Last changed  : $Date: 2014-04-06 10:57:21 -0500 (Sun, 06 Apr 2014) $
    1.17 +// File revision : $Revision: 4 $
    1.18 +//
    1.19 +// $Id: RateTransposer.cpp 195 2014-04-06 15:57:21Z oparviai $
    1.20 +//
    1.21 +////////////////////////////////////////////////////////////////////////////////
    1.22 +//
    1.23 +// License :
    1.24 +//
    1.25 +//  SoundTouch audio processing library
    1.26 +//  Copyright (c) Olli Parviainen
    1.27 +//
    1.28 +//  This library is free software; you can redistribute it and/or
    1.29 +//  modify it under the terms of the GNU Lesser General Public
    1.30 +//  License as published by the Free Software Foundation; either
    1.31 +//  version 2.1 of the License, or (at your option) any later version.
    1.32 +//
    1.33 +//  This library is distributed in the hope that it will be useful,
    1.34 +//  but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.35 +//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.36 +//  Lesser General Public License for more details.
    1.37 +//
    1.38 +//  You should have received a copy of the GNU Lesser General Public
    1.39 +//  License along with this library; if not, write to the Free Software
    1.40 +//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.41 +//
    1.42 +////////////////////////////////////////////////////////////////////////////////
    1.43 +
    1.44 +#include <memory.h>
    1.45 +#include <assert.h>
    1.46 +#include <stdlib.h>
    1.47 +#include <stdio.h>
    1.48 +#include "RateTransposer.h"
    1.49 +#include "InterpolateLinear.h"
    1.50 +#include "InterpolateCubic.h"
    1.51 +#include "InterpolateShannon.h"
    1.52 +#include "AAFilter.h"
    1.53 +
    1.54 +using namespace soundtouch;
    1.55 +
    1.56 +// Define default interpolation algorithm here
    1.57 +TransposerBase::ALGORITHM TransposerBase::algorithm = TransposerBase::CUBIC;
    1.58 +
    1.59 +
    1.60 +// Constructor
    1.61 +RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
    1.62 +{
    1.63 +    bUseAAFilter = true;
    1.64 +
    1.65 +    // Instantiates the anti-alias filter
    1.66 +    pAAFilter = new AAFilter(64);
    1.67 +    pTransposer = TransposerBase::newInstance();
    1.68 +}
    1.69 +
    1.70 +
    1.71 +
    1.72 +RateTransposer::~RateTransposer()
    1.73 +{
    1.74 +    delete pAAFilter;
    1.75 +    delete pTransposer;
    1.76 +}
    1.77 +
    1.78 +
    1.79 +
    1.80 +/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
    1.81 +void RateTransposer::enableAAFilter(bool newMode)
    1.82 +{
    1.83 +    bUseAAFilter = newMode;
    1.84 +}
    1.85 +
    1.86 +
    1.87 +/// Returns nonzero if anti-alias filter is enabled.
    1.88 +bool RateTransposer::isAAFilterEnabled() const
    1.89 +{
    1.90 +    return bUseAAFilter;
    1.91 +}
    1.92 +
    1.93 +
    1.94 +AAFilter *RateTransposer::getAAFilter()
    1.95 +{
    1.96 +    return pAAFilter;
    1.97 +}
    1.98 +
    1.99 +
   1.100 +
   1.101 +// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
   1.102 +// iRate, larger faster iRates.
   1.103 +void RateTransposer::setRate(float newRate)
   1.104 +{
   1.105 +    double fCutoff;
   1.106 +
   1.107 +    pTransposer->setRate(newRate);
   1.108 +
   1.109 +    // design a new anti-alias filter
   1.110 +    if (newRate > 1.0f) 
   1.111 +    {
   1.112 +        fCutoff = 0.5f / newRate;
   1.113 +    } 
   1.114 +    else 
   1.115 +    {
   1.116 +        fCutoff = 0.5f * newRate;
   1.117 +    }
   1.118 +    pAAFilter->setCutoffFreq(fCutoff);
   1.119 +}
   1.120 +
   1.121 +
   1.122 +// Adds 'nSamples' pcs of samples from the 'samples' memory position into
   1.123 +// the input of the object.
   1.124 +void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
   1.125 +{
   1.126 +    processSamples(samples, nSamples);
   1.127 +}
   1.128 +
   1.129 +
   1.130 +// Transposes sample rate by applying anti-alias filter to prevent folding. 
   1.131 +// Returns amount of samples returned in the "dest" buffer.
   1.132 +// The maximum amount of samples that can be returned at a time is set by
   1.133 +// the 'set_returnBuffer_size' function.
   1.134 +void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
   1.135 +{
   1.136 +    uint count;
   1.137 +
   1.138 +    if (nSamples == 0) return;
   1.139 +
   1.140 +    // Store samples to input buffer
   1.141 +    inputBuffer.putSamples(src, nSamples);
   1.142 +
   1.143 +    // If anti-alias filter is turned off, simply transpose without applying
   1.144 +    // the filter
   1.145 +    if (bUseAAFilter == false) 
   1.146 +    {
   1.147 +        count = pTransposer->transpose(outputBuffer, inputBuffer);
   1.148 +        return;
   1.149 +    }
   1.150 +
   1.151 +    assert(pAAFilter);
   1.152 +
   1.153 +    // Transpose with anti-alias filter
   1.154 +    if (pTransposer->rate < 1.0f) 
   1.155 +    {
   1.156 +        // If the parameter 'Rate' value is smaller than 1, first transpose
   1.157 +        // the samples and then apply the anti-alias filter to remove aliasing.
   1.158 +
   1.159 +        // Transpose the samples, store the result to end of "midBuffer"
   1.160 +        pTransposer->transpose(midBuffer, inputBuffer);
   1.161 +
   1.162 +        // Apply the anti-alias filter for transposed samples in midBuffer
   1.163 +        pAAFilter->evaluate(outputBuffer, midBuffer);
   1.164 +    } 
   1.165 +    else  
   1.166 +    {
   1.167 +        // If the parameter 'Rate' value is larger than 1, first apply the
   1.168 +        // anti-alias filter to remove high frequencies (prevent them from folding
   1.169 +        // over the lover frequencies), then transpose.
   1.170 +
   1.171 +        // Apply the anti-alias filter for samples in inputBuffer
   1.172 +        pAAFilter->evaluate(midBuffer, inputBuffer);
   1.173 +
   1.174 +        // Transpose the AA-filtered samples in "midBuffer"
   1.175 +        pTransposer->transpose(outputBuffer, midBuffer);
   1.176 +    }
   1.177 +}
   1.178 +
   1.179 +
   1.180 +// Sets the number of channels, 1 = mono, 2 = stereo
   1.181 +void RateTransposer::setChannels(int nChannels)
   1.182 +{
   1.183 +    assert(nChannels > 0);
   1.184 +
   1.185 +    if (pTransposer->numChannels == nChannels) return;
   1.186 +    pTransposer->setChannels(nChannels);
   1.187 +
   1.188 +    inputBuffer.setChannels(nChannels);
   1.189 +    midBuffer.setChannels(nChannels);
   1.190 +    outputBuffer.setChannels(nChannels);
   1.191 +}
   1.192 +
   1.193 +
   1.194 +// Clears all the samples in the object
   1.195 +void RateTransposer::clear()
   1.196 +{
   1.197 +    outputBuffer.clear();
   1.198 +    midBuffer.clear();
   1.199 +    inputBuffer.clear();
   1.200 +}
   1.201 +
   1.202 +
   1.203 +// Returns nonzero if there aren't any samples available for outputting.
   1.204 +int RateTransposer::isEmpty() const
   1.205 +{
   1.206 +    int res;
   1.207 +
   1.208 +    res = FIFOProcessor::isEmpty();
   1.209 +    if (res == 0) return 0;
   1.210 +    return inputBuffer.isEmpty();
   1.211 +}
   1.212 +
   1.213 +
   1.214 +//////////////////////////////////////////////////////////////////////////////
   1.215 +//
   1.216 +// TransposerBase - Base class for interpolation
   1.217 +// 
   1.218 +
   1.219 +// static function to set interpolation algorithm
   1.220 +void TransposerBase::setAlgorithm(TransposerBase::ALGORITHM a)
   1.221 +{
   1.222 +    TransposerBase::algorithm = a;
   1.223 +}
   1.224 +
   1.225 +
   1.226 +// Transposes the sample rate of the given samples using linear interpolation. 
   1.227 +// Returns the number of samples returned in the "dest" buffer
   1.228 +int TransposerBase::transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src)
   1.229 +{
   1.230 +    int numSrcSamples = src.numSamples();
   1.231 +    int sizeDemand = (int)((float)numSrcSamples / rate) + 8;
   1.232 +    int numOutput;
   1.233 +    SAMPLETYPE *psrc = src.ptrBegin();
   1.234 +    SAMPLETYPE *pdest = dest.ptrEnd(sizeDemand);
   1.235 +
   1.236 +#ifndef USE_MULTICH_ALWAYS
   1.237 +    if (numChannels == 1)
   1.238 +    {
   1.239 +        numOutput = transposeMono(pdest, psrc, numSrcSamples);
   1.240 +    }
   1.241 +    else if (numChannels == 2) 
   1.242 +    {
   1.243 +        numOutput = transposeStereo(pdest, psrc, numSrcSamples);
   1.244 +    } 
   1.245 +    else 
   1.246 +#endif // USE_MULTICH_ALWAYS
   1.247 +    {
   1.248 +        assert(numChannels > 0);
   1.249 +        numOutput = transposeMulti(pdest, psrc, numSrcSamples);
   1.250 +    }
   1.251 +    dest.putSamples(numOutput);
   1.252 +    src.receiveSamples(numSrcSamples);
   1.253 +    return numOutput;
   1.254 +}
   1.255 +
   1.256 +
   1.257 +TransposerBase::TransposerBase()
   1.258 +{
   1.259 +    numChannels = 0;
   1.260 +    rate = 1.0f;
   1.261 +}
   1.262 +
   1.263 +
   1.264 +TransposerBase::~TransposerBase()
   1.265 +{
   1.266 +}
   1.267 +
   1.268 +
   1.269 +void TransposerBase::setChannels(int channels)
   1.270 +{
   1.271 +    numChannels = channels;
   1.272 +    resetRegisters();
   1.273 +}
   1.274 +
   1.275 +
   1.276 +void TransposerBase::setRate(float newRate)
   1.277 +{
   1.278 +    rate = newRate;
   1.279 +}
   1.280 +
   1.281 +
   1.282 +// static factory function
   1.283 +TransposerBase *TransposerBase::newInstance()
   1.284 +{
   1.285 +#ifdef SOUNDTOUCH_INTEGER_SAMPLES
   1.286 +    // Notice: For integer arithmetics support only linear algorithm (due to simplest calculus)
   1.287 +    return ::new InterpolateLinearInteger;
   1.288 +#else
   1.289 +    switch (algorithm)
   1.290 +    {
   1.291 +        case LINEAR:
   1.292 +            return new InterpolateLinearFloat;
   1.293 +
   1.294 +        case CUBIC:
   1.295 +            return new InterpolateCubic;
   1.296 +
   1.297 +        case SHANNON:
   1.298 +            return new InterpolateShannon;
   1.299 +
   1.300 +        default:
   1.301 +            assert(false);
   1.302 +            return NULL;
   1.303 +    }
   1.304 +#endif
   1.305 +}

mercurial