annotate libao2/fir.h @ 5119:636b20788503

szrii, tuu, van, fajor
author gabucino
date Fri, 15 Mar 2002 23:17:50 +0000
parents c2bb05709676
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3631
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
1 /*=============================================================================
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
2 //
4049
d6f8feeac656 Correction of lisensing comment
anders
parents: 3631
diff changeset
3 // This software has been released under the terms of the GNU Public
d6f8feeac656 Correction of lisensing comment
anders
parents: 3631
diff changeset
4 // license. See http://www.gnu.org/copyleft/gpl.html for details.
3631
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
5 //
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
6 // Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
7 //
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
8 //=============================================================================
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
9 */
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
10
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
11 #ifndef __FIR_H__
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
12 #define __FIR_H__
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
13
4789
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
14 /* Fixpoint 16 bit FIR filter. The filter is implemented both in C and
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
15 MMX assembly. The filter consists of the two inline functions updateq
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
16 and firn, update q is used for adding new data to the circular buffer
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
17 used by the filter firn. Limitations: max length of n = 16*4 and n
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
18 must be multiple of 4 (pad fiter with zeros for other lengths).
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
19 Sometimes it works with filters longer than 4*16 (the problem is
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
20 overshoot and the acumulated energy in the filter taps). */
3631
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
21
4725
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
22 #ifdef HAVE_MMX
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
23 inline int32_t firn(int16_t* x, int16_t* w, int16_t n)
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
24 {
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
25 register int32_t y; // Output
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
26 // Prologue
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
27 asm volatile(" pxor %mm1, %mm1;\n" ); // Clear buffer yt
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
28 // Main loop
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
29 while((n-=4)>=0){
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
30 asm volatile(
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
31 " movq (%1), %%mm0;\n" // Load x(n:n+4)
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
32 " pmaddwd (%0), %%mm0;\n" // yt(n:n+1)=sum(x(n:n+4).*w(n:n+4))
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
33 " psrld $16, %%mm0;\n" // yt(n:n+1)=yt(n:n+1)>>16
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
34 " paddd %%mm0, %%mm1;\n" // yt(n:n+1)=yt(n-2:n-1)+yt(n:n+1)
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
35 :: "r" (w), "r" (x));
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
36 w+=4; x+=4;
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
37 }
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
38 // Epilogue
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
39 asm volatile(
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
40 " movq %%mm1, %%mm0;\n"
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
41 " punpckhdq %%mm1, %%mm0;\n"
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
42 " paddd %%mm0, %%mm1;\n" //yt(n)=yt(n)+yt(n+1)
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
43 " movd %%mm1, %0 ;\n" //y=yt
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
44 " emms ;\n"
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
45 : "=&r" (y));
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
46 return y;
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
47 }
3631
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
48
4725
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
49 #else /* HAVE_MMX */
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
50
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
51 // Same thing as above but in C
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
52 inline int32_t firn(int16_t* x, int16_t* w, int16_t n)
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
53 {
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
54 register int32_t y=0;
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
55 while((n-=4) >=0)
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
56 y+=w[n]*x[n]+w[n+1]*x[n+1]+w[n+2]*x[n+2]+w[n+3]*x[n+3] >> 16;
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
57 return y;
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
58 }
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
59
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
60 #endif /* HAVE_MMX */
534ef9323eca MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents: 4535
diff changeset
61
4789
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
62 /* Add new data to circular queue designed to be used with a FIR
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
63 filter. xq is the circular queue, in pointing at the new sample, xi
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
64 current index for in xq and l the lenght of the filter */
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
65 inline uint16_t updateq(int16_t* xq, int16_t* in, uint16_t xi, uint16_t l)
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
66 {
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
67 xq[xi]=xq[xi+l]=*in;
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
68 return (--xi)&(l-1); \
3631
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
69 }
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
70
5f5189ac6a41 Added plugin for fractional resampling (alpha code)
anders
parents:
diff changeset
71 #endif /* __FIR_H__ */
4789
c2bb05709676 Cleanup and comment
anders
parents: 4725
diff changeset
72