1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Karl Kurbjun based on midi2wav by Stepan Moskovchenko
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 ****************************************************************************/
25 #include "sequencer.h"
31 /* variable button definitions */
32 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
33 #define BTN_QUIT BUTTON_OFF
34 #define BTN_RIGHT BUTTON_RIGHT
35 #define BTN_UP BUTTON_UP
36 #define BTN_DOWN BUTTON_DOWN
37 #define BTN_LEFT BUTTON_LEFT
38 #define BTN_RC_QUIT BUTTON_RC_STOP
39 #define BTN_PLAY BUTTON_ON
41 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
42 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
43 #define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU)
44 #define BTN_RIGHT BUTTON_RIGHT
45 #define BTN_LEFT BUTTON_LEFT
46 #define BTN_UP BUTTON_SCROLL_FWD
47 #define BTN_DOWN BUTTON_SCROLL_BACK
48 #define BTN_PLAY BUTTON_PLAY
51 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
52 #define BTN_QUIT BUTTON_POWER
53 #define BTN_RIGHT BUTTON_RIGHT
54 #define BTN_LEFT BUTTON_LEFT
55 #define BTN_UP BUTTON_UP
56 #define BTN_DOWN BUTTON_DOWN
57 #define BTN_PLAY BUTTON_A
60 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
61 #define BTN_QUIT BUTTON_POWER
62 #define BTN_RIGHT BUTTON_RIGHT
63 #define BTN_LEFT BUTTON_LEFT
64 #define BTN_UP BUTTON_UP
65 #define BTN_DOWN BUTTON_DOWN
66 #define BTN_PLAY BUTTON_PLAY
69 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
70 #define BTN_QUIT BUTTON_POWER
71 #define BTN_RIGHT BUTTON_RIGHT
72 #define BTN_LEFT BUTTON_LEFT
73 #define BTN_UP BUTTON_SCROLL_FWD
74 #define BTN_DOWN BUTTON_SCROLL_BACK
75 #define BTN_PLAY BUTTON_UP
77 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
78 #define BTN_QUIT (BUTTON_HOME|BUTTON_REPEAT)
79 #define BTN_RIGHT BUTTON_RIGHT
80 #define BTN_LEFT BUTTON_LEFT
81 #define BTN_UP BUTTON_SCROLL_FWD
82 #define BTN_DOWN BUTTON_SCROLL_BACK
83 #define BTN_PLAY BUTTON_UP
86 #elif (CONFIG_KEYPAD == SANSA_C200_PAD) || \
87 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
88 (CONFIG_KEYPAD == SANSA_M200_PAD)
89 #define BTN_QUIT BUTTON_POWER
90 #define BTN_RIGHT BUTTON_RIGHT
91 #define BTN_LEFT BUTTON_LEFT
92 #define BTN_UP BUTTON_VOL_UP
93 #define BTN_DOWN BUTTON_VOL_DOWN
94 #define BTN_PLAY BUTTON_UP
97 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
98 #define BTN_QUIT BUTTON_POWER
99 #define BTN_RIGHT BUTTON_RIGHT
100 #define BTN_LEFT BUTTON_LEFT
101 #define BTN_UP BUTTON_UP
102 #define BTN_DOWN BUTTON_DOWN
103 #define BTN_PLAY BUTTON_PLAY
106 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
107 #define BTN_QUIT BUTTON_POWER
108 #define BTN_RIGHT BUTTON_RIGHT
109 #define BTN_LEFT BUTTON_LEFT
110 #define BTN_UP BUTTON_SCROLL_UP
111 #define BTN_DOWN BUTTON_SCROLL_DOWN
112 #define BTN_PLAY BUTTON_PLAY
115 #elif CONFIG_KEYPAD == MROBE500_PAD
116 #define BTN_QUIT BUTTON_POWER
117 #define BTN_RIGHT BUTTON_RIGHT
118 #define BTN_LEFT BUTTON_LEFT
119 #define BTN_UP BUTTON_RC_PLAY
120 #define BTN_DOWN BUTTON_RC_DOWN
121 #define BTN_PLAY BUTTON_RC_HEART
124 #elif (CONFIG_KEYPAD == MROBE100_PAD)
125 #define BTN_QUIT BUTTON_POWER
126 #define BTN_RIGHT BUTTON_RIGHT
127 #define BTN_LEFT BUTTON_LEFT
128 #define BTN_UP BUTTON_UP
129 #define BTN_DOWN BUTTON_DOWN
130 #define BTN_PLAY BUTTON_DISPLAY
133 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
134 #define BTN_QUIT BUTTON_RC_REC
135 #define BTN_RIGHT BUTTON_RC_FF
136 #define BTN_LEFT BUTTON_RC_REW
137 #define BTN_UP BUTTON_RC_VOL_UP
138 #define BTN_DOWN BUTTON_RC_VOL_DOWN
139 #define BTN_PLAY BUTTON_RC_PLAY
142 #elif CONFIG_KEYPAD == COWOND2_PAD
143 #define BTN_QUIT BUTTON_POWER
145 #elif CONFIG_KEYPAD == IAUDIO67_PAD
146 #define BTN_QUIT BUTTON_POWER
147 #define BTN_RIGHT BUTTON_RIGHT
148 #define BTN_LEFT BUTTON_LEFT
149 #define BTN_UP BUTTON_STOP
150 #define BTN_DOWN BUTTON_PLAY
151 #define BTN_PLAY BUTTON_MENU
153 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
154 #define BTN_QUIT BUTTON_BACK
155 #define BTN_RIGHT BUTTON_RIGHT
156 #define BTN_LEFT BUTTON_LEFT
157 #define BTN_UP BUTTON_UP
158 #define BTN_DOWN BUTTON_DOWN
159 #define BTN_PLAY BUTTON_PLAY
161 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
162 #define BTN_QUIT BUTTON_POWER
163 #define BTN_RIGHT BUTTON_RIGHT
164 #define BTN_LEFT BUTTON_LEFT
165 #define BTN_UP BUTTON_UP
166 #define BTN_DOWN BUTTON_DOWN
167 #define BTN_PLAY BUTTON_MENU
169 #elif CONFIG_KEYPAD == ONDAVX747_PAD
170 #define BTN_QUIT BUTTON_POWER
172 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
173 #define BTN_QUIT BUTTON_REW
174 #define BTN_RIGHT BUTTON_RIGHT
175 #define BTN_LEFT BUTTON_LEFT
176 #define BTN_UP BUTTON_UP
177 #define BTN_DOWN BUTTON_DOWN
178 #define BTN_PLAY BUTTON_PLAY
181 #error No keymap defined!
184 #ifdef HAVE_TOUCHSCREEN
186 #define BTN_QUIT BUTTON_TOPLEFT
189 #define BTN_RIGHT BUTTON_MIDRIGHT
192 #define BTN_LEFT BUTTON_MIDLEFT
195 #define BTN_UP BUTTON_TOPMIDDLE
198 #define BTN_DOWN BUTTON_BOTTOMMIDDLE
201 #define BTN_PLAY BUTTON_CENTER
211 struct MIDIfile
* mf IBSS_ATTR
;
213 int number_of_samples IBSS_ATTR
; /* the number of samples in the current tick */
214 int playing_time IBSS_ATTR
; /* How many seconds into the file have we been playing? */
215 int samples_this_second IBSS_ATTR
; /* How many samples produced during this second so far? */
218 int32_t gmbuf
[BUF_SIZE
*NBUF
];
219 static unsigned int samples_in_buf
;
223 bool lastswap
= true;
225 static inline void synthbuf(void)
231 if (lastswap
== swap
)
235 outptr
= (swap
? gmbuf
: gmbuf
+BUF_SIZE
);
240 /* synth samples for as many whole ticks as we can fit in the buffer */
241 for (; i
>= number_of_samples
; i
-= number_of_samples
)
243 synthSamples((int32_t*)outptr
, number_of_samples
);
244 outptr
+= number_of_samples
;
246 /* synthbuf is called in interrupt context is SYNC is defined so it cannot yield
247 that bug causing the sim to crach when not using SYNC should really be fixed */
254 /* how many samples did we write to the buffer? */
255 samples_in_buf
= BUF_SIZE
-i
;
258 void get_more(unsigned char** start
, size_t* size
)
263 printf("Buffer miss!"); /* Comment out the printf to make missses less noticable. */
267 synthbuf(); /* For some reason midiplayer crashes when an update is forced */
270 *size
= samples_in_buf
*sizeof(int32_t);
272 *start
= (unsigned char*)((swap
? gmbuf
: gmbuf
+ BUF_SIZE
));
275 *start
= (unsigned char*)(gmbuf
);
279 static int midimain(const void * filename
)
281 int a
, notes_used
, vol
;
282 bool is_playing
= true; /* false = paused */
284 printf("Loading file");
285 mf
= loadFile(filename
);
289 printf("Error loading file.");
293 if (initSynth(mf
, ROCKBOX_DIR
"/patchset/patchset.cfg",
294 ROCKBOX_DIR
"/patchset/drums.cfg") == -1)
298 #if INPUT_SRC_CAPS != 0
299 /* Select playback */
300 rb
->audio_set_input_source(AUDIO_SRC_PLAYBACK
, SRCF_PLAYBACK
);
301 rb
->audio_set_output_source(AUDIO_SRC_PLAYBACK
);
303 rb
->pcm_set_frequency(SAMPLE_RATE
); /* 44100 22050 11025 */
306 * tick() will do one MIDI clock tick. Then, there's a loop here that
307 * will generate the right number of samples per MIDI tick. The whole
308 * MIDI playback is timed in terms of this value.. there are no forced
309 * delays or anything. It just produces enough samples for each tick, and
310 * the playback of these samples is what makes the timings right.
312 * This seems to work quite well. On a laptop, anyway.
315 printf("Okay, starting sequencing");
317 bpm
= mf
->div
*1000000/tempo
;
318 number_of_samples
= SAMPLE_RATE
/bpm
;
320 /* Skip over any junk in the beginning of the file, so start playing */
321 /* after the first note event */
325 for (a
= 0; a
< MAX_VOICES
; a
++)
326 if (voices
[a
].isUsed
)
329 } while (notes_used
== 0);
332 samples_this_second
= 0;
335 rb
->pcm_play_data(&get_more
, NULL
, 0);
344 /* Prevent idle poweroff */
345 rb
->reset_poweroff_timer();
347 /* Code taken from Oscilloscope plugin */
348 switch (rb
->button_get(false))
351 case BTN_UP
| BUTTON_REPEAT
:
353 vol
= rb
->global_settings
->volume
;
354 if (vol
< rb
->sound_max(SOUND_VOLUME
))
357 rb
->sound_set(SOUND_VOLUME
, vol
);
358 rb
->global_settings
->volume
= vol
;
364 case BTN_DOWN
| BUTTON_REPEAT
:
366 vol
= rb
->global_settings
->volume
;
367 if (vol
> rb
->sound_min(SOUND_VOLUME
))
370 rb
->sound_set(SOUND_VOLUME
, vol
);
371 rb
->global_settings
->volume
= vol
;
378 /* Rewinding is tricky. Basically start the file over */
379 /* but run through the tracks without the synth running */
382 printf("Rewind to %d:%02d\n", playing_time
/60, playing_time
%60);
384 rb
->pcm_play_data(&get_more
, NULL
, 0);
392 printf("Skip to %d:%02d\n", playing_time
/60, playing_time
%60);
394 rb
->pcm_play_data(&get_more
, NULL
, 0);
402 printf("Paused at %d:%02d\n", playing_time
/60, playing_time
%60);
407 printf("Playing from %d:%02d\n", playing_time
/60, playing_time
%60);
409 rb
->pcm_play_data(&get_more
, NULL
, 0);
424 enum plugin_status
plugin_start(const void* parameter
)
429 if (parameter
== NULL
)
431 rb
->splash(HZ
*2, " Play .MID file ");
436 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
440 printf("%s", parameter
);
441 /* rb->splash(HZ, true, parameter); */
444 rb
->profile_thread();
447 retval
= midimain(parameter
);
454 rb
->pcm_set_frequency(HW_SAMPR_DEFAULT
);
456 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
457 rb
->cpu_boost(false);
459 rb
->splash(HZ
, "FINISHED PLAYING");