summaryrefslogtreecommitdiff
path: root/apps/eq_menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/eq_menu.c')
-rw-r--r--apps/eq_menu.c1182
1 files changed, 0 insertions, 1182 deletions
diff --git a/apps/eq_menu.c b/apps/eq_menu.c
deleted file mode 100644
index beaf385366..0000000000
--- a/apps/eq_menu.c
+++ /dev/null
@@ -1,1182 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "config.h"
21#include <stdio.h>
22#include <stdbool.h>
23#include <string.h>
24#include "eq_menu.h"
25#include "system.h"
26#include "kernel.h"
27#include "lcd.h"
28#include "menu.h"
29#include "action.h"
30#include "mp3_playback.h"
31#include "settings.h"
32#include "statusbar.h"
33#include "screens.h"
34#include "icons.h"
35#include "font.h"
36#include "lang.h"
37#include "sprintf.h"
38#include "talk.h"
39#include "misc.h"
40#include "sound.h"
41#include "splash.h"
42#include "dsp.h"
43#include "tree.h"
44#include "talk.h"
45#include "screen_access.h"
46#include "keyboard.h"
47#include "gui/scrollbar.h"
48#ifdef HAVE_WM8758
49#include "wm8758.h"
50#endif
51
52/* Various user interface limits and sizes */
53#define EQ_CUTOFF_MIN 20
54#define EQ_CUTOFF_MAX 22040
55#define EQ_CUTOFF_STEP 10
56#define EQ_CUTOFF_FAST_STEP 100
57#define EQ_GAIN_MIN (-240)
58#define EQ_GAIN_MAX 240
59#define EQ_GAIN_STEP 5
60#define EQ_GAIN_FAST_STEP 10
61#define EQ_Q_MIN 5
62#define EQ_Q_MAX 64
63#define EQ_Q_STEP 1
64#define EQ_Q_FAST_STEP 10
65
66#define EQ_USER_DIVISOR 10
67
68/*
69 * Utility functions
70 */
71
72static void eq_gain_format(char* buffer, int buffer_size, int value, const char* unit)
73{
74 int v = abs(value);
75
76 snprintf(buffer, buffer_size, "%s%d.%d %s", value < 0 ? "-" : "",
77 v / EQ_USER_DIVISOR, v % EQ_USER_DIVISOR, unit);
78}
79
80static void eq_q_format(char* buffer, int buffer_size, int value, const char* unit)
81{
82 snprintf(buffer, buffer_size, "%d.%d %s", value / EQ_USER_DIVISOR, value % EQ_USER_DIVISOR, unit);
83}
84
85static void eq_precut_format(char* buffer, int buffer_size, int value, const char* unit)
86{
87 snprintf(buffer, buffer_size, "%s%d.%d %s", value == 0 ? " " : "-",
88 value / EQ_USER_DIVISOR, value % EQ_USER_DIVISOR, unit);
89}
90
91/*
92 * Settings functions
93 */
94
95static bool eq_enabled(void)
96{
97 int i;
98
99 bool result = set_bool(str(LANG_EQUALIZER_ENABLED),
100 &global_settings.eq_enabled);
101
102 dsp_set_eq(global_settings.eq_enabled);
103
104 dsp_set_eq_precut(global_settings.eq_precut);
105
106 /* Update all bands */
107 for(i = 0; i < 5; i++) {
108 dsp_set_eq_coefs(i);
109 }
110
111 return result;
112}
113
114static bool eq_precut(void)
115{
116 bool result = set_int(str(LANG_EQUALIZER_PRECUT), str(LANG_UNIT_DB),
117 UNIT_DB, &global_settings.eq_precut, dsp_set_eq_precut, 5, 0, 240,
118 eq_precut_format);
119
120 return result;
121}
122
123/* Possibly dodgy way of simplifying the code a bit. */
124#define eq_make_gain_label(buf, bufsize, frequency) snprintf((buf), \
125 (bufsize), str(LANG_EQUALIZER_GAIN_ITEM), (frequency))
126
127#define eq_set_center(band) \
128static bool eq_set_band ## band ## _center(void) \
129{ \
130 bool result = set_int(str(LANG_EQUALIZER_BAND_CENTER), "Hertz", \
131 UNIT_HERTZ, &global_settings.eq_band ## band ## _cutoff, NULL, \
132 EQ_CUTOFF_STEP, EQ_CUTOFF_MIN, EQ_CUTOFF_MAX, NULL); \
133 dsp_set_eq_coefs(band); \
134 return result; \
135}
136
137#define eq_set_cutoff(band) \
138static bool eq_set_band ## band ## _cutoff(void) \
139{ \
140 bool result = set_int(str(LANG_EQUALIZER_BAND_CUTOFF), "Hertz", \
141 UNIT_HERTZ, &global_settings.eq_band ## band ## _cutoff, NULL, \
142 EQ_CUTOFF_STEP, EQ_CUTOFF_MIN, EQ_CUTOFF_MAX, NULL); \
143 dsp_set_eq_coefs(band); \
144 return result; \
145}
146
147#define eq_set_q(band) \
148static bool eq_set_band ## band ## _q(void) \
149{ \
150 bool result = set_int(str(LANG_EQUALIZER_BAND_Q), "Q", UNIT_INT, \
151 &global_settings.eq_band ## band ## _q, NULL, \
152 EQ_Q_STEP, EQ_Q_MIN, EQ_Q_MAX, eq_q_format); \
153 dsp_set_eq_coefs(band); \
154 return result; \
155}
156
157#define eq_set_gain(band) \
158static bool eq_set_band ## band ## _gain(void) \
159{ \
160 bool result = set_int("Band " #band, str(LANG_UNIT_DB), UNIT_DB, \
161 &global_settings.eq_band ## band ## _gain, NULL, \
162 EQ_GAIN_STEP, EQ_GAIN_MIN, EQ_GAIN_MAX, eq_gain_format); \
163 dsp_set_eq_coefs(band); \
164 return result; \
165}
166
167eq_set_cutoff(0);
168eq_set_center(1);
169eq_set_center(2);
170eq_set_center(3);
171eq_set_cutoff(4);
172
173eq_set_q(0);
174eq_set_q(1);
175eq_set_q(2);
176eq_set_q(3);
177eq_set_q(4);
178
179eq_set_gain(0);
180eq_set_gain(1);
181eq_set_gain(2);
182eq_set_gain(3);
183eq_set_gain(4);
184
185static bool eq_gain_menu(void)
186{
187 int m, i;
188 int *setting;
189 bool result;
190 char gain_label[5][32];
191 static struct menu_item items[5] = {
192 { NULL, eq_set_band0_gain },
193 { NULL, eq_set_band1_gain },
194 { NULL, eq_set_band2_gain },
195 { NULL, eq_set_band3_gain },
196 { NULL, eq_set_band4_gain },
197 };
198
199 setting = &global_settings.eq_band0_cutoff;
200
201 /* Construct menu labels */
202 for(i = 0; i < 5; i++) {
203 eq_make_gain_label(gain_label[i], sizeof(gain_label[i]),
204 *setting);
205 items[i].desc = gain_label[i];
206
207 /* Skip to next band */
208 setting += 3;
209 }
210
211 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
212 NULL, NULL, NULL);
213 result = menu_run(m);
214 menu_exit(m);
215
216 return result;
217}
218
219static bool eq_set_band0(void)
220{
221 int m;
222 bool result;
223 static const struct menu_item items[] = {
224 { ID2P(LANG_EQUALIZER_BAND_CUTOFF), eq_set_band0_cutoff },
225 { ID2P(LANG_EQUALIZER_BAND_Q), eq_set_band0_q },
226 { ID2P(LANG_EQUALIZER_BAND_GAIN), eq_set_band0_gain },
227 };
228
229 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
230 NULL, NULL, NULL);
231 result = menu_run(m);
232 menu_exit(m);
233
234 return result;
235}
236
237static bool eq_set_band1(void)
238{
239 int m;
240 bool result;
241 static const struct menu_item items[] = {
242 { ID2P(LANG_EQUALIZER_BAND_CENTER), eq_set_band1_center },
243 { ID2P(LANG_EQUALIZER_BAND_Q), eq_set_band1_q },
244 { ID2P(LANG_EQUALIZER_BAND_GAIN), eq_set_band1_gain },
245 };
246
247 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
248 NULL, NULL, NULL);
249 result = menu_run(m);
250 menu_exit(m);
251
252 return result;
253}
254
255static bool eq_set_band2(void)
256{
257 int m;
258 bool result;
259 static const struct menu_item items[] = {
260 { ID2P(LANG_EQUALIZER_BAND_CENTER), eq_set_band2_center },
261 { ID2P(LANG_EQUALIZER_BAND_Q), eq_set_band2_q },
262 { ID2P(LANG_EQUALIZER_BAND_GAIN), eq_set_band2_gain },
263 };
264
265 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
266 NULL, NULL, NULL);
267 result = menu_run(m);
268 menu_exit(m);
269
270 return result;
271}
272
273static bool eq_set_band3(void)
274{
275 int m;
276 bool result;
277 static const struct menu_item items[] = {
278 { ID2P(LANG_EQUALIZER_BAND_CENTER), eq_set_band3_center },
279 { ID2P(LANG_EQUALIZER_BAND_Q), eq_set_band3_q },
280 { ID2P(LANG_EQUALIZER_BAND_GAIN), eq_set_band3_gain },
281 };
282
283 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
284 NULL, NULL, NULL);
285 result = menu_run(m);
286 menu_exit(m);
287
288 return result;
289}
290
291static bool eq_set_band4(void)
292{
293 int m;
294 bool result;
295 static const struct menu_item items[] = {
296 { ID2P(LANG_EQUALIZER_BAND_CUTOFF), eq_set_band4_cutoff },
297 { ID2P(LANG_EQUALIZER_BAND_Q), eq_set_band4_q },
298 { ID2P(LANG_EQUALIZER_BAND_GAIN), eq_set_band4_gain },
299 };
300
301 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
302 NULL, NULL, NULL);
303 result = menu_run(m);
304 menu_exit(m);
305
306 return result;
307}
308
309static bool eq_advanced_menu(void)
310{
311 int m, i;
312 bool result;
313 char peak_band_label[3][32];
314 static struct menu_item items[] = {
315 { ID2P(LANG_EQUALIZER_BAND_LOW_SHELF), eq_set_band0 },
316 { NULL, eq_set_band1 },
317 { NULL, eq_set_band2 },
318 { NULL, eq_set_band3 },
319 { ID2P(LANG_EQUALIZER_BAND_HIGH_SHELF), eq_set_band4 },
320 };
321
322 /* Construct menu labels */
323 for(i = 1; i < 4; i++) {
324 snprintf(peak_band_label[i-1], sizeof(peak_band_label[i-1]),
325 str(LANG_EQUALIZER_BAND_PEAK), i);
326 items[i].desc = peak_band_label[i-1];
327 }
328
329 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
330 NULL, NULL, NULL);
331 result = menu_run(m);
332 menu_exit(m);
333
334 return result;
335}
336
337enum eq_slider_mode {
338 GAIN,
339 CUTOFF,
340 Q,
341};
342
343enum eq_type {
344 LOW_SHELF,
345 PEAK,
346 HIGH_SHELF
347};
348
349/* Draw the UI for a whole EQ band */
350static int draw_eq_slider(struct screen * screen, int x, int y,
351 int width, int cutoff, int q, int gain, bool selected,
352 enum eq_slider_mode mode, enum eq_type type)
353{
354 char buf[26];
355 const char separator[2] = " ";
356 int steps, min_item, max_item;
357 int abs_gain = abs(gain);
358 int current_x, total_height, separator_width, separator_height;
359 int w, h;
360 const int slider_height = 6;
361
362 switch(mode) {
363 case Q:
364 steps = EQ_Q_MAX - EQ_Q_MIN;
365 min_item = q - EQ_Q_STEP - EQ_Q_MIN;
366 max_item = q + EQ_Q_STEP - EQ_Q_MIN;
367 break;
368 case CUTOFF:
369 steps = EQ_CUTOFF_MAX - EQ_CUTOFF_MIN;
370 min_item = cutoff - EQ_CUTOFF_FAST_STEP * 2;
371 max_item = cutoff + EQ_CUTOFF_FAST_STEP * 2;
372 break;
373 case GAIN:
374 default:
375 steps = EQ_GAIN_MAX - EQ_GAIN_MIN;
376 min_item = abs(EQ_GAIN_MIN) + gain - EQ_GAIN_STEP * 5;
377 max_item = abs(EQ_GAIN_MIN) + gain + EQ_GAIN_STEP * 5;
378 break;
379 }
380
381 /* Start two pixels in, one for border, one for margin */
382 current_x = x + 2;
383
384 /* Figure out how large our separator string is */
385 screen->getstringsize(separator, &separator_width, &separator_height);
386
387 /* Total height includes margins, text, and line selector */
388 total_height = separator_height + slider_height + 2 + 3;
389
390 /* Print out the band label */
391 if (type == LOW_SHELF) {
392 screen->putsxy(current_x, y + 2, "LS:");
393 screen->getstringsize("LS:", &w, &h);
394 } else if (type == HIGH_SHELF) {
395 screen->putsxy(current_x, y + 2, "HS:");
396 screen->getstringsize("HS:", &w, &h);
397 } else {
398 screen->putsxy(current_x, y + 2, "PK:");
399 screen->getstringsize("PK:", &w, &h);
400 }
401 current_x += w;
402
403 /* Print separator */
404 screen->set_drawmode(DRMODE_SOLID);
405 screen->putsxy(current_x, y + 2, separator);
406 current_x += separator_width;
407#if NB_SCREENS > 1
408 if (screen->screen_type == SCREEN_REMOTE) {
409 if (mode == GAIN) {
410 screen->putsxy(current_x, y + 2, str(LANG_EQUALIZER_BAND_GAIN));
411 screen->getstringsize(str(LANG_EQUALIZER_BAND_GAIN), &w, &h);
412 } else if (mode == CUTOFF) {
413 screen->putsxy(current_x, y + 2, str(LANG_EQUALIZER_BAND_CUTOFF));
414 screen->getstringsize(str(LANG_EQUALIZER_BAND_CUTOFF), &w, &h);
415 } else {
416 screen->putsxy(current_x, y + 2, str(LANG_EQUALIZER_BAND_Q));
417 screen->getstringsize(str(LANG_EQUALIZER_BAND_Q), &w, &h);
418 }
419
420 /* Draw horizontal slider. Reuse scrollbar for this */
421 gui_scrollbar_draw(screen, x + 3, y + h + 3, width - 6, slider_height, steps,
422 min_item, max_item, HORIZONTAL);
423
424 /* Print out cutoff part */
425 snprintf(buf, sizeof(buf), "%sGain %s%2d.%ddB",mode==GAIN?" > ":" ", gain < 0 ? "-" : " ",
426 abs_gain / EQ_USER_DIVISOR, abs_gain % EQ_USER_DIVISOR);
427 screen->getstringsize(buf, &w, &h);
428 y = 3*h;
429 screen->putsxy(0, y, buf);
430 /* Print out cutoff part */
431 snprintf(buf, sizeof(buf), "%sCutoff %5dHz",mode==CUTOFF?" > ":" ", cutoff);
432 y += h;
433 screen->putsxy(0, y, buf);
434 snprintf(buf, sizeof(buf), "%sQ setting %d.%d Q",mode==Q?" > ":" ", q / EQ_USER_DIVISOR,
435 q % EQ_USER_DIVISOR);
436 y += h;
437 screen->putsxy(0, y, buf);
438 return y;
439 }
440#endif
441
442 /* Print out gain part of status line */
443 snprintf(buf, sizeof(buf), "%s%2d.%ddB", gain < 0 ? "-" : " ",
444 abs_gain / EQ_USER_DIVISOR, abs_gain % EQ_USER_DIVISOR);
445
446 if (mode == GAIN && selected)
447 screen->set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
448
449 screen->putsxy(current_x, y + 2, buf);
450 screen->getstringsize(buf, &w, &h);
451 current_x += w;
452
453 /* Print separator */
454 screen->set_drawmode(DRMODE_SOLID);
455 screen->putsxy(current_x, y + 2, separator);
456 current_x += separator_width;
457
458 /* Print out cutoff part of status line */
459 snprintf(buf, sizeof(buf), "%5dHz", cutoff);
460
461 if (mode == CUTOFF && selected)
462 screen->set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
463
464 screen->putsxy(current_x, y + 2, buf);
465 screen->getstringsize(buf, &w, &h);
466 current_x += w;
467
468 /* Print separator */
469 screen->set_drawmode(DRMODE_SOLID);
470 screen->putsxy(current_x, y + 2, separator);
471 current_x += separator_width;
472
473 /* Print out Q part of status line */
474 snprintf(buf, sizeof(buf), "%d.%d Q", q / EQ_USER_DIVISOR,
475 q % EQ_USER_DIVISOR);
476
477 if (mode == Q && selected)
478 screen->set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
479
480 screen->putsxy(current_x, y + 2, buf);
481 screen->getstringsize(buf, &w, &h);
482 current_x += w;
483
484 screen->set_drawmode(DRMODE_SOLID);
485
486 /* Draw selection box */
487 if (selected) {
488 screen->drawrect(x, y, width, total_height);
489 }
490
491 /* Draw horizontal slider. Reuse scrollbar for this */
492 gui_scrollbar_draw(screen, x + 3, y + h + 3, width - 6, slider_height, steps,
493 min_item, max_item, HORIZONTAL);
494
495 return total_height;
496}
497
498/* Draw's all the EQ sliders. Returns the total height of the sliders drawn */
499static int draw_eq_sliders(int current_band, enum eq_slider_mode mode)
500{
501 int i, gain, q, cutoff;
502 int height = 2; /* Two pixel margin */
503 int slider_width[NB_SCREENS];
504 int *setting = &global_settings.eq_band0_cutoff;
505 enum eq_type type;
506
507 FOR_NB_SCREENS(i)
508 slider_width[i] = screens[i].width - 4; /* two pixel margin on each side */
509
510 for (i=0; i<5; i++) {
511 cutoff = *setting++;
512 q = *setting++;
513 gain = *setting++;
514
515 if (i == 0) {
516 type = LOW_SHELF;
517 } else if (i == 4) {
518 type = HIGH_SHELF;
519 } else {
520 type = PEAK;
521 }
522 height += draw_eq_slider(&(screens[SCREEN_MAIN]), 2, height,
523 slider_width[SCREEN_MAIN], cutoff, q, gain,
524 i == current_band, mode, type);
525#if NB_SCREENS > 1
526 if (i == current_band)
527 draw_eq_slider(&(screens[SCREEN_REMOTE]), 2, 0,
528 slider_width[SCREEN_REMOTE], cutoff, q, gain,1, mode, type);
529#endif
530 /* add a margin */
531 height += 2;
532 }
533
534 return height;
535}
536
537/* Provides a graphical means of editing the EQ settings */
538bool eq_menu_graphical(void)
539{
540 bool exit_request = false;
541 bool result = true;
542 bool has_changed = false;
543 int button;
544 int *setting;
545 int current_band, y, step, fast_step, min, max, voice_unit;
546 enum eq_slider_mode mode;
547 enum eq_type current_type;
548 char buf[24];
549 int i;
550
551 FOR_NB_SCREENS(i) {
552 screens[i].setfont(FONT_SYSFIXED);
553 screens[i].clear_display();
554 }
555
556 /* Start off editing gain on the first band */
557 mode = GAIN;
558 current_type = LOW_SHELF;
559 current_band = 0;
560
561 while (!exit_request) {
562
563 FOR_NB_SCREENS(i) {
564 /* Clear the screen. The drawing routines expect this */
565 screens[i].clear_display();
566 /* Draw equalizer band details */
567 y = draw_eq_sliders(current_band, mode);
568 }
569
570 /* Set pointer to the band data currently editable */
571 if (mode == GAIN) {
572 /* gain */
573 setting = &global_settings.eq_band0_gain;
574 setting += current_band * 3;
575
576 step = EQ_GAIN_STEP;
577 fast_step = EQ_GAIN_FAST_STEP;
578 min = EQ_GAIN_MIN;
579 max = EQ_GAIN_MAX;
580 voice_unit = UNIT_DB;
581
582 snprintf(buf, sizeof(buf), str(LANG_SYSFONT_EQUALIZER_EDIT_MODE),
583 str(LANG_SYSFONT_EQUALIZER_BAND_GAIN));
584
585 screens[SCREEN_MAIN].putsxy(2, y, buf);
586 } else if (mode == CUTOFF) {
587 /* cutoff */
588 setting = &global_settings.eq_band0_cutoff;
589 setting += current_band * 3;
590
591 step = EQ_CUTOFF_STEP;
592 fast_step = EQ_CUTOFF_FAST_STEP;
593 min = EQ_CUTOFF_MIN;
594 max = EQ_CUTOFF_MAX;
595 voice_unit = UNIT_HERTZ;
596
597 snprintf(buf, sizeof(buf), str(LANG_SYSFONT_EQUALIZER_EDIT_MODE),
598 str(LANG_SYSFONT_EQUALIZER_BAND_CUTOFF));
599
600 screens[SCREEN_MAIN].putsxy(2, y, buf);
601 } else {
602 /* Q */
603 setting = &global_settings.eq_band0_q;
604 setting += current_band * 3;
605
606 step = EQ_Q_STEP;
607 fast_step = EQ_Q_FAST_STEP;
608 min = EQ_Q_MIN;
609 max = EQ_Q_MAX;
610 voice_unit = UNIT_INT;
611
612 snprintf(buf, sizeof(buf), str(LANG_SYSFONT_EQUALIZER_EDIT_MODE),
613 str(LANG_EQUALIZER_BAND_Q));
614
615 screens[SCREEN_MAIN].putsxy(2, y, buf);
616 }
617
618 FOR_NB_SCREENS(i) {
619 screens[i].update();
620 }
621
622 button = get_action(CONTEXT_SETTINGS_EQ,TIMEOUT_BLOCK);
623
624 switch (button) {
625 case ACTION_SETTINGS_DEC:
626 case ACTION_SETTINGS_DECREPEAT:
627 *(setting) -= step;
628 has_changed = true;
629 if (*(setting) < min)
630 *(setting) = min;
631 break;
632
633 case ACTION_SETTINGS_INC:
634 case ACTION_SETTINGS_INCREPEAT:
635 *(setting) += step;
636 has_changed = true;
637 if (*(setting) > max)
638 *(setting) = max;
639 break;
640
641 case ACTION_SETTINGS_INCBIGSTEP:
642 *(setting) += fast_step;
643 has_changed = true;
644 if (*(setting) > max)
645 *(setting) = max;
646 break;
647
648 case ACTION_SETTINGS_DECBIGSTEP:
649 *(setting) -= fast_step;
650 has_changed = true;
651 if (*(setting) < min)
652 *(setting) = min;
653 break;
654
655 case ACTION_STD_PREV:
656 case ACTION_STD_PREVREPEAT:
657 current_band--;
658 if (current_band < 0)
659 current_band = 4; /* wrap around */
660 break;
661
662 case ACTION_STD_NEXT:
663 case ACTION_STD_NEXTREPEAT:
664 current_band++;
665 if (current_band > 4)
666 current_band = 0; /* wrap around */
667 break;
668
669 case ACTION_STD_OK:
670 mode++;
671 if (mode > Q)
672 mode = GAIN; /* wrap around */
673 break;
674
675 case ACTION_STD_CANCEL:
676 exit_request = true;
677 result = false;
678 break;
679
680 default:
681 if(default_event_handler(button) == SYS_USB_CONNECTED) {
682 exit_request = true;
683 result = true;
684 }
685 break;
686 }
687
688 /* Update the filter if the user changed something */
689 if (has_changed) {
690 dsp_set_eq_coefs(current_band);
691 has_changed = false;
692 }
693 }
694
695 action_signalscreenchange();
696 /* Reset screen settings */
697 FOR_NB_SCREENS(i) {
698 screens[i].setfont(FONT_UI);
699 screens[i].clear_display();
700 }
701 return result;
702}
703
704/* Preset saver.
705 * TODO: Can the settings system be used to do this instead?
706 */
707static bool eq_save_preset(void)
708{
709 int fd, i;
710 char filename[MAX_PATH];
711 int *setting;
712
713 create_numbered_filename(filename, EQS_DIR, "eq", ".cfg", 2
714 IF_CNFN_NUM_(, NULL));
715
716 /* allow user to modify filename */
717 while (true) {
718 if (!kbd_input(filename, sizeof filename)) {
719 fd = creat(filename);
720 if (fd < 0)
721 gui_syncsplash(HZ, true, str(LANG_FAILED));
722 else
723 break;
724 }
725 else {
726 gui_syncsplash(HZ, true, str(LANG_MENU_SETTING_CANCEL));
727 return false;
728 }
729 }
730
731 /* TODO: Should we really do this? */
732 fdprintf(fd, "eq enabled: on\r\n");
733 fdprintf(fd, "eq precut: %d\r\n", global_settings.eq_precut);
734
735 setting = &global_settings.eq_band0_cutoff;
736
737 for(i = 0; i < 5; ++i) {
738 fdprintf(fd, "eq band %d cutoff: %d\r\n", i, *setting++);
739 fdprintf(fd, "eq band %d q: %d\r\n", i, *setting++);
740 fdprintf(fd, "eq band %d gain: %d\r\n", i, *setting++);
741 }
742
743 close(fd);
744
745 gui_syncsplash(HZ, true, str(LANG_SETTINGS_SAVED));
746
747 return true;
748}
749
750/* Allows browsing of preset files */
751bool eq_browse_presets(void)
752{
753 return rockbox_browse(EQS_DIR, SHOW_CFG);
754}
755
756#ifdef HAVE_WM8758
757
758/* WM8758 equalizer supports -12 to +12 dB gain in 1 dB increments. */
759#define EQ_HW_GAIN_STEP 1
760#define EQ_HW_GAIN_MIN -12
761#define EQ_HW_GAIN_MAX 12
762
763static const struct opt_items BANDWIDTH_NAMES[] = {
764 { STR(LANG_EQUALIZER_HARDWARE_BANDWIDTH_NARROW) },
765 { STR(LANG_EQUALIZER_HARDWARE_BANDWIDTH_WIDE) },
766};
767
768static const int BANDWIDTH_NAMES_SIZE = sizeof(BANDWIDTH_NAMES) /
769 sizeof(*BANDWIDTH_NAMES);
770
771static void eq_hw_gain_format(char* buffer, int buffer_size, int value,
772 const char* unit)
773{
774 snprintf(buffer, buffer_size, "%d %s", value, unit);
775}
776
777static bool eq_hw_set_band0_cutoff(void)
778{
779 static const struct opt_items names[] = {
780 { (unsigned char *)"80 Hz", TALK_ID(80, UNIT_HERTZ) },
781 { (unsigned char *)"105 Hz", TALK_ID(105, UNIT_HERTZ) },
782 { (unsigned char *)"135 Hz", TALK_ID(135, UNIT_HERTZ) },
783 { (unsigned char *)"175 Hz", TALK_ID(175, UNIT_HERTZ) },
784 };
785
786 bool result = set_option(str(LANG_EQUALIZER_BANDWIDTH),
787 &global_settings.eq_hw_band0_cutoff, INT, names,
788 sizeof(names) / sizeof(*names), NULL);
789
790#ifndef SIMULATOR
791 audiohw_set_equalizer_band(0, global_settings.eq_hw_band0_cutoff, 0,
792 global_settings.eq_hw_band0_gain);
793#endif
794
795 return result;
796}
797
798static bool eq_hw_set_band0_gain(void)
799{
800 bool result = set_int(str(LANG_EQUALIZER_BAND_GAIN), str(LANG_UNIT_DB), UNIT_DB,
801 &global_settings.eq_hw_band0_gain, NULL,
802 EQ_HW_GAIN_STEP, EQ_HW_GAIN_MIN, EQ_HW_GAIN_MAX,
803 eq_hw_gain_format);
804
805#ifndef SIMULATOR
806 audiohw_set_equalizer_band(0, global_settings.eq_hw_band0_cutoff, 0,
807 global_settings.eq_hw_band0_gain);
808#endif
809
810 return result;
811}
812
813static bool eq_hw_set_band1_center(void)
814{
815 static const struct opt_items names[] = {
816 { (unsigned char *)"230 Hz", TALK_ID(230, UNIT_HERTZ) },
817 { (unsigned char *)"300 Hz", TALK_ID(300, UNIT_HERTZ) },
818 { (unsigned char *)"385 Hz", TALK_ID(385, UNIT_HERTZ) },
819 { (unsigned char *)"500 Hz", TALK_ID(500, UNIT_HERTZ) },
820 };
821
822 bool result = set_option(str(LANG_EQUALIZER_BAND_CENTER),
823 &global_settings.eq_hw_band1_center, INT, names,
824 sizeof(names) / sizeof(*names), NULL);
825
826#ifndef SIMULATOR
827 audiohw_set_equalizer_band(1, global_settings.eq_hw_band1_center,
828 global_settings.eq_hw_band1_bandwidth,
829 global_settings.eq_hw_band1_gain);
830#endif
831
832 return result;
833}
834
835static bool eq_hw_set_band1_bandwidth(void)
836{
837 bool result = set_option(str(LANG_EQUALIZER_BANDWIDTH),
838 &global_settings.eq_hw_band1_bandwidth, INT, BANDWIDTH_NAMES,
839 BANDWIDTH_NAMES_SIZE, NULL);
840
841#ifndef SIMULATOR
842 audiohw_set_equalizer_band(1, global_settings.eq_hw_band1_center,
843 global_settings.eq_hw_band1_bandwidth,
844 global_settings.eq_hw_band1_gain);
845#endif
846
847 return result;
848}
849
850static bool eq_hw_set_band1_gain(void)
851{
852 bool result = set_int(str(LANG_EQUALIZER_BAND_GAIN), str(LANG_UNIT_DB), UNIT_DB,
853 &global_settings.eq_hw_band1_gain, NULL,
854 EQ_HW_GAIN_STEP, EQ_HW_GAIN_MIN, EQ_HW_GAIN_MAX,
855 eq_hw_gain_format);
856
857#ifndef SIMULATOR
858 audiohw_set_equalizer_band(1, global_settings.eq_hw_band1_center,
859 global_settings.eq_hw_band1_bandwidth,
860 global_settings.eq_hw_band1_gain);
861#endif
862
863 return result;
864}
865
866static bool eq_hw_set_band2_center(void)
867{
868 static const struct opt_items names[] = {
869 { (unsigned char *)"650 Hz", TALK_ID(650, UNIT_HERTZ) },
870 { (unsigned char *)"850 Hz", TALK_ID(850, UNIT_HERTZ) },
871 { (unsigned char *)"1.1 kHz", TALK_ID(1100, UNIT_HERTZ) },
872 { (unsigned char *)"1.4 kHz", TALK_ID(1400, UNIT_HERTZ) },
873 };
874
875 bool result = set_option(str(LANG_EQUALIZER_BAND_CENTER),
876 &global_settings.eq_hw_band2_center, INT, names,
877 sizeof(names) / sizeof(*names), NULL);
878
879#ifndef SIMULATOR
880 audiohw_set_equalizer_band(2, global_settings.eq_hw_band2_center,
881 global_settings.eq_hw_band2_bandwidth,
882 global_settings.eq_hw_band2_gain);
883#endif
884
885 return result;
886}
887
888static bool eq_hw_set_band2_bandwidth(void)
889{
890 bool result = set_option(str(LANG_EQUALIZER_BANDWIDTH),
891 &global_settings.eq_hw_band2_bandwidth, INT, BANDWIDTH_NAMES,
892 BANDWIDTH_NAMES_SIZE, NULL);
893
894#ifndef SIMULATOR
895 audiohw_set_equalizer_band(2, global_settings.eq_hw_band2_center,
896 global_settings.eq_hw_band2_bandwidth,
897 global_settings.eq_hw_band2_gain);
898#endif
899
900 return result;
901}
902
903static bool eq_hw_set_band2_gain(void)
904{
905 bool result = set_int(str(LANG_EQUALIZER_BAND_GAIN), str(LANG_UNIT_DB), UNIT_DB,
906 &global_settings.eq_hw_band2_gain, NULL,
907 EQ_HW_GAIN_STEP, EQ_HW_GAIN_MIN, EQ_HW_GAIN_MAX,
908 eq_hw_gain_format);
909
910#ifndef SIMULATOR
911 audiohw_set_equalizer_band(2, global_settings.eq_hw_band2_center,
912 global_settings.eq_hw_band2_bandwidth,
913 global_settings.eq_hw_band2_gain);
914#endif
915
916 return result;
917}
918
919static bool eq_hw_set_band3_center(void)
920{
921 static const struct opt_items names[] = {
922 { (unsigned char *)"1.8 kHz", TALK_ID(1800, UNIT_HERTZ) },
923 { (unsigned char *)"2.4 kHz", TALK_ID(2400, UNIT_HERTZ) },
924 { (unsigned char *)"3.2 kHz", TALK_ID(3200, UNIT_HERTZ) },
925 { (unsigned char *)"4.1 kHz", TALK_ID(4100, UNIT_HERTZ) },
926 };
927
928 bool result = set_option(str(LANG_EQUALIZER_BAND_CENTER),
929 &global_settings.eq_hw_band3_center, INT, names,
930 sizeof(names) / sizeof(*names), NULL);
931
932#ifndef SIMULATOR
933 audiohw_set_equalizer_band(3, global_settings.eq_hw_band3_center,
934 global_settings.eq_hw_band3_bandwidth,
935 global_settings.eq_hw_band3_gain);
936#endif
937
938 return result;
939}
940
941static bool eq_hw_set_band3_bandwidth(void)
942{
943 bool result = set_option(str(LANG_EQUALIZER_BANDWIDTH),
944 &global_settings.eq_hw_band3_bandwidth, INT, BANDWIDTH_NAMES,
945 BANDWIDTH_NAMES_SIZE, NULL);
946
947#ifndef SIMULATOR
948 audiohw_set_equalizer_band(3, global_settings.eq_hw_band3_center,
949 global_settings.eq_hw_band3_bandwidth,
950 global_settings.eq_hw_band3_gain);
951#endif
952
953 return result;
954}
955
956static bool eq_hw_set_band3_gain(void)
957{
958 bool result = set_int(str(LANG_EQUALIZER_BAND_GAIN), str(LANG_UNIT_DB), UNIT_DB,
959 &global_settings.eq_hw_band3_gain, NULL,
960 EQ_HW_GAIN_STEP, EQ_HW_GAIN_MIN, EQ_HW_GAIN_MAX,
961 eq_hw_gain_format);
962
963#ifndef SIMULATOR
964 audiohw_set_equalizer_band(3, global_settings.eq_hw_band3_center,
965 global_settings.eq_hw_band3_bandwidth,
966 global_settings.eq_hw_band3_gain);
967#endif
968
969 return result;
970}
971
972static bool eq_hw_set_band4_cutoff(void)
973{
974 static const struct opt_items names[] = {
975 { (unsigned char *)"5.3 kHz", TALK_ID(5300, UNIT_HERTZ) },
976 { (unsigned char *)"6.9 kHz", TALK_ID(6900, UNIT_HERTZ) },
977 { (unsigned char *)"9.0 kHz", TALK_ID(9000, UNIT_HERTZ) },
978 { (unsigned char *)"11.7 kHz", TALK_ID(11700, UNIT_HERTZ) },
979 };
980
981 bool result = set_option(str(LANG_EQUALIZER_BAND_CUTOFF),
982 &global_settings.eq_hw_band4_cutoff, INT, names,
983 sizeof(names) / sizeof(*names), NULL);
984
985#ifndef SIMULATOR
986 audiohw_set_equalizer_band(4, global_settings.eq_hw_band4_cutoff, 0,
987 global_settings.eq_hw_band4_gain);
988#endif
989
990 return result;
991}
992
993static bool eq_hw_set_band4_gain(void)
994{
995 bool result = set_int(str(LANG_EQUALIZER_BAND_GAIN), str(LANG_UNIT_DB), UNIT_DB,
996 &global_settings.eq_hw_band4_gain, NULL,
997 EQ_HW_GAIN_STEP, EQ_HW_GAIN_MIN, EQ_HW_GAIN_MAX,
998 eq_hw_gain_format);
999
1000#ifndef SIMULATOR
1001 audiohw_set_equalizer_band(4, global_settings.eq_hw_band4_cutoff, 0,
1002 global_settings.eq_hw_band4_gain);
1003#endif
1004
1005 return result;
1006}
1007
1008void eq_hw_enable(bool enable)
1009{
1010#ifdef SIMULATOR
1011 (void) enable;
1012#else
1013 if (enable) {
1014 audiohw_set_equalizer_band(0, global_settings.eq_hw_band0_cutoff,
1015 0, global_settings.eq_hw_band0_gain);
1016 audiohw_set_equalizer_band(1, global_settings.eq_hw_band1_center,
1017 global_settings.eq_hw_band1_bandwidth,
1018 global_settings.eq_hw_band1_gain);
1019 audiohw_set_equalizer_band(2, global_settings.eq_hw_band2_center,
1020 global_settings.eq_hw_band2_bandwidth,
1021 global_settings.eq_hw_band2_gain);
1022 audiohw_set_equalizer_band(3, global_settings.eq_hw_band3_center,
1023 global_settings.eq_hw_band3_bandwidth,
1024 global_settings.eq_hw_band3_gain);
1025 audiohw_set_equalizer_band(4, global_settings.eq_hw_band4_cutoff,
1026 0, global_settings.eq_hw_band4_gain);
1027 } else {
1028 audiohw_set_equalizer_band(0, global_settings.eq_hw_band0_cutoff, 0, 0);
1029 audiohw_set_equalizer_band(1, global_settings.eq_hw_band1_center,
1030 global_settings.eq_hw_band1_bandwidth, 0);
1031 audiohw_set_equalizer_band(2, global_settings.eq_hw_band2_center,
1032 global_settings.eq_hw_band2_bandwidth, 0);
1033 audiohw_set_equalizer_band(3, global_settings.eq_hw_band3_center,
1034 global_settings.eq_hw_band3_bandwidth, 0);
1035 audiohw_set_equalizer_band(4, global_settings.eq_hw_band4_cutoff, 0, 0);
1036 }
1037#endif
1038}
1039
1040static bool eq_hw_enabled(void)
1041{
1042 bool result = set_bool(str(LANG_EQUALIZER_HARDWARE_ENABLED),
1043 &global_settings.eq_hw_enabled);
1044
1045 eq_hw_enable(global_settings.eq_hw_enabled);
1046
1047 return result;
1048}
1049
1050static bool eq_hw_set_band0(void)
1051{
1052 int m;
1053 bool result;
1054 static const struct menu_item items[] = {
1055 { ID2P(LANG_EQUALIZER_BAND_CUTOFF), eq_hw_set_band0_cutoff },
1056 { ID2P(LANG_EQUALIZER_BAND_GAIN), eq_hw_set_band0_gain },
1057 };
1058
1059 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
1060 NULL, NULL, NULL);
1061 result = menu_run(m);
1062 menu_exit(m);
1063
1064 return result;
1065}
1066
1067static bool eq_hw_set_band1(void)
1068{
1069 int m;
1070 bool result;
1071 static const struct menu_item items[] = {
1072 { ID2P(LANG_EQUALIZER_BAND_CENTER), eq_hw_set_band1_center },
1073 { ID2P(LANG_EQUALIZER_BANDWIDTH), eq_hw_set_band1_bandwidth },
1074 { ID2P(LANG_EQUALIZER_BAND_GAIN), eq_hw_set_band1_gain },
1075 };
1076
1077 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
1078 NULL, NULL, NULL);
1079 result = menu_run(m);
1080 menu_exit(m);
1081
1082 return result;
1083}
1084
1085static bool eq_hw_set_band2(void)
1086{
1087 int m;
1088 bool result;
1089 static const struct menu_item items[] = {
1090 { ID2P(LANG_EQUALIZER_BAND_CENTER), eq_hw_set_band2_center },
1091 { ID2P(LANG_EQUALIZER_BANDWIDTH), eq_hw_set_band2_bandwidth },
1092 { ID2P(LANG_EQUALIZER_BAND_GAIN), eq_hw_set_band2_gain },
1093 };
1094
1095 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
1096 NULL, NULL, NULL);
1097 result = menu_run(m);
1098 menu_exit(m);
1099
1100 return result;
1101}
1102
1103static bool eq_hw_set_band3(void)
1104{
1105 int m;
1106 bool result;
1107 static const struct menu_item items[] = {
1108 { ID2P(LANG_EQUALIZER_BAND_CENTER), eq_hw_set_band3_center },
1109 { ID2P(LANG_EQUALIZER_BANDWIDTH), eq_hw_set_band3_bandwidth },
1110 { ID2P(LANG_EQUALIZER_BAND_GAIN), eq_hw_set_band3_gain },
1111 };
1112
1113 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
1114 NULL, NULL, NULL);
1115 result = menu_run(m);
1116 menu_exit(m);
1117
1118 return result;
1119}
1120
1121static bool eq_hw_set_band4(void)
1122{
1123 int m;
1124 bool result;
1125 static const struct menu_item items[] = {
1126 { ID2P(LANG_EQUALIZER_BAND_CUTOFF), eq_hw_set_band4_cutoff },
1127 { ID2P(LANG_EQUALIZER_BAND_GAIN), eq_hw_set_band4_gain },
1128 };
1129
1130 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
1131 NULL, NULL, NULL);
1132 result = menu_run(m);
1133 menu_exit(m);
1134
1135 return result;
1136}
1137
1138bool eq_hw_menu(void)
1139{
1140 int m;
1141 bool result;
1142 static const struct menu_item items[] = {
1143 { ID2P(LANG_EQUALIZER_HARDWARE_ENABLED), eq_hw_enabled },
1144 { ID2P(LANG_EQUALIZER_BAND_LOW_SHELF), eq_hw_set_band0 },
1145 { "Peak Filter 1", eq_hw_set_band1 },
1146 { "Peak Filter 2", eq_hw_set_band2 },
1147 { "Peak Filter 3", eq_hw_set_band3 },
1148 { ID2P(LANG_EQUALIZER_BAND_HIGH_SHELF), eq_hw_set_band4 },
1149 };
1150
1151 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
1152 NULL, NULL, NULL);
1153 result = menu_run(m);
1154 menu_exit(m);
1155
1156 return result;
1157}
1158#endif
1159
1160/* Full equalizer menu */
1161bool eq_menu(void)
1162{
1163 int m;
1164 bool result;
1165 static const struct menu_item items[] = {
1166 { ID2P(LANG_EQUALIZER_ENABLED), eq_enabled },
1167 { ID2P(LANG_EQUALIZER_GRAPHICAL), eq_menu_graphical },
1168 { ID2P(LANG_EQUALIZER_PRECUT), eq_precut },
1169 { ID2P(LANG_EQUALIZER_GAIN), eq_gain_menu },
1170 { ID2P(LANG_EQUALIZER_ADVANCED), eq_advanced_menu },
1171 { ID2P(LANG_EQUALIZER_SAVE), eq_save_preset },
1172 { ID2P(LANG_EQUALIZER_BROWSE), eq_browse_presets },
1173 };
1174
1175 m = menu_init( items, sizeof(items) / sizeof(*items), NULL,
1176 NULL, NULL, NULL);
1177 result = menu_run(m);
1178 menu_exit(m);
1179
1180 return result;
1181}
1182