summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom Johansen <thomj@rockbox.org>2007-10-19 21:10:25 +0000
committerThom Johansen <thomj@rockbox.org>2007-10-19 21:10:25 +0000
commit56db5597548d0e9b9733b556a5c14ab4e38547e6 (patch)
tree8846e7d3a15f264853e6ee238994e3522e3bcc5a
parent6dc3a743addde6146b736ec5e1c71159c2150f95 (diff)
downloadrockbox-56db5597548d0e9b9733b556a5c14ab4e38547e6.tar.gz
rockbox-56db5597548d0e9b9733b556a5c14ab4e38547e6.zip
Sync Speex to SVN. Add new header file to adapt to Speex' new way of doing wrapper functions.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15209 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/libspeex/_kiss_fft_guts.h8
-rw-r--r--apps/codecs/libspeex/cb_search.c7
-rw-r--r--apps/codecs/libspeex/config-speex.h8
-rw-r--r--apps/codecs/libspeex/filterbank.c2
-rw-r--r--apps/codecs/libspeex/filters.c11
-rw-r--r--apps/codecs/libspeex/jitter.c87
-rw-r--r--apps/codecs/libspeex/kiss_fft.c9
-rw-r--r--apps/codecs/libspeex/kiss_fftr.c8
-rw-r--r--apps/codecs/libspeex/math_approx.c253
-rw-r--r--apps/codecs/libspeex/math_approx.h275
-rw-r--r--apps/codecs/libspeex/mdf.c14
-rw-r--r--apps/codecs/libspeex/misc.c121
-rw-r--r--apps/codecs/libspeex/misc.h148
-rw-r--r--apps/codecs/libspeex/modes.h2
-rw-r--r--apps/codecs/libspeex/nb_celp.c77
-rw-r--r--apps/codecs/libspeex/nb_celp.h2
-rw-r--r--apps/codecs/libspeex/preprocess.c4
-rw-r--r--apps/codecs/libspeex/pseudofloat.h4
-rw-r--r--apps/codecs/libspeex/quant_lsp.c4
-rw-r--r--apps/codecs/libspeex/resample.c49
-rw-r--r--apps/codecs/libspeex/rockbox.c59
-rw-r--r--apps/codecs/libspeex/rockbox.h99
-rw-r--r--apps/codecs/libspeex/sb_celp.c21
-rw-r--r--apps/codecs/libspeex/speex/speex.h2
-rw-r--r--apps/codecs/libspeex/speex/speex_callbacks.h2
-rw-r--r--apps/codecs/libspeex/speex/speex_echo.h6
-rw-r--r--apps/codecs/libspeex/speex/speex_jitter.h10
-rw-r--r--apps/codecs/libspeex/stack_alloc.h14
-rw-r--r--apps/codecs/libspeex/vorbis_psy.h2
29 files changed, 637 insertions, 671 deletions
diff --git a/apps/codecs/libspeex/_kiss_fft_guts.h b/apps/codecs/libspeex/_kiss_fft_guts.h
index 6eb9bd312b..3023b98b06 100644
--- a/apps/codecs/libspeex/_kiss_fft_guts.h
+++ b/apps/codecs/libspeex/_kiss_fft_guts.h
@@ -12,6 +12,14 @@ Redistribution and use in source and binary forms, with or without modification,
12THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*/ 13*/
14 14
15#ifdef MIN
16#undef MIN
17#endif
18#define MIN(a,b) ((a)<(b) ? (a):(b))
19#ifdef MAX
20#undef MAX
21#endif
22#define MAX(a,b) ((a)>(b) ? (a):(b))
15 23
16/* kiss_fft.h 24/* kiss_fft.h
17 defines kiss_fft_scalar as either short or a float type 25 defines kiss_fft_scalar as either short or a float type
diff --git a/apps/codecs/libspeex/cb_search.c b/apps/codecs/libspeex/cb_search.c
index 1090af0e08..ad883cc07f 100644
--- a/apps/codecs/libspeex/cb_search.c
+++ b/apps/codecs/libspeex/cb_search.c
@@ -359,7 +359,11 @@ int update_target
359 /*"erase" nbest list*/ 359 /*"erase" nbest list*/
360 for (j=0;j<N;j++) 360 for (j=0;j<N;j++)
361 ndist[j]=VERY_LARGE32; 361 ndist[j]=VERY_LARGE32;
362 362 /* This is not strictly necessary, but it provides an additonal safety
363 to prevent crashes in case something goes wrong in the previous
364 steps (e.g. NaNs) */
365 for (j=0;j<N;j++)
366 best_nind[j] = best_ntarget[j] = 0;
363 /*For all n-bests of previous subvector*/ 367 /*For all n-bests of previous subvector*/
364 for (j=0;j<N;j++) 368 for (j=0;j<N;j++)
365 { 369 {
@@ -397,6 +401,7 @@ int update_target
397 best_nind[n] = best_nind[n-1]; 401 best_nind[n] = best_nind[n-1];
398 best_ntarget[n] = best_ntarget[n-1]; 402 best_ntarget[n] = best_ntarget[n-1];
399 } 403 }
404 /* n is equal to m here, so they're interchangeable */
400 ndist[m] = err; 405 ndist[m] = err;
401 best_nind[n] = best_index[k]; 406 best_nind[n] = best_index[k];
402 best_ntarget[n] = j; 407 best_ntarget[n] = j;
diff --git a/apps/codecs/libspeex/config-speex.h b/apps/codecs/libspeex/config-speex.h
index 461873945f..52c71e9e82 100644
--- a/apps/codecs/libspeex/config-speex.h
+++ b/apps/codecs/libspeex/config-speex.h
@@ -102,19 +102,19 @@
102#define SIZEOF_SHORT 2 102#define SIZEOF_SHORT 2
103 103
104/* Version extra */ 104/* Version extra */
105#define SPEEX_EXTRA_VERSION "-svn" 105#define SPEEX_EXTRA_VERSION "-git"
106 106
107/* Version major */ 107/* Version major */
108#define SPEEX_MAJOR_VERSION 1 108#define SPEEX_MAJOR_VERSION 1
109 109
110/* Version micro */ 110/* Version micro */
111#define SPEEX_MICRO_VERSION 14 111#define SPEEX_MICRO_VERSION 15
112 112
113/* Version minor */ 113/* Version minor */
114#define SPEEX_MINOR_VERSION 1 114#define SPEEX_MINOR_VERSION 1
115 115
116/* Complete version string */ 116/* Complete version string */
117#define SPEEX_VERSION "1.1.14-svn" 117#define SPEEX_VERSION "1.2beta3"
118 118
119/* Define to 1 if you have the ANSI C header files. */ 119/* Define to 1 if you have the ANSI C header files. */
120#define STDC_HEADERS 1 120#define STDC_HEADERS 1
@@ -160,7 +160,7 @@
160#define OVERRIDE_SPEEX_FREE 1 160#define OVERRIDE_SPEEX_FREE 1
161#define OVERRIDE_SPEEX_FREE_SCRATCH 1 161#define OVERRIDE_SPEEX_FREE_SCRATCH 1
162#define OVERRIDE_SPEEX_MOVE 1 162#define OVERRIDE_SPEEX_MOVE 1
163#define OVERRIDE_SPEEX_ERROR 1 163#define OVERRIDE_SPEEX_FATAL 1
164#define OVERRIDE_SPEEX_WARNING 1 164#define OVERRIDE_SPEEX_WARNING 1
165#define OVERRIDE_SPEEX_WARNING_INT 1 165#define OVERRIDE_SPEEX_WARNING_INT 1
166#define OVERRIDE_SPEEX_NOTIFY 1 166#define OVERRIDE_SPEEX_NOTIFY 1
diff --git a/apps/codecs/libspeex/filterbank.c b/apps/codecs/libspeex/filterbank.c
index e665560bff..00391ebf7f 100644
--- a/apps/codecs/libspeex/filterbank.c
+++ b/apps/codecs/libspeex/filterbank.c
@@ -59,7 +59,7 @@ FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type)
59 int id1; 59 int id1;
60 int id2; 60 int id2;
61 df = DIV32(SHL32(sampling,15),MULT16_16(2,len)); 61 df = DIV32(SHL32(sampling,15),MULT16_16(2,len));
62 max_mel = toBARK(EXTRACT16(MULT16_16_Q15(QCONST16(.5f,15),sampling))); 62 max_mel = toBARK(EXTRACT16(sampling/2));
63 mel_interval = PDIV32(max_mel,banks-1); 63 mel_interval = PDIV32(max_mel,banks-1);
64 64
65 bank = (FilterBank*)speex_alloc(sizeof(FilterBank)); 65 bank = (FilterBank*)speex_alloc(sizeof(FilterBank));
diff --git a/apps/codecs/libspeex/filters.c b/apps/codecs/libspeex/filters.c
index fcb8ed4bac..a6a5f62d26 100644
--- a/apps/codecs/libspeex/filters.c
+++ b/apps/codecs/libspeex/filters.c
@@ -80,17 +80,16 @@ void sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max
80 } 80 }
81} 81}
82 82
83void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem)
84{
85 int i;
83#ifdef FIXED_POINT 86#ifdef FIXED_POINT
84 const spx_word16_t Pcoef[5][3] ICONST_ATTR = {{16384, -31313, 14991}, {16384, -31569, 15249}, {16384, -31677, 15328}, {16384, -32313, 15947}, {16384, -22446, 6537}}; 87 static const spx_word16_t Pcoef[5][3] ICONST_ATTR = {{16384, -31313, 14991}, {16384, -31569, 15249}, {16384, -31677, 15328}, {16384, -32313, 15947}, {16384, -22446, 6537}};
85 const spx_word16_t Zcoef[5][3] ICONST_ATTR = {{15672, -31344, 15672}, {15802, -31601, 15802}, {15847, -31694, 15847}, {16162, -32322, 16162}, {14418, -28836, 14418}}; 88 static const spx_word16_t Zcoef[5][3] ICONST_ATTR = {{15672, -31344, 15672}, {15802, -31601, 15802}, {15847, -31694, 15847}, {16162, -32322, 16162}, {14418, -28836, 14418}};
86#else 89#else
87 const spx_word16_t Pcoef[5][3] = {{1.00000f, -1.91120f, 0.91498f}, {1.00000f, -1.92683f, 0.93071f}, {1.00000f, -1.93338f, 0.93553f}, {1.00000f, -1.97226f, 0.97332f}, {1.00000f, -1.37000f, 0.39900f}}; 90 const spx_word16_t Pcoef[5][3] = {{1.00000f, -1.91120f, 0.91498f}, {1.00000f, -1.92683f, 0.93071f}, {1.00000f, -1.93338f, 0.93553f}, {1.00000f, -1.97226f, 0.97332f}, {1.00000f, -1.37000f, 0.39900f}};
88 const spx_word16_t Zcoef[5][3] = {{0.95654f, -1.91309f, 0.95654f}, {0.96446f, -1.92879f, 0.96446f}, {0.96723f, -1.93445f, 0.96723f}, {0.98645f, -1.97277f, 0.98645f}, {0.88000f, -1.76000f, 0.88000f}}; 91 const spx_word16_t Zcoef[5][3] = {{0.95654f, -1.91309f, 0.95654f}, {0.96446f, -1.92879f, 0.96446f}, {0.96723f, -1.93445f, 0.96723f}, {0.98645f, -1.97277f, 0.98645f}, {0.88000f, -1.76000f, 0.88000f}};
89#endif 92#endif
90
91void highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem)
92{
93 int i;
94 const spx_word16_t *den, *num; 93 const spx_word16_t *den, *num;
95 if (filtID>4) 94 if (filtID>4)
96 filtID=4; 95 filtID=4;
diff --git a/apps/codecs/libspeex/jitter.c b/apps/codecs/libspeex/jitter.c
index 81935e9195..6806b4ff22 100644
--- a/apps/codecs/libspeex/jitter.c
+++ b/apps/codecs/libspeex/jitter.c
@@ -133,8 +133,7 @@ void jitter_buffer_destroy(JitterBuffer *jitter)
133/** Put one packet into the jitter buffer */ 133/** Put one packet into the jitter buffer */
134void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) 134void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
135{ 135{
136 int i; 136 int i,j;
137 unsigned int j;
138 spx_int32_t arrival_margin; 137 spx_int32_t arrival_margin;
139 /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ 138 /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/
140 if (jitter->reset_state) 139 if (jitter->reset_state)
@@ -545,87 +544,3 @@ int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr)
545 return 0; 544 return 0;
546} 545}
547 546
548
549
550void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate)
551{
552 jitter->dec = decoder;
553 speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size);
554
555 jitter->packets = jitter_buffer_init(jitter->frame_size);
556
557 speex_bits_init(&jitter->current_packet);
558 jitter->valid_bits = 0;
559
560}
561
562void speex_jitter_destroy(SpeexJitter *jitter)
563{
564 jitter_buffer_destroy(jitter->packets);
565 speex_bits_destroy(&jitter->current_packet);
566}
567
568void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp)
569{
570 JitterBufferPacket p;
571 p.data = packet;
572 p.len = len;
573 p.timestamp = timestamp;
574 p.span = jitter->frame_size;
575 jitter_buffer_put(jitter->packets, &p);
576}
577
578void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp)
579{
580 int i;
581 int ret;
582 spx_int32_t activity;
583 char data[2048];
584 JitterBufferPacket packet;
585 packet.data = data;
586
587 if (jitter->valid_bits)
588 {
589 /* Try decoding last received packet */
590 ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
591 if (ret == 0)
592 {
593 jitter_buffer_tick(jitter->packets);
594 return;
595 } else {
596 jitter->valid_bits = 0;
597 }
598 }
599
600 ret = jitter_buffer_get(jitter->packets, &packet, NULL);
601
602 if (ret != JITTER_BUFFER_OK)
603 {
604 /* No packet found */
605
606 /*fprintf (stderr, "lost/late frame\n");*/
607 /*Packet is late or lost*/
608 speex_decode_int(jitter->dec, NULL, out);
609 } else {
610 speex_bits_read_from(&jitter->current_packet, packet.data, packet.len);
611 /* Decode packet */
612 ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
613 if (ret == 0)
614 {
615 jitter->valid_bits = 1;
616 } else {
617 /* Error while decoding */
618 for (i=0;i<jitter->frame_size;i++)
619 out[i]=0;
620 }
621 }
622 speex_decoder_ctl(jitter->dec, SPEEX_GET_ACTIVITY, &activity);
623 if (activity < 30)
624 jitter_buffer_update_delay(jitter->packets, &packet, NULL);
625 jitter_buffer_tick(jitter->packets);
626}
627
628int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter)
629{
630 return jitter_buffer_get_pointer_timestamp(jitter->packets);
631}
diff --git a/apps/codecs/libspeex/kiss_fft.c b/apps/codecs/libspeex/kiss_fft.c
index 3470d1108e..c5c0345820 100644
--- a/apps/codecs/libspeex/kiss_fft.c
+++ b/apps/codecs/libspeex/kiss_fft.c
@@ -86,7 +86,7 @@ static void kf_bfly4(
86 kiss_fft_cpx * Fout, 86 kiss_fft_cpx * Fout,
87 const size_t fstride, 87 const size_t fstride,
88 const kiss_fft_cfg st, 88 const kiss_fft_cfg st,
89 const size_t m, 89 int m,
90 int N, 90 int N,
91 int mm 91 int mm
92 ) 92 )
@@ -95,8 +95,7 @@ static void kf_bfly4(
95 kiss_fft_cpx scratch[6]; 95 kiss_fft_cpx scratch[6];
96 const size_t m2=2*m; 96 const size_t m2=2*m;
97 const size_t m3=3*m; 97 const size_t m3=3*m;
98 int i; 98 int i, j;
99 unsigned int j;
100 99
101 if (st->inverse) 100 if (st->inverse)
102 { 101 {
@@ -291,7 +290,7 @@ static void kf_bfly_generic(
291 290
292 /*CHECKBUF(scratchbuf,nscratchbuf,p);*/ 291 /*CHECKBUF(scratchbuf,nscratchbuf,p);*/
293 if (p>17) 292 if (p>17)
294 speex_error("KissFFT: max radix supported is 17"); 293 speex_fatal("KissFFT: max radix supported is 17");
295 294
296 for ( u=0; u<m; ++u ) { 295 for ( u=0; u<m; ++u ) {
297 k=u; 296 k=u;
@@ -506,7 +505,7 @@ void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,
506{ 505{
507 if (fin == fout) 506 if (fin == fout)
508 { 507 {
509 speex_error("In-place FFT not supported"); 508 speex_fatal("In-place FFT not supported");
510 /*CHECKBUF(tmpbuf,ntmpbuf,st->nfft); 509 /*CHECKBUF(tmpbuf,ntmpbuf,st->nfft);
511 kf_work(tmpbuf,fin,1,in_stride, st->factors,st); 510 kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
512 speex_move(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);*/ 511 speex_move(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);*/
diff --git a/apps/codecs/libspeex/kiss_fftr.c b/apps/codecs/libspeex/kiss_fftr.c
index ef8e464dcd..9bb4763169 100644
--- a/apps/codecs/libspeex/kiss_fftr.c
+++ b/apps/codecs/libspeex/kiss_fftr.c
@@ -84,7 +84,7 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr
84 kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; 84 kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
85 85
86 if ( st->substate->inverse) { 86 if ( st->substate->inverse) {
87 speex_error("kiss fft usage error: improper alloc\n"); 87 speex_fatal("kiss fft usage error: improper alloc\n");
88 } 88 }
89 89
90 ncfft = st->substate->nfft; 90 ncfft = st->substate->nfft;
@@ -138,7 +138,7 @@ void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata, kiss_fft_scalar *
138 int k, ncfft; 138 int k, ncfft;
139 139
140 if (st->substate->inverse == 0) { 140 if (st->substate->inverse == 0) {
141 speex_error ("kiss fft usage error: improper alloc\n"); 141 speex_fatal("kiss fft usage error: improper alloc\n");
142 } 142 }
143 143
144 ncfft = st->substate->nfft; 144 ncfft = st->substate->nfft;
@@ -177,7 +177,7 @@ void kiss_fftr2(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar
177 spx_word32_t f1kr, f1ki, twr, twi; 177 spx_word32_t f1kr, f1ki, twr, twi;
178 178
179 if ( st->substate->inverse) { 179 if ( st->substate->inverse) {
180 speex_error("kiss fft usage error: improper alloc\n"); 180 speex_fatal("kiss fft usage error: improper alloc\n");
181 } 181 }
182 182
183 ncfft = st->substate->nfft; 183 ncfft = st->substate->nfft;
@@ -263,7 +263,7 @@ void kiss_fftri2(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scala
263 int k, ncfft; 263 int k, ncfft;
264 264
265 if (st->substate->inverse == 0) { 265 if (st->substate->inverse == 0) {
266 speex_error ("kiss fft usage error: improper alloc\n"); 266 speex_fatal ("kiss fft usage error: improper alloc\n");
267 } 267 }
268 268
269 ncfft = st->substate->nfft; 269 ncfft = st->substate->nfft;
diff --git a/apps/codecs/libspeex/math_approx.c b/apps/codecs/libspeex/math_approx.c
index 5c8b3498c4..cf5853e313 100644
--- a/apps/codecs/libspeex/math_approx.c
+++ b/apps/codecs/libspeex/math_approx.c
@@ -36,256 +36,3 @@
36 36
37#include "math_approx.h" 37#include "math_approx.h"
38#include "misc.h" 38#include "misc.h"
39
40spx_int16_t spx_ilog2(spx_uint32_t x)
41{
42 int r=0;
43 if (x>=(spx_int32_t)65536)
44 {
45 x >>= 16;
46 r += 16;
47 }
48 if (x>=256)
49 {
50 x >>= 8;
51 r += 8;
52 }
53 if (x>=16)
54 {
55 x >>= 4;
56 r += 4;
57 }
58 if (x>=4)
59 {
60 x >>= 2;
61 r += 2;
62 }
63 if (x>=2)
64 {
65 r += 1;
66 }
67 return r;
68}
69
70spx_int16_t spx_ilog4(spx_uint32_t x)
71{
72 int r=0;
73 if (x>=(spx_int32_t)65536)
74 {
75 x >>= 16;
76 r += 8;
77 }
78 if (x>=256)
79 {
80 x >>= 8;
81 r += 4;
82 }
83 if (x>=16)
84 {
85 x >>= 4;
86 r += 2;
87 }
88 if (x>=4)
89 {
90 r += 1;
91 }
92 return r;
93}
94
95#ifdef FIXED_POINT
96
97/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
98/*#define C0 3634
99#define C1 21173
100#define C2 -12627
101#define C3 4215*/
102
103/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */
104#define C0 3634
105#define C1 21173
106#define C2 -12627
107#define C3 4204
108
109spx_word16_t spx_sqrt(spx_word32_t x)
110{
111 int k;
112 spx_word32_t rt;
113 k = spx_ilog4(x)-6;
114 x = VSHR32(x, (k<<1));
115 rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
116 rt = VSHR32(rt,7-k);
117 return rt;
118}
119
120/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
121
122
123#define A1 16469
124#define A2 2242
125#define A3 1486
126
127spx_word16_t spx_acos(spx_word16_t x)
128{
129 int s=0;
130 spx_word16_t ret;
131 spx_word16_t sq;
132 if (x<0)
133 {
134 s=1;
135 x = NEG16(x);
136 }
137 x = SUB16(16384,x);
138
139 x = x >> 1;
140 sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
141 ret = spx_sqrt(SHL32(EXTEND32(sq),13));
142
143 /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
144 if (s)
145 ret = SUB16(25736,ret);
146 return ret;
147}
148
149
150#define K1 8192
151#define K2 -4096
152#define K3 340
153#define K4 -10
154
155spx_word16_t spx_cos(spx_word16_t x)
156{
157 spx_word16_t x2;
158
159 if (x<12868)
160 {
161 x2 = MULT16_16_P13(x,x);
162 return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
163 } else {
164 x = SUB16(25736,x);
165 x2 = MULT16_16_P13(x,x);
166 return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
167 }
168}
169
170#define L1 32767
171#define L2 -7651
172#define L3 8277
173#define L4 -626
174
175static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x)
176{
177 spx_word16_t x2;
178
179 x2 = MULT16_16_P15(x,x);
180 return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2))))))));
181}
182
183spx_word16_t spx_cos_norm(spx_word32_t x)
184{
185 x = x&0x0001ffff;
186 if (x>SHL32(EXTEND32(1), 16))
187 x = SUB32(SHL32(EXTEND32(1), 17),x);
188 if (x&0x00007fff)
189 {
190 if (x<SHL32(EXTEND32(1), 15))
191 {
192 return _spx_cos_pi_2(EXTRACT16(x));
193 } else {
194 return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x)));
195 }
196 } else {
197 if (x&0x0000ffff)
198 return 0;
199 else if (x&0x0001ffff)
200 return -32767;
201 else
202 return 32767;
203 }
204}
205
206/*
207 K0 = 1
208 K1 = log(2)
209 K2 = 3-4*log(2)
210 K3 = 3*log(2) - 2
211*/
212#define D0 16384
213#define D1 11356
214#define D2 3726
215#define D3 1301
216/* Input in Q11 format, output in Q16 */
217static spx_word32_t spx_exp2(spx_word16_t x)
218{
219 int integer;
220 spx_word16_t frac;
221 integer = SHR16(x,11);
222 if (integer>14)
223 return 0x7fffffff;
224 else if (integer < -15)
225 return 0;
226 frac = SHL16(x-SHL16(integer,11),3);
227 frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac))))));
228 return VSHR32(EXTEND32(frac), -integer-2);
229}
230
231/* Input in Q11 format, output in Q16 */
232spx_word32_t spx_exp(spx_word16_t x)
233{
234 if (x>21290)
235 return 0x7fffffff;
236 else if (x<-21290)
237 return 0;
238 else
239 return spx_exp2(MULT16_16_P14(23637,x));
240}
241#define M1 32767
242#define M2 -21
243#define M3 -11943
244#define M4 4936
245
246static inline spx_word16_t spx_atan01(spx_word16_t x)
247{
248 return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
249}
250
251/* Input in Q15, output in Q14 */
252spx_word16_t spx_atan(spx_word32_t x)
253{
254 if (x <= 32767)
255 {
256 return SHR16(spx_atan01(x),1);
257 } else {
258 int e = spx_ilog2(x);
259 if (e>=29)
260 return 25736;
261 x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14)));
262 return SUB16(25736, SHR16(spx_atan01(x),1));
263 }
264}
265#else
266
267#ifndef M_PI
268#define M_PI 3.14159265358979323846 /* pi */
269#endif
270
271#define C1 0.9999932946f
272#define C2 -0.4999124376f
273#define C3 0.0414877472f
274#define C4 -0.0012712095f
275
276
277#define SPX_PI_2 1.5707963268
278spx_word16_t spx_cos(spx_word16_t x)
279{
280 if (x<SPX_PI_2)
281 {
282 x *= x;
283 return C1 + x*(C2+x*(C3+C4*x));
284 } else {
285 x = M_PI-x;
286 x *= x;
287 return NEG16(C1 + x*(C2+x*(C3+C4*x)));
288 }
289}
290
291#endif
diff --git a/apps/codecs/libspeex/math_approx.h b/apps/codecs/libspeex/math_approx.h
index 49cfda6ebe..8421d634bb 100644
--- a/apps/codecs/libspeex/math_approx.h
+++ b/apps/codecs/libspeex/math_approx.h
@@ -37,19 +37,7 @@
37 37
38#include "misc.h" 38#include "misc.h"
39 39
40spx_word16_t spx_cos(spx_word16_t x); 40#ifndef FIXED_POINT
41spx_int16_t spx_ilog2(spx_uint32_t x);
42spx_int16_t spx_ilog4(spx_uint32_t x);
43#ifdef FIXED_POINT
44spx_word16_t spx_sqrt(spx_word32_t x);
45spx_word16_t spx_acos(spx_word16_t x);
46spx_word32_t spx_exp(spx_word16_t x);
47spx_word16_t spx_cos_norm(spx_word32_t x);
48
49/* Input in Q15, output in Q14 */
50spx_word16_t spx_atan(spx_word32_t x);
51
52#else
53 41
54#define spx_sqrt sqrt 42#define spx_sqrt sqrt
55#define spx_acos acos 43#define spx_acos acos
@@ -59,4 +47,265 @@ spx_word16_t spx_atan(spx_word32_t x);
59 47
60#endif 48#endif
61 49
50
51
52static inline spx_int16_t spx_ilog2(spx_uint32_t x)
53{
54 int r=0;
55 if (x>=(spx_int32_t)65536)
56 {
57 x >>= 16;
58 r += 16;
59 }
60 if (x>=256)
61 {
62 x >>= 8;
63 r += 8;
64 }
65 if (x>=16)
66 {
67 x >>= 4;
68 r += 4;
69 }
70 if (x>=4)
71 {
72 x >>= 2;
73 r += 2;
74 }
75 if (x>=2)
76 {
77 r += 1;
78 }
79 return r;
80}
81
82static inline spx_int16_t spx_ilog4(spx_uint32_t x)
83{
84 int r=0;
85 if (x>=(spx_int32_t)65536)
86 {
87 x >>= 16;
88 r += 8;
89 }
90 if (x>=256)
91 {
92 x >>= 8;
93 r += 4;
94 }
95 if (x>=16)
96 {
97 x >>= 4;
98 r += 2;
99 }
100 if (x>=4)
101 {
102 r += 1;
103 }
104 return r;
105}
106
107#ifdef FIXED_POINT
108
109/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
110/*#define C0 3634
111#define C1 21173
112#define C2 -12627
113#define C3 4215*/
114
115/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */
116#define C0 3634
117#define C1 21173
118#define C2 -12627
119#define C3 4204
120
121static inline spx_word16_t spx_sqrt(spx_word32_t x)
122{
123 int k;
124 spx_word32_t rt;
125 k = spx_ilog4(x)-6;
126 x = VSHR32(x, (k<<1));
127 rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
128 rt = VSHR32(rt,7-k);
129 return rt;
130}
131
132/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
133
134
135#define A1 16469
136#define A2 2242
137#define A3 1486
138
139static inline spx_word16_t spx_acos(spx_word16_t x)
140{
141 int s=0;
142 spx_word16_t ret;
143 spx_word16_t sq;
144 if (x<0)
145 {
146 s=1;
147 x = NEG16(x);
148 }
149 x = SUB16(16384,x);
150
151 x = x >> 1;
152 sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
153 ret = spx_sqrt(SHL32(EXTEND32(sq),13));
154
155 /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
156 if (s)
157 ret = SUB16(25736,ret);
158 return ret;
159}
160
161
162#define K1 8192
163#define K2 -4096
164#define K3 340
165#define K4 -10
166
167static inline spx_word16_t spx_cos(spx_word16_t x)
168{
169 spx_word16_t x2;
170
171 if (x<12868)
172 {
173 x2 = MULT16_16_P13(x,x);
174 return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
175 } else {
176 x = SUB16(25736,x);
177 x2 = MULT16_16_P13(x,x);
178 return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
179 }
180}
181
182#define L1 32767
183#define L2 -7651
184#define L3 8277
185#define L4 -626
186
187static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x)
188{
189 spx_word16_t x2;
190
191 x2 = MULT16_16_P15(x,x);
192 return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2))))))));
193}
194
195static inline spx_word16_t spx_cos_norm(spx_word32_t x)
196{
197 x = x&0x0001ffff;
198 if (x>SHL32(EXTEND32(1), 16))
199 x = SUB32(SHL32(EXTEND32(1), 17),x);
200 if (x&0x00007fff)
201 {
202 if (x<SHL32(EXTEND32(1), 15))
203 {
204 return _spx_cos_pi_2(EXTRACT16(x));
205 } else {
206 return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x)));
207 }
208 } else {
209 if (x&0x0000ffff)
210 return 0;
211 else if (x&0x0001ffff)
212 return -32767;
213 else
214 return 32767;
215 }
216}
217
218/*
219 K0 = 1
220 K1 = log(2)
221 K2 = 3-4*log(2)
222 K3 = 3*log(2) - 2
223*/
224#define D0 16384
225#define D1 11356
226#define D2 3726
227#define D3 1301
228/* Input in Q11 format, output in Q16 */
229static inline spx_word32_t spx_exp2(spx_word16_t x)
230{
231 int integer;
232 spx_word16_t frac;
233 integer = SHR16(x,11);
234 if (integer>14)
235 return 0x7fffffff;
236 else if (integer < -15)
237 return 0;
238 frac = SHL16(x-SHL16(integer,11),3);
239 frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac))))));
240 return VSHR32(EXTEND32(frac), -integer-2);
241}
242
243/* Input in Q11 format, output in Q16 */
244static inline spx_word32_t spx_exp(spx_word16_t x)
245{
246 if (x>21290)
247 return 0x7fffffff;
248 else if (x<-21290)
249 return 0;
250 else
251 return spx_exp2(MULT16_16_P14(23637,x));
252}
253#define M1 32767
254#define M2 -21
255#define M3 -11943
256#define M4 4936
257
258static inline spx_word16_t spx_atan01(spx_word16_t x)
259{
260 return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
261}
262
263#undef M1
264#undef M2
265#undef M3
266#undef M4
267
268/* Input in Q15, output in Q14 */
269static inline spx_word16_t spx_atan(spx_word32_t x)
270{
271 if (x <= 32767)
272 {
273 return SHR16(spx_atan01(x),1);
274 } else {
275 int e = spx_ilog2(x);
276 if (e>=29)
277 return 25736;
278 x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14)));
279 return SUB16(25736, SHR16(spx_atan01(x),1));
280 }
281}
282#else
283
284#ifndef M_PI
285#define M_PI 3.14159265358979323846 /* pi */
286#endif
287
288#define C1 0.9999932946f
289#define C2 -0.4999124376f
290#define C3 0.0414877472f
291#define C4 -0.0012712095f
292
293
294#define SPX_PI_2 1.5707963268
295static inline spx_word16_t spx_cos(spx_word16_t x)
296{
297 if (x<SPX_PI_2)
298 {
299 x *= x;
300 return C1 + x*(C2+x*(C3+C4*x));
301 } else {
302 x = M_PI-x;
303 x *= x;
304 return NEG16(C1 + x*(C2+x*(C3+C4*x)));
305 }
306}
307
308#endif
309
310
62#endif 311#endif
diff --git a/apps/codecs/libspeex/mdf.c b/apps/codecs/libspeex/mdf.c
index 2fe3bd08fd..e9ea0fadba 100644
--- a/apps/codecs/libspeex/mdf.c
+++ b/apps/codecs/libspeex/mdf.c
@@ -368,7 +368,7 @@ static void dump_audio(const spx_int16_t *rec, const spx_int16_t *play, const sp
368{ 368{
369 if (!(rFile && pFile && oFile)) 369 if (!(rFile && pFile && oFile))
370 { 370 {
371 speex_error("Dump files not open"); 371 speex_fatal("Dump files not open");
372 } 372 }
373 fwrite(rec, sizeof(spx_int16_t), len, rFile); 373 fwrite(rec, sizeof(spx_int16_t), len, rFile);
374 fwrite(play, sizeof(spx_int16_t), len, pFile); 374 fwrite(play, sizeof(spx_int16_t), len, pFile);
@@ -384,10 +384,10 @@ SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length)
384 384
385#ifdef DUMP_ECHO_CANCEL_DATA 385#ifdef DUMP_ECHO_CANCEL_DATA
386 if (rFile || pFile || oFile) 386 if (rFile || pFile || oFile)
387 speex_error("Opening dump files twice"); 387 speex_fatal("Opening dump files twice");
388 rFile = fopen("aec_rec.sw", "w"); 388 rFile = fopen("aec_rec.sw", "wb");
389 pFile = fopen("aec_play.sw", "w"); 389 pFile = fopen("aec_play.sw", "wb");
390 oFile = fopen("aec_out.sw", "w"); 390 oFile = fopen("aec_out.sw", "wb");
391#endif 391#endif
392 392
393 st->frame_size = frame_size; 393 st->frame_size = frame_size;
@@ -635,13 +635,13 @@ void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play)
635 } 635 }
636} 636}
637 637
638/** Performs echo cancellation on a frame */ 638/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */
639void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout) 639void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout)
640{ 640{
641 speex_echo_cancellation(st, in, far_end, out); 641 speex_echo_cancellation(st, in, far_end, out);
642} 642}
643 643
644/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */ 644/** Performs echo cancellation on a frame */
645void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out) 645void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out)
646{ 646{
647 int i,j; 647 int i,j;
diff --git a/apps/codecs/libspeex/misc.c b/apps/codecs/libspeex/misc.c
index ae6869781d..e33b910850 100644
--- a/apps/codecs/libspeex/misc.c
+++ b/apps/codecs/libspeex/misc.c
@@ -47,124 +47,3 @@
47#include "misc_bfin.h" 47#include "misc_bfin.h"
48#endif 48#endif
49 49
50#ifndef RELEASE
51void print_vec(float *vec, int len, char *name)
52{
53 int i;
54 printf ("%s ", name);
55 for (i=0;i<len;i++)
56 printf (" %f", vec[i]);
57 printf ("\n");
58}
59#endif
60
61#ifdef FIXED_DEBUG
62long long spx_mips=0;
63#endif
64
65
66#ifndef OVERRIDE_SPEEX_ALLOC
67void *speex_alloc (int size)
68{
69 return calloc(size,1);
70}
71#endif
72
73#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH
74void *speex_alloc_scratch (int size)
75{
76 return calloc(size,1);
77}
78#endif
79
80#ifndef OVERRIDE_SPEEX_REALLOC
81void *speex_realloc (void *ptr, int size)
82{
83 return realloc(ptr, size);
84}
85#endif
86
87#ifndef OVERRIDE_SPEEX_FREE
88void speex_free (void *ptr)
89{
90 free(ptr);
91}
92#endif
93
94#ifndef OVERRIDE_SPEEX_FREE_SCRATCH
95void speex_free_scratch (void *ptr)
96{
97 free(ptr);
98}
99#endif
100
101#ifndef OVERRIDE_SPEEX_MOVE
102void *speex_move (void *dest, void *src, int n)
103{
104 return memmove(dest,src,n);
105}
106#endif
107
108#ifndef OVERRIDE_SPEEX_ERROR
109void speex_error(const char *str)
110{
111 fprintf (stderr, "Fatal (internal) error: %s\n", str);
112 exit(1);
113}
114#endif
115
116#ifndef OVERRIDE_SPEEX_WARNING
117void speex_warning(const char *str)
118{
119#ifndef DISABLE_WARNINGS
120 fprintf (stderr, "warning: %s\n", str);
121#endif
122}
123#endif
124
125#ifndef OVERRIDE_SPEEX_WARNING_INT
126void speex_warning_int(const char *str, int val)
127{
128#ifndef DISABLE_WARNINGS
129 fprintf (stderr, "warning: %s %d\n", str, val);
130#endif
131}
132#endif
133
134#ifndef OVERRIDE_SPEEX_NOTIFY
135void speex_notify(const char *str)
136{
137#ifndef DISABLE_NOTIFICATIONS
138 fprintf (stderr, "notification: %s\n", str);
139#endif
140}
141#endif
142
143#ifdef FIXED_POINT
144spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
145{
146 spx_word32_t res;
147 *seed = 1664525 * *seed + 1013904223;
148 res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
149 return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14));
150}
151#else
152spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
153{
154 const unsigned int jflone = 0x3f800000;
155 const unsigned int jflmsk = 0x007fffff;
156 union {int i; float f;} ran;
157 *seed = 1664525 * *seed + 1013904223;
158 ran.i = jflone | (jflmsk & *seed);
159 ran.f -= 1.5;
160 return 3.4642*std*ran.f;
161}
162#endif
163
164#ifndef OVERRIDE_SPEEX_PUTC
165void _speex_putc(int ch, void *file)
166{
167 FILE *f = (FILE *)file;
168 fprintf(f, "%c", ch);
169}
170#endif
diff --git a/apps/codecs/libspeex/misc.h b/apps/codecs/libspeex/misc.h
index 1664aaed9d..8702919b7b 100644
--- a/apps/codecs/libspeex/misc.h
+++ b/apps/codecs/libspeex/misc.h
@@ -35,6 +35,8 @@
35#ifndef MISC_H 35#ifndef MISC_H
36#define MISC_H 36#define MISC_H
37 37
38#include "config-speex.h"
39
38#ifndef SPEEX_VERSION 40#ifndef SPEEX_VERSION
39#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */ 41#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */
40#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */ 42#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */
@@ -69,16 +71,14 @@
69#endif 71#endif
70 72
71#include "arch.h" 73#include "arch.h"
72 74#include "rockbox.h"
73#ifndef RELEASE
74/** Print a named vector to stdout */
75void print_vec(float *vec, int len, char *name);
76#endif
77 75
78/** Convert little endian */ 76/** Convert little endian */
79static inline spx_int32_t le_int(spx_int32_t i) 77static inline spx_int32_t le_int(spx_int32_t i)
80{ 78{
81#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) 79#if 1
80 return letoh32(i);
81#elif !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
82 spx_uint32_t ui, ret; 82 spx_uint32_t ui, ret;
83 ui = i; 83 ui = i;
84 ret = ui>>24; 84 ret = ui>>24;
@@ -91,40 +91,138 @@ static inline spx_int32_t le_int(spx_int32_t i)
91#endif 91#endif
92} 92}
93 93
94#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__);
95#define speex_assert(cond) {if (!(cond)) {speex_fatal("assertion failed: " #cond);}}
96
97#ifndef RELEASE
98static void print_vec(float *vec, int len, char *name)
99{
100 int i;
101 printf ("%s ", name);
102 for (i=0;i<len;i++)
103 printf (" %f", vec[i]);
104 printf ("\n");
105}
106#endif
107
108#ifdef FIXED_DEBUG
109long long spx_mips=0;
110#endif
111
112
94/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free */ 113/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free */
95void *speex_alloc (int size); 114#ifndef OVERRIDE_SPEEX_ALLOC
115static inline void *speex_alloc (int size)
116{
117 return calloc(size,1);
118}
119#endif
96 120
97/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */ 121/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
98void *speex_alloc_scratch (int size); 122#ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH
123static inline void *speex_alloc_scratch (int size)
124{
125 return calloc(size,1);
126}
127#endif
99 128
100/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */ 129/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */
101void *speex_realloc (void *ptr, int size); 130#ifndef OVERRIDE_SPEEX_REALLOC
131static inline void *speex_realloc (void *ptr, int size)
132{
133 return realloc(ptr, size);
134}
135#endif
102 136
103/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */ 137/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */
104void speex_free (void *ptr); 138#ifndef OVERRIDE_SPEEX_FREE
139static inline void speex_free (void *ptr)
140{
141 free(ptr);
142}
143#endif
105 144
106/** Same as speex_alloc, except that the area is only needed inside a Speex call (might cause problem with wideband though) */ 145/** Same as speex_free, except that the area is only needed inside a Speex call (might cause problem with wideband though) */
107void speex_free_scratch (void *ptr); 146#ifndef OVERRIDE_SPEEX_FREE_SCRATCH
147static inline void speex_free_scratch (void *ptr)
148{
149 free(ptr);
150}
151#endif
108 152
109/** Speex wrapper for mem_move */ 153/** Print warning message with integer argument to stderr */
110void *speex_move (void *dest, void *src, int n); 154#ifndef OVERRIDE_SPEEX_MOVE
155static inline void *speex_move (void *dest, void *src, int n)
156{
157 return memmove(dest,src,n);
158}
159#endif
111 160
112/** Abort with an error message to stderr (internal Speex error) */ 161#ifndef OVERRIDE_SPEEX_FATAL
113void speex_error(const char *str); 162static inline void _speex_fatal(const char *str, const char *file, int line)
163{
164 fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
165 exit(1);
166}
167#endif
114 168
115/** Print warning message to stderr (programming error) */ 169#ifndef OVERRIDE_SPEEX_WARNING
116void speex_warning(const char *str); 170static inline void speex_warning(const char *str)
171{
172#ifndef DISABLE_WARNINGS
173 fprintf (stderr, "warning: %s\n", str);
174#endif
175}
176#endif
117 177
118/** Print warning message with integer argument to stderr */ 178#ifndef OVERRIDE_SPEEX_WARNING_INT
119void speex_warning_int(const char *str, int val); 179static inline void speex_warning_int(const char *str, int val)
180{
181#ifndef DISABLE_WARNINGS
182 fprintf (stderr, "warning: %s %d\n", str, val);
183#endif
184}
185#endif
120 186
121/** Print notification message to stderr */ 187#ifndef OVERRIDE_SPEEX_NOTIFY
122void speex_notify(const char *str); 188static inline void speex_notify(const char *str)
189{
190#ifndef DISABLE_NOTIFICATIONS
191 fprintf (stderr, "notification: %s\n", str);
192#endif
193}
194#endif
123 195
124/** Generate a random number */ 196#ifdef FIXED_POINT
125spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed); 197/** Generate a pseudo-random number */
198static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
199{
200 spx_word32_t res;
201 *seed = 1664525 * *seed + 1013904223;
202 res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
203 return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14));
204}
205#else
206/** Generate a pseudo-random number */
207static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
208{
209 const unsigned int jflone = 0x3f800000;
210 const unsigned int jflmsk = 0x007fffff;
211 union {int i; float f;} ran;
212 *seed = 1664525 * *seed + 1013904223;
213 ran.i = jflone | (jflmsk & *seed);
214 ran.f -= 1.5;
215 return 3.4642*std*ran.f;
216}
217#endif
126 218
219#ifndef OVERRIDE_SPEEX_PUTC
127/** Speex wrapper for putc */ 220/** Speex wrapper for putc */
128void _speex_putc(int ch, void *file); 221static inline void _speex_putc(int ch, void *file)
222{
223 FILE *f = (FILE *)file;
224 fprintf(f, "%c", ch);
225}
226#endif
129 227
130#endif 228#endif
diff --git a/apps/codecs/libspeex/modes.h b/apps/codecs/libspeex/modes.h
index 5bf1971c21..730c80fb07 100644
--- a/apps/codecs/libspeex/modes.h
+++ b/apps/codecs/libspeex/modes.h
@@ -98,7 +98,7 @@ typedef struct SpeexSubmode {
98 lsp_quant_func lsp_quant; /**< LSP quantization function */ 98 lsp_quant_func lsp_quant; /**< LSP quantization function */
99 lsp_unquant_func lsp_unquant; /**< LSP unquantization function */ 99 lsp_unquant_func lsp_unquant; /**< LSP unquantization function */
100 100
101 /*Lont-term predictor functions*/ 101 /*Long-term predictor functions*/
102 ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */ 102 ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */
103 ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */ 103 ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */
104 const void *ltp_params; /**< Pitch parameters (options) */ 104 const void *ltp_params; /**< Pitch parameters (options) */
diff --git a/apps/codecs/libspeex/nb_celp.c b/apps/codecs/libspeex/nb_celp.c
index a2da760156..64ecb58689 100644
--- a/apps/codecs/libspeex/nb_celp.c
+++ b/apps/codecs/libspeex/nb_celp.c
@@ -209,7 +209,7 @@ void *nb_encoder_init(const SpeexMode *m)
209 st->highpass_enabled = 1; 209 st->highpass_enabled = 1;
210 210
211#ifdef ENABLE_VALGRIND 211#ifdef ENABLE_VALGRIND
212 VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st)); 212 VALGRIND_MAKE_READABLE(st, NB_ENC_STACK);
213#endif 213#endif
214 return st; 214 return st;
215} 215}
@@ -355,7 +355,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
355 355
356 356
357 /*Open-loop pitch*/ 357 /*Open-loop pitch*/
358 if (st->complexity>2 || !st->submodes[st->submodeID] || st->vbr_enabled || st->vad_enabled || SUBMODE(forced_pitch_gain) || 358 if (!st->submodes[st->submodeID] || (st->complexity>2 && SUBMODE(have_subframe_gain)<3) || st->vbr_enabled || st->vad_enabled || SUBMODE(forced_pitch_gain) ||
359 SUBMODE(lbr_pitch) != -1) 359 SUBMODE(lbr_pitch) != -1)
360 { 360 {
361 int nol_pitch[6]; 361 int nol_pitch[6];
@@ -440,7 +440,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
440#endif 440#endif
441 { 441 {
442 spx_word16_t g = compute_rms16(st->exc, st->frameSize); 442 spx_word16_t g = compute_rms16(st->exc, st->frameSize);
443 if (ol_pitch>0) 443 if (st->submodeID!=1 && ol_pitch>0)
444 ol_gain = MULT16_16(g, MULT16_16_Q14(QCONST16(1.1,14), 444 ol_gain = MULT16_16(g, MULT16_16_Q14(QCONST16(1.1,14),
445 spx_sqrt(QCONST32(1.,28)-MULT16_32_Q15(QCONST16(.8,15),SHL32(MULT16_16(ol_pitch_coef,ol_pitch_coef),16))))); 445 spx_sqrt(QCONST32(1.,28)-MULT16_32_Q15(QCONST16(.8,15),SHL32(MULT16_16(ol_pitch_coef,ol_pitch_coef),16)))));
446 else 446 else
@@ -787,18 +787,15 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
787 /*print_vec(st->bw_lpc1, 10, "bw_lpc");*/ 787 /*print_vec(st->bw_lpc1, 10, "bw_lpc");*/
788#endif 788#endif
789 789
790 /*FIXME: This will break if we change the window size */
791 speex_assert(st->windowSize-st->frameSize == st->subframeSize);
792 if (sub==0)
790 { 793 {
791 /*FIXME: This will break if we change the window size */ 794 for (i=0;i<st->subframeSize;i++)
792 if (st->windowSize-st->frameSize != st->subframeSize) 795 real_exc[i] = sw[i] = st->winBuf[i];
793 speex_error("windowSize-frameSize != subframeSize"); 796 } else {
794 if (sub==0) 797 for (i=0;i<st->subframeSize;i++)
795 { 798 real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)];
796 for (i=0;i<st->subframeSize;i++)
797 real_exc[i] = sw[i] = st->winBuf[i];
798 } else {
799 for (i=0;i<st->subframeSize;i++)
800 real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)];
801 }
802 } 799 }
803 fir_mem16(real_exc, interp_qlpc, real_exc, st->subframeSize, st->lpcSize, st->mem_exc2, stack); 800 fir_mem16(real_exc, interp_qlpc, real_exc, st->subframeSize, st->lpcSize, st->mem_exc2, stack);
804 801
@@ -845,7 +842,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
845 exc[i]=0; 842 exc[i]=0;
846 843
847 /* If we have a long-term predictor (otherwise, something's wrong) */ 844 /* If we have a long-term predictor (otherwise, something's wrong) */
848 if (SUBMODE(ltp_quant)) 845 speex_assert (SUBMODE(ltp_quant));
849 { 846 {
850 int pit_min, pit_max; 847 int pit_min, pit_max;
851 /* Long-term prediction */ 848 /* Long-term prediction */
@@ -894,10 +891,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
894#endif 891#endif
895 892
896 st->pitch[sub]=pitch; 893 st->pitch[sub]=pitch;
897 } else {
898 speex_error ("No pitch prediction, what's wrong");
899 } 894 }
900
901 /* Quantization of innovation */ 895 /* Quantization of innovation */
902 for (i=0;i<st->subframeSize;i++) 896 for (i=0;i<st->subframeSize;i++)
903 innov[i]=0; 897 innov[i]=0;
@@ -944,7 +938,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
944 signal_div(target, target, ener, st->subframeSize); 938 signal_div(target, target, ener, st->subframeSize);
945 939
946 /* Quantize innovation */ 940 /* Quantize innovation */
947 if (SUBMODE(innovation_quant)) 941 speex_assert (SUBMODE(innovation_quant));
948 { 942 {
949 /* Codebook search */ 943 /* Codebook search */
950 SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2, 944 SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2,
@@ -980,11 +974,8 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
980 { 974 {
981 st->innov_rms_save[sub] = compute_rms(innov, st->subframeSize); 975 st->innov_rms_save[sub] = compute_rms(innov, st->subframeSize);
982 } 976 }
983 } else {
984 speex_error("No fixed codebook");
985 } 977 }
986 978
987
988 for (i=0;i<st->subframeSize;i++) 979 for (i=0;i<st->subframeSize;i++)
989 sw[i] = exc[i]; 980 sw[i] = exc[i];
990 /* Final signal synthesis from excitation */ 981 /* Final signal synthesis from excitation */
@@ -1101,7 +1092,7 @@ void *nb_decoder_init(const SpeexMode *m)
1101 st->highpass_enabled = 1; 1092 st->highpass_enabled = 1;
1102 1093
1103#ifdef ENABLE_VALGRIND 1094#ifdef ENABLE_VALGRIND
1104 VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st)); 1095 VALGRIND_MAKE_READABLE(st, NB_DEC_STACK);
1105#endif 1096#endif
1106 return st; 1097 return st;
1107} 1098}
@@ -1330,10 +1321,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
1330 ALLOC(lpc, st->lpcSize, spx_coef_t); 1321 ALLOC(lpc, st->lpcSize, spx_coef_t);
1331 bw_lpc(QCONST16(0.93f,15), st->interp_qlpc, lpc, st->lpcSize); 1322 bw_lpc(QCONST16(0.93f,15), st->interp_qlpc, lpc, st->lpcSize);
1332 { 1323 {
1333 float innov_gain=0; 1324 spx_word16_t innov_gain=0;
1334 float pgain=GAIN_SCALING_1*st->last_pitch_gain;
1335 if (pgain>.6)
1336 pgain=.6;
1337 /* FIXME: This was innov, not exc */ 1325 /* FIXME: This was innov, not exc */
1338 innov_gain = compute_rms16(st->exc, st->frameSize); 1326 innov_gain = compute_rms16(st->exc, st->frameSize);
1339 for (i=0;i<st->frameSize;i++) 1327 for (i=0;i<st->frameSize;i++)
@@ -1477,7 +1465,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
1477 exc[i]=0; 1465 exc[i]=0;
1478 1466
1479 /*Adaptive codebook contribution*/ 1467 /*Adaptive codebook contribution*/
1480 if (SUBMODE(ltp_unquant)) 1468 speex_assert (SUBMODE(ltp_unquant));
1481 { 1469 {
1482 int pit_min, pit_max; 1470 int pit_min, pit_max;
1483 /* Handle pitch constraints if any */ 1471 /* Handle pitch constraints if any */
@@ -1542,8 +1530,6 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
1542 if (tmp > best_pitch_gain) 1530 if (tmp > best_pitch_gain)
1543 best_pitch_gain = tmp; 1531 best_pitch_gain = tmp;
1544 } 1532 }
1545 } else {
1546 speex_error("No pitch prediction, what's wrong");
1547 } 1533 }
1548 1534
1549 /* Unquantize the innovation */ 1535 /* Unquantize the innovation */
@@ -1567,7 +1553,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
1567 ener = ol_gain; 1553 ener = ol_gain;
1568 } 1554 }
1569 1555
1570 if (SUBMODE(innovation_unquant)) 1556 speex_assert (SUBMODE(innovation_unquant));
1571 { 1557 {
1572 /*Fixed codebook contribution*/ 1558 /*Fixed codebook contribution*/
1573 SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed); 1559 SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);
@@ -1599,39 +1585,40 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
1599 for (i=0;i<st->subframeSize;i++) 1585 for (i=0;i<st->subframeSize;i++)
1600 innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT)); 1586 innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT));
1601 } 1587 }
1602 } else {
1603 speex_error("No fixed codebook");
1604 } 1588 }
1605 1589
1606 /*Vocoder mode*/ 1590 /*Vocoder mode*/
1607 if (st->submodeID==1) 1591 if (st->submodeID==1)
1608 { 1592 {
1609 float g=ol_pitch_coef*GAIN_SCALING_1; 1593 spx_word16_t g=ol_pitch_coef;
1610 1594 g=MULT16_16_P14(QCONST16(1.5f,14),(g-QCONST16(.2f,6)));
1595 if (g<0)
1596 g=0;
1597 if (g>GAIN_SCALING)
1598 g=GAIN_SCALING;
1611 1599
1612 for (i=0;i<st->subframeSize;i++) 1600 for (i=0;i<st->subframeSize;i++)
1613 exc[i]=0; 1601 exc[i]=0;
1614 while (st->voc_offset<st->subframeSize) 1602 while (st->voc_offset<st->subframeSize)
1615 { 1603 {
1604 /* exc[st->voc_offset]= g*sqrt(2*ol_pitch)*ol_gain;
1605 Not quite sure why we need the factor of two in the sqrt */
1616 if (st->voc_offset>=0) 1606 if (st->voc_offset>=0)
1617 exc[st->voc_offset]=sqrt(1.0*ol_pitch); 1607 exc[st->voc_offset]=MULT16_16(spx_sqrt(MULT16_16_16(2,ol_pitch)),EXTRACT16(PSHR32(MULT16_16(g,PSHR32(ol_gain,SIG_SHIFT)),6)));
1618 st->voc_offset+=ol_pitch; 1608 st->voc_offset+=ol_pitch;
1619 } 1609 }
1620 st->voc_offset -= st->subframeSize; 1610 st->voc_offset -= st->subframeSize;
1621 1611
1622 g=.5+2*(g-.6);
1623 if (g<0)
1624 g=0;
1625 if (g>1)
1626 g=1;
1627 for (i=0;i<st->subframeSize;i++) 1612 for (i=0;i<st->subframeSize;i++)
1628 { 1613 {
1629 spx_word16_t exci=exc[i]; 1614 spx_word16_t exci=exc[i];
1630 /* FIXME: cleanup the innov[i]/SIG_SCALING */ 1615 exc[i]= ADD16(ADD16(MULT16_16_Q15(QCONST16(.7f,15),exc[i]) , MULT16_16_Q15(QCONST16(.3f,15),st->voc_m1)),
1631 exc[i]=.8*g*exc[i]*PSHR32(ol_gain,SIG_SHIFT) + .6*g*st->voc_m1*PSHR32(ol_gain,SIG_SHIFT) + (1-.5*g)*PSHR32(innov[i],SIG_SHIFT) - .5*g*PSHR32(st->voc_m2,SIG_SHIFT); 1616 SUB16(MULT16_16_Q15(Q15_ONE-MULT16_16_16(QCONST16(.85f,9),g),EXTRACT16(PSHR32(innov[i],SIG_SHIFT))),
1617 MULT16_16_Q15(MULT16_16_16(QCONST16(.15f,9),g),EXTRACT16(PSHR32(st->voc_m2,SIG_SHIFT)))
1618 ));
1632 st->voc_m1 = exci; 1619 st->voc_m1 = exci;
1633 st->voc_m2=innov[i]; 1620 st->voc_m2=innov[i];
1634 st->voc_mean = .95*st->voc_mean + .05*exc[i]; 1621 st->voc_mean = EXTRACT16(PSHR32(ADD32(MULT16_16(QCONST16(.8f,15),st->voc_mean), MULT16_16(QCONST16(.2f,15),exc[i])), 15));
1635 exc[i]-=st->voc_mean; 1622 exc[i]-=st->voc_mean;
1636 } 1623 }
1637 } 1624 }
diff --git a/apps/codecs/libspeex/nb_celp.h b/apps/codecs/libspeex/nb_celp.h
index cc91b1c4fe..fe30d38669 100644
--- a/apps/codecs/libspeex/nb_celp.h
+++ b/apps/codecs/libspeex/nb_celp.h
@@ -172,7 +172,7 @@ typedef struct DecState {
172 /*Vocoder data*/ 172 /*Vocoder data*/
173 spx_word16_t voc_m1; 173 spx_word16_t voc_m1;
174 spx_word32_t voc_m2; 174 spx_word32_t voc_m2;
175 float voc_mean; 175 spx_word16_t voc_mean;
176 int voc_offset; 176 int voc_offset;
177 177
178 int dtx_enabled; 178 int dtx_enabled;
diff --git a/apps/codecs/libspeex/preprocess.c b/apps/codecs/libspeex/preprocess.c
index 7e7f106b55..a720e88479 100644
--- a/apps/codecs/libspeex/preprocess.c
+++ b/apps/codecs/libspeex/preprocess.c
@@ -215,7 +215,7 @@ struct SpeexPreprocessState_ {
215 spx_word32_t *S; /**< Smoothed power spectrum */ 215 spx_word32_t *S; /**< Smoothed power spectrum */
216 spx_word32_t *Smin; /**< See Cohen paper */ 216 spx_word32_t *Smin; /**< See Cohen paper */
217 spx_word32_t *Stmp; /**< See Cohen paper */ 217 spx_word32_t *Stmp; /**< See Cohen paper */
218 int *update_prob; /**< Propability of speech presence for noise update */ 218 int *update_prob; /**< Probability of speech presence for noise update */
219 219
220 spx_word16_t *zeta; /**< Smoothed a priori SNR */ 220 spx_word16_t *zeta; /**< Smoothed a priori SNR */
221 spx_word32_t *echo_noise; 221 spx_word32_t *echo_noise;
@@ -737,6 +737,8 @@ int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x)
737 spx_word16_t effective_echo_suppress; 737 spx_word16_t effective_echo_suppress;
738 738
739 st->nb_adapt++; 739 st->nb_adapt++;
740 if (st->nb_adapt>20000)
741 st->nb_adapt = 20000;
740 st->min_count++; 742 st->min_count++;
741 743
742 beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt)); 744 beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt));
diff --git a/apps/codecs/libspeex/pseudofloat.h b/apps/codecs/libspeex/pseudofloat.h
index 05542f1d7f..9d588642a8 100644
--- a/apps/codecs/libspeex/pseudofloat.h
+++ b/apps/codecs/libspeex/pseudofloat.h
@@ -59,6 +59,10 @@ static const spx_float_t FLOAT_ZERO = {0,0};
59static const spx_float_t FLOAT_ONE = {16384,-14}; 59static const spx_float_t FLOAT_ONE = {16384,-14};
60static const spx_float_t FLOAT_HALF = {16384,-15}; 60static const spx_float_t FLOAT_HALF = {16384,-15};
61 61
62#ifdef MIN
63#undef MIN
64#endif
65#define MIN(a,b) ((a)<(b)?(a):(b))
62static inline spx_float_t PSEUDOFLOAT(spx_int32_t x) 66static inline spx_float_t PSEUDOFLOAT(spx_int32_t x)
63{ 67{
64 int e=0; 68 int e=0;
diff --git a/apps/codecs/libspeex/quant_lsp.c b/apps/codecs/libspeex/quant_lsp.c
index 472efa95a6..b2f4f85497 100644
--- a/apps/codecs/libspeex/quant_lsp.c
+++ b/apps/codecs/libspeex/quant_lsp.c
@@ -304,11 +304,11 @@ void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)
304#ifdef DISABLE_WIDEBAND 304#ifdef DISABLE_WIDEBAND
305void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) 305void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
306{ 306{
307 speex_error("Wideband and Ultra-wideband are disabled"); 307 speex_fatal("Wideband and Ultra-wideband are disabled");
308} 308}
309void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits) 309void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
310{ 310{
311 speex_error("Wideband and Ultra-wideband are disabled"); 311 speex_fatal("Wideband and Ultra-wideband are disabled");
312} 312}
313#else 313#else
314extern const signed char high_lsp_cdbk[]; 314extern const signed char high_lsp_cdbk[];
diff --git a/apps/codecs/libspeex/resample.c b/apps/codecs/libspeex/resample.c
index 2dfe2dd5f3..51270c572d 100644
--- a/apps/codecs/libspeex/resample.c
+++ b/apps/codecs/libspeex/resample.c
@@ -37,17 +37,23 @@
37 - Low memory requirement 37 - Low memory requirement
38 - Good *perceptual* quality (and not best SNR) 38 - Good *perceptual* quality (and not best SNR)
39 39
40 The code is working, but it's in a very early stage, so it may have 40 Warning: This resampler is relatively new. Although I think I got rid of
41 artifacts, noise or subliminal messages from satan. Also, the API 41 all the major bugs and I don't expect the API to change anymore, there
42 isn't stable and I can actually promise that I *will* change the API 42 may be something I've missed. So use with caution.
43 some time in the future.
44 43
45TODO list: 44 This algorithm is based on this original resampling algorithm:
46 - Variable calculation resolution depending on quality setting 45 Smith, Julius O. Digital Audio Resampling Home Page
47 - Single vs double in float mode 46 Center for Computer Research in Music and Acoustics (CCRMA),
48 - 16-bit vs 32-bit (sinc only) in fixed-point mode 47 Stanford University, 2007.
49 - Make sure the filter update works even when changing params 48 Web published at http://www-ccrma.stanford.edu/~jos/resample/.
50 after only a few samples procesed 49
50 There is one main difference, though. This resampler uses cubic
51 interpolation instead of linear interpolation in the above paper. This
52 makes the table much smaller and makes it possible to compute that table
53 on a per-stream basis. In turn, being able to tweak the table for each
54 stream makes it possible to both reduce complexity on simple ratios
55 (e.g. 2/3), and get rid of the rounding operations in the inner loop.
56 The latter both reduces CPU time and makes the algorithm more SIMD-friendly.
51*/ 57*/
52 58
53#ifdef HAVE_CONFIG_H 59#ifdef HAVE_CONFIG_H
@@ -84,6 +90,7 @@ static void speex_free (void *ptr) {free(ptr);}
84#define OVERSAMPLE 8 90#define OVERSAMPLE 8
85 91
86#define IMAX(a,b) ((a) > (b) ? (a) : (b)) 92#define IMAX(a,b) ((a) > (b) ? (a) : (b))
93#define IMIN(a,b) ((a) < (b) ? (a) : (b))
87 94
88#ifndef NULL 95#ifndef NULL
89#define NULL 0 96#define NULL 0
@@ -576,10 +583,10 @@ static void update_filter(SpeexResamplerState *st)
576 } 583 }
577 for (i=0;i<st->den_rate;i++) 584 for (i=0;i<st->den_rate;i++)
578 { 585 {
579 spx_uint32_t j; 586 spx_int32_t j;
580 for (j=0;j<st->filt_len;j++) 587 for (j=0;j<st->filt_len;j++)
581 { 588 {
582 st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func); 589 st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func);
583 } 590 }
584 } 591 }
585#ifdef FIXED_POINT 592#ifdef FIXED_POINT
@@ -997,16 +1004,19 @@ void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, sp
997 1004
998int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate) 1005int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate)
999{ 1006{
1000 int fact; 1007 spx_uint32_t fact;
1008 spx_uint32_t old_den;
1009 spx_uint32_t i;
1001 if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den) 1010 if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)
1002 return RESAMPLER_ERR_SUCCESS; 1011 return RESAMPLER_ERR_SUCCESS;
1003 1012
1013 old_den = st->den_rate;
1004 st->in_rate = in_rate; 1014 st->in_rate = in_rate;
1005 st->out_rate = out_rate; 1015 st->out_rate = out_rate;
1006 st->num_rate = ratio_num; 1016 st->num_rate = ratio_num;
1007 st->den_rate = ratio_den; 1017 st->den_rate = ratio_den;
1008 /* FIXME: This is terribly inefficient, but who cares (at least for now)? */ 1018 /* FIXME: This is terribly inefficient, but who cares (at least for now)? */
1009 for (fact=2;fact<=sqrt(IMAX(in_rate, out_rate));fact++) 1019 for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++)
1010 { 1020 {
1011 while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0)) 1021 while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))
1012 { 1022 {
@@ -1015,6 +1025,17 @@ int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_nu
1015 } 1025 }
1016 } 1026 }
1017 1027
1028 if (old_den > 0)
1029 {
1030 for (i=0;i<st->nb_channels;i++)
1031 {
1032 st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den;
1033 /* Safety net */
1034 if (st->samp_frac_num[i] >= st->den_rate)
1035 st->samp_frac_num[i] = st->den_rate-1;
1036 }
1037 }
1038
1018 if (st->initialised) 1039 if (st->initialised)
1019 update_filter(st); 1040 update_filter(st);
1020 return RESAMPLER_ERR_SUCCESS; 1041 return RESAMPLER_ERR_SUCCESS;
diff --git a/apps/codecs/libspeex/rockbox.c b/apps/codecs/libspeex/rockbox.c
index 89af3cba5d..2abf8ccb32 100644
--- a/apps/codecs/libspeex/rockbox.c
+++ b/apps/codecs/libspeex/rockbox.c
@@ -19,8 +19,6 @@
19#include "../codec.h" 19#include "../codec.h"
20#include "../lib/codeclib.h" 20#include "../lib/codeclib.h"
21 21
22extern struct codec_api* ci;
23
24#if defined(DEBUG) || defined(SIMULATOR) 22#if defined(DEBUG) || defined(SIMULATOR)
25#undef DEBUGF 23#undef DEBUGF
26#define DEBUGF ci->debugf 24#define DEBUGF ci->debugf
@@ -35,62 +33,7 @@ extern struct codec_api* ci;
35#define LOGF(...) 33#define LOGF(...)
36#endif 34#endif
37 35
38void *speex_alloc (int size) 36extern struct codec_api* ci;
39{
40 return codec_calloc(size, 1);
41}
42
43void *speex_alloc_scratch (int size)
44{
45 return codec_calloc(size,1);
46}
47
48void *speex_realloc (void *ptr, int size)
49{
50 return codec_realloc(ptr, size);
51}
52
53void speex_free (void *ptr)
54{
55 codec_free(ptr);
56}
57
58void speex_free_scratch (void *ptr)
59{
60 codec_free(ptr);
61}
62
63void *speex_move (void *dest, void *src, int n)
64{
65 return memmove(dest,src,n);
66}
67
68void speex_error(const char *str)
69{
70 DEBUGF("Fatal error: %s\n", str);
71 //exit(1);
72}
73
74void speex_warning(const char *str)
75{
76 DEBUGF("warning: %s\n", str);
77}
78
79void speex_warning_int(const char *str, int val)
80{
81 DEBUGF("warning: %s %d\n", str, val);
82}
83
84void speex_notify(const char *str)
85{
86 DEBUGF("notice: %s\n", str);
87}
88
89void _speex_putc(int ch, void *file)
90{
91 //FILE *f = (FILE *)file;
92 //printf("%c", ch);
93}
94 37
95float floor(float x) { 38float floor(float x) {
96 return ((float)(((int)x))); 39 return ((float)(((int)x)));
diff --git a/apps/codecs/libspeex/rockbox.h b/apps/codecs/libspeex/rockbox.h
new file mode 100644
index 0000000000..368f1fb2d2
--- /dev/null
+++ b/apps/codecs/libspeex/rockbox.h
@@ -0,0 +1,99 @@
1/**************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 Dan Everton
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ***************************************************************************/
18
19#ifndef SPEEX_ROCKBOX_H
20#define SPEEX_ROCKBOX_H
21
22#include "../codec.h"
23#include "../lib/codeclib.h"
24
25#if defined(DEBUG) || defined(SIMULATOR)
26#undef DEBUGF
27#define DEBUGF ci->debugf
28#else
29#define DEBUGF(...)
30#endif
31
32#ifdef ROCKBOX_HAS_LOGF
33#undef LOGF
34#define LOGF ci->logf
35#else
36#define LOGF(...)
37#endif
38
39extern struct codec_api* ci;
40
41static inline void *speex_alloc (int size)
42{
43 return codec_calloc(size, 1);
44}
45
46static inline void *speex_alloc_scratch (int size)
47{
48 return codec_calloc(size,1);
49}
50
51static inline void *speex_realloc (void *ptr, int size)
52{
53 return codec_realloc(ptr, size);
54}
55
56static inline void speex_free (void *ptr)
57{
58 codec_free(ptr);
59}
60
61static inline void speex_free_scratch (void *ptr)
62{
63 codec_free(ptr);
64}
65
66static inline void *speex_move (void *dest, void *src, int n)
67{
68 return memmove(dest,src,n);
69}
70
71static inline void _speex_fatal(const char *str, const char *file, int line)
72{
73 DEBUGF("Fatal error: %s\n", str);
74 //exit(1);
75}
76
77static inline void speex_warning(const char *str)
78{
79 DEBUGF("warning: %s\n", str);
80}
81
82static inline void speex_warning_int(const char *str, int val)
83{
84 DEBUGF("warning: %s %d\n", str, val);
85}
86
87static inline void speex_notify(const char *str)
88{
89 DEBUGF("notice: %s\n", str);
90}
91
92static inline void _speex_putc(int ch, void *file)
93{
94 //FILE *f = (FILE *)file;
95 //printf("%c", ch);
96}
97
98#endif
99
diff --git a/apps/codecs/libspeex/sb_celp.c b/apps/codecs/libspeex/sb_celp.c
index 6066c8c51b..c44cfffb58 100644
--- a/apps/codecs/libspeex/sb_celp.c
+++ b/apps/codecs/libspeex/sb_celp.c
@@ -35,7 +35,6 @@
35 35
36#include <math.h> 36#include <math.h>
37#include "sb_celp.h" 37#include "sb_celp.h"
38#include "stdlib.h"
39#include "filters.h" 38#include "filters.h"
40#include "lpc.h" 39#include "lpc.h"
41#include "lsp.h" 40#include "lsp.h"
@@ -47,6 +46,10 @@
47#include "misc.h" 46#include "misc.h"
48#include "math_approx.h" 47#include "math_approx.h"
49 48
49#ifndef NULL
50#define NULL 0
51#endif
52
50/* Default size for the encoder and decoder stack (can be changed at compile time). 53/* Default size for the encoder and decoder stack (can be changed at compile time).
51 This does not apply when using variable-size arrays or alloca. */ 54 This does not apply when using variable-size arrays or alloca. */
52#ifndef SB_ENC_STACK 55#ifndef SB_ENC_STACK
@@ -61,40 +64,40 @@
61#ifdef DISABLE_WIDEBAND 64#ifdef DISABLE_WIDEBAND
62void *sb_encoder_init(const SpeexMode *m) 65void *sb_encoder_init(const SpeexMode *m)
63{ 66{
64 speex_error("Wideband and Ultra-wideband are disabled"); 67 speex_fatal("Wideband and Ultra-wideband are disabled");
65 return NULL; 68 return NULL;
66} 69}
67void sb_encoder_destroy(void *state) 70void sb_encoder_destroy(void *state)
68{ 71{
69 speex_error("Wideband and Ultra-wideband are disabled"); 72 speex_fatal("Wideband and Ultra-wideband are disabled");
70} 73}
71int sb_encode(void *state, void *vin, SpeexBits *bits) 74int sb_encode(void *state, void *vin, SpeexBits *bits)
72{ 75{
73 speex_error("Wideband and Ultra-wideband are disabled"); 76 speex_fatal("Wideband and Ultra-wideband are disabled");
74 return -2; 77 return -2;
75} 78}
76void *sb_decoder_init(const SpeexMode *m) 79void *sb_decoder_init(const SpeexMode *m)
77{ 80{
78 speex_error("Wideband and Ultra-wideband are disabled"); 81 speex_fatal("Wideband and Ultra-wideband are disabled");
79 return NULL; 82 return NULL;
80} 83}
81void sb_decoder_destroy(void *state) 84void sb_decoder_destroy(void *state)
82{ 85{
83 speex_error("Wideband and Ultra-wideband are disabled"); 86 speex_fatal("Wideband and Ultra-wideband are disabled");
84} 87}
85int sb_decode(void *state, SpeexBits *bits, void *vout) 88int sb_decode(void *state, SpeexBits *bits, void *vout)
86{ 89{
87 speex_error("Wideband and Ultra-wideband are disabled"); 90 speex_fatal("Wideband and Ultra-wideband are disabled");
88 return -2; 91 return -2;
89} 92}
90int sb_encoder_ctl(void *state, int request, void *ptr) 93int sb_encoder_ctl(void *state, int request, void *ptr)
91{ 94{
92 speex_error("Wideband and Ultra-wideband are disabled"); 95 speex_fatal("Wideband and Ultra-wideband are disabled");
93 return -2; 96 return -2;
94} 97}
95int sb_decoder_ctl(void *state, int request, void *ptr) 98int sb_decoder_ctl(void *state, int request, void *ptr)
96{ 99{
97 speex_error("Wideband and Ultra-wideband are disabled"); 100 speex_fatal("Wideband and Ultra-wideband are disabled");
98 return -2; 101 return -2;
99} 102}
100#else 103#else
diff --git a/apps/codecs/libspeex/speex/speex.h b/apps/codecs/libspeex/speex/speex.h
index 0ff4be135f..9ac1d2da6c 100644
--- a/apps/codecs/libspeex/speex/speex.h
+++ b/apps/codecs/libspeex/speex/speex.h
@@ -156,7 +156,7 @@ extern "C" {
156#define SPEEX_GET_HIGHPASS 45 156#define SPEEX_GET_HIGHPASS 45
157 157
158/** Get "activity level" of the last decoded frame, i.e. 158/** Get "activity level" of the last decoded frame, i.e.
159 now much damage we cause if we remove the frame */ 159 how much damage we cause if we remove the frame */
160#define SPEEX_GET_ACTIVITY 47 160#define SPEEX_GET_ACTIVITY 47
161 161
162 162
diff --git a/apps/codecs/libspeex/speex/speex_callbacks.h b/apps/codecs/libspeex/speex/speex_callbacks.h
index 7892e2f9eb..6f450b3a3a 100644
--- a/apps/codecs/libspeex/speex/speex_callbacks.h
+++ b/apps/codecs/libspeex/speex/speex_callbacks.h
@@ -119,7 +119,7 @@ int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data)
119/** Standard handler for VBR request (Set VBR, no questions asked) */ 119/** Standard handler for VBR request (Set VBR, no questions asked) */
120int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data); 120int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data);
121 121
122/** Standard handler for enhancer request (Turn ehnancer on/off, no questions asked) */ 122/** Standard handler for enhancer request (Turn enhancer on/off, no questions asked) */
123int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data); 123int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data);
124 124
125/** Standard handler for VBR quality request (Set VBR quality, no questions asked) */ 125/** Standard handler for VBR quality request (Set VBR quality, no questions asked) */
diff --git a/apps/codecs/libspeex/speex/speex_echo.h b/apps/codecs/libspeex/speex/speex_echo.h
index 5b5eccd1d5..6fcb0c00d7 100644
--- a/apps/codecs/libspeex/speex/speex_echo.h
+++ b/apps/codecs/libspeex/speex/speex_echo.h
@@ -74,10 +74,10 @@ SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length);
74void speex_echo_state_destroy(SpeexEchoState *st); 74void speex_echo_state_destroy(SpeexEchoState *st);
75 75
76/** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added 76/** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added
77 * to playback ni this form) 77 * to playback in this form)
78 * 78 *
79 * @param st Echo canceller state 79 * @param st Echo canceller state
80 * @param rec signal from the microphone (near end + far end echo) 80 * @param rec Signal from the microphone (near end + far end echo)
81 * @param play Signal played to the speaker (received from far end) 81 * @param play Signal played to the speaker (received from far end)
82 * @param out Returns near-end signal with echo removed 82 * @param out Returns near-end signal with echo removed
83 */ 83 */
@@ -89,7 +89,7 @@ void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int
89/** Perform echo cancellation using internal playback buffer, which is delayed by two frames 89/** Perform echo cancellation using internal playback buffer, which is delayed by two frames
90 * to account for the delay introduced by most soundcards (but it could be off!) 90 * to account for the delay introduced by most soundcards (but it could be off!)
91 * @param st Echo canceller state 91 * @param st Echo canceller state
92 * @param rec signal from the microphone (near end + far end echo) 92 * @param rec Signal from the microphone (near end + far end echo)
93 * @param out Returns near-end signal with echo removed 93 * @param out Returns near-end signal with echo removed
94*/ 94*/
95void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out); 95void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out);
diff --git a/apps/codecs/libspeex/speex/speex_jitter.h b/apps/codecs/libspeex/speex/speex_jitter.h
index 570e22b1e2..3f3a43c240 100644
--- a/apps/codecs/libspeex/speex/speex_jitter.h
+++ b/apps/codecs/libspeex/speex/speex_jitter.h
@@ -69,7 +69,7 @@ struct _JitterBufferPacket {
69#define JITTER_BUFFER_OK 0 69#define JITTER_BUFFER_OK 0
70/** Packet is missing */ 70/** Packet is missing */
71#define JITTER_BUFFER_MISSING 1 71#define JITTER_BUFFER_MISSING 1
72/** Packet is incomplete (does not cover the entive tick */ 72/** Packet is incomplete (does not cover the entire tick */
73#define JITTER_BUFFER_INCOMPLETE 2 73#define JITTER_BUFFER_INCOMPLETE 2
74/** There was an error in the jitter buffer */ 74/** There was an error in the jitter buffer */
75#define JITTER_BUFFER_INTERNAL_ERROR -1 75#define JITTER_BUFFER_INTERNAL_ERROR -1
@@ -81,10 +81,14 @@ struct _JitterBufferPacket {
81#define JITTER_BUFFER_SET_MARGIN 0 81#define JITTER_BUFFER_SET_MARGIN 0
82/** Get minimum amount of extra buffering required (margin) */ 82/** Get minimum amount of extra buffering required (margin) */
83#define JITTER_BUFFER_GET_MARGIN 1 83#define JITTER_BUFFER_GET_MARGIN 1
84/* JITTER_BUFFER_SET_AVALIABLE_COUNT wouldn't make sense */ 84/* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */
85/** Get the amount of avaliable packets currently buffered */ 85/** Get the amount of available packets currently buffered */
86#define JITTER_BUFFER_GET_AVAILABLE_COUNT 3
87/** Included because of an early misspelling (will remove in next release) */
86#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3 88#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3
87 89
90
91
88#define JITTER_BUFFER_ADJUST_INTERPOLATE -1 92#define JITTER_BUFFER_ADJUST_INTERPOLATE -1
89#define JITTER_BUFFER_ADJUST_OK 0 93#define JITTER_BUFFER_ADJUST_OK 0
90#define JITTER_BUFFER_ADJUST_DROP 1 94#define JITTER_BUFFER_ADJUST_DROP 1
diff --git a/apps/codecs/libspeex/stack_alloc.h b/apps/codecs/libspeex/stack_alloc.h
index cb048fa55e..f9056b472d 100644
--- a/apps/codecs/libspeex/stack_alloc.h
+++ b/apps/codecs/libspeex/stack_alloc.h
@@ -36,11 +36,15 @@
36#define STACK_ALLOC_H 36#define STACK_ALLOC_H
37 37
38#ifdef USE_ALLOCA 38#ifdef USE_ALLOCA
39#ifdef WIN32 39# ifdef WIN32
40#include <malloc.h> 40# include <malloc.h>
41#else 41# else
42#include <alloca.h> 42# ifdef HAVE_ALLOCA_H
43#endif 43# include <alloca.h>
44# else
45# include <stdlib.h>
46# endif
47# endif
44#endif 48#endif
45 49
46/** 50/**
diff --git a/apps/codecs/libspeex/vorbis_psy.h b/apps/codecs/libspeex/vorbis_psy.h
index fbdb7c5506..6871057753 100644
--- a/apps/codecs/libspeex/vorbis_psy.h
+++ b/apps/codecs/libspeex/vorbis_psy.h
@@ -39,7 +39,7 @@
39#define NOISE_COMPAND_LEVELS 40 39#define NOISE_COMPAND_LEVELS 40
40 40
41 41
42#define todB(x) ((x)==0?-400.f:log((x)*(x))*4.34294480f) 42#define todB(x) ((x)>1e-13?log((x)*(x))*4.34294480f:-30)
43#define fromdB(x) (exp((x)*.11512925f)) 43#define fromdB(x) (exp((x)*.11512925f))
44 44
45/* The bark scale equations are approximations, since the original 45/* The bark scale equations are approximations, since the original