Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/speexdsp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING7
-rw-r--r--libspeex/Makefile.am9
-rw-r--r--libspeex/cb_search_bfin.h79
-rw-r--r--libspeex/filters_bfin.h339
-rw-r--r--libspeex/fixed_bfin.h134
-rw-r--r--libspeex/ltp_bfin.h103
-rw-r--r--libspeex/vq_bfin.h71
7 files changed, 739 insertions, 3 deletions
diff --git a/COPYING b/COPYING
index a0b97ef..5c710ac 100644
--- a/COPYING
+++ b/COPYING
@@ -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++;
+ }
+ }
+
+}