40 #define T2MS(ticks) (((double)ticks)*(double)60000L)/((double)tempoToMetronomeTempo(tempo)*(double)tPCN)
42 #define MS2T(ms) (((ms)*(double)tempoToMetronomeTempo(tempo)*(double)tPCN)/((double)60000L))
44 #define PEDANTIC_TRACK
45 #define CHANGETEMPO_ONLY_IN_TRACK0
64 printf(
"Track %d : Size %ld\n",
id,size);
69 perror(
"track: Not enough memory ?");
73 if ((rsize=fread(data,1,size,file))!=size)
75 fprintf(stderr,
"track (%d): File is corrupt : Couldn't load track (%ld!=%ld) !!\n",
id, rsize, size);
96 int MidiTrack::power2to(
int i)
101 ulong MidiTrack::readVariableLengthValue(
void)
105 while ((*ptrdata) & 0x80)
107 #ifdef PEDANTIC_TRACK
108 if (currentpos>=size)
111 fprintf(stderr,
"track (%d) : EndofTrack found by accident !\n",
id);
112 delta_ticks = wait_ticks = ~0;
113 time_at_next_event=10000 * 60000L;
119 dticks=(dticks << 7) | (*ptrdata) & 0x7F;
120 ptrdata++;currentpos++;
124 dticks=((dticks << 7) | (*ptrdata) & 0x7F);
125 ptrdata++;currentpos++;
127 #ifdef PEDANTIC_TRACK
129 if (currentpos>=size)
132 fprintf(stderr,
"track (%d): EndofTrack found by accident 2 !\n",
id);
134 delta_ticks = wait_ticks = ~0;
135 time_at_next_event=10000 * 60000L;
140 printfdebug(
"track(%d): DTICKS : %ld\n",
id,dticks);
148 if (endoftrack==1)
return 0;
149 if (ticks>wait_ticks)
151 printfdebug(
"track (%d): ERROR : TICKS PASSED > WAIT TICKS\n",
id);
160 if (endoftrack==1)
return 0;
163 if ( current_time>time_at_next_event )
165 fprintf(stderr,
"track (%d): ERROR : MS PASSED > WAIT MS\n",
id);
169 if (current_time==time_at_next_event) printfdebug(
"track(%d): _OK_",
id);
176 if (endoftrack==1)
return 0;
179 #ifdef PEDANTIC_TRACK
180 if (current_time>time_at_next_event)
182 fprintf(stderr,
"track(%d): ERROR : MS PASSED > WAIT MS\n",
id);
204 current_time=time_at_next_event;
205 if (((*ptrdata)&0x80)!=0)
208 ptrdata++;currentpos++;
216 #ifdef PEDANTIC_TRACK
217 if (currentpos>=size)
220 delta_ticks = wait_ticks = ~0;
221 time_at_next_event=10000 * 60000L;
222 ev->
command=MIDI_SYSTEM_PREFIX;
224 ev->
d1=ME_END_OF_TRACK;
225 fprintf(stderr,
"track (%d): EndofTrack found by accident 3\n",
id);
235 ev->
note = *ptrdata;ptrdata++;currentpos++;
236 ev->
vel = *ptrdata;ptrdata++;currentpos++;
244 if (ev->
vel==0) printfdebug(
"Note Onf\n");
245 else printfdebug(
"Note On\n");
249 case (MIDI_NOTEOFF) :
251 if (ev->
chn==6) printfdebug(
"Note Off\n");
253 ev->
note = *ptrdata;ptrdata++;currentpos++;
254 ev->
vel = *ptrdata;ptrdata++;currentpos++;
258 case (MIDI_KEY_PRESSURE) :
260 if (ev->
chn==6) printfdebug (
"Key press\n");
262 ev->
note = *ptrdata;ptrdata++;currentpos++;
263 ev->
vel = *ptrdata;ptrdata++;currentpos++;
265 case (MIDI_PGM_CHANGE) :
267 if (ev->
chn==6) printfdebug (
"Pgm\n");
269 ev->
patch = *ptrdata;ptrdata++;currentpos++;
271 case (MIDI_CHN_PRESSURE) :
273 if (ev->
chn==6) printfdebug (
"Chn press\n");
275 ev->
vel = *ptrdata;ptrdata++;currentpos++;
277 case (MIDI_PITCH_BEND) :
279 if (ev->
chn==6) printfdebug (
"Pitch\n");
281 ev->
d1 = *ptrdata;ptrdata++;currentpos++;
282 ev->
d2 = *ptrdata;ptrdata++;currentpos++;
284 case (MIDI_CTL_CHANGE) :
286 if (ev->
chn==6) printfdebug (stderr,
"Ctl\n");
288 ev->
ctl = *ptrdata;ptrdata++; currentpos++;
289 ev->
d1 = *ptrdata;ptrdata++;currentpos++;
303 case (MIDI_SYSTEM_PREFIX) :
305 if (ev->
chn==6) printfdebug (
"Sys Prefix\n");
311 ev->
length=readVariableLengthValue();
312 #ifdef PEDANTIC_TRACK
315 ev->
command=MIDI_SYSTEM_PREFIX;
317 ev->
d1=ME_END_OF_TRACK;
331 ev->
d1=*ptrdata;ptrdata++;currentpos++;
334 case (ME_END_OF_TRACK) :
337 while ((i<16)&&(note[i][j]==FALSE))
340 if (j==128) { j=0; i++; };
344 ptrdata--;currentpos--;
350 fprintf(stderr,
"Note Off(simulated)\n");
356 delta_ticks = wait_ticks = ~0;
357 time_at_next_event=10000 * 60000L;
359 printfdebug(
"EndofTrack %d event\n",
id);
364 ev->
length=readVariableLengthValue();
365 #ifdef PEDANTIC_TRACK
368 ev->
command=MIDI_SYSTEM_PREFIX;
370 ev->
d1=ME_END_OF_TRACK;
381 printfdebug(
"Track %d : Set Tempo : %ld\n",
id,tempo);
383 #ifdef CHANGETEMPO_ONLY_IN_TRACK0
384 if (
id!=0) skip_event=1;
388 case (ME_TIME_SIGNATURE) :
389 ev->
length=*ptrdata;ptrdata++;currentpos++;
390 ev->
d2=*ptrdata;ptrdata++;currentpos++;
391 ev->
d3=power2to(*ptrdata);ptrdata++;currentpos++;
392 ev->
d4=*ptrdata;ptrdata++;currentpos++;
393 ev->
d5=*ptrdata;ptrdata++;currentpos++;
395 printfdebug(
"TIME SIGNATURE :\n");
396 printfdebug(
"%d\n",ev->
d2);
397 printfdebug(
"---- %d metronome , %d number of 32nd notes per quarter note\n",ev->
d4,ev->
d5);
398 printfdebug(
"%d\n",ev->
d3);
401 case (ME_TRACK_SEQ_NUMBER) :
403 case (ME_COPYRIGHT) :
404 case (ME_SEQ_OR_TRACK_NAME) :
405 case (ME_TRACK_INSTR_NAME) :
408 case (ME_CUE_POINT) :
409 case (ME_CHANNEL_PREFIX) :
410 case (ME_MIDI_PORT) :
411 case (ME_SMPTE_OFFSET) :
412 case (ME_KEY_SIGNATURE) :
413 ev->
length=readVariableLengthValue();
414 #ifdef PEDANTIC_TRACK
417 ev->
command=MIDI_SYSTEM_PREFIX;
419 ev->
d1=ME_END_OF_TRACK;
429 #ifdef GENERAL_DEBUG_MESSAGES
430 fprintf(stderr,
"track (%d) : Default handler for meta event " \
431 "0x%x\n",
id, ev->
d1);
433 ev->
length=readVariableLengthValue();
434 #ifdef PEDANTIC_TRACK
437 ev->
command=MIDI_SYSTEM_PREFIX;
439 ev->
d1=ME_END_OF_TRACK;
451 fprintf(stderr,
"track (%d): Default handler for system event 0x%x\n",
457 fprintf(stderr,
"track (%d): Default handler for event 0x%x\n",
461 #ifdef PEDANTIC_TRACK
462 if (currentpos>=size)
465 delta_ticks = wait_ticks = ~0;
466 time_at_next_event=10000 * 60000L;
467 printfdebug(
"track (%d): EndofTrack reached\n",
id);
472 current_ticks+=delta_ticks;
473 delta_ticks=readVariableLengthValue();
474 #ifdef PEDANTIC_TRACK
477 ev->
command=MIDI_SYSTEM_PREFIX;
479 ev->
d1=ME_END_OF_TRACK;
483 ticks_from_previous_tempochange+=delta_ticks;
485 time_at_next_event=T2MS(ticks_from_previous_tempochange)+time_at_previous_tempochange;
491 wait_ticks=delta_ticks;
505 for (
int i=0;i<16;i++)
506 for (
int j=0;j<128;j++)
509 delta_ticks = wait_ticks = ~0;
510 time_at_previous_tempochange=0;
512 ticks_from_previous_tempochange=0;
514 time_at_next_event=10000 * 60000L;
521 if (data==0L) {
clear();
return; };
527 for (
int i=0;i<16;i++)
528 for (
int j=0;j<128;j++)
531 delta_ticks=readVariableLengthValue();
532 if (endoftrack)
return;
533 wait_ticks=delta_ticks;
536 time_at_previous_tempochange=0;
538 ticks_from_previous_tempochange=wait_ticks;
540 time_at_next_event=T2MS(delta_ticks);
546 if (endoftrack==1)
return;
547 if (tempo==t)
return;
549 time_at_previous_tempochange=current_time;
550 ticks=MS2T(time_at_next_event-current_time);
552 time_at_next_event=T2MS(ticks)+current_time;
553 ticks_from_previous_tempochange=ticks;
uchar patch
Patch (if command was a change patch command)
uchar command
MIDI Command.
void readEvent(MidiEvent *ev)
Reads the event at the iterator position, and puts it on the structure pointed to by ev...
ulong length
Length of the generic data variable.
An structure that represents a MIDI event.
void clear(void)
Clears the internal variables.
void changeTempo(ulong t)
Change the tempo of the song.
int ticksPassed(ulong ticks)
Makes the iterator advance the given number of ticks.
MidiTrack(FILE *file, int tpcn, int Id)
Constructor.
void init(void)
Initializes the iterator.
uchar * data
The data for commands like text, sysex, etc.
int currentMs(double ms)
Returns the current millisecond which the iterator is at.
uchar ctl
Patch (if command was a controller command)
int msPassed(ulong ms)
Makes the iterator advance the given number of milliseconds.