summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/lang/english.lang34
-rw-r--r--apps/plugin.c2
-rw-r--r--apps/plugin.h2
-rw-r--r--apps/plugins/mpegplayer/mpeg_settings.c5
-rw-r--r--apps/settings.c2
-rw-r--r--apps/settings.h2
-rw-r--r--apps/settings_list.c6
-rw-r--r--lib/rbcodec/dsp/crossfeed.c133
-rw-r--r--lib/rbcodec/dsp/crossfeed.h9
-rw-r--r--lib/rbcodec/dsp/dsp_arm.S44
-rw-r--r--lib/rbcodec/dsp/dsp_cf.S47
11 files changed, 259 insertions, 27 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index fc575a3764..7366a80030 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -13052,3 +13052,37 @@
13052 *: "Western European" 13052 *: "Western European"
13053 </voice> 13053 </voice>
13054</phrase> 13054</phrase>
13055<phrase>
13056 id: LANG_CROSSFEED_MEIER
13057 desc: in sound settings
13058 user: core
13059 <source>
13060 *: none
13061 swcodec: "Simple (Meier)"
13062 </source>
13063 <dest>
13064 *: none
13065 swcodec: "Simple (Meier)"
13066 </dest>
13067 <voice>
13068 *: none
13069 swcodec: "Simple"
13070 </voice>
13071</phrase>
13072<phrase>
13073 id: LANG_CROSSFEED_CUSTOM
13074 desc: in sound settings
13075 user: core
13076 <source>
13077 *: none
13078 swcodec: "Custom"
13079 </source>
13080 <dest>
13081 *: none
13082 swcodec: "Custom"
13083 </dest>
13084 <voice>
13085 *: none
13086 swcodec: "Custom"
13087 </voice>
13088</phrase>
diff --git a/apps/plugin.c b/apps/plugin.c
index afb336ebdc..e0e565e504 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -565,7 +565,7 @@ static const struct plugin_api rockbox_api = {
565 audio_set_output_source, 565 audio_set_output_source,
566 audio_set_input_source, 566 audio_set_input_source,
567#endif 567#endif
568 dsp_crossfeed_enable, 568 dsp_set_crossfeed_type ,
569 dsp_eq_enable, 569 dsp_eq_enable,
570 dsp_dither_enable, 570 dsp_dither_enable,
571#ifdef HAVE_PITCHCONTROL 571#ifdef HAVE_PITCHCONTROL
diff --git a/apps/plugin.h b/apps/plugin.h
index b1d3c16979..bb2778164b 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -682,7 +682,7 @@ struct plugin_api {
682 void (*audio_set_output_source)(int monitor); 682 void (*audio_set_output_source)(int monitor);
683 void (*audio_set_input_source)(int source, unsigned flags); 683 void (*audio_set_input_source)(int source, unsigned flags);
684#endif 684#endif
685 void (*dsp_crossfeed_enable)(bool enable); 685 void (*dsp_set_crossfeed_type)(int type);
686 void (*dsp_eq_enable)(bool enable); 686 void (*dsp_eq_enable)(bool enable);
687 void (*dsp_dither_enable)(bool enable); 687 void (*dsp_dither_enable)(bool enable);
688#ifdef HAVE_PITCHCONTROL 688#ifdef HAVE_PITCHCONTROL
diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c
index 7f92fb7c69..bcef4c66bf 100644
--- a/apps/plugins/mpegplayer/mpeg_settings.c
+++ b/apps/plugins/mpegplayer/mpeg_settings.c
@@ -457,8 +457,9 @@ static void sync_audio_setting(int setting, bool global)
457 break; 457 break;
458 458
459 case MPEG_AUDIO_CROSSFEED: 459 case MPEG_AUDIO_CROSSFEED:
460 rb->dsp_crossfeed_enable((global || settings.crossfeed) ? 460 rb->dsp_set_crossfeed_type((global || settings.crossfeed) ?
461 rb->global_settings->crossfeed : false); 461 rb->global_settings->crossfeed :
462 CROSSFEED_TYPE_NONE);
462 break; 463 break;
463 464
464 case MPEG_AUDIO_EQUALIZER: 465 case MPEG_AUDIO_EQUALIZER:
diff --git a/apps/settings.c b/apps/settings.c
index d777eb1565..3bf9c5bf17 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -979,7 +979,7 @@ void settings_apply(bool read_disk)
979 audio_set_crossfade(global_settings.crossfade); 979 audio_set_crossfade(global_settings.crossfade);
980#endif 980#endif
981 replaygain_update(); 981 replaygain_update();
982 dsp_crossfeed_enable(global_settings.crossfeed); 982 dsp_set_crossfeed_type(global_settings.crossfeed);
983 dsp_set_crossfeed_direct_gain(global_settings.crossfeed_direct_gain); 983 dsp_set_crossfeed_direct_gain(global_settings.crossfeed_direct_gain);
984 dsp_set_crossfeed_cross_params(global_settings.crossfeed_cross_gain, 984 dsp_set_crossfeed_cross_params(global_settings.crossfeed_cross_gain,
985 global_settings.crossfeed_hf_attenuation, 985 global_settings.crossfeed_hf_attenuation,
diff --git a/apps/settings.h b/apps/settings.h
index 55d3344cb2..ef0bae520e 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -325,7 +325,7 @@ struct user_settings
325 struct replaygain_settings replaygain_settings; 325 struct replaygain_settings replaygain_settings;
326 326
327 /* Crossfeed */ 327 /* Crossfeed */
328 bool crossfeed; /* enable crossfeed */ 328 int crossfeed; /* crossfeed type */
329 unsigned int crossfeed_direct_gain; /* dB x 10 */ 329 unsigned int crossfeed_direct_gain; /* dB x 10 */
330 unsigned int crossfeed_cross_gain; /* dB x 10 */ 330 unsigned int crossfeed_cross_gain; /* dB x 10 */
331 unsigned int crossfeed_hf_attenuation; /* dB x 10 */ 331 unsigned int crossfeed_hf_attenuation; /* dB x 10 */
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 10d00d5c89..accd51dfe1 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1402,8 +1402,10 @@ const struct settings_list settings[] = {
1402#endif 1402#endif
1403 1403
1404 /* crossfeed */ 1404 /* crossfeed */
1405 OFFON_SETTING(F_SOUNDSETTING, crossfeed, LANG_CROSSFEED, false, 1405 CHOICE_SETTING(F_SOUNDSETTING, crossfeed, LANG_CROSSFEED, 0,"crossfeed",
1406 "crossfeed", dsp_crossfeed_enable), 1406 "off,meier,custom", dsp_set_crossfeed_type, 3,
1407 ID2P(LANG_OFF), ID2P(LANG_CROSSFEED_MEIER),
1408 ID2P(LANG_CROSSFEED_CUSTOM)),
1407 INT_SETTING_NOWRAP(F_SOUNDSETTING, crossfeed_direct_gain, 1409 INT_SETTING_NOWRAP(F_SOUNDSETTING, crossfeed_direct_gain,
1408 LANG_CROSSFEED_DIRECT_GAIN, -15, 1410 LANG_CROSSFEED_DIRECT_GAIN, -15,
1409 "crossfeed direct gain", UNIT_DB, -60, 0, 5, 1411 "crossfeed direct gain", UNIT_DB, -60, 0, 5,
diff --git a/lib/rbcodec/dsp/crossfeed.c b/lib/rbcodec/dsp/crossfeed.c
index 344addadd7..3fb51a7594 100644
--- a/lib/rbcodec/dsp/crossfeed.c
+++ b/lib/rbcodec/dsp/crossfeed.c
@@ -8,6 +8,7 @@
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2006 Thom Johansen 10 * Copyright (C) 2006 Thom Johansen
11 * Copyright (C) 2010 Bertrik Sikken
11 * Copyright (C) 2012 Michael Sevakis 12 * Copyright (C) 2012 Michael Sevakis
12 * 13 *
13 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
@@ -31,7 +32,11 @@
31#include <string.h> 32#include <string.h>
32 33
33/* Implemented here or in target assembly code */ 34/* Implemented here or in target assembly code */
34void crossfeed_process(struct dsp_proc_entry *this, struct dsp_buffer **buf_p); 35void crossfeed_process(struct dsp_proc_entry *this,
36 struct dsp_buffer **buf_p);
37void crossfeed_meier_process(struct dsp_proc_entry *this,
38 struct dsp_buffer **buf_p);
39
35 40
36/** 41/**
37 * Applies crossfeed to the stereo signal. 42 * Applies crossfeed to the stereo signal.
@@ -46,20 +51,44 @@ static struct crossfeed_state
46{ 51{
47 int32_t gain; /* 00h: Direct path gain */ 52 int32_t gain; /* 00h: Direct path gain */
48 int32_t coefs[3]; /* 04h: Coefficients for the shelving filter */ 53 int32_t coefs[3]; /* 04h: Coefficients for the shelving filter */
49 int32_t history[4]; /* 10h: Format is x[n - 1], y[n - 1] (L + R) */ 54 union
50 int32_t delay[13*2]; /* 20h: Delay line buffer (L + R interleaved) */ 55 {
56 struct /* 10h: Data for meier crossfeed */
57 {
58 int32_t vcl;
59 int32_t vcr;
60 int32_t vdiff;
61 int32_t coef1;
62 int32_t coef2;
63 };
64 struct /* 10h: Data for custom crossfeed */
65 {
66 int32_t history[4]; /* 10h: Format is x[n - 1], y[n - 1] (L + R) */
67 int32_t delay[13*2];/* 20h: Delay line buffer (L + R interleaved) */
68 };
69 };
51 int32_t *index; /* 88h: Current pointer into the delay line */ 70 int32_t *index; /* 88h: Current pointer into the delay line */
52 struct dsp_config *dsp; /* 8ch: Current DSP */ 71 struct dsp_config *dsp; /* 8ch: Current DSP */
53 /* 90h */ 72 /* 90h */
54} crossfeed_state IBSS_ATTR; 73} crossfeed_state IBSS_ATTR;
55 74
75static int crossfeed_type = CROSSFEED_TYPE_NONE;
76
56/* Discard the sample histories */ 77/* Discard the sample histories */
57static void crossfeed_flush(struct dsp_proc_entry *this) 78static void crossfeed_flush(struct dsp_proc_entry *this)
58{ 79{
59 struct crossfeed_state *state = (void *)this->data; 80 struct crossfeed_state *state = (void *)this->data;
60 memset(state->history, 0, sizeof (state->history)); 81
61 memset(state->delay, 0, sizeof (state->delay)); 82 if (crossfeed_type == CROSSFEED_TYPE_CUSTOM)
62 state->index = state->delay; 83 {
84 memset(state->history, 0,
85 sizeof (state->history) + sizeof (state->delay));
86 state->index = state->delay;
87 }
88 else
89 {
90 state->vcl = state->vcr = state->vdiff = 0;
91 }
63} 92}
64 93
65 94
@@ -74,30 +103,48 @@ static void crossfeed_process_new_format(struct dsp_proc_entry *this,
74 103
75 DSP_PRINT_FORMAT(DSP_PROC_CROSSFEED, DSP_PROC_CROSSFEED, buf->format); 104 DSP_PRINT_FORMAT(DSP_PROC_CROSSFEED, DSP_PROC_CROSSFEED, buf->format);
76 105
106 bool was_active = dsp_proc_active(state->dsp, DSP_PROC_CROSSFEED);
77 bool active = buf->format.num_channels >= 2; 107 bool active = buf->format.num_channels >= 2;
78 dsp_proc_activate(state->dsp, DSP_PROC_CROSSFEED, active); 108 dsp_proc_activate(state->dsp, DSP_PROC_CROSSFEED, active);
79 109
80 if (!active) 110 if (!active)
81 { 111 {
82 /* Can't do this. Sleep until next change */ 112 /* Can't do this. Sleep until next change */
83 crossfeed_flush(this);
84 DEBUGF(" DSP_PROC_CROSSFEED- deactivated\n"); 113 DEBUGF(" DSP_PROC_CROSSFEED- deactivated\n");
85 return; 114 return;
86 } 115 }
87 116
88 /* Switch to the real function and call it once */ 117 dsp_proc_fn_type fn = crossfeed_process;
89 this->process[0] = crossfeed_process; 118
119 if (crossfeed_type != CROSSFEED_TYPE_CUSTOM)
120 {
121 /* 1 / (F.Rforward.C) */
122 state->coef1 = (0x7fffffff / NATIVE_FREQUENCY) * 2128;
123 /* 1 / (F.Rcross.C) */
124 state->coef2 = (0x7fffffff / NATIVE_FREQUENCY) * 1000;
125 fn = crossfeed_meier_process;
126 }
127
128 if (!was_active || this->process[0] != fn)
129 {
130 crossfeed_flush(this); /* Going online or actual type change */
131 this->process[0] = fn; /* Set real function */
132 }
133
134 /* Call it once */
90 dsp_proc_call(this, buf_p, (unsigned)buf->format.changed - 1); 135 dsp_proc_call(this, buf_p, (unsigned)buf->format.changed - 1);
91} 136}
92 137
93/* Enable or disable the crossfeed */ 138/* Set the type of crossfeed to use */
94void dsp_crossfeed_enable(bool enable) 139void dsp_set_crossfeed_type(int type)
95{ 140{
96 if (enable != !crossfeed_state.dsp) 141 if (type == crossfeed_type)
97 return; 142 return; /* No change */
143
144 crossfeed_type = type;
98 145
99 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO); 146 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO);
100 dsp_proc_enable(dsp, DSP_PROC_CROSSFEED, enable); 147 dsp_proc_enable(dsp, DSP_PROC_CROSSFEED, type != CROSSFEED_TYPE_NONE);
101} 148}
102 149
103/* Set the gain of the dry mix */ 150/* Set the gain of the dry mix */
@@ -182,6 +229,50 @@ void crossfeed_process(struct dsp_proc_entry *this, struct dsp_buffer **buf_p)
182} 229}
183#endif /* CPU */ 230#endif /* CPU */
184 231
232#if !defined(CPU_COLDFIRE) && !defined(CPU_ARM)
233/**
234 * Implementation of the "simple" passive crossfeed circuit by Jan Meier.
235 * See also: http://www.meier-audio.homepage.t-online.de/passivefilter.htm
236 */
237
238void crossfeed_meier_process(struct dsp_proc_entry *this,
239 struct dsp_buffer **buf_p)
240{
241 struct dsp_buffer *buf = *buf_p;
242
243 /* Get filter state */
244 struct crossfeed_state *state = (struct crossfeed_state *)this->data;
245 int32_t vcl = state->vcl;
246 int32_t vcr = state->vcr;
247 int32_t vdiff = state->vdiff;
248 int32_t coef1 = state->coef1;
249 int32_t coef2 = state->coef2;
250
251 int count = buf->remcount;
252
253 for (int i = 0; i < count; i++)
254 {
255 /* Calculate new output */
256 int32_t lout = buf->p32[0][i] + vcl;
257 int32_t rout = buf->p32[1][i] + vcr;
258 buf->p32[0][i] = lout;
259 buf->p32[1][i] = rout;
260
261 /* Update filter state */
262 int32_t common = FRACMUL(vdiff, coef2);
263 vcl -= FRACMUL(vcl, coef1) + common;
264 vcr -= FRACMUL(vcr, coef1) - common;
265
266 vdiff = lout - rout;
267 }
268
269 /* Store filter state */
270 state->vcl = vcl;
271 state->vcr = vcr;
272 state->vdiff = vdiff;
273}
274#endif /* CPU */
275
185/* DSP message hook */ 276/* DSP message hook */
186static intptr_t crossfeed_configure(struct dsp_proc_entry *this, 277static intptr_t crossfeed_configure(struct dsp_proc_entry *this,
187 struct dsp_config *dsp, 278 struct dsp_config *dsp,
@@ -191,11 +282,19 @@ static intptr_t crossfeed_configure(struct dsp_proc_entry *this,
191 switch (setting) 282 switch (setting)
192 { 283 {
193 case DSP_PROC_INIT: 284 case DSP_PROC_INIT:
194 this->data = (intptr_t)&crossfeed_state; 285 if (value == 0)
286 {
287 /* New object */
288 this->data = (intptr_t)&crossfeed_state;
289 this->process[1] = crossfeed_process_new_format;
290 ((struct crossfeed_state *)this->data)->dsp = dsp;
291 }
292
293 /* Force format change call each time */
195 this->process[0] = crossfeed_process_new_format; 294 this->process[0] = crossfeed_process_new_format;
196 this->process[1] = crossfeed_process_new_format;
197 ((struct crossfeed_state *)this->data)->dsp = dsp;
198 dsp_proc_activate(dsp, DSP_PROC_CROSSFEED, true); 295 dsp_proc_activate(dsp, DSP_PROC_CROSSFEED, true);
296 break;
297
199 case DSP_FLUSH: 298 case DSP_FLUSH:
200 crossfeed_flush(this); 299 crossfeed_flush(this);
201 break; 300 break;
diff --git a/lib/rbcodec/dsp/crossfeed.h b/lib/rbcodec/dsp/crossfeed.h
index 63261bde9f..2c4d47dba5 100644
--- a/lib/rbcodec/dsp/crossfeed.h
+++ b/lib/rbcodec/dsp/crossfeed.h
@@ -21,7 +21,14 @@
21#ifndef CROSSFEED_H 21#ifndef CROSSFEED_H
22#define CROSSFEED_H 22#define CROSSFEED_H
23 23
24void dsp_crossfeed_enable(bool enable); 24enum crossfeed_type
25{
26 CROSSFEED_TYPE_NONE,
27 CROSSFEED_TYPE_MEIER,
28 CROSSFEED_TYPE_CUSTOM,
29};
30
31void dsp_set_crossfeed_type(int type);
25void dsp_set_crossfeed_direct_gain(int gain); 32void dsp_set_crossfeed_direct_gain(int gain);
26void dsp_set_crossfeed_cross_params(long lf_gain, long hf_gain, long cutoff); 33void dsp_set_crossfeed_cross_params(long lf_gain, long hf_gain, long cutoff);
27 34
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
257crossfeed_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)
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 @@
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2006 Thom Johansen 10 * Copyright (C) 2006 Thom Johansen
11 * Portions Copyright (C) 2007 Michael Sevakis 11 * Copyright (C) 2007, 2012 Michael Sevakis
12 * Copyright (C) 2010 Bertrik Sikken
12 * 13 *
13 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License 15 * modify it under the terms of the GNU General Public License
@@ -134,6 +135,50 @@ crossfeed_process:
134 .size crossfeed_process,.-crossfeed_process 135 .size crossfeed_process,.-crossfeed_process
135 136
136/**************************************************************************** 137/****************************************************************************
138 * void crossfeed_meier_process(struct dsp_proc_entry *this,
139 * struct dsp_buffer **buf_p)
140 */
141 .section .text
142 .global crossfeed_meier_process
143crossfeed_meier_process:
144 | input: 4(sp) = this, 8(sp) = buf_p
145 movem.l 4(%sp), %a0-%a1 | %a0 = this, %a1 = buf_p
146 lea.l -24(%sp), %sp | save non-volatiles
147 movem.l %d2-%d6/%a2, (%sp) | .
148 move.l (%a0), %a0 | %a0 = &this->data = &crossfeed_state
149 move.l (%a1), %a1 | %a1 = buf = *buf_p
150 movem.l 16(%a0), %d1-%d5 | %d1 = vcl, %d2 = vcr, %d3 = vdiff,
151 | %d4 = coef1, %d5 = coef2
152 movem.l (%a1), %d0/%a1-%a2 | %d0 = count = buf->remcount
153 | %a1 = p32[0], %a2 = p32[1]
154 | Register usage in loop:
155 | %d0 = count, %d1 = vcl, %d2 = vcr, %d3 = vdiff/lout,
156 | %d4 = coef1, %d5 = coef2, %d6 = rout/scratch
157 | %a1 = p32[0], %a2 = p32[1]
15810: | loop
159 mac.l %d5, %d3, %acc0 | %acc0 = common = coef2*vdiff
160 move.l %acc0, %acc1 | copy common
161 mac.l %d4, %d1, (%a1), %d3, %acc0 | %acc0 += coef1*vcl, %d3 = lout
162 msac.l %d4, %d2, (%a2), %d6, %acc1 | %acc1 -= coef1*vcr, %d6 = rout
163 add.l %d1, %d3 | lout += vcl
164 add.l %d2, %d6 | rout += vcr
165 move.l %d3, (%a1)+ | store left channel, pos inc
166 move.l %d6, (%a2)+ | store right channel, pos inc
167 sub.l %d6, %d3 | vdiff = lout - rout
168 movclr.l %acc0, %d6 | %d4 = fetch res1 in s0.31
169 sub.l %d6, %d1 | vcl -= res1
170 movclr.l %acc1, %d6 | %d5 = fetch -res2 in s0.31
171 add.l %d6, %d2 | vcr += -res2
172 subq.l #1, %d0 | count--
173 bgt 10b | loop | more samples?
174 |
175 movem.l %d1-%d3, 16(%a0) | save vcl, vcr, vdiff
176 movem.l (%sp), %d2-%d6/%a2 | restore non-volatiles
177 lea.l 24(%sp), %sp | .
178 rts |
179 .size crossfeed_meier_process, .-crossfeed_meier_process
180
181/****************************************************************************
137 * int lin_resample_resample(struct resample_data *data, 182 * int lin_resample_resample(struct resample_data *data,
138 * struct dsp_buffer *src, 183 * struct dsp_buffer *src,
139 * struct dsp_buffer *dst) 184 * struct dsp_buffer *dst)