[xiph-commits] r9357 - in trunk/speex: . libspeex

jm at motherfish-iii.xiph.org jm at motherfish-iii.xiph.org
Sat Jun 4 21:57:42 PDT 2005


Author: jm
Date: 2005-06-04 21:57:39 -0700 (Sat, 04 Jun 2005)
New Revision: 9357

Added:
   trunk/speex/libspeex/cb_search_bfin.h
   trunk/speex/libspeex/filters_bfin.h
   trunk/speex/libspeex/fixed_bfin.h
   trunk/speex/libspeex/ltp_bfin.h
   trunk/speex/libspeex/vq_bfin.h
Modified:
   trunk/speex/COPYING
   trunk/speex/libspeex/Makefile.am
Log:
Blackfin assembly optimizations.


Modified: trunk/speex/COPYING
===================================================================
--- trunk/speex/COPYING	2005-06-05 03:45:46 UTC (rev 9356)
+++ trunk/speex/COPYING	2005-06-05 04:57:39 UTC (rev 9357)
@@ -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

Modified: trunk/speex/libspeex/Makefile.am
===================================================================
--- trunk/speex/libspeex/Makefile.am	2005-06-05 03:45:46 UTC (rev 9356)
+++ trunk/speex/libspeex/Makefile.am	2005-06-05 04:57:39 UTC (rev 9357)
@@ -54,25 +54,30 @@
 	filters.h \
 	stack_alloc.h \
 	vq.h \
+	vq_sse.h \
 	vq_arm4.h \
-	vq_sse.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@

Added: trunk/speex/libspeex/cb_search_bfin.h
===================================================================
--- trunk/speex/libspeex/cb_search_bfin.h	2005-06-05 03:45:46 UTC (rev 9356)
+++ trunk/speex/libspeex/cb_search_bfin.h	2005-06-05 04:57:39 UTC (rev 9357)
@@ -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++;
+   }
+}

Added: trunk/speex/libspeex/filters_bfin.h
===================================================================
--- trunk/speex/libspeex/filters_bfin.h	2005-06-05 03:45:46 UTC (rev 9356)
+++ trunk/speex/libspeex/filters_bfin.h	2005-06-05 04:57:39 UTC (rev 9357)
@@ -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

Added: trunk/speex/libspeex/fixed_bfin.h
===================================================================
--- trunk/speex/libspeex/fixed_bfin.h	2005-06-05 03:45:46 UTC (rev 9356)
+++ trunk/speex/libspeex/fixed_bfin.h	2005-06-05 04:57:39 UTC (rev 9357)
@@ -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

Added: trunk/speex/libspeex/ltp_bfin.h
===================================================================
--- trunk/speex/libspeex/ltp_bfin.h	2005-06-05 03:45:46 UTC (rev 9356)
+++ trunk/speex/libspeex/ltp_bfin.h	2005-06-05 04:57:39 UTC (rev 9357)
@@ -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"
+   );
+}

Added: trunk/speex/libspeex/vq_bfin.h
===================================================================
--- trunk/speex/libspeex/vq_bfin.h	2005-06-05 03:45:46 UTC (rev 9356)
+++ trunk/speex/libspeex/vq_bfin.h	2005-06-05 04:57:39 UTC (rev 9357)
@@ -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++;
+      }
+   }
+
+}



More information about the commits mailing list