home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.65_stereo.zip / src / gsound.c < prev    next >
C/C++ Source or Header  |  2007-04-15  |  9KB  |  377 lines

  1. //
  2. // GOATTRACKER sound routines
  3. //
  4.  
  5. #define GSOUND_C
  6.  
  7. #ifdef __WIN32__
  8. #include <windows.h>
  9. #endif
  10.  
  11. #include "goattrk2.h"
  12.  
  13. // General / reSID output
  14. int playspeed;
  15. int usehardsid = 0;
  16. int lefthardsid = 0;
  17. int righthardsid = 0;
  18. int usecatweasel = 0;
  19. int initted = 0;
  20. int firsttimeinit = 1;
  21. unsigned framerate = PALFRAMERATE;
  22. Sint16 *lbuffer = NULL;
  23. Sint16 *rbuffer = NULL;
  24.  
  25. FILE *writehandle = NULL;
  26.  
  27. void sound_playrout(void);
  28. void sound_mixer(Sint32 *dest, unsigned samples);
  29. Uint32 sound_timer(Uint32 interval);
  30.  
  31.  
  32. #ifdef __WIN32__
  33.  
  34. // Win32 HardSID output
  35. typedef void (CALLBACK* lpWriteToHardSID)(Uint8 DeviceID, Uint8 SID_reg, Uint8 data);
  36. typedef Uint8 (CALLBACK* lpReadFromHardSID)(Uint8 DeviceID, Uint8 SID_reg);
  37. typedef void (CALLBACK* lpInitHardSID_Mapper)(void);
  38. typedef void (CALLBACK* lpMuteHardSID_Line)(int mute);
  39. lpWriteToHardSID WriteToHardSID;
  40. lpReadFromHardSID ReadFromHardSID;
  41. lpInitHardSID_Mapper InitHardSID_Mapper;
  42. lpMuteHardSID_Line MuteHardSID_Line;
  43. HINSTANCE hardsiddll = 0;
  44. int dll_initialized = FALSE;
  45.  
  46. void InitHardDLL(void);
  47.  
  48. // Win32 CatWeasel MK3 PCI output
  49. #define SID_SID_PEEK_POKE   CTL_CODE(FILE_DEVICE_SOUND,0x0800UL + 1,METHOD_BUFFERED,FILE_ANY_ACCESS)
  50. HANDLE catweaselhandle;
  51.  
  52. #else
  53.  
  54. // Unix HardSID & CatWeasel output
  55. int lefthardsidfd = -1;
  56. int righthardsidfd = -1;
  57. int catweaselfd = -1;
  58.  
  59. #endif
  60.  
  61. int sound_init(unsigned b, unsigned mr, unsigned writer, unsigned hardsid, unsigned m, unsigned ntsc, unsigned multiplier, unsigned catweasel, unsigned interpolate, unsigned customclockrate)
  62. {
  63.   int c;
  64.  
  65.   sound_uninit();
  66.  
  67.   if (multiplier)
  68.   {
  69.     if (ntsc)
  70.     {
  71.       framerate = NTSCFRAMERATE * multiplier;
  72.       snd_bpmtempo = 150 * multiplier;
  73.     }
  74.     else
  75.     {
  76.       framerate = PALFRAMERATE * multiplier;
  77.       snd_bpmtempo = 125 * multiplier;
  78.     }
  79.   }
  80.   else
  81.   {
  82.     if (ntsc)
  83.     {
  84.       framerate = NTSCFRAMERATE / 2;
  85.       snd_bpmtempo = 150 / 2;
  86.     }
  87.     else
  88.     {
  89.       framerate = PALFRAMERATE / 2;
  90.       snd_bpmtempo = 125 / 2;
  91.     }
  92.   }
  93.  
  94.   if (hardsid)
  95.   {
  96.     lefthardsid = (hardsid & 0xf) - 1;
  97.     righthardsid = ((hardsid >> 4) & 0xf) - 1;
  98.  
  99.     if ((righthardsid == lefthardsid) || (righthardsid < 0))
  100.       righthardsid = lefthardsid + 1;
  101.  
  102.     #ifdef __WIN32__
  103.     InitHardDLL();
  104.     if (dll_initialized)
  105.     {
  106.       usehardsid = hardsid;
  107.  
  108.       for (c = 0; c < NUMSIDREGS; c++)
  109.       {
  110.         sidreg[c] = 0;
  111.         WriteToHardSID(lefthardsid, c, 0x00);
  112.         WriteToHardSID(righthardsid, c, 0x00);
  113.       }
  114.       MuteHardSID_Line(FALSE);
  115.     }
  116.     else return 0;
  117.     #else
  118.     char filename[80];
  119.     sprintf(filename, "/dev/sid%d", lefthardsid);
  120.     lefthardsidfd = open(filename, O_WRONLY, S_IREAD|S_IWRITE);
  121.     sprintf(filename, "/dev/sid%d", righthardsid);
  122.     righthardsidfd = open(filename, O_WRONLY, S_IREAD|S_IWRITE);
  123.     if ((lefthardsidfd >= 0) && (righthardsidfd >= 0))
  124.     {
  125.       usehardsid = hardsid;
  126.       for (c = 0; c < NUMSIDREGS; c++)
  127.       {
  128.         Uint32 dataword = c << 8;
  129.         write(lefthardsidfd, &dataword, 4);
  130.         write(righthardsidfd, &dataword, 4);
  131.       }
  132.     }
  133.     else return 0;
  134.     #endif
  135.     SDL_SetTimer(1000 / framerate, sound_timer);
  136.     goto SOUNDOK;
  137.   }
  138.  
  139.   if (catweasel)
  140.   {
  141.     #ifdef __WIN32__
  142.     catweaselhandle = CreateFile("\\\\.\\SID6581_1", GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, 0L,
  143.       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0L);
  144.     if (catweaselhandle == INVALID_HANDLE_VALUE)
  145.       return 0;
  146.     #else
  147.     catweaselfd = open("/dev/sid", O_WRONLY);
  148.     if (catweaselfd < 0)
  149.       catweaselfd = open("/dev/misc/sid", O_WRONLY);
  150.     if (catweaselfd < 0)
  151.       return 0;
  152.     if (ntsc)
  153.       ioctl(catweaselfd, CWSID_IOCTL_NTSC);
  154.     else
  155.       ioctl(catweaselfd, CWSID_IOCTL_PAL);
  156.     #endif
  157.  
  158.     usecatweasel = 1;
  159.     SDL_SetTimer(1000 / framerate, sound_timer);
  160.     goto SOUNDOK;
  161.   }
  162.  
  163.   lbuffer = malloc(MIXBUFFERSIZE * sizeof(Sint16));
  164.   rbuffer = malloc(MIXBUFFERSIZE * sizeof(Sint16));
  165.   if ((!lbuffer) || (!rbuffer)) return 0;
  166.  
  167.   if (writer)
  168.     writehandle = fopen("sidaudio.raw", "wb");
  169.  
  170.   playspeed = mr;
  171.   if (playspeed < MINMIXRATE) playspeed = MINMIXRATE;
  172.   if (playspeed > MAXMIXRATE) playspeed = MAXMIXRATE;
  173.   if (b < MINBUF) b = MINBUF;
  174.   if (b > MAXBUF) b = MAXBUF;
  175.  
  176.   if (firsttimeinit)
  177.   {
  178.     if (!snd_init(mr, SIXTEENBIT|STEREO, b, 1, 0)) return 0;
  179.     firsttimeinit = 0;
  180.   }
  181.   playspeed = snd_mixrate;
  182.   sid_init(playspeed, m, ntsc, interpolate, customclockrate);
  183.  
  184.   snd_player = &sound_playrout;
  185.   snd_setcustommixer(sound_mixer);
  186.  
  187.   SOUNDOK:
  188.   initted = 1;
  189.   atexit(sound_uninit);
  190.   return 1;
  191. }
  192.  
  193. void sound_uninit(void)
  194. {
  195.   int c;
  196.  
  197.   if (!initted) return;
  198.   initted = 0;
  199.  
  200.   if (usehardsid || usecatweasel)
  201.   {
  202.     SDL_SetTimer(0, NULL);
  203.   }
  204.   else
  205.   {
  206.       snd_setcustommixer(NULL);
  207.     snd_player = NULL;
  208.   }
  209.  
  210.   if (writehandle)
  211.   {
  212.     fclose(writehandle);
  213.     writehandle = NULL;
  214.   }
  215.  
  216.   if (lbuffer)
  217.   {
  218.       free(lbuffer);
  219.       lbuffer = NULL;
  220.   }
  221.   if (rbuffer)
  222.   {
  223.       free(rbuffer);
  224.       rbuffer = NULL;
  225.   }
  226.  
  227.   if (usehardsid)
  228.   {
  229.     #ifdef __WIN32__
  230.     for (c = 0; c < NUMSIDREGS; c++)
  231.     {
  232.       WriteToHardSID(lefthardsid, c, 0x00);
  233.       WriteToHardSID(righthardsid, c, 0x00);
  234.     }
  235.     MuteHardSID_Line(TRUE);
  236.     #else
  237.     if ((lefthardsidfd >= 0) && (righthardsidfd >= 0))
  238.     {
  239.       for (c = 0; c < NUMSIDREGS; c++)
  240.       {
  241.         Uint32 dataword = c << 8;
  242.         write(lefthardsidfd, &dataword, 4);
  243.         write(righthardsidfd, &dataword, 4);
  244.       }
  245.       close(lefthardsidfd);
  246.       close(righthardsidfd);
  247.       lefthardsidfd = -1;
  248.       righthardsidfd = -1;
  249.     }
  250.     #endif
  251.   }
  252.  
  253.   if (usecatweasel)
  254.   {
  255.     #ifdef __WIN32__
  256.     DWORD w;
  257.     unsigned char buf[NUMSIDREGS * 2];
  258.     for (w = 0; w < NUMSIDREGS; w++)
  259.     {
  260.       buf[w*2] = 0x18 - w;
  261.       buf[w*2+1] = 0;
  262.     }
  263.     DeviceIoControl(catweaselhandle, SID_SID_PEEK_POKE, buf, sizeof(buf), 0L, 0UL, &w, 0L);
  264.     CloseHandle(catweaselhandle);
  265.     catweaselhandle = INVALID_HANDLE_VALUE;
  266.     #else
  267.     if (catweaselfd >= 0)
  268.     {
  269.       unsigned char buf[NUMSIDREGS];
  270.       memset(buf, 0, sizeof(buf));
  271.       lseek(catweaselfd, 0, SEEK_SET);
  272.       write(catweaselfd, buf, sizeof(buf));
  273.       close(catweaselfd);
  274.       catweaselfd = -1;
  275.     }
  276.     #endif
  277.   }
  278. }
  279.  
  280. Uint32 sound_timer(Uint32 interval)
  281. {
  282.   if (!initted) return interval;
  283.   sound_playrout();
  284.   return interval;
  285. }
  286.  
  287. void sound_playrout(void)
  288. {
  289.   int c;
  290.  
  291.   playroutine();
  292.   if (usehardsid)
  293.   {
  294.     #ifdef __WIN32__
  295.     for (c = 0; c < NUMSIDREGS; c++)
  296.     {
  297.       unsigned o = sid_getorder(c);
  298.       WriteToHardSID(lefthardsid, o, sidreg[o]);
  299.       WriteToHardSID(righthardsid, o, sidreg2[o]);
  300.     }
  301.     #else
  302.     for (c = 0; c < NUMSIDREGS; c++)
  303.     {
  304.       unsigned o = sid_getorder(c);
  305.       Uint32 dataword = (o << 8) | sidreg[o];
  306.       write(lefthardsidfd, &dataword, 4);
  307.       dataword = (o << 8) | sidreg2[o];
  308.       write(righthardsidfd, &dataword, 4);
  309.     }
  310.     #endif
  311.   }
  312.   else if (usecatweasel)
  313.   {
  314.     #ifdef __WIN32__
  315.     DWORD w;
  316.     unsigned char buf[NUMSIDREGS * 2];
  317.  
  318.     for(w = 0; w < NUMSIDREGS; w++)
  319.     {
  320.       unsigned o = sid_getorder(w);
  321.  
  322.       buf[w*2] = o;
  323.       buf[w*2+1] = sidreg[o];
  324.     }
  325.     DeviceIoControl(catweaselhandle, SID_SID_PEEK_POKE, buf, sizeof(buf), 0L, 0UL, &w, 0L);
  326.     #else
  327.     for (c = 0; c < NUMSIDREGS; c++)
  328.     {
  329.       unsigned o = sid_getorder(c);
  330.  
  331.       lseek(catweaselfd, o, SEEK_SET);
  332.       write(catweaselfd, &sidreg[o], 1);
  333.     }
  334.     #endif
  335.   }
  336. }
  337.  
  338. void sound_mixer(Sint32 *dest, unsigned samples)
  339. {
  340.   int c;
  341.  
  342.   if (!initted) return;
  343.   if (samples > MIXBUFFERSIZE) return;
  344.  
  345.   sid_fillbuffer(lbuffer, rbuffer, samples);
  346.   if (writehandle)
  347.   {
  348.     for (c = 0; c < samples; c++)
  349.     {
  350.       fwrite(&lbuffer[c], sizeof(Sint16), 1, writehandle);
  351.       fwrite(&rbuffer[c], sizeof(Sint16), 1, writehandle);
  352.     }
  353.   }
  354.   for (c = 0; c < samples; c++)
  355.   {
  356.     dest[c*2] = lbuffer[c];
  357.     dest[c*2+1] = rbuffer[c];
  358.   }
  359. }
  360.  
  361. #ifdef __WIN32__
  362. void InitHardDLL()
  363. {
  364.   if (!(hardsiddll=LoadLibrary("HARDSID.DLL"))) return;
  365.  
  366.   WriteToHardSID = (lpWriteToHardSID) GetProcAddress(hardsiddll, "WriteToHardSID");
  367.   ReadFromHardSID = (lpReadFromHardSID) GetProcAddress(hardsiddll, "ReadFromHardSID");
  368.   InitHardSID_Mapper = (lpInitHardSID_Mapper) GetProcAddress(hardsiddll, "InitHardSID_Mapper");
  369.   MuteHardSID_Line = (lpMuteHardSID_Line) GetProcAddress(hardsiddll, "MuteHardSID_Line");
  370.  
  371.   if (!WriteToHardSID) return;
  372.  
  373.   InitHardSID_Mapper();
  374.   dll_initialized = TRUE;
  375. }
  376. #endif
  377.