From 9636c1b61eb93897bffd4db96ddc9678c6aff245 Mon Sep 17 00:00:00 2001 From: Thom Johansen Date: Tue, 27 Feb 2007 17:33:23 +0000 Subject: 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 --- apps/dsp.c | 34 +++++++++------------- apps/dsp_arm.S | 91 +++++++++++++++++++++++++++++----------------------------- apps/dsp_asm.h | 12 +------- 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 int32_t coefs[3]; /* 04h - Coefficients for the shelving filter */ int32_t history[4]; /* 10h - Format is x[n - 1], y[n - 1] for both channels */ int32_t delay[13][2]; /* 20h */ - int index; /* 88h - Current index/pointer into the delay line */ + int32_t *index; /* 88h - Current pointer into the delay line */ /* 8ch */ }; @@ -138,10 +138,6 @@ typedef int (*resample_fn_type)(int count, struct dsp_data *data, int32_t *src[], int32_t *dst[]); typedef void (*sample_output_fn_type)(int count, struct dsp_data *data, int32_t *src[], int16_t *dst); -/* If ACF_SWITCHPARAM is no longer needed, make apply_crossfeed of type - channels_process_fn_type since it is really just that */ -typedef void (*apply_crossfeed_fn_type)(ACF_SWITCHPARAM(int count, - int32_t *buf[])); typedef void (*channels_process_fn_type)(int count, int32_t *buf[]); /* @@ -164,7 +160,7 @@ struct dsp_config sample_output_fn_type output_samples; /* These will be NULL for the voice codec and is more economical that way */ - apply_crossfeed_fn_type apply_crossfeed; + channels_process_fn_type apply_crossfeed; channels_process_fn_type channels_process; }; @@ -175,14 +171,10 @@ static struct dither_data dither_data[2] IBSS_ATTR; /* 0=left, 1=right */ static long dither_mask IBSS_ATTR; static long dither_bias IBSS_ATTR; /* Crossfeed */ -#ifdef DSP_CROSSFEED_DELAY_PTR struct crossfeed_data crossfeed_data IDATA_ATTR = /* A */ { - .index = (intptr_t)crossfeed_data.delay + .index = (int32_t *)crossfeed_data.delay }; -#else -struct crossfeed_data crossfeed_data IBSS_ATTR; /* A */ -#endif /* Equalizer */ static struct eq_state eq_data; /* A/V */ @@ -719,7 +711,7 @@ static void apply_crossfeed(int count, int32_t *buf[]) int32_t *delay = &crossfeed_data.delay[0][0]; int32_t *coefs = &crossfeed_data.coefs[0]; int32_t gain = crossfeed_data.gain; - int di = crossfeed_data.index; + int32_t *di = crossfeed_data.index; int32_t acc; int32_t left, right; @@ -731,28 +723,28 @@ static void apply_crossfeed(int count, int32_t *buf[]) right = buf[1][i]; /* Filter delayed sample from left speaker */ - ACC_INIT(acc, delay[di*2], coefs[0]); + ACC_INIT(acc, *di, coefs[0]); ACC(acc, hist_l[0], coefs[1]); ACC(acc, hist_l[1], coefs[2]); /* Save filter history for left speaker */ hist_l[1] = GET_ACC(acc); - hist_l[0] = delay[di*2]; + hist_l[0] = *di; + *di++ = left; /* Filter delayed sample from right speaker */ - ACC_INIT(acc, delay[di*2 + 1], coefs[0]); + ACC_INIT(acc, *di, coefs[0]); ACC(acc, hist_r[0], coefs[1]); ACC(acc, hist_r[1], coefs[2]); /* Save filter history for right speaker */ hist_r[1] = GET_ACC(acc); - hist_r[0] = delay[di*2 + 1]; - delay[di*2] = left; - delay[di*2 + 1] = right; + hist_r[0] = *di; + *di++ = right; /* Now add the attenuated direct sound and write to outputs */ buf[0][i] = FRACMUL(left, gain) + hist_r[1]; buf[1][i] = FRACMUL(right, gain) + hist_l[1]; /* Wrap delay line index if bigger than delay line size */ - if (++di > 12) - di = 0; + if (di >= delay + 13*2) + di = delay; } /* Write back local copies of data we've modified */ crossfeed_data.index = di; @@ -1127,7 +1119,7 @@ int dsp_process(char *dst, const char *src[], int count) if ((samples = resample(samples, tmp)) <= 0) break; /* I'm pretty sure we're downsampling here */ if (dsp->apply_crossfeed) - dsp->apply_crossfeed(ACF_SWITCHPARAM(samples, tmp)); + dsp->apply_crossfeed(samples, tmp); /* TODO: EQ and tone controls need separate structs for audio and voice * DSP processing thanks to filter history. isn't really audible now, but * 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 @@ * \/ \/ \/ \/ \/ * $Id$ * - * Copyright (C) 2006 Thom Johansen + * Copyright (C) 2006-2007 Thom Johansen * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. @@ -17,63 +17,64 @@ * ****************************************************************************/ +/* + * void apply_crossfeed(int count, int32_t* src[]) + */ .section .text .global apply_crossfeed apply_crossfeed: @ unfortunately, we ended up in a bit of a register squeeze here, and need @ to keep both the count and the delay line index on the stack :/ - stmdb sp!, { r4-r11, lr } @ stack modified regs - ldmia r0, { r2-r3 } @ r2 = src[0], r3 = src[1] + stmdb sp!, { r4-r11, lr } @ stack modified regs + ldmia r1, { r2-r3 } @ r2 = src[0], r3 = src[1] - ldr r0, =crossfeed_data - ldmia r0!, { r4-r11 } @ load direct gain and filter data - ldr r12, [r0, #13*4*2] @ fetch delay line index - add r0, r0, r12, lsl #3 @ r0 = &delay[index][0] - stmdb sp!, { r1, r12 } @ stack count and delay line index + ldr r1, =crossfeed_data + ldmia r1!, { r4-r11 } @ load direct gain and filter data + add r12, r1, #13*4*2 @ calculate end of delay + stmdb sp!, { r0, r12 } @ stack count and end of delay adr + ldr r0, [r1, #13*4*2] @ fetch current delay line address + /* Register usage in loop: * r0 = &delay[index][0], r1 = accumulator high, r2 = src[0], r3 = src[1], * r4 = direct gain, r5-r7 = b0, b1, a1 (filter coefs), * r8-r11 = filter history, r12 = temp, r14 = accumulator low */ .cfloop: - smull r14, r1, r6, r8 @ acc = b1*dr[n - 1] - smlal r14, r1, r7, r9 @ acc += a1*y_l[n - 1] - ldr r8, [r0, #4] @ r8 = dr[n] - smlal r14, r1, r5, r8 @ acc += b0*dr[n] - mov r9, r1, lsl #1 @ fix format for filter history - ldr r12, [r2] @ load left input - smlal r14, r1, r4, r12 @ acc += gain*x_l[n] - mov r1, r1, lsl #1 @ fix format - str r1, [r2], #4 @ save result - - smull r14, r1, r6, r10 @ acc = b1*dl[n - 1] - smlal r14, r1, r7, r11 @ acc += a1*y_r[n - 1] - ldr r10, [r0] @ r10 = dl[n] - str r12, [r0], #4 @ save left input to delay line - smlal r14, r1, r5, r10 @ acc += b0*dl[n] - mov r11, r1, lsl #1 @ fix format for filter history - ldr r12, [r3] @ load right input - smlal r14, r1, r4, r12 @ acc += gain*x_r[n] - str r12, [r0], #4 @ save right input to delay line - mov r1, r1, lsl #1 @ fix format - str r1, [r3], #4 @ save result + smull r14, r1, r6, r8 @ acc = b1*dr[n - 1] + smlal r14, r1, r7, r9 @ acc += a1*y_l[n - 1] + ldr r8, [r0, #4] @ r8 = dr[n] + smlal r14, r1, r5, r8 @ acc += b0*dr[n] + mov r9, r1, lsl #1 @ fix format for filter history + ldr r12, [r2] @ load left input + smlal r14, r1, r4, r12 @ acc += gain*x_l[n] + mov r1, r1, lsl #1 @ fix format + str r1, [r2], #4 @ save result - ldr r12, [sp, #4] @ fetch delay line index from stack - add r12, r12, #1 @ increment index - cmp r12, #13 @ do we need to wrap to start of delay? - moveq r12, #0 @ yes, wrap index to 0 - subeq r0, r0, #13*4*2 @ also wrap back delay line ptr to start - str r12, [sp, #4] @ stack delay line index again - - ldr r1, [sp] @ fetch count from stack - subs r1, r1, #1 @ are we finished? - strne r1, [sp] @ nope, save count back to stack - bne .cfloop + smull r14, r1, r6, r10 @ acc = b1*dl[n - 1] + smlal r14, r1, r7, r11 @ acc += a1*y_r[n - 1] + ldr r10, [r0] @ r10 = dl[n] + str r12, [r0], #4 @ save left input to delay line + smlal r14, r1, r5, r10 @ acc += b0*dl[n] + mov r11, r1, lsl #1 @ fix format for filter history + ldr r12, [r3] @ load right input + smlal r14, r1, r4, r12 @ acc += gain*x_r[n] + str r12, [r0], #4 @ save right input to delay line + mov r1, r1, lsl #1 @ fix format + str r1, [r3], #4 @ save result + + ldr r12, [sp, #4] @ fetch delay line end addr from stack + cmp r0, r12 @ need to wrap to start of delay? + subeq r0, r0, #13*4*2 @ wrap back delay line ptr to start + + ldr r1, [sp] @ fetch count from stack + subs r1, r1, #1 @ are we finished? + strne r1, [sp] @ nope, save count back to stack + bne .cfloop @ save data back to struct - ldr r0, =crossfeed_data + 4*4 - stmia r0, { r8-r11 } @ save filter history - str r12, [r0, #30*4] @ save delay line index - add sp, sp, #8 @ remove temp variables from stack - ldmia sp!, { r4-r11, pc } + ldr r12, =crossfeed_data + 4*4 + stmia r12, { r8-r11 } @ save filter history + str r0, [r12, #30*4] @ save delay line index + add sp, sp, #8 @ remove temp variables from stack + ldmia sp!, { r4-r11, pc } 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 @@ #ifndef _DSP_ASM_H #define _DSP_ASM_H -#define ACF_SWITCHPARAM(count, buf) count, buf - #ifndef SIMULATOR #if defined(CPU_COLDFIRE) || defined(CPU_ARM) #define DSP_HAVE_ASM_CROSSFEED -#if defined(CPU_COLDFIRE) -/* ACF_SWITCHPARAM can be stripped out if all have the same parameter - order - DSP_CROSSFEED_DELAY_PTR if all use a pointer instead of index */ -#define DSP_CROSSFEED_DELAY_PTR -#else -#undef ACF_SWITCHPARAM -#define ACF_SWITCHPARAM(count, buf) buf, count -#endif -void apply_crossfeed(ACF_SWITCHPARAM(int count, int32_t *buf[])); +void apply_crossfeed(int count, int32_t *buf[]); #endif /* defined(CPU_COLDFIRE) || defined(CPU_ARM) */ #if defined (CPU_COLDFIRE) -- cgit v1.2.3