diff options
author | Bertrik Sikken <bertrik@sikken.nl> | 2012-05-01 03:58:27 -0400 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2012-05-28 11:34:15 +0200 |
commit | afc96087f8a6282cf732d142a4db7a3d604d39d8 (patch) | |
tree | ccdf78007bb087ab658edaa951f245ad4141bae2 /lib/rbcodec/dsp/dsp_arm.S | |
parent | 08f5224b1bf1293ab1d59fdfbf9045561733c38d (diff) | |
download | rockbox-afc96087f8a6282cf732d142a4db7a3d604d39d8.tar.gz rockbox-afc96087f8a6282cf732d142a4db7a3d604d39d8.zip |
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
Diffstat (limited to 'lib/rbcodec/dsp/dsp_arm.S')
-rw-r--r-- | lib/rbcodec/dsp/dsp_arm.S | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/rbcodec/dsp/dsp_arm.S b/lib/rbcodec/dsp/dsp_arm.S index 1674d6617a..4fdaf8d5a8 100644 --- a/lib/rbcodec/dsp/dsp_arm.S +++ b/lib/rbcodec/dsp/dsp_arm.S | |||
@@ -8,6 +8,8 @@ | |||
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2006-2007 Thom Johansen | 10 | * Copyright (C) 2006-2007 Thom Johansen |
11 | * Copyright (C) 2010 Bertrik Sikken | ||
12 | * Copyright (C) 2012 Michael Sevakis | ||
11 | * | 13 | * |
12 | * This program is free software; you can redistribute it and/or | 14 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 15 | * modify it under the terms of the GNU General Public License |
@@ -247,6 +249,48 @@ crossfeed_process: | |||
247 | .size crossfeed_process, .-crossfeed_process | 249 | .size crossfeed_process, .-crossfeed_process |
248 | 250 | ||
249 | /**************************************************************************** | 251 | /**************************************************************************** |
252 | * void crossfeed_meier_process(struct dsp_proc_entry *this, | ||
253 | * struct dsp_buffer **buf_p) | ||
254 | */ | ||
255 | .section .text | ||
256 | .global crossfeed_meier_process | ||
257 | crossfeed_meier_process: | ||
258 | @ input: r0 = this, r1 = buf_p | ||
259 | ldr r1, [r1] @ r1 = buf = *buf_p; | ||
260 | ldr r0, [r0] @ r0 = this->data = &crossfeed_state | ||
261 | stmfd sp!, { r4-r10, lr } @ stack non-volatile context | ||
262 | ldmia r1, { r1-r3 } @ r1 = buf->remcout, r2=p32[0], r3=p32[1] | ||
263 | add r0, r0, #16 @ r0 = &state->vcl | ||
264 | ldmia r0, { r4-r8 } @ r4 = vcl, r5 = vcr, r6 = vdiff | ||
265 | @ r7 = coef1, r8 = coef2 | ||
266 | .cfm_loop: | ||
267 | ldr r12, [r2] @ r12 = lout | ||
268 | ldr r14, [r3] @ r14 = rout | ||
269 | smull r9, r10, r8, r6 @ r9, r10 = common = coef2*vdiff | ||
270 | add r12, r12, r4 @ lout += vcl | ||
271 | add r14, r14, r5 @ rout += vcr | ||
272 | sub r6, r12, r14 @ r6 = vdiff = lout - rout | ||
273 | str r12, [r2], #4 @ store left channel | ||
274 | str r14, [r3], #4 @ store right channel | ||
275 | rsbs r12, r9, #0 @ r12 = -common (lo) | ||
276 | rsc r14, r10, #0 @ r14 = -common (hi) | ||
277 | smlal r9, r10, r7, r4 @ r9, r10 = res1 = coef1*vcl + common | ||
278 | smlal r12, r14, r7, r5 @ r12, r14 = res2 = coef1*vcr - common | ||
279 | subs r1, r1, #1 @ count-- | ||
280 | mov r9, r9, lsr #31 @ r9 = convert res1 to s0.31 | ||
281 | orr r9, r9, r10, asl #1 @ . | ||
282 | mov r12, r12, lsr #31 @ r12 = convert res2 to s0.31 | ||
283 | orr r12, r12, r14, asl #1 @ . | ||
284 | sub r4, r4, r9 @ r4 = vcl -= res1 | ||
285 | sub r5, r5, r12 @ r5 = vcr -= res2 | ||
286 | bgt .cfm_loop @ more samples? | ||
287 | |||
288 | stmia r0, { r4-r6 } @ save vcl, vcr, vdiff | ||
289 | ldmpc regs=r4-r10 @ restore non-volatile context, return | ||
290 | .size crossfeed_meier_process, .-crossfeed_meier_process | ||
291 | |||
292 | |||
293 | /**************************************************************************** | ||
250 | * int lin_resample_resample(struct resample_data *data, | 294 | * int lin_resample_resample(struct resample_data *data, |
251 | * struct dsp_buffer *src, | 295 | * struct dsp_buffer *src, |
252 | * struct dsp_buffer *dst) | 296 | * struct dsp_buffer *dst) |