diff options
-rw-r--r-- | apps/eq.c | 14 | ||||
-rw-r--r-- | apps/eq_cf.S | 17 |
2 files changed, 18 insertions, 13 deletions
@@ -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 |