home *** CD-ROM | disk | FTP | other *** search
/ PC Loisirs 18 / cd.iso / sharewar / mikm202 / source / mdriver.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-18  |  4.4 KB  |  267 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3. #include <conio.h>
  4. #include "mtypes.h"
  5. #include "mdriver.h"
  6.  
  7. DRIVER *firstdriver=NULL,*md_driver;
  8.  
  9. void  (*md_tickhandler)(void)=NULL;
  10.  
  11. UWORD md_device         =0;
  12. UWORD md_mixfreq        =44100;
  13. UWORD md_mode           =0;
  14. UWORD md_dmabufsize     =8192;
  15. UBYTE md_bpm            =125;
  16. UBYTE md_numchn         =0;
  17.  
  18. static FILE *sl_fp;
  19. static WORD  sl_old;
  20. static UWORD sl_infmt;
  21. static UWORD sl_outfmt;
  22.  
  23. GHOLD ghld[32];
  24.  
  25.  
  26. void SL_Init(FILE *fp,UWORD infmt,UWORD outfmt)
  27. {
  28.     sl_old=0;
  29.     sl_fp=fp;
  30.     sl_infmt=infmt;
  31.     sl_outfmt=outfmt;
  32. }
  33.  
  34.  
  35. int SL_GetSample(void)
  36. {
  37.     WORD s;
  38.  
  39.     if(sl_infmt & SF_16BITS){
  40.         fread(&s,2,1,sl_fp);
  41.     }
  42.     else{
  43.         s=fgetc(sl_fp)<<8;
  44.     }
  45.  
  46.     if(sl_infmt & SF_DELTA){
  47.         s+=sl_old;
  48.         sl_old=s;
  49.     }
  50.  
  51.     if((sl_infmt^sl_outfmt) & SF_SIGNED) s^=0x8000;
  52.  
  53.     return s;
  54. }
  55.  
  56.  
  57.  
  58. void SL_Load(void *buffer,ULONG length)
  59. {
  60.     if(sl_outfmt & SF_16BITS){
  61.         WORD *p=buffer;
  62.         length>>=1;
  63.         while(length--) *(p++)=SL_GetSample();
  64.     }
  65.     else{
  66.         BYTE *p=buffer;
  67.         while(length--) *(p++)=SL_GetSample()>>8;
  68.     }
  69. }
  70.  
  71.  
  72. ULONG tcount;
  73. UWORD tspeed;
  74.  
  75.  
  76. void SetBPM(UBYTE BPM)
  77. {
  78.     tspeed=(1193181UL*125)/(50U*BPM);
  79.     outportb(0x43,0x34);
  80.     outportb(0x40,tspeed&0xff);
  81.     outportb(0x40,tspeed>>8);
  82. }
  83.  
  84.  
  85.  
  86. void MD_InfoDriver(void)
  87. {
  88.     int t;
  89.     DRIVER *l;
  90.  
  91.     /* list all registered devicedrivers: */
  92.  
  93.     for(t=1,l=firstdriver; l!=NULL; l=l->next, t++){
  94.         printf("%d. %s\n",t,l->Version);
  95.     }
  96. }
  97.  
  98.  
  99. void MD_RegisterDriver(DRIVER *drv)
  100. {
  101.     if(firstdriver==NULL){
  102.         firstdriver=drv;
  103.         drv->next=NULL;
  104.     }
  105.     else{
  106.         drv->next=firstdriver;
  107.         firstdriver=drv;
  108.     }
  109. }
  110.  
  111.  
  112. WORD MD_SampleLoad(FILE *fp,ULONG size,ULONG reppos,ULONG repend,UWORD flags)
  113. {
  114.     return(md_driver->SampleLoad(fp,size,reppos,repend,flags));
  115. }
  116.  
  117.  
  118. void MD_SampleUnLoad(WORD handle)
  119. {
  120.     md_driver->SampleUnLoad(handle);
  121. }
  122.  
  123.  
  124. BOOL MD_Init(void)
  125. {
  126.     UWORD t;
  127.  
  128.     // if md_device==0, try to find a device number
  129.  
  130.     if(md_device==0){
  131.  
  132.         for(t=1,md_driver=firstdriver; md_driver!=NULL; md_driver=md_driver->next, t++){
  133.             if(md_driver->IsPresent()) break;
  134.         }
  135.  
  136.         if(md_driver==NULL){
  137.             myerr="You don't have any of the supported sound-devices";
  138.             return 0;
  139.         }
  140.  
  141.         md_device=t;
  142.     }
  143.  
  144.     // if n>0 use that driver
  145.  
  146.     for(t=1,md_driver=firstdriver; md_driver!=NULL && t!=md_device; md_driver=md_driver->next, t++);
  147.  
  148.     if(md_driver==NULL){
  149.         myerr="Device number out of range";
  150.         return 0;
  151.     }
  152.  
  153.     return(md_driver->Init());
  154. }
  155.  
  156.  
  157. void MD_Exit(void)
  158. {
  159.     md_driver->Exit();
  160. }
  161.  
  162.  
  163. static int isfirst;
  164. void (interrupt far *oldclocktick)(void);
  165.  
  166.  
  167. void interrupt timerhandler(void)
  168. {
  169.     SetBPM(md_bpm);
  170.  
  171.     if(md_tickhandler!=NULL){
  172.  
  173.         /* do not call the tickhandler if this is the very first interrupt
  174.            generated by the timer.. this prevents getting getting wierd
  175.            noises on the first tick when the dma buffer played an uncertain
  176.            amount of samples.
  177.         */
  178.  
  179.         if(isfirst)
  180.             isfirst=0;
  181.         else
  182.             md_tickhandler();
  183.     }
  184.  
  185.     md_driver->Update();
  186.  
  187.     tcount+=tspeed;
  188.     if(tcount>=0x10000){
  189.         tcount-=0x10000;
  190.         oldclocktick();
  191.     }
  192.     else outportb(0x20,0x20);
  193. }
  194.  
  195.  
  196. void MD_PlayStart(void)
  197. {
  198.     UWORD t;
  199.  
  200.     for(t=0;t<md_numchn;t++){
  201.         ghld[t].flags=0;
  202.         ghld[t].handle=0;
  203.         ghld[t].kick=0;
  204.         ghld[t].active=0;
  205.         ghld[t].frq=10000;
  206.         ghld[t].vol=0;
  207.         ghld[t].pan=(t&1)?0:255;
  208.         ghld[t].iter=0;
  209.         ghld[t].current=0;
  210.     }
  211.  
  212.     isfirst=1;
  213.     md_driver->PlayStart();
  214.     oldclocktick=_dos_getvect(0x8);
  215.     _dos_setvect(0x8,timerhandler);
  216.     tcount=0;
  217.     SetBPM(md_bpm);
  218. }
  219.  
  220.  
  221. void MD_PlayStop(void)
  222. {
  223.     _dos_setvect(0x8,oldclocktick);
  224.     outportb(0x43,0x34);
  225.     outportb(0x40,0);
  226.     outportb(0x40,0);
  227.     md_driver->PlayStop();
  228. }
  229.  
  230.  
  231. void MD_VoiceSetVolume(UBYTE voice,UBYTE vol)
  232. {
  233.     ghld[voice].vol=vol;
  234. }
  235.  
  236. void MD_VoiceSetFrequency(UBYTE voice,ULONG frq)
  237. {
  238.     ghld[voice].frq=frq;
  239. }
  240.  
  241. void MD_VoiceSetPanning(UBYTE voice,ULONG pan)
  242. {
  243.     ghld[voice].pan=pan;
  244. }
  245.  
  246. void MD_VoicePlay(UBYTE voice,WORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags)
  247. {
  248.     if(start>=size) return;
  249.  
  250.     if(flags&SF_LOOP){
  251.         if(repend>size) repend=size;    // repend can't be bigger than size
  252.     }
  253.  
  254.     ghld[voice].flags=flags;
  255.     ghld[voice].handle=handle;
  256.     ghld[voice].start=start;
  257.     ghld[voice].size=size;
  258.     ghld[voice].reppos=reppos;
  259.     ghld[voice].repend=repend;
  260.     ghld[voice].kick=1;
  261. }
  262.  
  263. void MD_RegisterTickHandler(void (*tickhandler)(void))
  264. {
  265.     md_tickhandler=tickhandler;
  266. }
  267.