diff options
Diffstat (limited to 'apps/screens.c')
-rw-r--r-- | apps/screens.c | 170 |
1 files changed, 132 insertions, 38 deletions
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) | |||
362 | #endif /* CONFIG_CHARGING && !HAVE_POWEROFF_WHILE_CHARGING */ | 362 | #endif /* CONFIG_CHARGING && !HAVE_POWEROFF_WHILE_CHARGING */ |
363 | 363 | ||
364 | #ifdef HAVE_PITCHSCREEN | 364 | #ifdef HAVE_PITCHSCREEN |
365 | |||
366 | #define PITCH_MAX 2000 | ||
367 | #define PITCH_MIN 500 | ||
368 | #define PITCH_SMALL_DELTA 1 | ||
369 | #define PITCH_BIG_DELTA 10 | ||
370 | #define PITCH_NUDGE_DELTA 20 | ||
371 | |||
372 | #define PITCH_MODE_ABSOLUTE 1 | ||
373 | #define PITCH_MODE_SEMITONE -PITCH_MODE_ABSOLUTE | ||
374 | |||
375 | static int pitch_mode = PITCH_MODE_ABSOLUTE; /* 1 - absolute, -1 - semitone */ | ||
376 | |||
365 | /* returns: | 377 | /* returns: |
366 | 0 if no key was pressed | 378 | 0 if no key was pressed |
367 | 1 if USB was connected */ | 379 | 1 if USB was connected */ |
368 | 380 | ||
369 | void pitch_screen_draw(struct screen *display, int pitch) | 381 | void pitch_screen_draw(struct screen *display, int pitch, int pitch_mode) |
370 | { | 382 | { |
371 | unsigned char* ptr; | 383 | unsigned char* ptr; |
372 | unsigned char buf[32]; | 384 | unsigned char buf[32]; |
@@ -385,14 +397,22 @@ void pitch_screen_draw(struct screen *display, int pitch) | |||
385 | { | 397 | { |
386 | 398 | ||
387 | /* UP: Pitch Up */ | 399 | /* UP: Pitch Up */ |
388 | ptr = str(LANG_SYSFONT_PITCH_UP); | 400 | if (pitch_mode == PITCH_MODE_ABSOLUTE) { |
401 | ptr = str(LANG_SYSFONT_PITCH_UP); | ||
402 | } else { | ||
403 | ptr = str(LANG_SYSFONT_PITCH_UP_SEMITONE); | ||
404 | } | ||
389 | display->getstringsize(ptr,&w,&h); | 405 | display->getstringsize(ptr,&w,&h); |
390 | display->putsxy((display->width-w)/2, 0, ptr); | 406 | display->putsxy((display->width-w)/2, 0, ptr); |
391 | display->mono_bitmap(bitmap_icons_7x8[Icon_UpArrow], | 407 | display->mono_bitmap(bitmap_icons_7x8[Icon_UpArrow], |
392 | display->width/2 - 3, h, 7, 8); | 408 | display->width/2 - 3, h, 7, 8); |
393 | 409 | ||
394 | /* DOWN: Pitch Down */ | 410 | /* DOWN: Pitch Down */ |
395 | ptr = str(LANG_SYSFONT_PITCH_DOWN); | 411 | if (pitch_mode == PITCH_MODE_ABSOLUTE) { |
412 | ptr = str(LANG_SYSFONT_PITCH_DOWN); | ||
413 | } else { | ||
414 | ptr = str(LANG_SYSFONT_PITCH_DOWN_SEMITONE); | ||
415 | } | ||
396 | display->getstringsize(ptr,&w,&h); | 416 | display->getstringsize(ptr,&w,&h); |
397 | display->putsxy((display->width-w)/2, display->height - h, ptr); | 417 | display->putsxy((display->width-w)/2, display->height - h, ptr); |
398 | display->mono_bitmap(bitmap_icons_7x8[Icon_DownArrow], | 418 | display->mono_bitmap(bitmap_icons_7x8[Icon_DownArrow], |
@@ -426,10 +446,83 @@ void pitch_screen_draw(struct screen *display, int pitch) | |||
426 | display->update(); | 446 | display->update(); |
427 | } | 447 | } |
428 | 448 | ||
449 | static int pitch_increase(int pitch, int delta, | ||
450 | bool allow_cutoff, bool redraw_screens) { | ||
451 | int new_pitch; | ||
452 | int i; | ||
453 | |||
454 | if (delta < 0) { | ||
455 | if (pitch + delta >= PITCH_MIN) { | ||
456 | new_pitch = pitch + delta; | ||
457 | } else { | ||
458 | if (!allow_cutoff) { | ||
459 | return pitch; | ||
460 | } | ||
461 | new_pitch = PITCH_MIN; | ||
462 | } | ||
463 | } else if (delta > 0) { | ||
464 | if (pitch + delta <= PITCH_MAX) { | ||
465 | new_pitch = pitch + delta; | ||
466 | } else { | ||
467 | if (!allow_cutoff) { | ||
468 | return pitch; | ||
469 | } | ||
470 | new_pitch = PITCH_MAX; | ||
471 | } | ||
472 | } else { | ||
473 | /* delta == 0 -> no real change */ | ||
474 | return pitch; | ||
475 | } | ||
476 | sound_set_pitch(new_pitch); | ||
477 | |||
478 | if (redraw_screens) { | ||
479 | FOR_NB_SCREENS(i) | ||
480 | pitch_screen_draw(&screens[i], pitch, pitch_mode); | ||
481 | } | ||
482 | |||
483 | return new_pitch; | ||
484 | } | ||
485 | |||
486 | /* Factor for changing the pitch one half tone up. | ||
487 | The exact value is 2^(1/12) = 1.05946309436 | ||
488 | But we use only integer arithmetics, so take | ||
489 | rounded factor multiplied by 10^5=100,000. This is | ||
490 | enough to get the same promille values as if we | ||
491 | had used floating point (checked with a spread | ||
492 | sheet). | ||
493 | */ | ||
494 | #define PITCH_SEMITONE_FACTOR 105946L | ||
495 | |||
496 | /* Some helpful constants. K is the scaling factor for SEMITONE. | ||
497 | N is for more accurate rounding | ||
498 | KN is K * N | ||
499 | */ | ||
500 | #define PITCH_K_FCT 100000UL | ||
501 | #define PITCH_N_FCT 10 | ||
502 | #define PITCH_KN_FCT 1000000UL | ||
503 | |||
504 | static int pitch_increase_semitone(int pitch, bool up) { | ||
505 | uint32_t tmp; | ||
506 | uint32_t round_fct; /* How much to scale down at the end */ | ||
507 | tmp = pitch; | ||
508 | if (up) { | ||
509 | tmp = tmp * PITCH_SEMITONE_FACTOR; | ||
510 | round_fct = PITCH_K_FCT; | ||
511 | } else { | ||
512 | tmp = (tmp * PITCH_KN_FCT) / PITCH_SEMITONE_FACTOR; | ||
513 | round_fct = PITCH_N_FCT; | ||
514 | } | ||
515 | /* Scaling down with rounding */ | ||
516 | tmp = (tmp + round_fct / 2) / round_fct; | ||
517 | return pitch_increase(pitch, tmp - pitch, false, false); | ||
518 | } | ||
519 | |||
429 | bool pitch_screen(void) | 520 | bool pitch_screen(void) |
430 | { | 521 | { |
431 | int button; | 522 | int button; |
432 | int pitch = sound_get_pitch(); | 523 | int pitch = sound_get_pitch(); |
524 | int new_pitch; | ||
525 | bool nudged = false; | ||
433 | bool exit = false; | 526 | bool exit = false; |
434 | int i; | 527 | int i; |
435 | 528 | ||
@@ -441,64 +534,61 @@ bool pitch_screen(void) | |||
441 | while (!exit) | 534 | while (!exit) |
442 | { | 535 | { |
443 | FOR_NB_SCREENS(i) | 536 | FOR_NB_SCREENS(i) |
444 | pitch_screen_draw(&screens[i],pitch); | 537 | pitch_screen_draw(&screens[i], pitch, pitch_mode); |
445 | 538 | ||
446 | button = get_action(CONTEXT_PITCHSCREEN,TIMEOUT_BLOCK); | 539 | button = get_action(CONTEXT_PITCHSCREEN,TIMEOUT_BLOCK); |
447 | switch (button) { | 540 | switch (button) { |
448 | case ACTION_PS_INC_SMALL: | 541 | case ACTION_PS_INC_SMALL: |
449 | if ( pitch < 2000 ) | 542 | if (pitch_mode == PITCH_MODE_ABSOLUTE) { |
450 | pitch++; | 543 | pitch = pitch_increase(pitch, PITCH_SMALL_DELTA, true, false); |
451 | sound_set_pitch(pitch); | 544 | } else { |
545 | pitch = pitch_increase_semitone(pitch, true); | ||
546 | } | ||
452 | break; | 547 | break; |
453 | 548 | ||
454 | case ACTION_PS_INC_BIG: | 549 | case ACTION_PS_INC_BIG: |
455 | if ( pitch < 1990 ) | 550 | if (pitch_mode == PITCH_MODE_ABSOLUTE) { |
456 | pitch += 10; | 551 | pitch = pitch_increase(pitch, PITCH_BIG_DELTA, true, false); |
457 | else | 552 | } |
458 | pitch = 2000; | ||
459 | sound_set_pitch(pitch); | ||
460 | break; | 553 | break; |
461 | 554 | ||
462 | case ACTION_PS_DEC_SMALL: | 555 | case ACTION_PS_DEC_SMALL: |
463 | if ( pitch > 500 ) | 556 | if (pitch_mode == PITCH_MODE_ABSOLUTE) { |
464 | pitch--; | 557 | pitch = pitch_increase(pitch, -PITCH_SMALL_DELTA, true, false); |
465 | sound_set_pitch(pitch); | 558 | } else { |
559 | pitch = pitch_increase_semitone(pitch, false); | ||
560 | } | ||
466 | break; | 561 | break; |
467 | 562 | ||
468 | case ACTION_PS_DEC_BIG: | 563 | case ACTION_PS_DEC_BIG: |
469 | if ( pitch > 510 ) | 564 | if (pitch_mode == PITCH_MODE_ABSOLUTE) { |
470 | pitch -= 10; | 565 | pitch = pitch_increase(pitch, -PITCH_BIG_DELTA, true, false); |
471 | else | 566 | } |
472 | pitch = 500; | ||
473 | sound_set_pitch(pitch); | ||
474 | break; | 567 | break; |
475 | 568 | ||
476 | case ACTION_PS_NUDGE_RIGHT: | 569 | case ACTION_PS_NUDGE_RIGHT: |
477 | if ( pitch < 1980 ) | 570 | new_pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false, true); |
478 | { | 571 | nudged = (new_pitch != pitch); |
479 | pitch += 20; | 572 | pitch = new_pitch; |
480 | sound_set_pitch(pitch); | ||
481 | FOR_NB_SCREENS(i) | ||
482 | pitch_screen_draw(&screens[i],pitch); | ||
483 | } | ||
484 | break; | 573 | break; |
485 | case ACTION_PS_NUDGE_RIGHTOFF: | 574 | case ACTION_PS_NUDGE_RIGHTOFF: |
486 | pitch -= 20; | 575 | if (nudged) { |
487 | sound_set_pitch(pitch); | 576 | pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false, false); |
577 | } | ||
578 | nudged = false; | ||
488 | break; | 579 | break; |
489 | 580 | ||
490 | case ACTION_PS_NUDGE_LEFT: | 581 | case ACTION_PS_NUDGE_LEFT: |
491 | if ( pitch > 520 ) | 582 | new_pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false, true); |
492 | { | 583 | nudged = (new_pitch != pitch); |
493 | pitch -= 20; | 584 | pitch = new_pitch; |
494 | sound_set_pitch(pitch); | ||
495 | FOR_NB_SCREENS(i) | ||
496 | pitch_screen_draw(&screens[i],pitch); | ||
497 | } | ||
498 | break; | 585 | break; |
586 | |||
499 | case ACTION_PS_NUDGE_LEFTOFF: | 587 | case ACTION_PS_NUDGE_LEFTOFF: |
500 | pitch += 20; | 588 | if (nudged) { |
501 | sound_set_pitch(pitch); | 589 | pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false, false); |
590 | } | ||
591 | nudged = false; | ||
502 | break; | 592 | break; |
503 | 593 | ||
504 | case ACTION_PS_RESET: | 594 | case ACTION_PS_RESET: |
@@ -506,6 +596,10 @@ bool pitch_screen(void) | |||
506 | sound_set_pitch( pitch ); | 596 | sound_set_pitch( pitch ); |
507 | break; | 597 | break; |
508 | 598 | ||
599 | case ACTION_PS_TOGGLE_MODE: | ||
600 | pitch_mode = -pitch_mode; | ||
601 | break; | ||
602 | |||
509 | case ACTION_PS_EXIT: | 603 | case ACTION_PS_EXIT: |
510 | exit = true; | 604 | exit = true; |
511 | break; | 605 | break; |