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;
void readEvent(MidiEvent *ev)
Reads the event at the iterator position, and puts it on the structure pointed to by ev.
void clear(void)
Clears the internal variables.
void init(void)
Initializes the iterator.
MidiTrack(FILE *file, int tpcn, int Id)
Constructor.
int currentMs(double ms)
Returns the current millisecond which the iterator is at.
int ticksPassed(ulong ticks)
Makes the iterator advance the given number of ticks.
void changeTempo(ulong t)
Change the tempo of the song.
int msPassed(ulong ms)
Makes the iterator advance the given number of milliseconds.
An structure that represents a MIDI event.
ulong length
Length of the generic data variable.
uchar command
MIDI Command.
uchar ctl
Patch (if command was a controller command)
uchar patch
Patch (if command was a change patch command)
uchar * data
The data for commands like text, sysex, etc.