/* Converts MID format 0 files to CMF */
#include <stdio.h>
#include <dos.h>
#include <alloc.h>
long read32bit();
long to32bit();
int read16bit();
int to16bit();
long Mf_toberead = 0L;
long musdatalen = 0L;
int format,ntrks,division;
unsigned char CMFHeader[40] =
{'C','T','M','F',0x01,0x01,0x28,0x00,
0x28,0x08,0x30,0,0x60,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,128,0,120,0};
unsigned char InstrBuf[128][16];
unsigned char *MusicBuf;
FILE* midfile;
main(int argc, char **argv)
{
FILE* cmffile;
FILE* instrfile;
int ch;
int tempo,ticks_psec,ticks_pqn;
if(argc > 1)
{
readmidfile(argv);
if(argc>4)
{
tempo = atoi(argv[4]);
ticks_psec =(int)( (float)division * ((float)tempo/(float)60) );
ticks_pqn = (int)( (float)ticks_psec * ((float)60/(float)tempo) );
CMFHeader[10] = ticks_pqn & 0xFF;
CMFHeader[11] = (ticks_pqn >> 8) & 0xFF;
CMFHeader[12] = ticks_psec & 0xff;
CMFHeader[13] = (ticks_psec >> 8) & 0xFF;
CMFHeader[38] = tempo & 0xff;
CMFHeader[39] = (tempo >> 8) & 0xff;
}
cmffile = fopen(argv[1],"wb");
fwrite(CMFHeader,1,40,cmffile);
if(instrfile=fopen(argv[3],"rb"))
{
fread(&InstrBuf[0],1,2048,instrfile);
fclose(instrfile);
} else
{
printf("Instrument file %s not found!\n",argv[3]);
free(MusicBuf);
exit(1);
}
fwrite(&InstrBuf[0],1,2048,cmffile);
fwrite(MusicBuf,1,(unsigned)musdatalen,cmffile);
fclose(cmffile);
free(MusicBuf);
}
else
{
printf("MAKECMF converts a .MID format 0 file to CMF\n");
printf("usage: makecmf <cmffile> <midfile> <instrfile> [<tempo>]\n");
}
}
readmidfile(char **argv)
{
int i;
if(midfile=fopen(argv[2],"rb"))
{
if ( (i=readmt("MThd")) == EOF )
{
printf("This is not a valid MID file!\n");
fclose(midfile);
exit(1);
}
Mf_toberead = read32bit();
format = read16bit();
if(format == 1)
{
printf("Not a format 0 MID file!\n");
fclose(midfile);
exit(1);
}
ntrks = read16bit();
division = read16bit();
while ( Mf_toberead > 0 )
(void) egetc();
readmt("MTrk");
Mf_toberead = read32bit();
musdatalen = Mf_toberead;
if( MusicBuf = malloc(musdatalen))
{
fread(MusicBuf,1,(unsigned)musdatalen,midfile);
fclose(midfile);
}
else
{
printf("Not enough memory!\n");
fclose(midfile);
exit(1);
}
}
else
{
printf("Couldn't find MID file %s!\n",argv[2]);
exit(1);
}
}
readmt(char *s) /* read through the "MThd" or "MTrk" header string */
{
int n = 0;
char *p = s;
int c;
while ( (n++<4) && ((c=getc(midfile)) != EOF) ) {
if ( c != *p++ ) {
char buff[32];
(void) strcpy(buff,"expecting ");
(void) strcat(buff,s);
return(EOF);
}
}
return(c);
}
egetc() /* read a single character and abort on EOF */
{
int c = getc(midfile);
if ( c == EOF )
{
printf("premature EOF");
fclose(midfile);
exit(1);
}
Mf_toberead--;
return(c);
}
long to32bit(c1,c2,c3,c4)
{
long value = 0L;
value = (c1 & 0xff);
value = (value<<8) + (c2 & 0xff);
value = (value<<8) + (c3 & 0xff);
value = (value<<8) + (c4 & 0xff);
return (value);
}
to16bit(int c1,int c2)
{
return ((c1 & 0xff ) << 8) + (c2 & 0xff);
}
long read32bit()
{
int c1, c2, c3, c4;
c1 = egetc();
c2 = egetc();
c3 = egetc();
c4 = egetc();
return to32bit(c1,c2,c3,c4);
}
read16bit()
{
int c1, c2;
c1 = egetc();
c2 = egetc();
return to16bit(c1,c2);
}