home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.71_stereo.zip / src / gsid.cpp < prev    next >
C/C++ Source or Header  |  2009-12-23  |  7KB  |  284 lines

  1. /*
  2.  * GOATTRACKER reSID interface
  3.  */
  4.  
  5. #define GSID_C
  6.  
  7. #include <stdlib.h>
  8. #include "resid/sid.h"
  9. #include "resid-fp/sidfp.h"
  10.  
  11. extern "C" {
  12.  
  13. #include "gsid.h"
  14. #include "gsound.h"
  15.  
  16. int clockrate;
  17. int samplerate;
  18. unsigned char sidreg[NUMSIDREGS];
  19. unsigned char sidreg2[NUMSIDREGS];
  20.  
  21. unsigned char sidorder[] =
  22.   {0x15,0x16,0x18,0x17,
  23.    0x02,0x03,0x06,0x05,0x00,0x01,0x04,
  24.    0x09,0x0a,0x0d,0x0c,0x07,0x08,0x0b,
  25.    0x10,0x11,0x14,0x13,0x0e,0x0f,0x12};
  26.  
  27. unsigned char altsidorder[] =
  28.   {0x15,0x16,0x18,0x17,
  29.    0x04,0x00,0x01,0x02,0x03,0x05,0x06,
  30.    0x0b,0x07,0x08,0x09,0x0a,0x0c,0x0d,
  31.    0x12,0x0e,0x0f,0x10,0x11,0x13,0x14};
  32.  
  33. FILTERPARAMS filterparams =
  34.   {0.50f, 3.3e6f, 1.0e-4f,
  35.    1147036.4394268463f, 274228796.97550374f, 1.0066634233403395f, 16125.154840564108f,
  36.    5.5f, 20.f,
  37.    0.9613160610660189f};
  38.  
  39. SID *sid = 0;
  40. SID *sid2 = 0;
  41. SIDFP *sidfp = 0;
  42. SIDFP *sidfp2 = 0;
  43.  
  44. extern unsigned residdelay;
  45. extern unsigned adparam;
  46.  
  47. void sid_init(int speed, unsigned m, unsigned ntsc, unsigned interpolate, unsigned customclockrate, unsigned usefp)
  48. {
  49.   int c;
  50.  
  51.   if (ntsc) clockrate = NTSCCLOCKRATE;
  52.     else clockrate = PALCLOCKRATE;
  53.  
  54.   if (customclockrate)
  55.     clockrate = customclockrate;
  56.  
  57.   samplerate = speed;
  58.  
  59.   if (!usefp)
  60.   {
  61.     if (!sid) sid = new SID;
  62.     if (!sid2) sid2 = new SID;
  63.     
  64.     if (sidfp) 
  65.     { 
  66.       delete sidfp; 
  67.       sidfp = NULL;
  68.     }
  69.     if (sidfp2)
  70.     { 
  71.       delete sidfp2;
  72.       sidfp = NULL;
  73.     }
  74.   }
  75.   else
  76.   {
  77.     if (!sidfp) sidfp = new SIDFP;
  78.     if (!sidfp2) sidfp2 = new SIDFP;
  79.     
  80.     if (sid)
  81.     {
  82.       delete sid;
  83.       sid = NULL;
  84.     }
  85.     if (sid2)
  86.     {
  87.       delete sid2;
  88.       sid2 = NULL;
  89.     }
  90.   }
  91.  
  92.   switch(interpolate)
  93.   {
  94.     case 0:
  95.     if (sid) sid->set_sampling_parameters(clockrate, SAMPLE_FAST, speed);
  96.     if (sid2) sid2->set_sampling_parameters(clockrate, SAMPLE_FAST, speed);
  97.     if (sidfp) sidfp->set_sampling_parameters(clockrate, SAMPLE_INTERPOLATE, speed);
  98.     if (sidfp2) sidfp2->set_sampling_parameters(clockrate, SAMPLE_INTERPOLATE, speed);
  99.     break;
  100.  
  101.     default:
  102.     if (sid) sid->set_sampling_parameters(clockrate, SAMPLE_INTERPOLATE, speed);
  103.     if (sid2) sid2->set_sampling_parameters(clockrate, SAMPLE_INTERPOLATE, speed);
  104.     if (sidfp) sidfp->set_sampling_parameters(clockrate, SAMPLE_RESAMPLE_INTERPOLATE, speed);
  105.     if (sidfp2) sidfp2->set_sampling_parameters(clockrate, SAMPLE_RESAMPLE_INTERPOLATE, speed);
  106.     break;
  107.   }
  108.  
  109.   if (sid) sid->reset();
  110.   if (sid2) sid2->reset();
  111.   if (sidfp) sidfp->reset();
  112.   if (sidfp2) sidfp2->reset();
  113.  
  114.   for (c = 0; c < NUMSIDREGS; c++)
  115.   {
  116.     sidreg[c] = 0x00;
  117.     sidreg2[c] = 0x00;
  118.   }
  119.   if (m == 1)
  120.   {
  121.     if (sid) sid->set_chip_model(MOS8580);
  122.     if (sid2) sid2->set_chip_model(MOS8580);
  123.     if (sidfp) sidfp->set_chip_model(MOS8580);
  124.     if (sidfp2) sidfp2->set_chip_model(MOS8580);
  125.   }
  126.   else
  127.   {
  128.     if (sid) sid->set_chip_model(MOS6581);
  129.     if (sid2) sid2->set_chip_model(MOS6581);
  130.     if (sidfp) sidfp->set_chip_model(MOS6581);
  131.     if (sidfp2) sidfp2->set_chip_model(MOS6581);
  132.   }
  133.   
  134.   if (sidfp)
  135.   {
  136.     sidfp->get_filter().set_distortion_properties(
  137.       filterparams.distortionrate,
  138.       filterparams.distortionpoint,
  139.       filterparams.distortioncfthreshold);
  140.     sidfp->get_filter().set_type3_properties(
  141.       filterparams.type3baseresistance,
  142.       filterparams.type3offset,
  143.       filterparams.type3steepness,
  144.       filterparams.type3minimumfetresistance);
  145.     sidfp->get_filter().set_type4_properties(
  146.       filterparams.type4k,
  147.       filterparams.type4b);
  148.     sidfp->set_voice_nonlinearity(
  149.       filterparams.voicenonlinearity);
  150.   }
  151.   
  152.   if (sidfp2)
  153.   {
  154.     sidfp2->get_filter().set_distortion_properties(
  155.       filterparams.distortionrate,
  156.       filterparams.distortionpoint,
  157.       filterparams.distortioncfthreshold);
  158.     sidfp2->get_filter().set_type3_properties(
  159.       filterparams.type3baseresistance,
  160.       filterparams.type3offset,
  161.       filterparams.type3steepness,
  162.       filterparams.type3minimumfetresistance);
  163.     sidfp2->get_filter().set_type4_properties(
  164.       filterparams.type4k,
  165.       filterparams.type4b);
  166.     sidfp2->set_voice_nonlinearity(
  167.       filterparams.voicenonlinearity);
  168.   }
  169. }
  170.  
  171. unsigned char sid_getorder(unsigned char index)
  172. {
  173.   if (adparam >= 0xf000)
  174.     return altsidorder[index];
  175.   else
  176.     return sidorder[index];
  177. }
  178.  
  179. int sid_fillbuffer(short *lptr, short *rptr, int samples)
  180. {
  181.   int tdelta;
  182.   int tdelta2;
  183.   int result = 0;
  184.   int total = 0;
  185.   int c;
  186.  
  187.   int badline = rand() % NUMSIDREGS;
  188.  
  189.   tdelta = clockrate * samples / samplerate;
  190.   if (tdelta <= 0) return total;
  191.  
  192.   for (c = 0; c < NUMSIDREGS; c++)
  193.   {
  194.     unsigned char o = sid_getorder(c);
  195.  
  196.       // Extra delay for loading the waveform (and mt_chngate,x)
  197.       if ((o == 4) || (o == 11) || (o == 18))
  198.       {
  199.         tdelta2 = SIDWAVEDELAY;
  200.       if (sid) result = sid->clock(tdelta2, lptr, samples);
  201.       if (sidfp) result = sidfp->clock(tdelta2, lptr, samples);
  202.         tdelta2 = SIDWAVEDELAY;
  203.       if (sid2) sid2->clock(tdelta2, rptr, samples);
  204.       if (sidfp2) sidfp2->clock(tdelta2, rptr, samples);
  205.  
  206.       total += result;
  207.       lptr += result;
  208.       rptr += result;
  209.       samples -= result;
  210.       tdelta -= SIDWAVEDELAY;
  211.     }
  212.  
  213.     // Possible random badline delay once per writing
  214.     if ((badline == c) && (residdelay))
  215.       {
  216.       tdelta2 = residdelay;
  217.       if (sid) result = sid->clock(tdelta2, lptr, samples);
  218.       if (sidfp) result = sidfp->clock(tdelta2, lptr, samples);
  219.       tdelta2 = residdelay;
  220.       if (sid2) sid2->clock(tdelta2, rptr, samples);
  221.       if (sidfp2) sidfp2->clock(tdelta2, rptr, samples);
  222.  
  223.       total += result;
  224.       lptr += result;
  225.       rptr += result;
  226.       samples -= result;
  227.       tdelta -= residdelay;
  228.     }
  229.  
  230.     if (sid) sid->write(o, sidreg[o]);
  231.     if (sidfp) sidfp->write(o, sidreg[o]);
  232.     if (sid2) sid2->write(o, sidreg2[o]);
  233.     if (sidfp2) sidfp2->write(o, sidreg2[o]);
  234.  
  235.     tdelta2 = SIDWRITEDELAY;
  236.     if (sid) result = sid->clock(tdelta2, lptr, samples);
  237.     if (sidfp) result = sidfp->clock(tdelta2, lptr, samples);
  238.     tdelta2 = SIDWRITEDELAY;
  239.     if (sid2) sid2->clock(tdelta2, rptr, samples);
  240.     if (sidfp2) sidfp2->clock(tdelta2, rptr, samples);
  241.  
  242.     total += result;
  243.     lptr += result;
  244.     rptr += result;
  245.     samples -= result;
  246.     tdelta -= SIDWRITEDELAY;
  247.  
  248.     if (tdelta <= 0) return total;
  249.   }
  250.  
  251.   tdelta2 = tdelta;
  252.   if (sid) result = sid->clock(tdelta2, lptr, samples);
  253.   if (sidfp) result = sidfp->clock(tdelta2, lptr, samples);
  254.   tdelta2 = tdelta;
  255.   if (sid2) result = sid2->clock(tdelta2, rptr, samples);
  256.   if (sidfp2) result = sidfp2->clock(tdelta2, rptr, samples);
  257.  
  258.   total += result;
  259.   lptr += result;
  260.   rptr += result;
  261.   samples -= result;
  262.  
  263.   // Loop extra cycles until all samples produced
  264.   while (samples)
  265.   {
  266.     tdelta = clockrate * samples / samplerate;
  267.     if (tdelta <= 0) return total;
  268.         
  269.     if (sid) result = sid->clock(tdelta, lptr, samples);
  270.     if (sidfp) result = sidfp->clock(tdelta, lptr, samples);
  271.     tdelta = clockrate * samples / samplerate;
  272.     if (sid2) result = sid2->clock(tdelta, rptr, samples);
  273.     if (sidfp2) result = sidfp2->clock(tdelta, rptr, samples);
  274.     total += result;
  275.     lptr += result;
  276.     rptr += result;
  277.     samples -= result;
  278.   }
  279.  
  280.   return total;
  281. }
  282.  
  283. }
  284.