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