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
This commit is contained in:
Linus Nielsen Feltzing 2006-11-06 09:19:40 +00:00
parent ddba5fa37d
commit 3b99840019
10 changed files with 170 additions and 40 deletions

View file

@ -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 */

View file

@ -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 */

View file

@ -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 },

View file

@ -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 },

View file

@ -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 },

View file

@ -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 },

View file

@ -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 },

View file

@ -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 },

View file

@ -9374,6 +9374,34 @@
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SYSFONT_PITCH_UP_SEMITONE
desc: in wps
user:
<source>
*: "Semitone Up"
</source>
<dest>
*: "Semitone Up"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SYSFONT_PITCH_DOWN_SEMITONE
desc: in wps
user:
<source>
*: "Semitone Down"
</source>
<dest>
*: "Semitone Down"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SYSFONT_F2_MODE
desc: in wps F2 pressed

View file

@ -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;