media/libopus/silk/resampler.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libopus/silk/resampler.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,215 @@
     1.4 +/***********************************************************************
     1.5 +Copyright (c) 2006-2011, Skype Limited. All rights reserved.
     1.6 +Redistribution and use in source and binary forms, with or without
     1.7 +modification, are permitted provided that the following conditions
     1.8 +are met:
     1.9 +- Redistributions of source code must retain the above copyright notice,
    1.10 +this list of conditions and the following disclaimer.
    1.11 +- Redistributions in binary form must reproduce the above copyright
    1.12 +notice, this list of conditions and the following disclaimer in the
    1.13 +documentation and/or other materials provided with the distribution.
    1.14 +- Neither the name of Internet Society, IETF or IETF Trust, nor the
    1.15 +names of specific contributors, may be used to endorse or promote
    1.16 +products derived from this software without specific prior written
    1.17 +permission.
    1.18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    1.19 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.20 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.21 +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    1.22 +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    1.23 +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    1.24 +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    1.25 +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    1.26 +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.27 +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    1.28 +POSSIBILITY OF SUCH DAMAGE.
    1.29 +***********************************************************************/
    1.30 +
    1.31 +#ifdef HAVE_CONFIG_H
    1.32 +#include "config.h"
    1.33 +#endif
    1.34 +
    1.35 +/*
    1.36 + * Matrix of resampling methods used:
    1.37 + *                                 Fs_out (kHz)
    1.38 + *                        8      12     16     24     48
    1.39 + *
    1.40 + *               8        C      UF     U      UF     UF
    1.41 + *              12        AF     C      UF     U      UF
    1.42 + * Fs_in (kHz)  16        D      AF     C      UF     UF
    1.43 + *              24        AF     D      AF     C      U
    1.44 + *              48        AF     AF     AF     D      C
    1.45 + *
    1.46 + * C   -> Copy (no resampling)
    1.47 + * D   -> Allpass-based 2x downsampling
    1.48 + * U   -> Allpass-based 2x upsampling
    1.49 + * UF  -> Allpass-based 2x upsampling followed by FIR interpolation
    1.50 + * AF  -> AR2 filter followed by FIR interpolation
    1.51 + */
    1.52 +
    1.53 +#include "resampler_private.h"
    1.54 +
    1.55 +/* Tables with delay compensation values to equalize total delay for different modes */
    1.56 +static const opus_int8 delay_matrix_enc[ 5 ][ 3 ] = {
    1.57 +/* in  \ out  8  12  16 */
    1.58 +/*  8 */   {  6,  0,  3 },
    1.59 +/* 12 */   {  0,  7,  3 },
    1.60 +/* 16 */   {  0,  1, 10 },
    1.61 +/* 24 */   {  0,  2,  6 },
    1.62 +/* 48 */   { 18, 10, 12 }
    1.63 +};
    1.64 +
    1.65 +static const opus_int8 delay_matrix_dec[ 3 ][ 5 ] = {
    1.66 +/* in  \ out  8  12  16  24  48 */
    1.67 +/*  8 */   {  4,  0,  2,  0,  0 },
    1.68 +/* 12 */   {  0,  9,  4,  7,  4 },
    1.69 +/* 16 */   {  0,  3, 12,  7,  7 }
    1.70 +};
    1.71 +
    1.72 +/* Simple way to make [8000, 12000, 16000, 24000, 48000] to [0, 1, 2, 3, 4] */
    1.73 +#define rateID(R) ( ( ( ((R)>>12) - ((R)>16000) ) >> ((R)>24000) ) - 1 )
    1.74 +
    1.75 +#define USE_silk_resampler_copy                     (0)
    1.76 +#define USE_silk_resampler_private_up2_HQ_wrapper   (1)
    1.77 +#define USE_silk_resampler_private_IIR_FIR          (2)
    1.78 +#define USE_silk_resampler_private_down_FIR         (3)
    1.79 +
    1.80 +/* Initialize/reset the resampler state for a given pair of input/output sampling rates */
    1.81 +opus_int silk_resampler_init(
    1.82 +    silk_resampler_state_struct *S,                 /* I/O  Resampler state                                             */
    1.83 +    opus_int32                  Fs_Hz_in,           /* I    Input sampling rate (Hz)                                    */
    1.84 +    opus_int32                  Fs_Hz_out,          /* I    Output sampling rate (Hz)                                   */
    1.85 +    opus_int                    forEnc              /* I    If 1: encoder; if 0: decoder                                */
    1.86 +)
    1.87 +{
    1.88 +    opus_int up2x;
    1.89 +
    1.90 +    /* Clear state */
    1.91 +    silk_memset( S, 0, sizeof( silk_resampler_state_struct ) );
    1.92 +
    1.93 +    /* Input checking */
    1.94 +    if( forEnc ) {
    1.95 +        if( ( Fs_Hz_in  != 8000 && Fs_Hz_in  != 12000 && Fs_Hz_in  != 16000 && Fs_Hz_in  != 24000 && Fs_Hz_in  != 48000 ) ||
    1.96 +            ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) {
    1.97 +            silk_assert( 0 );
    1.98 +            return -1;
    1.99 +        }
   1.100 +        S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
   1.101 +    } else {
   1.102 +        if( ( Fs_Hz_in  != 8000 && Fs_Hz_in  != 12000 && Fs_Hz_in  != 16000 ) ||
   1.103 +            ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) {
   1.104 +            silk_assert( 0 );
   1.105 +            return -1;
   1.106 +        }
   1.107 +        S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
   1.108 +    }
   1.109 +
   1.110 +    S->Fs_in_kHz  = silk_DIV32_16( Fs_Hz_in,  1000 );
   1.111 +    S->Fs_out_kHz = silk_DIV32_16( Fs_Hz_out, 1000 );
   1.112 +
   1.113 +    /* Number of samples processed per batch */
   1.114 +    S->batchSize = S->Fs_in_kHz * RESAMPLER_MAX_BATCH_SIZE_MS;
   1.115 +
   1.116 +    /* Find resampler with the right sampling ratio */
   1.117 +    up2x = 0;
   1.118 +    if( Fs_Hz_out > Fs_Hz_in ) {
   1.119 +        /* Upsample */
   1.120 +        if( Fs_Hz_out == silk_MUL( Fs_Hz_in, 2 ) ) {                            /* Fs_out : Fs_in = 2 : 1 */
   1.121 +            /* Special case: directly use 2x upsampler */
   1.122 +            S->resampler_function = USE_silk_resampler_private_up2_HQ_wrapper;
   1.123 +        } else {
   1.124 +            /* Default resampler */
   1.125 +            S->resampler_function = USE_silk_resampler_private_IIR_FIR;
   1.126 +            up2x = 1;
   1.127 +        }
   1.128 +    } else if ( Fs_Hz_out < Fs_Hz_in ) {
   1.129 +        /* Downsample */
   1.130 +         S->resampler_function = USE_silk_resampler_private_down_FIR;
   1.131 +        if( silk_MUL( Fs_Hz_out, 4 ) == silk_MUL( Fs_Hz_in, 3 ) ) {             /* Fs_out : Fs_in = 3 : 4 */
   1.132 +            S->FIR_Fracs = 3;
   1.133 +            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0;
   1.134 +            S->Coefs = silk_Resampler_3_4_COEFS;
   1.135 +        } else if( silk_MUL( Fs_Hz_out, 3 ) == silk_MUL( Fs_Hz_in, 2 ) ) {      /* Fs_out : Fs_in = 2 : 3 */
   1.136 +            S->FIR_Fracs = 2;
   1.137 +            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0;
   1.138 +            S->Coefs = silk_Resampler_2_3_COEFS;
   1.139 +        } else if( silk_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) {                     /* Fs_out : Fs_in = 1 : 2 */
   1.140 +            S->FIR_Fracs = 1;
   1.141 +            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR1;
   1.142 +            S->Coefs = silk_Resampler_1_2_COEFS;
   1.143 +        } else if( silk_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) {                     /* Fs_out : Fs_in = 1 : 3 */
   1.144 +            S->FIR_Fracs = 1;
   1.145 +            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;
   1.146 +            S->Coefs = silk_Resampler_1_3_COEFS;
   1.147 +        } else if( silk_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) {                     /* Fs_out : Fs_in = 1 : 4 */
   1.148 +            S->FIR_Fracs = 1;
   1.149 +            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;
   1.150 +            S->Coefs = silk_Resampler_1_4_COEFS;
   1.151 +        } else if( silk_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) {                     /* Fs_out : Fs_in = 1 : 6 */
   1.152 +            S->FIR_Fracs = 1;
   1.153 +            S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;
   1.154 +            S->Coefs = silk_Resampler_1_6_COEFS;
   1.155 +        } else {
   1.156 +            /* None available */
   1.157 +            silk_assert( 0 );
   1.158 +            return -1;
   1.159 +        }
   1.160 +    } else {
   1.161 +        /* Input and output sampling rates are equal: copy */
   1.162 +        S->resampler_function = USE_silk_resampler_copy;
   1.163 +    }
   1.164 +
   1.165 +    /* Ratio of input/output samples */
   1.166 +    S->invRatio_Q16 = silk_LSHIFT32( silk_DIV32( silk_LSHIFT32( Fs_Hz_in, 14 + up2x ), Fs_Hz_out ), 2 );
   1.167 +    /* Make sure the ratio is rounded up */
   1.168 +    while( silk_SMULWW( S->invRatio_Q16, Fs_Hz_out ) < silk_LSHIFT32( Fs_Hz_in, up2x ) ) {
   1.169 +        S->invRatio_Q16++;
   1.170 +    }
   1.171 +
   1.172 +    return 0;
   1.173 +}
   1.174 +
   1.175 +/* Resampler: convert from one sampling rate to another */
   1.176 +/* Input and output sampling rate are at most 48000 Hz  */
   1.177 +opus_int silk_resampler(
   1.178 +    silk_resampler_state_struct *S,                 /* I/O  Resampler state                                             */
   1.179 +    opus_int16                  out[],              /* O    Output signal                                               */
   1.180 +    const opus_int16            in[],               /* I    Input signal                                                */
   1.181 +    opus_int32                  inLen               /* I    Number of input samples                                     */
   1.182 +)
   1.183 +{
   1.184 +    opus_int nSamples;
   1.185 +
   1.186 +    /* Need at least 1 ms of input data */
   1.187 +    silk_assert( inLen >= S->Fs_in_kHz );
   1.188 +    /* Delay can't exceed the 1 ms of buffering */
   1.189 +    silk_assert( S->inputDelay <= S->Fs_in_kHz );
   1.190 +
   1.191 +    nSamples = S->Fs_in_kHz - S->inputDelay;
   1.192 +
   1.193 +    /* Copy to delay buffer */
   1.194 +    silk_memcpy( &S->delayBuf[ S->inputDelay ], in, nSamples * sizeof( opus_int16 ) );
   1.195 +
   1.196 +    switch( S->resampler_function ) {
   1.197 +        case USE_silk_resampler_private_up2_HQ_wrapper:
   1.198 +            silk_resampler_private_up2_HQ_wrapper( S, out, S->delayBuf, S->Fs_in_kHz );
   1.199 +            silk_resampler_private_up2_HQ_wrapper( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );
   1.200 +            break;
   1.201 +        case USE_silk_resampler_private_IIR_FIR:
   1.202 +            silk_resampler_private_IIR_FIR( S, out, S->delayBuf, S->Fs_in_kHz );
   1.203 +            silk_resampler_private_IIR_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );
   1.204 +            break;
   1.205 +        case USE_silk_resampler_private_down_FIR:
   1.206 +            silk_resampler_private_down_FIR( S, out, S->delayBuf, S->Fs_in_kHz );
   1.207 +            silk_resampler_private_down_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );
   1.208 +            break;
   1.209 +        default:
   1.210 +            silk_memcpy( out, S->delayBuf, S->Fs_in_kHz * sizeof( opus_int16 ) );
   1.211 +            silk_memcpy( &out[ S->Fs_out_kHz ], &in[ nSamples ], ( inLen - S->Fs_in_kHz ) * sizeof( opus_int16 ) );
   1.212 +    }
   1.213 +
   1.214 +    /* Copy to delay buffer */
   1.215 +    silk_memcpy( S->delayBuf, &in[ inLen - S->inputDelay ], S->inputDelay * sizeof( opus_int16 ) );
   1.216 +
   1.217 +    return 0;
   1.218 +}

mercurial