Index: apps/lang/english.lang
===================================================================
--- apps/lang/english.lang (revision 28159)
+++ apps/lang/english.lang (working copy)
@@ -904,6 +904,40 @@
+ id: LANG_CROSSFEED_MEIER
+ desc: in sound settings
+ user: core
+
+ *: none
+ swcodec: "Meier"
+
+
+ *: none
+ swcodec: "Meier"
+
+
+ *: none
+ swcodec: "Meier"
+
+
+
+ id: LANG_CROSSFEED_CUSTOM
+ desc: in sound settings
+ user: core
+
+ *: none
+ swcodec: "Custom"
+
+
+ *: none
+ swcodec: "Custom"
+
+
+ *: none
+ swcodec: "Custom"
+
+
+
id: LANG_CROSSFEED_DIRECT_GAIN
desc: in crossfeed settings
user: core
Index: apps/settings.h
===================================================================
--- apps/settings.h (revision 28159)
+++ apps/settings.h (working copy)
@@ -321,7 +321,7 @@
int replaygain_preamp; /* scale replaygained tracks by this */
/* Crossfeed */
- bool crossfeed; /* enable crossfeed */
+ int crossfeed; /* crossfeed type */
unsigned int crossfeed_direct_gain; /* dB x 10 */
unsigned int crossfeed_cross_gain; /* dB x 10 */
unsigned int crossfeed_hf_attenuation; /* dB x 10 */
Index: apps/dsp.c
===================================================================
--- apps/dsp.c (revision 28159)
+++ apps/dsp.c (working copy)
@@ -189,7 +189,7 @@
/* These will be NULL for the voice codec and is more economical that
way */
channels_process_dsp_fn_type apply_gain;
- channels_process_fn_type apply_crossfeed;
+ channels_process_fn_type crossfeed_process;
channels_process_fn_type eq_process;
channels_process_fn_type channels_process;
channels_process_fn_type compressor_process;
@@ -232,7 +232,7 @@
static long track_peak;
static long album_peak;
static long replaygain;
-static bool crossfeed_enabled;
+static int crossfeed_type;
#define AUDIO_DSP (dsp_conf[CODEC_IDX_AUDIO])
#define VOICE_DSP (dsp_conf[CODEC_IDX_VOICE])
@@ -829,6 +829,45 @@
}
#endif /* DSP_HAVE_ASM_CROSSFEED */
+static void meier_crossfeed(int count, int32_t *buf[])
+{
+ int32_t *hist_l = &crossfeed_data.history[0];
+ int32_t *hist_r = &crossfeed_data.history[2];
+ int32_t vdiff, vcl, vcr, common;
+ int32_t left, right;
+ int i;
+ int32_t coef1, coef2;
+
+ // 1 / F.Rforward.C
+ coef1 = (0xffffffff/NATIVE_FREQUENCY) * 2128;
+ // 1 / F.Rcross.C
+ coef2 = (0xffffffff/NATIVE_FREQUENCY) * 1000;
+
+ vcl = hist_l[0];
+ vcr = hist_r[0];
+ left = hist_l[1];
+ right = hist_r[1];
+ for (i = 0; i < count; i++) {
+ vdiff = left - right;
+
+ // calculate output
+ left = buf[0][i] + vcl;
+ right = buf[1][i] + vcr;
+ buf[0][i] = left;
+ buf[1][i] = right;
+
+ // update filter
+ common = FRACMUL(coef2, vdiff);
+ vcl -= (FRACMUL(coef1, vcl) + common);
+ vcr -= (FRACMUL(coef1, vcr) - common);
+ }
+ // store filter state
+ hist_l[0] = vcl;
+ hist_r[0] = vcr;
+ hist_l[1] = left;
+ hist_r[1] = right;
+}
+
/**
* dsp_set_crossfeed(bool enable)
*
@@ -836,11 +875,19 @@
* needs syncing with changes to the following dsp parameters:
* * dsp->stereo_mode (A)
*/
-void dsp_set_crossfeed(bool enable)
+void dsp_set_crossfeed(int type)
{
- crossfeed_enabled = enable;
- AUDIO_DSP.apply_crossfeed = (enable && AUDIO_DSP.data.num_channels > 1)
- ? apply_crossfeed : NULL;
+ crossfeed_type = type;
+
+ if (AUDIO_DSP.data.num_channels == 1) {
+ type = 0;
+ }
+
+ switch (type) {
+ case 0: AUDIO_DSP.crossfeed_process = NULL; break;
+ case 1: AUDIO_DSP.crossfeed_process = meier_crossfeed; break;
+ case 2: AUDIO_DSP.crossfeed_process = apply_crossfeed; break;
+ }
}
void dsp_set_crossfeed_direct_gain(int gain)
@@ -1255,8 +1302,8 @@
if (dsp->resample && (chunk = resample(dsp, chunk, t2)) <= 0)
break; /* I'm pretty sure we're downsampling here */
- if (dsp->apply_crossfeed)
- dsp->apply_crossfeed(chunk, t2);
+ if (dsp->crossfeed_process)
+ dsp->crossfeed_process(chunk, t2);
if (dsp->eq_process)
dsp->eq_process(chunk, t2);
@@ -1360,7 +1407,7 @@
sample_input_new_format(dsp);
sample_output_new_format(dsp);
if (dsp == &AUDIO_DSP)
- dsp_set_crossfeed(crossfeed_enabled);
+ dsp_set_crossfeed(crossfeed_type);
}
intptr_t dsp_configure(struct dsp_config *dsp, int setting, intptr_t value)
Index: apps/settings_list.c
===================================================================
--- apps/settings_list.c (revision 28159)
+++ apps/settings_list.c (working copy)
@@ -1293,8 +1293,12 @@
#endif
/* crossfeed */
- OFFON_SETTING(F_SOUNDSETTING, crossfeed, LANG_CROSSFEED, false,
- "crossfeed", dsp_set_crossfeed),
+ CHOICE_SETTING(F_SOUNDSETTING, crossfeed, LANG_CROSSFEED,
+ 0,"crossfeed",
+ "off,meier,custom",
+ dsp_set_crossfeed, 3,
+ ID2P(LANG_OFF), ID2P(LANG_CROSSFEED_MEIER),
+ ID2P(LANG_CROSSFEED_CUSTOM)),
INT_SETTING_NOWRAP(F_SOUNDSETTING, crossfeed_direct_gain,
LANG_CROSSFEED_DIRECT_GAIN, -15,
"crossfeed direct gain", UNIT_DB, -60, 0, 5,
Index: apps/dsp.h
===================================================================
--- apps/dsp.h (revision 28159)
+++ apps/dsp.h (working copy)
@@ -67,7 +67,7 @@
intptr_t value);
int get_replaygain_mode(bool have_track_gain, bool have_album_gain);
void dsp_set_replaygain(void);
-void dsp_set_crossfeed(bool enable);
+void dsp_set_crossfeed(int type);
void dsp_set_crossfeed_direct_gain(int gain);
void dsp_set_crossfeed_cross_params(long lf_gain, long hf_gain,
long cutoff);
Index: apps/plugin.h
===================================================================
--- apps/plugin.h (revision 28159)
+++ apps/plugin.h (working copy)
@@ -638,7 +638,7 @@
void (*audio_set_output_source)(int monitor);
void (*audio_set_input_source)(int source, unsigned flags);
#endif
- void (*dsp_set_crossfeed)(bool enable);
+ void (*dsp_set_crossfeed)(int type);
void (*dsp_set_eq)(bool enable);
void (*dsp_dither_enable)(bool enable);
intptr_t (*dsp_configure)(struct dsp_config *dsp, int setting,