Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit e460833

Browse files
committed
b=995075 update speex resampler to speexdsp 769dc295 r=padenot
--HG-- extra : rebase_source : 786ee924d4d41745bfad84fbf9457c82db4158fb
1 parent dd6d759 commit e460833

3 files changed

Lines changed: 107 additions & 50 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
This source is from the Speex DSP library
2-
(http://git.xiph.org/?p=speexdsp.git), from commit 305e54ea.
2+
(http://git.xiph.org/?p=speexdsp.git), from commit 769dc295.
33

44
It consists in the audio resampling code (resampler.c) and its header files
55
dependancies, imported into the tree using the update.sh script.

media/libspeex_resampler/hugemem.patch

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/
2020
#include "speex_resampler.h"
2121
#include "arch.h"
2222
#else /* OUTSIDE_SPEEX */
23-
@@ -613,18 +615,18 @@ static void update_filter(SpeexResampler
23+
@@ -632,18 +634,18 @@ static int update_filter(SpeexResamplerS
2424
if (st->oversample < 1)
2525
st->oversample = 1;
2626
} else {
@@ -30,14 +30,14 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/
3030

3131
/* Choose the resampling type that requires the least amount of memory */
3232
-#ifdef RESAMPLE_FULL_SINC_TABLE
33-
- if (1)
33+
- use_direct = 1;
3434
+#ifdef RESAMPLE_HUGEMEM
35-
+ if (st->den_rate <= 16*(st->oversample+8))
35+
+ use_direct = st->den_rate <= 16*(st->oversample+8);
3636
#else
37-
if (st->filt_len*st->den_rate <= st->filt_len*st->oversample+8)
37+
use_direct = st->filt_len*st->den_rate <= st->filt_len*st->oversample+8;
3838
#endif
39+
if (use_direct)
3940
{
40-
spx_uint32_t i;
41-
if (st->sinc_table_length < st->filt_len*st->den_rate)
42-
{
43-
st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t));
41+
min_sinc_table_length = st->filt_len*st->den_rate;
42+
} else {
43+
min_sinc_table_length = st->filt_len*st->oversample+8;

media/libspeex_resampler/src/resample.c

Lines changed: 98 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -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

189189
struct 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

205205
struct 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

733784
EXPORT 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

9641021
EXPORT 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

9871044
EXPORT 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

10101067
EXPORT 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

Comments
 (0)