1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Björn Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
37 #include "screen_access.h"
40 #define PITCH_MAX 2000
42 #define PITCH_SMALL_DELTA 1
43 #define PITCH_BIG_DELTA 10
44 #define PITCH_NUDGE_DELTA 20
46 #define PITCH_MODE_ABSOLUTE 1
47 #define PITCH_MODE_SEMITONE -PITCH_MODE_ABSOLUTE
49 static int pitch_mode
= PITCH_MODE_ABSOLUTE
; /* 1 - absolute, -1 - semitone */
52 0 if no key was pressed
53 1 if USB was connected */
55 static void pitch_screen_draw(struct screen
*display
, int pitch
, int pitch_mode
)
58 unsigned char buf
[32];
61 display
->clear_display();
63 if (display
->nb_lines
< 4) /* very small screen, just show the pitch value */
65 w
= snprintf((char *)buf
, sizeof(buf
), "%s: %d.%d%%",str(LANG_PITCH
),
66 pitch
/ 10, pitch
% 10 );
67 display
->putsxy((display
->lcdwidth
-(w
*display
->char_width
))/2,
68 display
->nb_lines
/2,buf
);
70 else /* bigger screen, show everything... */
74 if (pitch_mode
== PITCH_MODE_ABSOLUTE
) {
75 ptr
= str(LANG_PITCH_UP
);
77 ptr
= str(LANG_PITCH_UP_SEMITONE
);
79 display
->getstringsize(ptr
,&w
,&h
);
80 display
->putsxy((display
->lcdwidth
-w
)/2, 0, ptr
);
81 display
->mono_bitmap(bitmap_icons_7x8
[Icon_UpArrow
],
82 display
->lcdwidth
/2 - 3, h
, 7, 8);
84 /* DOWN: Pitch Down */
85 if (pitch_mode
== PITCH_MODE_ABSOLUTE
) {
86 ptr
= str(LANG_PITCH_DOWN
);
88 ptr
= str(LANG_PITCH_DOWN_SEMITONE
);
90 display
->getstringsize(ptr
,&w
,&h
);
91 display
->putsxy((display
->lcdwidth
-w
)/2, display
->lcdheight
- h
, ptr
);
92 display
->mono_bitmap(bitmap_icons_7x8
[Icon_DownArrow
],
93 display
->lcdwidth
/2 - 3,
94 display
->lcdheight
- h
*2, 7, 8);
98 display
->getstringsize(ptr
,&w
,&h
);
99 display
->putsxy(display
->lcdwidth
-w
, (display
->lcdheight
-h
)/2, ptr
);
100 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastForward
],
101 display
->lcdwidth
-w
-8,
102 (display
->lcdheight
-h
)/2, 7, 8);
106 display
->getstringsize(ptr
,&w
,&h
);
107 display
->putsxy(0, (display
->lcdheight
-h
)/2, ptr
);
108 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastBackward
],
109 w
+1, (display
->lcdheight
-h
)/2, 7, 8);
112 snprintf((char *)buf
, sizeof(buf
), "%s", str(LANG_PITCH
));
113 display
->getstringsize(buf
,&w
,&h
);
114 display
->putsxy((display
->lcdwidth
-w
)/2, (display
->lcdheight
/2)-h
, buf
);
116 snprintf((char *)buf
, sizeof(buf
), "%d.%d%%",
117 pitch
/ 10, pitch
% 10 );
118 display
->getstringsize(buf
,&w
,&h
);
119 display
->putsxy((display
->lcdwidth
-w
)/2, display
->lcdheight
/2, buf
);
125 static int pitch_increase(int pitch
, int delta
, bool allow_cutoff
)
130 if (pitch
+ delta
>= PITCH_MIN
) {
131 new_pitch
= pitch
+ delta
;
136 new_pitch
= PITCH_MIN
;
138 } else if (delta
> 0) {
139 if (pitch
+ delta
<= PITCH_MAX
) {
140 new_pitch
= pitch
+ delta
;
145 new_pitch
= PITCH_MAX
;
148 /* delta == 0 -> no real change */
151 sound_set_pitch(new_pitch
);
156 /* Factor for changing the pitch one half tone up.
157 The exact value is 2^(1/12) = 1.05946309436
158 But we use only integer arithmetics, so take
159 rounded factor multiplied by 10^5=100,000. This is
160 enough to get the same promille values as if we
161 had used floating point (checked with a spread
164 #define PITCH_SEMITONE_FACTOR 105946L
166 /* Some helpful constants. K is the scaling factor for SEMITONE.
167 N is for more accurate rounding
170 #define PITCH_K_FCT 100000UL
171 #define PITCH_N_FCT 10
172 #define PITCH_KN_FCT 1000000UL
174 static int pitch_increase_semitone(int pitch
, bool up
)
177 uint32_t round_fct
; /* How much to scale down at the end */
180 tmp
= tmp
* PITCH_SEMITONE_FACTOR
;
181 round_fct
= PITCH_K_FCT
;
183 tmp
= (tmp
* PITCH_KN_FCT
) / PITCH_SEMITONE_FACTOR
;
184 round_fct
= PITCH_N_FCT
;
186 /* Scaling down with rounding */
187 tmp
= (tmp
+ round_fct
/ 2) / round_fct
;
188 return pitch_increase(pitch
, tmp
- pitch
, false);
191 bool pitch_screen(void)
194 int pitch
= sound_get_pitch();
195 int new_pitch
, delta
= 0;
200 #if CONFIG_CODEC == SWCODEC
201 pcmbuf_set_low_latency(true);
207 pitch_screen_draw(&screens
[i
], pitch
, pitch_mode
);
209 button
= get_action(CONTEXT_PITCHSCREEN
,TIMEOUT_BLOCK
);
211 case ACTION_PS_INC_SMALL
:
212 delta
= PITCH_SMALL_DELTA
;
215 case ACTION_PS_INC_BIG
:
216 delta
= PITCH_BIG_DELTA
;
219 case ACTION_PS_DEC_SMALL
:
220 delta
= -PITCH_SMALL_DELTA
;
223 case ACTION_PS_DEC_BIG
:
224 delta
= -PITCH_BIG_DELTA
;
227 case ACTION_PS_NUDGE_RIGHT
:
228 new_pitch
= pitch_increase(pitch
, PITCH_NUDGE_DELTA
, false);
229 nudged
= (new_pitch
!= pitch
);
233 case ACTION_PS_NUDGE_RIGHTOFF
:
235 pitch
= pitch_increase(pitch
, -PITCH_NUDGE_DELTA
, false);
240 case ACTION_PS_NUDGE_LEFT
:
241 new_pitch
= pitch_increase(pitch
, -PITCH_NUDGE_DELTA
, false);
242 nudged
= (new_pitch
!= pitch
);
246 case ACTION_PS_NUDGE_LEFTOFF
:
248 pitch
= pitch_increase(pitch
, PITCH_NUDGE_DELTA
, false);
253 case ACTION_PS_RESET
:
255 sound_set_pitch( pitch
);
258 case ACTION_PS_TOGGLE_MODE
:
259 pitch_mode
= -pitch_mode
;
267 if(default_event_handler(button
) == SYS_USB_CONNECTED
)
274 if (pitch_mode
== PITCH_MODE_ABSOLUTE
) {
275 pitch
= pitch_increase(pitch
, delta
, true);
277 pitch
= pitch_increase_semitone(pitch
, delta
> 0 ? true:false);
284 #if CONFIG_CODEC == SWCODEC
285 pcmbuf_set_low_latency(false);
287 lcd_setfont(FONT_UI
);