home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 26
/
CD_ASCQ_26_1295.iso
/
vrac
/
cmf_play.zip
/
SOUND.H
< prev
next >
Wrap
Text File
|
1995-09-22
|
5KB
|
224 lines
/* Functions to play .CMF files. *
* Note: MAKE SURE THE 'SBFMDRV.COM' TSR IS LOADED BEFORE EXECUTION! *
* Read 'PROTOTYPE.TXT' for in-depth how-to info. */
#define INTRPT (int)cmf_interrupt
#define BYTE unsigned char
#define WORD unsigned int
unsigned int cmfplay(char huge *cmfdata);
long getlength(char *filename);
void loadcmf(char *data, char *filename, long length);
unsigned short getcmfdriverversion(void);
void setcmfstatusbyte(void);
void freestatusbyte(void);
void setinstruments(unsigned int instruments, char far *data);
void setsystemclock(unsigned int hertz);
void setdriverclock(unsigned int hertz);
void cmftranspose(int halfsteps);
unsigned int startcmfplayback(char far *cmfdata, unsigned int offset);
unsigned int stopcmfplayback(void);
unsigned int initcmfdriver(void);
unsigned int pausecmfplayback(void);
unsigned int continuecmfplayback(void);
WORD findcmfdriver(void);
unsigned char far *cmf_status=NULL;
BYTE cmf_interrupt=0x80;
unsigned int cmfplay(char huge *cmfdata)
{
unsigned int inst_off= cmfdata[ 6]+cmfdata[ 7]*256;
unsigned int music_off= cmfdata[ 8]+cmfdata[ 9]*256;
unsigned int ticks_second=cmfdata[12]+cmfdata[13]*256;
unsigned int num_inst= cmfdata[36]+cmfdata[37]*256;
if (initcmfdriver()==1) return(1);
setdriverclock(ticks_second);
setinstruments(num_inst,cmfdata+inst_off);
cmftranspose(0);
if(startcmfplayback(cmfdata, music_off)!=0) return(1);
return(0);
}
long getlength(char *filename)
{
int handle;
long length;
if((_dos_open(filename,O_RDONLY,&handle))!=0)
{
printf("Error opening %s.\n",filename);
exit(-1);
}
length=filelength(handle);
if(_dos_close(handle))
{
printf("Error closing %s.\n",filename);
exit(-1);
}
return(length);
}
void loadcmf(char *data, char *filename, long length)
{
int a,b;
FILE *filebinary;
if((filebinary=fopen(filename,"rb"))==NULL)
{
printf("%s not found: error.\n",filename);
exit(-1);
}
a=fread(data,1,(size_t)(length),filebinary);
fclose(filebinary);
}
unsigned short getcmfdriverversion(void)
{
union REGS regs;
regs.x.bx=0;
int86(INTRPT,®s,®s);
return(regs.x.ax);
}
void setcmfstatusbyte(void)
{
union REGS regs;
if (cmf_status==NULL) cmf_status=(char far *)malloc(1);
regs.x.bx=1;
regs.x.dx=FP_SEG(cmf_status);
regs.x.ax=FP_OFF(cmf_status);
int86(INTRPT,®s,®s);
return;
}
void freestatusbyte(void)
{
union REGS regs;
regs.x.bx=1;
regs.x.dx=0;
regs.x.ax=0;
int86(INTRPT,®s,®s);
if (cmf_status!=NULL) free(cmf_status);
return;
}
void setinstruments(unsigned int instruments, char far *instdata)
{
union REGS regs;
regs.x.bx=2;
regs.x.cx=instruments;
regs.x.dx=FP_SEG(instdata);
regs.x.ax=FP_OFF(instdata);
int86(INTRPT,®s,®s);
return;
}
void setsystemclock(unsigned int hertz)
{
union REGS regs;
ldiv_t ans;
regs.x.bx=3;
ans=ldiv(1193180L,(long)hertz);
regs.x.ax=(int)ans.quot;
int86(INTRPT,®s,®s);
return;
}
void setdriverclock(unsigned int hertz)
{
union REGS regs;
ldiv_t ans;
regs.x.bx=4;
ans=ldiv(1193180L,(long)hertz);
regs.x.ax=(int)ans.quot;
int86(INTRPT,®s,®s);
return;
}
void cmftranspose(int halfsteps)
{
union REGS regs;
regs.x.bx=05;
regs.x.ax=halfsteps;
int86(INTRPT,®s,®s);
return;
}
unsigned int startcmfplayback(char far *cmfdata, unsigned int offset)
{
union REGS regs;
regs.x.bx=06;
regs.x.dx=FP_SEG(cmfdata);
regs.x.ax=offset%256;
int86(INTRPT,®s,®s);
return(regs.x.ax);
}
unsigned int stopcmfplayback(void)
{
union REGS regs;
regs.x.bx=7;
int86(INTRPT,®s,®s);
return(regs.x.ax);
}
unsigned int initcmfdriver(void)
{
union REGS regs;
regs.x.bx=8;
int86(INTRPT,®s,®s);
return(regs.x.ax);
}
unsigned int pausecmfplayback(void)
{
union REGS regs;
regs.x.bx=9;
int86(INTRPT,®s,®s);
return(regs.x.ax);
}
unsigned int continuecmfplayback(void)
{
union REGS regs;
regs.x.bx=10;
int86(INTRPT,®s,®s);
return(regs.x.ax);
}
WORD findcmfdriver(void)
{
union REGS regs;
const char string[]="FMDRV";
int a,b;
char ch;
BYTE far *test_irq;
BYTE scan_irq;
/* NOTE: This code should work, but does not on QC2
for(scan_irq=0x80;scan_irq<0xc0;scan_irq++)
{
test_irq=(BYTE far *)_dos_getvect(scan_irq);
FP_OFF(test_irq)=0x103;
for(a=0;a<5;a++)
{
if (string[a]!=test_irq[a]) a=255;
}
if (a==5)
{
cmf_interrupt=scan_irq;
return(1);
}
}
*/
return(0);
}