diff options
Diffstat (limited to 'apps/plugins/midi/sequencer.c')
-rw-r--r-- | apps/plugins/midi/sequencer.c | 225 |
1 files changed, 106 insertions, 119 deletions
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 | ||
26 | extern int playingTime IBSS_ATTR; | 26 | long tempo = 375000; |
27 | extern int samplesThisSecond IBSS_ATTR; | ||
28 | |||
29 | long 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 | ||
63 | static inline void setVol(int ch, int vol) | 60 | static 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 | ||
144 | static void findDelta(struct SynthObject * so, int ch, int note) | 139 | static 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 | ||
170 | static inline void computeDeltas(int ch) | 166 | static 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 | ||
285 | static void releaseNote(int ch, int note) | 281 | static 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 | ||
389 | void rewindFile(void) | 384 | void 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 | |||
400 | int tick(void) ICODE_ATTR; | 394 | int tick(void) ICODE_ATTR; |
401 | |||
402 | void 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 | |||
445 | void seekForward(int nsec) | ||
446 | { | ||
447 | int desiredTime = playingTime + nsec; | ||
448 | while(tick() && playingTime < desiredTime); | ||
449 | } | ||
450 | |||
451 | int tick(void) | 395 | int 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 | ||
460 | void 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 | |||
501 | void seekForward(int nsec) | ||
502 | { | ||
503 | int desired_time = playing_time + nsec; | ||
504 | while (tick() && playing_time < desired_time); | ||
505 | } | ||
506 | |||