summaryrefslogtreecommitdiff
path: root/apps/screens.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/screens.c')
-rw-r--r--apps/screens.c170
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
375static 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
369void pitch_screen_draw(struct screen *display, int pitch) 381void 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
449static 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
504static 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
429bool pitch_screen(void) 520bool 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;