diff --git a/media/libspeex_resampler/COPYING b/media/libspeex_resampler/COPYING index de6fbe2c9..7d6dc4aab 100644 --- a/media/libspeex_resampler/COPYING +++ b/media/libspeex_resampler/COPYING @@ -1,7 +1,7 @@ Copyright 2002-2008 Xiph.org Foundation Copyright 2002-2008 Jean-Marc Valin Copyright 2005-2007 Analog Devices Inc. -Copyright 2005-2008 Commonwealth Scientific and Industrial Research +Copyright 2005-2008 Commonwealth Scientific and Industrial Research Organisation (CSIRO) Copyright 1993, 2002, 2006 David Rowe Copyright 2003 EpicGames diff --git a/media/libspeex_resampler/README_MOZILLA b/media/libspeex_resampler/README_MOZILLA index 7f6b1bb33..0138c47a5 100644 --- a/media/libspeex_resampler/README_MOZILLA +++ b/media/libspeex_resampler/README_MOZILLA @@ -1,5 +1,5 @@ This source is from the Speex DSP library -(http://git.xiph.org/?p=speexdsp.git), from commit d60e75b2. +(http://git.xiph.org/?p=speexdsp.git), from commit 738e179. It consists in the audio resampling code (resampler.c) and its header files dependancies, imported into the tree using the update.sh script. diff --git a/media/libspeex_resampler/fix-overflow.patch b/media/libspeex_resampler/fix-overflow.patch deleted file mode 100644 index cee9a7edb..000000000 --- a/media/libspeex_resampler/fix-overflow.patch +++ /dev/null @@ -1,87 +0,0 @@ -diff --git a/media/libspeex_resampler/fix-overflow.patch b/media/libspeex_resampler/fix-overflow.patch -new file mode 100644 -index 0000000..e69de29 -diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/src/resample.c -index a3859e3..d99595a 100644 ---- a/media/libspeex_resampler/src/resample.c -+++ b/media/libspeex_resampler/src/resample.c -@@ -98,6 +98,10 @@ static void speex_free (void *ptr) {free(ptr);} - #define NULL 0 - #endif - -+#ifndef UINT32_MAX -+#define UINT32_MAX 4294967296U -+#endif -+ - #include "simd_detect.h" - - /* Numer of elements to allocate on the stack */ -@@ -603,6 +607,22 @@ static int resampler_basic_zero(SpeexResamplerState *st, spx_uint32_t channel_in - return out_sample; - } - -+static int _muldiv_safe(spx_uint32_t value, spx_uint32_t mul, spx_uint32_t div) -+{ -+ /* TODO: Could be simplified with 64 bits operation. */ -+ spx_uint32_t major = value / div; -+ spx_uint32_t remainder = value % div; -+ return remainder <= UINT32_MAX / mul && major <= UINT32_MAX / mul && -+ major * mul <= UINT32_MAX - remainder * mul / div; -+} -+ -+static spx_uint32_t _muldiv(spx_uint32_t value, spx_uint32_t mul, spx_uint32_t div) -+{ -+ spx_uint32_t major = value / div; -+ spx_uint32_t remainder = value % div; -+ return remainder * mul / div + major * mul; -+} -+ - static int update_filter(SpeexResamplerState *st) - { - spx_uint32_t old_length = st->filt_len; -@@ -620,8 +640,9 @@ static int update_filter(SpeexResamplerState *st) - { - /* down-sampling */ - st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate; -- /* FIXME: divide the numerator and denominator by a certain amount if they're too large */ -- st->filt_len = st->filt_len*st->num_rate / st->den_rate; -+ if (!_muldiv_safe(st->filt_len,st->num_rate,st->den_rate)) -+ goto fail; -+ st->filt_len = _muldiv(st->filt_len,st->num_rate,st->den_rate); - /* Round up to make sure we have a multiple of 8 for SSE */ - st->filt_len = ((st->filt_len-1)&(~0x7))+8; - if (2*st->den_rate < st->num_rate) -@@ -1129,7 +1150,9 @@ EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t r - { - for (i=0;inb_channels;i++) - { -- st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den; -+ if (!_muldiv_safe(st->samp_frac_num[i],st->den_rate,old_den)) -+ return RESAMPLER_ERR_OVERFLOW; -+ st->samp_frac_num[i]= _muldiv(st->samp_frac_num[i],st->den_rate,old_den); - /* Safety net */ - if (st->samp_frac_num[i] >= st->den_rate) - st->samp_frac_num[i] = st->den_rate-1; -diff --git a/media/libspeex_resampler/src/speex_resampler.h b/media/libspeex_resampler/src/speex_resampler.h -index 70abe52..1286872 100644 ---- a/media/libspeex_resampler/src/speex_resampler.h -+++ b/media/libspeex_resampler/src/speex_resampler.h -@@ -106,7 +106,8 @@ enum { - RESAMPLER_ERR_BAD_STATE = 2, - RESAMPLER_ERR_INVALID_ARG = 3, - RESAMPLER_ERR_PTR_OVERLAP = 4, -- -+ RESAMPLER_ERR_OVERFLOW = 5, -+ - RESAMPLER_ERR_MAX_ERROR - }; - -diff --git a/media/libspeex_resampler/update.sh b/media/libspeex_resampler/update.sh -index d4a025b..6950bc6 100644 ---- a/media/libspeex_resampler/update.sh -+++ b/media/libspeex_resampler/update.sh -@@ -26,3 +26,4 @@ patch -p3 < set-skip-frac.patch - patch -p3 < hugemem.patch - patch -p3 < remove-empty-asm-clobber.patch - patch -p3 < handle-memory-error.patch -+patch -p3 < fix-overflow.patch diff --git a/media/libspeex_resampler/handle-memory-error.patch b/media/libspeex_resampler/handle-memory-error.patch deleted file mode 100644 index f712a2de6..000000000 --- a/media/libspeex_resampler/handle-memory-error.patch +++ /dev/null @@ -1,46 +0,0 @@ -diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/src/resample.c -index 83ad119..a3859e3 100644 ---- a/media/libspeex_resampler/src/resample.c -+++ b/media/libspeex_resampler/src/resample.c -@@ -811,6 +811,12 @@ EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, - return NULL; - } - st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState)); -+ if (!st) -+ { -+ if (err) -+ *err = RESAMPLER_ERR_ALLOC_FAILED; -+ return NULL; -+ } - st->initialised = 0; - st->started = 0; - st->in_rate = 0; -@@ -832,9 +838,12 @@ EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, - st->buffer_size = 160; - - /* Per channel data */ -- st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(spx_int32_t)); -- st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(spx_uint32_t)); -- st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(spx_uint32_t)); -+ if (!(st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(spx_int32_t)))) -+ goto fail; -+ if (!(st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(spx_uint32_t)))) -+ goto fail; -+ if (!(st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(spx_uint32_t)))) -+ goto fail; - for (i=0;ilast_sample[i] = 0; -@@ -857,6 +866,12 @@ EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, - *err = filter_err; - - return st; -+ -+fail: -+ if (err) -+ *err = RESAMPLER_ERR_ALLOC_FAILED; -+ speex_resampler_destroy(st); -+ return NULL; - } - - EXPORT void speex_resampler_destroy(SpeexResamplerState *st) diff --git a/media/libspeex_resampler/hugemem.patch b/media/libspeex_resampler/hugemem.patch index 4e1f5baa6..f93b72846 100644 --- a/media/libspeex_resampler/hugemem.patch +++ b/media/libspeex_resampler/hugemem.patch @@ -1,10 +1,7 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/src/resample.c --- a/media/libspeex_resampler/src/resample.c +++ b/media/libspeex_resampler/src/resample.c -@@ -56,16 +56,18 @@ - (e.g. 2/3), and get rid of the rounding operations in the inner loop. - The latter both reduces CPU time and makes the algorithm more SIMD-friendly. - */ +@@ -59,10 +59,12 @@ #ifdef HAVE_CONFIG_H #include "config.h" @@ -14,22 +11,15 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/ + #ifdef OUTSIDE_SPEEX #include - static void *speex_alloc (int size) {return calloc(size,1);} - static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);} - static void speex_free (void *ptr) {free(ptr);} - #include "speex_resampler.h" - #include "arch.h" - #else /* OUTSIDE_SPEEX */ -@@ -632,25 +634,26 @@ static int update_filter(SpeexResamplerS - st->oversample >>= 1; - if (st->oversample < 1) - st->oversample = 1; + static void *speex_alloc(int size) {return calloc(size,1);} + static void *speex_realloc(void *ptr, int size) {return realloc(ptr, size);} + static void speex_free(void *ptr) {free(ptr);} +@@ -646,19 +648,20 @@ } else { /* up-sampling */ st->cutoff = quality_map[st->quality].upsample_bandwidth; } - -- /* Choose the resampling type that requires the least amount of memory */ + -#ifdef RESAMPLE_FULL_SINC_TABLE - use_direct = 1; - if (INT_MAX/sizeof(spx_word16_t)/st->den_rate < st->filt_len) @@ -40,17 +30,14 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/ + when resampling any multiple of 100 to 44100. */ + st->den_rate <= 441 #else + /* Choose the resampling type that requires the least amount of memory */ - use_direct = st->filt_len*st->den_rate <= st->filt_len*st->oversample+8 -+ /* Choose the resampling type that requires the least amount of memory */ +- && INT_MAX/sizeof(spx_word16_t)/st->den_rate >= st->filt_len; + st->filt_len*st->den_rate <= st->filt_len*st->oversample+8 -+#endif - && INT_MAX/sizeof(spx_word16_t)/st->den_rate >= st->filt_len; --#endif + #endif ++ && INT_MAX/sizeof(spx_word16_t)/st->den_rate >= st->filt_len; if (use_direct) { min_sinc_table_length = st->filt_len*st->den_rate; } else { if ((INT_MAX/sizeof(spx_word16_t)-8)/st->oversample < st->filt_len) - goto fail; - - min_sinc_table_length = st->filt_len*st->oversample+8; diff --git a/media/libspeex_resampler/moz.build b/media/libspeex_resampler/moz.build index f59ee5f25..221f63b7c 100644 --- a/media/libspeex_resampler/moz.build +++ b/media/libspeex_resampler/moz.build @@ -1,5 +1,4 @@ # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/media/libspeex_resampler/outside-speex.patch b/media/libspeex_resampler/outside-speex.patch index baa47c666..db309123f 100644 --- a/media/libspeex_resampler/outside-speex.patch +++ b/media/libspeex_resampler/outside-speex.patch @@ -15,7 +15,7 @@ diff --git a/media/libspeex_resampler/src/speex_resampler.h b/media/libspeex_res /********* WARNING: MENTAL SANITY ENDS HERE *************/ - /* If the resampler is defined outside of Speex, we change the symbol names so that + /* If the resampler is defined outside of Speex, we change the symbol names so that there won't be any clash if linking with Speex later on. */ /* #define RANDOM_PREFIX your software name here */ @@ -26,5 +26,5 @@ diff --git a/media/libspeex_resampler/src/speex_resampler.h b/media/libspeex_res #define CAT_PREFIX2(a,b) a ## b #define CAT_PREFIX(a,b) CAT_PREFIX2(a, b) - + #define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init) diff --git a/media/libspeex_resampler/remove-empty-asm-clobber.patch b/media/libspeex_resampler/remove-empty-asm-clobber.patch index ebb6d6698..41c059676 100644 --- a/media/libspeex_resampler/remove-empty-asm-clobber.patch +++ b/media/libspeex_resampler/remove-empty-asm-clobber.patch @@ -11,15 +11,12 @@ resample_neon.c:50: error: expected string literal before ')' token diff --git a/media/libspeex_resampler/src/resample_neon.c b/media/libspeex_resampler/src/resample_neon.c --- a/media/libspeex_resampler/src/resample_neon.c +++ b/media/libspeex_resampler/src/resample_neon.c -@@ -41,18 +41,17 @@ - #include - - #ifdef FIXED_POINT - #ifdef __thumb2__ +@@ -56,12 +56,11 @@ + #elif defined(__thumb2__) static inline int32_t saturate_32bit_to_16bit(int32_t a) { int32_t ret; asm ("ssat %[ret], #16, %[a]" - : [ret] "=&r" (ret) + : [ret] "=r" (ret) - : [a] "r" (a) - : ); + : [a] "r" (a)); @@ -28,6 +25,3 @@ diff --git a/media/libspeex_resampler/src/resample_neon.c b/media/libspeex_resam #else static inline int32_t saturate_32bit_to_16bit(int32_t a) { int32_t ret; - asm ("vmov.s32 d0[0], %[a]\n" - "vqmovn.s32 d0, q0\n" - "vmov.s16 %[ret], d0[0]\n" diff --git a/media/libspeex_resampler/set-rate-overflow-no-return.patch b/media/libspeex_resampler/set-rate-overflow-no-return.patch new file mode 100644 index 000000000..b05c7a428 --- /dev/null +++ b/media/libspeex_resampler/set-rate-overflow-no-return.patch @@ -0,0 +1,19 @@ +diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/src/resample.c +--- a/media/libspeex_resampler/src/resample.c ++++ b/media/libspeex_resampler/src/resample.c +@@ -1145,12 +1145,13 @@ + + if (old_den > 0) + { + for (i=0;inb_channels;i++) + { +- if (multiply_frac(&st->samp_frac_num[i],st->samp_frac_num[i],st->den_rate,old_den) != RESAMPLER_ERR_SUCCESS) +- return RESAMPLER_ERR_OVERFLOW; ++ if (multiply_frac(&st->samp_frac_num[i],st->samp_frac_num[i],st->den_rate,old_den) != RESAMPLER_ERR_SUCCESS) { ++ st->samp_frac_num[i] = st->den_rate-1; ++ } + /* Safety net */ + if (st->samp_frac_num[i] >= st->den_rate) + st->samp_frac_num[i] = st->den_rate-1; + } + } diff --git a/media/libspeex_resampler/simd-detect-runtime.patch b/media/libspeex_resampler/simd-detect-runtime.patch index c8b182dda..1dbcce0e1 100644 --- a/media/libspeex_resampler/simd-detect-runtime.patch +++ b/media/libspeex_resampler/simd-detect-runtime.patch @@ -1,35 +1,26 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/src/resample.c --- a/media/libspeex_resampler/src/resample.c +++ b/media/libspeex_resampler/src/resample.c -@@ -92,23 +92,17 @@ static void speex_free (void *ptr) {free - - #define IMAX(a,b) ((a) > (b) ? (a) : (b)) - #define IMIN(a,b) ((a) < (b) ? (a) : (b)) +@@ -94,17 +94,11 @@ - #ifndef NULL - #define NULL 0 + #ifndef UINT32_MAX + #define UINT32_MAX 4294967295U #endif --#ifdef _USE_SSE +-#ifdef USE_SSE -#include "resample_sse.h" -#endif - --#ifdef _USE_NEON +-#ifdef USE_NEON -#include "resample_neon.h" -#endif +#include "simd_detect.h" - /* Numer of elements to allocate on the stack */ + /* Number of elements to allocate on the stack */ #ifdef VAR_ARRAYS #define FIXED_STACK_ALLOC 8192 #else - #define FIXED_STACK_ALLOC 1024 - #endif - -@@ -344,17 +338,19 @@ static int resampler_basic_direct_single - const spx_uint32_t den_rate = st->den_rate; - spx_word32_t sum; - +@@ -344,11 +338,13 @@ while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) { const spx_word16_t *sinct = & sinc_table[samp_frac_num*N]; @@ -44,13 +35,7 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/ for(j=0;j= den_rate) - { - samp_frac_num -= den_rate; -@@ -402,29 +400,33 @@ static int resampler_basic_direct_double - const spx_uint32_t den_rate = st->den_rate; - double sum; - +@@ -402,23 +400,27 @@ while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) { const spx_word16_t *sinct = & sinc_table[samp_frac_num*N]; @@ -102,13 +81,7 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/ out[out_stride * out_sample++] = PSHR32(sum, 15); last_sample += int_advance; samp_frac_num += frac_advance; - if (samp_frac_num >= den_rate) - { - samp_frac_num -= den_rate; -@@ -458,34 +460,38 @@ static int resampler_basic_interpolate_s - #ifdef FIXED_POINT - const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate); - #else +@@ -458,11 +460,13 @@ const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; #endif spx_word16_t interp[4]; @@ -123,14 +96,11 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/ for(j=0;jsinc_table[4+(j+1)*st->oversample-offset-2]); - accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); - accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); - accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); +@@ -473,13 +477,15 @@ } cubic_coef(frac, interp); - sum = MULT16_32_Q15(interp[0],SHR32(accum[0], 1)) + MULT16_32_Q15(interp[1],SHR32(accum[1], 1)) + MULT16_32_Q15(interp[2],SHR32(accum[2], 1)) + MULT16_32_Q15(interp[3],SHR32(accum[3], 1)); + sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); sum = SATURATE32PSHR(sum, 15, 32767); -#else +#ifdef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE @@ -139,17 +109,11 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/ sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); + } #endif - + out[out_stride * out_sample++] = sum; last_sample += int_advance; samp_frac_num += frac_advance; - if (samp_frac_num >= den_rate) - { - samp_frac_num -= den_rate; -@@ -521,33 +527,37 @@ static int resampler_basic_interpolate_d - #ifdef FIXED_POINT - const spx_word16_t frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate); - #else +@@ -521,11 +527,13 @@ const spx_word16_t frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; #endif spx_word16_t interp[4]; @@ -164,9 +128,7 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/ for(j=0;jsinc_table[4+(j+1)*st->oversample-offset-2]); - accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); - accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); +@@ -535,13 +543,15 @@ accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); } @@ -179,20 +141,14 @@ diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/ sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); + } #endif - + out[out_stride * out_sample++] = PSHR32(sum,15); last_sample += int_advance; samp_frac_num += frac_advance; - if (samp_frac_num >= den_rate) - { - samp_frac_num -= den_rate; diff --git a/media/libspeex_resampler/src/resample_neon.c b/media/libspeex_resampler/src/resample_neon.c --- a/media/libspeex_resampler/src/resample_neon.c +++ b/media/libspeex_resampler/src/resample_neon.c -@@ -31,16 +31,18 @@ - 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 +@@ -34,10 +34,12 @@ 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. @@ -200,23 +156,17 @@ diff --git a/media/libspeex_resampler/src/resample_neon.c b/media/libspeex_resam +#include "simd_detect.h" + - #include + #include #ifdef FIXED_POINT - #ifdef __thumb2__ + #if defined(__aarch64__) static inline int32_t saturate_32bit_to_16bit(int32_t a) { - int32_t ret; - asm ("ssat %[ret], #16, %[a]" - : [ret] "=&r" (ret) -@@ -60,17 +62,17 @@ static inline int32_t saturate_32bit_to_ - return ret; - } - #endif - #undef WORD2INT +@@ -76,11 +78,11 @@ #define WORD2INT(x) (saturate_32bit_to_16bit(x)) #define OVERRIDE_INNER_PRODUCT_SINGLE - /* Only works when len % 4 == 0 */ + /* Only works when len % 4 == 0 and len >= 4 */ + #if defined(__aarch64__) -static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len) +int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len) { @@ -224,18 +174,38 @@ diff --git a/media/libspeex_resampler/src/resample_neon.c b/media/libspeex_resam uint32_t remainder = len % 16; len = len - remainder; - asm volatile (" cmp %[len], #0\n" - " bne 1f\n" - " vld1.16 {d16}, [%[b]]!\n" -@@ -134,17 +136,17 @@ static inline int32_t saturate_float_to_ - : "q0"); +@@ -131,11 +133,11 @@ + : "cc", "v0", + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23"); return ret; } - #undef WORD2INT + #else +-static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len) ++int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len) + { + int32_t ret; + uint32_t remainder = len % 16; + len = len - remainder; + +@@ -221,11 +223,11 @@ #define WORD2INT(x) (saturate_float_to_16bit(x)) #define OVERRIDE_INNER_PRODUCT_SINGLE - /* Only works when len % 4 == 0 */ + /* Only works when len % 4 == 0 and len >= 4 */ + #if defined(__aarch64__) +-static inline float inner_product_single(const float *a, const float *b, unsigned int len) ++float inner_product_single(const float *a, const float *b, unsigned int len) + { + float ret; + uint32_t remainder = len % 16; + len = len - remainder; + +@@ -276,11 +278,11 @@ + : "cc", "v1", "v2", "v3", "v4", + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23"); + return ret; + } + #else -static inline float inner_product_single(const float *a, const float *b, unsigned int len) +float inner_product_single(const float *a, const float *b, unsigned int len) { @@ -243,9 +213,6 @@ diff --git a/media/libspeex_resampler/src/resample_neon.c b/media/libspeex_resam uint32_t remainder = len % 16; len = len - remainder; - asm volatile (" cmp %[len], #0\n" - " bne 1f\n" - " vld1.32 {q4}, [%[b]]!\n" diff --git a/media/libspeex_resampler/src/resample_sse.c b/media/libspeex_resampler/src/resample_sse.c --- a/media/libspeex_resampler/src/resample_sse.c +++ b/media/libspeex_resampler/src/resample_sse.c @@ -296,7 +263,7 @@ diff --git a/media/libspeex_resampler/src/resample_sse.c b/media/libspeex_resamp return ret; } - #ifdef _USE_SSE2 + #ifdef USE_SSE2 #include #define OVERRIDE_INNER_PRODUCT_DOUBLE diff --git a/media/libspeex_resampler/src/arch.h b/media/libspeex_resampler/src/arch.h index 535d30830..1cac3d9c8 100644 --- a/media/libspeex_resampler/src/arch.h +++ b/media/libspeex_resampler/src/arch.h @@ -7,18 +7,18 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + - Neither the name of the Xiph.org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS 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 @@ -41,10 +41,10 @@ #ifdef FLOATING_POINT #error You cannot compile as floating point and fixed point at the same time #endif -#ifdef _USE_SSE +#ifdef USE_SSE #error SSE is only for floating-point #endif -#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM)) +#if defined(ARM4_ASM) + defined(ARM5E_ASM) + defined(BFIN_ASM) > 1 #error Make up your mind. What CPU do you have? #endif #ifdef VORBIS_PSYCHO @@ -56,10 +56,10 @@ #ifndef FLOATING_POINT #error You now need to define either FIXED_POINT or FLOATING_POINT #endif -#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) +#if defined(ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) #error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions? #endif -#ifdef FIXED_POINT_DEBUG +#ifdef FIXED_DEBUG #error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?" #endif @@ -101,6 +101,8 @@ typedef spx_word32_t spx_sig_t; #define SIG_SHIFT 14 #define GAIN_SHIFT 6 +#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x))) + #define VERY_SMALL 0 #define VERY_LARGE32 ((spx_word32_t)2147483647) #define VERY_LARGE16 ((spx_word16_t)32767) @@ -115,9 +117,9 @@ typedef spx_word32_t spx_sig_t; #ifdef ARM5E_ASM #include "fixed_arm5e.h" -#elif defined (ARM4_ASM) +#elif defined(ARM4_ASM) #include "fixed_arm4.h" -#elif defined (BFIN_ASM) +#elif defined(BFIN_ASM) #include "fixed_bfin.h" #endif @@ -175,16 +177,13 @@ typedef float spx_word32_t; #define ADD32(a,b) ((a)+(b)) #define SUB32(a,b) ((a)-(b)) #define MULT16_16_16(a,b) ((a)*(b)) +#define MULT16_32_32(a,b) ((a)*(b)) #define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b)) #define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b)) -#define MULT16_32_Q11(a,b) ((a)*(b)) -#define MULT16_32_Q13(a,b) ((a)*(b)) -#define MULT16_32_Q14(a,b) ((a)*(b)) #define MULT16_32_Q15(a,b) ((a)*(b)) #define MULT16_32_P15(a,b) ((a)*(b)) -#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b)) #define MAC16_32_Q15(c,a,b) ((c)+(a)*(b)) #define MAC16_16_Q11(c,a,b) ((c)+(a)*(b)) @@ -203,18 +202,19 @@ typedef float spx_word32_t; #define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) #define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) - +#define WORD2INT(x) ((x) < -32767.5f ? -32768 : \ + ((x) > 32766.5f ? 32767 : (spx_int16_t)floor(.5 + (x)))) #endif -#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) +#if defined(CONFIG_TI_C54X) || defined(CONFIG_TI_C55X) /* 2 on TI C5x DSP */ -#define BYTES_PER_CHAR 2 +#define BYTES_PER_CHAR 2 #define BITS_PER_CHAR 16 #define LOG2_BITS_PER_CHAR 4 -#else +#else #define BYTES_PER_CHAR 1 #define BITS_PER_CHAR 8 diff --git a/media/libspeex_resampler/src/fixed_generic.h b/media/libspeex_resampler/src/fixed_generic.h index 0e012e9ab..09366c36c 100644 --- a/media/libspeex_resampler/src/fixed_generic.h +++ b/media/libspeex_resampler/src/fixed_generic.h @@ -7,18 +7,18 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + - Neither the name of the Xiph.org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS 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 @@ -69,22 +69,18 @@ /* result fits in 16 bits */ -#define MULT16_16_16(a,b) ((((spx_word16_t)(a))*((spx_word16_t)(b)))) +#define MULT16_16_16(a,b) (((spx_word16_t)(a))*((spx_word16_t)(b))) +/* result fits in 32 bits */ +#define MULT16_32_32(a,b) (((spx_word16_t)(a))*((spx_word32_t)(b))) /* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */ #define MULT16_16(a,b) (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b))) #define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b)))) -#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12)) -#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13)) -#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14)) -#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)) -#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))) - -#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15)) -#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)) -#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) +#define MULT16_32_P15(a,b) ADD32(MULT16_32_32(a,SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15)) +#define MULT16_32_Q15(a,b) ADD32(MULT16_32_32(a,SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)) +#define MAC16_32_Q15(c,a,b) ADD32(c,MULT16_32_Q15(a,b)) #define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11))) diff --git a/media/libspeex_resampler/src/moz.build b/media/libspeex_resampler/src/moz.build index b5b5a8a7a..9e497df23 100644 --- a/media/libspeex_resampler/src/moz.build +++ b/media/libspeex_resampler/src/moz.build @@ -1,5 +1,4 @@ # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -36,20 +35,20 @@ else: # Only use SSE code when using floating point samples, and on x86 if CONFIG['INTEL_ARCHITECTURE'] and not CONFIG['MOZ_SAMPLE_TYPE_S16']: - DEFINES['_USE_SSE'] = True - DEFINES['_USE_SSE2'] = True + DEFINES['USE_SSE'] = True + DEFINES['USE_SSE2'] = True SOURCES += [ 'resample_sse.c' ] SOURCES['resample_sse.c'].flags += CONFIG['SSE2_FLAGS'] if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']: - DEFINES['_USE_NEON'] = True + DEFINES['USE_NEON'] = True SOURCES += [ 'resample_neon.c' ] SOURCES['resample_neon.c'].flags += CONFIG['NEON_FLAGS'] # Suppress warnings in third-party code. -if CONFIG['GNU_CC']: +if CONFIG['CC_TYPE'] in ('clang', 'gcc'): CFLAGS += ['-Wno-sign-compare'] diff --git a/media/libspeex_resampler/src/resample.c b/media/libspeex_resampler/src/resample.c index 7c6ef1287..0ee911690 100644 --- a/media/libspeex_resampler/src/resample.c +++ b/media/libspeex_resampler/src/resample.c @@ -1,6 +1,6 @@ /* Copyright (C) 2007-2008 Jean-Marc Valin Copyright (C) 2008 Thorvald Natvig - + File: resample.c Arbitrary resampling code @@ -38,22 +38,22 @@ - Low memory requirement - Good *perceptual* quality (and not best SNR) - Warning: This resampler is relatively new. Although I think I got rid of + Warning: This resampler is relatively new. Although I think I got rid of all the major bugs and I don't expect the API to change anymore, there may be something I've missed. So use with caution. This algorithm is based on this original resampling algorithm: Smith, Julius O. Digital Audio Resampling Home Page - Center for Computer Research in Music and Acoustics (CCRMA), + Center for Computer Research in Music and Acoustics (CCRMA), Stanford University, 2007. - Web published at http://www-ccrma.stanford.edu/~jos/resample/. + Web published at https://ccrma.stanford.edu/~jos/resample/. - There is one main difference, though. This resampler uses cubic + There is one main difference, though. This resampler uses cubic interpolation instead of linear interpolation in the above paper. This makes the table much smaller and makes it possible to compute that table - on a per-stream basis. In turn, being able to tweak the table for each - stream makes it possible to both reduce complexity on simple ratios - (e.g. 2/3), and get rid of the rounding operations in the inner loop. + on a per-stream basis. In turn, being able to tweak the table for each + stream makes it possible to both reduce complexity on simple ratios + (e.g. 2/3), and get rid of the rounding operations in the inner loop. The latter both reduces CPU time and makes the algorithm more SIMD-friendly. */ @@ -65,9 +65,12 @@ #ifdef OUTSIDE_SPEEX #include -static void *speex_alloc (int size) {return calloc(size,1);} -static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);} -static void speex_free (void *ptr) {free(ptr);} +static void *speex_alloc(int size) {return calloc(size,1);} +static void *speex_realloc(void *ptr, int size) {return realloc(ptr, size);} +static void speex_free(void *ptr) {free(ptr);} +#ifndef EXPORT +#define EXPORT +#endif #include "speex_resampler.h" #include "arch.h" #else /* OUTSIDE_SPEEX */ @@ -77,7 +80,6 @@ static void speex_free (void *ptr) {free(ptr);} #include "os_support.h" #endif /* OUTSIDE_SPEEX */ -#include "stack_alloc.h" #include #include @@ -85,12 +87,6 @@ static void speex_free (void *ptr) {free(ptr);} #define M_PI 3.14159265358979323846 #endif -#ifdef FIXED_POINT -#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x))) -#else -#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x)))) -#endif - #define IMAX(a,b) ((a) > (b) ? (a) : (b)) #define IMIN(a,b) ((a) < (b) ? (a) : (b)) @@ -99,12 +95,12 @@ static void speex_free (void *ptr) {free(ptr);} #endif #ifndef UINT32_MAX -#define UINT32_MAX 4294967296U +#define UINT32_MAX 4294967295U #endif #include "simd_detect.h" -/* Numer of elements to allocate on the stack */ +/* Number of elements to allocate on the stack */ #ifdef VAR_ARRAYS #define FIXED_STACK_ALLOC 8192 #else @@ -118,7 +114,7 @@ struct SpeexResamplerState_ { spx_uint32_t out_rate; spx_uint32_t num_rate; spx_uint32_t den_rate; - + int quality; spx_uint32_t nb_channels; spx_uint32_t filt_len; @@ -130,17 +126,17 @@ struct SpeexResamplerState_ { spx_uint32_t oversample; int initialised; int started; - + /* These are per-channel */ spx_int32_t *last_sample; spx_uint32_t *samp_frac_num; spx_uint32_t *magic_samples; - + spx_word16_t *mem; spx_word16_t *sinc_table; spx_uint32_t sinc_table_length; resampler_basic_func resampler_ptr; - + int in_stride; int out_stride; } ; @@ -182,7 +178,7 @@ static const double kaiser8_table[36] = { 0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758, 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490, 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000}; - + static const double kaiser6_table[36] = { 0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003, 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565, @@ -195,17 +191,15 @@ struct FuncDef { const double *table; int oversample; }; - -static const struct FuncDef _KAISER12 = {kaiser12_table, 64}; -#define KAISER12 (&_KAISER12) -/*static struct FuncDef _KAISER12 = {kaiser12_table, 32}; -#define KAISER12 (&_KAISER12)*/ -static const struct FuncDef _KAISER10 = {kaiser10_table, 32}; -#define KAISER10 (&_KAISER10) -static const struct FuncDef _KAISER8 = {kaiser8_table, 32}; -#define KAISER8 (&_KAISER8) -static const struct FuncDef _KAISER6 = {kaiser6_table, 32}; -#define KAISER6 (&_KAISER6) + +static const struct FuncDef kaiser12_funcdef = {kaiser12_table, 64}; +#define KAISER12 (&kaiser12_funcdef) +static const struct FuncDef kaiser10_funcdef = {kaiser10_table, 32}; +#define KAISER10 (&kaiser10_funcdef) +static const struct FuncDef kaiser8_funcdef = {kaiser8_table, 32}; +#define KAISER8 (&kaiser8_funcdef) +static const struct FuncDef kaiser6_funcdef = {kaiser6_table, 32}; +#define KAISER6 (&kaiser6_funcdef) struct QualityMapping { int base_length; @@ -217,7 +211,7 @@ struct QualityMapping { /* This table maps conversion quality to internal parameters. There are two - reasons that explain why the up-sampling bandwidth is larger than the + reasons that explain why the up-sampling bandwidth is larger than the down-sampling bandwidth: 1) When up-sampling, we can assume that the spectrum is already attenuated close to the Nyquist rate (from an A/D or a previous resampling filter) @@ -243,7 +237,7 @@ static double compute_func(float x, const struct FuncDef *func) { float y, frac; double interp[4]; - int ind; + int ind; y = x*func->oversample; ind = (int)floor(y); frac = (y-ind); @@ -254,7 +248,7 @@ static double compute_func(float x, const struct FuncDef *func) interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac); /* Just to make sure we don't have rounding problems */ interp[1] = 1.f-interp[3]-interp[2]-interp[0]; - + /*sum = frac*accum[1] + (1-frac)*accum[2];*/ return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3]; } @@ -485,7 +479,7 @@ static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint3 } cubic_coef(frac, interp); - sum = MULT16_32_Q15(interp[0],SHR32(accum[0], 1)) + MULT16_32_Q15(interp[1],SHR32(accum[1], 1)) + MULT16_32_Q15(interp[2],SHR32(accum[2], 1)) + MULT16_32_Q15(interp[3],SHR32(accum[3], 1)); + sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); sum = SATURATE32PSHR(sum, 15, 32767); #ifdef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE } else { @@ -493,7 +487,7 @@ static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint3 sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); } #endif - + out[out_stride * out_sample++] = sum; last_sample += int_advance; samp_frac_num += frac_advance; @@ -559,7 +553,7 @@ static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint3 sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp); } #endif - + out[out_stride * out_sample++] = PSHR32(sum,15); last_sample += int_advance; samp_frac_num += frac_advance; @@ -590,6 +584,7 @@ static int resampler_basic_zero(SpeexResamplerState *st, spx_uint32_t channel_in const int frac_advance = st->frac_advance; const spx_uint32_t den_rate = st->den_rate; + (void)in; while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) { out[out_stride * out_sample++] = 0; @@ -607,20 +602,16 @@ static int resampler_basic_zero(SpeexResamplerState *st, spx_uint32_t channel_in return out_sample; } -static int _muldiv_safe(spx_uint32_t value, spx_uint32_t mul, spx_uint32_t div) +static int multiply_frac(spx_uint32_t *result, spx_uint32_t value, spx_uint32_t num, spx_uint32_t den) { - /* TODO: Could be simplified with 64 bits operation. */ - spx_uint32_t major = value / div; - spx_uint32_t remainder = value % div; - return remainder <= UINT32_MAX / mul && major <= UINT32_MAX / mul && - major * mul <= UINT32_MAX - remainder * mul / div; -} - -static spx_uint32_t _muldiv(spx_uint32_t value, spx_uint32_t mul, spx_uint32_t div) -{ - spx_uint32_t major = value / div; - spx_uint32_t remainder = value % div; - return remainder * mul / div + major * mul; + spx_uint32_t major = value / den; + spx_uint32_t remain = value % den; + /* TODO: Could use 64 bits operation to check for overflow. But only guaranteed in C99+ */ + if (remain > UINT32_MAX / num || major > UINT32_MAX / num + || major * num > UINT32_MAX - remain * num / den) + return RESAMPLER_ERR_OVERFLOW; + *result = remain * num / den + major * num; + return RESAMPLER_ERR_SUCCESS; } static int update_filter(SpeexResamplerState *st) @@ -635,14 +626,13 @@ static int update_filter(SpeexResamplerState *st) st->frac_advance = st->num_rate%st->den_rate; st->oversample = quality_map[st->quality].oversample; st->filt_len = quality_map[st->quality].base_length; - + if (st->num_rate > st->den_rate) { /* down-sampling */ st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate; - if (!_muldiv_safe(st->filt_len,st->num_rate,st->den_rate)) + if (multiply_frac(&st->filt_len,st->filt_len,st->num_rate,st->den_rate) != RESAMPLER_ERR_SUCCESS) goto fail; - st->filt_len = _muldiv(st->filt_len,st->num_rate,st->den_rate); /* Round up to make sure we have a multiple of 8 for SSE */ st->filt_len = ((st->filt_len-1)&(~0x7))+8; if (2*st->den_rate < st->num_rate) @@ -659,14 +649,14 @@ static int update_filter(SpeexResamplerState *st) /* up-sampling */ st->cutoff = quality_map[st->quality].upsample_bandwidth; } - + use_direct = #ifdef RESAMPLE_HUGEMEM /* Choose the direct resampler, even with higher initialization costs, when resampling any multiple of 100 to 44100. */ st->den_rate <= 441 #else - /* Choose the resampling type that requires the least amount of memory */ + /* Choose the resampling type that requires the least amount of memory */ st->filt_len*st->den_rate <= st->filt_len*st->oversample+8 #endif && INT_MAX/sizeof(spx_word16_t)/st->den_rate >= st->filt_len; @@ -756,16 +746,18 @@ static int update_filter(SpeexResamplerState *st) { spx_uint32_t j; spx_uint32_t olen = old_length; + spx_uint32_t start = i*st->mem_alloc_size; + spx_uint32_t magic_samples = st->magic_samples[i]; /*if (st->magic_samples[i])*/ { /* Try and remove the magic samples as if nothing had happened */ - + /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */ - olen = old_length + 2*st->magic_samples[i]; - for (j=old_length-1+st->magic_samples[i];j--;) - st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j]; - for (j=0;jmagic_samples[i];j++) - st->mem[i*st->mem_alloc_size+j] = 0; + olen = old_length + 2*magic_samples; + for (j=old_length-1+magic_samples;j--;) + st->mem[start+j+magic_samples] = st->mem[i*old_alloc_size+j]; + for (j=0;jmem[start+j] = 0; st->magic_samples[i] = 0; } if (st->filt_len > olen) @@ -773,17 +765,18 @@ static int update_filter(SpeexResamplerState *st) /* If the new filter length is still bigger than the "augmented" length */ /* Copy data going backward */ for (j=0;jmem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)]; + st->mem[start+(st->filt_len-2-j)] = st->mem[start+(olen-2-j)]; /* Then put zeros for lack of anything better */ for (;jfilt_len-1;j++) - st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0; + st->mem[start+(st->filt_len-2-j)] = 0; /* Adjust last_sample */ st->last_sample[i] += (st->filt_len - olen)/2; } else { /* Put back some of the magic! */ - st->magic_samples[i] = (olen - st->filt_len)/2; - for (j=0;jfilt_len-1+st->magic_samples[i];j++) - st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; + magic_samples = (olen - st->filt_len)/2; + for (j=0;jfilt_len-1+magic_samples;j++) + st->mem[start+j] = st->mem[start+j+magic_samples]; + st->magic_samples[i] = magic_samples; } } } else if (st->filt_len < old_length) @@ -821,11 +814,10 @@ EXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_u EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) { - spx_uint32_t i; SpeexResamplerState *st; int filter_err; - if (quality > 10 || quality < 0) + if (nb_channels == 0 || ratio_num == 0 || ratio_den == 0 || quality > 10 || quality < 0) { if (err) *err = RESAMPLER_ERR_INVALID_ARG; @@ -850,14 +842,14 @@ EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, st->filt_len = 0; st->mem = 0; st->resampler_ptr = 0; - + st->cutoff = 1.f; st->nb_channels = nb_channels; st->in_stride = 1; st->out_stride = 1; - + st->buffer_size = 160; - + /* Per channel data */ if (!(st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(spx_int32_t)))) goto fail; @@ -865,12 +857,6 @@ EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, goto fail; if (!(st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(spx_uint32_t)))) goto fail; - for (i=0;ilast_sample[i] = 0; - st->magic_samples[i] = 0; - st->samp_frac_num[i] = 0; - } speex_resampler_set_quality(st, quality); speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate); @@ -912,17 +898,17 @@ static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t int out_sample = 0; spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; spx_uint32_t ilen; - + st->started = 1; - + /* Call the right resampler through the function ptr */ out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len); - + if (st->last_sample[channel_index] < (spx_int32_t)*in_len) *in_len = st->last_sample[channel_index]; *out_len = out_sample; st->last_sample[channel_index] -= *in_len; - + ilen = *in_len; for(j=0;jmagic_samples[channel_index]; spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size; const int N = st->filt_len; - + speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len); st->magic_samples[channel_index] -= tmp_in_len; - + /* If we couldn't process all "magic" input samples, save the rest for next time */ if (st->magic_samples[channel_index]) { @@ -965,13 +951,13 @@ EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t c const spx_uint32_t xlen = st->mem_alloc_size - filt_offs; const int istride = st->in_stride; - if (st->magic_samples[channel_index]) + if (st->magic_samples[channel_index]) olen -= speex_resampler_magic(st, channel_index, &out, olen); if (! st->magic_samples[channel_index]) { while (ilen && olen) { spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen; spx_uint32_t ochunk = olen; - + if (in) { for(j=0;jmem_alloc_size - (st->filt_len - 1); #ifdef VAR_ARRAYS const unsigned int ylen = (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC; - VARDECL(spx_word16_t *ystack); - ALLOC(ystack, ylen, spx_word16_t); + spx_word16_t ystack[ylen]; #else const unsigned int ylen = FIXED_STACK_ALLOC; spx_word16_t ystack[FIXED_STACK_ALLOC]; #endif st->out_stride = 1; - + while (ilen && olen) { spx_word16_t *y = ystack; spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen; @@ -1052,7 +1037,7 @@ EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t cha #else out[j*ostride_save] = WORD2INT(ystack[j]); #endif - + ilen -= ichunk; olen -= ochunk; out += (ochunk+omagic) * ostride_save; @@ -1088,7 +1073,7 @@ EXPORT int speex_resampler_process_interleaved_float(SpeexResamplerState *st, co st->out_stride = ostride_save; return st->resampler_ptr == resampler_basic_zero ? RESAMPLER_ERR_ALLOC_FAILED : RESAMPLER_ERR_SUCCESS; } - + 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) { spx_uint32_t i; @@ -1123,44 +1108,54 @@ EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_r *out_rate = st->out_rate; } +static inline spx_uint32_t compute_gcd(spx_uint32_t a, spx_uint32_t b) +{ + while (b != 0) + { + spx_uint32_t temp = a; + + a = b; + b = temp % b; + } + return a; +} + EXPORT int 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) { spx_uint32_t fact; spx_uint32_t old_den; spx_uint32_t i; + + if (ratio_num == 0 || ratio_den == 0) + return RESAMPLER_ERR_INVALID_ARG; + if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den) return RESAMPLER_ERR_SUCCESS; - + old_den = st->den_rate; st->in_rate = in_rate; st->out_rate = out_rate; st->num_rate = ratio_num; st->den_rate = ratio_den; - /* FIXME: This is terribly inefficient, but who cares (at least for now)? */ - for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++) - { - while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0)) - { - st->num_rate /= fact; - st->den_rate /= fact; - } - } - + + fact = compute_gcd(st->num_rate, st->den_rate); + + st->num_rate /= fact; + st->den_rate /= fact; + if (old_den > 0) { for (i=0;inb_channels;i++) { - if (!_muldiv_safe(st->samp_frac_num[i],st->den_rate,old_den)) - { - st->samp_frac_num[i] = st->den_rate-1; + if (multiply_frac(&st->samp_frac_num[i],st->samp_frac_num[i],st->den_rate,old_den) != RESAMPLER_ERR_SUCCESS) { + st->samp_frac_num[i] = st->den_rate-1; } - st->samp_frac_num[i]= _muldiv(st->samp_frac_num[i],st->den_rate,old_den); /* Safety net */ if (st->samp_frac_num[i] >= st->den_rate) st->samp_frac_num[i] = st->den_rate-1; } } - + if (st->initialised) return update_filter(st); return RESAMPLER_ERR_SUCCESS; diff --git a/media/libspeex_resampler/src/resample_neon.c b/media/libspeex_resampler/src/resample_neon.c index fa44519d8..c04b267cc 100644 --- a/media/libspeex_resampler/src/resample_neon.c +++ b/media/libspeex_resampler/src/resample_neon.c @@ -38,14 +38,26 @@ #include "simd_detect.h" -#include +#include #ifdef FIXED_POINT -#ifdef __thumb2__ +#if defined(__aarch64__) +static inline int32_t saturate_32bit_to_16bit(int32_t a) { + int32_t ret; + asm ("fmov s0, %w[a]\n" + "sqxtn h0, s0\n" + "sxtl v0.4s, v0.4h\n" + "fmov %w[ret], s0\n" + : [ret] "=r" (ret) + : [a] "r" (a) + : "v0" ); + return ret; +} +#elif defined(__thumb2__) static inline int32_t saturate_32bit_to_16bit(int32_t a) { int32_t ret; asm ("ssat %[ret], #16, %[a]" - : [ret] "=&r" (ret) + : [ret] "=r" (ret) : [a] "r" (a)); return ret; } @@ -55,7 +67,7 @@ static inline int32_t saturate_32bit_to_16bit(int32_t a) { asm ("vmov.s32 d0[0], %[a]\n" "vqmovn.s32 d0, q0\n" "vmov.s16 %[ret], d0[0]\n" - : [ret] "=&r" (ret) + : [ret] "=r" (ret) : [a] "r" (a) : "q0"); return ret; @@ -65,7 +77,63 @@ static inline int32_t saturate_32bit_to_16bit(int32_t a) { #define WORD2INT(x) (saturate_32bit_to_16bit(x)) #define OVERRIDE_INNER_PRODUCT_SINGLE -/* Only works when len % 4 == 0 */ +/* Only works when len % 4 == 0 and len >= 4 */ +#if defined(__aarch64__) +int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len) +{ + int32_t ret; + uint32_t remainder = len % 16; + len = len - remainder; + + asm volatile (" cmp %w[len], #0\n" + " b.ne 1f\n" + " ld1 {v16.4h}, [%[b]], #8\n" + " ld1 {v20.4h}, [%[a]], #8\n" + " subs %w[remainder], %w[remainder], #4\n" + " smull v0.4s, v16.4h, v20.4h\n" + " b.ne 4f\n" + " b 5f\n" + "1:" + " ld1 {v16.4h, v17.4h, v18.4h, v19.4h}, [%[b]], #32\n" + " ld1 {v20.4h, v21.4h, v22.4h, v23.4h}, [%[a]], #32\n" + " subs %w[len], %w[len], #16\n" + " smull v0.4s, v16.4h, v20.4h\n" + " smlal v0.4s, v17.4h, v21.4h\n" + " smlal v0.4s, v18.4h, v22.4h\n" + " smlal v0.4s, v19.4h, v23.4h\n" + " b.eq 3f\n" + "2:" + " ld1 {v16.4h, v17.4h, v18.4h, v19.4h}, [%[b]], #32\n" + " ld1 {v20.4h, v21.4h, v22.4h, v23.4h}, [%[a]], #32\n" + " subs %w[len], %w[len], #16\n" + " smlal v0.4s, v16.4h, v20.4h\n" + " smlal v0.4s, v17.4h, v21.4h\n" + " smlal v0.4s, v18.4h, v22.4h\n" + " smlal v0.4s, v19.4h, v23.4h\n" + " b.ne 2b\n" + "3:" + " cmp %w[remainder], #0\n" + " b.eq 5f\n" + "4:" + " ld1 {v18.4h}, [%[b]], #8\n" + " ld1 {v22.4h}, [%[a]], #8\n" + " subs %w[remainder], %w[remainder], #4\n" + " smlal v0.4s, v18.4h, v22.4h\n" + " b.ne 4b\n" + "5:" + " saddlv d0, v0.4s\n" + " sqxtn s0, d0\n" + " sqrshrn h0, s0, #15\n" + " sxtl v0.4s, v0.4h\n" + " fmov %w[ret], s0\n" + : [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b), + [len] "+r" (len), [remainder] "+r" (remainder) + : + : "cc", "v0", + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23"); + return ret; +} +#else int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len) { int32_t ret; @@ -113,33 +181,104 @@ int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int le " vqmovn.s64 d0, q0\n" " vqrshrn.s32 d0, q0, #15\n" " vmov.s16 %[ret], d0[0]\n" - : [ret] "=&r" (ret), [a] "+r" (a), [b] "+r" (b), + : [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b), [len] "+r" (len), [remainder] "+r" (remainder) : : "cc", "q0", - "d16", "d17", "d18", "d19", - "d20", "d21", "d22", "d23"); + "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23"); return ret; } -#elif defined(FLOATING_POINT) +#endif // !defined(__aarch64__) +#elif defined(FLOATING_POINT) +#if defined(__aarch64__) +static inline int32_t saturate_float_to_16bit(float a) { + int32_t ret; + asm ("fcvtas s1, %s[a]\n" + "sqxtn h1, s1\n" + "sxtl v1.4s, v1.4h\n" + "fmov %w[ret], s1\n" + : [ret] "=r" (ret) + : [a] "w" (a) + : "v1"); + return ret; +} +#else static inline int32_t saturate_float_to_16bit(float a) { int32_t ret; asm ("vmov.f32 d0[0], %[a]\n" "vcvt.s32.f32 d0, d0, #15\n" "vqrshrn.s32 d0, q0, #15\n" "vmov.s16 %[ret], d0[0]\n" - : [ret] "=&r" (ret) + : [ret] "=r" (ret) : [a] "r" (a) : "q0"); return ret; } +#endif + #undef WORD2INT #define WORD2INT(x) (saturate_float_to_16bit(x)) #define OVERRIDE_INNER_PRODUCT_SINGLE -/* Only works when len % 4 == 0 */ +/* Only works when len % 4 == 0 and len >= 4 */ +#if defined(__aarch64__) +float inner_product_single(const float *a, const float *b, unsigned int len) +{ + float ret; + uint32_t remainder = len % 16; + len = len - remainder; + + asm volatile (" cmp %w[len], #0\n" + " b.ne 1f\n" + " ld1 {v16.4s}, [%[b]], #16\n" + " ld1 {v20.4s}, [%[a]], #16\n" + " subs %w[remainder], %w[remainder], #4\n" + " fmul v1.4s, v16.4s, v20.4s\n" + " b.ne 4f\n" + " b 5f\n" + "1:" + " ld1 {v16.4s, v17.4s, v18.4s, v19.4s}, [%[b]], #64\n" + " ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [%[a]], #64\n" + " subs %w[len], %w[len], #16\n" + " fmul v1.4s, v16.4s, v20.4s\n" + " fmul v2.4s, v17.4s, v21.4s\n" + " fmul v3.4s, v18.4s, v22.4s\n" + " fmul v4.4s, v19.4s, v23.4s\n" + " b.eq 3f\n" + "2:" + " ld1 {v16.4s, v17.4s, v18.4s, v19.4s}, [%[b]], #64\n" + " ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [%[a]], #64\n" + " subs %w[len], %w[len], #16\n" + " fmla v1.4s, v16.4s, v20.4s\n" + " fmla v2.4s, v17.4s, v21.4s\n" + " fmla v3.4s, v18.4s, v22.4s\n" + " fmla v4.4s, v19.4s, v23.4s\n" + " b.ne 2b\n" + "3:" + " fadd v16.4s, v1.4s, v2.4s\n" + " fadd v17.4s, v3.4s, v4.4s\n" + " cmp %w[remainder], #0\n" + " fadd v1.4s, v16.4s, v17.4s\n" + " b.eq 5f\n" + "4:" + " ld1 {v18.4s}, [%[b]], #16\n" + " ld1 {v22.4s}, [%[a]], #16\n" + " subs %w[remainder], %w[remainder], #4\n" + " fmla v1.4s, v18.4s, v22.4s\n" + " b.ne 4b\n" + "5:" + " faddp v1.4s, v1.4s, v1.4s\n" + " faddp %[ret].4s, v1.4s, v1.4s\n" + : [ret] "=w" (ret), [a] "+r" (a), [b] "+r" (b), + [len] "+r" (len), [remainder] "+r" (remainder) + : + : "cc", "v1", "v2", "v3", "v4", + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23"); + return ret; +} +#else float inner_product_single(const float *a, const float *b, unsigned int len) { float ret; @@ -192,11 +331,12 @@ float inner_product_single(const float *a, const float *b, unsigned int len) " vadd.f32 d0, d0, d1\n" " vpadd.f32 d0, d0, d0\n" " vmov.f32 %[ret], d0[0]\n" - : [ret] "=&r" (ret), [a] "+r" (a), [b] "+r" (b), + : [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b), [len] "+l" (len), [remainder] "+l" (remainder) : - : "cc", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", - "q9", "q10", "q11"); + : "cc", "q0", "q1", "q2", "q3", + "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11"); return ret; } +#endif // defined(__aarch64__) #endif diff --git a/media/libspeex_resampler/src/resample_sse.c b/media/libspeex_resampler/src/resample_sse.c index 2eb7929ce..c3a864ccf 100644 --- a/media/libspeex_resampler/src/resample_sse.c +++ b/media/libspeex_resampler/src/resample_sse.c @@ -9,18 +9,18 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + - Neither the name of the Xiph.org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS 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 @@ -73,7 +73,7 @@ float interpolate_product_single(const float *a, const float *b, unsigned int le return ret; } -#ifdef _USE_SSE2 +#ifdef USE_SSE2 #include #define OVERRIDE_INNER_PRODUCT_DOUBLE diff --git a/media/libspeex_resampler/src/simd_detect.cpp b/media/libspeex_resampler/src/simd_detect.cpp index 50111273b..8dbd51d48 100644 --- a/media/libspeex_resampler/src/simd_detect.cpp +++ b/media/libspeex_resampler/src/simd_detect.cpp @@ -8,19 +8,19 @@ #include "mozilla/SSE.h" #include "mozilla/arm.h" -#ifdef _USE_SSE2 +#ifdef USE_SSE2 int moz_speex_have_double_simd() { return mozilla::supports_sse2() ? 1 : 0; } #endif -#ifdef _USE_SSE +#ifdef USE_SSE int moz_speex_have_single_simd() { return mozilla::supports_sse() ? 1 : 0; } #endif -#ifdef _USE_NEON +#ifdef USE_NEON int moz_speex_have_single_simd() { return mozilla::supports_neon() ? 1 : 0; } diff --git a/media/libspeex_resampler/src/simd_detect.h b/media/libspeex_resampler/src/simd_detect.h index f563b82b9..70f71c6a8 100644 --- a/media/libspeex_resampler/src/simd_detect.h +++ b/media/libspeex_resampler/src/simd_detect.h @@ -16,18 +16,18 @@ extern "C" { int moz_speex_have_single_simd(); int moz_speex_have_double_simd(); -#if defined(_USE_SSE) || defined(_USE_NEON) +#if defined(USE_SSE) || defined(USE_NEON) #define OVERRIDE_INNER_PRODUCT_SINGLE #define inner_product_single CAT_PREFIX(RANDOM_PREFIX,_inner_product_single) spx_word32_t inner_product_single(const spx_word16_t *a, const spx_word16_t *b, unsigned int len); #endif -#if defined(_USE_SSE) +#if defined(USE_SSE) #define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE #define interpolate_product_single CAT_PREFIX(RANDOM_PREFIX,_interpolate_product_single) spx_word32_t interpolate_product_single(const spx_word16_t *a, const spx_word16_t *b, unsigned int len, const spx_uint32_t oversample, float *frac); #endif -#if defined(_USE_SSE2) +#if defined(USE_SSE2) #define OVERRIDE_INNER_PRODUCT_DOUBLE #define inner_product_double CAT_PREFIX(RANDOM_PREFIX,_inner_product_double) double inner_product_double(const float *a, const float *b, unsigned int len); diff --git a/media/libspeex_resampler/src/speex_resampler.h b/media/libspeex_resampler/src/speex_resampler.h index 12868723e..65fb07827 100644 --- a/media/libspeex_resampler/src/speex_resampler.h +++ b/media/libspeex_resampler/src/speex_resampler.h @@ -1,8 +1,8 @@ /* Copyright (C) 2007 Jean-Marc Valin - + File: speex_resampler.h Resampling code - + The design goals of this code are: - Very fast algorithm - Low memory requirement @@ -43,7 +43,7 @@ /********* WARNING: MENTAL SANITY ENDS HERE *************/ -/* If the resampler is defined outside of Speex, we change the symbol names so that +/* If the resampler is defined outside of Speex, we change the symbol names so that there won't be any clash if linking with Speex later on. */ /* #define RANDOM_PREFIX your software name here */ @@ -54,7 +54,7 @@ #define CAT_PREFIX2(a,b) a ## b #define CAT_PREFIX(a,b) CAT_PREFIX2(a, b) - + #define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init) #define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac) #define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy) @@ -83,7 +83,9 @@ #define spx_int32_t int #define spx_uint16_t unsigned short #define spx_uint32_t unsigned int - + +#define speex_assert(cond) + #else /* OUTSIDE_SPEEX */ #include "speexdsp_types.h" @@ -123,14 +125,14 @@ typedef struct SpeexResamplerState_ SpeexResamplerState; * @return Newly created resampler state * @retval NULL Error: not enough memory */ -SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, - spx_uint32_t in_rate, - spx_uint32_t out_rate, +SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, + spx_uint32_t in_rate, + spx_uint32_t out_rate, int quality, int *err); -/** Create a new resampler with fractional input/output rates. The sampling - * rate ratio is an arbitrary rational number with both the numerator and +/** Create a new resampler with fractional input/output rates. The sampling + * rate ratio is an arbitrary rational number with both the numerator and * denominator being 32-bit integers. * @param nb_channels Number of channels to be processed * @param ratio_num Numerator of the sampling rate ratio @@ -142,11 +144,11 @@ SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, * @return Newly created resampler state * @retval NULL Error: not enough memory */ -SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, - spx_uint32_t ratio_num, - spx_uint32_t ratio_den, - spx_uint32_t in_rate, - spx_uint32_t out_rate, +SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate, int quality, int *err); @@ -157,24 +159,24 @@ void speex_resampler_destroy(SpeexResamplerState *st); /** Resample a float array. The input and output buffers must *not* overlap. * @param st Resampler state - * @param channel_index Index of the channel to process for the multi-channel + * @param channel_index Index of the channel to process for the multi-channel * base (0 otherwise) * @param in Input buffer - * @param in_len Number of input samples in the input buffer. Returns the + * @param in_len Number of input samples in the input buffer. Returns the * number of samples processed * @param out Output buffer * @param out_len Size of the output buffer. Returns the number of samples written */ -int speex_resampler_process_float(SpeexResamplerState *st, - spx_uint32_t channel_index, - const float *in, - spx_uint32_t *in_len, - float *out, +int speex_resampler_process_float(SpeexResamplerState *st, + spx_uint32_t channel_index, + const float *in, + spx_uint32_t *in_len, + float *out, spx_uint32_t *out_len); /** Resample an int array. The input and output buffers must *not* overlap. * @param st Resampler state - * @param channel_index Index of the channel to process for the multi-channel + * @param channel_index Index of the channel to process for the multi-channel * base (0 otherwise) * @param in Input buffer * @param in_len Number of input samples in the input buffer. Returns the number @@ -182,11 +184,11 @@ int speex_resampler_process_float(SpeexResamplerState *st, * @param out Output buffer * @param out_len Size of the output buffer. Returns the number of samples written */ -int speex_resampler_process_int(SpeexResamplerState *st, - spx_uint32_t channel_index, - const spx_int16_t *in, - spx_uint32_t *in_len, - spx_int16_t *out, +int speex_resampler_process_int(SpeexResamplerState *st, + spx_uint32_t channel_index, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, spx_uint32_t *out_len); /** Resample an interleaved float array. The input and output buffers must *not* overlap. @@ -198,10 +200,10 @@ int speex_resampler_process_int(SpeexResamplerState *st, * @param out_len Size of the output buffer. Returns the number of samples written. * This is all per-channel. */ -int speex_resampler_process_interleaved_float(SpeexResamplerState *st, - const float *in, - spx_uint32_t *in_len, - float *out, +int speex_resampler_process_interleaved_float(SpeexResamplerState *st, + const float *in, + spx_uint32_t *in_len, + float *out, spx_uint32_t *out_len); /** Resample an interleaved int array. The input and output buffers must *not* overlap. @@ -213,10 +215,10 @@ int speex_resampler_process_interleaved_float(SpeexResamplerState *st, * @param out_len Size of the output buffer. Returns the number of samples written. * This is all per-channel. */ -int speex_resampler_process_interleaved_int(SpeexResamplerState *st, - const spx_int16_t *in, - spx_uint32_t *in_len, - spx_int16_t *out, +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); /** Set (change) the input/output sampling rates (integer value). @@ -224,8 +226,8 @@ int speex_resampler_process_interleaved_int(SpeexResamplerState *st, * @param in_rate Input sampling rate (integer number of Hz). * @param out_rate Output sampling rate (integer number of Hz). */ -int speex_resampler_set_rate(SpeexResamplerState *st, - spx_uint32_t in_rate, +int speex_resampler_set_rate(SpeexResamplerState *st, + spx_uint32_t in_rate, spx_uint32_t out_rate); /** Get the current input/output sampling rates (integer value). @@ -233,11 +235,11 @@ int speex_resampler_set_rate(SpeexResamplerState *st, * @param in_rate Input sampling rate (integer number of Hz) copied. * @param out_rate Output sampling rate (integer number of Hz) copied. */ -void speex_resampler_get_rate(SpeexResamplerState *st, - spx_uint32_t *in_rate, +void speex_resampler_get_rate(SpeexResamplerState *st, + spx_uint32_t *in_rate, spx_uint32_t *out_rate); -/** Set (change) the input/output sampling rates and resampling ratio +/** Set (change) the input/output sampling rates and resampling ratio * (fractional values in Hz supported). * @param st Resampler state * @param ratio_num Numerator of the sampling rate ratio @@ -245,10 +247,10 @@ void speex_resampler_get_rate(SpeexResamplerState *st, * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). */ -int speex_resampler_set_rate_frac(SpeexResamplerState *st, - spx_uint32_t ratio_num, - spx_uint32_t ratio_den, - spx_uint32_t in_rate, +int 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); /** Get the current resampling ratio. This will be reduced to the least @@ -257,52 +259,52 @@ int speex_resampler_set_rate_frac(SpeexResamplerState *st, * @param ratio_num Numerator of the sampling rate ratio copied * @param ratio_den Denominator of the sampling rate ratio copied */ -void speex_resampler_get_ratio(SpeexResamplerState *st, - spx_uint32_t *ratio_num, +void speex_resampler_get_ratio(SpeexResamplerState *st, + spx_uint32_t *ratio_num, spx_uint32_t *ratio_den); /** Set (change) the conversion quality. * @param st Resampler state - * @param quality Resampling quality between 0 and 10, where 0 has poor + * @param quality Resampling quality between 0 and 10, where 0 has poor * quality and 10 has very high quality. */ -int speex_resampler_set_quality(SpeexResamplerState *st, +int speex_resampler_set_quality(SpeexResamplerState *st, int quality); /** Get the conversion quality. * @param st Resampler state - * @param quality Resampling quality between 0 and 10, where 0 has poor + * @param quality Resampling quality between 0 and 10, where 0 has poor * quality and 10 has very high quality. */ -void speex_resampler_get_quality(SpeexResamplerState *st, +void speex_resampler_get_quality(SpeexResamplerState *st, int *quality); /** Set (change) the input stride. * @param st Resampler state * @param stride Input stride */ -void speex_resampler_set_input_stride(SpeexResamplerState *st, +void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride); /** Get the input stride. * @param st Resampler state * @param stride Input stride copied */ -void speex_resampler_get_input_stride(SpeexResamplerState *st, +void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride); /** Set (change) the output stride. * @param st Resampler state * @param stride Output stride */ -void speex_resampler_set_output_stride(SpeexResamplerState *st, +void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride); /** Get the output stride. * @param st Resampler state copied * @param stride Output stride */ -void speex_resampler_get_output_stride(SpeexResamplerState *st, +void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride); /** Get the latency introduced by the resampler measured in input samples. @@ -315,8 +317,8 @@ int speex_resampler_get_input_latency(SpeexResamplerState *st); */ int speex_resampler_get_output_latency(SpeexResamplerState *st); -/** Make sure that the first samples to go out of the resamplers don't have - * leading zeros. This is only useful before starting to use a newly created +/** Make sure that the first samples to go out of the resamplers don't have + * leading zeros. This is only useful before starting to use a newly created * resampler. It is recommended to use that when resampling an audio file, as * it will generate a file with the same length. For real-time processing, * it is probably easier not to use this call (so that the output duration diff --git a/media/libspeex_resampler/src/stack_alloc.h b/media/libspeex_resampler/src/stack_alloc.h deleted file mode 100644 index 5264e666b..000000000 --- a/media/libspeex_resampler/src/stack_alloc.h +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file stack_alloc.h - @brief Temporary memory allocation on stack -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS 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 FOUNDATION 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. -*/ - -#ifndef STACK_ALLOC_H -#define STACK_ALLOC_H - -#ifdef USE_ALLOCA -# ifdef WIN32 -# include -# else -# ifdef HAVE_ALLOCA_H -# include -# else -# include -# endif -# endif -#endif - -/** - * @def ALIGN(stack, size) - * - * Aligns the stack to a 'size' boundary - * - * @param stack Stack - * @param size New size boundary - */ - -/** - * @def PUSH(stack, size, type) - * - * Allocates 'size' elements of type 'type' on the stack - * - * @param stack Stack - * @param size Number of elements - * @param type Type of element - */ - -/** - * @def VARDECL(var) - * - * Declare variable on stack - * - * @param var Variable to declare - */ - -/** - * @def ALLOC(var, size, type) - * - * Allocate 'size' elements of 'type' on stack - * - * @param var Name of variable to allocate - * @param size Number of elements - * @param type Type of element - */ - -#ifdef ENABLE_VALGRIND - -#include - -#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) - -#define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) - -#else - -#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) - -#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) - -#endif - -#if defined(VAR_ARRAYS) -#define VARDECL(var) -#define ALLOC(var, size, type) type var[size] -#elif defined(USE_ALLOCA) -#define VARDECL(var) var -#define ALLOC(var, size, type) var = alloca(sizeof(type)*(size)) -#else -#define VARDECL(var) var -#define ALLOC(var, size, type) var = PUSH(stack, size, type) -#endif - - -#endif diff --git a/media/libspeex_resampler/update.sh b/media/libspeex_resampler/update.sh index 6950bc61b..ec1ff76aa 100644 --- a/media/libspeex_resampler/update.sh +++ b/media/libspeex_resampler/update.sh @@ -13,17 +13,15 @@ cp $1/libspeexdsp/resample.c src cp $1/libspeexdsp/resample_sse.h src/resample_sse.c cp $1/libspeexdsp/resample_neon.h src/resample_neon.c cp $1/libspeexdsp/arch.h src -cp $1/libspeexdsp/stack_alloc.h src cp $1/libspeexdsp/fixed_generic.h src cp $1/include/speex/speex_resampler.h src cp $1/AUTHORS . cp $1/COPYING . # apply outstanding local patches -patch -p3 < outside-speex.patch -patch -p3 < simd-detect-runtime.patch -patch -p3 < set-skip-frac.patch -patch -p3 < hugemem.patch -patch -p3 < remove-empty-asm-clobber.patch -patch -p3 < handle-memory-error.patch -patch -p3 < fix-overflow.patch +patch -p3 -i outside-speex.patch +patch -p3 -i simd-detect-runtime.patch +patch -p3 -i set-skip-frac.patch +patch -p3 -i hugemem.patch +patch -p3 -i remove-empty-asm-clobber.patch +patch -p3 -i set-rate-overflow-no-return.patch