summaryrefslogtreecommitdiff
path: root/silk/resampler.c
diff options
context:
space:
mode:
authorGregory Maxwell <greg@xiph.org>2011-09-28 02:26:45 -0400
committerGregory Maxwell <greg@xiph.org>2011-09-28 02:26:45 -0400
commit96739ad35e57706a69b9198b4862a5814f8e98bd (patch)
tree6959a35a6ccd7c58906968369649449384b99a39 /silk/resampler.c
parent5d48dbd3117cda1413b9677f28bc32127b78c7f5 (diff)
downloadopus-96739ad35e57706a69b9198b4862a5814f8e98bd.tar.gz
Eliminate function pointers from the resampler.
Diffstat (limited to 'silk/resampler.c')
-rw-r--r--silk/resampler.c149
1 files changed, 36 insertions, 113 deletions
diff --git a/silk/resampler.c b/silk/resampler.c
index cb1aeb76..cdbe7340 100644
--- a/silk/resampler.c
+++ b/silk/resampler.c
@@ -72,6 +72,11 @@ static opus_int32 gcd(
return a;
}
+#define USE_silk_resampler_copy (0)
+#define USE_silk_resampler_private_up2_HQ_wrapper (1)
+#define USE_silk_resampler_private_IIR_FIR (2)
+#define USE_silk_resampler_private_down_FIR (3)
+
/* Initialize/reset the resampler state for a given pair of input/output sampling rates */
opus_int silk_resampler_init(
silk_resampler_state_struct *S, /* I/O: Resampler state */
@@ -85,54 +90,11 @@ opus_int silk_resampler_init(
silk_memset( S, 0, sizeof( silk_resampler_state_struct ) );
/* Input checking */
-#if RESAMPLER_SUPPORT_ABOVE_48KHZ
- if( Fs_Hz_in < 8000 || Fs_Hz_in > 192000 || Fs_Hz_out < 8000 || Fs_Hz_out > 192000 ) {
-#else
if( Fs_Hz_in < 8000 || Fs_Hz_in > 48000 || Fs_Hz_out < 8000 || Fs_Hz_out > 48000 ) {
-#endif
silk_assert( 0 );
return -1;
}
-#if RESAMPLER_SUPPORT_ABOVE_48KHZ
- /* Determine pre downsampling and post upsampling */
- if( Fs_Hz_in > 96000 ) {
- S->nPreDownsamplers = 2;
- S->down_pre_function = silk_resampler_private_down4;
- } else if( Fs_Hz_in > 48000 ) {
- S->nPreDownsamplers = 1;
- S->down_pre_function = silk_resampler_down2;
- } else {
- S->nPreDownsamplers = 0;
- S->down_pre_function = NULL;
- }
-
- if( Fs_Hz_out > 96000 ) {
- S->nPostUpsamplers = 2;
- S->up_post_function = silk_resampler_private_up4;
- } else if( Fs_Hz_out > 48000 ) {
- S->nPostUpsamplers = 1;
- S->up_post_function = silk_resampler_up2;
- } else {
- S->nPostUpsamplers = 0;
- S->up_post_function = NULL;
- }
-
- if( S->nPreDownsamplers + S->nPostUpsamplers > 0 ) {
- /* Ratio of output/input samples */
- S->ratio_Q16 = silk_LSHIFT32( silk_DIV32( silk_LSHIFT32( Fs_Hz_out, 13 ), Fs_Hz_in ), 3 );
- /* Make sure the ratio is rounded up */
- while( silk_SMULWW( S->ratio_Q16, Fs_Hz_in ) < Fs_Hz_out ) S->ratio_Q16++;
-
- /* Batch size is 10 ms */
- S->batchSizePrePost = silk_DIV32_16( Fs_Hz_in, 100 );
-
- /* Convert sampling rate to those after pre-downsampling and before post-upsampling */
- Fs_Hz_in = silk_RSHIFT( Fs_Hz_in, S->nPreDownsamplers );
- Fs_Hz_out = silk_RSHIFT( Fs_Hz_out, S->nPostUpsamplers );
- }
-#endif
-
/* Number of samples processed per batch */
/* First, try 10 ms frames */
S->batchSize = silk_DIV32_16( Fs_Hz_in, 100 );
@@ -155,81 +117,69 @@ opus_int silk_resampler_init(
/* Upsample */
if( Fs_Hz_out == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 1 */
/* Special case: directly use 2x upsampler */
- S->resampler_function = silk_resampler_private_up2_HQ_wrapper;
+ S->resampler_function = USE_silk_resampler_private_up2_HQ_wrapper;
} else {
/* Default resampler */
- S->resampler_function = silk_resampler_private_IIR_FIR;
+ S->resampler_function = USE_silk_resampler_private_IIR_FIR;
up2 = 1;
- if( Fs_Hz_in > 24000 ) {
- /* Low-quality all-pass upsampler */
- S->up2_function = silk_resampler_up2;
- } else {
- /* High-quality all-pass upsampler */
- S->up2_function = silk_resampler_private_up2_HQ;
- }
+ S->up2_hq = Fs_Hz_in <= 24000;
}
} else if ( Fs_Hz_out < Fs_Hz_in ) {
/* Downsample */
if( silk_MUL( Fs_Hz_out, 4 ) == silk_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 4 */
S->FIR_Fracs = 3;
S->Coefs = silk_Resampler_3_4_COEFS;
- S->resampler_function = silk_resampler_private_down_FIR;
+ S->resampler_function = USE_silk_resampler_private_down_FIR;
} else if( silk_MUL( Fs_Hz_out, 3 ) == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 3 */
S->FIR_Fracs = 2;
S->Coefs = silk_Resampler_2_3_COEFS;
- S->resampler_function = silk_resampler_private_down_FIR;
+ S->resampler_function = USE_silk_resampler_private_down_FIR;
} else if( silk_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 2 */
S->FIR_Fracs = 1;
S->Coefs = silk_Resampler_1_2_COEFS;
- S->resampler_function = silk_resampler_private_down_FIR;
+ S->resampler_function = USE_silk_resampler_private_down_FIR;
} else if( silk_MUL( Fs_Hz_out, 8 ) == silk_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 8 */
S->FIR_Fracs = 3;
S->Coefs = silk_Resampler_3_8_COEFS;
- S->resampler_function = silk_resampler_private_down_FIR;
+ S->resampler_function = USE_silk_resampler_private_down_FIR;
} else if( silk_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 3 */
S->FIR_Fracs = 1;
S->Coefs = silk_Resampler_1_3_COEFS;
- S->resampler_function = silk_resampler_private_down_FIR;
+ S->resampler_function = USE_silk_resampler_private_down_FIR;
} else if( silk_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 4 */
S->FIR_Fracs = 1;
down2 = 1;
S->Coefs = silk_Resampler_1_2_COEFS;
- S->resampler_function = silk_resampler_private_down_FIR;
+ S->resampler_function = USE_silk_resampler_private_down_FIR;
} else if( silk_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 6 */
S->FIR_Fracs = 1;
down2 = 1;
S->Coefs = silk_Resampler_1_3_COEFS;
- S->resampler_function = silk_resampler_private_down_FIR;
+ S->resampler_function = USE_silk_resampler_private_down_FIR;
} else if( silk_MUL( Fs_Hz_out, 441 ) == silk_MUL( Fs_Hz_in, 80 ) ) { /* Fs_out : Fs_in = 80 : 441 */
S->Coefs = silk_Resampler_80_441_ARMA4_COEFS;
- S->resampler_function = silk_resampler_private_IIR_FIR;
+ S->resampler_function = USE_silk_resampler_private_IIR_FIR;
} else if( silk_MUL( Fs_Hz_out, 441 ) == silk_MUL( Fs_Hz_in, 120 ) ) { /* Fs_out : Fs_in = 120 : 441 */
S->Coefs = silk_Resampler_120_441_ARMA4_COEFS;
- S->resampler_function = silk_resampler_private_IIR_FIR;
+ S->resampler_function = USE_silk_resampler_private_IIR_FIR;
} else if( silk_MUL( Fs_Hz_out, 441 ) == silk_MUL( Fs_Hz_in, 160 ) ) { /* Fs_out : Fs_in = 160 : 441 */
S->Coefs = silk_Resampler_160_441_ARMA4_COEFS;
- S->resampler_function = silk_resampler_private_IIR_FIR;
+ S->resampler_function = USE_silk_resampler_private_IIR_FIR;
} else if( silk_MUL( Fs_Hz_out, 441 ) == silk_MUL( Fs_Hz_in, 240 ) ) { /* Fs_out : Fs_in = 240 : 441 */
S->Coefs = silk_Resampler_240_441_ARMA4_COEFS;
- S->resampler_function = silk_resampler_private_IIR_FIR;
+ S->resampler_function = USE_silk_resampler_private_IIR_FIR;
} else if( silk_MUL( Fs_Hz_out, 441 ) == silk_MUL( Fs_Hz_in, 320 ) ) { /* Fs_out : Fs_in = 320 : 441 */
S->Coefs = silk_Resampler_320_441_ARMA4_COEFS;
- S->resampler_function = silk_resampler_private_IIR_FIR;
+ S->resampler_function = USE_silk_resampler_private_IIR_FIR;
} else {
/* Default resampler */
- S->resampler_function = silk_resampler_private_IIR_FIR;
+ S->resampler_function = USE_silk_resampler_private_IIR_FIR;
up2 = 1;
- if( Fs_Hz_in > 24000 ) {
- /* Low-quality all-pass upsampler */
- S->up2_function = silk_resampler_up2;
- } else {
- /* High-quality all-pass upsampler */
- S->up2_function = silk_resampler_private_up2_HQ;
- }
+ S->up2_hq = Fs_Hz_in <= 24000;
}
} else {
/* Input and output sampling rates are equal: copy */
- S->resampler_function = silk_resampler_private_copy;
+ S->resampler_function = USE_silk_resampler_copy;
}
S->input2x = up2 | down2;
@@ -255,10 +205,6 @@ opus_int silk_resampler_clear(
silk_memset( S->sDown2, 0, sizeof( S->sDown2 ) );
silk_memset( S->sIIR, 0, sizeof( S->sIIR ) );
silk_memset( S->sFIR, 0, sizeof( S->sFIR ) );
-#if RESAMPLER_SUPPORT_ABOVE_48KHZ
- silk_memset( S->sDownPre, 0, sizeof( S->sDownPre ) );
- silk_memset( S->sUpPost, 0, sizeof( S->sUpPost ) );
-#endif
return 0;
}
@@ -276,42 +222,19 @@ opus_int silk_resampler(
return -1;
}
-#if RESAMPLER_SUPPORT_ABOVE_48KHZ
- if( S->nPreDownsamplers + S->nPostUpsamplers > 0 ) {
- /* The input and/or output sampling rate is above 48000 Hz */
- opus_int32 nSamplesIn, nSamplesOut;
- opus_int16 in_buf[ 480 ], out_buf[ 480 ];
-
- while( inLen > 0 ) {
- /* Number of input and output samples to process */
- nSamplesIn = silk_min( inLen, S->batchSizePrePost );
- nSamplesOut = silk_SMULWB( S->ratio_Q16, nSamplesIn );
-
- silk_assert( silk_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) <= 480 );
- silk_assert( silk_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) <= 480 );
-
- if( S->nPreDownsamplers > 0 ) {
- S->down_pre_function( S->sDownPre, in_buf, in, nSamplesIn );
- if( S->nPostUpsamplers > 0 ) {
- S->resampler_function( S, out_buf, in_buf, silk_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) );
- S->up_post_function( S->sUpPost, out, out_buf, silk_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) );
- } else {
- S->resampler_function( S, out, in_buf, silk_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) );
- }
- } else {
- S->resampler_function( S, out_buf, in, silk_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) );
- S->up_post_function( S->sUpPost, out, out_buf, silk_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) );
- }
-
- in += nSamplesIn;
- out += nSamplesOut;
- inLen -= nSamplesIn;
- }
- } else
-#endif
- {
- /* Input and output sampling rate are at most 48000 Hz */
- S->resampler_function( S, out, in, inLen );
+ /* Input and output sampling rate are at most 48000 Hz */
+ switch(S->resampler_function) {
+ case USE_silk_resampler_private_up2_HQ_wrapper:
+ silk_resampler_private_up2_HQ_wrapper( S, out, in, inLen );
+ break;
+ case USE_silk_resampler_private_IIR_FIR:
+ silk_resampler_private_IIR_FIR( S, out, in, inLen );
+ break;
+ case USE_silk_resampler_private_down_FIR:
+ silk_resampler_private_down_FIR( S, out, in, inLen );
+ break;
+ default:
+ silk_memcpy( out, in, inLen * sizeof( opus_int16 ) );
}
return 0;