tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

InterpolateShannon.cpp (5461B)


      1 ////////////////////////////////////////////////////////////////////////////////
      2 /// 
      3 /// Sample interpolation routine using 8-tap band-limited Shannon interpolation 
      4 /// with kaiser window.
      5 ///
      6 /// Notice. This algorithm is remarkably much heavier than linear or cubic
      7 /// interpolation, and not remarkably better than cubic algorithm. Thus mostly
      8 /// for experimental purposes
      9 ///
     10 /// Author        : Copyright (c) Olli Parviainen
     11 /// Author e-mail : oparviai 'at' iki.fi
     12 /// SoundTouch WWW: http://www.surina.net/soundtouch
     13 ///
     14 ////////////////////////////////////////////////////////////////////////////////
     15 //
     16 // License :
     17 //
     18 //  SoundTouch audio processing library
     19 //  Copyright (c) Olli Parviainen
     20 //
     21 //  This library is free software; you can redistribute it and/or
     22 //  modify it under the terms of the GNU Lesser General Public
     23 //  License as published by the Free Software Foundation; either
     24 //  version 2.1 of the License, or (at your option) any later version.
     25 //
     26 //  This library is distributed in the hope that it will be useful,
     27 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
     28 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     29 //  Lesser General Public License for more details.
     30 //
     31 //  You should have received a copy of the GNU Lesser General Public
     32 //  License along with this library; if not, write to the Free Software
     33 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     34 //
     35 ////////////////////////////////////////////////////////////////////////////////
     36 
     37 #include <math.h>
     38 #include "InterpolateShannon.h"
     39 #include "STTypes.h"
     40 
     41 using namespace soundtouch;
     42 
     43 
     44 /// Kaiser window with beta = 2.0
     45 /// Values scaled down by 5% to avoid overflows
     46 static const double _kaiser8[8] = 
     47 {
     48   0.41778693317814,
     49   0.64888025049173,
     50   0.83508562409944,
     51   0.93887857733412,
     52   0.93887857733412,
     53   0.83508562409944,
     54   0.64888025049173,
     55   0.41778693317814
     56 };
     57 
     58 
     59 InterpolateShannon::InterpolateShannon()
     60 {
     61    fract = 0;
     62 }
     63 
     64 
     65 void InterpolateShannon::resetRegisters()
     66 {
     67    fract = 0;
     68 }
     69 
     70 
     71 #define PI 3.1415926536
     72 #define sinc(x) (sin(PI * (x)) / (PI * (x)))
     73 
     74 /// Transpose mono audio. Returns number of produced output samples, and 
     75 /// updates "srcSamples" to amount of consumed source samples
     76 int InterpolateShannon::transposeMono(SAMPLETYPE *pdest, 
     77                    const SAMPLETYPE *psrc, 
     78                    int &srcSamples)
     79 {
     80    int i;
     81    int srcSampleEnd = srcSamples - 8;
     82    int srcCount = 0;
     83 
     84    i = 0;
     85    while (srcCount < srcSampleEnd)
     86    {
     87        double out;
     88        assert(fract < 1.0);
     89 
     90        out  = psrc[0] * sinc(-3.0 - fract) * _kaiser8[0];
     91        out += psrc[1] * sinc(-2.0 - fract) * _kaiser8[1];
     92        out += psrc[2] * sinc(-1.0 - fract) * _kaiser8[2];
     93        if (fract < 1e-6)
     94        {
     95            out += psrc[3] * _kaiser8[3];     // sinc(0) = 1
     96        }
     97        else
     98        {
     99            out += psrc[3] * sinc(- fract) * _kaiser8[3];
    100        }
    101        out += psrc[4] * sinc( 1.0 - fract) * _kaiser8[4];
    102        out += psrc[5] * sinc( 2.0 - fract) * _kaiser8[5];
    103        out += psrc[6] * sinc( 3.0 - fract) * _kaiser8[6];
    104        out += psrc[7] * sinc( 4.0 - fract) * _kaiser8[7];
    105 
    106        pdest[i] = (SAMPLETYPE)out;
    107        i ++;
    108 
    109        // update position fraction
    110        fract += rate;
    111        // update whole positions
    112        int whole = (int)fract;
    113        fract -= whole;
    114        psrc += whole;
    115        srcCount += whole;
    116    }
    117    srcSamples = srcCount;
    118    return i;
    119 }
    120 
    121 
    122 /// Transpose stereo audio. Returns number of produced output samples, and 
    123 /// updates "srcSamples" to amount of consumed source samples
    124 int InterpolateShannon::transposeStereo(SAMPLETYPE *pdest, 
    125                    const SAMPLETYPE *psrc, 
    126                    int &srcSamples)
    127 {
    128    int i;
    129    int srcSampleEnd = srcSamples - 8;
    130    int srcCount = 0;
    131 
    132    i = 0;
    133    while (srcCount < srcSampleEnd)
    134    {
    135        double out0, out1, w;
    136        assert(fract < 1.0);
    137 
    138        w = sinc(-3.0 - fract) * _kaiser8[0];
    139        out0 = psrc[0] * w; out1 = psrc[1] * w;
    140        w = sinc(-2.0 - fract) * _kaiser8[1];
    141        out0 += psrc[2] * w; out1 += psrc[3] * w;
    142        w = sinc(-1.0 - fract) * _kaiser8[2];
    143        out0 += psrc[4] * w; out1 += psrc[5] * w;
    144        w = _kaiser8[3] * ((fract < 1e-5) ? 1.0 : sinc(- fract));   // sinc(0) = 1
    145        out0 += psrc[6] * w; out1 += psrc[7] * w;
    146        w = sinc( 1.0 - fract) * _kaiser8[4];
    147        out0 += psrc[8] * w; out1 += psrc[9] * w;
    148        w = sinc( 2.0 - fract) * _kaiser8[5];
    149        out0 += psrc[10] * w; out1 += psrc[11] * w;
    150        w = sinc( 3.0 - fract) * _kaiser8[6];
    151        out0 += psrc[12] * w; out1 += psrc[13] * w;
    152        w = sinc( 4.0 - fract) * _kaiser8[7];
    153        out0 += psrc[14] * w; out1 += psrc[15] * w;
    154 
    155        pdest[2*i]   = (SAMPLETYPE)out0;
    156        pdest[2*i+1] = (SAMPLETYPE)out1;
    157        i ++;
    158 
    159        // update position fraction
    160        fract += rate;
    161        // update whole positions
    162        int whole = (int)fract;
    163        fract -= whole;
    164        psrc += 2*whole;
    165        srcCount += whole;
    166    }
    167    srcSamples = srcCount;
    168    return i;
    169 }
    170 
    171 
    172 /// Transpose stereo audio. Returns number of produced output samples, and 
    173 /// updates "srcSamples" to amount of consumed source samples
    174 int InterpolateShannon::transposeMulti(SAMPLETYPE *pdest, 
    175                    const SAMPLETYPE *psrc, 
    176                    int &srcSamples)
    177 {
    178    // not implemented
    179    assert(false);
    180    return 0;
    181 }