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