From 55ff456c4615b4cedc1d936d510abe4d92403b61 Mon Sep 17 00:00:00 2001 From: Thom Johansen Date: Sun, 29 Jan 2006 15:37:03 +0000 Subject: Recommit reverted changes and add the missing file... git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8484 a1c6a512-1295-4272-9138-f99709370657 --- apps/SOURCES | 4 ++++ apps/dsp.c | 34 +++++++++++++++++++++++++++++++++ apps/eq_cf.S | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 apps/eq_cf.S diff --git a/apps/SOURCES b/apps/SOURCES index cf17bbc27c..cd2316fc24 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -76,4 +76,8 @@ playback.c metadata.c codecs.c dsp.c +eq.c +#if defined(CPU_COLDFIRE) && !defined(SIMULATOR) +eq_cf.S +#endif #endif diff --git a/apps/dsp.c b/apps/dsp.c index 19cb669a06..b2fc0ce7a2 100644 --- a/apps/dsp.c +++ b/apps/dsp.c @@ -19,6 +19,7 @@ #include #include #include "dsp.h" +#include "eq.h" #include "kernel.h" #include "playback.h" #include "system.h" @@ -166,10 +167,21 @@ struct crossfeed_data int index; }; +/* Current setup is one lowshelf filters, three peaking filters and one + highshelf filter. Varying the number of shelving filters make no sense, + but adding peaking filters are possible. */ +struct eq_state { + char enabled[5]; /* Flags for active filters */ + struct eqfilter ls; + struct eqfilter pk[3]; + struct eqfilter hs; +}; + static struct dsp_config dsp_conf[2] IBSS_ATTR; static struct dither_data dither_data[2] IBSS_ATTR; static struct resample_data resample_data[2] IBSS_ATTR; struct crossfeed_data crossfeed_data IBSS_ATTR; +static struct eq_state eq_data; static int pitch_ratio = 1000; @@ -608,6 +620,25 @@ static void apply_crossfeed(long* src[], int count) } #endif +/* Apply EQ filters to those bands that have got it switched on. */ +void eq_process(long **x, unsigned num) +{ + int i; + unsigned int channels = dsp->stereo_mode != STEREO_MONO ? 2 : 1; + + /* filter configuration currently is 1 low shelf filter, 3 band peaking + filters and 1 high shelf filter, in that order. + */ + if (eq_data.enabled[0]) + eq_filter(x, &eq_data.ls, num, channels, EQ_SHELF_SHIFT); + for (i = 0; i < 3; i++) { + if (eq_data.enabled[1 + i]) + eq_filter(x, &eq_data.pk[i], num, channels, EQ_PEAK_SHIFT); + } + if (eq_data.enabled[4]) + eq_filter(x, &eq_data.hs, num, channels, EQ_SHELF_SHIFT); +} + /* Apply a constant gain to the samples (e.g., for ReplayGain). May update * the src array if gain was applied. * Note that this must be called before the resampler. @@ -713,6 +744,9 @@ long dsp_process(char* dst, char* src[], long size) samples = resample(tmp, samples); if (dsp->crossfeed_enabled && dsp->stereo_mode != STEREO_MONO) apply_crossfeed(tmp, samples); + /* TODO: Might want to wrap this with a generic eq_enabled when the + settings are in place */ + eq_process(tmp, samples); write_samples((short*) dst, tmp, samples); written += samples; dst += samples * sizeof(short) * 2; diff --git a/apps/eq_cf.S b/apps/eq_cf.S new file mode 100644 index 0000000000..3876ca72d6 --- /dev/null +++ b/apps/eq_cf.S @@ -0,0 +1,61 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 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. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + .text + .global eq_filter +eq_filter: + lea.l (-11*4, %sp), %sp + movem.l %d2-%d7/%a2-%a6, (%sp) | save clobbered regs + move.l (11*4+8, %sp), %a5 | fetch filter structure address + movem.l (11*4+16, %sp), %d6-%d7 | load num. channels and shift count + movem.l (%a5), %a0-%a4 | load coefs + lea.l (5*4, %a5), %a5 | point to filter history + moveq.l #2, %d6 | number of channels (hardcode to stereo) + +.filterloop: + move.l (11*4+4, %sp), %a6 | load input channel pointer + move.l (%a6), %a6 + move.l (11*4+12, %sp), %d5 | number of samples + addq.l #4, (11*4+4, %sp) | point x to next channel + movem.l (%a5), %d0-%d3 | load filter history +.loop: + move.l (%a6), %d4 + mac.l %a0, %d4, %acc0 | acc = b0*x[i] + mac.l %a1, %d0, %acc0 | acc += b1*x[i - 1] + mac.l %a2, %d1, %acc0 | acc += b2*x[i - 2] + msac.l %a3, %d2, %acc0 | acc -= a1*y[i - 1] + msac.l %a4, %d3, %acc0 | acc -= a2*y[i - 2] + move.l %d0, %d1 | fix history + move.l %d4, %d0 + move.l %d2, %d3 + movclr.l %acc0, %d2 | fetch and write result + asl.l %d7, %d2 | restore fixed point format + move.l %d2, (%a6)+ | save result + subq.l #1, %d5 | are we done with this channel? + jne .loop + + movem.l %d0-%d3, (%a5) | save history back to struct + lea.l (4*4, %a5), %a5 | point to next channel's history + subq.l #1, %d6 | have we processed both channels? + jne .filterloop + + movem.l (%sp), %d2-%d7/%a2-%a6 + lea.l (11*4, %sp), %sp + rts + -- cgit v1.2.3