[Speex-dev] Possible fixed point overflow/div 0 preprocess.c
peter.rowling at jacques.com.au
Mon Sep 17 18:24:28 PDT 2007
I'll try to keep this as brief, yet descriptive enough to save everyone
If I'm off with this one please forgive me, but it has fixed my issues.
I am not
sure whether it is just my compiler (gcc 3.3.5) doing the wrong thing
with the cast.
Arch affected: x86, (others?)
svn revision: 12778
The SpeexPreprocessState_ member 'nb_adapt' is a signed integer.
nb_adapt is only
modified during 'speex_preprocess_run' when an unbounded increment is
calculating 'beta' within 'speex_preprocess_run', I received a floating
even when compiled with -DFIXED_POINT. The reason is as follows:
<original beta calculation within speex_preprocess_run>
beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt));
beta_1 = Q15_ONE-beta;
On my architecture(x86) at least the DIV32_16 is defined as follows.
typedef short spx_int16_t;
typedef spx_int16_t spx_word16_t;
The nb_adapt overflow occurred when its value reached 0x00010000 when
the cast is
performed to a short the value 0x0000 is given and hence the divide by
The SpeexPreprocessState_ member 'nb_adapt' is only checked in a couple
of places and
mostly for initial conditions such as within update_noise_prob below:
st->Smin[i] = st->Stmp[i] = 0;
if (st->nb_adapt < 100)
min_range = 15;
else if (st->nb_adapt < 1000)
min_range = 50;
else if (st->nb_adapt < 10000)
min_range = 150;
min_range = 300;
Maybe something like this is required within speex_preprocess_run to
prevent the observed overflow.
if ( st->nb_adapt < 0x7FFF /* or 32767 as elsewhere in the code */ )
More information about the Speex-dev