diff options
-rw-r--r-- | apps/plugins/metronome.c | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/apps/plugins/metronome.c b/apps/plugins/metronome.c new file mode 100644 index 0000000000..ece5275e87 --- /dev/null +++ b/apps/plugins/metronome.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2004 Matthias Wientapper | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "plugin.h" | ||
20 | |||
21 | #ifndef SIMULATOR | ||
22 | |||
23 | static struct plugin_api* rb; | ||
24 | |||
25 | static unsigned int bpm = 120; | ||
26 | static unsigned int time_to_next_tock; | ||
27 | |||
28 | static bool sound_active = false; | ||
29 | static bool sound_paused = true; | ||
30 | static bool mute = false; | ||
31 | static long mute_until_tick; | ||
32 | |||
33 | /*tick sound from a metronome*/ | ||
34 | static unsigned char sound[]={ | ||
35 | 255,251, 80,196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
36 | 0, 73,110,102,111, 0, 0, 0, 15, 0, 0, 0, 4, 0, 0, 4, 19, 0, 64, 64, | ||
37 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | ||
38 | 64, 64, 64,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, | ||
39 | 128,128,128,128,128,128,128,128,192,192,192,192,192,192,192,192,192,192,192,192, | ||
40 | 192,192,192,192,192,192,192,192,192,192,192,192,192,255,255,255,255,255,255,255, | ||
41 | 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, | ||
42 | 58, 76, 65, 77, 69, 51, 46, 57, 50, 32, 1,137, 0, 0, 0, 0, 0, 0, 0, 0, | ||
43 | 2, 64, 36, 5,191, 65, 0, 0, 0, 0, 0, 4, 19,168,187,153, 93, 0, 0, 0, | ||
44 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
45 | 0, 0, 0, 0, 0, 0, 0, 0,255,251, 80,196, 0, 0, 10, 81, 57, 65,184,120, | ||
46 | 128, 1, 95,159,239,191,144, 96, 0, 0,128, 0, 0, 0, 0, 0, 0, 48, 24, 12, | ||
47 | 0, 0, 15,175,185,222, 39, 7,126, 46, 50,191,243,197,255,247, 62, 92,111,252, | ||
48 | 115, 15, 27,140,153,159,247,242,124, 44, 92,164,177, 57,175,255,236, 79,164, 98, | ||
49 | 68,205, 69,160, 64, 15,251,127,128,168, 38, 92,138, 17, 67,196, 80,184,223,255, | ||
50 | 255,161,117, 33, 55, 83,191,255,193,240, 33, 57,114, 17, 0, 2, 0, 0, 0, 10, | ||
51 | 191, 10, 8,196,209, 75, 55,236,177,115,238,223,203, 61,176, 89, 78,101,219,118, | ||
52 | 118, 65,154,126,187,239,241,127,247,245, 59, 18,219, 94,105,245,221,161,173, 91, | ||
53 | 191, 27,255,247, 18,124, 71,117,139,133,170,221,227,251,135,110,236,255,183,219, | ||
54 | 100, 78,184,125,212,131, 65, 95,212,245,145, 67, 77, 10,153,250,132,195, 4,138, | ||
55 | 224, 0, 0, 0,158,107, 42, 65,227,185, 90,158, 86, 6,155, 77,255,251, 82,196, | ||
56 | 8, 0, 10,136,185,103, 4, 61, 48, 65,118,173, 44, 60,147, 10,152,107, 49, 74, | ||
57 | 18,208, 91, 23,178,196,220, 25, 64,233,230, 36,170, 0,210,219,131, 40,165, 22, | ||
58 | 86,195, 23,145, 33, 16,138, 99,109,117,245, 71,162, 69, 42,220,164, 91, 72,165, | ||
59 | 26, 69,146,150,199,222, 73,102,148, 29, 19, 5, 65, 86, 6,150,120,180, 26, 88, | ||
60 | 75, 18,191,255,250,171, 4, 8,132,140, 0, 0, 20,186,242,162, 66,100, 62, 86, | ||
61 | 206, 86,255, 26,203,201,255,255,141,128,166,196,175,133, 9, 70,188,146,175,133, | ||
62 | 60, 17,217,229, 90, 27, 87, 93, 34, 76,113,185, 84,213, 56, 17,170, 83, 75,180, | ||
63 | 203,116,101, 93, 90, 99, 35,174,230, 42,125, 12,128, 79, 93, 81,234, 67, 66,137, | ||
64 | 105,157,157, 23, 71, 53, 40,250,204,105, 89,203,107,250, 63,174, 89,133, 81,140, | ||
65 | 0, 52, 17, 16, 0, 0, 18,111, 20, 92, 32,213, 48,179, 50, 26,244,179, 27,230, | ||
66 | 154, 34,133,177, 88,255,251, 82,196, 13, 0, 10,125, 65, 85,244, 85, 0, 1,210, | ||
67 | 172,231, 7, 31, 32, 0, 37, 11, 68, 69, 13, 37, 48,210, 23, 69, 36,122,143,148, | ||
68 | 211,141, 44, 76,135, 72,148,195,135,174, 84,149,167, 30,198,183,255,213,111, 61, | ||
69 | 27,155,191,177,207,246,163,255,230, 30,137,219,255,182,186,185,239, 52,148,171, | ||
70 | 75, 63,167, 44, 0, 2, 81,190, 41,253,248,182,180, 23, 43,127,217,161, 41,191, | ||
71 | 36,199, 40,153,108, 66,224,131,192,217, 12, 67,217, 6,218,240,108,112, 63, 33, | ||
72 | 93, 12, 8, 43, 66, 42, 74, 12,215,135,100,172, 33, 65,172, 29, 98, 4, 83, 34, | ||
73 | 40, 17,111,133,255, 18,145, 60, 59,136,145, 92,106,144, 34,185, 58, 76,154,254, | ||
74 | 146,144,115, 4, 84,180,142,178, 38, 79,253, 34,237,105, 31,106, 70, 73, 36,138, | ||
75 | 73,164,181,127,253,182, 82,217, 26,245,117,163,255,219, 50,115,223,245, 92,198, | ||
76 | 165,173, 0, 15,249,132, 50, 19,157, 85,121,153,245, 51,255,251, 82,196, 6,131, | ||
77 | 74, 96,134,156, 92, 19, 0, 8, 0, 0, 52,128, 0, 0, 0, 60,226, 73, 57, 26, | ||
78 | 249,253,122,211,128, 65, 86, 10, 1, 9,195,128, 36, 72,225,196,146,115, 73, 18, | ||
79 | 75, 65, 77, 9, 5,200, 43, 16,163,129, 77, 9, 5,200,110, 39,127,255,255,255, | ||
80 | 255,255,255,255,252, 83, 66,142,140, 21,136, 46, 64,166,133, 28, 12, 21,136, 46, | ||
81 | 64,166,133, 21, 6, 76, 65, 77, 69, 51, 46, 57, 50, 85, 85, 85, 85, 85, 85, 85, | ||
82 | 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, | ||
83 | 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, | ||
84 | 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, | ||
85 | 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, | ||
86 | 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, | ||
87 | 85, 85, 85}; | ||
88 | |||
89 | |||
90 | |||
91 | void led(bool on){ | ||
92 | if(on) | ||
93 | or_b(0x40, &PBDRL); | ||
94 | else | ||
95 | and_b(~0x40, &PBDRL); | ||
96 | } | ||
97 | |||
98 | void calc_time_to_next_tock(void){ | ||
99 | time_to_next_tock = (HZ * 60) / bpm ; | ||
100 | } | ||
101 | |||
102 | void callback(unsigned char** start, int* size){ | ||
103 | *start = sound; /* give it the same frame again */ | ||
104 | *size = NULL; | ||
105 | sound_active = false; | ||
106 | led(0); | ||
107 | } | ||
108 | |||
109 | void play_tock(void){ | ||
110 | sound_active = true; | ||
111 | led(1); | ||
112 | rb->mp3_play_data(sound, sizeof(sound), callback); | ||
113 | rb->mp3_play_pause(true); /* kickoff audio */ | ||
114 | } | ||
115 | |||
116 | |||
117 | void draw_display(void){ | ||
118 | char buffer[30]; | ||
119 | rb->lcd_clear_display(); | ||
120 | |||
121 | #ifdef HAVE_LCD_BITMAP | ||
122 | rb->lcd_setfont(FONT_SYSFIXED); | ||
123 | rb->lcd_putsxy(1, 1, "Metronome"); | ||
124 | #endif | ||
125 | rb->snprintf(buffer, sizeof(buffer), "BPM: %d ",bpm); | ||
126 | #ifdef HAVE_LCD_BITMAP | ||
127 | rb->lcd_puts(0,7, buffer); | ||
128 | #else | ||
129 | rb->lcd_puts(0,0, buffer); | ||
130 | #endif | ||
131 | rb->snprintf(buffer, sizeof(buffer), "Vol: %d", | ||
132 | rb->global_settings->volume); | ||
133 | #ifdef HAVE_LCD_BITMAP | ||
134 | rb->lcd_puts(10, 7, buffer); | ||
135 | #else | ||
136 | rb->lcd_puts(0,1, buffer); | ||
137 | #endif | ||
138 | |||
139 | #ifdef HAVE_LCD_BITMAP | ||
140 | rb->lcd_drawline(0, 12, 111, 12); | ||
141 | if(sound_paused) | ||
142 | rb->lcd_puts(0,2,"press play"); | ||
143 | else | ||
144 | rb->lcd_puts(0,2,"press pause"); | ||
145 | rb->lcd_update(); | ||
146 | #endif | ||
147 | } | ||
148 | |||
149 | // helper function to change the volume by a certain amount, +/- | ||
150 | // ripped from video.c | ||
151 | void change_volume(int delta){ | ||
152 | int vol = rb->global_settings->volume + delta; | ||
153 | char buffer[30]; | ||
154 | if (vol > 100) vol = 100; | ||
155 | else if (vol < 0) vol = 0; | ||
156 | if (vol != rb->global_settings->volume) { | ||
157 | rb->mpeg_sound_set(SOUND_VOLUME, vol); | ||
158 | rb->global_settings->volume = vol; | ||
159 | rb->snprintf(buffer, sizeof(buffer), "Vol: %d ", vol); | ||
160 | #ifdef HAVE_LCD_BITMAP | ||
161 | rb->lcd_puts(0,7, buffer); | ||
162 | rb->lcd_update(); | ||
163 | #else | ||
164 | rb->lcd_puts(0,1, buffer); | ||
165 | #endif | ||
166 | } | ||
167 | } | ||
168 | |||
169 | // if a key was pressed we shut up for a little while | ||
170 | void set_mute_ticks(void){ | ||
171 | mute_until_tick = *rb->current_tick + 50; | ||
172 | mute = true; | ||
173 | } | ||
174 | |||
175 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter){ | ||
176 | |||
177 | TEST_PLUGIN_API(api); | ||
178 | (void)parameter; | ||
179 | rb = api; | ||
180 | |||
181 | rb->bitswap(sound, sizeof(sound)); | ||
182 | |||
183 | if (rb->mp3_is_playing) | ||
184 | rb->mp3_play_stop(); // stop audio ISR | ||
185 | |||
186 | calc_time_to_next_tock(); | ||
187 | draw_display(); | ||
188 | |||
189 | /* main loop */ | ||
190 | while (true){ | ||
191 | if (!mute && !sound_active && !sound_paused){ | ||
192 | play_tock(); | ||
193 | } | ||
194 | |||
195 | if (*rb->current_tick >= mute_until_tick) | ||
196 | mute = false; | ||
197 | |||
198 | switch (rb->button_get_w_tmo(time_to_next_tock)) { | ||
199 | #ifdef HAVE_RECORDER_KEYPAD | ||
200 | case BUTTON_OFF: | ||
201 | #else | ||
202 | case BUTTON_STOP: | ||
203 | #endif | ||
204 | /* get out of here */ | ||
205 | rb->mp3_play_stop(); /* stop audio ISR */ | ||
206 | led(0); | ||
207 | set_mute_ticks(); | ||
208 | return PLUGIN_OK; | ||
209 | |||
210 | case BUTTON_PLAY: | ||
211 | if(sound_paused) | ||
212 | sound_paused = false; | ||
213 | else | ||
214 | sound_paused = true; | ||
215 | calc_time_to_next_tock(); | ||
216 | draw_display(); | ||
217 | set_mute_ticks(); | ||
218 | break; | ||
219 | |||
220 | #ifdef HAVE_RECORDER_KEYPAD | ||
221 | case BUTTON_UP: | ||
222 | case BUTTON_UP | BUTTON_REPEAT: | ||
223 | #else | ||
224 | case BUTTON_ON | BUTTON_RIGHT: | ||
225 | case BUTTON_ON | BUTTON_RIGHT | BUTTON_REPEAT: | ||
226 | #endif | ||
227 | set_mute_ticks(); | ||
228 | change_volume(1); | ||
229 | break; | ||
230 | |||
231 | #ifdef HAVE_RECORDER_KEYPAD | ||
232 | case BUTTON_DOWN: | ||
233 | case BUTTON_DOWN | BUTTON_REPEAT: | ||
234 | #else | ||
235 | case BUTTON_ON | BUTTON_LEFT: | ||
236 | case BUTTON_ON | BUTTON_LEFT | BUTTON_REPEAT: | ||
237 | #endif | ||
238 | set_mute_ticks(); | ||
239 | change_volume(-1); | ||
240 | break; | ||
241 | |||
242 | case BUTTON_LEFT: | ||
243 | set_mute_ticks(); | ||
244 | if (bpm > 1) | ||
245 | bpm--; | ||
246 | calc_time_to_next_tock(); | ||
247 | draw_display(); | ||
248 | break; | ||
249 | |||
250 | case BUTTON_LEFT | BUTTON_REPEAT: | ||
251 | set_mute_ticks(); | ||
252 | if (bpm > 10) | ||
253 | bpm=bpm-10; | ||
254 | calc_time_to_next_tock(); | ||
255 | draw_display(); | ||
256 | break; | ||
257 | |||
258 | case BUTTON_RIGHT: | ||
259 | set_mute_ticks(); | ||
260 | if(bpm < 300) | ||
261 | bpm++; | ||
262 | calc_time_to_next_tock(); | ||
263 | draw_display(); | ||
264 | break; | ||
265 | |||
266 | case BUTTON_RIGHT | BUTTON_REPEAT: | ||
267 | set_mute_ticks(); | ||
268 | if (bpm < 300) | ||
269 | bpm=bpm+10; | ||
270 | calc_time_to_next_tock(); | ||
271 | draw_display(); | ||
272 | break; | ||
273 | |||
274 | case SYS_USB_CONNECTED: | ||
275 | rb->usb_screen(); | ||
276 | return PLUGIN_USB_CONNECTED; | ||
277 | } | ||
278 | } | ||
279 | } | ||
280 | #endif /* #ifndef SIMULATOR */ | ||