home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.70.zip / src / gsid.cpp < prev    next >
C/C++ Source or Header  |  2010-01-03  |  5KB  |  212 lines

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