mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
Allow customizing EQ filter types
Allows any EQ band to be set to any of Low Shelf, Peak, or High Shelf, instead of hardcoding the types per band. Change-Id: I470ab916359092ba465e7b6331baed3bf11b2fc9
This commit is contained in:
parent
1007216fc4
commit
e764656ab7
6 changed files with 231 additions and 92 deletions
|
|
@ -1091,10 +1091,10 @@
|
||||||
desc: in the equalizer settings menu
|
desc: in the equalizer settings menu
|
||||||
user: core
|
user: core
|
||||||
<source>
|
<source>
|
||||||
*: "Peak Filter %d"
|
*: "Peak Filter"
|
||||||
</source>
|
</source>
|
||||||
<dest>
|
<dest>
|
||||||
*: "Peak Filter %d"
|
*: "Peak Filter"
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: "Peak filter"
|
*: "Peak filter"
|
||||||
|
|
@ -17169,3 +17169,31 @@
|
||||||
*: "Finished"
|
*: "Finished"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
id: LANG_EQUALIZER_BAND
|
||||||
|
desc: in the equalizer settings menu
|
||||||
|
user: core
|
||||||
|
<source>
|
||||||
|
*: "Filter %d"
|
||||||
|
</source>
|
||||||
|
<dest>
|
||||||
|
*: "Filter %d"
|
||||||
|
</dest>
|
||||||
|
<voice>
|
||||||
|
*: "Filter"
|
||||||
|
</voice>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
id: LANG_EQUALIZER_FILTER_TYPE
|
||||||
|
desc: in the equalizer settings menu
|
||||||
|
user: core
|
||||||
|
<source>
|
||||||
|
*: "Filter Type"
|
||||||
|
</source>
|
||||||
|
<dest>
|
||||||
|
*: "Filter Type"
|
||||||
|
</dest>
|
||||||
|
<voice>
|
||||||
|
*: "Filter Type"
|
||||||
|
</voice>
|
||||||
|
</phrase>
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,17 @@ static const struct int_setting cutoff_int_setting = {
|
||||||
.get_talk_id = NULL,
|
.get_talk_id = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct choice_setting type_choice_setting = {
|
||||||
|
.option_callback = NULL,
|
||||||
|
.count = 3,
|
||||||
|
.cfg_vals = "low_shelf,peaking,high_shelf",
|
||||||
|
{.desc = (const unsigned char*[]) {
|
||||||
|
ID2P(LANG_EQUALIZER_BAND_LOW_SHELF),
|
||||||
|
ID2P(LANG_EQUALIZER_BAND_PEAK),
|
||||||
|
ID2P(LANG_EQUALIZER_BAND_HIGH_SHELF),
|
||||||
|
}}
|
||||||
|
};
|
||||||
|
|
||||||
static int simplelist_action_callback(int action, struct gui_synclist *lists)
|
static int simplelist_action_callback(int action, struct gui_synclist *lists)
|
||||||
{
|
{
|
||||||
(void)lists;
|
(void)lists;
|
||||||
|
|
@ -234,7 +245,7 @@ static void selection_to_banditem(int selection, int expanded_band, int *band, i
|
||||||
*item = 0;
|
*item = 0;
|
||||||
*band = selection;
|
*band = selection;
|
||||||
}
|
}
|
||||||
else if (diff < 4)
|
else if (diff < 5)
|
||||||
{
|
{
|
||||||
*item = selection - expanded_band;
|
*item = selection - expanded_band;
|
||||||
*band = expanded_band;
|
*band = expanded_band;
|
||||||
|
|
@ -242,7 +253,7 @@ static void selection_to_banditem(int selection, int expanded_band, int *band, i
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*item = 0;
|
*item = 0;
|
||||||
*band = expanded_band + diff - 3;
|
*band = expanded_band + diff - 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,23 +268,13 @@ static char *advancedmenu_item_get_name(int selected_item, void *data, char *buf
|
||||||
switch (item)
|
switch (item)
|
||||||
{
|
{
|
||||||
case 0: /* Band title */
|
case 0: /* Band title */
|
||||||
if (band == 0)
|
snprintf(buffer, len, str(LANG_EQUALIZER_BAND), band);
|
||||||
return str(LANG_EQUALIZER_BAND_LOW_SHELF);
|
return buffer;
|
||||||
else if (band == EQ_NUM_BANDS - 1)
|
|
||||||
return str(LANG_EQUALIZER_BAND_HIGH_SHELF);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
snprintf(buffer, len, str(LANG_EQUALIZER_BAND_PEAK), band);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: /* cutoff */
|
case 1: /* cutoff */
|
||||||
if (band == 0)
|
if (global_settings.eq_band_settings[band].type == EQ_FILTER_PEAK)
|
||||||
lang = LANG_EQUALIZER_BAND_CUTOFF;
|
|
||||||
else if (band == EQ_NUM_BANDS - 1)
|
|
||||||
lang = LANG_EQUALIZER_BAND_CUTOFF;
|
|
||||||
else
|
|
||||||
lang = LANG_EQUALIZER_BAND_CENTER;
|
lang = LANG_EQUALIZER_BAND_CENTER;
|
||||||
|
else
|
||||||
|
lang = LANG_EQUALIZER_BAND_CUTOFF;
|
||||||
break;
|
break;
|
||||||
case 2: /* Q */
|
case 2: /* Q */
|
||||||
lang = LANG_EQUALIZER_BAND_Q;
|
lang = LANG_EQUALIZER_BAND_Q;
|
||||||
|
|
@ -281,6 +282,9 @@ static char *advancedmenu_item_get_name(int selected_item, void *data, char *buf
|
||||||
case 3: /* Gain */
|
case 3: /* Gain */
|
||||||
lang = LANG_GAIN;
|
lang = LANG_GAIN;
|
||||||
break;
|
break;
|
||||||
|
case 4: /* Type */
|
||||||
|
lang = LANG_EQUALIZER_FILTER_TYPE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lang < 0)
|
if(lang < 0)
|
||||||
|
|
@ -305,24 +309,14 @@ static int advancedmenu_speak_item(int selected_item, void *data)
|
||||||
switch (item)
|
switch (item)
|
||||||
{
|
{
|
||||||
case 0: /* Band title */
|
case 0: /* Band title */
|
||||||
if (band == 0)
|
talk_id(LANG_EQUALIZER_BAND, false);
|
||||||
lang = LANG_EQUALIZER_BAND_LOW_SHELF;
|
talk_number(band, true);
|
||||||
else if (band == EQ_NUM_BANDS - 1)
|
return -1;
|
||||||
lang = LANG_EQUALIZER_BAND_HIGH_SHELF;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
talk_id(LANG_EQUALIZER_BAND_PEAK, false);
|
|
||||||
talk_number(band, true);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: /* cutoff */
|
case 1: /* cutoff */
|
||||||
if (band == 0)
|
if (global_settings.eq_band_settings[band].type == EQ_FILTER_PEAK)
|
||||||
lang = LANG_EQUALIZER_BAND_CUTOFF;
|
|
||||||
else if (band == EQ_NUM_BANDS - 1)
|
|
||||||
lang = LANG_EQUALIZER_BAND_CUTOFF;
|
|
||||||
else
|
|
||||||
lang = LANG_EQUALIZER_BAND_CENTER;
|
lang = LANG_EQUALIZER_BAND_CENTER;
|
||||||
|
else
|
||||||
|
lang = LANG_EQUALIZER_BAND_CUTOFF;
|
||||||
break;
|
break;
|
||||||
case 2: /* Q */
|
case 2: /* Q */
|
||||||
lang = LANG_EQUALIZER_BAND_Q;
|
lang = LANG_EQUALIZER_BAND_Q;
|
||||||
|
|
@ -368,7 +362,6 @@ static int eq_do_advanced_menu(void * param)
|
||||||
info.action_callback = simplelist_action_callback;
|
info.action_callback = simplelist_action_callback;
|
||||||
info.selection = -1;
|
info.selection = -1;
|
||||||
info.title_icon = Icon_EQ;
|
info.title_icon = Icon_EQ;
|
||||||
setting.flags = F_BANFROMQS|F_INT_SETTING|F_T_INT|F_NO_WRAP;
|
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
@ -388,7 +381,7 @@ static int eq_do_advanced_menu(void * param)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
extra = 3;
|
extra = 4;
|
||||||
selected_band = band;
|
selected_band = band;
|
||||||
}
|
}
|
||||||
info.selection = band;
|
info.selection = band;
|
||||||
|
|
@ -396,7 +389,8 @@ static int eq_do_advanced_menu(void * param)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case 1: /* cutoff */
|
case 1: /* cutoff */
|
||||||
if (band == 0 || band == EQ_NUM_BANDS - 1)
|
setting.flags = F_BANFROMQS|F_INT_SETTING|F_T_INT|F_NO_WRAP;
|
||||||
|
if (global_settings.eq_band_settings[band].type != EQ_FILTER_PEAK)
|
||||||
setting.lang_id = LANG_EQUALIZER_BAND_CUTOFF;
|
setting.lang_id = LANG_EQUALIZER_BAND_CUTOFF;
|
||||||
else
|
else
|
||||||
setting.lang_id = LANG_EQUALIZER_BAND_CENTER;
|
setting.lang_id = LANG_EQUALIZER_BAND_CENTER;
|
||||||
|
|
@ -405,17 +399,26 @@ static int eq_do_advanced_menu(void * param)
|
||||||
setting.setting = &global_settings.eq_band_settings[band].cutoff;
|
setting.setting = &global_settings.eq_band_settings[band].cutoff;
|
||||||
break;
|
break;
|
||||||
case 2: /* Q */
|
case 2: /* Q */
|
||||||
|
setting.flags = F_BANFROMQS|F_INT_SETTING|F_T_INT|F_NO_WRAP;
|
||||||
setting.lang_id = LANG_EQUALIZER_BAND_Q;
|
setting.lang_id = LANG_EQUALIZER_BAND_Q;
|
||||||
setting.default_val.int_ = eq_defaults[band].q;
|
setting.default_val.int_ = eq_defaults[band].q;
|
||||||
setting.int_setting = &q_int_setting;
|
setting.int_setting = &q_int_setting;
|
||||||
setting.setting = &global_settings.eq_band_settings[band].q;
|
setting.setting = &global_settings.eq_band_settings[band].q;
|
||||||
break;
|
break;
|
||||||
case 3: /* Gain */
|
case 3: /* Gain */
|
||||||
|
setting.flags = F_BANFROMQS|F_INT_SETTING|F_T_INT|F_NO_WRAP;
|
||||||
setting.lang_id = LANG_GAIN;
|
setting.lang_id = LANG_GAIN;
|
||||||
setting.default_val.int_ = eq_defaults[band].gain;
|
setting.default_val.int_ = eq_defaults[band].gain;
|
||||||
setting.int_setting = &gain_int_setting;
|
setting.int_setting = &gain_int_setting;
|
||||||
setting.setting = &global_settings.eq_band_settings[band].gain;
|
setting.setting = &global_settings.eq_band_settings[band].gain;
|
||||||
break;
|
break;
|
||||||
|
case 4: /* Type */
|
||||||
|
setting.flags = F_BANFROMQS|F_CHOICE_SETTING|F_T_INT;
|
||||||
|
setting.lang_id = LANG_EQUALIZER_FILTER_TYPE;
|
||||||
|
setting.default_val.int_ = eq_defaults[band].type;
|
||||||
|
setting.choice_setting = &type_choice_setting;
|
||||||
|
setting.setting = &global_settings.eq_band_settings[band].type;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
pcmbuf_set_low_latency(true);
|
pcmbuf_set_low_latency(true);
|
||||||
advancedmenu_item_get_name(info.selection, &selected_band, title, MAX_PATH);
|
advancedmenu_item_get_name(info.selection, &selected_band, title, MAX_PATH);
|
||||||
|
|
@ -430,21 +433,17 @@ MENUITEM_FUNCTION(advanced_menu, 0, ID2P(LANG_EQUALIZER_ADVANCED),
|
||||||
eq_do_advanced_menu, NULL, Icon_EQ);
|
eq_do_advanced_menu, NULL, Icon_EQ);
|
||||||
|
|
||||||
enum eq_slider_mode {
|
enum eq_slider_mode {
|
||||||
|
TYPE,
|
||||||
GAIN,
|
GAIN,
|
||||||
CUTOFF,
|
CUTOFF,
|
||||||
Q,
|
Q,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eq_type {
|
|
||||||
LOW_SHELF,
|
|
||||||
PEAK,
|
|
||||||
HIGH_SHELF
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Draw the UI for a whole EQ band */
|
/* Draw the UI for a whole EQ band */
|
||||||
static int draw_eq_slider(struct screen * screen, int x, int y,
|
static int draw_eq_slider(struct screen * screen, int x, int y,
|
||||||
int width, int cutoff, int q, int gain, bool selected,
|
int width, int cutoff, int q, int gain, bool selected,
|
||||||
enum eq_slider_mode mode, int band, int scrollbar_size)
|
enum eq_slider_mode mode, int band, int scrollbar_size,
|
||||||
|
enum eq_filter_type type)
|
||||||
{
|
{
|
||||||
char buf[26];
|
char buf[26];
|
||||||
int steps, min_item, max_item;
|
int steps, min_item, max_item;
|
||||||
|
|
@ -453,6 +452,11 @@ static int draw_eq_slider(struct screen * screen, int x, int y,
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
|
case TYPE:
|
||||||
|
steps = 5;
|
||||||
|
min_item = (type * 2);
|
||||||
|
max_item = (type * 2) + 1;
|
||||||
|
break;
|
||||||
case Q:
|
case Q:
|
||||||
steps = EQ_Q_MAX - EQ_Q_MIN;
|
steps = EQ_Q_MAX - EQ_Q_MIN;
|
||||||
min_item = q - EQ_Q_STEP - EQ_Q_MIN;
|
min_item = q - EQ_Q_STEP - EQ_Q_MIN;
|
||||||
|
|
@ -476,11 +480,17 @@ static int draw_eq_slider(struct screen * screen, int x, int y,
|
||||||
y1 = y + 2;
|
y1 = y + 2;
|
||||||
|
|
||||||
/* Print out the band label */
|
/* Print out the band label */
|
||||||
if (band == 0) {
|
if (mode == TYPE && selected)
|
||||||
screen->putsxy(x1, y1, "LS: ");
|
screen->set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
|
||||||
|
else
|
||||||
|
screen->set_drawmode(DRMODE_SOLID);
|
||||||
|
if (type == EQ_FILTER_LOW_SHELF) {
|
||||||
|
snprintf(buf, sizeof(buf), "LS%d:", band);
|
||||||
|
screen->putsxy(x1, y1, buf);
|
||||||
/*screen->getstringsize("LS:", &w, &h); UNUSED*/
|
/*screen->getstringsize("LS:", &w, &h); UNUSED*/
|
||||||
} else if (band == EQ_NUM_BANDS - 1) {
|
} else if (type == EQ_FILTER_HIGH_SHELF) {
|
||||||
screen->putsxy(x1, y1, "HS: ");
|
snprintf(buf, sizeof(buf), "HS%d:", band);
|
||||||
|
screen->putsxy(x1, y1, buf);
|
||||||
/*screen->getstringsize("HS:", &w, &h); UNUSED*/
|
/*screen->getstringsize("HS:", &w, &h); UNUSED*/
|
||||||
} else {
|
} else {
|
||||||
snprintf(buf, sizeof(buf), "PK%d:", band);
|
snprintf(buf, sizeof(buf), "PK%d:", band);
|
||||||
|
|
@ -557,6 +567,7 @@ static void draw_eq_sliders(struct screen * screen, int x, int y,
|
||||||
int cutoff = setting->cutoff;
|
int cutoff = setting->cutoff;
|
||||||
int q = setting->q;
|
int q = setting->q;
|
||||||
int gain = setting->gain;
|
int gain = setting->gain;
|
||||||
|
enum eq_filter_type type = setting->type;
|
||||||
|
|
||||||
if (i == start_item + nb_eq_sliders)
|
if (i == start_item + nb_eq_sliders)
|
||||||
break;
|
break;
|
||||||
|
|
@ -564,7 +575,7 @@ static void draw_eq_sliders(struct screen * screen, int x, int y,
|
||||||
if (i >= start_item) {
|
if (i >= start_item) {
|
||||||
height += draw_eq_slider(screen, x, height, screen->lcdwidth - x - 1,
|
height += draw_eq_slider(screen, x, height, screen->lcdwidth - x - 1,
|
||||||
cutoff, q, gain, i == current_band, mode,
|
cutoff, q, gain, i == current_band, mode,
|
||||||
i, scrollbar_size);
|
i, scrollbar_size, type);
|
||||||
/* add a margin */
|
/* add a margin */
|
||||||
height++;
|
height++;
|
||||||
}
|
}
|
||||||
|
|
@ -629,7 +640,18 @@ int eq_menu_graphical(void)
|
||||||
screens[i].clear_display();
|
screens[i].clear_display();
|
||||||
|
|
||||||
/* Set pointer to the band data currently editable */
|
/* Set pointer to the band data currently editable */
|
||||||
if (mode == GAIN) {
|
if (mode == TYPE) {
|
||||||
|
/* type */
|
||||||
|
setting = (int*) &global_settings.eq_band_settings[current_band].type;
|
||||||
|
|
||||||
|
step = 1;
|
||||||
|
fast_step = 1;
|
||||||
|
min = EQ_FILTER_LOW_SHELF;
|
||||||
|
max = EQ_FILTER_HIGH_SHELF;
|
||||||
|
|
||||||
|
screens[i].putsxyf(0, 0, str(LANG_SYSFONT_EQUALIZER_EDIT_MODE),
|
||||||
|
str(LANG_EQUALIZER_FILTER_TYPE), "");
|
||||||
|
} else if (mode == GAIN) {
|
||||||
/* gain */
|
/* gain */
|
||||||
setting = &global_settings.eq_band_settings[current_band].gain;
|
setting = &global_settings.eq_band_settings[current_band].gain;
|
||||||
|
|
||||||
|
|
@ -734,7 +756,7 @@ int eq_menu_graphical(void)
|
||||||
case ACTION_STD_OK:
|
case ACTION_STD_OK:
|
||||||
mode++;
|
mode++;
|
||||||
if (mode > Q)
|
if (mode > Q)
|
||||||
mode = GAIN; /* wrap around */
|
mode = TYPE; /* wrap around */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_STD_CANCEL:
|
case ACTION_STD_CANCEL:
|
||||||
|
|
@ -785,6 +807,7 @@ static struct browse_folder_info eqs = { EQS_DIR, SHOW_CFG };
|
||||||
static void eq_reset_defaults(void)
|
static void eq_reset_defaults(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < EQ_NUM_BANDS; i++) {
|
for (int i = 0; i < EQ_NUM_BANDS; i++) {
|
||||||
|
global_settings.eq_band_settings[i].type = eq_defaults[i].type;
|
||||||
global_settings.eq_band_settings[i].cutoff = eq_defaults[i].cutoff;
|
global_settings.eq_band_settings[i].cutoff = eq_defaults[i].cutoff;
|
||||||
global_settings.eq_band_settings[i].q = eq_defaults[i].q;
|
global_settings.eq_band_settings[i].q = eq_defaults[i].q;
|
||||||
global_settings.eq_band_settings[i].gain = eq_defaults[i].gain;
|
global_settings.eq_band_settings[i].gain = eq_defaults[i].gain;
|
||||||
|
|
|
||||||
|
|
@ -676,16 +676,16 @@ static int32_t get_precut_talkid(int value, int unit)
|
||||||
#endif /* __PCTOOL__ */
|
#endif /* __PCTOOL__ */
|
||||||
|
|
||||||
struct eq_band_setting eq_defaults[EQ_NUM_BANDS] = {
|
struct eq_band_setting eq_defaults[EQ_NUM_BANDS] = {
|
||||||
{ 32, 7, 0 },
|
{ EQ_FILTER_LOW_SHELF, 32, 7, 0 },
|
||||||
{ 64, 10, 0 },
|
{ EQ_FILTER_PEAK, 64, 10, 0 },
|
||||||
{ 125, 10, 0 },
|
{ EQ_FILTER_PEAK, 125, 10, 0 },
|
||||||
{ 250, 10, 0 },
|
{ EQ_FILTER_PEAK, 250, 10, 0 },
|
||||||
{ 500, 10, 0 },
|
{ EQ_FILTER_PEAK, 500, 10, 0 },
|
||||||
{ 1000, 10, 0 },
|
{ EQ_FILTER_PEAK, 1000, 10, 0 },
|
||||||
{ 2000, 10, 0 },
|
{ EQ_FILTER_PEAK, 2000, 10, 0 },
|
||||||
{ 4000, 10, 0 },
|
{ EQ_FILTER_PEAK, 4000, 10, 0 },
|
||||||
{ 8000, 10, 0 },
|
{ EQ_FILTER_PEAK, 8000, 10, 0 },
|
||||||
{ 16000, 7, 0 },
|
{ EQ_FILTER_HIGH_SHELF, 16000, 7, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int wps_context_menu_default =
|
static const int wps_context_menu_default =
|
||||||
|
|
@ -704,7 +704,7 @@ static const int tree_hotkey_default = HOTKEY_OFF;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __PCTOOL__
|
#ifndef __PCTOOL__
|
||||||
static void eq_load_from_cfg(void *setting, char *value)
|
static void eq_load_from_cfg(void *setting, char *value, bool new)
|
||||||
{
|
{
|
||||||
struct eq_band_setting *eq = setting;
|
struct eq_band_setting *eq = setting;
|
||||||
char *val_end, *end;
|
char *val_end, *end;
|
||||||
|
|
@ -728,14 +728,68 @@ static void eq_load_from_cfg(void *setting, char *value)
|
||||||
/* gain */
|
/* gain */
|
||||||
value = end + 1;
|
value = end + 1;
|
||||||
if (value > val_end) return;
|
if (value > val_end) return;
|
||||||
|
if (new)
|
||||||
|
{
|
||||||
|
end = strchr(value, ',');
|
||||||
|
if (!end) return;
|
||||||
|
}
|
||||||
eq->gain = atoi(value);
|
eq->gain = atoi(value);
|
||||||
|
|
||||||
|
if (!new) return;
|
||||||
|
|
||||||
|
/* type */
|
||||||
|
value = end + 1;
|
||||||
|
if (value > val_end) return;
|
||||||
|
value = skip_whitespace(value);
|
||||||
|
if (strcasecmp(value, "LOW_SHELF") == 0)
|
||||||
|
eq->type = EQ_FILTER_LOW_SHELF;
|
||||||
|
else if (strcasecmp(value, "PEAK") == 0)
|
||||||
|
eq->type = EQ_FILTER_PEAK;
|
||||||
|
else if (strcasecmp(value, "HIGH_SHELF") == 0)
|
||||||
|
eq->type = EQ_FILTER_HIGH_SHELF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eq_load_from_cfg_old_low_shelf(void *setting, char *value)
|
||||||
|
{
|
||||||
|
eq_load_from_cfg(setting, value, false);
|
||||||
|
((struct eq_band_setting *)setting)->type = EQ_FILTER_LOW_SHELF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eq_load_from_cfg_old_peak(void *setting, char *value)
|
||||||
|
{
|
||||||
|
eq_load_from_cfg(setting, value, false);
|
||||||
|
((struct eq_band_setting *)setting)->type = EQ_FILTER_PEAK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eq_load_from_cfg_old_high_shelf(void *setting, char *value)
|
||||||
|
{
|
||||||
|
eq_load_from_cfg(setting, value, false);
|
||||||
|
((struct eq_band_setting *)setting)->type = EQ_FILTER_HIGH_SHELF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eq_load_from_cfg_new(void *setting, char *value)
|
||||||
|
{
|
||||||
|
eq_load_from_cfg(setting, value, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* eq_write_to_cfg(void *setting, char *buf, int buf_len)
|
static char* eq_write_to_cfg(void *setting, char *buf, int buf_len)
|
||||||
{
|
{
|
||||||
struct eq_band_setting *eq = setting;
|
struct eq_band_setting *eq = setting;
|
||||||
|
|
||||||
snprintf(buf, buf_len, "%d, %d, %d", eq->cutoff, eq->q, eq->gain);
|
const char *type = "PEAK";
|
||||||
|
switch (eq->type)
|
||||||
|
{
|
||||||
|
case EQ_FILTER_LOW_SHELF:
|
||||||
|
type = "LOW_SHELF";
|
||||||
|
break;
|
||||||
|
case EQ_FILTER_PEAK:
|
||||||
|
type = "PEAK";
|
||||||
|
break;
|
||||||
|
case EQ_FILTER_HIGH_SHELF:
|
||||||
|
type = "HIGH_SHELF";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
snprintf(buf, buf_len, "%d, %d, %d, %s", eq->cutoff, eq->q, eq->gain, type);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1835,21 +1889,39 @@ const struct settings_list settings[] = {
|
||||||
"eq precut", UNIT_DB, 0, 240, 1, eq_precut_format,
|
"eq precut", UNIT_DB, 0, 240, 1, eq_precut_format,
|
||||||
get_precut_talkid, dsp_set_eq_precut),
|
get_precut_talkid, dsp_set_eq_precut),
|
||||||
|
|
||||||
|
|
||||||
|
#define EQ_BAND_OLD(id, string, type) \
|
||||||
|
CUSTOM_SETTING(F_EQSETTING|F_DEPRECATED, eq_band_settings[id], -1, \
|
||||||
|
&eq_defaults[id], string, \
|
||||||
|
eq_load_from_cfg_old_##type, eq_write_to_cfg, \
|
||||||
|
eq_is_changed, eq_set_default)
|
||||||
|
EQ_BAND_OLD(0, "eq low shelf filter", low_shelf),
|
||||||
|
EQ_BAND_OLD(1, "eq peak filter 1", peak),
|
||||||
|
EQ_BAND_OLD(2, "eq peak filter 2", peak),
|
||||||
|
EQ_BAND_OLD(3, "eq peak filter 3", peak),
|
||||||
|
EQ_BAND_OLD(4, "eq peak filter 4", peak),
|
||||||
|
EQ_BAND_OLD(5, "eq peak filter 5", peak),
|
||||||
|
EQ_BAND_OLD(6, "eq peak filter 6", peak),
|
||||||
|
EQ_BAND_OLD(7, "eq peak filter 7", peak),
|
||||||
|
EQ_BAND_OLD(8, "eq peak filter 8", peak),
|
||||||
|
EQ_BAND_OLD(9, "eq high shelf filter", high_shelf),
|
||||||
|
#undef EQ_BAND_OLD
|
||||||
|
|
||||||
#define EQ_BAND(id, string) \
|
#define EQ_BAND(id, string) \
|
||||||
CUSTOM_SETTING(F_EQSETTING, eq_band_settings[id], -1, \
|
CUSTOM_SETTING(F_EQSETTING, eq_band_settings[id], -1, \
|
||||||
&eq_defaults[id], string, \
|
&eq_defaults[id], string, \
|
||||||
eq_load_from_cfg, eq_write_to_cfg, \
|
eq_load_from_cfg_new, eq_write_to_cfg, \
|
||||||
eq_is_changed, eq_set_default)
|
eq_is_changed, eq_set_default)
|
||||||
EQ_BAND(0, "eq low shelf filter"),
|
EQ_BAND(0, "eq filter 0"),
|
||||||
EQ_BAND(1, "eq peak filter 1"),
|
EQ_BAND(1, "eq filter 1"),
|
||||||
EQ_BAND(2, "eq peak filter 2"),
|
EQ_BAND(2, "eq filter 2"),
|
||||||
EQ_BAND(3, "eq peak filter 3"),
|
EQ_BAND(3, "eq filter 3"),
|
||||||
EQ_BAND(4, "eq peak filter 4"),
|
EQ_BAND(4, "eq filter 4"),
|
||||||
EQ_BAND(5, "eq peak filter 5"),
|
EQ_BAND(5, "eq filter 5"),
|
||||||
EQ_BAND(6, "eq peak filter 6"),
|
EQ_BAND(6, "eq filter 6"),
|
||||||
EQ_BAND(7, "eq peak filter 7"),
|
EQ_BAND(7, "eq filter 7"),
|
||||||
EQ_BAND(8, "eq peak filter 8"),
|
EQ_BAND(8, "eq filter 8"),
|
||||||
EQ_BAND(9, "eq high shelf filter"),
|
EQ_BAND(9, "eq filter 9"),
|
||||||
#undef EQ_BAND
|
#undef EQ_BAND
|
||||||
|
|
||||||
/* dithering */
|
/* dithering */
|
||||||
|
|
|
||||||
|
|
@ -71,15 +71,22 @@ static void update_band_filter(int band, unsigned int fout)
|
||||||
functions */
|
functions */
|
||||||
typeof (filter_pk_coefs) *coef_gen = filter_pk_coefs;
|
typeof (filter_pk_coefs) *coef_gen = filter_pk_coefs;
|
||||||
|
|
||||||
/* Only first and last bands are not peaking filters */
|
|
||||||
if (band == 0)
|
|
||||||
coef_gen = filter_ls_coefs;
|
|
||||||
else if (band == EQ_NUM_BANDS-1)
|
|
||||||
coef_gen = filter_hs_coefs;
|
|
||||||
|
|
||||||
const struct eq_band_setting *setting = &settings[band];
|
const struct eq_band_setting *setting = &settings[band];
|
||||||
struct dsp_filter *filter = &eq_data.filters[band];
|
struct dsp_filter *filter = &eq_data.filters[band];
|
||||||
|
|
||||||
|
switch (setting->type)
|
||||||
|
{
|
||||||
|
case EQ_FILTER_LOW_SHELF:
|
||||||
|
coef_gen = filter_ls_coefs;
|
||||||
|
break;
|
||||||
|
case EQ_FILTER_PEAK:
|
||||||
|
coef_gen = filter_pk_coefs;
|
||||||
|
break;
|
||||||
|
case EQ_FILTER_HIGH_SHELF:
|
||||||
|
coef_gen = filter_hs_coefs;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
coef_gen(fp_div(setting->cutoff, fout, 32), setting->q ?: 1,
|
coef_gen(fp_div(setting->cutoff, fout, 32), setting->q ?: 1,
|
||||||
setting->gain, filter);
|
setting->gain, filter);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,16 @@
|
||||||
/* => support from 3 to 32 bands */
|
/* => support from 3 to 32 bands */
|
||||||
#define EQ_NUM_BANDS 10
|
#define EQ_NUM_BANDS 10
|
||||||
|
|
||||||
|
enum eq_filter_type
|
||||||
|
{
|
||||||
|
EQ_FILTER_LOW_SHELF = 0,
|
||||||
|
EQ_FILTER_PEAK,
|
||||||
|
EQ_FILTER_HIGH_SHELF,
|
||||||
|
};
|
||||||
|
|
||||||
struct eq_band_setting
|
struct eq_band_setting
|
||||||
{
|
{
|
||||||
|
enum eq_filter_type type;
|
||||||
int cutoff; /* Hz */
|
int cutoff; /* Hz */
|
||||||
int q;
|
int q;
|
||||||
int gain; /* +/- dB */
|
int gain; /* +/- dB */
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,7 @@ change to customise your listening experience.
|
||||||
\section{\label{ref:EQ}Equalizer}
|
\section{\label{ref:EQ}Equalizer}
|
||||||
\screenshot{configure_rockbox/images/ss-equalizer}{The graphical equalizer}{}
|
\screenshot{configure_rockbox/images/ss-equalizer}{The graphical equalizer}{}
|
||||||
Rockbox features a parametric equalizer (EQ). In contrast to non-parametric
|
Rockbox features a parametric equalizer (EQ). In contrast to non-parametric
|
||||||
equalizers, a parametric EQ enables adjusting the center frequency, gain, and
|
equalizers, a parametric EQ enables adjusting the type, center frequency, gain, and
|
||||||
width of EQ bands separately. The ability to adjust the frequency and width
|
width of EQ bands separately. The ability to adjust the frequency and width
|
||||||
of bands enables more precise control of the EQ frequency response while
|
of bands enables more precise control of the EQ frequency response while
|
||||||
avoiding the use of a large number of bands (often 12+) needed in a
|
avoiding the use of a large number of bands (often 12+) needed in a
|
||||||
|
|
@ -338,10 +338,11 @@ change to customise your listening experience.
|
||||||
than are required will waste battery and introduce additional rounding
|
than are required will waste battery and introduce additional rounding
|
||||||
noise. For best results, use the fewest number of bands required.}
|
noise. For best results, use the fewest number of bands required.}
|
||||||
|
|
||||||
Rockbox's parametric EQ is composed of up to ten different bands:
|
Rockbox's parametric EQ is composed of up to ten EQ bands consisting of any combination of three different filter types:
|
||||||
|
|
||||||
\begin{description}
|
\begin{description}
|
||||||
\item[Band 0: Low shelf filter.]
|
\item[Low shelf filter.]
|
||||||
The low shelf filter boosts or lowers all frequencies below a certain
|
Low shelf filters boost or lower all frequencies below a certain
|
||||||
frequency limit, much as the ``bass'' control found on ordinary
|
frequency limit, much as the ``bass'' control found on ordinary
|
||||||
stereo systems does.
|
stereo systems does.
|
||||||
Adjust the ``cutoff'' frequency parameter to decide where the shelving
|
Adjust the ``cutoff'' frequency parameter to decide where the shelving
|
||||||
|
|
@ -354,12 +355,12 @@ change to customise your listening experience.
|
||||||
The ``Q'' parameter should always be set to 0.7 for the shelving
|
The ``Q'' parameter should always be set to 0.7 for the shelving
|
||||||
filters. Higher values will add a small boost around the cutoff
|
filters. Higher values will add a small boost around the cutoff
|
||||||
frequency that is almost always undesirable.
|
frequency that is almost always undesirable.
|
||||||
\item[Bands 1-8: Peaking filters.]
|
\item[Peaking filters.]
|
||||||
Peaking EQ filters boost or lower a frequency range centered at the
|
Peaking EQ filters boost or lower a frequency range centered at the
|
||||||
centre frequency chosen.
|
centre frequency chosen.
|
||||||
Graphic equalizers in home stereos are usually peaking
|
Graphic equalizers in home stereos are usually peaking
|
||||||
filters. The peaking filters in Rockbox's EQ lets you adjust three
|
filters. The peaking filters in Rockbox's EQ lets you adjust three
|
||||||
different parameters for EQ bands 1 through 8. The ``centre'' parameter
|
different parameters. The ``centre'' parameter
|
||||||
controls the centre frequency of the frequency range that is affected
|
controls the centre frequency of the frequency range that is affected
|
||||||
as described above.
|
as described above.
|
||||||
The ``gain'' parameter controls how much each band is adjusted, and
|
The ``gain'' parameter controls how much each band is adjusted, and
|
||||||
|
|
@ -368,11 +369,11 @@ change to customise your listening experience.
|
||||||
frequency range is. Higher Q values will affect a narrower band of
|
frequency range is. Higher Q values will affect a narrower band of
|
||||||
frequencies, while lower Q values will affect a wider band of
|
frequencies, while lower Q values will affect a wider band of
|
||||||
frequencies.
|
frequencies.
|
||||||
\item[Band 9: High shelf filter.]
|
\item[High shelf filter.]
|
||||||
A high shelf filter boosts or lowers all frequencies above a certain
|
A high shelf filter boosts or lowers all frequencies above a certain
|
||||||
frequency limit, much as the ``treble'' control found on ordinary
|
frequency limit, much as the ``treble'' control found on ordinary
|
||||||
stereo systems does.
|
stereo systems does.
|
||||||
The high shelf filter is adjusted the same way as the low shelf filter,
|
A high shelf filter is adjusted the same way as A low shelf filter,
|
||||||
except that it works on the high end of the frequency spectrum rather
|
except that it works on the high end of the frequency spectrum rather
|
||||||
than the low end.
|
than the low end.
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
@ -385,7 +386,7 @@ change to customise your listening experience.
|
||||||
|
|
||||||
\item[Graphical EQ.]
|
\item[Graphical EQ.]
|
||||||
This option brings up a graphic EQ screen, which allows adjustment of each of
|
This option brings up a graphic EQ screen, which allows adjustment of each of
|
||||||
the three parameters described above (gain, centre frequency, and Q) for each
|
the four parameters described above (gain, centre frequency, Q, and type) for each
|
||||||
of the five EQ bands.
|
of the five EQ bands.
|
||||||
|
|
||||||
\begin{btnmap}
|
\begin{btnmap}
|
||||||
|
|
@ -476,8 +477,8 @@ change to customise your listening experience.
|
||||||
\opt{IRIVER_RC_H100_PAD}{\ButtonRCSelect}
|
\opt{IRIVER_RC_H100_PAD}{\ButtonRCSelect}
|
||||||
\opt{GIGABEAT_RC_PAD,IAUDIO_RC_PAD}{\ButtonRCPlay}
|
\opt{GIGABEAT_RC_PAD,IAUDIO_RC_PAD}{\ButtonRCPlay}
|
||||||
&}
|
&}
|
||||||
Toggles the cursor among the three parameters (gain, centre frequency,
|
Toggles the cursor among the four parameters (type, gain, centre
|
||||||
Q) for the selected EQ band
|
frequency, Q) for the selected EQ band
|
||||||
\\
|
\\
|
||||||
%
|
%
|
||||||
\opt{IRIVER_H100_PAD,IRIVER_H300_PAD}{\ButtonMode}
|
\opt{IRIVER_H100_PAD,IRIVER_H300_PAD}{\ButtonMode}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue