@@ -140,7 +140,7 @@ struct SpeexResamplerState_ {
140140 int out_stride ;
141141} ;
142142
143- static double kaiser12_table [68 ] = {
143+ static const double kaiser12_table [68 ] = {
144144 0.99859849 , 1.00000000 , 0.99859849 , 0.99440475 , 0.98745105 , 0.97779076 ,
145145 0.96549770 , 0.95066529 , 0.93340547 , 0.91384741 , 0.89213598 , 0.86843014 ,
146146 0.84290116 , 0.81573067 , 0.78710866 , 0.75723148 , 0.72629970 , 0.69451601 ,
@@ -154,31 +154,31 @@ static double kaiser12_table[68] = {
154154 0.00105297 , 0.00069463 , 0.00043489 , 0.00025272 , 0.00013031 , 0.0000527734 ,
155155 0.00001000 , 0.00000000 };
156156/*
157- static double kaiser12_table[36] = {
157+ static const double kaiser12_table[36] = {
158158 0.99440475, 1.00000000, 0.99440475, 0.97779076, 0.95066529, 0.91384741,
159159 0.86843014, 0.81573067, 0.75723148, 0.69451601, 0.62920216, 0.56287762,
160160 0.49704014, 0.43304576, 0.37206735, 0.31506490, 0.26276832, 0.21567274,
161161 0.17404546, 0.13794294, 0.10723616, 0.08164178, 0.06075685, 0.04409466,
162162 0.03111947, 0.02127838, 0.01402878, 0.00886058, 0.00531256, 0.00298291,
163163 0.00153438, 0.00069463, 0.00025272, 0.0000527734, 0.00000500, 0.00000000};
164164*/
165- static double kaiser10_table [36 ] = {
165+ static const double kaiser10_table [36 ] = {
166166 0.99537781 , 1.00000000 , 0.99537781 , 0.98162644 , 0.95908712 , 0.92831446 ,
167167 0.89005583 , 0.84522401 , 0.79486424 , 0.74011713 , 0.68217934 , 0.62226347 ,
168168 0.56155915 , 0.50119680 , 0.44221549 , 0.38553619 , 0.33194107 , 0.28205962 ,
169169 0.23636152 , 0.19515633 , 0.15859932 , 0.12670280 , 0.09935205 , 0.07632451 ,
170170 0.05731132 , 0.04193980 , 0.02979584 , 0.02044510 , 0.01345224 , 0.00839739 ,
171171 0.00488951 , 0.00257636 , 0.00115101 , 0.00035515 , 0.00000000 , 0.00000000 };
172172
173- static double kaiser8_table [36 ] = {
173+ static const double kaiser8_table [36 ] = {
174174 0.99635258 , 1.00000000 , 0.99635258 , 0.98548012 , 0.96759014 , 0.94302200 ,
175175 0.91223751 , 0.87580811 , 0.83439927 , 0.78875245 , 0.73966538 , 0.68797126 ,
176176 0.63451750 , 0.58014482 , 0.52566725 , 0.47185369 , 0.41941150 , 0.36897272 ,
177177 0.32108304 , 0.27619388 , 0.23465776 , 0.19672670 , 0.16255380 , 0.13219758 ,
178178 0.10562887 , 0.08273982 , 0.06335451 , 0.04724088 , 0.03412321 , 0.02369490 ,
179179 0.01563093 , 0.00959968 , 0.00527363 , 0.00233883 , 0.00050000 , 0.00000000 };
180180
181- static double kaiser6_table [36 ] = {
181+ static const double kaiser6_table [36 ] = {
182182 0.99733006 , 1.00000000 , 0.99733006 , 0.98935595 , 0.97618418 , 0.95799003 ,
183183 0.93501423 , 0.90755855 , 0.87598009 , 0.84068475 , 0.80211977 , 0.76076565 ,
184184 0.71712752 , 0.67172623 , 0.62508937 , 0.57774224 , 0.53019925 , 0.48295561 ,
@@ -187,27 +187,27 @@ static double kaiser6_table[36] = {
187187 0.05031820 , 0.03607231 , 0.02432151 , 0.01487334 , 0.00752000 , 0.00000000 };
188188
189189struct FuncDef {
190- double * table ;
190+ const double * table ;
191191 int oversample ;
192192};
193193
194- static struct FuncDef _KAISER12 = {kaiser12_table , 64 };
194+ static const struct FuncDef _KAISER12 = {kaiser12_table , 64 };
195195#define KAISER12 (&_KAISER12)
196196/*static struct FuncDef _KAISER12 = {kaiser12_table, 32};
197197#define KAISER12 (&_KAISER12)*/
198- static struct FuncDef _KAISER10 = {kaiser10_table , 32 };
198+ static const struct FuncDef _KAISER10 = {kaiser10_table , 32 };
199199#define KAISER10 (&_KAISER10)
200- static struct FuncDef _KAISER8 = {kaiser8_table , 32 };
200+ static const struct FuncDef _KAISER8 = {kaiser8_table , 32 };
201201#define KAISER8 (&_KAISER8)
202- static struct FuncDef _KAISER6 = {kaiser6_table , 32 };
202+ static const struct FuncDef _KAISER6 = {kaiser6_table , 32 };
203203#define KAISER6 (&_KAISER6)
204204
205205struct QualityMapping {
206206 int base_length ;
207207 int oversample ;
208208 float downsample_bandwidth ;
209209 float upsample_bandwidth ;
210- struct FuncDef * window_func ;
210+ const struct FuncDef * window_func ;
211211};
212212
213213
@@ -234,7 +234,7 @@ static const struct QualityMapping quality_map[11] = {
234234 {256 , 32 , 0.975f , 0.975f , KAISER12 }, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */
235235};
236236/*8,24,40,56,80,104,128,160,200,256,320*/
237- static double compute_func (float x , struct FuncDef * func )
237+ static double compute_func (float x , const struct FuncDef * func )
238238{
239239 float y , frac ;
240240 double interp [4 ];
@@ -269,7 +269,7 @@ int main(int argc, char **argv)
269269
270270#ifdef FIXED_POINT
271271/* The slow way of computing a sinc for the table. Should improve that some day */
272- static spx_word16_t sinc (float cutoff , float x , int N , struct FuncDef * window_func )
272+ static spx_word16_t sinc (float cutoff , float x , int N , const struct FuncDef * window_func )
273273{
274274 /*fprintf (stderr, "%f ", x);*/
275275 float xx = x * cutoff ;
@@ -282,7 +282,7 @@ static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_fu
282282}
283283#else
284284/* The slow way of computing a sinc for the table. Should improve that some day */
285- static spx_word16_t sinc (float cutoff , float x , int N , struct FuncDef * window_func )
285+ static spx_word16_t sinc (float cutoff , float x , int N , const struct FuncDef * window_func )
286286{
287287 /*fprintf (stderr, "%f ", x);*/
288288 float xx = x * cutoff ;
@@ -571,12 +571,47 @@ static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint3
571571}
572572#endif
573573
574- static void update_filter (SpeexResamplerState * st )
574+ /* This resampler is used to produce zero output in situations where memory
575+ for the filter could not be allocated. The expected numbers of input and
576+ output samples are still processed so that callers failing to check error
577+ codes are not surprised, possibly getting into infinite loops. */
578+ static int resampler_basic_zero (SpeexResamplerState * st , spx_uint32_t channel_index , const spx_word16_t * in , spx_uint32_t * in_len , spx_word16_t * out , spx_uint32_t * out_len )
579+ {
580+ int out_sample = 0 ;
581+ int last_sample = st -> last_sample [channel_index ];
582+ spx_uint32_t samp_frac_num = st -> samp_frac_num [channel_index ];
583+ const int out_stride = st -> out_stride ;
584+ const int int_advance = st -> int_advance ;
585+ const int frac_advance = st -> frac_advance ;
586+ const spx_uint32_t den_rate = st -> den_rate ;
587+
588+ while (!(last_sample >= (spx_int32_t )* in_len || out_sample >= (spx_int32_t )* out_len ))
589+ {
590+ out [out_stride * out_sample ++ ] = 0 ;
591+ last_sample += int_advance ;
592+ samp_frac_num += frac_advance ;
593+ if (samp_frac_num >= den_rate )
594+ {
595+ samp_frac_num -= den_rate ;
596+ last_sample ++ ;
597+ }
598+ }
599+
600+ st -> last_sample [channel_index ] = last_sample ;
601+ st -> samp_frac_num [channel_index ] = samp_frac_num ;
602+ return out_sample ;
603+ }
604+
605+ static int update_filter (SpeexResamplerState * st )
575606{
576607 spx_uint32_t old_length = st -> filt_len ;
577608 spx_uint32_t old_alloc_size = st -> mem_alloc_size ;
609+ int use_direct ;
610+ spx_uint32_t min_sinc_table_length ;
578611 spx_uint32_t min_alloc_size ;
579612
613+ st -> int_advance = st -> num_rate /st -> den_rate ;
614+ st -> frac_advance = st -> num_rate %st -> den_rate ;
580615 st -> oversample = quality_map [st -> quality ].oversample ;
581616 st -> filt_len = quality_map [st -> quality ].base_length ;
582617
@@ -605,17 +640,28 @@ static void update_filter(SpeexResamplerState *st)
605640
606641 /* Choose the resampling type that requires the least amount of memory */
607642#ifdef RESAMPLE_HUGEMEM
608- if ( st -> den_rate <= 16 * (st -> oversample + 8 ))
643+ use_direct = st -> den_rate <= 16 * (st -> oversample + 8 );
609644#else
610- if ( st -> filt_len * st -> den_rate <= st -> filt_len * st -> oversample + 8 )
645+ use_direct = st -> filt_len * st -> den_rate <= st -> filt_len * st -> oversample + 8 ;
611646#endif
647+ if (use_direct )
648+ {
649+ min_sinc_table_length = st -> filt_len * st -> den_rate ;
650+ } else {
651+ min_sinc_table_length = st -> filt_len * st -> oversample + 8 ;
652+ }
653+ if (st -> sinc_table_length < min_sinc_table_length )
654+ {
655+ spx_word16_t * sinc_table = (spx_word16_t * )speex_realloc (st -> sinc_table ,min_sinc_table_length * sizeof (spx_word16_t ));
656+ if (!sinc_table )
657+ goto fail ;
658+
659+ st -> sinc_table = sinc_table ;
660+ st -> sinc_table_length = min_sinc_table_length ;
661+ }
662+ if (use_direct )
612663 {
613664 spx_uint32_t i ;
614- if (st -> sinc_table_length < st -> filt_len * st -> den_rate )
615- {
616- st -> sinc_table = (spx_word16_t * )speex_realloc (st -> sinc_table ,st -> filt_len * st -> den_rate * sizeof (spx_word16_t ));
617- st -> sinc_table_length = st -> filt_len * st -> den_rate ;
618- }
619665 for (i = 0 ;i < st -> den_rate ;i ++ )
620666 {
621667 spx_int32_t j ;
@@ -635,11 +681,6 @@ static void update_filter(SpeexResamplerState *st)
635681 /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/
636682 } else {
637683 spx_int32_t i ;
638- if (st -> sinc_table_length < st -> filt_len * st -> oversample + 8 )
639- {
640- st -> sinc_table = (spx_word16_t * )speex_realloc (st -> sinc_table ,(st -> filt_len * st -> oversample + 8 )* sizeof (spx_word16_t ));
641- st -> sinc_table_length = st -> filt_len * st -> oversample + 8 ;
642- }
643684 for (i = -4 ;i < (spx_int32_t )(st -> oversample * st -> filt_len + 4 );i ++ )
644685 st -> sinc_table [i + 4 ] = sinc (st -> cutoff ,(i /(float )st -> oversample - st -> filt_len /2 ), st -> filt_len , quality_map [st -> quality ].window_func );
645686#ifdef FIXED_POINT
@@ -652,8 +693,6 @@ static void update_filter(SpeexResamplerState *st)
652693#endif
653694 /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/
654695 }
655- st -> int_advance = st -> num_rate /st -> den_rate ;
656- st -> frac_advance = st -> num_rate %st -> den_rate ;
657696
658697
659698 /* Here's the place where we update the filter memory to take into account
@@ -662,7 +701,11 @@ static void update_filter(SpeexResamplerState *st)
662701 min_alloc_size = st -> filt_len - 1 + st -> buffer_size ;
663702 if (min_alloc_size > st -> mem_alloc_size )
664703 {
665- st -> mem = (spx_word16_t * )speex_realloc (st -> mem , st -> nb_channels * min_alloc_size * sizeof (spx_word16_t ));
704+ spx_word16_t * mem = (spx_word16_t * )speex_realloc (st -> mem , st -> nb_channels * min_alloc_size * sizeof (spx_word16_t ));
705+ if (!mem )
706+ goto fail ;
707+
708+ st -> mem = mem ;
666709 st -> mem_alloc_size = min_alloc_size ;
667710 }
668711 if (!st -> started )
@@ -727,7 +770,15 @@ static void update_filter(SpeexResamplerState *st)
727770 st -> magic_samples [i ] += old_magic ;
728771 }
729772 }
773+ return RESAMPLER_ERR_SUCCESS ;
730774
775+ fail :
776+ st -> resampler_ptr = resampler_basic_zero ;
777+ /* st->mem may still contain consumed input samples for the filter.
778+ Restore filt_len so that filt_len - 1 still points to the position after
779+ the last of these samples. */
780+ st -> filt_len = old_length ;
781+ return RESAMPLER_ERR_ALLOC_FAILED ;
731782}
732783
733784EXPORT SpeexResamplerState * speex_resampler_init (spx_uint32_t nb_channels , spx_uint32_t in_rate , spx_uint32_t out_rate , int quality , int * err )
@@ -739,6 +790,8 @@ EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
739790{
740791 spx_uint32_t i ;
741792 SpeexResamplerState * st ;
793+ int filter_err ;
794+
742795 if (quality > 10 || quality < 0 )
743796 {
744797 if (err )
@@ -780,12 +833,16 @@ EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
780833 speex_resampler_set_quality (st , quality );
781834 speex_resampler_set_rate_frac (st , ratio_num , ratio_den , in_rate , out_rate );
782835
783-
784- update_filter (st );
785-
786- st -> initialised = 1 ;
836+ filter_err = update_filter (st );
837+ if (filter_err == RESAMPLER_ERR_SUCCESS )
838+ {
839+ st -> initialised = 1 ;
840+ } else {
841+ speex_resampler_destroy (st );
842+ st = NULL ;
843+ }
787844 if (err )
788- * err = RESAMPLER_ERR_SUCCESS ;
845+ * err = filter_err ;
789846
790847 return st ;
791848}
@@ -884,7 +941,7 @@ EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t c
884941 }
885942 * in_len -= ilen ;
886943 * out_len -= olen ;
887- return RESAMPLER_ERR_SUCCESS ;
944+ return st -> resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS ;
888945}
889946
890947#ifdef FIXED_POINT
@@ -958,7 +1015,7 @@ EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t cha
9581015 * in_len -= ilen ;
9591016 * out_len -= olen ;
9601017
961- return RESAMPLER_ERR_SUCCESS ;
1018+ return st -> resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS ;
9621019}
9631020
9641021EXPORT int speex_resampler_process_interleaved_float (SpeexResamplerState * st , const float * in , spx_uint32_t * in_len , float * out , spx_uint32_t * out_len )
@@ -981,7 +1038,7 @@ EXPORT int speex_resampler_process_interleaved_float(SpeexResamplerState *st, co
9811038 }
9821039 st -> in_stride = istride_save ;
9831040 st -> out_stride = ostride_save ;
984- return RESAMPLER_ERR_SUCCESS ;
1041+ return st -> resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS ;
9851042}
9861043
9871044EXPORT int speex_resampler_process_interleaved_int (SpeexResamplerState * st , const spx_int16_t * in , spx_uint32_t * in_len , spx_int16_t * out , spx_uint32_t * out_len )
@@ -1004,7 +1061,7 @@ EXPORT int speex_resampler_process_interleaved_int(SpeexResamplerState *st, cons
10041061 }
10051062 st -> in_stride = istride_save ;
10061063 st -> out_stride = ostride_save ;
1007- return RESAMPLER_ERR_SUCCESS ;
1064+ return st -> resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS ;
10081065}
10091066
10101067EXPORT int speex_resampler_set_rate (SpeexResamplerState * st , spx_uint32_t in_rate , spx_uint32_t out_rate )
@@ -1053,7 +1110,7 @@ EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t r
10531110 }
10541111
10551112 if (st -> initialised )
1056- update_filter (st );
1113+ return update_filter (st );
10571114 return RESAMPLER_ERR_SUCCESS ;
10581115}
10591116
@@ -1071,7 +1128,7 @@ EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality)
10711128 return RESAMPLER_ERR_SUCCESS ;
10721129 st -> quality = quality ;
10731130 if (st -> initialised )
1074- update_filter (st );
1131+ return update_filter (st );
10751132 return RESAMPLER_ERR_SUCCESS ;
10761133}
10771134
0 commit comments