From 3b998400199cc5cf9b3d01c900cbf5f89c8d0002 Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Mon, 6 Nov 2006 09:19:40 +0000 Subject: [PATCH] Patch #6145 by Alexander Levin - Pitch adjustment in semitone steps git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11442 a1c6a512-1295-4272-9138-f99709370657 --- apps/action.h | 1 + apps/keymaps/keymap-gigabeat.c | 5 +- apps/keymaps/keymap-h10.c | 1 + apps/keymaps/keymap-h1x0_h3x0.c | 1 + apps/keymaps/keymap-ipod.c | 1 + apps/keymaps/keymap-ondio.c | 1 + apps/keymaps/keymap-recorder.c | 1 + apps/keymaps/keymap-x5.c | 1 + apps/lang/english.lang | 28 ++++++ apps/screens.c | 170 +++++++++++++++++++++++++------- 10 files changed, 170 insertions(+), 40 deletions(-) diff --git a/apps/action.h b/apps/action.h index c096abf880..d3da152e35 100644 --- a/apps/action.h +++ b/apps/action.h @@ -187,6 +187,7 @@ enum { ACTION_PS_NUDGE_RIGHT, ACTION_PS_NUDGE_LEFTOFF, ACTION_PS_NUDGE_RIGHTOFF, + ACTION_PS_TOGGLE_MODE, ACTION_PS_RESET, ACTION_PS_EXIT, /* _STD_* isnt going to work here */ diff --git a/apps/keymaps/keymap-gigabeat.c b/apps/keymaps/keymap-gigabeat.c index 9822049214..e248e2c4db 100644 --- a/apps/keymaps/keymap-gigabeat.c +++ b/apps/keymaps/keymap-gigabeat.c @@ -216,8 +216,9 @@ const struct button_mapping button_context_pitchscreen[] = { { ACTION_PS_NUDGE_LEFTOFF, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE }, - { ACTION_PS_RESET, BUTTON_POWER, BUTTON_NONE }, - { ACTION_PS_EXIT, BUTTON_A, BUTTON_NONE }, + { ACTION_PS_TOGGLE_MODE, BUTTON_MENU, BUTTON_NONE }, + { ACTION_PS_RESET, BUTTON_POWER, BUTTON_NONE }, + { ACTION_PS_EXIT, BUTTON_A, BUTTON_NONE }, LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) }; /* button_context_pitchcreen */ diff --git a/apps/keymaps/keymap-h10.c b/apps/keymaps/keymap-h10.c index 45dde38844..b1355568ec 100644 --- a/apps/keymaps/keymap-h10.c +++ b/apps/keymaps/keymap-h10.c @@ -254,6 +254,7 @@ const struct button_mapping button_context_pitchscreen[] = { { ACTION_PS_NUDGE_LEFTOFF, BUTTON_REW|BUTTON_REL, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHT, BUTTON_FF, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_FF|BUTTON_REL, BUTTON_NONE }, + { ACTION_PS_TOGGLE_MODE, BUTTON_POWER, BUTTON_NONE }, { ACTION_PS_RESET, BUTTON_PLAY, BUTTON_NONE }, { ACTION_PS_EXIT, BUTTON_LEFT, BUTTON_NONE }, diff --git a/apps/keymaps/keymap-h1x0_h3x0.c b/apps/keymaps/keymap-h1x0_h3x0.c index 7eaccc96a7..7793669d33 100644 --- a/apps/keymaps/keymap-h1x0_h3x0.c +++ b/apps/keymaps/keymap-h1x0_h3x0.c @@ -226,6 +226,7 @@ const struct button_mapping button_context_pitchscreen[] = { { ACTION_PS_NUDGE_LEFTOFF, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE }, + { ACTION_PS_TOGGLE_MODE, BUTTON_MODE, BUTTON_NONE }, { ACTION_PS_RESET, BUTTON_ON, BUTTON_NONE }, { ACTION_PS_EXIT, BUTTON_OFF, BUTTON_NONE }, diff --git a/apps/keymaps/keymap-ipod.c b/apps/keymaps/keymap-ipod.c index be5429d65b..e0268e29ca 100644 --- a/apps/keymaps/keymap-ipod.c +++ b/apps/keymaps/keymap-ipod.c @@ -143,6 +143,7 @@ const struct button_mapping button_context_pitchscreen[] = { { ACTION_PS_NUDGE_LEFTOFF, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE }, + { ACTION_PS_TOGGLE_MODE, BUTTON_SELECT, BUTTON_NONE }, { ACTION_PS_RESET, BUTTON_MENU, BUTTON_NONE }, { ACTION_PS_EXIT, BUTTON_SELECT, BUTTON_NONE }, diff --git a/apps/keymaps/keymap-ondio.c b/apps/keymaps/keymap-ondio.c index defc4e3762..bc92fc47ba 100644 --- a/apps/keymaps/keymap-ondio.c +++ b/apps/keymaps/keymap-ondio.c @@ -125,6 +125,7 @@ const struct button_mapping button_context_pitchscreen[] = { { ACTION_PS_NUDGE_LEFTOFF, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE }, + { ACTION_PS_TOGGLE_MODE, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU }, { ACTION_PS_RESET, BUTTON_MENU, BUTTON_NONE }, { ACTION_PS_EXIT, BUTTON_OFF, BUTTON_NONE }, diff --git a/apps/keymaps/keymap-recorder.c b/apps/keymaps/keymap-recorder.c index 718fddf888..cc09b90bfd 100644 --- a/apps/keymaps/keymap-recorder.c +++ b/apps/keymaps/keymap-recorder.c @@ -150,6 +150,7 @@ static const struct button_mapping button_context_pitchscreen[] = { { ACTION_PS_NUDGE_LEFTOFF, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE }, + { ACTION_PS_TOGGLE_MODE, BUTTON_F1, BUTTON_NONE }, { ACTION_PS_RESET, BUTTON_ON, BUTTON_NONE }, { ACTION_PS_EXIT, BUTTON_OFF, BUTTON_NONE }, diff --git a/apps/keymaps/keymap-x5.c b/apps/keymaps/keymap-x5.c index 2bfa48c517..4b5b74dced 100644 --- a/apps/keymaps/keymap-x5.c +++ b/apps/keymaps/keymap-x5.c @@ -138,6 +138,7 @@ const struct button_mapping button_context_pitchscreen[] = { { ACTION_PS_NUDGE_LEFTOFF, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE }, + { ACTION_PS_TOGGLE_MODE, BUTTON_SELECT, BUTTON_NONE }, { ACTION_PS_RESET, BUTTON_POWER, BUTTON_NONE }, { ACTION_PS_EXIT, BUTTON_PLAY, BUTTON_NONE }, diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 0b463f58c0..8d050a72bf 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -9374,6 +9374,34 @@ *: "" + + id: LANG_SYSFONT_PITCH_UP_SEMITONE + desc: in wps + user: + + *: "Semitone Up" + + + *: "Semitone Up" + + + *: "" + + + + id: LANG_SYSFONT_PITCH_DOWN_SEMITONE + desc: in wps + user: + + *: "Semitone Down" + + + *: "Semitone Down" + + + *: "" + + id: LANG_SYSFONT_F2_MODE desc: in wps F2 pressed diff --git a/apps/screens.c b/apps/screens.c index b81932b941..50f1055f90 100644 --- a/apps/screens.c +++ b/apps/screens.c @@ -362,11 +362,23 @@ int charging_screen(void) #endif /* CONFIG_CHARGING && !HAVE_POWEROFF_WHILE_CHARGING */ #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 */ -void pitch_screen_draw(struct screen *display, int pitch) +void pitch_screen_draw(struct screen *display, int pitch, int pitch_mode) { unsigned char* ptr; unsigned char buf[32]; @@ -385,14 +397,22 @@ void pitch_screen_draw(struct screen *display, int pitch) { /* UP: Pitch Up */ - ptr = str(LANG_SYSFONT_PITCH_UP); + if (pitch_mode == PITCH_MODE_ABSOLUTE) { + ptr = str(LANG_SYSFONT_PITCH_UP); + } else { + ptr = str(LANG_SYSFONT_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 */ - ptr = str(LANG_SYSFONT_PITCH_DOWN); + if (pitch_mode == PITCH_MODE_ABSOLUTE) { + ptr = str(LANG_SYSFONT_PITCH_DOWN); + } else { + ptr = str(LANG_SYSFONT_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], @@ -426,10 +446,83 @@ void pitch_screen_draw(struct screen *display, int pitch) display->update(); } +static int pitch_increase(int pitch, int delta, + bool allow_cutoff, bool redraw_screens) { + int new_pitch; + int i; + + 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); + + if (redraw_screens) { + FOR_NB_SCREENS(i) + pitch_screen_draw(&screens[i], pitch, pitch_mode); + } + + 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, false); +} + bool pitch_screen(void) { int button; int pitch = sound_get_pitch(); + int new_pitch; + bool nudged = false; bool exit = false; int i; @@ -441,64 +534,61 @@ bool pitch_screen(void) while (!exit) { FOR_NB_SCREENS(i) - pitch_screen_draw(&screens[i],pitch); + pitch_screen_draw(&screens[i], pitch, pitch_mode); button = get_action(CONTEXT_PITCHSCREEN,TIMEOUT_BLOCK); switch (button) { case ACTION_PS_INC_SMALL: - if ( pitch < 2000 ) - pitch++; - sound_set_pitch(pitch); + if (pitch_mode == PITCH_MODE_ABSOLUTE) { + pitch = pitch_increase(pitch, PITCH_SMALL_DELTA, true, false); + } else { + pitch = pitch_increase_semitone(pitch, true); + } break; case ACTION_PS_INC_BIG: - if ( pitch < 1990 ) - pitch += 10; - else - pitch = 2000; - sound_set_pitch(pitch); + if (pitch_mode == PITCH_MODE_ABSOLUTE) { + pitch = pitch_increase(pitch, PITCH_BIG_DELTA, true, false); + } break; case ACTION_PS_DEC_SMALL: - if ( pitch > 500 ) - pitch--; - sound_set_pitch(pitch); + if (pitch_mode == PITCH_MODE_ABSOLUTE) { + pitch = pitch_increase(pitch, -PITCH_SMALL_DELTA, true, false); + } else { + pitch = pitch_increase_semitone(pitch, false); + } break; case ACTION_PS_DEC_BIG: - if ( pitch > 510 ) - pitch -= 10; - else - pitch = 500; - sound_set_pitch(pitch); + if (pitch_mode == PITCH_MODE_ABSOLUTE) { + pitch = pitch_increase(pitch, -PITCH_BIG_DELTA, true, false); + } break; case ACTION_PS_NUDGE_RIGHT: - if ( pitch < 1980 ) - { - pitch += 20; - sound_set_pitch(pitch); - FOR_NB_SCREENS(i) - pitch_screen_draw(&screens[i],pitch); - } + new_pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false, true); + nudged = (new_pitch != pitch); + pitch = new_pitch; break; case ACTION_PS_NUDGE_RIGHTOFF: - pitch -= 20; - sound_set_pitch(pitch); + if (nudged) { + pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false, false); + } + nudged = false; break; case ACTION_PS_NUDGE_LEFT: - if ( pitch > 520 ) - { - pitch -= 20; - sound_set_pitch(pitch); - FOR_NB_SCREENS(i) - pitch_screen_draw(&screens[i],pitch); - } + new_pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false, true); + nudged = (new_pitch != pitch); + pitch = new_pitch; break; + case ACTION_PS_NUDGE_LEFTOFF: - pitch += 20; - sound_set_pitch(pitch); + if (nudged) { + pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false, false); + } + nudged = false; break; case ACTION_PS_RESET: @@ -506,6 +596,10 @@ bool pitch_screen(void) sound_set_pitch( pitch ); break; + case ACTION_PS_TOGGLE_MODE: + pitch_mode = -pitch_mode; + break; + case ACTION_PS_EXIT: exit = true; break;