33#define T2MS(ticks) (((double)ticks)*(double)60000L)/((double)tempoToMetronomeTempo(tempo)*(double)tPCN)
35#define MS2T(ms) (((ms)*(double)tempoToMetronomeTempo(tempo)*(double)tPCN)/((double)60000L))
38#define CHANGETEMPO_ONLY_IN_TRACK0
57 printf(
"Track %d : Size %ld\n",
id,size);
62 perror(
"track: Not enough memory ?");
66 if ((rsize=fread(data,1,size,file))!=size)
68 fprintf(stderr,
"track (%d): File is corrupt : Couldn't load track (%ld!=%ld) !!\n",
id, rsize, size);
89int MidiTrack::power2to(
int i)
94ulong MidiTrack::readVariableLengthValue(
void)
98 while ((*ptrdata) & 0x80)
101 if (currentpos>=size)
104 fprintf(stderr,
"track (%d) : EndofTrack found by accident !\n",
id);
105 delta_ticks = wait_ticks = ~0;
106 time_at_next_event=10000 * 60000L;
112 dticks=(dticks << 7) | (*ptrdata) & 0x7F;
113 ptrdata++;currentpos++;
117 dticks=((dticks << 7) | (*ptrdata) & 0x7F);
118 ptrdata++;currentpos++;
122 if (currentpos>=size)
125 fprintf(stderr,
"track (%d): EndofTrack found by accident 2 !\n",
id);
127 delta_ticks = wait_ticks = ~0;
128 time_at_next_event=10000 * 60000L;
133 printfdebug(
"track(%d): DTICKS : %ld\n",
id,dticks);
141 if (endoftrack==1)
return 0;
142 if (ticks>wait_ticks)
144 printfdebug(
"track (%d): ERROR : TICKS PASSED > WAIT TICKS\n",
id);
153 if (endoftrack==1)
return 0;
156 if ( current_time>time_at_next_event )
158 fprintf(stderr,
"track (%d): ERROR : MS PASSED > WAIT MS\n",
id);
162 if (current_time==time_at_next_event) printfdebug(
"track(%d): _OK_",
id);
169 if (endoftrack==1)
return 0;
173 if (current_time>time_at_next_event)
175 fprintf(stderr,
"track(%d): ERROR : MS PASSED > WAIT MS\n",
id);
197 current_time=time_at_next_event;
198 if (((*ptrdata)&0x80)!=0)
201 ptrdata++;currentpos++;
210 if (currentpos>=size)
213 delta_ticks = wait_ticks = ~0;
214 time_at_next_event=10000 * 60000L;
215 ev->
command=MIDI_SYSTEM_PREFIX;
217 ev->
d1=ME_END_OF_TRACK;
218 fprintf(stderr,
"track (%d): EndofTrack found by accident 3\n",
id);
228 ev->
note = *ptrdata;ptrdata++;currentpos++;
229 ev->
vel = *ptrdata;ptrdata++;currentpos++;
237 if (ev->
vel==0) printfdebug(
"Note Onf\n");
238 else printfdebug(
"Note On\n");
242 case (MIDI_NOTEOFF) :
244 if (ev->
chn==6) printfdebug(
"Note Off\n");
246 ev->
note = *ptrdata;ptrdata++;currentpos++;
247 ev->
vel = *ptrdata;ptrdata++;currentpos++;
251 case (MIDI_KEY_PRESSURE) :
253 if (ev->
chn==6) printfdebug (
"Key press\n");
255 ev->
note = *ptrdata;ptrdata++;currentpos++;
256 ev->
vel = *ptrdata;ptrdata++;currentpos++;
258 case (MIDI_PGM_CHANGE) :
260 if (ev->
chn==6) printfdebug (
"Pgm\n");
262 ev->
patch = *ptrdata;ptrdata++;currentpos++;
264 case (MIDI_CHN_PRESSURE) :
266 if (ev->
chn==6) printfdebug (
"Chn press\n");
268 ev->
vel = *ptrdata;ptrdata++;currentpos++;
270 case (MIDI_PITCH_BEND) :
272 if (ev->
chn==6) printfdebug (
"Pitch\n");
274 ev->
d1 = *ptrdata;ptrdata++;currentpos++;
275 ev->
d2 = *ptrdata;ptrdata++;currentpos++;
277 case (MIDI_CTL_CHANGE) :
279 if (ev->
chn==6) printfdebug (stderr,
"Ctl\n");
281 ev->
ctl = *ptrdata;ptrdata++; currentpos++;
282 ev->
d1 = *ptrdata;ptrdata++;currentpos++;
296 case (MIDI_SYSTEM_PREFIX) :
298 if (ev->
chn==6) printfdebug (
"Sys Prefix\n");
304 ev->
length=readVariableLengthValue();
308 ev->
command=MIDI_SYSTEM_PREFIX;
310 ev->
d1=ME_END_OF_TRACK;
324 ev->
d1=*ptrdata;ptrdata++;currentpos++;
327 case (ME_END_OF_TRACK) :
330 while ((i<16)&&(note[i][j]==
false))
333 if (j==128) { j=0; i++; };
337 ptrdata--;currentpos--;
343 fprintf(stderr,
"Note Off(simulated)\n");
349 delta_ticks = wait_ticks = ~0;
350 time_at_next_event=10000 * 60000L;
352 printfdebug(
"EndofTrack %d event\n",
id);
357 ev->
length=readVariableLengthValue();
361 ev->
command=MIDI_SYSTEM_PREFIX;
363 ev->
d1=ME_END_OF_TRACK;
374 printfdebug(
"Track %d : Set Tempo : %ld\n",
id,tempo);
376#ifdef CHANGETEMPO_ONLY_IN_TRACK0
377 if (
id!=0) skip_event=1;
381 case (ME_TIME_SIGNATURE) :
382 ev->
length=*ptrdata;ptrdata++;currentpos++;
383 ev->
d2=*ptrdata;ptrdata++;currentpos++;
384 ev->
d3=power2to(*ptrdata);ptrdata++;currentpos++;
385 ev->
d4=*ptrdata;ptrdata++;currentpos++;
386 ev->
d5=*ptrdata;ptrdata++;currentpos++;
388 printfdebug(
"TIME SIGNATURE :\n");
389 printfdebug(
"%d\n",ev->
d2);
390 printfdebug(
"---- %d metronome , %d number of 32nd notes per quarter note\n",ev->
d4,ev->
d5);
391 printfdebug(
"%d\n",ev->
d3);
394 case (ME_TRACK_SEQ_NUMBER) :
396 case (ME_COPYRIGHT) :
397 case (ME_SEQ_OR_TRACK_NAME) :
398 case (ME_TRACK_INSTR_NAME) :
401 case (ME_CUE_POINT) :
402 case (ME_CHANNEL_PREFIX) :
403 case (ME_MIDI_PORT) :
404 case (ME_SMPTE_OFFSET) :
405 case (ME_KEY_SIGNATURE) :
406 ev->
length=readVariableLengthValue();
410 ev->
command=MIDI_SYSTEM_PREFIX;
412 ev->
d1=ME_END_OF_TRACK;
422#ifdef GENERAL_DEBUG_MESSAGES
423 fprintf(stderr,
"track (%d) : Default handler for meta event " \
424 "0x%x\n",
id, ev->
d1);
426 ev->
length=readVariableLengthValue();
430 ev->
command=MIDI_SYSTEM_PREFIX;
432 ev->
d1=ME_END_OF_TRACK;
444 fprintf(stderr,
"track (%d): Default handler for system event 0x%x\n",
450 fprintf(stderr,
"track (%d): Default handler for event 0x%x\n",
455 if (currentpos>=size)
458 delta_ticks = wait_ticks = ~0;
459 time_at_next_event=10000 * 60000L;
460 printfdebug(
"track (%d): EndofTrack reached\n",
id);
465 current_ticks+=delta_ticks;
466 delta_ticks=readVariableLengthValue();
470 ev->
command=MIDI_SYSTEM_PREFIX;
472 ev->
d1=ME_END_OF_TRACK;
476 ticks_from_previous_tempochange+=delta_ticks;
478 time_at_next_event=T2MS(ticks_from_previous_tempochange)+time_at_previous_tempochange;
484 wait_ticks=delta_ticks;
498 for (
int i=0;i<16;i++)
499 for (
int j=0;j<128;j++)
502 delta_ticks = wait_ticks = ~0;
503 time_at_previous_tempochange=0;
505 ticks_from_previous_tempochange=0;
507 time_at_next_event=10000 * 60000L;
514 if (data==0L) {
clear();
return; };
520 for (
int i=0;i<16;i++)
521 for (
int j=0;j<128;j++)
524 delta_ticks=readVariableLengthValue();
525 if (endoftrack)
return;
526 wait_ticks=delta_ticks;
529 time_at_previous_tempochange=0;
531 ticks_from_previous_tempochange=wait_ticks;
533 time_at_next_event=T2MS(delta_ticks);
539 if (endoftrack==1)
return;
540 if (tempo==t)
return;
542 time_at_previous_tempochange=current_time;
543 ticks=MS2T(time_at_next_event-current_time);
545 time_at_next_event=T2MS(ticks)+current_time;
546 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.