FS#9281 Rename of splash functions.
[kugel-rb.git] / apps / gui / pitchscreen.c
blob2a568afc0aff02f8ef472bc7e2ccf751ba69efa7
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
22 #include <stdbool.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include "config.h"
26 #include "sprintf.h"
27 #include "settings.h"
28 #include "action.h"
29 #include "system.h"
30 #include "font.h"
31 #include "misc.h"
32 #include "dsp.h"
33 #include "sound.h"
34 #include "pcmbuf.h"
35 #include "lang.h"
36 #include "icons.h"
37 #include "screen_access.h"
38 #include "screens.h"
40 #define PITCH_MAX 2000
41 #define PITCH_MIN 500
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 */
51 /* returns:
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)
57 unsigned char* ptr;
58 unsigned char buf[32];
59 int w, h;
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... */
73 /* UP: Pitch Up */
74 if (pitch_mode == PITCH_MODE_ABSOLUTE) {
75 ptr = str(LANG_PITCH_UP);
76 } else {
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);
87 } else {
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);
96 /* RIGHT: +2% */
97 ptr = "+2%";
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);
104 /* LEFT: -2% */
105 ptr = "-2%";
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);
111 /* "Pitch" */
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);
115 /* "XX.X%" */
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);
122 display->update();
125 static int pitch_increase(int pitch, int delta, bool allow_cutoff)
127 int new_pitch;
129 if (delta < 0) {
130 if (pitch + delta >= PITCH_MIN) {
131 new_pitch = pitch + delta;
132 } else {
133 if (!allow_cutoff) {
134 return pitch;
136 new_pitch = PITCH_MIN;
138 } else if (delta > 0) {
139 if (pitch + delta <= PITCH_MAX) {
140 new_pitch = pitch + delta;
141 } else {
142 if (!allow_cutoff) {
143 return pitch;
145 new_pitch = PITCH_MAX;
147 } else {
148 /* delta == 0 -> no real change */
149 return pitch;
151 sound_set_pitch(new_pitch);
153 return 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
162 sheet).
164 #define PITCH_SEMITONE_FACTOR 105946L
166 /* Some helpful constants. K is the scaling factor for SEMITONE.
167 N is for more accurate rounding
168 KN is K * N
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)
176 uint32_t tmp;
177 uint32_t round_fct; /* How much to scale down at the end */
178 tmp = pitch;
179 if (up) {
180 tmp = tmp * PITCH_SEMITONE_FACTOR;
181 round_fct = PITCH_K_FCT;
182 } else {
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)
193 int button;
194 int pitch = sound_get_pitch();
195 int new_pitch, delta = 0;
196 bool nudged = false;
197 bool exit = false;
198 int i;
200 #if CONFIG_CODEC == SWCODEC
201 pcmbuf_set_low_latency(true);
202 #endif
204 while (!exit)
206 FOR_NB_SCREENS(i)
207 pitch_screen_draw(&screens[i], pitch, pitch_mode);
209 button = get_action(CONTEXT_PITCHSCREEN,TIMEOUT_BLOCK);
210 switch (button) {
211 case ACTION_PS_INC_SMALL:
212 delta = PITCH_SMALL_DELTA;
213 break;
215 case ACTION_PS_INC_BIG:
216 delta = PITCH_BIG_DELTA;
217 break;
219 case ACTION_PS_DEC_SMALL:
220 delta = -PITCH_SMALL_DELTA;
221 break;
223 case ACTION_PS_DEC_BIG:
224 delta = -PITCH_BIG_DELTA;
225 break;
227 case ACTION_PS_NUDGE_RIGHT:
228 new_pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false);
229 nudged = (new_pitch != pitch);
230 pitch = new_pitch;
231 break;
233 case ACTION_PS_NUDGE_RIGHTOFF:
234 if (nudged) {
235 pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false);
237 nudged = false;
238 break;
240 case ACTION_PS_NUDGE_LEFT:
241 new_pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false);
242 nudged = (new_pitch != pitch);
243 pitch = new_pitch;
244 break;
246 case ACTION_PS_NUDGE_LEFTOFF:
247 if (nudged) {
248 pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false);
250 nudged = false;
251 break;
253 case ACTION_PS_RESET:
254 pitch = 1000;
255 sound_set_pitch( pitch );
256 break;
258 case ACTION_PS_TOGGLE_MODE:
259 pitch_mode = -pitch_mode;
260 break;
262 case ACTION_PS_EXIT:
263 exit = true;
264 break;
266 default:
267 if(default_event_handler(button) == SYS_USB_CONNECTED)
268 return 1;
269 break;
272 if(delta)
274 if (pitch_mode == PITCH_MODE_ABSOLUTE) {
275 pitch = pitch_increase(pitch, delta, true);
276 } else {
277 pitch = pitch_increase_semitone(pitch, delta > 0 ? true:false);
280 delta = 0;
284 #if CONFIG_CODEC == SWCODEC
285 pcmbuf_set_low_latency(false);
286 #endif
287 lcd_setfont(FONT_UI);
288 return 0;