annotate src/opus-1.3/silk/resampler.c @ 84:08ae793730bd

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