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
->width
-(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
->width
-w
)/2, 0, ptr
);
81 display
->mono_bitmap(bitmap_icons_7x8
[Icon_UpArrow
],
82 display
->width
/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
->width
-w
)/2, display
->height
- h
, ptr
);
92 display
->mono_bitmap(bitmap_icons_7x8
[Icon_DownArrow
],
93 display
->width
/2 - 3, display
->height
- h
*2, 7, 8);
97 display
->getstringsize(ptr
,&w
,&h
);
98 display
->putsxy(display
->width
-w
, (display
->height
-h
)/2, ptr
);
99 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastForward
],
100 display
->width
-w
-8, (display
->height
-h
)/2, 7, 8);
104 display
->getstringsize(ptr
,&w
,&h
);
105 display
->putsxy(0, (display
->height
-h
)/2, ptr
);
106 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastBackward
],
107 w
+1, (display
->height
-h
)/2, 7, 8);
110 snprintf((char *)buf
, sizeof(buf
), str(LANG_PITCH
));
111 display
->getstringsize(buf
,&w
,&h
);
112 display
->putsxy((display
->width
-w
)/2, (display
->height
/2)-h
, buf
);
114 snprintf((char *)buf
, sizeof(buf
), "%d.%d%%",
115 pitch
/ 10, pitch
% 10 );
116 display
->getstringsize(buf
,&w
,&h
);
117 display
->putsxy((display
->width
-w
)/2, display
->height
/2, buf
);
123 static int pitch_increase(int pitch
, int delta
, bool allow_cutoff
)
128 if (pitch
+ delta
>= PITCH_MIN
) {
129 new_pitch
= pitch
+ delta
;
134 new_pitch
= PITCH_MIN
;
136 } else if (delta
> 0) {
137 if (pitch
+ delta
<= PITCH_MAX
) {
138 new_pitch
= pitch
+ delta
;
143 new_pitch
= PITCH_MAX
;
146 /* delta == 0 -> no real change */
149 sound_set_pitch(new_pitch
);
154 /* Factor for changing the pitch one half tone up.
155 The exact value is 2^(1/12) = 1.05946309436
156 But we use only integer arithmetics, so take
157 rounded factor multiplied by 10^5=100,000. This is
158 enough to get the same promille values as if we
159 had used floating point (checked with a spread
162 #define PITCH_SEMITONE_FACTOR 105946L
164 /* Some helpful constants. K is the scaling factor for SEMITONE.
165 N is for more accurate rounding
168 #define PITCH_K_FCT 100000UL
169 #define PITCH_N_FCT 10
170 #define PITCH_KN_FCT 1000000UL
172 static int pitch_increase_semitone(int pitch
, bool up
)
175 uint32_t round_fct
; /* How much to scale down at the end */
178 tmp
= tmp
* PITCH_SEMITONE_FACTOR
;
179 round_fct
= PITCH_K_FCT
;
181 tmp
= (tmp
* PITCH_KN_FCT
) / PITCH_SEMITONE_FACTOR
;
182 round_fct
= PITCH_N_FCT
;
184 /* Scaling down with rounding */
185 tmp
= (tmp
+ round_fct
/ 2) / round_fct
;
186 return pitch_increase(pitch
, tmp
- pitch
, false);
189 bool pitch_screen(void)
192 int pitch
= sound_get_pitch();
193 int new_pitch
, delta
= 0;
198 #if CONFIG_CODEC == SWCODEC
199 pcmbuf_set_low_latency(true);
205 pitch_screen_draw(&screens
[i
], pitch
, pitch_mode
);
207 button
= get_action(CONTEXT_PITCHSCREEN
,TIMEOUT_BLOCK
);
209 case ACTION_PS_INC_SMALL
:
210 delta
= PITCH_SMALL_DELTA
;
213 case ACTION_PS_INC_BIG
:
214 delta
= PITCH_BIG_DELTA
;
217 case ACTION_PS_DEC_SMALL
:
218 delta
= -PITCH_SMALL_DELTA
;
221 case ACTION_PS_DEC_BIG
:
222 delta
= -PITCH_BIG_DELTA
;
225 case ACTION_PS_NUDGE_RIGHT
:
226 new_pitch
= pitch_increase(pitch
, PITCH_NUDGE_DELTA
, false);
227 nudged
= (new_pitch
!= pitch
);
231 case ACTION_PS_NUDGE_RIGHTOFF
:
233 pitch
= pitch_increase(pitch
, -PITCH_NUDGE_DELTA
, false);
238 case ACTION_PS_NUDGE_LEFT
:
239 new_pitch
= pitch_increase(pitch
, -PITCH_NUDGE_DELTA
, false);
240 nudged
= (new_pitch
!= pitch
);
244 case ACTION_PS_NUDGE_LEFTOFF
:
246 pitch
= pitch_increase(pitch
, PITCH_NUDGE_DELTA
, false);
251 case ACTION_PS_RESET
:
253 sound_set_pitch( pitch
);
256 case ACTION_PS_TOGGLE_MODE
:
257 pitch_mode
= -pitch_mode
;
265 if(default_event_handler(button
) == SYS_USB_CONNECTED
)
272 if (pitch_mode
== PITCH_MODE_ABSOLUTE
) {
273 pitch
= pitch_increase(pitch
, delta
, true);
275 pitch
= pitch_increase_semitone(pitch
, delta
> 0 ? true:false);
282 #if CONFIG_CODEC == SWCODEC
283 pcmbuf_set_low_latency(false);
285 lcd_setfont(FONT_UI
);