diff options
Diffstat (limited to 'apps/plugins/midi/midiplay.c')
-rw-r--r-- | apps/plugins/midi/midiplay.c | 313 |
1 files changed, 145 insertions, 168 deletions
diff --git a/apps/plugins/midi/midiplay.c b/apps/plugins/midi/midiplay.c index ac23187686..b0024087b6 100644 --- a/apps/plugins/midi/midiplay.c +++ b/apps/plugins/midi/midiplay.c | |||
@@ -29,24 +29,7 @@ PLUGIN_HEADER | |||
29 | PLUGIN_IRAM_DECLARE | 29 | PLUGIN_IRAM_DECLARE |
30 | 30 | ||
31 | /* variable button definitions */ | 31 | /* variable button definitions */ |
32 | #if CONFIG_KEYPAD == RECORDER_PAD | 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_PLAY BUTTON_PLAY | ||
39 | |||
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) | ||
47 | |||
48 | |||
49 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) | ||
50 | #define BTN_QUIT BUTTON_OFF | 33 | #define BTN_QUIT BUTTON_OFF |
51 | #define BTN_RIGHT BUTTON_RIGHT | 34 | #define BTN_RIGHT BUTTON_RIGHT |
52 | #define BTN_UP BUTTON_UP | 35 | #define BTN_UP BUTTON_UP |
@@ -209,110 +192,67 @@ PLUGIN_IRAM_DECLARE | |||
209 | 192 | ||
210 | struct MIDIfile * mf IBSS_ATTR; | 193 | struct MIDIfile * mf IBSS_ATTR; |
211 | 194 | ||
212 | int numberOfSamples IBSS_ATTR; /* the number of samples in the current tick */ | 195 | int number_of_samples IBSS_ATTR; /* the number of samples in the current tick */ |
213 | int playingTime IBSS_ATTR; /* How many seconds into the file have we been playing? */ | 196 | int playing_time IBSS_ATTR; /* How many seconds into the file have we been playing? */ |
214 | int samplesThisSecond IBSS_ATTR; /* How many samples produced during this second so far? */ | 197 | int samples_this_second IBSS_ATTR; /* How many samples produced during this second so far? */ |
215 | |||
216 | long bpm IBSS_ATTR; | 198 | long bpm IBSS_ATTR; |
217 | 199 | ||
218 | int32_t gmbuf[BUF_SIZE*NBUF]; | 200 | int32_t gmbuf[BUF_SIZE*NBUF]; |
219 | static unsigned int samples_in_buf; | 201 | static unsigned int samples_in_buf; |
220 | 202 | ||
221 | int quit=0; | 203 | bool quit = false; |
222 | 204 | bool swap = false; | |
223 | static int midimain(const void * filename); | 205 | bool lastswap = true; |
224 | |||
225 | enum plugin_status plugin_start(const void* parameter) | ||
226 | { | ||
227 | int retval = 0; | ||
228 | |||
229 | |||
230 | PLUGIN_IRAM_INIT(rb) | ||
231 | |||
232 | if(parameter == NULL) | ||
233 | { | ||
234 | rb->splash(HZ*2, " Play .MID file "); | ||
235 | return PLUGIN_OK; | ||
236 | } | ||
237 | rb->lcd_setfont(0); | ||
238 | |||
239 | #if defined(HAVE_ADJUSTABLE_CPU_FREQ) | ||
240 | rb->cpu_boost(true); | ||
241 | #endif | ||
242 | |||
243 | printf("%s", parameter); | ||
244 | /* rb->splash(HZ, true, parameter); */ | ||
245 | |||
246 | #ifdef RB_PROFILE | ||
247 | rb->profile_thread(); | ||
248 | #endif | ||
249 | |||
250 | retval = midimain(parameter); | ||
251 | |||
252 | #ifdef RB_PROFILE | ||
253 | rb->profstop(); | ||
254 | #endif | ||
255 | |||
256 | rb->pcm_play_stop(); | ||
257 | rb->pcm_set_frequency(HW_SAMPR_DEFAULT); | ||
258 | |||
259 | #if defined(HAVE_ADJUSTABLE_CPU_FREQ) | ||
260 | rb->cpu_boost(false); | ||
261 | #endif | ||
262 | rb->splash(HZ, "FINISHED PLAYING"); | ||
263 | |||
264 | if(retval == -1) | ||
265 | return PLUGIN_ERROR; | ||
266 | return PLUGIN_OK; | ||
267 | } | ||
268 | |||
269 | bool swap=0; | ||
270 | bool lastswap=1; | ||
271 | 206 | ||
272 | static inline void synthbuf(void) | 207 | static inline void synthbuf(void) |
273 | { | 208 | { |
274 | int32_t *outptr; | 209 | int32_t *outptr; |
275 | int i=BUF_SIZE; | 210 | int i = BUF_SIZE; |
276 | 211 | ||
277 | #ifndef SYNC | 212 | #ifndef SYNC |
278 | if(lastswap==swap) return; | 213 | if (lastswap == swap) |
279 | lastswap=swap; | 214 | return; |
215 | lastswap = swap; | ||
280 | 216 | ||
281 | outptr=(swap ? gmbuf : gmbuf+BUF_SIZE); | 217 | outptr = (swap ? gmbuf : gmbuf+BUF_SIZE); |
282 | #else | 218 | #else |
283 | outptr=gmbuf; | 219 | outptr = gmbuf; |
284 | #endif | 220 | #endif |
285 | 221 | ||
286 | /* synth samples for as many whole ticks as we can fit in the buffer */ | 222 | /* synth samples for as many whole ticks as we can fit in the buffer */ |
287 | for(; i >= numberOfSamples; i -= numberOfSamples) | 223 | for (; i >= number_of_samples; i -= number_of_samples) |
288 | { | 224 | { |
289 | synthSamples((int32_t*)outptr, numberOfSamples); | 225 | synthSamples((int32_t*)outptr, number_of_samples); |
290 | outptr += numberOfSamples; | 226 | outptr += number_of_samples; |
291 | if( tick() == 0 ) | 227 | #ifndef SYNC |
292 | quit=1; | 228 | /* synthbuf is called in interrupt context is SYNC is defined so it cannot yield |
229 | that bug causing the sim to crach when not using SYNC should really be fixed */ | ||
230 | rb->yield(); | ||
231 | #endif | ||
232 | if (tick() == 0) | ||
233 | quit = true; | ||
293 | } | 234 | } |
294 | 235 | ||
295 | /* how many samples did we write to the buffer? */ | 236 | /* how many samples did we write to the buffer? */ |
296 | samples_in_buf = BUF_SIZE-i; | 237 | samples_in_buf = BUF_SIZE-i; |
297 | |||
298 | } | 238 | } |
299 | 239 | ||
300 | void get_more(unsigned char** start, size_t* size) | 240 | void get_more(unsigned char** start, size_t* size) |
301 | { | 241 | { |
302 | #ifndef SYNC | 242 | #ifndef SYNC |
303 | if(lastswap!=swap) | 243 | if(lastswap != swap) |
304 | { | 244 | { |
305 | printf("Buffer miss!"); // Comment out the printf to make missses less noticable. | 245 | printf("Buffer miss!"); /* Comment out the printf to make missses less noticable. */ |
306 | } | 246 | } |
307 | 247 | ||
308 | #else | 248 | #else |
309 | synthbuf(); // For some reason midiplayer crashes when an update is forced | 249 | synthbuf(); /* For some reason midiplayer crashes when an update is forced */ |
310 | #endif | 250 | #endif |
311 | 251 | ||
312 | *size = samples_in_buf*sizeof(int32_t); | 252 | *size = samples_in_buf*sizeof(int32_t); |
313 | #ifndef SYNC | 253 | #ifndef SYNC |
314 | *start = (unsigned char*)((swap ? gmbuf : gmbuf + BUF_SIZE)); | 254 | *start = (unsigned char*)((swap ? gmbuf : gmbuf + BUF_SIZE)); |
315 | swap=!swap; | 255 | swap = !swap; |
316 | #else | 256 | #else |
317 | *start = (unsigned char*)(gmbuf); | 257 | *start = (unsigned char*)(gmbuf); |
318 | #endif | 258 | #endif |
@@ -320,12 +260,13 @@ void get_more(unsigned char** start, size_t* size) | |||
320 | 260 | ||
321 | static int midimain(const void * filename) | 261 | static int midimain(const void * filename) |
322 | { | 262 | { |
323 | int notesUsed = 0; | 263 | int a, notes_used, vol; |
324 | int a=0; | 264 | bool is_playing = true; /* false = paused */ |
265 | |||
325 | printf("Loading file"); | 266 | printf("Loading file"); |
326 | mf= loadFile(filename); | 267 | mf = loadFile(filename); |
327 | 268 | ||
328 | if(mf == NULL) | 269 | if (mf == NULL) |
329 | { | 270 | { |
330 | printf("Error loading file."); | 271 | printf("Error loading file."); |
331 | return -1; | 272 | return -1; |
@@ -341,7 +282,7 @@ static int midimain(const void * filename) | |||
341 | rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); | 282 | rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); |
342 | rb->audio_set_output_source(AUDIO_SRC_PLAYBACK); | 283 | rb->audio_set_output_source(AUDIO_SRC_PLAYBACK); |
343 | #endif | 284 | #endif |
344 | rb->pcm_set_frequency(SAMPLE_RATE); // 44100 22050 11025 | 285 | rb->pcm_set_frequency(SAMPLE_RATE); /* 44100 22050 11025 */ |
345 | 286 | ||
346 | /* | 287 | /* |
347 | * tick() will do one MIDI clock tick. Then, there's a loop here that | 288 | * tick() will do one MIDI clock tick. Then, there's a loop here that |
@@ -355,32 +296,27 @@ static int midimain(const void * filename) | |||
355 | 296 | ||
356 | printf("Okay, starting sequencing"); | 297 | printf("Okay, starting sequencing"); |
357 | 298 | ||
358 | bpm=mf->div*1000000/tempo; | 299 | bpm = mf->div*1000000/tempo; |
359 | numberOfSamples=SAMPLE_RATE/bpm; | 300 | number_of_samples = SAMPLE_RATE/bpm; |
360 | |||
361 | |||
362 | 301 | ||
363 | /* Skip over any junk in the beginning of the file, so start playing */ | 302 | /* Skip over any junk in the beginning of the file, so start playing */ |
364 | /* after the first note event */ | 303 | /* after the first note event */ |
365 | do | 304 | do |
366 | { | 305 | { |
367 | notesUsed = 0; | 306 | notes_used = 0; |
368 | for(a=0; a<MAX_VOICES; a++) | 307 | for (a = 0; a < MAX_VOICES; a++) |
369 | if(voices[a].isUsed) | 308 | if (voices[a].isUsed) |
370 | notesUsed++; | 309 | notes_used++; |
371 | tick(); | 310 | tick(); |
372 | } while(notesUsed == 0); | 311 | } while (notes_used == 0); |
373 | 312 | ||
374 | playingTime = 0; | 313 | playing_time = 0; |
375 | samplesThisSecond = 0; | 314 | samples_this_second = 0; |
376 | 315 | ||
377 | synthbuf(); | 316 | synthbuf(); |
378 | rb->pcm_play_data(&get_more, NULL, 0); | 317 | rb->pcm_play_data(&get_more, NULL, 0); |
379 | 318 | ||
380 | int isPlaying = 1; /* 0 = paused */ | 319 | while (!quit) |
381 | int vol=0; | ||
382 | |||
383 | while(!quit) | ||
384 | { | 320 | { |
385 | #ifndef SYNC | 321 | #ifndef SYNC |
386 | synthbuf(); | 322 | synthbuf(); |
@@ -391,80 +327,121 @@ static int midimain(const void * filename) | |||
391 | rb->reset_poweroff_timer(); | 327 | rb->reset_poweroff_timer(); |
392 | 328 | ||
393 | /* Code taken from Oscilloscope plugin */ | 329 | /* Code taken from Oscilloscope plugin */ |
394 | switch(rb->button_get(false)) | 330 | switch (rb->button_get(false)) |
395 | { | 331 | { |
396 | case BTN_UP: | 332 | case BTN_UP: |
397 | case BTN_UP | BUTTON_REPEAT: | 333 | case BTN_UP | BUTTON_REPEAT: |
398 | vol = rb->global_settings->volume; | 334 | { |
399 | if (vol < rb->sound_max(SOUND_VOLUME)) | 335 | vol = rb->global_settings->volume; |
400 | { | 336 | if (vol < rb->sound_max(SOUND_VOLUME)) |
401 | vol++; | ||
402 | rb->sound_set(SOUND_VOLUME, vol); | ||
403 | rb->global_settings->volume = vol; | ||
404 | } | ||
405 | break; | ||
406 | |||
407 | case BTN_DOWN: | ||
408 | case BTN_DOWN | BUTTON_REPEAT: | ||
409 | vol = rb->global_settings->volume; | ||
410 | if (vol > rb->sound_min(SOUND_VOLUME)) | ||
411 | { | ||
412 | vol--; | ||
413 | rb->sound_set(SOUND_VOLUME, vol); | ||
414 | rb->global_settings->volume = vol; | ||
415 | } | ||
416 | break; | ||
417 | |||
418 | |||
419 | case BTN_LEFT: | ||
420 | { | 337 | { |
421 | /* Rewinding is tricky. Basically start the file over */ | 338 | vol++; |
422 | /* but run through the tracks without the synth running */ | 339 | rb->sound_set(SOUND_VOLUME, vol); |
423 | rb->pcm_play_stop(); | 340 | rb->global_settings->volume = vol; |
424 | seekBackward(5); | ||
425 | printf("Rewind to %d:%02d\n", playingTime/60, playingTime%60); | ||
426 | |||
427 | if(isPlaying) | ||
428 | rb->pcm_play_data(&get_more, NULL, 0); | ||
429 | break; | ||
430 | } | 341 | } |
431 | 342 | break; | |
432 | case BTN_RIGHT: | 343 | } |
344 | |||
345 | case BTN_DOWN: | ||
346 | case BTN_DOWN | BUTTON_REPEAT: | ||
347 | { | ||
348 | vol = rb->global_settings->volume; | ||
349 | if (vol > rb->sound_min(SOUND_VOLUME)) | ||
433 | { | 350 | { |
434 | rb->pcm_play_stop(); | 351 | vol--; |
435 | seekForward(5); | 352 | rb->sound_set(SOUND_VOLUME, vol); |
436 | printf("Skip to %d:%02d\n", playingTime/60, playingTime%60); | 353 | rb->global_settings->volume = vol; |
437 | |||
438 | if(isPlaying) | ||
439 | rb->pcm_play_data(&get_more, NULL, 0); | ||
440 | break; | ||
441 | } | 354 | } |
442 | 355 | break; | |
443 | case BTN_PLAY: | 356 | } |
357 | |||
358 | case BTN_LEFT: | ||
359 | { | ||
360 | /* Rewinding is tricky. Basically start the file over */ | ||
361 | /* but run through the tracks without the synth running */ | ||
362 | rb->pcm_play_stop(); | ||
363 | seekBackward(5); | ||
364 | printf("Rewind to %d:%02d\n", playing_time/60, playing_time%60); | ||
365 | if (is_playing) | ||
366 | rb->pcm_play_data(&get_more, NULL, 0); | ||
367 | break; | ||
368 | } | ||
369 | |||
370 | case BTN_RIGHT: | ||
371 | { | ||
372 | rb->pcm_play_stop(); | ||
373 | seekForward(5); | ||
374 | printf("Skip to %d:%02d\n", playing_time/60, playing_time%60); | ||
375 | if (is_playing) | ||
376 | rb->pcm_play_data(&get_more, NULL, 0); | ||
377 | break; | ||
378 | } | ||
379 | |||
380 | case BTN_PLAY: | ||
381 | { | ||
382 | if (is_playing) | ||
383 | { | ||
384 | printf("Paused at %d:%02d\n", playing_time/60, playing_time%60); | ||
385 | is_playing = false; | ||
386 | rb->pcm_play_stop(); | ||
387 | } else | ||
444 | { | 388 | { |
445 | if(isPlaying == 1) | 389 | printf("Playing from %d:%02d\n", playing_time/60, playing_time%60); |
446 | { | 390 | is_playing = true; |
447 | printf("Paused at %d:%02d\n", playingTime/60, playingTime%60); | 391 | rb->pcm_play_data(&get_more, NULL, 0); |
448 | isPlaying = 0; | ||
449 | rb->pcm_play_stop(); | ||
450 | } else | ||
451 | { | ||
452 | printf("Playing from %d:%02d\n", playingTime/60, playingTime%60); | ||
453 | isPlaying = 1; | ||
454 | rb->pcm_play_data(&get_more, NULL, 0); | ||
455 | } | ||
456 | break; | ||
457 | } | 392 | } |
393 | break; | ||
394 | } | ||
458 | 395 | ||
459 | #ifdef BTN_RC_QUIT | 396 | #ifdef BTN_RC_QUIT |
460 | case BTN_RC_QUIT: | 397 | case BTN_RC_QUIT: |
461 | #endif | 398 | #endif |
462 | case BTN_QUIT: | 399 | case BTN_QUIT: |
463 | quit=1; | 400 | quit = true; |
464 | } | 401 | } |
402 | } | ||
403 | return 0; | ||
404 | } | ||
465 | 405 | ||
406 | enum plugin_status plugin_start(const void* parameter) | ||
407 | { | ||
408 | int retval; | ||
409 | PLUGIN_IRAM_INIT(rb) | ||
466 | 410 | ||
411 | if (parameter == NULL) | ||
412 | { | ||
413 | rb->splash(HZ*2, " Play .MID file "); | ||
414 | return PLUGIN_OK; | ||
467 | } | 415 | } |
416 | rb->lcd_setfont(0); | ||
468 | 417 | ||
469 | return 0; | 418 | #if defined(HAVE_ADJUSTABLE_CPU_FREQ) |
419 | rb->cpu_boost(true); | ||
420 | #endif | ||
421 | |||
422 | printf("%s", parameter); | ||
423 | /* rb->splash(HZ, true, parameter); */ | ||
424 | |||
425 | #ifdef RB_PROFILE | ||
426 | rb->profile_thread(); | ||
427 | #endif | ||
428 | |||
429 | retval = midimain(parameter); | ||
430 | |||
431 | #ifdef RB_PROFILE | ||
432 | rb->profstop(); | ||
433 | #endif | ||
434 | |||
435 | rb->pcm_play_stop(); | ||
436 | rb->pcm_set_frequency(HW_SAMPR_DEFAULT); | ||
437 | |||
438 | #if defined(HAVE_ADJUSTABLE_CPU_FREQ) | ||
439 | rb->cpu_boost(false); | ||
440 | #endif | ||
441 | rb->splash(HZ, "FINISHED PLAYING"); | ||
442 | |||
443 | if (retval == -1) | ||
444 | return PLUGIN_ERROR; | ||
445 | return PLUGIN_OK; | ||
470 | } | 446 | } |
447 | |||