home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 26 / CD_ASCQ_26_1295.iso / vrac / cmf_play.zip / SOUND.H < prev    next >
Text File  |  1995-09-22  |  5KB  |  224 lines

  1. /*   Functions to play .CMF files.                    *
  2.  *   Note: MAKE SURE THE 'SBFMDRV.COM' TSR IS LOADED BEFORE EXECUTION!    *
  3.  *   Read 'PROTOTYPE.TXT' for in-depth how-to info.            */
  4.  
  5. #define INTRPT (int)cmf_interrupt
  6. #define BYTE unsigned char
  7. #define WORD unsigned int
  8.  
  9. unsigned int    cmfplay(char huge *cmfdata);
  10. long            getlength(char *filename);
  11. void            loadcmf(char *data, char *filename, long length);
  12. unsigned short  getcmfdriverversion(void);
  13. void            setcmfstatusbyte(void);
  14. void            freestatusbyte(void);
  15. void            setinstruments(unsigned int instruments, char far *data);
  16. void            setsystemclock(unsigned int hertz);
  17. void            setdriverclock(unsigned int hertz);
  18. void            cmftranspose(int halfsteps);
  19. unsigned int    startcmfplayback(char far *cmfdata, unsigned int offset);
  20. unsigned int    stopcmfplayback(void);
  21. unsigned int    initcmfdriver(void);
  22. unsigned int    pausecmfplayback(void);
  23. unsigned int    continuecmfplayback(void);
  24. WORD            findcmfdriver(void);
  25.  
  26. unsigned char far *cmf_status=NULL;
  27. BYTE cmf_interrupt=0x80;
  28.  
  29. unsigned int cmfplay(char huge *cmfdata)
  30. {
  31.  unsigned int inst_off=    cmfdata[ 6]+cmfdata[ 7]*256;
  32.  unsigned int music_off=   cmfdata[ 8]+cmfdata[ 9]*256;
  33.  unsigned int ticks_second=cmfdata[12]+cmfdata[13]*256;
  34.  unsigned int num_inst=    cmfdata[36]+cmfdata[37]*256;
  35.  
  36.  if (initcmfdriver()==1) return(1);
  37.  setdriverclock(ticks_second);
  38.  setinstruments(num_inst,cmfdata+inst_off);
  39.  cmftranspose(0);
  40.  
  41.  if(startcmfplayback(cmfdata, music_off)!=0) return(1);
  42.  return(0);
  43. }
  44.  
  45. long getlength(char *filename)
  46. {
  47.  int handle;
  48.  long length;
  49.  
  50.  if((_dos_open(filename,O_RDONLY,&handle))!=0)
  51.  {
  52.   printf("Error opening %s.\n",filename);
  53.   exit(-1);
  54.  }
  55.  length=filelength(handle);
  56.  
  57.  if(_dos_close(handle))
  58.  {
  59.   printf("Error closing %s.\n",filename);
  60.   exit(-1);
  61.  }
  62.  return(length);
  63. }
  64.  
  65. void loadcmf(char *data, char *filename, long length)
  66. {
  67.  int a,b;
  68.  FILE *filebinary;
  69.  
  70.  if((filebinary=fopen(filename,"rb"))==NULL)
  71.  {
  72.   printf("%s not found: error.\n",filename);
  73.   exit(-1);
  74.  }
  75.  a=fread(data,1,(size_t)(length),filebinary);
  76.  
  77.  fclose(filebinary);
  78. }
  79.  
  80. unsigned short getcmfdriverversion(void)
  81. {
  82.  union REGS regs;
  83.  regs.x.bx=0;
  84.  int86(INTRPT,®s,®s);
  85.  return(regs.x.ax);
  86. }
  87.  
  88. void setcmfstatusbyte(void)
  89. {
  90.  union REGS regs;
  91.  if (cmf_status==NULL) cmf_status=(char far *)malloc(1);
  92.  regs.x.bx=1;
  93.  regs.x.dx=FP_SEG(cmf_status);
  94.  regs.x.ax=FP_OFF(cmf_status);
  95.  int86(INTRPT,®s,®s);
  96.  return;
  97. }
  98.  
  99. void freestatusbyte(void)
  100. {
  101.  union REGS regs;
  102.  regs.x.bx=1;
  103.  regs.x.dx=0;
  104.  regs.x.ax=0;
  105.  int86(INTRPT,®s,®s);
  106.  if (cmf_status!=NULL) free(cmf_status);
  107.  return;
  108. }
  109.  
  110. void setinstruments(unsigned int instruments, char far *instdata)
  111. {
  112.  union REGS regs;
  113.  regs.x.bx=2;
  114.  regs.x.cx=instruments;
  115.  regs.x.dx=FP_SEG(instdata);
  116.  regs.x.ax=FP_OFF(instdata);
  117.  int86(INTRPT,®s,®s);
  118.  return;
  119. }
  120.  
  121. void setsystemclock(unsigned int hertz)
  122. {
  123.  union REGS regs;
  124.  ldiv_t ans;
  125.  regs.x.bx=3;
  126.  
  127.  ans=ldiv(1193180L,(long)hertz);
  128.  regs.x.ax=(int)ans.quot;
  129.  int86(INTRPT,®s,®s);
  130.  return;
  131. }
  132.  
  133. void setdriverclock(unsigned int hertz)
  134. {
  135.  union REGS regs;
  136.  ldiv_t ans;
  137.  regs.x.bx=4;
  138.  ans=ldiv(1193180L,(long)hertz);
  139.  regs.x.ax=(int)ans.quot;
  140.  int86(INTRPT,®s,®s);
  141.  return;
  142. }
  143.  
  144. void cmftranspose(int halfsteps)
  145. {
  146.  union REGS regs;
  147.  regs.x.bx=05;
  148.  regs.x.ax=halfsteps;
  149.  int86(INTRPT,®s,®s);
  150.  return;
  151. }
  152.  
  153. unsigned int startcmfplayback(char far *cmfdata, unsigned int offset)
  154. {
  155.  union REGS regs;
  156.  regs.x.bx=06;
  157.  regs.x.dx=FP_SEG(cmfdata);
  158.  regs.x.ax=offset%256;
  159.  int86(INTRPT,®s,®s);
  160.  return(regs.x.ax);
  161. }
  162.  
  163. unsigned int stopcmfplayback(void)
  164. {
  165.  union REGS regs;
  166.  regs.x.bx=7;
  167.  int86(INTRPT,®s,®s);
  168.  return(regs.x.ax);
  169. }
  170.  
  171. unsigned int initcmfdriver(void)
  172. {
  173.  union REGS regs;
  174.  regs.x.bx=8;
  175.  int86(INTRPT,®s,®s);
  176.  return(regs.x.ax);
  177. }
  178.  
  179. unsigned int pausecmfplayback(void)
  180. {
  181.  union REGS regs;
  182.  regs.x.bx=9;
  183.  int86(INTRPT,®s,®s);
  184.  return(regs.x.ax);
  185. }
  186.  
  187. unsigned int continuecmfplayback(void)
  188. {
  189.  union REGS regs;
  190.  regs.x.bx=10;
  191.  int86(INTRPT,®s,®s);
  192.  return(regs.x.ax);
  193. }
  194.  
  195. WORD findcmfdriver(void)
  196. {
  197.  union REGS regs;
  198.  const char string[]="FMDRV";
  199.  int a,b;
  200.  char ch;
  201.  BYTE far *test_irq;
  202.  BYTE scan_irq;
  203. /*                       NOTE: This code should work, but does not on QC2
  204.  for(scan_irq=0x80;scan_irq<0xc0;scan_irq++)
  205.  {
  206.   test_irq=(BYTE far *)_dos_getvect(scan_irq);
  207.   FP_OFF(test_irq)=0x103;
  208.  
  209.   for(a=0;a<5;a++)
  210.   {
  211.    if (string[a]!=test_irq[a]) a=255;
  212.   }
  213.   if (a==5)
  214.   {
  215.    cmf_interrupt=scan_irq;
  216.    return(1);
  217.   }
  218.  }
  219. */
  220.  return(0);
  221. }
  222.  
  223.  
  224.