summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom Johansen <thomj@rockbox.org>2007-02-27 17:33:23 +0000
committerThom Johansen <thomj@rockbox.org>2007-02-27 17:33:23 +0000
commit9636c1b61eb93897bffd4db96ddc9678c6aff245 (patch)
treef718bfba9c86418d415eb71b1a2ad0891210aca4
parent342337031cc7c20c141fb11a0d7aa900e89e022e (diff)
downloadrockbox-9636c1b61eb93897bffd4db96ddc9678c6aff245.tar.gz
rockbox-9636c1b61eb93897bffd4db96ddc9678c6aff245.zip
Adapt ARM crossfeed assembler to work like the Coldfire one. Remove SWITCHPARAM cruft as it's no longer needed.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12507 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/dsp.c34
-rw-r--r--apps/dsp_arm.S91
-rw-r--r--apps/dsp_asm.h12
3 files changed, 60 insertions, 77 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index d27df0500c..cca94ae075 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -112,7 +112,7 @@ struct crossfeed_data
112 int32_t coefs[3]; /* 04h - Coefficients for the shelving filter */ 112 int32_t coefs[3]; /* 04h - Coefficients for the shelving filter */
113 int32_t history[4]; /* 10h - Format is x[n - 1], y[n - 1] for both channels */ 113 int32_t history[4]; /* 10h - Format is x[n - 1], y[n - 1] for both channels */
114 int32_t delay[13][2]; /* 20h */ 114 int32_t delay[13][2]; /* 20h */
115 int index; /* 88h - Current index/pointer into the delay line */ 115 int32_t *index; /* 88h - Current pointer into the delay line */
116 /* 8ch */ 116 /* 8ch */
117}; 117};
118 118
@@ -138,10 +138,6 @@ typedef int (*resample_fn_type)(int count, struct dsp_data *data,
138 int32_t *src[], int32_t *dst[]); 138 int32_t *src[], int32_t *dst[]);
139typedef void (*sample_output_fn_type)(int count, struct dsp_data *data, 139typedef void (*sample_output_fn_type)(int count, struct dsp_data *data,
140 int32_t *src[], int16_t *dst); 140 int32_t *src[], int16_t *dst);
141/* If ACF_SWITCHPARAM is no longer needed, make apply_crossfeed of type
142 channels_process_fn_type since it is really just that */
143typedef void (*apply_crossfeed_fn_type)(ACF_SWITCHPARAM(int count,
144 int32_t *buf[]));
145typedef void (*channels_process_fn_type)(int count, int32_t *buf[]); 141typedef void (*channels_process_fn_type)(int count, int32_t *buf[]);
146 142
147/* 143/*
@@ -164,7 +160,7 @@ struct dsp_config
164 sample_output_fn_type output_samples; 160 sample_output_fn_type output_samples;
165 /* These will be NULL for the voice codec and is more economical that 161 /* These will be NULL for the voice codec and is more economical that
166 way */ 162 way */
167 apply_crossfeed_fn_type apply_crossfeed; 163 channels_process_fn_type apply_crossfeed;
168 channels_process_fn_type channels_process; 164 channels_process_fn_type channels_process;
169}; 165};
170 166
@@ -175,14 +171,10 @@ static struct dither_data dither_data[2] IBSS_ATTR; /* 0=left, 1=right */
175static long dither_mask IBSS_ATTR; 171static long dither_mask IBSS_ATTR;
176static long dither_bias IBSS_ATTR; 172static long dither_bias IBSS_ATTR;
177/* Crossfeed */ 173/* Crossfeed */
178#ifdef DSP_CROSSFEED_DELAY_PTR
179struct crossfeed_data crossfeed_data IDATA_ATTR = /* A */ 174struct crossfeed_data crossfeed_data IDATA_ATTR = /* A */
180{ 175{
181 .index = (intptr_t)crossfeed_data.delay 176 .index = (int32_t *)crossfeed_data.delay
182}; 177};
183#else
184struct crossfeed_data crossfeed_data IBSS_ATTR; /* A */
185#endif
186 178
187/* Equalizer */ 179/* Equalizer */
188static struct eq_state eq_data; /* A/V */ 180static struct eq_state eq_data; /* A/V */
@@ -719,7 +711,7 @@ static void apply_crossfeed(int count, int32_t *buf[])
719 int32_t *delay = &crossfeed_data.delay[0][0]; 711 int32_t *delay = &crossfeed_data.delay[0][0];
720 int32_t *coefs = &crossfeed_data.coefs[0]; 712 int32_t *coefs = &crossfeed_data.coefs[0];
721 int32_t gain = crossfeed_data.gain; 713 int32_t gain = crossfeed_data.gain;
722 int di = crossfeed_data.index; 714 int32_t *di = crossfeed_data.index;
723 715
724 int32_t acc; 716 int32_t acc;
725 int32_t left, right; 717 int32_t left, right;
@@ -731,28 +723,28 @@ static void apply_crossfeed(int count, int32_t *buf[])
731 right = buf[1][i]; 723 right = buf[1][i];
732 724
733 /* Filter delayed sample from left speaker */ 725 /* Filter delayed sample from left speaker */
734 ACC_INIT(acc, delay[di*2], coefs[0]); 726 ACC_INIT(acc, *di, coefs[0]);
735 ACC(acc, hist_l[0], coefs[1]); 727 ACC(acc, hist_l[0], coefs[1]);
736 ACC(acc, hist_l[1], coefs[2]); 728 ACC(acc, hist_l[1], coefs[2]);
737 /* Save filter history for left speaker */ 729 /* Save filter history for left speaker */
738 hist_l[1] = GET_ACC(acc); 730 hist_l[1] = GET_ACC(acc);
739 hist_l[0] = delay[di*2]; 731 hist_l[0] = *di;
732 *di++ = left;
740 /* Filter delayed sample from right speaker */ 733 /* Filter delayed sample from right speaker */
741 ACC_INIT(acc, delay[di*2 + 1], coefs[0]); 734 ACC_INIT(acc, *di, coefs[0]);
742 ACC(acc, hist_r[0], coefs[1]); 735 ACC(acc, hist_r[0], coefs[1]);
743 ACC(acc, hist_r[1], coefs[2]); 736 ACC(acc, hist_r[1], coefs[2]);
744 /* Save filter history for right speaker */ 737 /* Save filter history for right speaker */
745 hist_r[1] = GET_ACC(acc); 738 hist_r[1] = GET_ACC(acc);
746 hist_r[0] = delay[di*2 + 1]; 739 hist_r[0] = *di;
747 delay[di*2] = left; 740 *di++ = right;
748 delay[di*2 + 1] = right;
749 /* Now add the attenuated direct sound and write to outputs */ 741 /* Now add the attenuated direct sound and write to outputs */
750 buf[0][i] = FRACMUL(left, gain) + hist_r[1]; 742 buf[0][i] = FRACMUL(left, gain) + hist_r[1];
751 buf[1][i] = FRACMUL(right, gain) + hist_l[1]; 743 buf[1][i] = FRACMUL(right, gain) + hist_l[1];
752 744
753 /* Wrap delay line index if bigger than delay line size */ 745 /* Wrap delay line index if bigger than delay line size */
754 if (++di > 12) 746 if (di >= delay + 13*2)
755 di = 0; 747 di = delay;
756 } 748 }
757 /* Write back local copies of data we've modified */ 749 /* Write back local copies of data we've modified */
758 crossfeed_data.index = di; 750 crossfeed_data.index = di;
@@ -1127,7 +1119,7 @@ int dsp_process(char *dst, const char *src[], int count)
1127 if ((samples = resample(samples, tmp)) <= 0) 1119 if ((samples = resample(samples, tmp)) <= 0)
1128 break; /* I'm pretty sure we're downsampling here */ 1120 break; /* I'm pretty sure we're downsampling here */
1129 if (dsp->apply_crossfeed) 1121 if (dsp->apply_crossfeed)
1130 dsp->apply_crossfeed(ACF_SWITCHPARAM(samples, tmp)); 1122 dsp->apply_crossfeed(samples, tmp);
1131 /* TODO: EQ and tone controls need separate structs for audio and voice 1123 /* TODO: EQ and tone controls need separate structs for audio and voice
1132 * DSP processing thanks to filter history. isn't really audible now, but 1124 * DSP processing thanks to filter history. isn't really audible now, but
1133 * might be the day we start handling voice more delicately. 1125 * might be the day we start handling voice more delicately.
diff --git a/apps/dsp_arm.S b/apps/dsp_arm.S
index 1abfd34983..27669203f1 100644
--- a/apps/dsp_arm.S
+++ b/apps/dsp_arm.S
@@ -7,7 +7,7 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2006 Thom Johansen 10 * Copyright (C) 2006-2007 Thom Johansen
11 * 11 *
12 * All files in this archive are subject to the GNU General Public License. 12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement. 13 * See the file COPYING in the source tree root for full license agreement.
@@ -17,63 +17,64 @@
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19 19
20/*
21 * void apply_crossfeed(int count, int32_t* src[])
22 */
20 .section .text 23 .section .text
21 .global apply_crossfeed 24 .global apply_crossfeed
22apply_crossfeed: 25apply_crossfeed:
23 @ unfortunately, we ended up in a bit of a register squeeze here, and need 26 @ unfortunately, we ended up in a bit of a register squeeze here, and need
24 @ to keep both the count and the delay line index on the stack :/ 27 @ to keep both the count and the delay line index on the stack :/
25 stmdb sp!, { r4-r11, lr } @ stack modified regs 28 stmdb sp!, { r4-r11, lr } @ stack modified regs
26 ldmia r0, { r2-r3 } @ r2 = src[0], r3 = src[1] 29 ldmia r1, { r2-r3 } @ r2 = src[0], r3 = src[1]
27 30
28 ldr r0, =crossfeed_data 31 ldr r1, =crossfeed_data
29 ldmia r0!, { r4-r11 } @ load direct gain and filter data 32 ldmia r1!, { r4-r11 } @ load direct gain and filter data
30 ldr r12, [r0, #13*4*2] @ fetch delay line index 33 add r12, r1, #13*4*2 @ calculate end of delay
31 add r0, r0, r12, lsl #3 @ r0 = &delay[index][0] 34 stmdb sp!, { r0, r12 } @ stack count and end of delay adr
32 stmdb sp!, { r1, r12 } @ stack count and delay line index 35 ldr r0, [r1, #13*4*2] @ fetch current delay line address
36
33 /* Register usage in loop: 37 /* Register usage in loop:
34 * r0 = &delay[index][0], r1 = accumulator high, r2 = src[0], r3 = src[1], 38 * r0 = &delay[index][0], r1 = accumulator high, r2 = src[0], r3 = src[1],
35 * r4 = direct gain, r5-r7 = b0, b1, a1 (filter coefs), 39 * r4 = direct gain, r5-r7 = b0, b1, a1 (filter coefs),
36 * r8-r11 = filter history, r12 = temp, r14 = accumulator low 40 * r8-r11 = filter history, r12 = temp, r14 = accumulator low
37 */ 41 */
38.cfloop: 42.cfloop:
39 smull r14, r1, r6, r8 @ acc = b1*dr[n - 1] 43 smull r14, r1, r6, r8 @ acc = b1*dr[n - 1]
40 smlal r14, r1, r7, r9 @ acc += a1*y_l[n - 1] 44 smlal r14, r1, r7, r9 @ acc += a1*y_l[n - 1]
41 ldr r8, [r0, #4] @ r8 = dr[n] 45 ldr r8, [r0, #4] @ r8 = dr[n]
42 smlal r14, r1, r5, r8 @ acc += b0*dr[n] 46 smlal r14, r1, r5, r8 @ acc += b0*dr[n]
43 mov r9, r1, lsl #1 @ fix format for filter history 47 mov r9, r1, lsl #1 @ fix format for filter history
44 ldr r12, [r2] @ load left input 48 ldr r12, [r2] @ load left input
45 smlal r14, r1, r4, r12 @ acc += gain*x_l[n] 49 smlal r14, r1, r4, r12 @ acc += gain*x_l[n]
46 mov r1, r1, lsl #1 @ fix format 50 mov r1, r1, lsl #1 @ fix format
47 str r1, [r2], #4 @ save result 51 str r1, [r2], #4 @ save result
48
49 smull r14, r1, r6, r10 @ acc = b1*dl[n - 1]
50 smlal r14, r1, r7, r11 @ acc += a1*y_r[n - 1]
51 ldr r10, [r0] @ r10 = dl[n]
52 str r12, [r0], #4 @ save left input to delay line
53 smlal r14, r1, r5, r10 @ acc += b0*dl[n]
54 mov r11, r1, lsl #1 @ fix format for filter history
55 ldr r12, [r3] @ load right input
56 smlal r14, r1, r4, r12 @ acc += gain*x_r[n]
57 str r12, [r0], #4 @ save right input to delay line
58 mov r1, r1, lsl #1 @ fix format
59 str r1, [r3], #4 @ save result
60 52
61 ldr r12, [sp, #4] @ fetch delay line index from stack 53 smull r14, r1, r6, r10 @ acc = b1*dl[n - 1]
62 add r12, r12, #1 @ increment index 54 smlal r14, r1, r7, r11 @ acc += a1*y_r[n - 1]
63 cmp r12, #13 @ do we need to wrap to start of delay? 55 ldr r10, [r0] @ r10 = dl[n]
64 moveq r12, #0 @ yes, wrap index to 0 56 str r12, [r0], #4 @ save left input to delay line
65 subeq r0, r0, #13*4*2 @ also wrap back delay line ptr to start 57 smlal r14, r1, r5, r10 @ acc += b0*dl[n]
66 str r12, [sp, #4] @ stack delay line index again 58 mov r11, r1, lsl #1 @ fix format for filter history
67 59 ldr r12, [r3] @ load right input
68 ldr r1, [sp] @ fetch count from stack 60 smlal r14, r1, r4, r12 @ acc += gain*x_r[n]
69 subs r1, r1, #1 @ are we finished? 61 str r12, [r0], #4 @ save right input to delay line
70 strne r1, [sp] @ nope, save count back to stack 62 mov r1, r1, lsl #1 @ fix format
71 bne .cfloop 63 str r1, [r3], #4 @ save result
64
65 ldr r12, [sp, #4] @ fetch delay line end addr from stack
66 cmp r0, r12 @ need to wrap to start of delay?
67 subeq r0, r0, #13*4*2 @ wrap back delay line ptr to start
68
69 ldr r1, [sp] @ fetch count from stack
70 subs r1, r1, #1 @ are we finished?
71 strne r1, [sp] @ nope, save count back to stack
72 bne .cfloop
72 73
73 @ save data back to struct 74 @ save data back to struct
74 ldr r0, =crossfeed_data + 4*4 75 ldr r12, =crossfeed_data + 4*4
75 stmia r0, { r8-r11 } @ save filter history 76 stmia r12, { r8-r11 } @ save filter history
76 str r12, [r0, #30*4] @ save delay line index 77 str r0, [r12, #30*4] @ save delay line index
77 add sp, sp, #8 @ remove temp variables from stack 78 add sp, sp, #8 @ remove temp variables from stack
78 ldmia sp!, { r4-r11, pc } 79 ldmia sp!, { r4-r11, pc }
79 80
diff --git a/apps/dsp_asm.h b/apps/dsp_asm.h
index a9e7fac6b0..ee90f5763e 100644
--- a/apps/dsp_asm.h
+++ b/apps/dsp_asm.h
@@ -22,21 +22,11 @@
22#ifndef _DSP_ASM_H 22#ifndef _DSP_ASM_H
23#define _DSP_ASM_H 23#define _DSP_ASM_H
24 24
25#define ACF_SWITCHPARAM(count, buf) count, buf
26
27#ifndef SIMULATOR 25#ifndef SIMULATOR
28 26
29#if defined(CPU_COLDFIRE) || defined(CPU_ARM) 27#if defined(CPU_COLDFIRE) || defined(CPU_ARM)
30#define DSP_HAVE_ASM_CROSSFEED 28#define DSP_HAVE_ASM_CROSSFEED
31#if defined(CPU_COLDFIRE) 29void apply_crossfeed(int count, int32_t *buf[]);
32/* ACF_SWITCHPARAM can be stripped out if all have the same parameter
33 order - DSP_CROSSFEED_DELAY_PTR if all use a pointer instead of index */
34#define DSP_CROSSFEED_DELAY_PTR
35#else
36#undef ACF_SWITCHPARAM
37#define ACF_SWITCHPARAM(count, buf) buf, count
38#endif
39void apply_crossfeed(ACF_SWITCHPARAM(int count, int32_t *buf[]));
40#endif /* defined(CPU_COLDFIRE) || defined(CPU_ARM) */ 30#endif /* defined(CPU_COLDFIRE) || defined(CPU_ARM) */
41 31
42#if defined (CPU_COLDFIRE) 32#if defined (CPU_COLDFIRE)