media/libopus/silk/resampler.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /***********************************************************************
michael@0 2 Copyright (c) 2006-2011, Skype Limited. All rights reserved.
michael@0 3 Redistribution and use in source and binary forms, with or without
michael@0 4 modification, are permitted provided that the following conditions
michael@0 5 are met:
michael@0 6 - Redistributions of source code must retain the above copyright notice,
michael@0 7 this list of conditions and the following disclaimer.
michael@0 8 - Redistributions in binary form must reproduce the above copyright
michael@0 9 notice, this list of conditions and the following disclaimer in the
michael@0 10 documentation and/or other materials provided with the distribution.
michael@0 11 - Neither the name of Internet Society, IETF or IETF Trust, nor the
michael@0 12 names of specific contributors, may be used to endorse or promote
michael@0 13 products derived from this software without specific prior written
michael@0 14 permission.
michael@0 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
michael@0 16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
michael@0 17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
michael@0 18 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
michael@0 19 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
michael@0 20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
michael@0 21 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
michael@0 22 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
michael@0 23 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
michael@0 24 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
michael@0 25 POSSIBILITY OF SUCH DAMAGE.
michael@0 26 ***********************************************************************/
michael@0 27
michael@0 28 #ifdef HAVE_CONFIG_H
michael@0 29 #include "config.h"
michael@0 30 #endif
michael@0 31
michael@0 32 /*
michael@0 33 * Matrix of resampling methods used:
michael@0 34 * Fs_out (kHz)
michael@0 35 * 8 12 16 24 48
michael@0 36 *
michael@0 37 * 8 C UF U UF UF
michael@0 38 * 12 AF C UF U UF
michael@0 39 * Fs_in (kHz) 16 D AF C UF UF
michael@0 40 * 24 AF D AF C U
michael@0 41 * 48 AF AF AF D C
michael@0 42 *
michael@0 43 * C -> Copy (no resampling)
michael@0 44 * D -> Allpass-based 2x downsampling
michael@0 45 * U -> Allpass-based 2x upsampling
michael@0 46 * UF -> Allpass-based 2x upsampling followed by FIR interpolation
michael@0 47 * AF -> AR2 filter followed by FIR interpolation
michael@0 48 */
michael@0 49
michael@0 50 #include "resampler_private.h"
michael@0 51
michael@0 52 /* Tables with delay compensation values to equalize total delay for different modes */
michael@0 53 static const opus_int8 delay_matrix_enc[ 5 ][ 3 ] = {
michael@0 54 /* in \ out 8 12 16 */
michael@0 55 /* 8 */ { 6, 0, 3 },
michael@0 56 /* 12 */ { 0, 7, 3 },
michael@0 57 /* 16 */ { 0, 1, 10 },
michael@0 58 /* 24 */ { 0, 2, 6 },
michael@0 59 /* 48 */ { 18, 10, 12 }
michael@0 60 };
michael@0 61
michael@0 62 static const opus_int8 delay_matrix_dec[ 3 ][ 5 ] = {
michael@0 63 /* in \ out 8 12 16 24 48 */
michael@0 64 /* 8 */ { 4, 0, 2, 0, 0 },
michael@0 65 /* 12 */ { 0, 9, 4, 7, 4 },
michael@0 66 /* 16 */ { 0, 3, 12, 7, 7 }
michael@0 67 };
michael@0 68
michael@0 69 /* Simple way to make [8000, 12000, 16000, 24000, 48000] to [0, 1, 2, 3, 4] */
michael@0 70 #define rateID(R) ( ( ( ((R)>>12) - ((R)>16000) ) >> ((R)>24000) ) - 1 )
michael@0 71
michael@0 72 #define USE_silk_resampler_copy (0)
michael@0 73 #define USE_silk_resampler_private_up2_HQ_wrapper (1)
michael@0 74 #define USE_silk_resampler_private_IIR_FIR (2)
michael@0 75 #define USE_silk_resampler_private_down_FIR (3)
michael@0 76
michael@0 77 /* Initialize/reset the resampler state for a given pair of input/output sampling rates */
michael@0 78 opus_int silk_resampler_init(
michael@0 79 silk_resampler_state_struct *S, /* I/O Resampler state */
michael@0 80 opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */
michael@0 81 opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */
michael@0 82 opus_int forEnc /* I If 1: encoder; if 0: decoder */
michael@0 83 )
michael@0 84 {
michael@0 85 opus_int up2x;
michael@0 86
michael@0 87 /* Clear state */
michael@0 88 silk_memset( S, 0, sizeof( silk_resampler_state_struct ) );
michael@0 89
michael@0 90 /* Input checking */
michael@0 91 if( forEnc ) {
michael@0 92 if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) ||
michael@0 93 ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) {
michael@0 94 silk_assert( 0 );
michael@0 95 return -1;
michael@0 96 }
michael@0 97 S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
michael@0 98 } else {
michael@0 99 if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) ||
michael@0 100 ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) {
michael@0 101 silk_assert( 0 );
michael@0 102 return -1;
michael@0 103 }
michael@0 104 S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
michael@0 105 }
michael@0 106
michael@0 107 S->Fs_in_kHz = silk_DIV32_16( Fs_Hz_in, 1000 );
michael@0 108 S->Fs_out_kHz = silk_DIV32_16( Fs_Hz_out, 1000 );
michael@0 109
michael@0 110 /* Number of samples processed per batch */
michael@0 111 S->batchSize = S->Fs_in_kHz * RESAMPLER_MAX_BATCH_SIZE_MS;
michael@0 112
michael@0 113 /* Find resampler with the right sampling ratio */
michael@0 114 up2x = 0;
michael@0 115 if( Fs_Hz_out > Fs_Hz_in ) {
michael@0 116 /* Upsample */
michael@0 117 if( Fs_Hz_out == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 1 */
michael@0 118 /* Special case: directly use 2x upsampler */
michael@0 119 S->resampler_function = USE_silk_resampler_private_up2_HQ_wrapper;
michael@0 120 } else {
michael@0 121 /* Default resampler */
michael@0 122 S->resampler_function = USE_silk_resampler_private_IIR_FIR;
michael@0 123 up2x = 1;
michael@0 124 }
michael@0 125 } else if ( Fs_Hz_out < Fs_Hz_in ) {
michael@0 126 /* Downsample */
michael@0 127 S->resampler_function = USE_silk_resampler_private_down_FIR;
michael@0 128 if( silk_MUL( Fs_Hz_out, 4 ) == silk_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 4 */
michael@0 129 S->FIR_Fracs = 3;
michael@0 130 S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0;
michael@0 131 S->Coefs = silk_Resampler_3_4_COEFS;
michael@0 132 } else if( silk_MUL( Fs_Hz_out, 3 ) == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 3 */
michael@0 133 S->FIR_Fracs = 2;
michael@0 134 S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0;
michael@0 135 S->Coefs = silk_Resampler_2_3_COEFS;
michael@0 136 } else if( silk_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 2 */
michael@0 137 S->FIR_Fracs = 1;
michael@0 138 S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR1;
michael@0 139 S->Coefs = silk_Resampler_1_2_COEFS;
michael@0 140 } else if( silk_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 3 */
michael@0 141 S->FIR_Fracs = 1;
michael@0 142 S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;
michael@0 143 S->Coefs = silk_Resampler_1_3_COEFS;
michael@0 144 } else if( silk_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 4 */
michael@0 145 S->FIR_Fracs = 1;
michael@0 146 S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;
michael@0 147 S->Coefs = silk_Resampler_1_4_COEFS;
michael@0 148 } else if( silk_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 6 */
michael@0 149 S->FIR_Fracs = 1;
michael@0 150 S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2;
michael@0 151 S->Coefs = silk_Resampler_1_6_COEFS;
michael@0 152 } else {
michael@0 153 /* None available */
michael@0 154 silk_assert( 0 );
michael@0 155 return -1;
michael@0 156 }
michael@0 157 } else {
michael@0 158 /* Input and output sampling rates are equal: copy */
michael@0 159 S->resampler_function = USE_silk_resampler_copy;
michael@0 160 }
michael@0 161
michael@0 162 /* Ratio of input/output samples */
michael@0 163 S->invRatio_Q16 = silk_LSHIFT32( silk_DIV32( silk_LSHIFT32( Fs_Hz_in, 14 + up2x ), Fs_Hz_out ), 2 );
michael@0 164 /* Make sure the ratio is rounded up */
michael@0 165 while( silk_SMULWW( S->invRatio_Q16, Fs_Hz_out ) < silk_LSHIFT32( Fs_Hz_in, up2x ) ) {
michael@0 166 S->invRatio_Q16++;
michael@0 167 }
michael@0 168
michael@0 169 return 0;
michael@0 170 }
michael@0 171
michael@0 172 /* Resampler: convert from one sampling rate to another */
michael@0 173 /* Input and output sampling rate are at most 48000 Hz */
michael@0 174 opus_int silk_resampler(
michael@0 175 silk_resampler_state_struct *S, /* I/O Resampler state */
michael@0 176 opus_int16 out[], /* O Output signal */
michael@0 177 const opus_int16 in[], /* I Input signal */
michael@0 178 opus_int32 inLen /* I Number of input samples */
michael@0 179 )
michael@0 180 {
michael@0 181 opus_int nSamples;
michael@0 182
michael@0 183 /* Need at least 1 ms of input data */
michael@0 184 silk_assert( inLen >= S->Fs_in_kHz );
michael@0 185 /* Delay can't exceed the 1 ms of buffering */
michael@0 186 silk_assert( S->inputDelay <= S->Fs_in_kHz );
michael@0 187
michael@0 188 nSamples = S->Fs_in_kHz - S->inputDelay;
michael@0 189
michael@0 190 /* Copy to delay buffer */
michael@0 191 silk_memcpy( &S->delayBuf[ S->inputDelay ], in, nSamples * sizeof( opus_int16 ) );
michael@0 192
michael@0 193 switch( S->resampler_function ) {
michael@0 194 case USE_silk_resampler_private_up2_HQ_wrapper:
michael@0 195 silk_resampler_private_up2_HQ_wrapper( S, out, S->delayBuf, S->Fs_in_kHz );
michael@0 196 silk_resampler_private_up2_HQ_wrapper( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );
michael@0 197 break;
michael@0 198 case USE_silk_resampler_private_IIR_FIR:
michael@0 199 silk_resampler_private_IIR_FIR( S, out, S->delayBuf, S->Fs_in_kHz );
michael@0 200 silk_resampler_private_IIR_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );
michael@0 201 break;
michael@0 202 case USE_silk_resampler_private_down_FIR:
michael@0 203 silk_resampler_private_down_FIR( S, out, S->delayBuf, S->Fs_in_kHz );
michael@0 204 silk_resampler_private_down_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz );
michael@0 205 break;
michael@0 206 default:
michael@0 207 silk_memcpy( out, S->delayBuf, S->Fs_in_kHz * sizeof( opus_int16 ) );
michael@0 208 silk_memcpy( &out[ S->Fs_out_kHz ], &in[ nSamples ], ( inLen - S->Fs_in_kHz ) * sizeof( opus_int16 ) );
michael@0 209 }
michael@0 210
michael@0 211 /* Copy to delay buffer */
michael@0 212 silk_memcpy( S->delayBuf, &in[ inLen - S->inputDelay ], S->inputDelay * sizeof( opus_int16 ) );
michael@0 213
michael@0 214 return 0;
michael@0 215 }

mercurial