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 == RECORDER_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_PLAY BUTTON_PLAY
40 #elif CONFIG_KEYPAD == ONDIO_PAD
41 #define BTN_QUIT BUTTON_OFF
42 #define BTN_RIGHT BUTTON_RIGHT
43 #define BTN_UP BUTTON_UP
44 #define BTN_DOWN BUTTON_DOWN
45 #define BTN_LEFT BUTTON_LEFT
46 #define BTN_PLAY (BUTTON_MENU | BUTTON_OFF)
49 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
50 #define BTN_QUIT BUTTON_OFF
51 #define BTN_RIGHT BUTTON_RIGHT
52 #define BTN_UP BUTTON_UP
53 #define BTN_DOWN BUTTON_DOWN
54 #define BTN_LEFT BUTTON_LEFT
55 #define BTN_RC_QUIT BUTTON_RC_STOP
56 #define BTN_PLAY BUTTON_ON
58 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
59 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
60 #define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU)
61 #define BTN_RIGHT BUTTON_RIGHT
62 #define BTN_LEFT BUTTON_LEFT
63 #define BTN_UP BUTTON_SCROLL_FWD
64 #define BTN_DOWN BUTTON_SCROLL_BACK
65 #define BTN_PLAY BUTTON_PLAY
68 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
69 #define BTN_QUIT BUTTON_POWER
70 #define BTN_RIGHT BUTTON_RIGHT
71 #define BTN_LEFT BUTTON_LEFT
72 #define BTN_UP BUTTON_UP
73 #define BTN_DOWN BUTTON_DOWN
74 #define BTN_PLAY BUTTON_A
77 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
78 #define BTN_QUIT BUTTON_POWER
79 #define BTN_RIGHT BUTTON_RIGHT
80 #define BTN_LEFT BUTTON_LEFT
81 #define BTN_UP BUTTON_UP
82 #define BTN_DOWN BUTTON_DOWN
83 #define BTN_PLAY BUTTON_PLAY
86 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
87 #define BTN_QUIT BUTTON_POWER
88 #define BTN_RIGHT BUTTON_RIGHT
89 #define BTN_LEFT BUTTON_LEFT
90 #define BTN_UP BUTTON_SCROLL_FWD
91 #define BTN_DOWN BUTTON_SCROLL_BACK
92 #define BTN_PLAY BUTTON_UP
95 #elif (CONFIG_KEYPAD == SANSA_C200_PAD)
96 #define BTN_QUIT BUTTON_POWER
97 #define BTN_RIGHT BUTTON_RIGHT
98 #define BTN_LEFT BUTTON_LEFT
99 #define BTN_UP BUTTON_VOL_UP
100 #define BTN_DOWN BUTTON_VOL_DOWN
101 #define BTN_PLAY BUTTON_UP
104 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
105 #define BTN_QUIT BUTTON_POWER
106 #define BTN_RIGHT BUTTON_RIGHT
107 #define BTN_LEFT BUTTON_LEFT
108 #define BTN_UP BUTTON_UP
109 #define BTN_DOWN BUTTON_DOWN
110 #define BTN_PLAY BUTTON_PLAY
113 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
114 #define BTN_QUIT BUTTON_POWER
115 #define BTN_RIGHT BUTTON_RIGHT
116 #define BTN_LEFT BUTTON_LEFT
117 #define BTN_UP BUTTON_SCROLL_UP
118 #define BTN_DOWN BUTTON_SCROLL_DOWN
119 #define BTN_PLAY BUTTON_PLAY
122 #elif CONFIG_KEYPAD == MROBE500_PAD
123 #define BTN_QUIT BUTTON_POWER
124 #define BTN_RIGHT BUTTON_RIGHT
125 #define BTN_LEFT BUTTON_LEFT
126 #define BTN_UP BUTTON_RC_PLAY
127 #define BTN_DOWN BUTTON_RC_DOWN
128 #define BTN_PLAY BUTTON_RC_HEART
131 #elif (CONFIG_KEYPAD == MROBE100_PAD)
132 #define BTN_QUIT BUTTON_POWER
133 #define BTN_RIGHT BUTTON_RIGHT
134 #define BTN_LEFT BUTTON_LEFT
135 #define BTN_UP BUTTON_UP
136 #define BTN_DOWN BUTTON_DOWN
137 #define BTN_PLAY BUTTON_DISPLAY
140 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
141 #define BTN_QUIT BUTTON_RC_REC
142 #define BTN_RIGHT BUTTON_RC_FF
143 #define BTN_LEFT BUTTON_RC_REW
144 #define BTN_UP BUTTON_RC_VOL_UP
145 #define BTN_DOWN BUTTON_RC_VOL_DOWN
146 #define BTN_PLAY BUTTON_RC_PLAY
149 #elif CONFIG_KEYPAD == COWOND2_PAD
150 #define BTN_QUIT BUTTON_POWER
154 #error No keymap defined!
159 #define BTN_QUIT BUTTON_TOPLEFT
162 #define BTN_RIGHT BUTTON_MIDRIGHT
165 #define BTN_LEFT BUTTON_MIDLEFT
168 #define BTN_UP BUTTON_TOPMIDDLE
171 #define BTN_DOWN BUTTON_BOTTOMMIDDLE
174 #define BTN_PLAY BUTTON_CENTER
184 struct MIDIfile
* mf IBSS_ATTR
;
186 int numberOfSamples IBSS_ATTR
; /* the number of samples in the current tick */
187 int playingTime IBSS_ATTR
; /* How many seconds into the file have we been playing? */
188 int samplesThisSecond IBSS_ATTR
; /* How many samples produced during this second so far? */
192 int32_t gmbuf
[BUF_SIZE
*NBUF
];
193 static unsigned int samples_in_buf
;
196 const struct plugin_api
* rb
;
198 static int midimain(const void * filename
);
200 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
)
205 PLUGIN_IRAM_INIT(api
)
208 if(parameter
== NULL
)
210 rb
->splash(HZ
*2, " Play .MID file ");
215 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
219 printf("%s", parameter
);
220 /* rb->splash(HZ, true, parameter); */
223 rb
->profile_thread();
226 retval
= midimain(parameter
);
233 rb
->pcm_set_frequency(HW_SAMPR_DEFAULT
);
235 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
236 rb
->cpu_boost(false);
238 rb
->splash(HZ
, "FINISHED PLAYING");
248 static inline void synthbuf(void)
254 if(lastswap
==swap
) return;
257 outptr
=(swap
? gmbuf
: gmbuf
+BUF_SIZE
);
262 /* synth samples for as many whole ticks as we can fit in the buffer */
263 for(; i
>= numberOfSamples
; i
-= numberOfSamples
)
265 synthSamples((int32_t*)outptr
, numberOfSamples
);
266 outptr
+= numberOfSamples
;
271 /* how many samples did we write to the buffer? */
272 samples_in_buf
= BUF_SIZE
-i
;
276 void get_more(unsigned char** start
, size_t* size
)
281 printf("Buffer miss!"); // Comment out the printf to make missses less noticable.
285 synthbuf(); // For some reason midiplayer crashes when an update is forced
288 *size
= samples_in_buf
*sizeof(int32_t);
290 *start
= (unsigned char*)((swap
? gmbuf
: gmbuf
+ BUF_SIZE
));
293 *start
= (unsigned char*)(gmbuf
);
297 static int midimain(const void * filename
)
301 printf("Loading file");
302 mf
= loadFile(filename
);
306 printf("Error loading file.");
310 if (initSynth(mf
, ROCKBOX_DIR
"/patchset/patchset.cfg",
311 ROCKBOX_DIR
"/patchset/drums.cfg") == -1)
315 #if INPUT_SRC_CAPS != 0
316 /* Select playback */
317 rb
->audio_set_input_source(AUDIO_SRC_PLAYBACK
, SRCF_PLAYBACK
);
318 rb
->audio_set_output_source(AUDIO_SRC_PLAYBACK
);
320 rb
->pcm_set_frequency(SAMPLE_RATE
); // 44100 22050 11025
323 * tick() will do one MIDI clock tick. Then, there's a loop here that
324 * will generate the right number of samples per MIDI tick. The whole
325 * MIDI playback is timed in terms of this value.. there are no forced
326 * delays or anything. It just produces enough samples for each tick, and
327 * the playback of these samples is what makes the timings right.
329 * This seems to work quite well. On a laptop, anyway.
332 printf("Okay, starting sequencing");
334 bpm
=mf
->div
*1000000/tempo
;
335 numberOfSamples
=SAMPLE_RATE
/bpm
;
339 /* Skip over any junk in the beginning of the file, so start playing */
340 /* after the first note event */
344 for(a
=0; a
<MAX_VOICES
; a
++)
348 } while(notesUsed
== 0);
351 samplesThisSecond
= 0;
354 rb
->pcm_play_data(&get_more
, NULL
, 0);
356 int isPlaying
= 1; /* 0 = paused */
366 /* Prevent idle poweroff */
367 rb
->reset_poweroff_timer();
369 /* Code taken from Oscilloscope plugin */
370 switch(rb
->button_get(false))
373 case BTN_UP
| BUTTON_REPEAT
:
374 vol
= rb
->global_settings
->volume
;
375 if (vol
< rb
->sound_max(SOUND_VOLUME
))
378 rb
->sound_set(SOUND_VOLUME
, vol
);
379 rb
->global_settings
->volume
= vol
;
384 case BTN_DOWN
| BUTTON_REPEAT
:
385 vol
= rb
->global_settings
->volume
;
386 if (vol
> rb
->sound_min(SOUND_VOLUME
))
389 rb
->sound_set(SOUND_VOLUME
, vol
);
390 rb
->global_settings
->volume
= vol
;
397 /* Rewinding is tricky. Basically start the file over */
398 /* but run through the tracks without the synth running */
401 printf("Rewind to %d:%02d\n", playingTime
/60, playingTime
%60);
404 rb
->pcm_play_data(&get_more
, NULL
, 0);
412 printf("Skip to %d:%02d\n", playingTime
/60, playingTime
%60);
415 rb
->pcm_play_data(&get_more
, NULL
, 0);
423 printf("Paused at %d:%02d\n", playingTime
/60, playingTime
%60);
428 printf("Playing from %d:%02d\n", playingTime
/60, playingTime
%60);
430 rb
->pcm_play_data(&get_more
, NULL
, 0);