diff --git a/apps/SOURCES b/apps/SOURCES index c4a1cb67bb..e617d5f174 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -60,6 +60,9 @@ gui/bitmap/list.c gui/charcell/list.c #endif gui/option_select.c +#ifdef HAVE_PITCHSCREEN +gui/pitchscreen.c +#endif #ifdef HAVE_QUICKSCREEN gui/quickscreen.c #endif diff --git a/apps/gui/pitchscreen.c b/apps/gui/pitchscreen.c new file mode 100644 index 0000000000..b790835fcb --- /dev/null +++ b/apps/gui/pitchscreen.c @@ -0,0 +1,284 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include "config.h" +#include "sprintf.h" +#include "settings.h" +#include "action.h" +#include "system.h" +#include "font.h" +#include "misc.h" +#include "dsp.h" +#include "sound.h" +#include "pcmbuf.h" +#include "lang.h" +#include "icons.h" +#include "screen_access.h" + +#define PITCH_MAX 2000 +#define PITCH_MIN 500 +#define PITCH_SMALL_DELTA 1 +#define PITCH_BIG_DELTA 10 +#define PITCH_NUDGE_DELTA 20 + +#define PITCH_MODE_ABSOLUTE 1 +#define PITCH_MODE_SEMITONE -PITCH_MODE_ABSOLUTE + +static int pitch_mode = PITCH_MODE_ABSOLUTE; /* 1 - absolute, -1 - semitone */ + +/* returns: + 0 if no key was pressed + 1 if USB was connected */ + +static void pitch_screen_draw(struct screen *display, int pitch, int pitch_mode) +{ + unsigned char* ptr; + unsigned char buf[32]; + int w, h; + + display->clear_display(); + + if (display->nb_lines < 4) /* very small screen, just show the pitch value */ + { + w = snprintf((char *)buf, sizeof(buf), "%s: %d.%d%%",str(LANG_PITCH), + pitch / 10, pitch % 10 ); + display->putsxy((display->width-(w*display->char_width))/2, + display->nb_lines/2,buf); + } + else /* bigger screen, show everything... */ + { + + /* UP: Pitch Up */ + if (pitch_mode == PITCH_MODE_ABSOLUTE) { + ptr = str(LANG_PITCH_UP); + } else { + ptr = str(LANG_PITCH_UP_SEMITONE); + } + display->getstringsize(ptr,&w,&h); + display->putsxy((display->width-w)/2, 0, ptr); + display->mono_bitmap(bitmap_icons_7x8[Icon_UpArrow], + display->width/2 - 3, h, 7, 8); + + /* DOWN: Pitch Down */ + if (pitch_mode == PITCH_MODE_ABSOLUTE) { + ptr = str(LANG_PITCH_DOWN); + } else { + ptr = str(LANG_PITCH_DOWN_SEMITONE); + } + display->getstringsize(ptr,&w,&h); + display->putsxy((display->width-w)/2, display->height - h, ptr); + display->mono_bitmap(bitmap_icons_7x8[Icon_DownArrow], + display->width/2 - 3, display->height - h*2, 7, 8); + + /* RIGHT: +2% */ + ptr = "+2%"; + display->getstringsize(ptr,&w,&h); + display->putsxy(display->width-w, (display->height-h)/2, ptr); + display->mono_bitmap(bitmap_icons_7x8[Icon_FastForward], + display->width-w-8, (display->height-h)/2, 7, 8); + + /* LEFT: -2% */ + ptr = "-2%"; + display->getstringsize(ptr,&w,&h); + display->putsxy(0, (display->height-h)/2, ptr); + display->mono_bitmap(bitmap_icons_7x8[Icon_FastBackward], + w+1, (display->height-h)/2, 7, 8); + + /* "Pitch" */ + snprintf((char *)buf, sizeof(buf), str(LANG_PITCH)); + display->getstringsize(buf,&w,&h); + display->putsxy((display->width-w)/2, (display->height/2)-h, buf); + /* "XX.X%" */ + snprintf((char *)buf, sizeof(buf), "%d.%d%%", + pitch / 10, pitch % 10 ); + display->getstringsize(buf,&w,&h); + display->putsxy((display->width-w)/2, display->height/2, buf); + } + + display->update(); +} + +static int pitch_increase(int pitch, int delta, bool allow_cutoff) +{ + int new_pitch; + + if (delta < 0) { + if (pitch + delta >= PITCH_MIN) { + new_pitch = pitch + delta; + } else { + if (!allow_cutoff) { + return pitch; + } + new_pitch = PITCH_MIN; + } + } else if (delta > 0) { + if (pitch + delta <= PITCH_MAX) { + new_pitch = pitch + delta; + } else { + if (!allow_cutoff) { + return pitch; + } + new_pitch = PITCH_MAX; + } + } else { + /* delta == 0 -> no real change */ + return pitch; + } + sound_set_pitch(new_pitch); + + return new_pitch; +} + +/* Factor for changing the pitch one half tone up. + The exact value is 2^(1/12) = 1.05946309436 + But we use only integer arithmetics, so take + rounded factor multiplied by 10^5=100,000. This is + enough to get the same promille values as if we + had used floating point (checked with a spread + sheet). + */ +#define PITCH_SEMITONE_FACTOR 105946L + +/* Some helpful constants. K is the scaling factor for SEMITONE. + N is for more accurate rounding + KN is K * N + */ +#define PITCH_K_FCT 100000UL +#define PITCH_N_FCT 10 +#define PITCH_KN_FCT 1000000UL + +static int pitch_increase_semitone(int pitch, bool up) +{ + uint32_t tmp; + uint32_t round_fct; /* How much to scale down at the end */ + tmp = pitch; + if (up) { + tmp = tmp * PITCH_SEMITONE_FACTOR; + round_fct = PITCH_K_FCT; + } else { + tmp = (tmp * PITCH_KN_FCT) / PITCH_SEMITONE_FACTOR; + round_fct = PITCH_N_FCT; + } + /* Scaling down with rounding */ + tmp = (tmp + round_fct / 2) / round_fct; + return pitch_increase(pitch, tmp - pitch, false); +} + +bool pitch_screen(void) +{ + int button; + int pitch = sound_get_pitch(); + int new_pitch, delta = 0; + bool nudged = false; + bool exit = false; + int i; + +#if CONFIG_CODEC == SWCODEC + pcmbuf_set_low_latency(true); +#endif + + while (!exit) + { + FOR_NB_SCREENS(i) + pitch_screen_draw(&screens[i], pitch, pitch_mode); + + button = get_action(CONTEXT_PITCHSCREEN,TIMEOUT_BLOCK); + switch (button) { + case ACTION_PS_INC_SMALL: + delta = PITCH_SMALL_DELTA; + break; + + case ACTION_PS_INC_BIG: + delta = PITCH_BIG_DELTA; + break; + + case ACTION_PS_DEC_SMALL: + delta = -PITCH_SMALL_DELTA; + break; + + case ACTION_PS_DEC_BIG: + delta = -PITCH_BIG_DELTA; + break; + + case ACTION_PS_NUDGE_RIGHT: + new_pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false); + nudged = (new_pitch != pitch); + pitch = new_pitch; + break; + + case ACTION_PS_NUDGE_RIGHTOFF: + if (nudged) { + pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false); + } + nudged = false; + break; + + case ACTION_PS_NUDGE_LEFT: + new_pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false); + nudged = (new_pitch != pitch); + pitch = new_pitch; + break; + + case ACTION_PS_NUDGE_LEFTOFF: + if (nudged) { + pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false); + } + nudged = false; + break; + + case ACTION_PS_RESET: + pitch = 1000; + sound_set_pitch( pitch ); + break; + + case ACTION_PS_TOGGLE_MODE: + pitch_mode = -pitch_mode; + break; + + case ACTION_PS_EXIT: + exit = true; + break; + + default: + if(default_event_handler(button) == SYS_USB_CONNECTED) + return 1; + break; + } + + if(delta) + { + if (pitch_mode == PITCH_MODE_ABSOLUTE) { + pitch = pitch_increase(pitch, delta, true); + } else { + pitch = pitch_increase_semitone(pitch, delta > 0 ? true:false); + } + + delta = 0; + } + + } +#if CONFIG_CODEC == SWCODEC + pcmbuf_set_low_latency(false); +#endif + lcd_setfont(FONT_UI); + return 0; +} diff --git a/apps/screens.c b/apps/screens.c index f9dd49b995..48a5a873a1 100644 --- a/apps/screens.c +++ b/apps/screens.c @@ -7,7 +7,7 @@ * \/ \/ \/ \/ \/ * $Id$ * - * Copyright (C) 2002 Björn Stenberg + * Copyright (C) 2002 Björn Stenberg * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. @@ -381,258 +381,6 @@ int charging_screen(void) } #endif /* CONFIG_CHARGING && !HAVE_POWEROFF_WHILE_CHARGING && defined(CPU_SH) */ -#ifdef HAVE_PITCHSCREEN - -#define PITCH_MAX 2000 -#define PITCH_MIN 500 -#define PITCH_SMALL_DELTA 1 -#define PITCH_BIG_DELTA 10 -#define PITCH_NUDGE_DELTA 20 - -#define PITCH_MODE_ABSOLUTE 1 -#define PITCH_MODE_SEMITONE -PITCH_MODE_ABSOLUTE - -static int pitch_mode = PITCH_MODE_ABSOLUTE; /* 1 - absolute, -1 - semitone */ - -/* returns: - 0 if no key was pressed - 1 if USB was connected */ - -static void pitch_screen_draw(struct screen *display, int pitch, int pitch_mode) -{ - unsigned char* ptr; - unsigned char buf[32]; - int w, h; - - display->clear_display(); - - if (display->nb_lines < 4) /* very small screen, just show the pitch value */ - { - w = snprintf((char *)buf, sizeof(buf), "%s: %d.%d%%",str(LANG_PITCH), - pitch / 10, pitch % 10 ); - display->putsxy((display->width-(w*display->char_width))/2, - display->nb_lines/2,buf); - } - else /* bigger screen, show everything... */ - { - - /* UP: Pitch Up */ - if (pitch_mode == PITCH_MODE_ABSOLUTE) { - ptr = str(LANG_PITCH_UP); - } else { - ptr = str(LANG_PITCH_UP_SEMITONE); - } - display->getstringsize(ptr,&w,&h); - display->putsxy((display->width-w)/2, 0, ptr); - display->mono_bitmap(bitmap_icons_7x8[Icon_UpArrow], - display->width/2 - 3, h, 7, 8); - - /* DOWN: Pitch Down */ - if (pitch_mode == PITCH_MODE_ABSOLUTE) { - ptr = str(LANG_PITCH_DOWN); - } else { - ptr = str(LANG_PITCH_DOWN_SEMITONE); - } - display->getstringsize(ptr,&w,&h); - display->putsxy((display->width-w)/2, display->height - h, ptr); - display->mono_bitmap(bitmap_icons_7x8[Icon_DownArrow], - display->width/2 - 3, display->height - h*2, 7, 8); - - /* RIGHT: +2% */ - ptr = "+2%"; - display->getstringsize(ptr,&w,&h); - display->putsxy(display->width-w, (display->height-h)/2, ptr); - display->mono_bitmap(bitmap_icons_7x8[Icon_FastForward], - display->width-w-8, (display->height-h)/2, 7, 8); - - /* LEFT: -2% */ - ptr = "-2%"; - display->getstringsize(ptr,&w,&h); - display->putsxy(0, (display->height-h)/2, ptr); - display->mono_bitmap(bitmap_icons_7x8[Icon_FastBackward], - w+1, (display->height-h)/2, 7, 8); - - /* "Pitch" */ - snprintf((char *)buf, sizeof(buf), str(LANG_PITCH)); - display->getstringsize(buf,&w,&h); - display->putsxy((display->width-w)/2, (display->height/2)-h, buf); - /* "XX.X%" */ - snprintf((char *)buf, sizeof(buf), "%d.%d%%", - pitch / 10, pitch % 10 ); - display->getstringsize(buf,&w,&h); - display->putsxy((display->width-w)/2, display->height/2, buf); - } - - display->update(); -} - -static int pitch_increase(int pitch, int delta, bool allow_cutoff) -{ - int new_pitch; - - if (delta < 0) { - if (pitch + delta >= PITCH_MIN) { - new_pitch = pitch + delta; - } else { - if (!allow_cutoff) { - return pitch; - } - new_pitch = PITCH_MIN; - } - } else if (delta > 0) { - if (pitch + delta <= PITCH_MAX) { - new_pitch = pitch + delta; - } else { - if (!allow_cutoff) { - return pitch; - } - new_pitch = PITCH_MAX; - } - } else { - /* delta == 0 -> no real change */ - return pitch; - } - sound_set_pitch(new_pitch); - - return new_pitch; -} - -/* Factor for changing the pitch one half tone up. - The exact value is 2^(1/12) = 1.05946309436 - But we use only integer arithmetics, so take - rounded factor multiplied by 10^5=100,000. This is - enough to get the same promille values as if we - had used floating point (checked with a spread - sheet). - */ -#define PITCH_SEMITONE_FACTOR 105946L - -/* Some helpful constants. K is the scaling factor for SEMITONE. - N is for more accurate rounding - KN is K * N - */ -#define PITCH_K_FCT 100000UL -#define PITCH_N_FCT 10 -#define PITCH_KN_FCT 1000000UL - -static int pitch_increase_semitone(int pitch, bool up) -{ - uint32_t tmp; - uint32_t round_fct; /* How much to scale down at the end */ - tmp = pitch; - if (up) { - tmp = tmp * PITCH_SEMITONE_FACTOR; - round_fct = PITCH_K_FCT; - } else { - tmp = (tmp * PITCH_KN_FCT) / PITCH_SEMITONE_FACTOR; - round_fct = PITCH_N_FCT; - } - /* Scaling down with rounding */ - tmp = (tmp + round_fct / 2) / round_fct; - return pitch_increase(pitch, tmp - pitch, false); -} - -bool pitch_screen(void) -{ - int button; - int pitch = sound_get_pitch(); - int new_pitch, delta = 0; - bool nudged = false; - bool exit = false; - int i; - -#if CONFIG_CODEC == SWCODEC - pcmbuf_set_low_latency(true); -#endif - - while (!exit) - { - FOR_NB_SCREENS(i) - pitch_screen_draw(&screens[i], pitch, pitch_mode); - - button = get_action(CONTEXT_PITCHSCREEN,TIMEOUT_BLOCK); - switch (button) { - case ACTION_PS_INC_SMALL: - delta = PITCH_SMALL_DELTA; - break; - - case ACTION_PS_INC_BIG: - delta = PITCH_BIG_DELTA; - break; - - case ACTION_PS_DEC_SMALL: - delta = -PITCH_SMALL_DELTA; - break; - - case ACTION_PS_DEC_BIG: - delta = -PITCH_BIG_DELTA; - break; - - case ACTION_PS_NUDGE_RIGHT: - new_pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false); - nudged = (new_pitch != pitch); - pitch = new_pitch; - break; - - case ACTION_PS_NUDGE_RIGHTOFF: - if (nudged) { - pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false); - } - nudged = false; - break; - - case ACTION_PS_NUDGE_LEFT: - new_pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false); - nudged = (new_pitch != pitch); - pitch = new_pitch; - break; - - case ACTION_PS_NUDGE_LEFTOFF: - if (nudged) { - pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false); - } - nudged = false; - break; - - case ACTION_PS_RESET: - pitch = 1000; - sound_set_pitch( pitch ); - break; - - case ACTION_PS_TOGGLE_MODE: - pitch_mode = -pitch_mode; - break; - - case ACTION_PS_EXIT: - exit = true; - break; - - default: - if(default_event_handler(button) == SYS_USB_CONNECTED) - return 1; - break; - } - - if(delta) - { - if (pitch_mode == PITCH_MODE_ABSOLUTE) { - pitch = pitch_increase(pitch, delta, true); - } else { - pitch = pitch_increase_semitone(pitch, delta > 0 ? true:false); - } - - delta = 0; - } - - } -#if CONFIG_CODEC == SWCODEC - pcmbuf_set_low_latency(false); -#endif - lcd_setfont(FONT_UI); - return 0; -} -#endif /* HAVE_PITCHSCREEN */ - #if CONFIG_CHARGING void charging_splash(void) {