summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2009-03-28 11:27:56 +0000
committerNils Wallménius <nils@rockbox.org>2009-03-28 11:27:56 +0000
commit1adc869d9ca7b0dcc173e607976fddcde34f3e3a (patch)
tree44897421e4544916af394a651e820e618c97a8b5
parent24ae50699d0b467497c4584945917720347550db (diff)
downloadrockbox-1adc869d9ca7b0dcc173e607976fddcde34f3e3a.tar.gz
rockbox-1adc869d9ca7b0dcc173e607976fddcde34f3e3a.zip
midi: yield more, fixes flickering backlight fade on some targets while playing midi. Some coding style clean up, it's a little better but still a mess
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20562 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/midi/midiplay.c313
-rw-r--r--apps/plugins/midi/midiutil.h10
-rw-r--r--apps/plugins/midi/sequencer.c225
3 files changed, 258 insertions, 290 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
29PLUGIN_IRAM_DECLARE 29PLUGIN_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
210struct MIDIfile * mf IBSS_ATTR; 193struct MIDIfile * mf IBSS_ATTR;
211 194
212int numberOfSamples IBSS_ATTR; /* the number of samples in the current tick */ 195int number_of_samples IBSS_ATTR; /* the number of samples in the current tick */
213int playingTime IBSS_ATTR; /* How many seconds into the file have we been playing? */ 196int playing_time IBSS_ATTR; /* How many seconds into the file have we been playing? */
214int samplesThisSecond IBSS_ATTR; /* How many samples produced during this second so far? */ 197int samples_this_second IBSS_ATTR; /* How many samples produced during this second so far? */
215
216long bpm IBSS_ATTR; 198long bpm IBSS_ATTR;
217 199
218int32_t gmbuf[BUF_SIZE*NBUF]; 200int32_t gmbuf[BUF_SIZE*NBUF];
219static unsigned int samples_in_buf; 201static unsigned int samples_in_buf;
220 202
221int quit=0; 203bool quit = false;
222 204bool swap = false;
223static int midimain(const void * filename); 205bool lastswap = true;
224
225enum 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
269bool swap=0;
270bool lastswap=1;
271 206
272static inline void synthbuf(void) 207static 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
300void get_more(unsigned char** start, size_t* size) 240void 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
321static int midimain(const void * filename) 261static 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
406enum 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
diff --git a/apps/plugins/midi/midiutil.h b/apps/plugins/midi/midiutil.h
index 4b1afa2928..ba64a00e28 100644
--- a/apps/plugins/midi/midiutil.h
+++ b/apps/plugins/midi/midiutil.h
@@ -32,8 +32,10 @@
32#define SAMPLE_RATE SAMPR_44 /* 44100 */ 32#define SAMPLE_RATE SAMPR_44 /* 44100 */
33#endif 33#endif
34 34
35#ifdef CPU_PP /* the pp based targets can't handle too many voices 35/* Some of the pp based targets can't handle too many voices
36 mainly because they have to use 44100Hz sample rate */ 36 mainly because they have to use 44100Hz sample rate, this could be
37 improved to increase MAX_VOICES for targets that can do 22kHz */
38#ifdef CPU_PP
37#define MAX_VOICES 16 39#define MAX_VOICES 16
38#else 40#else
39#define MAX_VOICES 24 /* Note: 24 midi channels is the minimum general midi spec implementation */ 41#define MAX_VOICES 24 /* Note: 24 midi channels is the minimum general midi spec implementation */
@@ -166,6 +168,8 @@ extern struct GPatch * drumSet[128];
166 168
167extern struct MIDIfile * mf; 169extern struct MIDIfile * mf;
168 170
169extern int numberOfSamples; 171extern int number_of_samples;
172extern int playing_time IBSS_ATTR;
173extern int samples_this_second IBSS_ATTR;
170extern long bpm; 174extern long bpm;
171 175
diff --git a/apps/plugins/midi/sequencer.c b/apps/plugins/midi/sequencer.c
index 11dd0e3f96..f97cac0130 100644
--- a/apps/plugins/midi/sequencer.c
+++ b/apps/plugins/midi/sequencer.c
@@ -23,10 +23,7 @@
23#include "guspat.h" 23#include "guspat.h"
24#include "synth.h" 24#include "synth.h"
25 25
26extern int playingTime IBSS_ATTR; 26long tempo = 375000;
27extern int samplesThisSecond IBSS_ATTR;
28
29long tempo=375000;
30 27
31/* From the old patch config.... each patch is scaled. 28/* From the old patch config.... each patch is scaled.
32 * Should be moved into patchset.cfg 29 * Should be moved into patchset.cfg
@@ -62,13 +59,13 @@ static inline void setVolScale(int a)
62 59
63static inline void setVol(int ch, int vol) 60static inline void setVol(int ch, int vol)
64{ 61{
65 int a=0; 62 int a;
66 chVol[ch]=vol; 63 chVol[ch] = vol;
67 64
68 /* If channel volume changes, we need to recalculate the volume scale */ 65 /* If channel volume changes, we need to recalculate the volume scale */
69 /* factor for all voices active on this channel */ 66 /* factor for all voices active on this channel */
70 for(a=0; a<MAX_VOICES; a++) 67 for (a = 0; a < MAX_VOICES; a++)
71 if(voices[a].ch == ch) 68 if (voices[a].ch == ch)
72 setVolScale(a); 69 setVolScale(a);
73} 70}
74 71
@@ -77,8 +74,6 @@ static inline void setPatch(int ch, int pat)
77 chPat[ch]=pat; 74 chPat[ch]=pat;
78} 75}
79 76
80
81
82/* 77/*
83 This is the new pitch bend table. There are 512 entries. 78 This is the new pitch bend table. There are 512 entries.
84 The middle entry is exactly 65536 - no bending. 79 The middle entry is exactly 65536 - no bending.
@@ -143,11 +138,12 @@ const uint32_t pitchTbl[] ICONST_ATTR={
143 138
144static void findDelta(struct SynthObject * so, int ch, int note) 139static void findDelta(struct SynthObject * so, int ch, int note)
145{ 140{
146 struct GWaveform * wf = patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]]; 141 struct GWaveform * wf =
147 so->wf=wf; 142 patchSet[chPat[ch]]->waveforms[patchSet[chPat[ch]]->noteTable[note]];
143 so->wf = wf;
148 144
149 /* Used to be unsigned int, but math had to be done in different order to avoid overflow */ 145 /* Used to be unsigned int, but math had to be done in different order to avoid overflow */
150 unsigned long long delta= 0; 146 unsigned long long delta = 0;
151 147
152/* 148/*
153 Old formula: 149 Old formula:
@@ -169,10 +165,10 @@ static void findDelta(struct SynthObject * so, int ch, int note)
169 165
170static inline void computeDeltas(int ch) 166static inline void computeDeltas(int ch)
171{ 167{
172 int a=0; 168 int a;
173 for(a = 0; a<MAX_VOICES; a++) 169 for (a = 0; a < MAX_VOICES; a++)
174 { 170 {
175 if(voices[a].isUsed && voices[a].ch == ch) 171 if (voices[a].isUsed && voices[a].ch == ch)
176 { 172 {
177 findDelta(&voices[a], ch, voices[a].note); 173 findDelta(&voices[a], ch, voices[a].note);
178 } 174 }
@@ -212,16 +208,16 @@ inline void pressNote(int ch, int note, int vol)
212 if(ch == 14) return; 208 if(ch == 14) return;
213 if(ch == 15) return; 209 if(ch == 15) return;
214*/ 210*/
215 int a=0; 211 int a;
216 for(a=0; a<MAX_VOICES; a++) 212 for (a = 0; a < MAX_VOICES; a++)
217 { 213 {
218 if(voices[a].ch == ch && voices[a].note == note) 214 if (voices[a].ch == ch && voices[a].note == note)
219 break; 215 break;
220 216
221 if(!voices[a].isUsed) 217 if (!voices[a].isUsed)
222 break; 218 break;
223 } 219 }
224 if(a==MAX_VOICES) 220 if (a == MAX_VOICES)
225 { 221 {
226// printf("\nVoice kill"); 222// printf("\nVoice kill");
227// printf("\nToo many voices playing at once. No more left"); 223// printf("\nToo many voices playing at once. No more left");
@@ -229,17 +225,17 @@ inline void pressNote(int ch, int note, int vol)
229// for(a=0; a<48; a++) 225// for(a=0; a<48; a++)
230// printf("\n#%d Ch=%d Note=%d curRate=%d curOffset=%d curPoint=%d targetOffset=%d", a, voices[a].ch, voices[a].note, voices[a].curRate, voices[a].curOffset, voices[a].curPoint, voices[a].targetOffset); 226// printf("\n#%d Ch=%d Note=%d curRate=%d curOffset=%d curPoint=%d targetOffset=%d", a, voices[a].ch, voices[a].note, voices[a].curRate, voices[a].curOffset, voices[a].curPoint, voices[a].targetOffset);
231 lastKill++; 227 lastKill++;
232 if(lastKill == MAX_VOICES) 228 if (lastKill == MAX_VOICES)
233 lastKill = 0; 229 lastKill = 0;
234 a = lastKill; 230 a = lastKill;
235// return; /* None available */ 231// return; /* None available */
236 } 232 }
237 voices[a].ch=ch; 233 voices[a].ch = ch;
238 voices[a].note=note; 234 voices[a].note = note;
239 voices[a].vol=vol; 235 voices[a].vol = vol;
240 voices[a].cp=0; 236 voices[a].cp = 0;
241 voices[a].state=STATE_ATTACK; 237 voices[a].state = STATE_ATTACK;
242 voices[a].decay=255; 238 voices[a].decay = 255;
243 239
244 setVolScale(a); 240 setVolScale(a);
245 241
@@ -251,28 +247,28 @@ inline void pressNote(int ch, int note, int vol)
251 * sr = WAVE sampling rate 247 * sr = WAVE sampling rate
252 */ 248 */
253 249
254 if(ch!=9) 250 if (ch != 9)
255 { 251 {
256 findDelta(&voices[a], ch, note); 252 findDelta(&voices[a], ch, note);
257 /* Turn it on */ 253 /* Turn it on */
258 voices[a].isUsed=true; 254 voices[a].isUsed = true;
259 setPoint(&voices[a], 0); 255 setPoint(&voices[a], 0);
260 } else 256 } else
261 { 257 {
262 if(drumSet[note]!=NULL) 258 if (drumSet[note] != NULL)
263 { 259 {
264 if(note<35) 260 if (note < 35)
265 printf("NOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?"); 261 printf("NOTE LESS THAN 35, AND A DRUM PATCH EXISTS FOR THIS? WHAT THE HELL?");
266 262
267 struct GWaveform * wf = drumSet[note]->waveforms[0]; 263 struct GWaveform * wf = drumSet[note]->waveforms[0];
268 voices[a].wf=wf; 264 voices[a].wf = wf;
269 voices[a].delta = (((gustable[note]<<FRACTSIZE) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE); 265 voices[a].delta = (((gustable[note]<<FRACTSIZE) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE);
270 if(wf->mode & 28) 266 if (wf->mode & 28)
271// printf("\nWoah, a drum patch has a loop. Stripping the loop..."); 267// printf("\nWoah, a drum patch has a loop. Stripping the loop...");
272 wf->mode = wf->mode & (255-28); 268 wf->mode = wf->mode & (255-28);
273 269
274 /* Turn it on */ 270 /* Turn it on */
275 voices[a].isUsed=true; 271 voices[a].isUsed = true;
276 setPoint(&voices[a], 0); 272 setPoint(&voices[a], 0);
277 273
278 } else 274 } else
@@ -284,16 +280,15 @@ inline void pressNote(int ch, int note, int vol)
284 280
285static void releaseNote(int ch, int note) 281static void releaseNote(int ch, int note)
286{ 282{
287 283 if (ch == 9)
288 if(ch==9)
289 return; 284 return;
290 285
291 int a=0; 286 int a;
292 for(a=0; a<MAX_VOICES; a++) 287 for (a = 0; a < MAX_VOICES; a++)
293 { 288 {
294 if(voices[a].ch == ch && voices[a].note == note) 289 if (voices[a].ch == ch && voices[a].note == note)
295 { 290 {
296 if((voices[a].wf->mode & 28)) 291 if (voices[a].wf->mode & 28)
297 { 292 {
298 setPoint(&voices[a], 3); 293 setPoint(&voices[a], 3);
299 } 294 }
@@ -306,10 +301,10 @@ static void sendEvent(struct Event * ev)
306 const unsigned char status_low = ev->status & 0x0F; 301 const unsigned char status_low = ev->status & 0x0F;
307 const unsigned char d1 = ev->d1; 302 const unsigned char d1 = ev->d1;
308 const unsigned char d2 = ev->d2; 303 const unsigned char d2 = ev->d2;
309 switch(ev->status & 0xF0) 304 switch (ev->status & 0xF0)
310 { 305 {
311 case MIDI_CONTROL: 306 case MIDI_CONTROL:
312 switch(d1) 307 switch (d1)
313 { 308 {
314 case CTRL_VOLUME: 309 case CTRL_VOLUME:
315 { 310 {
@@ -318,7 +313,7 @@ static void sendEvent(struct Event * ev)
318 } 313 }
319 case CTRL_PANNING: 314 case CTRL_PANNING:
320 { 315 {
321 chPan[status_low]=d2; 316 chPan[status_low] = d2;
322 return; 317 return;
323 } 318 }
324 case CTRL_DATAENT_MSB: 319 case CTRL_DATAENT_MSB:
@@ -365,7 +360,7 @@ static void sendEvent(struct Event * ev)
365 return; 360 return;
366 361
367 case MIDI_NOTE_ON: 362 case MIDI_NOTE_ON:
368 switch(d2) 363 switch (d2)
369 { 364 {
370 case 0: /* Release by vol=0 */ 365 case 0: /* Release by vol=0 */
371 releaseNote(status_low, d1); 366 releaseNote(status_low, d1);
@@ -381,139 +376,131 @@ static void sendEvent(struct Event * ev)
381 return; 376 return;
382 377
383 case MIDI_PRGM: 378 case MIDI_PRGM:
384 if((status_low) != 9) 379 if (status_low != 9)
385 setPatch(status_low, d1); 380 setPatch(status_low, d1);
386 } 381 }
387} 382}
388 383
389void rewindFile(void) 384void rewindFile(void)
390{ 385{
391 int i=0; 386 int i;
392 for(i=0; i<mf->numTracks; i++) 387 for (i = 0; i < mf->numTracks; i++)
393 { 388 {
394 mf->tracks[i]->delta = 0; 389 mf->tracks[i]->delta = 0;
395 mf->tracks[i]->pos = 0; 390 mf->tracks[i]->pos = 0;
396 } 391 }
397} 392}
398 393
399
400int tick(void) ICODE_ATTR; 394int tick(void) ICODE_ATTR;
401
402void seekBackward(int nsec)
403{
404 int notesUsed = 0, a=0;
405 int desiredTime = playingTime - nsec; /* Rewind 5 sec */
406
407 if(desiredTime < 0)
408 desiredTime = 0;
409
410 /* Set controllers to default values */
411 resetControllers();
412
413 /* Set the tempo to defalt */
414 bpm=mf->div*1000000/tempo;
415 numberOfSamples=SAMPLE_RATE/bpm;
416
417
418 /* Reset the tracks to start */
419 rewindFile();
420
421 /* Reset the time counter to 0 */
422 playingTime = 0;
423 samplesThisSecond = 0;
424
425 /* Quickly run through any initial things that occur before notes */
426 do
427 {
428 notesUsed = 0;
429 for(a=0; a<MAX_VOICES; a++)
430 if(voices[a].isUsed)
431 notesUsed++;
432 tick();
433 } while(notesUsed == 0);
434
435 /* Reset the time counter to 0 */
436 playingTime = 0;
437 samplesThisSecond = 0;
438
439 /* Tick until goal is reached */
440 while(playingTime < desiredTime)
441 tick();
442}
443
444
445void seekForward(int nsec)
446{
447 int desiredTime = playingTime + nsec;
448 while(tick() && playingTime < desiredTime);
449}
450
451int tick(void) 395int tick(void)
452{ 396{
453 if(mf==NULL) 397 if (mf == NULL)
454 return 0; 398 return 0;
455 399
456 int a=0; 400 int a, tracksAdv=0;
457 int tracksAdv=0; 401 for (a = 0; a < mf->numTracks; a++)
458 for(a=0; a<mf->numTracks; a++)
459 { 402 {
460 struct Track * tr = mf->tracks[a]; 403 struct Track * tr = mf->tracks[a];
461 404
462 if(tr == NULL) 405 if (tr == NULL)
463 printf("NULL TRACK: %d", a); 406 printf("NULL TRACK: %d", a);
464 407
465
466 //BIG DEBUG STATEMENT 408 //BIG DEBUG STATEMENT
467 //printf("\nTrack %2d, Event = %4d of %4d, Delta = %5d, Next = %4d", a, tr->pos, tr->numEvents, tr->delta, getEvent(tr, tr->pos)->delta); 409 //printf("\nTrack %2d, Event = %4d of %4d, Delta = %5d, Next = %4d", a, tr->pos, tr->numEvents, tr->delta, getEvent(tr, tr->pos)->delta);
468 410
469 411 if (tr != NULL && (tr->pos < tr->numEvents))
470 if(tr != NULL && (tr->pos < tr->numEvents))
471 { 412 {
472 tr->delta++; 413 tr->delta++;
473 tracksAdv++; 414 tracksAdv++;
474 while(getEvent(tr, tr->pos)->delta <= tr->delta) 415 while (getEvent(tr, tr->pos)->delta <= tr->delta)
475 { 416 {
476 struct Event * e = getEvent(tr, tr->pos); 417 struct Event * e = getEvent(tr, tr->pos);
477 418
478 if(e->status != 0xFF) 419 if (e->status != 0xFF)
479 { 420 {
480 sendEvent(e); 421 sendEvent(e);
481 if(((e->status&0xF0) == MIDI_PRGM)) 422 if ((e->status&0xF0) == MIDI_PRGM)
482 { 423 {
483/* printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1); */ 424/* printf("\nPatch Event, patch[%d] ==> %d", e->status&0xF, e->d1); */
484 } 425 }
485 } 426 }
486 else 427 else
487 { 428 {
488 if(e->d1 == 0x51) 429 if (e->d1 == 0x51)
489 { 430 {
490 tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]); 431 tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]);
491/* printf("\nMeta-Event: Tempo Set = %d", tempo); */ 432/* printf("\nMeta-Event: Tempo Set = %d", tempo); */
492 bpm=mf->div*1000000/tempo; 433 bpm=mf->div*1000000/tempo;
493 numberOfSamples=SAMPLE_RATE/bpm; 434 number_of_samples=SAMPLE_RATE/bpm;
494 435
495 } 436 }
496 } 437 }
497 tr->delta = 0; 438 tr->delta = 0;
498 tr->pos++; 439 tr->pos++;
499 if(tr->pos>=(tr->numEvents-1)) 440 if (tr->pos >= (tr->numEvents-1))
500 break; 441 break;
501 } 442 }
502 } 443 }
503 } 444 }
504 445
505 samplesThisSecond += numberOfSamples; 446 samples_this_second += number_of_samples;
506 447
507 while(samplesThisSecond >= SAMPLE_RATE) 448 while (samples_this_second >= SAMPLE_RATE)
508 { 449 {
509 samplesThisSecond -= SAMPLE_RATE; 450 samples_this_second -= SAMPLE_RATE;
510 playingTime++; 451 playing_time++;
511// printf("Time: %d sec\n", playingTime);
512 } 452 }
513 453
514 if(tracksAdv != 0) 454 if (tracksAdv != 0)
515 return 1; 455 return 1;
516 else 456 else
517 return 0; 457 return 0;
518} 458}
519 459
460void seekBackward(int nsec)
461{
462 int notes_used, a;
463 int desired_time = playing_time - nsec; /* Rewind 5 sec */
464
465 if (desired_time < 0)
466 desired_time = 0;
467
468 /* Set controllers to default values */
469 resetControllers();
470
471 /* Set the tempo to defalt */
472 bpm = mf->div*1000000/tempo;
473 number_of_samples = SAMPLE_RATE/bpm;
474
475 /* Reset the tracks to start */
476 rewindFile();
477
478 /* Reset the time counter to 0 */
479 playing_time = 0;
480 samples_this_second = 0;
481
482 /* Quickly run through any initial things that occur before notes */
483 do
484 {
485 notes_used = 0;
486 for (a = 0; a < MAX_VOICES; a++)
487 if (voices[a].isUsed)
488 notes_used++;
489 tick();
490 } while (notes_used == 0);
491
492 /* Reset the time counter to 0 */
493 playing_time = 0;
494 samples_this_second = 0;
495
496 /* Tick until goal is reached */
497 while (playing_time < desired_time)
498 tick();
499}
500
501void seekForward(int nsec)
502{
503 int desired_time = playing_time + nsec;
504 while (tick() && playing_time < desired_time);
505}
506