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)) 37 #define PEDANTIC_TRACK 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);
89 int MidiTrack::power2to(
int i)
94 ulong MidiTrack::readVariableLengthValue(
void)
98 while ((*ptrdata) & 0x80)
100 #ifdef PEDANTIC_TRACK 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++;
120 #ifdef PEDANTIC_TRACK 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;
172 #ifdef PEDANTIC_TRACK 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++;
209 #ifdef PEDANTIC_TRACK 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();
305 #ifdef PEDANTIC_TRACK 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();
358 #ifdef PEDANTIC_TRACK 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();
407 #ifdef PEDANTIC_TRACK 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();
427 #ifdef PEDANTIC_TRACK 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",
454 #ifdef PEDANTIC_TRACK 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();
467 #ifdef PEDANTIC_TRACK 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;
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.