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
35 #define BTN_LEFT BUTTON_LEFT
36 #define BTN_PLAY BUTTON_PLAY
38 #elif CONFIG_KEYPAD == ONDIO_PAD
39 #define BTN_QUIT BUTTON_OFF
40 #define BTN_RIGHT BUTTON_RIGHT
41 #define BTN_UP BUTTON_UP
42 #define BTN_DOWN BUTTON_DOWN
43 #define BTN_LEFT BUTTON_LEFT
44 #define BTN_PLAY (BUTTON_MENU | BUTTON_OFF)
47 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
48 #define BTN_QUIT BUTTON_OFF
49 #define BTN_RIGHT BUTTON_RIGHT
50 #define BTN_UP BUTTON_UP
51 #define BTN_DOWN BUTTON_DOWN
52 #define BTN_LEFT BUTTON_LEFT
53 #define BTN_RC_QUIT BUTTON_RC_STOP
54 #define BTN_PLAY BUTTON_ON
56 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
57 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
58 #define BTN_QUIT (BUTTON_SELECT | BUTTON_MENU)
59 #define BTN_RIGHT BUTTON_RIGHT
60 #define BTN_LEFT BUTTON_LEFT
61 #define BTN_UP BUTTON_SCROLL_FWD
62 #define BTN_DOWN BUTTON_SCROLL_BACK
63 #define BTN_PLAY BUTTON_PLAY
66 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
67 #define BTN_QUIT BUTTON_POWER
68 #define BTN_RIGHT BUTTON_RIGHT
69 #define BTN_LEFT BUTTON_LEFT
70 #define BTN_UP BUTTON_UP
71 #define BTN_DOWN BUTTON_DOWN
72 #define BTN_PLAY BUTTON_A
75 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
76 #define BTN_QUIT BUTTON_POWER
77 #define BTN_RIGHT BUTTON_RIGHT
78 #define BTN_LEFT BUTTON_LEFT
79 #define BTN_UP BUTTON_SCROLL_FWD
80 #define BTN_DOWN BUTTON_SCROLL_BACK
81 #define BTN_PLAY BUTTON_UP
84 #elif (CONFIG_KEYPAD == SANSA_C200_PAD)
85 #define BTN_QUIT BUTTON_POWER
86 #define BTN_RIGHT BUTTON_RIGHT
87 #define BTN_LEFT BUTTON_LEFT
88 #define BTN_UP BUTTON_UP
89 #define BTN_DOWN BUTTON_DOWN
90 #define BTN_PLAY BUTTON_REC
93 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
94 #define BTN_QUIT BUTTON_POWER
95 #define BTN_RIGHT BUTTON_RIGHT
96 #define BTN_LEFT BUTTON_LEFT
97 #define BTN_UP BUTTON_UP
98 #define BTN_DOWN BUTTON_DOWN
99 #define BTN_PLAY BUTTON_PLAY
102 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
103 #define BTN_QUIT BUTTON_POWER
104 #define BTN_RIGHT BUTTON_RIGHT
105 #define BTN_LEFT BUTTON_LEFT
106 #define BTN_UP BUTTON_SCROLL_UP
107 #define BTN_DOWN BUTTON_SCROLL_DOWN
108 #define BTN_PLAY BUTTON_PLAY
111 #elif CONFIG_KEYPAD == MROBE500_PAD
112 #define BTN_QUIT BUTTON_POWER
113 #define BTN_RIGHT BUTTON_RIGHT
114 #define BTN_LEFT BUTTON_LEFT
115 #define BTN_UP BUTTON_RC_PLAY
116 #define BTN_DOWN BUTTON_RC_DOWN
117 #define BTN_PLAY BUTTON_RC_HEART
128 struct MIDIfile
* mf IBSS_ATTR
;
130 int numberOfSamples IBSS_ATTR
; /* the number of samples in the current tick */
131 int playingTime IBSS_ATTR
; /* How many seconds into the file have we been playing? */
132 int samplesThisSecond IBSS_ATTR
; /* How many samples produced during this second so far? */
136 int32_t gmbuf
[BUF_SIZE
*NBUF
];
137 static unsigned int samples_in_buf
;
140 struct plugin_api
* rb
;
142 static int midimain(void * filename
);
144 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
149 PLUGIN_IRAM_INIT(api
)
152 if(parameter
== NULL
)
154 rb
->splash(HZ
*2, " Play .MID file ");
159 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
163 printf("%s", parameter
);
164 /* rb->splash(HZ, true, parameter); */
167 rb
->profile_thread();
170 retval
= midimain(parameter
);
177 rb
->pcm_set_frequency(HW_SAMPR_DEFAULT
);
179 #if defined(HAVE_ADJUSTABLE_CPU_FREQ)
180 rb
->cpu_boost(false);
182 rb
->splash(HZ
, "FINISHED PLAYING");
192 static inline void synthbuf(void)
198 if(lastswap
==swap
) return;
201 outptr
=(swap
? gmbuf
: gmbuf
+BUF_SIZE
);
206 /* synth samples for as many whole ticks as we can fit in the buffer */
207 for(; i
>= numberOfSamples
; i
-= numberOfSamples
)
209 synthSamples((int32_t*)outptr
, numberOfSamples
);
210 outptr
+= numberOfSamples
;
215 /* how many samples did we write to the buffer? */
216 samples_in_buf
= BUF_SIZE
-i
;
220 void get_more(unsigned char** start
, size_t* size
)
225 printf("Buffer miss!"); // Comment out the printf to make missses less noticable.
229 synthbuf(); // For some reason midiplayer crashes when an update is forced
232 *size
= samples_in_buf
*sizeof(int32_t);
234 *start
= (unsigned char*)((swap
? gmbuf
: gmbuf
+ BUF_SIZE
));
237 *start
= (unsigned char*)(gmbuf
);
241 static int midimain(void * filename
)
245 printf("Loading file");
246 mf
= loadFile(filename
);
250 printf("Error loading file.");
254 if (initSynth(mf
, ROCKBOX_DIR
"/patchset/patchset.cfg",
255 ROCKBOX_DIR
"/patchset/drums.cfg") == -1)
259 #if INPUT_SRC_CAPS != 0
260 /* Select playback */
261 rb
->audio_set_input_source(AUDIO_SRC_PLAYBACK
, SRCF_PLAYBACK
);
262 rb
->audio_set_output_source(AUDIO_SRC_PLAYBACK
);
264 rb
->pcm_set_frequency(SAMPLE_RATE
); // 44100 22050 11025
267 * tick() will do one MIDI clock tick. Then, there's a loop here that
268 * will generate the right number of samples per MIDI tick. The whole
269 * MIDI playback is timed in terms of this value.. there are no forced
270 * delays or anything. It just produces enough samples for each tick, and
271 * the playback of these samples is what makes the timings right.
273 * This seems to work quite well. On a laptop, anyway.
276 printf("Okay, starting sequencing");
278 bpm
=mf
->div
*1000000/tempo
;
279 numberOfSamples
=SAMPLE_RATE
/bpm
;
283 /* Skip over any junk in the beginning of the file, so start playing */
284 /* after the first note event */
288 for(a
=0; a
<MAX_VOICES
; a
++)
292 } while(notesUsed
== 0);
295 samplesThisSecond
= 0;
298 rb
->pcm_play_data(&get_more
, NULL
, 0);
300 int isPlaying
= 1; /* 0 = paused */
310 /* Prevent idle poweroff */
311 rb
->reset_poweroff_timer();
313 /* Code taken from Oscilloscope plugin */
314 switch(rb
->button_get(false))
317 case BTN_UP
| BUTTON_REPEAT
:
318 vol
= rb
->global_settings
->volume
;
319 if (vol
< rb
->sound_max(SOUND_VOLUME
))
322 rb
->sound_set(SOUND_VOLUME
, vol
);
323 rb
->global_settings
->volume
= vol
;
328 case BTN_DOWN
| BUTTON_REPEAT
:
329 vol
= rb
->global_settings
->volume
;
330 if (vol
> rb
->sound_min(SOUND_VOLUME
))
333 rb
->sound_set(SOUND_VOLUME
, vol
);
334 rb
->global_settings
->volume
= vol
;
341 /* Rewinding is tricky. Basically start the file over */
342 /* but run through the tracks without the synth running */
345 printf("Rewind to %d:%02d\n", playingTime
/60, playingTime
%60);
348 rb
->pcm_play_data(&get_more
, NULL
, 0);
356 printf("Skip to %d:%02d\n", playingTime
/60, playingTime
%60);
359 rb
->pcm_play_data(&get_more
, NULL
, 0);
367 printf("Paused at %d:%02d\n", playingTime
/60, playingTime
%60);
372 printf("Playing from %d:%02d\n", playingTime
/60, playingTime
%60);
374 rb
->pcm_play_data(&get_more
, NULL
, 0);