summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom Johansen <thomj@rockbox.org>2006-01-29 17:52:13 +0000
committerThom Johansen <thomj@rockbox.org>2006-01-29 17:52:13 +0000
commit65721f0b3573460d306528ff34aa395c45e94ea3 (patch)
treece1476b13c66ba067d3944fabaac949aa78afb11
parenta371ec3e77f7fcc6d498c747ad46ede7900e0bde (diff)
downloadrockbox-65721f0b3573460d306528ff34aa395c45e94ea3.tar.gz
rockbox-65721f0b3573460d306528ff34aa395c45e94ea3.zip
Slight change of coef format. Removed erronous hard code of channel
number in EQ filtering routine and added some minor changes. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8486 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/eq.c14
-rw-r--r--apps/eq_cf.S17
2 files changed, 18 insertions, 13 deletions
diff --git a/apps/eq.c b/apps/eq.c
index 8ad886fc0c..3d2f8d133d 100644
--- a/apps/eq.c
+++ b/apps/eq.c
@@ -24,6 +24,8 @@
24 Slightly faster calculation can be done by deriving forms which use tan() 24 Slightly faster calculation can be done by deriving forms which use tan()
25 instead of cos() and sin(), but the latter are far easier to use when doing 25 instead of cos() and sin(), but the latter are far easier to use when doing
26 fixed point math, and performance is not a big point in the calculation part. 26 fixed point math, and performance is not a big point in the calculation part.
27 All the 'a' filter coefficients are negated so we can use only additions
28 in the filtering equation.
27 We realise the filters as a second order direct form 1 structure. Direct 29 We realise the filters as a second order direct form 1 structure. Direct
28 form 1 was chosen because of better numerical properties for fixed point 30 form 1 was chosen because of better numerical properties for fixed point
29 implementations. 31 implementations.
@@ -153,8 +155,8 @@ void eq_pk_coefs(unsigned long cutoff, unsigned long Q, long db, long *c)
153 c[0] = DIV64(b0, a0, 28); 155 c[0] = DIV64(b0, a0, 28);
154 c[1] = DIV64(b1, a0, 28); 156 c[1] = DIV64(b1, a0, 28);
155 c[2] = DIV64(b2, a0, 28); 157 c[2] = DIV64(b2, a0, 28);
156 c[3] = DIV64(a1, a0, 28); 158 c[3] = DIV64(-a1, a0, 28);
157 c[4] = DIV64(a2, a0, 28); 159 c[4] = DIV64(-a2, a0, 28);
158} 160}
159 161
160/* Calculate coefficients for lowshelf filter */ 162/* Calculate coefficients for lowshelf filter */
@@ -180,8 +182,8 @@ void eq_ls_coefs(unsigned long cutoff, unsigned long Q, long db, long *c)
180 c[0] = DIV64(b0, a0, 24); 182 c[0] = DIV64(b0, a0, 24);
181 c[1] = DIV64(b1, a0, 24); 183 c[1] = DIV64(b1, a0, 24);
182 c[2] = DIV64(b2, a0, 24); 184 c[2] = DIV64(b2, a0, 24);
183 c[3] = DIV64(a1, a0, 24); 185 c[3] = DIV64(-a1, a0, 24);
184 c[4] = DIV64(a2, a0, 24); 186 c[4] = DIV64(-a2, a0, 24);
185} 187}
186 188
187/* Calculate coefficients for highshelf filter */ 189/* Calculate coefficients for highshelf filter */
@@ -207,8 +209,8 @@ void eq_hs_coefs(unsigned long cutoff, unsigned long Q, long db, long *c)
207 c[0] = DIV64(b0, a0, 24); 209 c[0] = DIV64(b0, a0, 24);
208 c[1] = DIV64(b1, a0, 24); 210 c[1] = DIV64(b1, a0, 24);
209 c[2] = DIV64(b2, a0, 24); 211 c[2] = DIV64(b2, a0, 24);
210 c[3] = DIV64(a1, a0, 24); 212 c[3] = DIV64(-a1, a0, 24);
211 c[4] = DIV64(a2, a0, 24); 213 c[4] = DIV64(-a2, a0, 24);
212} 214}
213 215
214#if !defined(CPU_COLDFIRE) || defined(SIMULATOR) 216#if !defined(CPU_COLDFIRE) || defined(SIMULATOR)
diff --git a/apps/eq_cf.S b/apps/eq_cf.S
index 3876ca72d6..0a34d7707e 100644
--- a/apps/eq_cf.S
+++ b/apps/eq_cf.S
@@ -26,21 +26,24 @@ eq_filter:
26 movem.l (11*4+16, %sp), %d6-%d7 | load num. channels and shift count 26 movem.l (11*4+16, %sp), %d6-%d7 | load num. channels and shift count
27 movem.l (%a5), %a0-%a4 | load coefs 27 movem.l (%a5), %a0-%a4 | load coefs
28 lea.l (5*4, %a5), %a5 | point to filter history 28 lea.l (5*4, %a5), %a5 | point to filter history
29 moveq.l #2, %d6 | number of channels (hardcode to stereo)
30 29
31.filterloop: 30.filterloop:
32 move.l (11*4+4, %sp), %a6 | load input channel pointer 31 move.l (11*4+4, %sp), %a6 | load input channel pointer
32 addq.l #4, (11*4+4, %sp) | point x to next channel
33 move.l (%a6), %a6 33 move.l (%a6), %a6
34 move.l (11*4+12, %sp), %d5 | number of samples 34 move.l (11*4+12, %sp), %d5 | number of samples
35 addq.l #4, (11*4+4, %sp) | point x to next channel
36 movem.l (%a5), %d0-%d3 | load filter history 35 movem.l (%a5), %d0-%d3 | load filter history
37.loop: 36.loop:
38 move.l (%a6), %d4 37 /* Direct form 1 filtering code. We assume DSP has put EMAC in frac mode.
39 mac.l %a0, %d4, %acc0 | acc = b0*x[i] 38 y[n] = b0*x[i] + b1*x[i - 1] + b2*x[i - 2] + a1*y[i - 1] + a2*y[i - 2],
40 mac.l %a1, %d0, %acc0 | acc += b1*x[i - 1] 39 where y[] is output and x[] is input. This is performed out of order
40 to do parallel load of input value.
41 */
42 mac.l %a1, %d0, (%a6), %d4, %acc0 | acc = b1*x[i - 1], x[i] -> d4
41 mac.l %a2, %d1, %acc0 | acc += b2*x[i - 2] 43 mac.l %a2, %d1, %acc0 | acc += b2*x[i - 2]
42 msac.l %a3, %d2, %acc0 | acc -= a1*y[i - 1] 44 mac.l %a0, %d4, %acc0 | acc += b0*x[i]
43 msac.l %a4, %d3, %acc0 | acc -= a2*y[i - 2] 45 mac.l %a3, %d2, %acc0 | acc += a1*y[i - 1]
46 mac.l %a4, %d3, %acc0 | acc += a2*y[i - 2]
44 move.l %d0, %d1 | fix history 47 move.l %d0, %d1 | fix history
45 move.l %d4, %d0 48 move.l %d4, %d0
46 move.l %d2, %d3 49 move.l %d2, %d3