37 #include <tdeprocess.h>
40 int fsearch(FILE *fh,
const char *text,
long *ptr);
44 double tempoToMetronomeTempo(ulong x)
46 return 60/((double)x/1000000);
49 double metronomeTempoToTempo(ulong x)
51 return ((
double)60*x)/1000000;
54 int uncompressFile(
const char *gzname,
char *tmpname)
58 FILE *infile = popen( TQFile::encodeName(cmd).data(),
"r");
60 fprintf(stderr,
"ERROR : popen failed : %s\n",TQFile::encodeName(cmd).data());
63 strcpy(tmpname,
"/tmp/KMid.XXXXXXXXXX");
64 int fd = mkstemp(tmpname);
70 FILE *outfile= fdopen(fd,
"wb");
86 n = fread(buf, 1, BUFSIZ, infile);
89 fwrite(buf, 1, n, outfile);
90 n = fread(buf, 1, BUFSIZ, infile);
108 if (stat(name,&buf) || !S_ISREG(buf.st_mode))
110 fprintf(stderr,
"ERROR: %s is not a regular file\n",name);
115 FILE *fh=fopen(name,
"rb");
118 fprintf(stderr,
"ERROR: Can't open file %s\n",name);
125 if ((strncmp(text,
"MThd",4)!=0)&&(strcmp(&name[strlen(name)-3],
".gz")==0))
129 fprintf(stderr,
"Trying to open zipped midi file...\n");
130 if (uncompressFile(name,tempname)!=0)
132 fprintf(stderr,
"ERROR: %s is not a (zipped) midi file\n",name);
136 fh=fopen(tempname,
"rb");
141 if (strncmp(text,
"MThd",4)!=0)
143 fseek(fh,0,SEEK_SET);
145 if (fsearch(fh,
"MThd",&pos)==0)
148 fprintf(stderr,
"ERROR: %s is not a midi file.\n",name);
152 fseek(fh,pos,SEEK_SET);
155 long header_size=readLong(fh);
156 info->
format=readShort(fh);
161 fprintf(stderr,
"ERROR: Ticks per cuarter note is negative !\n");
162 fprintf(stderr,
"Please report this error to : larrosa@kde.org\n");
167 if (header_size>6) fseek(fh,header_size-6,SEEK_CUR);
171 fprintf(stderr,
"ERROR: Not enough memory\n");
177 while (i<info->ntracks)
180 if (strncmp(text,
"MTrk",4)!=0)
182 fprintf(stderr,
"ERROR: Not a well built midi file\n");
183 fprintf(stderr,
"%s",text);
191 fprintf(stderr,
"ERROR: Not enough memory");
219 ulong tempo=(ulong)(500000 * ratioTempo);
222 printf(
"Parsing 1 ...\n");
225 int pgminchannel[16];
246 maxTime=minTime + 2 * 60000L;
248 while (trk<info->ntracks)
250 if (tracks[trk]->absMsOfNextEvent()<minTime)
257 if ((minTime==maxTime))
261 printf(
"END of parsing\n");
267 while (trk<info->ntracks)
279 if (ev->
chn!=PERCUSSION_CHANNEL)
284 case (MIDI_PGM_CHANGE) :
287 case (MIDI_SYSTEM_PREFIX) :
288 if (((ev->
command|ev->
chn)==META_EVENT)&&(ev->
d1==ME_SET_TEMPO))
290 tempo=(ulong)(((ev->
data[0]<<16)|(ev->
data[1]<<8)|(ev->
data[2])) * ratioTempo);
309 printf(
"info.ticksTotal = %ld \n",info->
ticksTotal);
310 printf(
"info.ticksPlayed= %ld \n",info->ticksPlayed);
330 printf(
"Parsing for patches ...\n");
343 int pgminchannel[16];
354 maxTime=minTime + 2 * 60000L;
356 while (trk<info->ntracks)
358 if (tracks[trk]->absMsOfNextEvent()<minTime)
365 if ((minTime==maxTime))
369 printf(
"END of parsing for patches\n");
375 while (trk<info->ntracks)
386 if (ev->
chn!=PERCUSSION_CHANNEL)
391 case (MIDI_PGM_CHANGE) :
392 pgminchannel[ev->
chn]=(gm==1)?(ev->
patch):(MT32toGM[ev->
patch]);
394 case (MIDI_SYSTEM_PREFIX) :
395 if (((ev->
command|ev->
chn)==META_EVENT)&&(ev->
d1==ME_SET_TEMPO))
397 if (tempoToMetronomeTempo(tmp=((ev->
data[0]<<16)|(ev->
data[1]<<8)|(ev->
data[2])))>=8)
420 int fsearch(FILE *fh,
const char *text,
long *ptr)
426 if ((text==NULL)||(text[0]==0))
return 0;
435 k=fread(buf,1,1024,fh);
442 r=strncmp(text,&buf[i],l);
445 fseek(fh,pos+i,SEEK_SET);
446 if (fread(tmp,1,l,fh)<(uint)l)
return 0;
447 fseek(fh,pos+k,SEEK_SET);
448 r=strncmp(text,tmp,l);
452 if (ptr!=NULL) *ptr=pos+i;
void readEvent(MidiEvent *ev)
Reads the event at the iterator position, and puts it on the structure pointed to by ev.
void init(void)
Initializes the iterator.
int currentMs(double ms)
Returns the current millisecond which the iterator is at.
void changeTempo(ulong t)
Change the tempo of the song.
double absMsOfNextEvent(void)
Returns the absolute number of milliseconds of the next event.
static TQString quote(const TQString &arg)
An structure that represents a MIDI event.
uchar command
MIDI Command.
uchar patch
Patch (if command was a change patch command)
uchar * data
The data for commands like text, sysex, etc.
Contains all the information about a MIDI file.
int format
Format of MIDI file.
ulong ticksTotal
Total number of MIDI ticks.
double millisecsTotal
Total number of milliseconds.
int ntracks
Number of tracks.
int patchesUsed[256]
Patches used in the MIDI file.
int ticksPerCuarterNote
Ticks per cuarter note.