1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Karl Kurbjun based on midi2wav by Stepan Moskovchenko
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 #include "sequencer.h"
29 /* variable button definitions */
30 #if CONFIG_KEYPAD == RECORDER_PAD
31 #define BTN_QUIT BUTTON_OFF
32 #define BTN_RIGHT BUTTON_RIGHT
33 #define BTN_UP BUTTON_UP
34 #define BTN_DOWN BUTTON_DOWN
36 #elif CONFIG_KEYPAD == ONDIO_PAD
37 #define BTN_QUIT BUTTON_OFF
38 #define BTN_RIGHT BUTTON_RIGHT
39 #define BTN_UP BUTTON_UP
40 #define BTN_DOWN BUTTON_DOWN
42 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
43 #define BTN_QUIT BUTTON_OFF
44 #define BTN_RIGHT BUTTON_RIGHT
45 #define BTN_UP BUTTON_UP
46 #define BTN_DOWN BUTTON_DOWN
48 #define BTN_RC_QUIT BUTTON_RC_STOP
50 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
51 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
52 #define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU)
53 #define BTN_RIGHT BUTTON_RIGHT
54 #define BTN_UP BUTTON_SCROLL_FWD
55 #define BTN_DOWN BUTTON_SCROLL_BACK
57 #elif (CONFIG_KEYPAD == GIGABEAT_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
63 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
64 (CONFIG_KEYPAD == SANSA_C200_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 == IAUDIO_X5M5_PAD
71 #define BTN_QUIT BUTTON_POWER
72 #define BTN_RIGHT BUTTON_RIGHT
73 #define BTN_UP BUTTON_UP
74 #define BTN_DOWN BUTTON_DOWN
76 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
77 #define BTN_QUIT BUTTON_POWER
78 #define BTN_RIGHT BUTTON_RIGHT
79 #define BTN_UP BUTTON_SCROLL_UP
80 #define BTN_DOWN BUTTON_SCROLL_DOWN
90 struct MIDIfile
* mf IBSS_ATTR
;
92 int numberOfSamples IBSS_ATTR
;
95 int32_t gmbuf
[BUF_SIZE
*NBUF
];
96 static unsigned int samples_in_buf
;
99 struct plugin_api
* rb
;
101 static int midimain(void * filename
);
103 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
107 PLUGIN_IRAM_INIT(api
)
110 if(parameter
== NULL
)
112 rb
->splash(HZ
*2, " Play .MID file ");
117 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
121 printf("%s", parameter
);
122 /* rb->splash(HZ, true, parameter); */
125 rb
->profile_thread();
128 retval
= midimain(parameter
);
135 rb
->pcm_set_frequency(HW_SAMPR_DEFAULT
);
137 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
138 rb
->cpu_boost(false);
140 rb
->splash(HZ
, "FINISHED PLAYING");
150 static inline void synthbuf(void)
156 if(lastswap
==swap
) return;
159 outptr
=(swap
? gmbuf
: gmbuf
+BUF_SIZE
);
164 /* synth samples for as many whole ticks as we can fit in the buffer */
165 for(i
=0; i
< BUF_SIZE
/numberOfSamples
; i
++)
167 synthSamples((int32_t*)outptr
, numberOfSamples
);
168 outptr
+= numberOfSamples
;
173 /* how many samples did we write to the buffer? */
174 samples_in_buf
= BUF_SIZE
-(BUF_SIZE
%numberOfSamples
);
178 void get_more(unsigned char** start
, size_t* size
)
183 printf("Buffer miss!"); // Comment out the printf to make missses less noticable.
187 synthbuf(); // For some reason midiplayer crashes when an update is forced
190 *size
= samples_in_buf
*sizeof(int32_t);
192 *start
= (unsigned char*)((swap
? gmbuf
: gmbuf
+ BUF_SIZE
));
195 *start
= (unsigned char*)(gmbuf
);
199 static int midimain(void * filename
)
203 printf("Loading file");
204 mf
= loadFile(filename
);
208 printf("Error loading file.");
212 if (initSynth(mf
, ROCKBOX_DIR
"/patchset/patchset.cfg",
213 ROCKBOX_DIR
"/patchset/drums.cfg") == -1)
217 #if INPUT_SRC_CAPS != 0
218 /* Select playback */
219 rb
->audio_set_input_source(AUDIO_SRC_PLAYBACK
, SRCF_PLAYBACK
);
220 rb
->audio_set_output_source(AUDIO_SRC_PLAYBACK
);
222 rb
->pcm_set_frequency(SAMPLE_RATE
); // 44100 22050 11025
225 * tick() will do one MIDI clock tick. Then, there's a loop here that
226 * will generate the right number of samples per MIDI tick. The whole
227 * MIDI playback is timed in terms of this value.. there are no forced
228 * delays or anything. It just produces enough samples for each tick, and
229 * the playback of these samples is what makes the timings right.
231 * This seems to work quite well. On a laptop, anyway.
234 printf("Okay, starting sequencing");
236 bpm
=mf
->div
*1000000/tempo
;
237 numberOfSamples
=SAMPLE_RATE
/bpm
;
241 /* Skip over any junk in the beginning of the file, so start playing */
242 /* after the first note event */
246 for(a
=0; a
<MAX_VOICES
; a
++)
247 if(voices
[a
].isUsed
== 1)
250 } while(notesUsed
== 0);
253 rb
->pcm_play_data(&get_more
, NULL
, 0);
264 /* Prevent idle poweroff */
265 rb
->reset_poweroff_timer();
267 /* Code taken from Oscilloscope plugin */
268 switch(rb
->button_get(false))
271 case BTN_UP
| BUTTON_REPEAT
:
272 vol
= rb
->global_settings
->volume
;
273 if (vol
< rb
->sound_max(SOUND_VOLUME
))
276 rb
->sound_set(SOUND_VOLUME
, vol
);
277 rb
->global_settings
->volume
= vol
;
282 case BTN_DOWN
| BUTTON_REPEAT
:
283 vol
= rb
->global_settings
->volume
;
284 if (vol
> rb
->sound_min(SOUND_VOLUME
))
287 rb
->sound_set(SOUND_VOLUME
, vol
);
288 rb
->global_settings
->volume
= vol
;
295 /* Should skip length be retrieved from the RB settings? */
296 int samp
= 3*SAMPLE_RATE
;
297 int tickCount
= samp
/ numberOfSamples
;
299 for(a
=0; a
<tickCount
; a
++)