diff options
-rw-r--r-- | COPYING | 7 | ||||
-rw-r--r-- | libspeex/Makefile.am | 9 | ||||
-rw-r--r-- | libspeex/cb_search_bfin.h | 79 | ||||
-rw-r--r-- | libspeex/filters_bfin.h | 339 | ||||
-rw-r--r-- | libspeex/fixed_bfin.h | 134 | ||||
-rw-r--r-- | libspeex/ltp_bfin.h | 103 | ||||
-rw-r--r-- | libspeex/vq_bfin.h | 71 |
7 files changed, 739 insertions, 3 deletions
@@ -1,4 +1,9 @@ -Copyright 2002-2004 Xiph.org Foundation, Jean-Marc Valin, David Rowe, EpicGames +Copyright 2002-2005 + Xiph.org Foundation + Jean-Marc Valin + David Rowe + EpicGames + Analog Devices Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/libspeex/Makefile.am b/libspeex/Makefile.am index a488223..0bf99c2 100644 --- a/libspeex/Makefile.am +++ b/libspeex/Makefile.am @@ -54,25 +54,30 @@ noinst_HEADERS = lsp.h \ filters.h \ stack_alloc.h \ vq.h \ - vq_arm4.h \ vq_sse.h \ + vq_arm4.h \ + vq_bfin.h \ modes.h \ sb_celp.h \ vbr.h \ misc.h \ ltp_sse.h \ ltp_arm4.h \ + ltp_bfin.h \ filters_sse.h \ filters_arm4.h \ + filters_bfin.h \ math_approx.h \ smallft.h \ arch.h \ fixed_arm4.h \ fixed_arm5e.h \ + fixed_bfin.h \ fixed_debug.h \ fixed_generic.h \ cb_search_sse.h \ - cb_search_arm4.h + cb_search_arm4.h \ + cb_search_bfin.h libspeex_la_LDFLAGS = -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@ diff --git a/libspeex/cb_search_bfin.h b/libspeex/cb_search_bfin.h new file mode 100644 index 0000000..1ebc1f3 --- /dev/null +++ b/libspeex/cb_search_bfin.h @@ -0,0 +1,79 @@ +/* Copyright (C) 2005 Analog Devices + Author: Jean-Marc Valin + File: cb_search_bfin.h + Fixed codebook functions (Blackfin version) + + 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. +*/ + +#define OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK +void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack) +{ + int i; + for (i=0;i<shape_cb_size;i++) + { + __asm__ __volatile__ ( + "P0 = %0;\n\t" + "LC0 = P0;\n\t" + "P1 = %1;\n\t" + "P2 = %2;\n\t" + "P3 = %3;\n\t" + "P0 = 1;\n\t" + "L0 = 0;\n\t" + "L1 = 0;\n\t" + "R2 = 0;\n\t" + "A1 = 0;\n\t" + "LOOP outter%= LC0;\n\t" + "LOOP_BEGIN outter%=;\n\t" + "A0 = 0;\n\t" + "P4 = P1;\n\t" + "I1 = P2;\n\t" + "R0 = B[P4++] (X) || R1.L = W[I1--];\n\t" + "LOOP inner%= LC1 = P0;\n\t" + "LOOP_BEGIN inner%=;\n\t" + "LOOP_END inner%=;\n\t" + "A0 += R0.L*R1.L (IS) || R0 = B[P4++] (X) || R1.L = W[I1--];\n\t" /* Is there a danger of reading too far? */ + "R0 = A0;\n\t" + "R0 >>>= 11;\n\t" + "A1 += R0.L*R0.L (IS);\n\t" + "W[P3++] = R0;\n\t" + "P0 += 1;\n\t" + "LOOP_END outter%=;\n\t" + "P2 += 2;\n\t" + "P4 = %4;\n\t" + "R1 = A1;\n\t" + "[P4] = R1;\n\t" + : + : "m" (subvect_size), "m" (shape_cb), "m" (r), "m" (resp), "m" (E) + : "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "I0", "I1", "L0", "L1", "B0", "B1", "A0", "A1", "memory" + ); + shape_cb += subvect_size; + resp += subvect_size; + E++; + } +} diff --git a/libspeex/filters_bfin.h b/libspeex/filters_bfin.h new file mode 100644 index 0000000..b08cdde --- /dev/null +++ b/libspeex/filters_bfin.h @@ -0,0 +1,339 @@ +/* Copyright (C) 2005 Analog Devices + Author: Jean-Marc Valin + File: filters_bfin.h + Various analysis/synthesis filters (Blackfin version) + + 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. +*/ + +#include <stdio.h> + +#define OVERRIDE_NORMALIZE16 +int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len) +{ + spx_sig_t max_val=1; + int sig_shift; + + __asm__ + ( + "%0 = 0;\n\t" + "I0 = %1;\n\t" + "L0 = 0;\n\t" + "LOOP norm_max%= LC0 = %2;\n\t" + "LOOP_BEGIN norm_max%=;\n\t" + "R1 = [I0++];\n\t" + "R1 = ABS R1;\n\t" + "LOOP_END norm_max%=;\n\t" + "%0 = MAX(%0, R1);\n\t" + : "=d" (max_val) + : "a" (x), "a" (len) + : "R1" + ); + + sig_shift=0; + while (max_val>max_scale) + { + sig_shift++; + max_val >>= 1; + } + + __asm__ __volatile__ + ( + "I0 = %0;\n\t" + "L0 = 0;\n\t" + "I1 = %1;\n\t" + "L1 = 0;\n\t" + "R0 = [I0++];\n\t" + "LOOP norm_shift%= LC0 = %3 >> 1;\n\t" + "LOOP_BEGIN norm_shift%=;\n\t" + "R1 = ASHIFT R0 by %2.L || R2 = [I0++];\n\t" + "R3 = ASHIFT R2 by %2.L || R0 = [I0++];\n\t" + "R3 = PACK(R3.L, R1.L);\n\t" + "LOOP_END norm_shift%=;\n\t" + "[I1++] = R3;\n\t" + + : : "a" (x), "a" (y), "d" (-sig_shift), "a" (len) + : "I0", "L0", "I1", "L1", "R0", "R1", "R2", "R3", "memory" + ); + return sig_shift; +} + +#define OVERRIDE_FILTER_MEM2 +void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *_y, int N, int ord, spx_mem_t *mem) +{ + int i,j; + spx_word16_t x[N],y[N]; + spx_word16_t *xx, *yy; + xx = x; + yy = y; + + __asm__ __volatile__ + ( + "R0 = %7;\n\t" /*ord */ + + "P0 = %4;\n\t" + "I0 = P0;\n\t" + "B0 = P0;\n\t" + "L0 = 0;\n\t" + + "P1 = %5;\n\t" + "I1 = P1;\n\t" + "B1 = P1;\n\t" + "L1 = 0;\n\t" + + "P2 = %0;\n\t" + "P3 = %1;\n\t" + "I2 = P2;\n\t" + "I3 = P3;\n\t" + "L2 = 0;\n\t" + "L3 = 0;\n\t" + + "P4 = %8;\n\t" + "P0 = %2;\n\t" + "P1 = %3;\n\t" + + "R1 = [P4++];\n\t" + "R1 <<= 1;\n\t" + "R2 = [P0++];\n\t" + "R1 = R1 + R2;\n\t" + "[P1++] = R1;\n\t" + "R1 <<= 2;\n\t" + "W[P3] = R1.H;\n\t" + "R2 <<= 2;\n\t" + "W[P2] = R2.H;\n\t" + + "R0 += -1;\n\t" + "R3 = 0;\n\t" + "LC0 = R0;\n\t" + "LOOP filter_start%= LC0;\n\t" + "LOOP_BEGIN filter_start%=;\n\t" + "R3 += 1;\n\t" + "LC1 = R3;\n\t" + + "R1 = [P4++];\n\t" + "A1 = R1;\n\t" + "I0 = B0;\n\t" + "I1 = B1;\n\t" + "I2 = P2;\n\t" + "I3 = P3;\n\t" + "P2 += 2;\n\t" + "P3 += 2;\n\t" + "LOOP filter_start_inner%= LC1;\n\t" + "LOOP_BEGIN filter_start_inner%=;\n\t" + "R4.L = W[I0++];\n\t" + "R5.L = W[I2--];\n\t" + "A1 += R4.L*R5.L (IS);\n\t" + "R4.L = W[I1++];\n\t" + "R5.L = W[I3--];\n\t" + "A1 -= R4.L*R5.L (IS);\n\t" + "LOOP_END filter_start_inner%=;\n\t" + "nop;nop;nop;nop;\n\t" + + "R1 = A1;\n\t" + "R1 <<= 1;\n\t" + "R2 = [P0++];\n\t" + "R1 = R1 + R2;\n\t" + "[P1++] = R1;\n\t" + "R1 <<= 2;\n\t" + "W[P3] = R1.H;\n\t" + "R2 <<= 2;\n\t" + "W[P2] = R2.H;\n\t" + + "LOOP_END filter_start%=;\n\t" + "nop;nop;nop;nop;\n\t" + + + "R0 = %7;\n\t" + "R0 <<= 1;\n\t" + "I0 = B0;\n\t" + "I1 = B1;\n\t" + "L0 = R0;\n\t" + "L1 = R0;\n\t" + + "R0 = %7;\n\t" + "R2 = %6;\n\t" + "R2 = R2 - R0;\n\t" + "R4.L = W[I0++];\n\t" + "R6.L = W[I1++];\n\t" + "LC0 = R2;\n\t" + "LOOP filter_mid%= LC0;\n\t" + "LOOP_BEGIN filter_mid%=;\n\t" + "LC1 = R0;\n\t" + "A1 = 0;\n\t" + + "I2 = P2;\n\t" + "I3 = P3;\n\t" + "P2 += 2;\n\t" + "P3 += 2;\n\t" + "R5.L = W[I2--];\n\t" + "R7.L = W[I3--];\n\t" + "LOOP filter_mid_inner%= LC1;\n\t" + "LOOP_BEGIN filter_mid_inner%=;\n\t" + "A1 += R4.L*R5.L (IS) || R4.L = W[I0++] || R5.L = W[I2--];\n\t" + "LOOP_END filter_mid_inner%=;\n\t" + "A1 -= R6.L*R7.L (IS) || R6.L = W[I1++] || R7.L = W[I3--];\n\t" + "R1 = A1;\n\t" + "R1 <<= 1;\n\t" + "R2 = [P0++];\n\t" + "R1 = R1 + R2;\n\t" + "[P1++] = R1;\n\t" + "R1 <<= 2;\n\t" + "W[P3] = R1.H;\n\t" + "R2 <<= 2;\n\t" + "W[P2] = R2.H;\n\t" + + "LOOP_END filter_mid%=;\n\t" + "nop;nop;nop;nop;\n\t" + + : : "m" (xx), "m" (yy), "m" (_x), "m" (_y), "m" (num), "m" (den), "m" (N), "m" (ord), "m" (mem) + : "R0", "R1", "R2", "R3", "R4", "R5", "R7", "P0", "P1", "P2", "P3", "P4", "B0", "B1", "I0", "I1", "I2", "I3", "L0", "L1", "L2", "L3", "memory" + ); + + + for (i=0;i<ord;i++) + { + spx_mem_t m = 0; + for (j=0;j<ord-i;j++) + { + m = MAC16_16(m, x[N-1-j], num[j+i]); + m = MAC16_16(m, -y[N-1-j], den[j+i]); + } + mem[i] = m; + } +} + + + + +#define OVERRIDE_IIR_MEM2 +void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem) +{ + int i; + spx_coef_t num2[12]; + spx_coef_t *num; + num = (spx_coef_t*)((((int)num2)+4)&0xfffffffc); + for (i=0;i<10;i++) + num[i] = 0; + filter_mem2(x, num, den, y, N, ord, mem); +} + +#define OVERRIDE_FIR_MEM2 +void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem) +{ + int i; + spx_coef_t den2[12]; + spx_coef_t *den; + den = (spx_coef_t*)((((int)den2)+4)&0xfffffffc); + for (i=0;i<10;i++) + den[i] = 0; + filter_mem2(x, num, den, y, N, ord, mem); +} + +#define min(a,b) ((a)<(b) ? (a):(b)) + +#define OVERRIDE_COMPUTE_IMPULSE_RESPONSE +void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack) +{ + int i,j; + VARDECL(spx_word16_t *ytmp); + ALLOC(ytmp, N, spx_word16_t); + + y[0] = LPC_SCALING; + for (i=0;i<ord;i++) + y[i+1] = awk1[i]; + i++; + for (;i<N;i++) + y[i] = 0; + + for (i=0;i<N;i++) + { + spx_word32_t yi = SHL32(EXTEND32(y[i]),LPC_SHIFT); + spx_word32_t yi2 = 0; + for (j=0;j<min(i,ord);j++) + { + yi = MAC16_16(yi, awk2[j], -ytmp[i-j-1]); + yi2 = MAC16_16(yi2, ak[j], -y[i-j-1]); + } + ytmp[i] = EXTRACT16(SHR32(yi,LPC_SHIFT)); + yi2 = ADD32(yi2,SHL32(yi,1)); + y[i] = EXTRACT16(SHR32(yi2,LPC_SHIFT)); + } + +} + + + +#if 0 /* Equivalent C function for filter_mem2 */ +void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *_y, int N, int ord, spx_mem_t *mem) +{ + int i,j; + spx_word16_t xi,yi,nyi; + spx_word16_t x[N],y[N]; + spx_word16_t *xx, *yy; + xx = x; + yy = y; + for (i=0;i<N;i++) + { + x[i] = EXTRACT16(SHR32(_x[i],SIG_SHIFT)); + } + + for (i=0;i<ord;i++) + { + spx_word32_t yi = mem[i]; + for (j=0;j<i;j++) + { + yi = MAC16_16(yi, num[j], x[i-j-1]); + yi = MAC16_16(yi, den[j], -y[i-j-1]); + } + _y[i] = ADD32(_x[i],SHL32(yi,1)); + y[i] = EXTRACT16(SHR32(_y[i],SIG_SHIFT)); + } + for (i=ord;i<N;i++) + { + spx_word32_t yi = 0; + for (j=0;j<ord;j++) + { + yi = MAC16_16(yi, num[j], x[i-j-1]); + yi = MAC16_16(yi, den[j], -y[i-j-1]); + } + _y[i] = ADD32(_x[i],SHL32(yi,1)); + y[i] = EXTRACT16(SHR32(_y[i],SIG_SHIFT)); + } + + for (i=0;i<ord;i++) + { + spx_mem_t m = 0; + for (j=0;j<ord-i;j++) + { + m = MAC16_16(m, x[N-1-j], num[j+i]); + m = MAC16_16(m, -y[N-1-j], den[j+i]); + } + mem[i] = m; + } +} +#endif diff --git a/libspeex/fixed_bfin.h b/libspeex/fixed_bfin.h new file mode 100644 index 0000000..71c855a --- /dev/null +++ b/libspeex/fixed_bfin.h @@ -0,0 +1,134 @@ +/* Copyright (C) 2005 Analog Devices + Author: Jean-Marc Valin */ +/** + @file fixed_bfin.h + @brief Blackfin fixed-point operations +*/ +/* + 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 FIXED_BFIN_H +#define FIXED_BFIN_H + +#undef DIV32_16 +static inline spx_word16_t DIV32_16(spx_word32_t a, spx_word16_t b) +{ + spx_word32_t res, bb; + bb = b; + __asm__ ( + "P0 = 15;\n\t" + "R0 = %1;\n\t" + "R1 = %2;\n\t" + "R0 <<= 1;\n\t" + "DIVS (R0, R1);\n\t" + "LOOP divide%= LC0 = P0;\n\t" + "LOOP_BEGIN divide%=;\n\t" + "LOOP_END divide%=;\n\t" + "DIVQ (R0, R1);\n\t" + "R0 = R0.L;\n\t" + "%0 = R0;\n\t" + : "=m" (res) + : "m" (a), "m" (bb) + : "P0", "R0", "R1", "cc"); + return res; +} + +#undef MULT16_32_Q15 +static inline spx_word32_t MULT16_32_Q15(spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "%1 <<= 1;\n\t" + "A1 = %2.L*%1.L (M,IS);\n\t" + "A1 = A1 >>> 16;\n\t" + "R1 = (A1 += %2.L*%1.H) (IS);\n\t" + "%0 = R1;\n\t" + : "=&d" (res), "=&d" (b) + : "d" (a), "1" (b) + : "A1", "R1" + ); + return res; +} + +#undef MAC16_32_Q15 +static inline spx_word32_t MAC16_32_Q15(spx_word32_t c, spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "%1 <<= 1;\n\t" + "A1 = %2.L*%1.L (M,IS);\n\t" + "A1 = A1 >>> 16;\n\t" + "R1 = (A1 += %2.L*%1.H) (IS);\n\t" + "%0 = R1 + %4;\n\t" + : "=&d" (res), "=&d" (b) + : "d" (a), "1" (b), "d" (c) + : "A1", "R1" + ); + return res; +} + +#undef MULT16_32_Q14 +static inline spx_word32_t MULT16_32_Q14(spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "%2 <<= 2;\n\t" + "A1 = %1.L*%2.L (M,IS);\n\t" + "A1 = A1 >>> 16;\n\t" + "R1 = (A1 += %1.L*%2.H) (IS);\n\t" + "%0 = R1;\n\t" + : "=d" (res), "=d" (a), "=d" (b) + : "1" (a), "2" (b) + : "A1", "R1" + ); + return res; +} + +#undef MAC16_32_Q14 +static inline spx_word32_t MAC16_32_Q14(spx_word32_t c, spx_word16_t a, spx_word32_t b) +{ + spx_word32_t res; + __asm__ + ( + "%1 <<= 2;\n\t" + "A1 = %2.L*%1.L (M,IS);\n\t" + "A1 = A1 >>> 16;\n\t" + "R1 = (A1 += %2.L*%1.H) (IS);\n\t" + "%0 = R1 + %4;\n\t" + : "=&d" (res), "=&d" (b) + : "d" (a), "1" (b), "d" (c) + : "A1", "R1" + ); + return res; +} + +#endif diff --git a/libspeex/ltp_bfin.h b/libspeex/ltp_bfin.h new file mode 100644 index 0000000..511ccb8 --- /dev/null +++ b/libspeex/ltp_bfin.h @@ -0,0 +1,103 @@ +/* Copyright (C) 2005 Analog Devices + Author: Jean-Marc Valin + File: ltp_bfin.h + Long-Term Prediction functions (Blackfin version) + + 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. +*/ + +#define OVERRIDE_INNER_PROD +static spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) +{ + spx_word32_t sum=0; + __asm__ __volatile__ ( + "P0 = %3;\n\t" + "P1 = %1;\n\t" + "P2 = %2;\n\t" + "I0 = P1;\n\t" + "I1 = P2;\n\t" + "L0 = 0;\n\t" + "L1 = 0;\n\t" + "A0 = 0;\n\t" + "R0.L = W[I0++] || R1.L = W[I1++];\n\t" + "LOOP inner%= LC0 = P0;\n\t" + "LOOP_BEGIN inner%=;\n\t" + "LOOP_END inner%=;\n\t" + "A0 += R0.L*R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\n\t" + "A0 = A0 >>> 6;\n\t" + "R0 = A0;\n\t" + "%0 = R0;\n\t" + : "=m" (sum) + : "m" (x), "m" (y), "m" (len) + : "P0", "P1", "P2", "R0", "R1", "A0", "I0", "I1", "L0", "L1", "R3" + ); + return sum; +} + +#define OVERRIDE_PITCH_XCORR +static void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) +{ + int i; + corr += nb_pitch - 1; + __asm__ __volatile__ ( + "P2 = %0;\n\t" + "I0 = P2;\n\t" /* x in I0 */ + "B0 = P2;\n\t" /* x in B0 */ + "R0 = %3;\n\t" /* len in R0 */ + "P3 = %3;\n\t" /* len in R0 */ + "P4 = %4;\n\t" /* nb_pitch in R0 */ + "R1 = R0 << 1;\n\t" /* number of bytes in x */ + "L0 = R1;\n\t" + "P0 = %1;\n\t" + + "P1 = %2;\n\t" + "B1 = P1;\n\t" + "L1 = 0;\n\t" /*Disable looping on I1*/ + + "r0 = [I0++];\n\t" + "LOOP pitch%= LC0 = P4 >> 1;\n\t" + "LOOP_BEGIN pitch%=;\n\t" + "I1 = P0;\n\t" + "A1 = A0 = 0;\n\t" + "R1 = [I1++];\n\t" + "LOOP inner_prod%= LC1 = P3 >> 1;\n\t" + "LOOP_BEGIN inner_prod%=;\n\t" + "A0 += R0.L*R1.L , A1 += R0.L*R1.H (is) || R1.L = W[I1++];\n\t" + "LOOP_END inner_prod%=;\n\t" + "A0 += R0.H*R1.H , A1 += R0.H*R1.L (is) || R1.H = W[I1++] || R0 = [I0++];\n\t" + "A0 = A0 >>> 6;\n\t" + "A1 = A1 >>> 6;\n\t" + "R2 = A0, R3 = A1;\n\t" + "[P1--] = r2;\n\t" + "[P1--] = r3;\n\t" + "LOOP_END pitch%=;\n\t" + "P0 += 4;\n\t" + : : "m" (_x), "m" (_y), "m" (corr), "m" (len), "m" (nb_pitch) + : "A0", "A1", "P0", "P1", "P2", "P3", "P4", "R0", "R1", "R2", "R3", "I0", "I1", "L0", "L1", "B0", "B1", "memory" + ); +} diff --git a/libspeex/vq_bfin.h b/libspeex/vq_bfin.h new file mode 100644 index 0000000..93614ee --- /dev/null +++ b/libspeex/vq_bfin.h @@ -0,0 +1,71 @@ +/* Copyright (C) 2005 Analog Devices + Author: Jean-Marc Valin + File: vq_arm4.h + Blackfin-optimized vq routine + + 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. +*/ + +#define OVERRIDE_VQ_NBEST +void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack) +{ + int i,j,k,used; + used = 0; + for (i=0;i<entries;i++) + { + spx_word32_t dist; + __asm__ + ( + "%0 >>= 1;\n\t" + "A0 = %0;\n\t" + "I0 = %3;\n\t" + "L0 = 0;\n\t" + "R0.L = W[%1++%4] || R1.L = W[I0++];\n\t" + "LOOP vq_loop%= LC0 = %2;\n\t" + "LOOP_BEGIN vq_loop%=;\n\t" + "LOOP_END vq_loop%=;\n\t" + "%0 = (A0 -= R0.L*R1.L) (IS) || R0.L = W[%1++%4] || R1.L = W[I0++];\n\t" + "%0 = (A0 -= R0.L*R1.L) (IS);\n\t" + : "=D" (dist), "=a" (codebook) + : "a" (len-1), "a" (in), "a" (2), "1" (codebook), "0" (E[i]) + : "R0", "R1", "I0", "L0", "A0" + ); + if (i<N || dist<best_dist[N-1]) + { + for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--) + { + best_dist[k]=best_dist[k-1]; + nbest[k] = nbest[k-1]; + } + best_dist[k]=dist; + nbest[k]=i; + used++; + } + } + +} |