1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2005 Karl Kurbjun based on midi2wav by Stepan Moskovchenko
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
17 ****************************************************************************/
19 #include "../../plugin.h"
24 /* variable button definitions */
25 #if CONFIG_KEYPAD == RECORDER_PAD
26 #define BTN_QUIT BUTTON_OFF
27 #define BTN_RIGHT BUTTON_RIGHT
28 #define BTN_UP BUTTON_UP
29 #define BTN_DOWN BUTTON_DOWN
31 #elif CONFIG_KEYPAD == ONDIO_PAD
32 #define BTN_QUIT BUTTON_OFF
33 #define BTN_RIGHT BUTTON_RIGHT
34 #define BTN_UP BUTTON_UP
35 #define BTN_DOWN BUTTON_DOWN
37 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
38 #define BTN_QUIT BUTTON_OFF
39 #define BTN_RIGHT BUTTON_RIGHT
40 #define BTN_UP BUTTON_UP
41 #define BTN_DOWN BUTTON_DOWN
43 #define BTN_RC_QUIT BUTTON_RC_STOP
45 #elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
46 #define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU)
47 #define BTN_RIGHT BUTTON_RIGHT
48 #define BTN_UP BUTTON_SCROLL_FWD
49 #define BTN_DOWN BUTTON_SCROLL_BACK
51 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
52 #define BTN_QUIT BUTTON_POWER
53 #define BTN_RIGHT BUTTON_RIGHT
54 #define BTN_UP BUTTON_VOL_UP
55 #define BTN_DOWN BUTTON_VOL_DOWN
57 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
58 #define BTN_QUIT BUTTON_POWER
59 #define BTN_RIGHT BUTTON_RIGHT
60 #define BTN_UP BUTTON_UP
61 #define BTN_DOWN BUTTON_DOWN
64 #elif CONFIG_KEYPAD == IAUDIO_X5_PAD
65 #define BTN_QUIT BUTTON_POWER
66 #define BTN_RIGHT BUTTON_RIGHT
67 #define BTN_UP BUTTON_UP
68 #define BTN_DOWN BUTTON_DOWN
70 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
71 #define BTN_QUIT BUTTON_POWER
72 #define BTN_RIGHT BUTTON_RIGHT
73 #define BTN_UP BUTTON_SCROLL_UP
74 #define BTN_DOWN BUTTON_SCROLL_DOWN
83 #define SAMPLE_RATE 22050 // 44100 22050 11025
84 #define MAX_VOICES 14 // Note: 24 midi channels is the minimum general midi
85 // spec implementation
86 #else // Simulator requires 44100, and we can afford to use more voices
87 #define SAMPLE_RATE 44100
101 struct MIDIfile
* mf IBSS_ATTR
;
103 int numberOfSamples IBSS_ATTR
;
106 #include "midi/midiutil.c"
107 #include "midi/guspat.h"
108 #include "midi/guspat.c"
109 #include "midi/sequencer.c"
110 #include "midi/midifile.c"
111 #include "midi/synth.c"
113 short gmbuf
[BUF_SIZE
*NBUF
] IBSS_ATTR
;
116 struct plugin_api
* rb
;
118 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
122 PLUGIN_IRAM_INIT(api
)
125 if(parameter
== NULL
)
127 rb
->splash(HZ
*2, true, " Play .MID file ");
132 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
136 printf("\n%s", parameter
);
137 /* rb->splash(HZ, true, parameter); */
140 rb
->profile_thread();
143 retval
= midimain(parameter
);
151 rb
->pcm_set_frequency(SAMPLE_RATE
); // 44100
154 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
155 rb
->cpu_boost(false);
158 rb
->splash(HZ
, true, "FINISHED PLAYING");
168 inline void synthbuf(void)
172 static int currentSample
=0;
176 if(lastswap
==swap
) return;
179 outptr
=(swap
? gmbuf
: gmbuf
+BUF_SIZE
);
184 for(i
=0; i
<BUF_SIZE
/2; i
++)
186 synthSample(&synthtemp
[0], &synthtemp
[1]);
188 *outptr
=synthtemp
[0]&0xFFFF;
190 *outptr
=synthtemp
[1]&0xFFFF;
192 if(currentSample
==numberOfSamples
)
194 if( tick() == 0 ) quit
=1;
200 void get_more(unsigned char** start
, size_t* size
)
205 printf("Buffer miss!"); // Comment out the printf to make missses less noticable.
209 synthbuf(); // For some reason midiplayer crashes when an update is forced
212 *size
= BUF_SIZE
*sizeof(short);
214 *start
= (unsigned char*)((swap
? gmbuf
: gmbuf
+ BUF_SIZE
));
217 *start
= (unsigned char*)(gmbuf
);
221 int midimain(void * filename
)
225 printf("\nLoading file");
226 mf
= loadFile(filename
);
230 printf("\nError loading file.");
234 if (initSynth(mf
, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1)
239 rb
->pcm_set_frequency(SAMPLE_RATE
); // 44100 22050 11025
243 * tick() will do one MIDI clock tick. Then, there's a loop here that
244 * will generate the right number of samples per MIDI tick. The whole
245 * MIDI playback is timed in terms of this value.. there are no forced
246 * delays or anything. It just produces enough samples for each tick, and
247 * the playback of these samples is what makes the timings right.
249 * This seems to work quite well. On a laptop, anyway.
252 printf("\nOkay, starting sequencing");
254 bpm
=mf
->div
*1000000/tempo
;
255 numberOfSamples
=SAMPLE_RATE
/bpm
;
259 /* Skip over any junk in the beginning of the file, so start playing */
260 /* after the first note event */
264 for(a
=0; a
<MAX_VOICES
; a
++)
265 if(voices
[a
].isUsed
== 1)
268 } while(notesUsed
== 0);
272 rb
->pcm_play_data(&get_more
, NULL
, 0);
284 /* Code taken from Oscilloscope plugin */
285 switch(rb
->button_get(false))
288 case BTN_UP
| BUTTON_REPEAT
:
289 vol
= rb
->global_settings
->volume
;
290 if (vol
< rb
->sound_max(SOUND_VOLUME
))
293 rb
->sound_set(SOUND_VOLUME
, vol
);
294 rb
->global_settings
->volume
= vol
;
299 case BTN_DOWN
| BUTTON_REPEAT
:
300 vol
= rb
->global_settings
->volume
;
301 if (vol
> rb
->sound_min(SOUND_VOLUME
))
304 rb
->sound_set(SOUND_VOLUME
, vol
);
305 rb
->global_settings
->volume
= vol
;
312 /* Should skip length be retrieved from the RB settings? */
313 int samp
= 3*SAMPLE_RATE
;
314 int tickCount
= samp
/ numberOfSamples
;
316 for(a
=0; a
<tickCount
; a
++)