Mercurial > mplayer.hg
annotate libao2/fir.h @ 5119:636b20788503
szrii, tuu, van, fajor
author | gabucino |
---|---|
date | Fri, 15 Mar 2002 23:17:50 +0000 |
parents | c2bb05709676 |
children |
rev | line source |
---|---|
3631 | 1 /*============================================================================= |
2 // | |
4049 | 3 // This software has been released under the terms of the GNU Public |
4 // license. See http://www.gnu.org/copyleft/gpl.html for details. | |
3631 | 5 // |
6 // Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au | |
7 // | |
8 //============================================================================= | |
9 */ | |
10 | |
11 #ifndef __FIR_H__ | |
12 #define __FIR_H__ | |
13 | |
4789 | 14 /* Fixpoint 16 bit FIR filter. The filter is implemented both in C and |
15 MMX assembly. The filter consists of the two inline functions updateq | |
16 and firn, update q is used for adding new data to the circular buffer | |
17 used by the filter firn. Limitations: max length of n = 16*4 and n | |
18 must be multiple of 4 (pad fiter with zeros for other lengths). | |
19 Sometimes it works with filters longer than 4*16 (the problem is | |
20 overshoot and the acumulated energy in the filter taps). */ | |
3631 | 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 | 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 | 62 /* Add new data to circular queue designed to be used with a FIR |
63 filter. xq is the circular queue, in pointing at the new sample, xi | |
64 current index for in xq and l the lenght of the filter */ | |
65 inline uint16_t updateq(int16_t* xq, int16_t* in, uint16_t xi, uint16_t l) | |
66 { | |
67 xq[xi]=xq[xi+l]=*in; | |
68 return (--xi)&(l-1); \ | |
3631 | 69 } |
70 | |
71 #endif /* __FIR_H__ */ | |
4789 | 72 |