From afc96087f8a6282cf732d142a4db7a3d604d39d8 Mon Sep 17 00:00:00 2001 From: Bertrik Sikken Date: Tue, 1 May 2012 03:58:27 -0400 Subject: New crossfeed algorithm for Rockbox: "Meier" crossfeed Emulates the basic "Meier" crossfeed (2 capacitors, 3 resistors) as discussed in http://www.meier-audio.homepage.t-online.de/passivefilter.htm This crossfeed blends a bit of low-pass filtered L signal into the R signal (and vice versa) while adding about 300 us delay to the crossfed-signal. A difference with the crossfeed already present in rockbox, is that this algorithm keeps the total spectrum flat (the one currently in rockbox accentuates low-frequency signals, making it sound a bit muffled). This implementation is quite lightweight, just 3 multiplies per left-right pair of samples. Has a default C implementation and optimized assembly versions for ARM and Coldfire. The crossfeed effect is quite subtle and is noticeable mostly one albums that have very strong left-right separation (e.g. one instrument only on the left, another only on the right). In the user interface, the new crossfeed option appears as "Meier" and is not configureable. The existing crossfeed is renamed to "Custom" as it allows itself to be customised. There is no entry for the user manual yet. Change-Id: Iaa100616fe0fcd7e16f08cdb9a7f41501973eee1 --- lib/rbcodec/dsp/dsp_cf.S | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'lib/rbcodec/dsp/dsp_cf.S') diff --git a/lib/rbcodec/dsp/dsp_cf.S b/lib/rbcodec/dsp/dsp_cf.S index c710df5177..7d193e0957 100644 --- a/lib/rbcodec/dsp/dsp_cf.S +++ b/lib/rbcodec/dsp/dsp_cf.S @@ -8,7 +8,8 @@ * $Id$ * * Copyright (C) 2006 Thom Johansen - * Portions Copyright (C) 2007 Michael Sevakis + * Copyright (C) 2007, 2012 Michael Sevakis + * Copyright (C) 2010 Bertrik Sikken * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -133,6 +134,50 @@ crossfeed_process: rts | .size crossfeed_process,.-crossfeed_process +/**************************************************************************** + * void crossfeed_meier_process(struct dsp_proc_entry *this, + * struct dsp_buffer **buf_p) + */ + .section .text + .global crossfeed_meier_process +crossfeed_meier_process: + | input: 4(sp) = this, 8(sp) = buf_p + movem.l 4(%sp), %a0-%a1 | %a0 = this, %a1 = buf_p + lea.l -24(%sp), %sp | save non-volatiles + movem.l %d2-%d6/%a2, (%sp) | . + move.l (%a0), %a0 | %a0 = &this->data = &crossfeed_state + move.l (%a1), %a1 | %a1 = buf = *buf_p + movem.l 16(%a0), %d1-%d5 | %d1 = vcl, %d2 = vcr, %d3 = vdiff, + | %d4 = coef1, %d5 = coef2 + movem.l (%a1), %d0/%a1-%a2 | %d0 = count = buf->remcount + | %a1 = p32[0], %a2 = p32[1] + | Register usage in loop: + | %d0 = count, %d1 = vcl, %d2 = vcr, %d3 = vdiff/lout, + | %d4 = coef1, %d5 = coef2, %d6 = rout/scratch + | %a1 = p32[0], %a2 = p32[1] +10: | loop + mac.l %d5, %d3, %acc0 | %acc0 = common = coef2*vdiff + move.l %acc0, %acc1 | copy common + mac.l %d4, %d1, (%a1), %d3, %acc0 | %acc0 += coef1*vcl, %d3 = lout + msac.l %d4, %d2, (%a2), %d6, %acc1 | %acc1 -= coef1*vcr, %d6 = rout + add.l %d1, %d3 | lout += vcl + add.l %d2, %d6 | rout += vcr + move.l %d3, (%a1)+ | store left channel, pos inc + move.l %d6, (%a2)+ | store right channel, pos inc + sub.l %d6, %d3 | vdiff = lout - rout + movclr.l %acc0, %d6 | %d4 = fetch res1 in s0.31 + sub.l %d6, %d1 | vcl -= res1 + movclr.l %acc1, %d6 | %d5 = fetch -res2 in s0.31 + add.l %d6, %d2 | vcr += -res2 + subq.l #1, %d0 | count-- + bgt 10b | loop | more samples? + | + movem.l %d1-%d3, 16(%a0) | save vcl, vcr, vdiff + movem.l (%sp), %d2-%d6/%a2 | restore non-volatiles + lea.l 24(%sp), %sp | . + rts | + .size crossfeed_meier_process, .-crossfeed_meier_process + /**************************************************************************** * int lin_resample_resample(struct resample_data *data, * struct dsp_buffer *src, -- cgit v1.2.3