media/libsoundtouch/src/InterpolateShannon.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 // $Id: InterpolateShannon.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 <math.h>
    42 #include "InterpolateShannon.h"
    43 #include "STTypes.h"
    45 using namespace soundtouch;
    48 /// Kaiser window with beta = 2.0
    49 /// Values scaled down by 5% to avoid overflows
    50 static const double _kaiser8[8] = 
    51 {
    52    0.41778693317814,
    53    0.64888025049173,
    54    0.83508562409944,
    55    0.93887857733412,
    56    0.93887857733412,
    57    0.83508562409944,
    58    0.64888025049173,
    59    0.41778693317814
    60 };
    63 InterpolateShannon::InterpolateShannon()
    64 {
    65     fract = 0;
    66 }
    69 void InterpolateShannon::resetRegisters()
    70 {
    71     fract = 0;
    72 }
    75 #define PI 3.1415926536
    76 #define sinc(x) (sin(PI * (x)) / (PI * (x)))
    78 /// Transpose mono audio. Returns number of produced output samples, and 
    79 /// updates "srcSamples" to amount of consumed source samples
    80 int InterpolateShannon::transposeMono(SAMPLETYPE *pdest, 
    81                     const SAMPLETYPE *psrc, 
    82                     int &srcSamples)
    83 {
    84     int i;
    85     int srcSampleEnd = srcSamples - 8;
    86     int srcCount = 0;
    88     i = 0;
    89     while (srcCount < srcSampleEnd)
    90     {
    91         double out;
    92         assert(fract < 1.0);
    94         out  = psrc[0] * sinc(-3.0 - fract) * _kaiser8[0];
    95         out += psrc[1] * sinc(-2.0 - fract) * _kaiser8[1];
    96         out += psrc[2] * sinc(-1.0 - fract) * _kaiser8[2];
    97         if (fract < 1e-6)
    98         {
    99             out += psrc[3] * _kaiser8[3];     // sinc(0) = 1
   100         }
   101         else
   102         {
   103             out += psrc[3] * sinc(- fract) * _kaiser8[3];
   104         }
   105         out += psrc[4] * sinc( 1.0 - fract) * _kaiser8[4];
   106         out += psrc[5] * sinc( 2.0 - fract) * _kaiser8[5];
   107         out += psrc[6] * sinc( 3.0 - fract) * _kaiser8[6];
   108         out += psrc[7] * sinc( 4.0 - fract) * _kaiser8[7];
   110         pdest[i] = (SAMPLETYPE)out;
   111         i ++;
   113         // update position fraction
   114         fract += rate;
   115         // update whole positions
   116         int whole = (int)fract;
   117         fract -= whole;
   118         psrc += whole;
   119         srcCount += whole;
   120     }
   121     srcSamples = srcCount;
   122     return i;
   123 }
   126 /// Transpose stereo audio. Returns number of produced output samples, and 
   127 /// updates "srcSamples" to amount of consumed source samples
   128 int InterpolateShannon::transposeStereo(SAMPLETYPE *pdest, 
   129                     const SAMPLETYPE *psrc, 
   130                     int &srcSamples)
   131 {
   132     int i;
   133     int srcSampleEnd = srcSamples - 8;
   134     int srcCount = 0;
   136     i = 0;
   137     while (srcCount < srcSampleEnd)
   138     {
   139         double out0, out1, w;
   140         assert(fract < 1.0);
   142         w = sinc(-3.0 - fract) * _kaiser8[0];
   143         out0 = psrc[0] * w; out1 = psrc[1] * w;
   144         w = sinc(-2.0 - fract) * _kaiser8[1];
   145         out0 += psrc[2] * w; out1 += psrc[3] * w;
   146         w = sinc(-1.0 - fract) * _kaiser8[2];
   147         out0 += psrc[4] * w; out1 += psrc[5] * w;
   148         w = _kaiser8[3] * ((fract < 1e-5) ? 1.0 : sinc(- fract));   // sinc(0) = 1
   149         out0 += psrc[6] * w; out1 += psrc[7] * w;
   150         w = sinc( 1.0 - fract) * _kaiser8[4];
   151         out0 += psrc[8] * w; out1 += psrc[9] * w;
   152         w = sinc( 2.0 - fract) * _kaiser8[5];
   153         out0 += psrc[10] * w; out1 += psrc[11] * w;
   154         w = sinc( 3.0 - fract) * _kaiser8[6];
   155         out0 += psrc[12] * w; out1 += psrc[13] * w;
   156         w = sinc( 4.0 - fract) * _kaiser8[7];
   157         out0 += psrc[14] * w; out1 += psrc[15] * w;
   159         pdest[2*i]   = (SAMPLETYPE)out0;
   160         pdest[2*i+1] = (SAMPLETYPE)out1;
   161         i ++;
   163         // update position fraction
   164         fract += rate;
   165         // update whole positions
   166         int whole = (int)fract;
   167         fract -= whole;
   168         psrc += 2*whole;
   169         srcCount += whole;
   170     }
   171     srcSamples = srcCount;
   172     return i;
   173 }
   176 /// Transpose stereo audio. Returns number of produced output samples, and 
   177 /// updates "srcSamples" to amount of consumed source samples
   178 int InterpolateShannon::transposeMulti(SAMPLETYPE *pdest, 
   179                     const SAMPLETYPE *psrc, 
   180                     int &srcSamples)
   181 {
   182     // not implemented
   183     assert(false);
   184     return 0;
   185 }

mercurial