SHARE
TWEET

st3play v0.94a

8bitbubsy Dec 26th, 2013 (edited) 860 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ** st3play v0.94a - 21st of June 2019 - https://16-bits.org
  3. ** ========================================================
  4. **                 - NOT BIG ENDIAN SAFE! -
  5. **
  6. ** Very accurate C port of Scream Tracker 3.21's replayer,
  7. ** by Olav "8bitbubsy" Sørensen. Using the original asm source codes
  8. ** by Sami "PSI" Tammilehto (Future Crew) with permission.
  9. **
  10. ** This replayer supports 16-bit samples (which ST3 doesn't)!
  11. **
  12. ** You need to link winmm.lib for this to compile (-lwinmm)
  13. ** Alternatively, you can change out the mixer functions at the bottom with
  14. ** your own for your OS.
  15. **
  16. ** Example of st3play usage:
  17. ** #include "st3play.h"
  18. ** #include "songdata.h"
  19. **
  20. ** st3play_PlaySong(songData, songDataLength, true, 44100);
  21. ** mainLoop();
  22. ** st3play_Close();
  23. **
  24. ** To turn a song into an include file like in the example, you can use my
  25. ** win32 bin2h tool from here: https://16-bits.org/etc/bin2h.zip
  26. **
  27. ** Changes in v0.94a:
  28. ** - Code cleanup
  29. **
  30. ** Changes in v0.94:
  31. ** - Small mixer optimization for very tight sample loops
  32. **
  33. ** Changes in v0.93:
  34. ** - Code cleanup (uses the "bool" type now, spaces -> tabs, comment style change)
  35. **
  36. ** Changes in v0.92:
  37. ** - GUS mixing volume was slightly too loud
  38. ** - Read sample c2spd as 32-bit int and clamp to 65535
  39. ** - Use a table for low-periods-to-rate look-ups (prevents a ton of divs)
  40. ** - st3play can now mix at higher output rates than 65535Hz
  41. **
  42. ** Changes in v0.91:
  43. ** - Resampling interpolation was changed from 2-tap linear to 3-tap quadratic
  44. **   for less muddy sound.
  45. **
  46. ** Changes in v0.90:
  47. ** - Removed the soundcard selection in st3play_PlaySong(). Now it auto-scans
  48. **   for whatever soundcard is appropriate. If custom pannings are found,
  49. **   force to GUS.
  50. ** - Mastermul is forced to 48 in GUS mode (fixes clipping on some S3Ms)
  51. ** - Fixed some errors in the GUS panning table
  52. ** - Fixed a bug with panning in SB Pro mode
  53. **
  54. ** Changes in v0.89:
  55. ** - Bugfix: The last pattern in the order list would not be played!
  56. **
  57. ** Changes in v0.88:
  58. ** - Rewrote the S3M loader
  59. **
  60. ** Changes in v0.87:
  61. ** - More audio channel mixer optimizations
  62. **
  63. ** Changes in v0.86:
  64. ** - Fixed GUS panning positions (now uses a table)
  65. **
  66. ** Changes in v0.85:
  67. ** - Removed all 64-bit calculations, and made the mixer slightly faster
  68. ** - Some code was rewritten to be more correctly ported from the original code
  69. ** - st3play_SetMasterVol() now sets mixing vol. instead of the song's mastervol
  70. ** - Small code cleanup
  71. **
  72. ** Changes in v0.84:
  73. ** - Linear interpolation is done with 16-bit fractional precision instead of
  74. **   15-bit.
  75. **
  76. ** Changes in v0.83:
  77. ** - Prevent stuck loop if order list contains separators (254) only
  78. ** - Added a function to retrieve song name
  79. ** - Added a function to set master volume (0..256)
  80. **
  81. ** Changes in v0.82:
  82. ** - Fixed an error in loop wrapping in the audio channel mixer
  83. ** - Audio channel mixer is now optimized and fast!
  84. ** - WinMM mixer has been rewritten to be safe (don't use syscalls in callback)
  85. ** - Some small changes to the st3play functions (easier to use and safer!)
  86. ** - Removed all non-ST3 stuff (replayer should act identical to ST3 now).
  87. **   You should use another replayer if you want the non-ST3 features.
  88. ** - Some small fixes to the replayer and mixer functions
  89. */
  90.  
  91. /* st3play.h:
  92.  
  93. #pragma once
  94.  
  95. #include <stdint.h>
  96. #include <stdbool.h>
  97.  
  98. bool st3play_PlaySong(const uint8_t *moduleData, uint32_t dataLength, bool useInterpolationFlag, uint32_t audioFreq);
  99. void st3play_Close(void);
  100. void st3play_PauseSong(bool flag); // true/false
  101. void st3play_TogglePause(void);
  102. void st3play_SetMasterVol(uint16_t vol); // 0..256
  103. void st3play_SetInterpolation(bool flag); // true/false
  104. char *st3play_GetSongName(void); // max 28 chars (29 with '\0'), string is in code page 437
  105. uint32_t st3play_GetMixerTicks(void); // returns the amount of milliseconds of mixed audio (not realtime)
  106. */
  107.  
  108. #define MIX_BUF_SAMPLES 4096
  109.  
  110. #include <stdio.h>
  111. #include <stdlib.h>
  112. #include <string.h>
  113. #include <stdint.h>
  114. #include <stdbool.h>
  115.  
  116. #define LOOP_FIX_LEN 4
  117.  
  118. #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
  119.  
  120. // fast 32-bit -> 16-bit clamp
  121. #define CLAMP16(i) if ((int16_t)(i) != i) i = 0x7FFF ^ (i >> 31)
  122.  
  123. enum
  124. {
  125.     SOUNDCARD_GUS = 0,
  126.     SOUNDCARD_SBPRO = 1,
  127.     PATT_SEP = 254,
  128.     PATT_END = 255,
  129. };
  130.  
  131. typedef void (*mixRoutine)(void *, int32_t);
  132.  
  133. static struct
  134. {
  135.     int8_t *data, vol;
  136.     uint8_t type, flags;
  137.     uint16_t c2spd;
  138.     uint32_t length, loopbeg, looplen;
  139. } ins[100];
  140.  
  141. typedef struct
  142. {
  143.     int8_t aorgvol, avol, apanpos;
  144.     bool atreon;
  145.     uint8_t channelnum, amixtype, achannelused, aglis, atremor, atrigcnt, anotecutcnt, anotedelaycnt;
  146.     uint8_t avibtretype, note, ins, vol, cmd, info, lastins, lastnote, alastnfo, alasteff, alasteff1;
  147.     int16_t avibcnt, asldspd, aspd, aorgspd;
  148.     uint16_t astartoffset, astartoffset00, ac2spd;
  149. } chn_t;
  150.  
  151. typedef struct
  152. {
  153.     const int8_t *m_base8;
  154.     const int16_t *m_base16;
  155.     bool m_loopflag;
  156.     uint16_t m_vol_l, m_vol_r;
  157.     uint32_t m_pos, m_end, m_looplen, m_posfrac, m_speed, m_speedrev;
  158.     volatile void (*m_mixfunc)(void *, int32_t); // function pointer to mix routine
  159. } voice_t;
  160.  
  161. typedef void (*effect_routine)(chn_t *ch);
  162.  
  163. static char songname[28 + 1];
  164. static volatile bool musicPaused, interpolationFlag;
  165. static bool oldstvib, fastvolslide, amigalimits, stereomode;
  166. static int8_t **smpPtrs, volslidetype, patterndelay, patloopcount, lastachannelused;
  167. static uint8_t order[256], chnsettings[32], *patdata[100], *np_patseg;
  168. static uint8_t musicmax, soundcardtype, breakpat, startrow, musiccount;
  169. static int16_t jmptoord, np_ord, np_row, np_pat, np_patoff, patloopstart, jumptorow, globalvol, aspdmin, aspdmax;
  170. static uint16_t useglobalvol, patmusicrand, ordNum, insNum, patNum;
  171. static int32_t mastermul, mastervol = 256, samplesLeft, soundBufferSize, *mixBufferL, *mixBufferR;
  172. static uint32_t lowPeriod2Delta[(218 - 64) + 1], samplesPerTick, audioRate, sampleCounter;
  173. static chn_t chn[32];
  174. static voice_t voice[32];
  175. static mixRoutine mixRoutineTable[8];
  176.  
  177. /* 8bitbubsy: this panning table was made by sampling audio from my GUS PnP and processing it.
  178. ** It was scaled from 0..1 to 0..960 to fit the mixing volumes used for SB Pro mixing (4-bit pan * 16) */
  179. static const int16_t guspantab[16] = { 0, 246, 365, 438, 490, 562, 628, 682, 732, 775, 813, 847, 879, 909, 935, 960 };
  180.  
  181. static const int8_t retrigvoladd[32] =
  182. {
  183.     0, -1, -2, -4, -8,-16,  0,  0,
  184.     0,  1,  2,  4,  8, 16,  0,  0,
  185.     0,  0,  0,  0,  0,  0, 10,  8,
  186.     0,  0,  0,  0,  0,  0, 24, 32
  187. };
  188.  
  189. static const uint8_t octavediv[16] =
  190. {
  191.     0, 1, 2, 3, 4, 5, 6, 7,
  192.  
  193.     // overflow data from "xvol_amiga" table
  194.     0, 5, 11, 17, 27, 32, 42, 47
  195. };
  196.  
  197. static const int16_t notespd[16] =
  198. {
  199.     1712 * 16, 1616 * 16, 1524 * 16,
  200.     1440 * 16, 1356 * 16, 1280 * 16,
  201.     1208 * 16, 1140 * 16, 1076 * 16,
  202.     1016 * 16,  960 * 16,  907 * 16,
  203.     1712 * 8,
  204.  
  205.     // overflow data from "adlibiadd" table
  206.     0x0100, 0x0802, 0x0A09
  207. };
  208.  
  209. static const int16_t vibsin[64] =
  210. {
  211.     0x00, 0x18, 0x31, 0x4A, 0x61, 0x78, 0x8D, 0xA1,
  212.     0xB4, 0xC5, 0xD4, 0xE0, 0xEB, 0xF4, 0xFA, 0xFD,
  213.     0xFF, 0xFD, 0xFA, 0xF4, 0xEB, 0xE0, 0xD4, 0xC5,
  214.     0xB4, 0xA1, 0x8D, 0x78, 0x61, 0x4A, 0x31, 0x18,
  215.     0x00,-0x18,-0x31,-0x4A,-0x61,-0x78,-0x8D,-0xA1,
  216.    -0xB4,-0xC5,-0xD4,-0xE0,-0xEB,-0xF4,-0xFA,-0xFD,
  217.    -0xFF,-0xFD,-0xFA,-0xF4,-0xEB,-0xE0,-0xD4,-0xC5,
  218.    -0xB4,-0xA1,-0x8D,-0x78,-0x61,-0x4A,-0x31,-0x18
  219. };
  220.  
  221. static const uint8_t vibsqu[64] =
  222. {
  223.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  224.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  225.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  226.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  227.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  228.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  229.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  230.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  231. };
  232.  
  233. static const int16_t vibramp[64] =
  234. {
  235.       0, -248,-240,-232,-224,-216,-208,-200,
  236.    -192, -184,-176,-168,-160,-152,-144,-136,
  237.    -128, -120,-112,-104, -96, -88, -80, -72,
  238.     -64,  -56, -48, -40, -32, -24, -16,  -8,
  239.       0,    8,  16,  24,  32,  40,  48,  56,
  240.      64,   72,  80,  88,  96, 104, 112, 120,
  241.     128,  136, 144, 152, 160, 168, 176, 184,
  242.     192,  200, 208, 216, 224, 232, 240, 248
  243. };
  244.  
  245. static void voiceSetSource(uint8_t voiceNumber, const int8_t *sampleData,
  246.     int32_t length, int32_t loopStart, int32_t loopLength,
  247.     bool loopFlag, bool sampleIs16Bit);
  248. static void voiceSetSamplePosition(uint8_t voiceNumber, uint16_t value);
  249. static void voiceSetVolume(uint8_t voiceNumber, uint16_t vol, uint8_t pan);
  250.  
  251. static void s_ret(chn_t *ch);
  252. static void s_setgliss(chn_t *ch);
  253. static void s_setfinetune(chn_t *ch);
  254. static void s_setvibwave(chn_t *ch);
  255. static void s_settrewave(chn_t *ch);
  256. static void s_settrewave(chn_t *ch);
  257. static void s_setpanpos(chn_t *ch);
  258. static void s_stereocntr(chn_t *ch);
  259. static void s_patloop(chn_t *ch);
  260. static void s_notecut(chn_t *ch);
  261. static void s_notecutb(chn_t *ch);
  262. static void s_notedelay(chn_t *ch);
  263. static void s_notedelayb(chn_t *ch);
  264. static void s_patterdelay(chn_t *ch);
  265. static void s_setspeed(chn_t *ch);
  266. static void s_jmpto(chn_t *ch);
  267. static void s_break(chn_t *ch);
  268. static void s_volslide(chn_t *ch);
  269. static void s_slidedown(chn_t *ch);
  270. static void s_slideup(chn_t *ch);
  271. static void s_toneslide(chn_t *ch);
  272. static void s_vibrato(chn_t *ch);
  273. static void s_tremor(chn_t *ch);
  274. static void s_arp(chn_t *ch);
  275. static void s_vibvol(chn_t *ch);
  276. static void s_tonevol(chn_t *ch);
  277. static void s_retrig(chn_t *ch);
  278. static void s_tremolo(chn_t *ch);
  279. static void s_scommand1(chn_t *ch);
  280. static void s_scommand2(chn_t *ch);
  281. static void s_settempo(chn_t *ch);
  282. static void s_finevibrato(chn_t *ch);
  283. static void s_setgvol(chn_t *ch);
  284.  
  285. static bool openMixer(uint32_t audioFreq);
  286. static void closeMixer(void);
  287.  
  288. static const effect_routine ssoncejmp[16] =
  289. {
  290.     s_ret,         // 0
  291.     s_setgliss,    // 1
  292.     s_setfinetune, // 2
  293.     s_setvibwave,  // 3
  294.     s_settrewave,  // 4
  295.     s_ret,         // 5
  296.     s_ret,         // 6
  297.     s_ret,         // 7
  298.     s_setpanpos,   // 8
  299.     s_ret,         // 9
  300.     s_stereocntr,  // A
  301.     s_patloop,     // B
  302.     s_notecut,     // C
  303.     s_notedelay,   // D
  304.     s_patterdelay, // E
  305.     s_ret          // F
  306. };
  307.  
  308. static const effect_routine ssotherjmp[16] =
  309. {
  310.     s_ret,        // 0
  311.     s_ret,        // 1
  312.     s_ret,        // 2
  313.     s_ret,        // 3
  314.     s_ret,        // 4
  315.     s_ret,        // 5
  316.     s_ret,        // 6
  317.     s_ret,        // 7
  318.     s_ret,        // 8
  319.     s_ret,        // 9
  320.     s_ret,        // A
  321.     s_ret,        // B
  322.     s_notecutb,   // C
  323.     s_notedelayb, // D
  324.     s_ret,        // E
  325.     s_ret         // F
  326. };
  327.  
  328. static const effect_routine soncejmp[27] =
  329. {
  330.     s_ret,       // .
  331.     s_setspeed,  // A
  332.     s_jmpto,     // B
  333.     s_break,     // C
  334.     s_volslide,  // D
  335.     s_slidedown, // E
  336.     s_slideup,   // F
  337.     s_ret,       // G
  338.     s_ret,       // H
  339.     s_tremor,    // I
  340.     s_arp,       // J
  341.     s_ret,       // K
  342.     s_ret,       // L
  343.     s_ret,       // M
  344.     s_ret,       // N
  345.     s_ret,       // O - handled in doamiga()
  346.     s_ret,       // P
  347.     s_retrig,    // Q
  348.     s_ret,       // R
  349.     s_scommand1, // S
  350.     s_settempo,  // T
  351.     s_ret,       // U
  352.     s_ret,       // V
  353.     s_ret,       // W
  354.     s_ret,       // X
  355.     s_ret,       // Y
  356.     s_ret        // Z
  357. };
  358.  
  359. static const effect_routine sotherjmp[27] =
  360. {
  361.     s_ret,         // .
  362.     s_ret,         // A
  363.     s_ret,         // B
  364.     s_ret,         // C
  365.     s_volslide,    // D
  366.     s_slidedown,   // E
  367.     s_slideup,     // F
  368.     s_toneslide,   // G
  369.     s_vibrato,     // H
  370.     s_tremor,      // I
  371.     s_arp,         // J
  372.     s_vibvol,      // K
  373.     s_tonevol,     // L
  374.     s_ret,         // M
  375.     s_ret,         // N
  376.     s_ret,         // O
  377.     s_ret,         // P
  378.     s_retrig,      // Q
  379.     s_tremolo,     // R
  380.     s_scommand2,   // S
  381.     s_ret,         // T
  382.     s_finevibrato, // U
  383.     s_setgvol,     // V
  384.     s_ret,         // W
  385.     s_ret,         // X
  386.     s_ret,         // Y
  387.     s_ret          // Z
  388. };
  389.  
  390. // CODE START
  391.  
  392. static void getlastnfo(chn_t *ch)
  393. {
  394.     if (ch->info == 0)
  395.         ch->info = ch->alastnfo;
  396. }
  397.  
  398. static void setspeed(uint8_t val)
  399. {
  400.     if (val > 0)
  401.         musicmax = val;
  402. }
  403.  
  404. static void settempo(uint8_t val)
  405. {
  406.     if (val > 32)
  407.         samplesPerTick = (audioRate * 125) / (val * 50);
  408. }
  409.  
  410. static void setspd(chn_t *ch)
  411. {
  412.     int16_t tmpspd;
  413.     voice_t *v;
  414.  
  415.     v = &voice[ch->channelnum];
  416.  
  417.     ch->achannelused |= 0x80;
  418.  
  419.     if (amigalimits)
  420.     {
  421.         if ((uint16_t)ch->aorgspd > aspdmax)
  422.             ch->aorgspd = aspdmax;
  423.  
  424.         if (ch->aorgspd < aspdmin)
  425.             ch->aorgspd = aspdmin;
  426.     }
  427.  
  428.     tmpspd = ch->aspd;
  429.     if ((uint16_t)tmpspd > aspdmax)
  430.     {
  431.         tmpspd = aspdmax;
  432.         if (amigalimits)
  433.             ch->aspd = tmpspd;
  434.     }
  435.  
  436.     if (tmpspd == 0)
  437.     {
  438.         v->m_speed = 0; // cut voice (can be activated again by changing frequency)
  439.         v->m_speedrev = 0xFFFFFFFF;
  440.         return;
  441.     }
  442.  
  443.     if (tmpspd < aspdmin)
  444.     {
  445.         tmpspd = aspdmin;
  446.         if (amigalimits)
  447.             ch->aspd = tmpspd;
  448.     }
  449.  
  450.     // ST3 actually uses 14317056 (main timer 3.579264MHz * 4) instead of 14317456 (1712 * 8363)
  451.  
  452.     if (tmpspd < 219)
  453.     {
  454.         // channel rate >= 65536Hz, use a pre-calced table to prevent long calculations
  455.         v->m_speed = lowPeriod2Delta[tmpspd-64]; // tmpspd is never below 64 at this point
  456.     }
  457.     else
  458.     {
  459.         // channel rate <= 65535Hz, we can do a 32-bit calculation
  460.         v->m_speed = ((14317056 / tmpspd) << 16) / audioRate;
  461.     }
  462.  
  463.     v->m_speedrev = 0xFFFFFFFF / v->m_speed;
  464. }
  465.  
  466. static void setglobalvol(int8_t vol)
  467. {
  468.     globalvol = vol;
  469.  
  470.     if ((uint8_t)vol > 64)
  471.         vol = 64;
  472.  
  473.     useglobalvol = globalvol * 4; // for mixer
  474. }
  475.  
  476. static void setvol(chn_t *ch, bool volFlag)
  477. {
  478.     if (volFlag)
  479.         ch->achannelused |= 0x80;
  480.  
  481.     voiceSetVolume(ch->channelnum, (ch->avol * useglobalvol) >> 8, ch->apanpos & 0x0F);
  482. }
  483.  
  484. static int16_t stnote2herz(uint8_t note)
  485. {
  486.     uint8_t shiftVal;
  487.     uint16_t noteVal;
  488.  
  489.     if (note == 254)
  490.         return 0; // 0hertz/keyoff
  491.  
  492.     noteVal = notespd[note & 0x0F];
  493.  
  494.     shiftVal = octavediv[note >> 4];
  495.     if (shiftVal > 0)
  496.         noteVal >>= (shiftVal & 0x1F);
  497.  
  498.     return noteVal;
  499. }
  500.  
  501. static int16_t scalec2spd(chn_t *ch, int16_t spd)
  502. {
  503.     const int32_t c2freq = 8363;
  504.     int32_t tmpspd;
  505.  
  506.     tmpspd = spd * c2freq;
  507.     if ((tmpspd >> 16) >= ch->ac2spd)
  508.         return (32767); // div error
  509.  
  510.     tmpspd /= ch->ac2spd;
  511.     if (tmpspd > 32767)
  512.         tmpspd = 32767;
  513.  
  514.     return (int16_t)tmpspd;
  515. }
  516.  
  517. // for Gxx with semitones slide flag
  518. static int16_t roundspd(chn_t *ch, int16_t spd)
  519. {
  520.     const int32_t c2freq = 8363;
  521.     int8_t octa, newnote;
  522.     int16_t note, notemin, lastspd;
  523.     int32_t newspd;
  524.  
  525.     newspd = spd * ch->ac2spd;
  526.     if ((newspd >> 16) >= c2freq)
  527.         return spd; // div error
  528.  
  529.     newspd /= c2freq;
  530.  
  531.     // find octave
  532.  
  533.     octa = 0;
  534.     lastspd = (notespd[12] + notespd[11]) >> 1;
  535.  
  536.     while (lastspd >= newspd)
  537.     {
  538.         octa++;
  539.         lastspd >>= 1;
  540.     }
  541.  
  542.     // find note
  543.  
  544.     newnote = 0;
  545.     notemin = 32767;
  546.  
  547.     for (int8_t i = 0; i < 11; i++)
  548.     {
  549.         note = notespd[i];
  550.         if (octa > 0)
  551.             note >>= octa;
  552.  
  553.         note -= (int16_t)newspd;
  554.         if (note < 0)
  555.             note = -note;
  556.  
  557.         if (note < notemin)
  558.         {
  559.             notemin = note;
  560.             newnote = i;
  561.         }
  562.     }
  563.  
  564.     // get new speed from new note
  565.  
  566.     newspd = (stnote2herz((octa << 4) | (newnote & 0x0F))) * c2freq;
  567.     if ((newspd >> 16) >= ch->ac2spd)
  568.         return spd; // div error
  569.  
  570.     newspd /= ch->ac2spd;
  571.     return (int16_t)newspd;
  572. }
  573.  
  574. static int16_t neworder(void) // rewritten to be more safe
  575. {
  576.     uint8_t patt;
  577.     uint16_t numSep;
  578.  
  579.     numSep = 0;
  580.     while (true)
  581.     {
  582.         np_ord++;
  583.  
  584.         patt = order[np_ord-1];
  585.         if (patt == PATT_SEP)
  586.         {
  587.             /* added security that is not present in ST3: check if a
  588.             ** song has pattern separators only, prevent endless loop! */
  589.             if (++numSep >= ordNum)
  590.                 return 0;
  591.  
  592.             continue;
  593.         }
  594.  
  595.         if (patt == PATT_END)
  596.         {
  597.             // restart song
  598.             np_ord = 0;
  599.  
  600.             if (order[0] == PATT_END)
  601.                 return 0;
  602.  
  603.             continue;
  604.         }
  605.  
  606.         break;
  607.     }
  608.  
  609.     np_pat = patt;
  610.     np_patoff = -1; // force reseek
  611.     np_row = startrow;
  612.     startrow = 0;
  613.     patmusicrand = 0;
  614.     patloopstart = -1;
  615.     jumptorow = -1;
  616.  
  617.     return np_row;
  618. }
  619.  
  620. static int8_t getnote1(void)
  621. {
  622.     uint8_t dat, channel;
  623.     int16_t i;
  624.     chn_t *ch;
  625.  
  626.     if (np_patseg == NULL)
  627.         return 255;
  628.  
  629.     // added security that is not present in ST3
  630.     if (np_pat >= patNum)
  631.         return 255;
  632.  
  633.     channel = 0;
  634.  
  635.     i = np_patoff;
  636.     while (true)
  637.     {
  638.         dat = np_patseg[i++];
  639.         if (dat == 0)
  640.         {
  641.             np_patoff = i;
  642.             return 255;
  643.         }
  644.  
  645.         if ((chnsettings[dat & 0x1F] & 0x80) == 0)
  646.         {
  647.             channel = dat & 0x1F;
  648.             break;
  649.         }
  650.  
  651.         // channel off, skip
  652.         if (dat & 0x20) i += 2;
  653.         if (dat & 0x40) i += 1;
  654.         if (dat & 0x80) i += 2;
  655.     }
  656.  
  657.     ch = &chn[channel];
  658.  
  659.     // NOTE/INSTRUMENT
  660.     if (dat & 0x20)
  661.     {
  662.         ch->note = np_patseg[i++];
  663.         ch->ins = np_patseg[i++];
  664.  
  665.         if (ch->note != 255) ch->lastnote = ch->note;
  666.         if (ch->ins > 0) ch->lastins = ch->ins;
  667.     }
  668.  
  669.     // VOLUME
  670.     if (dat & 0x40)
  671.         ch->vol = np_patseg[i++];
  672.  
  673.     // COMMAND/INFO
  674.     if (dat & 0x80)
  675.     {
  676.         ch->cmd = np_patseg[i++];
  677.         ch->info = np_patseg[i++];
  678.     }
  679.  
  680.     np_patoff = i;
  681.     return channel;
  682. }
  683.  
  684. static void doamiga(uint8_t channel)
  685. {
  686.     uint8_t smp;
  687.     chn_t *ch;
  688.  
  689.     ch = &chn[channel];
  690.  
  691.     if (ch->ins > 0)
  692.         ch->astartoffset = 0;
  693.  
  694.     // set sample offset (also for sample triggering)
  695.     if (ch->lastins > 0 || ch->ins > 0)
  696.     {
  697.         if (ch->cmd == 'O'-64)
  698.         {
  699.             if (!ch->info)
  700.             {
  701.                 ch->astartoffset = ch->astartoffset00;
  702.             }
  703.             else
  704.             {
  705.                 ch->astartoffset = ch->info << 8;
  706.                 ch->astartoffset00 = ch->astartoffset;
  707.             }
  708.         }
  709.  
  710.         if (ch->note < 254 && ch->cmd != 'G'-64 && ch->cmd != 'L'-64)
  711.             voiceSetSamplePosition(channel, ch->astartoffset);
  712.     }
  713.  
  714.     // ***INSTRUMENT***
  715.     if (ch->ins > 0)
  716.     {
  717.         ch->astartoffset = 0;
  718.  
  719.         ch->lastins = ch->ins;
  720.         if (ch->ins <= insNum) // 8bitbubsy: added for safety reasons
  721.         {
  722.             smp = ch->ins - 1;
  723.  
  724.             if (ins[smp].type > 0)
  725.             {
  726.                 if (ins[smp].type == 1) // sample
  727.                 {
  728.                     ch->ac2spd = ins[smp].c2spd;
  729.                     ch->avol = ins[smp].vol;
  730.                     ch->aorgvol = ch->avol;
  731.                     setvol(ch, true);
  732.  
  733.                     // this specific portion differs from what sound card driver you use in ST3...
  734.                     if (soundcardtype == SOUNDCARD_SBPRO || (ch->cmd != 'G'-64 && ch->cmd != 'L'-64))
  735.                     {
  736.                         // on GUS, do no sample swapping without a note number
  737.                         if (soundcardtype != SOUNDCARD_GUS || ch->note != 255)
  738.                         {
  739.                             voiceSetSource(channel, (const int8_t *)ins[smp].data, ins[smp].length, ins[smp].loopbeg,
  740.                                 ins[smp].looplen, ins[smp].flags & 1, (ins[smp].flags >> 2) & 1);
  741.                         }
  742.                     }
  743.                 }
  744.                 else
  745.                 {
  746.                     // not sample (adlib instrument?)
  747.                     ch->lastins = 0;
  748.                 }
  749.             }
  750.         }
  751.     }
  752.  
  753.     // continue only if we have an active instrument on this channel
  754.     if (ch->lastins == 0)
  755.         return;
  756.  
  757.     // ***NOTE***
  758.     if (ch->note != 255)
  759.     {
  760.         if (ch->note == 254)
  761.         {
  762.             // end sample (not recovarable)
  763.  
  764.             ch->aspd = 0;
  765.             setspd(ch);
  766.  
  767.             ch->avol = 0;
  768.             setvol(ch, true);
  769.  
  770.             voice[channel].m_mixfunc = NULL;
  771.             voice[channel].m_pos = 0;
  772.  
  773.             ch->asldspd = 65535; // 8bitbubsy: most likely a bug
  774.         }
  775.         else
  776.         {
  777.             // calc note speed
  778.  
  779.             ch->lastnote = ch->note;
  780.  
  781.             ch->asldspd = scalec2spd(ch, stnote2herz(ch->note)); // destination for toneslide (G/L)
  782.             if (ch->aorgspd == 0 || (ch->cmd != 'G'-64 && ch->cmd != 'L'-64))
  783.             {
  784.                 ch->aspd = ch->asldspd;
  785.                 setspd(ch);
  786.                 ch->avibcnt = 0;
  787.                 ch->aorgspd = ch->aspd; // original speed if true one changed with vibrato etc.
  788.             }
  789.         }
  790.     }
  791.  
  792.     // ***VOLUME***
  793.     if (ch->vol != 255)
  794.     {
  795.         ch->avol = ch->vol;
  796.         setvol(ch, true);
  797.  
  798.         ch->aorgvol = ch->vol;
  799.         ch->aorgvol = ch->vol;
  800.     }
  801. }
  802.  
  803. static void donewnote(uint8_t channel, bool notedelayflag)
  804. {
  805.     chn_t *ch = &chn[channel];
  806.  
  807.     if (notedelayflag)
  808.     {
  809.         ch->achannelused = 0x81;
  810.     }
  811.     else
  812.     {
  813.         if (ch->channelnum > lastachannelused)
  814.         {
  815.             lastachannelused = ch->channelnum + 1;
  816.  
  817.             // added security that is not present in ST3
  818.             if (lastachannelused > 31)
  819.                 lastachannelused = 31;
  820.         }
  821.  
  822.         ch->achannelused = 0x01;
  823.  
  824.         if (ch->cmd == 'S'-64)
  825.         {
  826.             if ((ch->info & 0xF0) == 0xD0)
  827.                 return;
  828.         }
  829.     }
  830.  
  831.     doamiga(channel);
  832. }
  833.  
  834. static void donotes(void)
  835. {
  836.     uint8_t channel, dat;
  837.     int16_t i, j;
  838.     chn_t *ch;
  839.  
  840.     for (i = 0; i < 32; i++)
  841.     {
  842.         ch = &chn[i];
  843.  
  844.         ch->note = 255;
  845.         ch->vol = 255;
  846.         ch->ins = 0;
  847.         ch->cmd = 0;
  848.         ch->info = 0;
  849.     }
  850.  
  851.     // find np_row from pattern
  852.     if (np_patoff == -1)
  853.     {
  854.         np_patseg = patdata[np_pat];
  855.         if (np_patseg != NULL)
  856.         {
  857.             j = 0;
  858.             if (np_row > 0)
  859.             {
  860.                 i = np_row;
  861.                 while (i > 0)
  862.                 {
  863.                     dat = np_patseg[j++];
  864.                     if (dat == 0)
  865.                     {
  866.                         i--;
  867.                     }
  868.                     else
  869.                     {
  870.                         if (dat & 0x20) j += 2;
  871.                         if (dat & 0x40) j += 1;
  872.                         if (dat & 0x80) j += 2;
  873.                     }
  874.                 }
  875.             }
  876.  
  877.             np_patoff = j;
  878.         }
  879.     }
  880.  
  881.     while (true)
  882.     {
  883.         channel = getnote1();
  884.         if (channel == 255)
  885.             break; // end of row/channels
  886.  
  887.        if ((chnsettings[channel] & 0x7F) < 16) // only handle PCM channels for now
  888.             donewnote(channel, false);
  889.     }
  890. }
  891.  
  892. // tick 0 commands
  893. static void docmd1(void)
  894. {
  895.     chn_t *ch;
  896.  
  897.     for (uint8_t i = 0; i < lastachannelused+1; i++)
  898.     {
  899.         ch = &chn[i];
  900.  
  901.         if (ch->achannelused)
  902.         {
  903.             if (ch->info > 0)
  904.                 ch->alastnfo = ch->info;
  905.  
  906.             if (ch->cmd > 0)
  907.             {
  908.                 ch->achannelused |= 0x80;
  909.  
  910.                 if (ch->cmd == 'D'-64)
  911.                 {
  912.                     // fix trigger D
  913.  
  914.                     ch->atrigcnt = 0;
  915.  
  916.                     // fix speed if tone port noncomplete
  917.                     if (ch->aspd != ch->aorgspd)
  918.                     {
  919.                         ch->aspd = ch->aorgspd;
  920.                         setspd(ch);
  921.                     }
  922.                 }
  923.                 else
  924.                 {
  925.                     if (ch->cmd != 'I'-64)
  926.                     {
  927.                         ch->atremor = 0;
  928.                         ch->atreon  = true;
  929.                     }
  930.  
  931.                     if (ch->cmd != 'H'-64 && ch->cmd != 'U'-64 &&
  932.                         ch->cmd != 'K'-64 && ch->cmd != 'R'-64)
  933.                     {
  934.                         ch->avibcnt |= 128;
  935.                     }
  936.                 }
  937.  
  938.                 if (ch->cmd < 27)
  939.                 {
  940.                     volslidetype = 0;
  941.                     soncejmp[ch->cmd](ch);
  942.                 }
  943.             }
  944.             else
  945.             {
  946.                 // fix trigger 0
  947.  
  948.                 ch->atrigcnt = 0;
  949.  
  950.                 // fix speed if tone port noncomplete
  951.                 if (ch->aspd != ch->aorgspd)
  952.                 {
  953.                     ch->aspd = ch->aorgspd;
  954.                     setspd(ch);
  955.                 }
  956.  
  957.                 if (!amigalimits && ch->cmd < 27)
  958.                 {
  959.                     volslidetype = 0;
  960.                     soncejmp[ch->cmd](ch);
  961.                 }
  962.             }
  963.         }
  964.     }
  965. }
  966.  
  967. static void docmd2(void) // tick >0 commands
  968. {
  969.     chn_t *ch;
  970.  
  971.     for (uint8_t i = 0; i < lastachannelused+1; i++)
  972.     {
  973.         ch = &chn[i];
  974.         if (ch->achannelused && ch->cmd > 0)
  975.         {
  976.             ch->achannelused |= 0x80;
  977.  
  978.             if (ch->cmd < 27)
  979.             {
  980.                 volslidetype = 0;
  981.                 sotherjmp[ch->cmd](ch);
  982.             }
  983.         }
  984.     }
  985. }
  986.  
  987. static void dorow(void)
  988. {
  989.     patmusicrand = (((patmusicrand * 0xCDEF) >> 16) + 0x1727) & 0xFFFF;
  990.  
  991.     if (np_pat == 255)
  992.         return; // 8bitbubsy: there are no patterns in the song!
  993.  
  994.     if (musiccount == 0)
  995.     {
  996.         if (patterndelay > 0)
  997.         {
  998.             np_row--;
  999.             docmd1();
  1000.             patterndelay--;
  1001.         }
  1002.         else
  1003.         {
  1004.             donotes(); // new notes
  1005.             docmd1(); // also does 0volcut
  1006.         }
  1007.     }
  1008.     else
  1009.     {
  1010.         docmd2(); // effects only
  1011.     }
  1012.  
  1013.     if (++musiccount >= musicmax)
  1014.     {
  1015.         // next row
  1016.         np_row++;
  1017.  
  1018.         if (jumptorow != -1)
  1019.         {
  1020.             np_row = jumptorow;
  1021.             jumptorow = -1;
  1022.         }
  1023.  
  1024.         if (np_row >= 64 || (patloopcount == 0 && breakpat > 0))
  1025.         {
  1026.             // next pattern
  1027.             if (breakpat == 255)
  1028.             {
  1029.                 breakpat = 0;
  1030.                 return;
  1031.             }
  1032.  
  1033.             breakpat = 0;
  1034.  
  1035.             if (jmptoord != -1)
  1036.             {
  1037.                 np_ord = jmptoord;
  1038.                 jmptoord = -1;
  1039.             }
  1040.  
  1041.             np_row = neworder(); // if breakpat, np_row = break row
  1042.         }
  1043.  
  1044.         musiccount = 0;
  1045.     }
  1046. }
  1047.  
  1048. // EFFECTS
  1049.  
  1050. static void s_ret(chn_t *ch)
  1051. {
  1052.     (void)ch;
  1053. }
  1054.  
  1055. static void s_setgliss(chn_t *ch)
  1056. {
  1057.     ch->aglis = ch->info & 0x0F;
  1058. }
  1059.  
  1060. static void s_setfinetune(chn_t *ch)
  1061. {
  1062.     // this has a bug in ST3 that makes this effect do nothing!
  1063.     (void)ch;
  1064. }
  1065.  
  1066. static void s_setvibwave(chn_t *ch)
  1067. {
  1068.     ch->avibtretype = (ch->avibtretype & 0xF0) | ((ch->info << 1) & 0x0F);
  1069. }
  1070.  
  1071. static void s_settrewave(chn_t *ch)
  1072. {
  1073.     ch->avibtretype = ((ch->info << 5) & 0xF0) | (ch->avibtretype & 0x0F);
  1074. }
  1075.  
  1076. static void s_setpanpos(chn_t *ch)
  1077. {
  1078.     if (soundcardtype == SOUNDCARD_GUS)
  1079.     {
  1080.         ch->apanpos = ch->info & 0x0F;
  1081.         setvol(ch, false);
  1082.     }
  1083. }
  1084.  
  1085. static void s_stereocntr(chn_t *ch)
  1086. {
  1087.     /* Sound Blaster mix selector (buggy, undocumented ST3 effect):
  1088.     ** - SA0 = normal  mix
  1089.     ** - SA1 = swapped mix (L<->R)
  1090.     ** - SA2 = normal  mix (broken mixing)
  1091.     ** - SA3 = swapped mix (broken mixing)
  1092.     ** - SA4 = center  mix (broken mixing)
  1093.     ** - SA5 = center  mix (broken mixing)
  1094.     ** - SA6 = center  mix (broken mixing)
  1095.     ** - SA7 = center  mix (broken mixing)
  1096.     ** - SA8..F = changes nothing */
  1097.  
  1098.     if (soundcardtype == SOUNDCARD_SBPRO && (ch->info & 0x0F) < 8)
  1099.     {
  1100.         ch->amixtype = ch->info & 0x0F;
  1101.         setvol(ch, false);
  1102.     }
  1103. }
  1104.  
  1105. static void s_patloop(chn_t *ch)
  1106. {
  1107.     if ((ch->info & 0x0F) == 0)
  1108.     {
  1109.         patloopstart = np_row;
  1110.         return;
  1111.     }
  1112.  
  1113.     if (patloopcount == 0)
  1114.     {
  1115.         patloopcount = (ch->info & 0x0F) + 1;
  1116.         if (patloopstart == -1)
  1117.             patloopstart = 0; // default loopstart
  1118.     }
  1119.  
  1120.     if (patloopcount > 1)
  1121.     {
  1122.         patloopcount--;
  1123.         jumptorow = patloopstart;
  1124.         np_patoff = -1; // force reseek
  1125.     }
  1126.     else
  1127.     {
  1128.         patloopcount = 0;
  1129.         patloopstart = np_row + 1;
  1130.     }
  1131. }
  1132.  
  1133. static void s_notecut(chn_t *ch)
  1134. {
  1135.     ch->anotecutcnt = ch->info & 0x0F;
  1136. }
  1137.  
  1138. static void s_notecutb(chn_t *ch)
  1139. {
  1140.     if (ch->anotecutcnt > 0)
  1141.     {
  1142.         if (--ch->anotecutcnt == 0)
  1143.             voice[ch->channelnum].m_speed = 0; // shut down voice (recoverable by using pitch effects)
  1144.     }
  1145. }
  1146.  
  1147. static void s_notedelay(chn_t *ch)
  1148. {
  1149.     ch->anotedelaycnt = ch->info & 0x0F;
  1150. }
  1151.  
  1152. static void s_notedelayb(chn_t *ch)
  1153. {
  1154.     if (ch->anotedelaycnt > 0)
  1155.     {
  1156.         if (--ch->anotedelaycnt == 0)
  1157.             donewnote(ch->channelnum, true);
  1158.     }
  1159. }
  1160.  
  1161. static void s_patterdelay(chn_t *ch)
  1162. {
  1163.     if (patterndelay == 0)
  1164.         patterndelay = ch->info & 0x0F;
  1165. }
  1166.  
  1167. static void s_setspeed(chn_t *ch)
  1168. {
  1169.     setspeed(ch->info);
  1170. }
  1171.  
  1172. static void s_jmpto(chn_t *ch)
  1173. {
  1174.     if (ch->info == 0xFF)
  1175.     {
  1176.         breakpat = 255;
  1177.     }
  1178.     else
  1179.     {
  1180.         breakpat = 1;
  1181.         jmptoord = ch->info;
  1182.     }
  1183. }
  1184.  
  1185. static void s_break(chn_t *ch)
  1186. {
  1187.     uint8_t hi, lo;
  1188.  
  1189.     hi = ch->info >> 4;
  1190.     lo = ch->info & 0x0F;
  1191.  
  1192.     if (hi <= 9 && lo <= 9)
  1193.     {
  1194.         startrow = (hi * 10) + lo;
  1195.         breakpat = 1;
  1196.     }
  1197. }
  1198.  
  1199. static void s_volslide(chn_t *ch)
  1200. {
  1201.     uint8_t infohi;
  1202.     uint8_t infolo;
  1203.  
  1204.     getlastnfo(ch);
  1205.  
  1206.     infohi = ch->info >> 4;
  1207.     infolo = ch->info & 0x0F;
  1208.  
  1209.     if (infolo == 0x0F)
  1210.     {
  1211.              if (infohi == 0) ch->avol -= infolo;
  1212.         else if (musiccount == 0) ch->avol += infohi;
  1213.     }
  1214.     else if (infohi == 0x0F)
  1215.     {
  1216.              if (infolo == 0) ch->avol += infohi;
  1217.         else if (musiccount == 0) ch->avol -= infolo;
  1218.     }
  1219.     else if (fastvolslide || musiccount > 0)
  1220.     {
  1221.              if (infolo == 0) ch->avol += infohi;
  1222.         else ch->avol -= infolo;
  1223.     }
  1224.     else
  1225.     {
  1226.         return; // illegal slide
  1227.     }
  1228.  
  1229.     ch->avol = CLAMP(ch->avol, 0, 63);
  1230.     setvol(ch, true);
  1231.  
  1232.     // these are set on Kxy/Lxx
  1233.          if (volslidetype == 1) s_vibrato(ch);
  1234.     else if (volslidetype == 2) s_toneslide(ch);
  1235. }
  1236.  
  1237. static void s_slidedown(chn_t *ch)
  1238. {
  1239.     if (ch->aorgspd <= 0)
  1240.         return;
  1241.  
  1242.     getlastnfo(ch);
  1243.  
  1244.     if (musiccount > 0)
  1245.     {
  1246.         if (ch->info >= 0xE0)
  1247.             return; // no fine slides here
  1248.  
  1249.         ch->aspd += ch->info << 2;
  1250.         if ((uint16_t)ch->aspd > 32767)
  1251.             ch->aspd = 32767;
  1252.     }
  1253.     else
  1254.     {
  1255.         if (ch->info <= 0xE0)
  1256.             return; // only fine slides here
  1257.  
  1258.         if (ch->info <= 0xF0)
  1259.         {
  1260.             ch->aspd += ch->info & 0x0F;
  1261.             if ((uint16_t)ch->aspd > 32767)
  1262.                 ch->aspd = 32767;
  1263.         }
  1264.         else
  1265.         {
  1266.             ch->aspd += (ch->info & 0x0F) << 2;
  1267.             if ((uint16_t)ch->aspd > 32767)
  1268.                 ch->aspd = 32767;
  1269.         }
  1270.     }
  1271.  
  1272.     ch->aorgspd = ch->aspd;
  1273.     setspd(ch);
  1274. }
  1275.  
  1276. static void s_slideup(chn_t *ch)
  1277. {
  1278.     if (ch->aorgspd <= 0)
  1279.         return;
  1280.  
  1281.     getlastnfo(ch);
  1282.  
  1283.     if (musiccount > 0)
  1284.     {
  1285.         if (ch->info >= 0xE0)
  1286.             return; // no fine slides here
  1287.  
  1288.         ch->aspd -= ch->info << 2;
  1289.         if (ch->aspd < 0)
  1290.             ch->aspd = 0;
  1291.     }
  1292.     else
  1293.     {
  1294.         if (ch->info <= 0xE0)
  1295.             return; // only fine slides here
  1296.  
  1297.         if (ch->info <= 0xF0)
  1298.         {
  1299.             ch->aspd -= ch->info & 0x0F;
  1300.             if (ch->aspd < 0)
  1301.                 ch->aspd = 0;
  1302.         }
  1303.         else
  1304.         {
  1305.             ch->aspd -= (ch->info & 0x0F) << 2;
  1306.             if (ch->aspd < 0)
  1307.                 ch->aspd = 0;
  1308.         }
  1309.     }
  1310.  
  1311.     ch->aorgspd = ch->aspd;
  1312.     setspd(ch);
  1313. }
  1314.  
  1315. static void s_toneslide(chn_t *ch)
  1316. {
  1317.     if (volslidetype == 2) // we came from an Lxy (toneslide+volslide)
  1318.     {
  1319.         ch->info = ch->alasteff1;
  1320.     }
  1321.     else
  1322.     {
  1323.         if (ch->aorgspd == 0)
  1324.         {
  1325.             if (ch->asldspd == 0)
  1326.                 return;
  1327.  
  1328.             ch->aorgspd = ch->asldspd;
  1329.             ch->aspd = ch->asldspd;
  1330.         }
  1331.  
  1332.         if (ch->info == 0)
  1333.             ch->info = ch->alasteff1;
  1334.         else
  1335.             ch->alasteff1 = ch->info;
  1336.     }
  1337.  
  1338.     if (ch->aorgspd != ch->asldspd)
  1339.     {
  1340.         if (ch->aorgspd < ch->asldspd)
  1341.         {
  1342.             ch->aorgspd += ch->info << 2;
  1343.             if ((uint16_t)ch->aorgspd > (uint16_t)ch->asldspd)
  1344.                 ch->aorgspd = ch->asldspd;
  1345.         }
  1346.         else
  1347.         {
  1348.             ch->aorgspd -= ch->info << 2;
  1349.             if (ch->aorgspd < ch->asldspd)
  1350.                 ch->aorgspd = ch->asldspd;
  1351.         }
  1352.  
  1353.         if (ch->aglis)
  1354.             ch->aspd = roundspd(ch, ch->aorgspd);
  1355.         else
  1356.             ch->aspd = ch->aorgspd;
  1357.  
  1358.         setspd(ch);
  1359.     }
  1360. }
  1361.  
  1362. static void s_vibrato(chn_t *ch)
  1363. {
  1364.     int8_t type;
  1365.     int16_t cnt;
  1366.     int32_t dat;
  1367.  
  1368.     if (volslidetype == 1) // we came from a Kxy (vibrato+volslide)
  1369.     {
  1370.         ch->info = ch->alasteff;
  1371.     }
  1372.     else
  1373.     {
  1374.         if (ch->info == 0)
  1375.             ch->info = ch->alasteff;
  1376.  
  1377.         if ((ch->info & 0xF0) == 0)
  1378.             ch->info = (ch->alasteff & 0xF0) | (ch->info & 0x0F);
  1379.  
  1380.         ch->alasteff = ch->info;
  1381.     }
  1382.  
  1383.     if (ch->aorgspd > 0)
  1384.     {
  1385.         cnt  = ch->avibcnt;
  1386.         type = (ch->avibtretype & 0x0E) >> 1;
  1387.         dat  = 0;
  1388.  
  1389.         // sine
  1390.         if (type == 0 || type == 4)
  1391.         {
  1392.             if (type == 4)
  1393.             {
  1394.                 cnt &= 0x7F;
  1395.             }
  1396.             else
  1397.             {
  1398.                 if (cnt & 0x80)
  1399.                     cnt = 0;
  1400.             }
  1401.  
  1402.             dat = vibsin[cnt >> 1];
  1403.         }
  1404.  
  1405.         // ramp
  1406.         else if (type == 1 || type == 5)
  1407.         {
  1408.             if (type == 5)
  1409.             {
  1410.                 cnt &= 0x7F;
  1411.             }
  1412.             else
  1413.             {
  1414.                 if (cnt & 0x80)
  1415.                     cnt = 0;
  1416.             }
  1417.  
  1418.             dat = vibramp[cnt >> 1];
  1419.         }
  1420.  
  1421.         // square
  1422.         else if (type == 2 || type == 6)
  1423.         {
  1424.             if (type == 6)
  1425.             {
  1426.                 cnt &= 0x7F;
  1427.             }
  1428.             else
  1429.             {
  1430.                 if (cnt & 0x80)
  1431.                     cnt = 0;
  1432.             }
  1433.  
  1434.             dat = vibsqu[cnt >> 1];
  1435.         }
  1436.  
  1437.         // random
  1438.         else if (type == 3 || type == 7)
  1439.         {
  1440.             if (type == 7)
  1441.             {
  1442.                 cnt &= 0x7F;
  1443.             }
  1444.             else
  1445.             {
  1446.                 if (cnt & 0x80)
  1447.                     cnt = 0;
  1448.             }
  1449.  
  1450.             dat  = vibsin[cnt >> 1];
  1451.             cnt += (patmusicrand & 0x1E);
  1452.         }
  1453.  
  1454.         if (oldstvib)
  1455.             ch->aspd = ch->aorgspd + ((int16_t)(dat * (ch->info & 0x0F)) >> 4);
  1456.         else
  1457.             ch->aspd = ch->aorgspd + ((int16_t)(dat * (ch->info & 0x0F)) >> 5);
  1458.  
  1459.         setspd(ch);
  1460.  
  1461.         ch->avibcnt = (cnt + ((ch->info >> 4) << 1)) & 126;
  1462.     }
  1463. }
  1464.  
  1465. static void s_tremor(chn_t *ch)
  1466. {
  1467.     getlastnfo(ch);
  1468.  
  1469.     if (ch->atremor > 0)
  1470.     {
  1471.         ch->atremor--;
  1472.         return;
  1473.     }
  1474.  
  1475.     if (ch->atreon)
  1476.     {
  1477.         // set to off
  1478.         ch->atreon = false;
  1479.  
  1480.         ch->avol = 0;
  1481.         setvol(ch, true);
  1482.  
  1483.         ch->atremor = ch->info & 0x0F;
  1484.     }
  1485.     else
  1486.     {
  1487.         // set to on
  1488.         ch->atreon = true;
  1489.  
  1490.         ch->avol = ch->aorgvol;
  1491.         setvol(ch, true);
  1492.  
  1493.         ch->atremor = ch->info >> 4;
  1494.     }
  1495. }
  1496.  
  1497. static void s_arp(chn_t *ch)
  1498. {
  1499.     int8_t note, octa, noteadd;
  1500.     uint8_t tick;
  1501.  
  1502.     getlastnfo(ch);
  1503.  
  1504.     tick = musiccount % 3;
  1505.  
  1506.          if (tick == 1) noteadd = ch->info >> 4;
  1507.     else if (tick == 2) noteadd = ch->info & 0x0F;
  1508.     else noteadd = 0;
  1509.  
  1510.     // check for octave overflow
  1511.     octa =  ch->lastnote & 0xF0;
  1512.     note = (ch->lastnote & 0x0F) + noteadd;
  1513.  
  1514.     while (note >= 12)
  1515.     {
  1516.         note -= 12;
  1517.         octa += 16;
  1518.     }
  1519.  
  1520.     ch->aspd = scalec2spd(ch, stnote2herz(octa | note));
  1521.     setspd(ch);
  1522. }
  1523.  
  1524. static void s_vibvol(chn_t *ch)
  1525. {
  1526.     volslidetype = 1;
  1527.     s_volslide(ch);
  1528. }
  1529.  
  1530. static void s_tonevol(chn_t *ch)
  1531. {
  1532.     volslidetype = 2;
  1533.     s_volslide(ch);
  1534. }
  1535.  
  1536. static void s_retrig(chn_t *ch)
  1537. {
  1538.     uint8_t infohi;
  1539.  
  1540.     getlastnfo(ch);
  1541.     infohi = ch->info >> 4;
  1542.  
  1543.     if ((ch->info & 0x0F) == 0 || ch->atrigcnt < (ch->info & 0x0F))
  1544.     {
  1545.         ch->atrigcnt++;
  1546.         return;
  1547.     }
  1548.  
  1549.     ch->atrigcnt = 0;
  1550.  
  1551.     voiceSetSamplePosition(ch->channelnum, 0);
  1552.  
  1553.     if (retrigvoladd[infohi+16] == 0)
  1554.         ch->avol += retrigvoladd[infohi];
  1555.     else
  1556.         ch->avol = (int8_t)((ch->avol * retrigvoladd[16 + infohi]) >> 4);
  1557.  
  1558.     ch->avol = CLAMP(ch->avol, 0, 63);
  1559.     setvol(ch, true);
  1560.  
  1561.     ch->atrigcnt++; // probably a bug?
  1562. }
  1563.  
  1564. static void s_tremolo(chn_t *ch)
  1565. {
  1566.     int8_t type;
  1567.     int16_t cnt, dat;
  1568.  
  1569.     getlastnfo(ch);
  1570.  
  1571.     if ((ch->info & 0xF0) == 0)
  1572.         ch->info = (ch->alastnfo & 0xF0) | (ch->info & 0x0F);
  1573.  
  1574.     ch->alastnfo = ch->info;
  1575.  
  1576.     if (ch->aorgvol > 0)
  1577.     {
  1578.         cnt = ch->avibcnt;
  1579.         type = ch->avibtretype >> 5;
  1580.         dat = 0;
  1581.  
  1582.         // sine
  1583.         if (type == 0 || type == 4)
  1584.         {
  1585.             if (type == 4)
  1586.             {
  1587.                 cnt &= 0x7F;
  1588.             }
  1589.             else
  1590.             {
  1591.                 if (cnt & 0x80)
  1592.                     cnt = 0;
  1593.             }
  1594.  
  1595.             dat = vibsin[cnt >> 1];
  1596.         }
  1597.  
  1598.         // ramp
  1599.         else if (type == 1 || type == 5)
  1600.         {
  1601.             if (type == 5)
  1602.             {
  1603.                 cnt &= 0x7F;
  1604.             }
  1605.             else
  1606.             {
  1607.                 if (cnt & 0x80)
  1608.                     cnt = 0;
  1609.             }
  1610.  
  1611.             dat = vibramp[cnt >> 1];
  1612.         }
  1613.  
  1614.         // square
  1615.         else if (type == 2 || type == 6)
  1616.         {
  1617.             if (type == 6)
  1618.             {
  1619.                 cnt &= 0x7F;
  1620.             }
  1621.             else
  1622.             {
  1623.                 if (cnt & 0x80)
  1624.                     cnt = 0;
  1625.             }
  1626.  
  1627.             dat = vibsqu[cnt >> 1];
  1628.         }
  1629.  
  1630.         // random
  1631.         else if (type == 3 || type == 7)
  1632.         {
  1633.             if (type == 7)
  1634.             {
  1635.                 cnt &= 0x7F;
  1636.             }
  1637.             else
  1638.             {
  1639.                 if (cnt & 0x80)
  1640.                     cnt = 0;
  1641.             }
  1642.  
  1643.             dat = vibsin[cnt >> 1];
  1644.             cnt += (patmusicrand & 0x1E);
  1645.         }
  1646.  
  1647.         dat = ch->aorgvol + (int8_t)((dat * (ch->info & 0x0F)) >> 7);
  1648.         dat = CLAMP(dat, 0, 63);
  1649.  
  1650.         ch->avol = (int8_t)dat;
  1651.         setvol(ch, true);
  1652.  
  1653.         ch->avibcnt = (cnt + ((ch->info & 0xF0) >> 3)) & 126;
  1654.     }
  1655. }
  1656.  
  1657. static void s_scommand1(chn_t *ch)
  1658. {
  1659.     getlastnfo(ch);
  1660.     ssoncejmp[ch->info >> 4](ch);
  1661. }
  1662.  
  1663. static void s_scommand2(chn_t *ch)
  1664. {
  1665.     getlastnfo(ch);
  1666.     ssotherjmp[ch->info >> 4](ch);
  1667. }
  1668.  
  1669. static void s_settempo(chn_t *ch)
  1670. {
  1671.     if (!musiccount && ch->info >= 0x20)
  1672.         settempo(ch->info);
  1673. }
  1674.  
  1675. static void s_finevibrato(chn_t *ch)
  1676. {
  1677.     int8_t type;
  1678.     int16_t cnt;
  1679.     int32_t dat;
  1680.  
  1681.     if (ch->info == 0)
  1682.         ch->info = ch->alasteff;
  1683.  
  1684.     if ((ch->info & 0xF0) == 0)
  1685.         ch->info = (ch->alasteff & 0xF0) | (ch->info & 0x0F);
  1686.  
  1687.     ch->alasteff = ch->info;
  1688.  
  1689.     if (ch->aorgspd > 0)
  1690.     {
  1691.         cnt = ch->avibcnt;
  1692.         type = (ch->avibtretype & 0x0E) >> 1;
  1693.         dat = 0;
  1694.  
  1695.         // sine
  1696.         if (type == 0 || type == 4)
  1697.         {
  1698.             if (type == 4)
  1699.             {
  1700.                 cnt &= 0x7F;
  1701.             }
  1702.             else
  1703.             {
  1704.                 if (cnt & 0x80)
  1705.                     cnt = 0;
  1706.             }
  1707.  
  1708.             dat = vibsin[cnt >> 1];
  1709.         }
  1710.  
  1711.         // ramp
  1712.         else if (type == 1 || type == 5)
  1713.         {
  1714.             if (type == 5)
  1715.             {
  1716.                 cnt &= 0x7F;
  1717.             }
  1718.             else
  1719.             {
  1720.                 if (cnt & 0x80)
  1721.                     cnt = 0;
  1722.             }
  1723.  
  1724.             dat = vibramp[cnt >> 1];
  1725.         }
  1726.  
  1727.         // square
  1728.         else if (type == 2 || type == 6)
  1729.         {
  1730.             if (type == 6)
  1731.             {
  1732.                 cnt &= 0x7F;
  1733.             }
  1734.             else
  1735.             {
  1736.                 if (cnt & 0x80)
  1737.                     cnt = 0;
  1738.             }
  1739.  
  1740.             dat = vibsqu[cnt >> 1];
  1741.         }
  1742.  
  1743.         // random
  1744.         else if (type == 3 || type == 7)
  1745.         {
  1746.             if (type == 7)
  1747.             {
  1748.                 cnt &= 0x7F;
  1749.             }
  1750.             else
  1751.             {
  1752.                 if (cnt & 0x80)
  1753.                     cnt = 0;
  1754.             }
  1755.  
  1756.             dat  = vibsin[cnt >> 1];
  1757.             cnt += (patmusicrand & 0x1E);
  1758.         }
  1759.  
  1760.         if (oldstvib)
  1761.             ch->aspd = ch->aorgspd + ((int16_t)(dat * (ch->info & 0x0F)) >> 6);
  1762.         else
  1763.             ch->aspd = ch->aorgspd + ((int16_t)(dat * (ch->info & 0x0F)) >> 7);
  1764.  
  1765.         setspd(ch);
  1766.  
  1767.         ch->avibcnt = (cnt + ((ch->info >> 4) << 1)) & 126;
  1768.     }
  1769. }
  1770.  
  1771. static void s_setgvol(chn_t *ch)
  1772. {
  1773.     if (ch->info <= 64)
  1774.         setglobalvol(ch->info);
  1775. }
  1776.  
  1777. static void voiceSetSource(uint8_t voiceNumber, const int8_t *sampleData,
  1778.     int32_t length, int32_t loopStart, int32_t loopLength,
  1779.     bool loopFlag, bool sampleIs16Bit)
  1780. {
  1781.     voice_t *v = &voice[voiceNumber];
  1782.  
  1783.     if (sampleData == NULL)
  1784.     {
  1785.         v->m_mixfunc = NULL; // shut down voice
  1786.         return;
  1787.     }
  1788.  
  1789.     v->m_loopflag = loopFlag;
  1790.     v->m_end = loopFlag ? (loopStart + loopLength) : length;
  1791.     v->m_looplen  = loopLength;
  1792.  
  1793.     // test sample swapping overflowing (with new sample length/loopLen)
  1794.     if (v->m_pos >= v->m_end)
  1795.     {
  1796.         v->m_mixfunc = NULL;
  1797.         return;
  1798.     }
  1799.  
  1800.     if (sampleIs16Bit)
  1801.         v->m_base16 = (int16_t *)sampleData;
  1802.     else
  1803.         v->m_base8 = sampleData;
  1804.  
  1805.     v->m_mixfunc = mixRoutineTable[(sampleIs16Bit << 2) + (interpolationFlag << 1) + v->m_loopflag];
  1806. }
  1807.  
  1808. static void voiceSetSamplePosition(uint8_t voiceNumber, uint16_t value)
  1809. {
  1810.     voice_t *v = &voice[voiceNumber];
  1811.  
  1812.     v->m_pos = value;
  1813.     v->m_posfrac = 0;
  1814.  
  1815.     // confirmed ST3.21 overflow behavior for Sample Offset (effect Oxx)
  1816.  
  1817.     if (v->m_pos >= v->m_end)
  1818.     {
  1819.         if (soundcardtype == SOUNDCARD_SBPRO)
  1820.         {
  1821.             // Sound Blaster
  1822.             v->m_mixfunc = NULL; // shut down voice
  1823.         }
  1824.         else
  1825.         {
  1826.             // GUS
  1827.             if (v->m_loopflag)
  1828.             {
  1829.                 // loop wrapping
  1830.                 do
  1831.                 {
  1832.                     v->m_pos -= v->m_looplen;
  1833.                 }
  1834.                 while (v->m_pos >= v->m_end);
  1835.             }
  1836.             else
  1837.             {
  1838.                 v->m_mixfunc = NULL; // shut down voice
  1839.             }
  1840.         }
  1841.     }
  1842. }
  1843.  
  1844. static void voiceSetVolume(uint8_t voiceNumber, uint16_t vol, uint8_t pan)
  1845. {
  1846.     const uint16_t centerPanVal = 1 << ((4 - 1) + 6);
  1847.     uint16_t panL, panR, tmpPan;
  1848.     voice_t *v;
  1849.     chn_t *ch;
  1850.  
  1851.     v  = &voice[voiceNumber];
  1852.     ch = &chn[voiceNumber];
  1853.  
  1854.     if (!stereomode)
  1855.     {
  1856.         // mono (center)
  1857.  
  1858.         if (soundcardtype == SOUNDCARD_SBPRO)
  1859.         {
  1860.             panL = centerPanVal;
  1861.             panR = centerPanVal;
  1862.         }
  1863.         else
  1864.         {
  1865.             panL = guspantab[7];
  1866.             panR = guspantab[7];
  1867.         }
  1868.     }
  1869.     else
  1870.     {
  1871.         // stereo
  1872.  
  1873.         if (soundcardtype == SOUNDCARD_SBPRO)
  1874.         {
  1875.             tmpPan = pan << 6; // 0..15 -> 0..960
  1876.  
  1877.             panL = 960 - tmpPan;
  1878.             panR = tmpPan;
  1879.         }
  1880.         else
  1881.         {
  1882.             panL = guspantab[0x0F - pan];
  1883.             panR = guspantab[pan];
  1884.         }
  1885.     }
  1886.  
  1887.     // in SB stereo mode, you can use effect SAx to control certain things
  1888.     if (ch->amixtype > 0 && soundcardtype == SOUNDCARD_SBPRO && stereomode)
  1889.     {
  1890.         if (ch->amixtype >= 4)
  1891.         {
  1892.             // center mixing
  1893.             panL = centerPanVal;
  1894.             panR = centerPanVal;
  1895.         }
  1896.         else if ((ch->amixtype & 1) == 1)
  1897.         {
  1898.             // swap L/R
  1899.             tmpPan = panL;
  1900.             panL = panR;
  1901.             panR = tmpPan;
  1902.         }
  1903.     }
  1904.  
  1905.     v->m_vol_l = vol * panL;
  1906.     v->m_vol_r = vol * panR;
  1907. }
  1908.  
  1909. /* ----------------------------------------------------------------------- */
  1910. /*                          GENERAL MIXER MACROS                           */
  1911. /* ----------------------------------------------------------------------- */
  1912.  
  1913. #define GET_MIXER_VARS \
  1914.     audioMixL = mixBufferL; \
  1915.     audioMixR = mixBufferR; \
  1916.     mixInMono = (volL == volR); \
  1917.     realPos = v->m_pos; \
  1918.     pos = v->m_posfrac; /* 16.16 fixed point */ \
  1919.     delta = v->m_speed; \
  1920.  
  1921. #define SET_BASE8 \
  1922.     base = v->m_base8; \
  1923.     smpPtr = base + realPos; \
  1924.  
  1925. #define SET_BASE16 \
  1926.     base = v->m_base16; \
  1927.     smpPtr = base + realPos; \
  1928.  
  1929. #define SET_BACK_MIXER_POS \
  1930.     v->m_posfrac = pos; \
  1931.     v->m_pos = realPos; \
  1932.  
  1933. #define GET_VOL \
  1934.     volL = v->m_vol_l; \
  1935.     volR = v->m_vol_r; \
  1936.  
  1937. #define GET_VOL_EXTEND \
  1938.     volL = v->m_vol_l << 8; \
  1939.     volR = v->m_vol_r << 8; \
  1940.  
  1941. #define INC_POS \
  1942.     pos += delta; \
  1943.     smpPtr += pos >> 16; \
  1944.     pos &= 0xFFFF; \
  1945.  
  1946. /* ----------------------------------------------------------------------- */
  1947. /*                          SAMPLE RENDERING MACROS                        */
  1948. /* ----------------------------------------------------------------------- */
  1949.  
  1950. // 3-tap quadratic interpolation
  1951.  
  1952. // in: int32_t s1,s2,s3 = -128..127 | f = 0..65535 (frac) | out: s1 (will exceed 16-bits because of overshoot)
  1953. #define INTERPOLATE8(s1, s2, s3, f) \
  1954. { \
  1955.     int32_t s4, frac = f >> 1; \
  1956.     \
  1957.     s2 <<= 8; \
  1958.     s4 = ((s1 + s3) << (8 - 1)) - s2; \
  1959.     s4 = ((s4 * frac) >> 16) + s2; \
  1960.     s3 = (s1 + s3) << (8 - 1); \
  1961.     s1 <<= 8; \
  1962.     s3 = (s1 + s3) >> 1; \
  1963.     s1 += ((s4 - s3) * frac) >> 14; \
  1964. } \
  1965.  
  1966. // in: int32_t s1,s2,s3 = -32768..32767 | f = 0..65535 (frac) | out: s1 (will exceed 16-bits because of overshoot)
  1967. #define INTERPOLATE16(s1, s2, s3, f) \
  1968. { \
  1969.     int32_t s4, frac = f >> 1; \
  1970.     \
  1971.     s4 = ((s1 + s3) >> 1) - s2; \
  1972.     s4 = ((s4 * frac) >> 16) + s2; \
  1973.     s3 = (s1 + s3) >> 1; \
  1974.     s3 = (s1 + s3) >> 1; \
  1975.     s1 += ((s4 - s3) * frac) >> 14; \
  1976. } \
  1977.  
  1978. #define RENDER_SMP \
  1979.     sample = *smpPtr; \
  1980.     *audioMixL++ += (sample * volL) >> 16; \
  1981.     *audioMixR++ += (sample * volR) >> 16; \
  1982.  
  1983. #define RENDER_SMP_MONO \
  1984.     sample = (*smpPtr * volL) >> 16; \
  1985.     *audioMixL++ += sample; \
  1986.     *audioMixR++ += sample; \
  1987.  
  1988. #define RENDER_8BIT_SMP_INTRP \
  1989.     sample = smpPtr[0]; \
  1990.     sample2 = smpPtr[1]; \
  1991.     sample3 = smpPtr[2]; \
  1992.     INTERPOLATE8(sample, sample2, sample3, pos) \
  1993.     *audioMixL++ += (sample * volL) >> 16; \
  1994.     *audioMixR++ += (sample * volR) >> 16; \
  1995.  
  1996. #define RENDER_16BIT_SMP_INTRP \
  1997.     sample = smpPtr[0]; \
  1998.     sample2 = smpPtr[1]; \
  1999.     sample3 = smpPtr[2]; \
  2000.     INTERPOLATE16(sample, sample2, sample3, pos) \
  2001.     *audioMixL++ += (sample * volL) >> 16; \
  2002.     *audioMixR++ += (sample * volR) >> 16; \
  2003.  
  2004. #define RENDER_8BIT_SMP_MONO_INTRP \
  2005.     sample = smpPtr[0]; \
  2006.     sample2 = smpPtr[1]; \
  2007.     sample3 = smpPtr[2]; \
  2008.     INTERPOLATE8(sample, sample2, sample3, pos) \
  2009.     sample = (sample * volL) >> 16; \
  2010.     *audioMixL++ += sample; \
  2011.     *audioMixR++ += sample; \
  2012.  
  2013. #define RENDER_16BIT_SMP_MONO_INTRP \
  2014.     sample = smpPtr[0]; \
  2015.     sample2 = smpPtr[1]; \
  2016.     sample3 = smpPtr[2]; \
  2017.     INTERPOLATE16(sample, sample2, sample3, pos) \
  2018.     sample = (sample * volL) >> 16; \
  2019.     *audioMixL++ += sample; \
  2020.     *audioMixR++ += sample; \
  2021.  
  2022. /* ----------------------------------------------------------------------- */
  2023. /*                     SAMPLES-TO-MIX LIMITING MACROS                      */
  2024. /* ----------------------------------------------------------------------- */
  2025.  
  2026. #define LIMIT_MIX_NUM \
  2027.     i = (v->m_end - 1) - realPos; \
  2028.     if (i > 65535) \
  2029.         i = 65535; \
  2030.     \
  2031.     samplesToMix = (((((uint64_t)i << 16) | (pos ^ 0xFFFF)) * v->m_speedrev) >> 32) + 1; \
  2032.     if (samplesToMix > (uint32_t)samplesToRender) \
  2033.         samplesToMix = samplesToRender; \
  2034.     \
  2035.     samplesToRender -= samplesToMix; \
  2036.  
  2037. #define HANDLE_SAMPLE_END \
  2038.     realPos = (uint32_t)(smpPtr - base); \
  2039.     if (realPos >= v->m_end) \
  2040.     { \
  2041.         v->m_mixfunc = NULL; /* shut down voice */ \
  2042.         return; \
  2043.     } \
  2044.  
  2045. #define WRAP_LOOP \
  2046.     realPos = (uint32_t)(smpPtr - base); \
  2047.     while (realPos >= v->m_end) \
  2048.         realPos -= v->m_looplen; \
  2049.     smpPtr = base + realPos; \
  2050.  
  2051. #define VOL0_OPTIMIZATION_NO_LOOP \
  2052.     pos = v->m_posfrac + ((v->m_speed & 0xFFFF) * numSamples); \
  2053.     realPos = v->m_pos + ((v->m_speed >> 16) * numSamples) + (pos >> 16); \
  2054.     \
  2055.     if (realPos >= v->m_end) \
  2056.     { \
  2057.         v->m_mixfunc = NULL; \
  2058.         return; \
  2059.     } \
  2060.     \
  2061.     pos &= 0xFFFF; \
  2062.     SET_BACK_MIXER_POS \
  2063.  
  2064. #define VOL0_OPTIMIZATION_LOOP \
  2065.     pos = v->m_posfrac + ((v->m_speed & 0xFFFF) * numSamples); \
  2066.     realPos = v->m_pos + ((v->m_speed >> 16) * numSamples) + (pos >> 16); \
  2067.     \
  2068.     while (realPos >= v->m_end) \
  2069.         realPos -= v->m_looplen; \
  2070.     \
  2071.     pos &= 0xFFFF; \
  2072.     SET_BACK_MIXER_POS \
  2073.  
  2074. /* ----------------------------------------------------------------------- */
  2075. /*                          8-BIT MIXING ROUTINES                          */
  2076. /* ----------------------------------------------------------------------- */
  2077.  
  2078. static void mix8bNoLoop(voice_t *v, uint32_t numSamples)
  2079. {
  2080.     const int8_t *base;
  2081.     bool mixInMono;
  2082.     int32_t sample, *audioMixL, *audioMixR, samplesToRender;
  2083.     register const int8_t *smpPtr;
  2084.     register int32_t volL, volR;
  2085.     register uint32_t pos, delta;
  2086.     uint32_t realPos, i, samplesToMix;
  2087.  
  2088.     if (v->m_vol_l == 0 && v->m_vol_r == 0)
  2089.     {
  2090.         VOL0_OPTIMIZATION_NO_LOOP
  2091.         return;
  2092.     }
  2093.  
  2094.     GET_VOL_EXTEND
  2095.     GET_MIXER_VARS
  2096.     SET_BASE8
  2097.  
  2098.     samplesToRender = numSamples;
  2099.     while (samplesToRender > 0)
  2100.     {
  2101.         LIMIT_MIX_NUM
  2102.         if (mixInMono)
  2103.         {
  2104.             if (samplesToMix & 1)
  2105.             {
  2106.                 RENDER_SMP_MONO
  2107.                 INC_POS
  2108.             }
  2109.             samplesToMix >>= 1;
  2110.             for (i = 0; i < samplesToMix; i++)
  2111.             {
  2112.                 RENDER_SMP_MONO
  2113.                 INC_POS
  2114.                 RENDER_SMP_MONO
  2115.                 INC_POS
  2116.             }
  2117.         }
  2118.         else
  2119.         {
  2120.             if (samplesToMix & 1)
  2121.             {
  2122.                 RENDER_SMP
  2123.                 INC_POS
  2124.             }
  2125.             samplesToMix >>= 1;
  2126.             for (i = 0; i < samplesToMix; i++)
  2127.             {
  2128.                 RENDER_SMP
  2129.                 INC_POS
  2130.                 RENDER_SMP
  2131.                 INC_POS
  2132.             }
  2133.         }
  2134.         HANDLE_SAMPLE_END
  2135.     }
  2136.  
  2137.     SET_BACK_MIXER_POS
  2138. }
  2139.  
  2140. static void mix8bLoop(voice_t *v, uint32_t numSamples)
  2141. {
  2142.     const int8_t *base;
  2143.     bool mixInMono;
  2144.     int32_t sample, *audioMixL, *audioMixR, samplesToRender;
  2145.     register const int8_t *smpPtr;
  2146.     register int32_t volL, volR;
  2147.     register uint32_t pos, delta;
  2148.     uint32_t realPos, i, samplesToMix;
  2149.    
  2150.     if (v->m_vol_l == 0 && v->m_vol_r == 0)
  2151.     {
  2152.         VOL0_OPTIMIZATION_LOOP
  2153.         return;
  2154.     }
  2155.  
  2156.     GET_VOL_EXTEND
  2157.     GET_MIXER_VARS
  2158.     SET_BASE8
  2159.  
  2160.     samplesToRender = numSamples;
  2161.     while (samplesToRender > 0)
  2162.     {
  2163.         LIMIT_MIX_NUM
  2164.         if (mixInMono)
  2165.         {
  2166.             if (samplesToMix & 1)
  2167.             {
  2168.                 RENDER_SMP_MONO
  2169.                 INC_POS
  2170.             }
  2171.             samplesToMix >>= 1;
  2172.             for (i = 0; i < samplesToMix; i++)
  2173.             {
  2174.                 RENDER_SMP_MONO
  2175.                 INC_POS
  2176.                 RENDER_SMP_MONO
  2177.                 INC_POS
  2178.             }
  2179.         }
  2180.         else
  2181.         {
  2182.             if (samplesToMix & 1)
  2183.             {
  2184.                 RENDER_SMP
  2185.                 INC_POS
  2186.             }
  2187.             samplesToMix >>= 1;
  2188.             for (i = 0; i < samplesToMix; i++)
  2189.             {
  2190.                 RENDER_SMP
  2191.                 INC_POS
  2192.                 RENDER_SMP
  2193.                 INC_POS
  2194.             }
  2195.         }
  2196.         WRAP_LOOP
  2197.     }
  2198.  
  2199.     SET_BACK_MIXER_POS
  2200. }
  2201.  
  2202. static void mix8bNoLoopIntrp(voice_t *v, uint32_t numSamples)
  2203. {
  2204.     const int8_t *base;
  2205.     bool mixInMono;
  2206.     int32_t sample, sample2, sample3, *audioMixL, *audioMixR, samplesToRender;
  2207.     register const int8_t *smpPtr;
  2208.     register int32_t volL, volR;
  2209.     register uint32_t pos, delta;
  2210.     uint32_t realPos, i, samplesToMix;
  2211.  
  2212.     if (v->m_vol_l == 0 && v->m_vol_r == 0)
  2213.     {
  2214.         VOL0_OPTIMIZATION_NO_LOOP
  2215.         return;
  2216.     }
  2217.  
  2218.     GET_VOL
  2219.     GET_MIXER_VARS
  2220.     SET_BASE8
  2221.  
  2222.     samplesToRender = numSamples;
  2223.     while (samplesToRender > 0)
  2224.     {
  2225.         LIMIT_MIX_NUM
  2226.         if (mixInMono)
  2227.         {
  2228.             if (samplesToMix & 1)
  2229.             {
  2230.                 RENDER_8BIT_SMP_MONO_INTRP
  2231.                 INC_POS
  2232.             }
  2233.             samplesToMix >>= 1;
  2234.             for (i = 0; i < samplesToMix; i++)
  2235.             {
  2236.                 RENDER_8BIT_SMP_MONO_INTRP
  2237.                 INC_POS
  2238.                 RENDER_8BIT_SMP_MONO_INTRP
  2239.                 INC_POS
  2240.             }
  2241.         }
  2242.         else
  2243.         {
  2244.             if (samplesToMix & 1)
  2245.             {
  2246.                 RENDER_8BIT_SMP_INTRP
  2247.                 INC_POS
  2248.             }
  2249.             samplesToMix >>= 1;
  2250.             for (i = 0; i < samplesToMix; i++)
  2251.             {
  2252.                 RENDER_8BIT_SMP_INTRP
  2253.                 INC_POS
  2254.                 RENDER_8BIT_SMP_INTRP
  2255.                 INC_POS
  2256.             }
  2257.         }
  2258.         HANDLE_SAMPLE_END
  2259.     }
  2260.  
  2261.     SET_BACK_MIXER_POS
  2262. }
  2263.  
  2264. static void mix8bLoopIntrp(voice_t *v, uint32_t numSamples)
  2265. {
  2266.     const int8_t *base;
  2267.     bool mixInMono;
  2268.     int32_t sample, sample2, sample3, *audioMixL, *audioMixR, samplesToRender;
  2269.     register const int8_t *smpPtr;
  2270.     register int32_t volL, volR;
  2271.     register uint32_t pos, delta;
  2272.     uint32_t realPos, i, samplesToMix;
  2273.  
  2274.     if (v->m_vol_l == 0 && v->m_vol_r == 0)
  2275.     {
  2276.         VOL0_OPTIMIZATION_LOOP
  2277.         return;
  2278.     }
  2279.  
  2280.     GET_VOL
  2281.     GET_MIXER_VARS
  2282.     SET_BASE8
  2283.  
  2284.     samplesToRender = numSamples;
  2285.     while (samplesToRender > 0)
  2286.     {
  2287.         LIMIT_MIX_NUM
  2288.         if (mixInMono)
  2289.         {
  2290.             if (samplesToMix & 1)
  2291.             {
  2292.                 RENDER_8BIT_SMP_MONO_INTRP
  2293.                 INC_POS
  2294.             }
  2295.             samplesToMix >>= 1;
  2296.             for (i = 0; i < samplesToMix; i++)
  2297.             {
  2298.                 RENDER_8BIT_SMP_MONO_INTRP
  2299.                 INC_POS
  2300.                 RENDER_8BIT_SMP_MONO_INTRP
  2301.                 INC_POS
  2302.             }
  2303.         }
  2304.         else
  2305.         {
  2306.             if (samplesToMix & 1)
  2307.             {
  2308.                 RENDER_8BIT_SMP_INTRP
  2309.                 INC_POS
  2310.             }
  2311.             samplesToMix >>= 1;
  2312.             for (i = 0; i < samplesToMix; i++)
  2313.             {
  2314.                 RENDER_8BIT_SMP_INTRP
  2315.                 INC_POS
  2316.                 RENDER_8BIT_SMP_INTRP
  2317.                 INC_POS
  2318.             }
  2319.         }
  2320.         WRAP_LOOP
  2321.     }
  2322.  
  2323.     SET_BACK_MIXER_POS
  2324. }
  2325.  
  2326. /* ----------------------------------------------------------------------- */
  2327. /*                          16-BIT MIXING ROUTINES                         */
  2328. /* ----------------------------------------------------------------------- */
  2329.  
  2330. static void mix16bNoLoop(voice_t *v, uint32_t numSamples)
  2331. {
  2332.     bool mixInMono;
  2333.     const int16_t *base;
  2334.     int32_t sample, *audioMixL, *audioMixR, samplesToRender;
  2335.     register const int16_t *smpPtr;
  2336.     register int32_t volL, volR;
  2337.     register uint32_t pos, delta;
  2338.     uint32_t realPos, i, samplesToMix;
  2339.  
  2340.     if (v->m_vol_l == 0 && v->m_vol_r == 0)
  2341.     {
  2342.         VOL0_OPTIMIZATION_NO_LOOP
  2343.         return;
  2344.     }
  2345.  
  2346.     GET_VOL
  2347.     GET_MIXER_VARS
  2348.     SET_BASE16
  2349.  
  2350.     samplesToRender = numSamples;
  2351.     while (samplesToRender > 0)
  2352.     {
  2353.         LIMIT_MIX_NUM
  2354.         if (mixInMono)
  2355.         {
  2356.             if (samplesToMix & 1)
  2357.             {
  2358.                 RENDER_SMP_MONO
  2359.                 INC_POS
  2360.             }
  2361.             samplesToMix >>= 1;
  2362.             for (i = 0; i < samplesToMix; i++)
  2363.             {
  2364.                 RENDER_SMP_MONO
  2365.                 INC_POS
  2366.                 RENDER_SMP_MONO
  2367.                 INC_POS
  2368.             }
  2369.         }
  2370.         else
  2371.         {
  2372.             if (samplesToMix & 1)
  2373.             {
  2374.                 RENDER_SMP
  2375.                 INC_POS
  2376.             }
  2377.             samplesToMix >>= 1;
  2378.             for (i = 0; i < samplesToMix; i++)
  2379.             {
  2380.                 RENDER_SMP
  2381.                 INC_POS
  2382.                 RENDER_SMP
  2383.                 INC_POS
  2384.             }
  2385.         }
  2386.         HANDLE_SAMPLE_END
  2387.     }
  2388.  
  2389.     SET_BACK_MIXER_POS
  2390. }
  2391.  
  2392. static void mix16bLoop(voice_t *v, uint32_t numSamples)
  2393. {
  2394.     bool mixInMono;
  2395.     const int16_t *base;
  2396.     int32_t sample, *audioMixL, *audioMixR, samplesToRender;
  2397.     register const int16_t *smpPtr;
  2398.     register int32_t volL, volR;
  2399.     register uint32_t pos, delta;
  2400.     uint32_t realPos, i, samplesToMix;
  2401.  
  2402.     if (v->m_vol_l == 0 && v->m_vol_r == 0)
  2403.     {
  2404.         VOL0_OPTIMIZATION_LOOP
  2405.         return;
  2406.     }
  2407.  
  2408.     GET_VOL
  2409.     GET_MIXER_VARS
  2410.     SET_BASE16
  2411.  
  2412.     samplesToRender = numSamples;
  2413.     while (samplesToRender > 0)
  2414.     {
  2415.         LIMIT_MIX_NUM
  2416.         if (mixInMono)
  2417.         {
  2418.             if (samplesToMix & 1)
  2419.             {
  2420.                 RENDER_SMP_MONO
  2421.                 INC_POS
  2422.             }
  2423.             samplesToMix >>= 1;
  2424.             for (i = 0; i < samplesToMix; i++)
  2425.             {
  2426.                 RENDER_SMP_MONO
  2427.                 INC_POS
  2428.                 RENDER_SMP_MONO
  2429.                 INC_POS
  2430.             }
  2431.         }
  2432.         else
  2433.         {
  2434.             if (samplesToMix & 1)
  2435.             {
  2436.                 RENDER_SMP
  2437.                 INC_POS
  2438.             }
  2439.             samplesToMix >>= 1;
  2440.             for (i = 0; i < samplesToMix; i++)
  2441.             {
  2442.                 RENDER_SMP
  2443.                 INC_POS
  2444.                 RENDER_SMP
  2445.                 INC_POS
  2446.             }
  2447.         }
  2448.         WRAP_LOOP
  2449.     }
  2450.  
  2451.     SET_BACK_MIXER_POS
  2452. }
  2453.  
  2454. static void mix16bNoLoopIntrp(voice_t *v, uint32_t numSamples)
  2455. {
  2456.     bool mixInMono;
  2457.     const int16_t *base;
  2458.     int32_t sample, sample2, sample3, *audioMixL, *audioMixR, samplesToRender;
  2459.     register const int16_t *smpPtr;
  2460.     register int32_t volL, volR;
  2461.     register uint32_t pos, delta;
  2462.     uint32_t realPos, i, samplesToMix;
  2463.  
  2464.     if (v->m_vol_l == 0 && v->m_vol_r == 0)
  2465.     {
  2466.         VOL0_OPTIMIZATION_NO_LOOP
  2467.         return;
  2468.     }
  2469.  
  2470.     GET_VOL
  2471.     GET_MIXER_VARS
  2472.     SET_BASE16
  2473.  
  2474.     samplesToRender = numSamples;
  2475.     while (samplesToRender > 0)
  2476.     {
  2477.         LIMIT_MIX_NUM
  2478.         if (mixInMono)
  2479.         {
  2480.             if (samplesToMix & 1)
  2481.             {
  2482.                 RENDER_16BIT_SMP_MONO_INTRP
  2483.                 INC_POS
  2484.             }
  2485.             samplesToMix >>= 1;
  2486.             for (i = 0; i < samplesToMix; i++)
  2487.             {
  2488.                 RENDER_16BIT_SMP_MONO_INTRP
  2489.                 INC_POS
  2490.                 RENDER_16BIT_SMP_MONO_INTRP
  2491.                 INC_POS
  2492.             }
  2493.         }
  2494.         else
  2495.         {
  2496.             if (samplesToMix & 1)
  2497.             {
  2498.                 RENDER_16BIT_SMP_INTRP
  2499.                 INC_POS
  2500.             }
  2501.             samplesToMix >>= 1;
  2502.             for (i = 0; i < samplesToMix; i++)
  2503.             {
  2504.                 RENDER_16BIT_SMP_INTRP
  2505.                 INC_POS
  2506.                 RENDER_16BIT_SMP_INTRP
  2507.                 INC_POS
  2508.             }
  2509.         }
  2510.         HANDLE_SAMPLE_END
  2511.     }
  2512.  
  2513.     SET_BACK_MIXER_POS
  2514. }
  2515.  
  2516. static void mix16bLoopIntrp(voice_t *v, uint32_t numSamples)
  2517. {
  2518.     bool mixInMono;
  2519.     const int16_t *base;
  2520.     int32_t sample, sample2, sample3, *audioMixL, *audioMixR, samplesToRender;
  2521.     register const int16_t *smpPtr;
  2522.     register int32_t volL, volR;
  2523.     register uint32_t pos, delta;
  2524.     uint32_t realPos, i, samplesToMix;
  2525.  
  2526.     if (v->m_vol_l == 0 && v->m_vol_r == 0)
  2527.     {
  2528.         VOL0_OPTIMIZATION_LOOP
  2529.         return;
  2530.     }
  2531.  
  2532.     GET_VOL
  2533.     GET_MIXER_VARS
  2534.     SET_BASE16
  2535.  
  2536.     samplesToRender = numSamples;
  2537.     while (samplesToRender > 0)
  2538.     {
  2539.         LIMIT_MIX_NUM
  2540.         if (mixInMono)
  2541.         {
  2542.             if (samplesToMix & 1)
  2543.             {
  2544.                 RENDER_16BIT_SMP_MONO_INTRP
  2545.                 INC_POS
  2546.             }
  2547.             samplesToMix >>= 1;
  2548.             for (i = 0; i < samplesToMix; i++)
  2549.             {
  2550.                 RENDER_16BIT_SMP_MONO_INTRP
  2551.                 INC_POS
  2552.                 RENDER_16BIT_SMP_MONO_INTRP
  2553.                 INC_POS
  2554.             }
  2555.         }
  2556.         else
  2557.         {
  2558.             if (samplesToMix & 1)
  2559.             {
  2560.                 RENDER_16BIT_SMP_INTRP
  2561.                 INC_POS
  2562.             }
  2563.             samplesToMix >>= 1;
  2564.             for (i = 0; i < samplesToMix; i++)
  2565.             {
  2566.                 RENDER_16BIT_SMP_INTRP
  2567.                 INC_POS
  2568.                 RENDER_16BIT_SMP_INTRP
  2569.                 INC_POS
  2570.             }
  2571.         }
  2572.         WRAP_LOOP
  2573.     }
  2574.  
  2575.     SET_BACK_MIXER_POS
  2576. }
  2577.  
  2578. mixRoutine mixRoutineTable[8] =
  2579. {
  2580.     (mixRoutine)mix8bNoLoop,
  2581.     (mixRoutine)mix8bLoop,
  2582.     (mixRoutine)mix8bNoLoopIntrp,
  2583.     (mixRoutine)mix8bLoopIntrp,
  2584.     (mixRoutine)mix16bNoLoop,
  2585.     (mixRoutine)mix16bLoop,
  2586.     (mixRoutine)mix16bNoLoopIntrp,
  2587.     (mixRoutine)mix16bLoopIntrp
  2588. };
  2589.  
  2590. // -----------------------------------------------------------------------
  2591.  
  2592. static void mixAudio(int16_t *stream, int32_t sampleBlockLength)
  2593. {
  2594.     int32_t i, out32;
  2595.     voice_t *v;
  2596.  
  2597.     if (musicPaused)
  2598.     {
  2599.         memset(stream, 0, sampleBlockLength * (sizeof (int16_t) * 2));
  2600.         return;
  2601.     }
  2602.  
  2603.     memset(mixBufferL, 0, sampleBlockLength * sizeof (int32_t));
  2604.     memset(mixBufferR, 0, sampleBlockLength * sizeof (int32_t));
  2605.  
  2606.     // mix channels
  2607.     for (i = 0; i < 32; i++)
  2608.     {
  2609.         v = &voice[i];
  2610.  
  2611.         // call the mixing routine currently set for the voice
  2612.         if (v->m_mixfunc != NULL)
  2613.             v->m_mixfunc(v, sampleBlockLength);
  2614.     }
  2615.  
  2616.     if (mastervol == 256) // user-adjustable volume is at max
  2617.     {
  2618.         for (i = 0; i < sampleBlockLength; i++)
  2619.         {
  2620.             out32 = (mixBufferL[i] * mastermul) >> 8;
  2621.             CLAMP16(out32);
  2622.             *stream++ = (int16_t)out32;
  2623.  
  2624.             out32 = (mixBufferR[i] * mastermul) >> 8;
  2625.             CLAMP16(out32);
  2626.             *stream++ = (int16_t)out32;
  2627.         }
  2628.     }
  2629.     else // user-adjustable volume is not at max, adjust amplitude
  2630.     {
  2631.         for (i = 0; i < sampleBlockLength; i++)
  2632.         {
  2633.             out32 = (mixBufferL[i] * mastermul) >> 8;
  2634.             CLAMP16(out32);
  2635.             out32 = (out32 * mastervol) >> 8;
  2636.             *stream++ = (int16_t)out32;
  2637.  
  2638.             out32 = (mixBufferR[i] * mastermul) >> 8;
  2639.             CLAMP16(out32);
  2640.             out32 = (out32 * mastervol) >> 8;
  2641.             *stream++ = (int16_t)out32;
  2642.         }
  2643.     }
  2644. }
  2645.  
  2646. static void st3play_FillAudioBuffer(int16_t *buffer, int32_t samples)
  2647. {
  2648.     int32_t a, b;
  2649.  
  2650.     a = samples;
  2651.     while (a > 0)
  2652.     {
  2653.         if (samplesLeft == 0)
  2654.         {
  2655.             // new replayer tick
  2656.             if (!musicPaused)
  2657.                 dorow();
  2658.  
  2659.             samplesLeft = samplesPerTick;
  2660.         }
  2661.  
  2662.         b = a;
  2663.         if (b > samplesLeft)
  2664.             b = samplesLeft;
  2665.  
  2666.         mixAudio(buffer, b);
  2667.         buffer += (uint32_t)b * 2;
  2668.  
  2669.         a -= b;
  2670.         samplesLeft -= b;
  2671.     }
  2672.  
  2673.     sampleCounter += samples;
  2674. }
  2675.  
  2676. void st3play_Close(void)
  2677. {
  2678.     closeMixer();
  2679.  
  2680.     if (mixBufferL != NULL)
  2681.     {
  2682.         free(mixBufferL);
  2683.         mixBufferL = NULL;
  2684.     }
  2685.  
  2686.     if (mixBufferR != NULL)
  2687.     {
  2688.         free(mixBufferR);
  2689.         mixBufferR = NULL;
  2690.     }
  2691.  
  2692.     for (uint8_t i = 0; i < 100; i++)
  2693.     {
  2694.         if (ins[i].data != NULL)
  2695.         {
  2696.             free(ins[i].data);
  2697.             ins[i].data = NULL;
  2698.         }
  2699.  
  2700.         if (patdata[i] != NULL)
  2701.         {
  2702.             free(patdata[i]);
  2703.             patdata[i] = NULL;
  2704.         }
  2705.     }
  2706. }
  2707.  
  2708. void st3play_PauseSong(bool flag)
  2709. {
  2710.     musicPaused = flag;
  2711. }
  2712.  
  2713. void st3play_TogglePause(void)
  2714. {
  2715.     musicPaused ^= 1;
  2716. }
  2717.  
  2718. void st3play_SetMasterVol(uint16_t vol)
  2719. {
  2720.     mastervol = CLAMP(vol, 0, 256);
  2721. }
  2722.  
  2723. void st3play_SetInterpolation(bool flag)
  2724. {
  2725.     interpolationFlag = flag;
  2726.  
  2727.     // shut down voices to prevent mixture of interpolated/non-interpolated voices
  2728.     for (uint8_t i = 0; i < 32; i++)
  2729.         voice[i].m_mixfunc = NULL;
  2730. }
  2731.  
  2732. char *st3play_GetSongName(void)
  2733. {
  2734.     return songname;
  2735. }
  2736.  
  2737. uint32_t st3play_GetMixerTicks(void)
  2738. {
  2739.     if (audioRate < 1000)
  2740.         return 0;
  2741.  
  2742.     return sampleCounter / (audioRate / 1000);
  2743. }
  2744.  
  2745. static bool loadS3M(const uint8_t *dat, uint32_t modLen)
  2746. {
  2747.     bool signedSamples;
  2748.     uint8_t pan, *ptr8, ch;
  2749.     int16_t *smpReadPtr16, *smpWritePtr16;
  2750.     uint16_t patDataLen;
  2751.     uint32_t c2spd, i, j, offs, loopEnd;
  2752.  
  2753.     if (modLen < 0x70 || dat[0x1D] != 16 || memcmp(&dat[0x2C], "SCRM", 4) != 0)
  2754.         return false; // not a valid S3M
  2755.  
  2756.     soundcardtype = SOUNDCARD_SBPRO;
  2757.  
  2758.     memcpy(songname, dat, 28);
  2759.     songname[28] = '\0';
  2760.  
  2761.     signedSamples = (*(uint16_t *)&dat[0x2A] == 1);
  2762.  
  2763.     ordNum = *(uint16_t *)&dat[0x20]; if (ordNum > 256) ordNum = 256;
  2764.     insNum = *(uint16_t *)&dat[0x22]; if (insNum > 100) insNum = 100;
  2765.     patNum = *(uint16_t *)&dat[0x24]; if (patNum > 100) patNum = 100;
  2766.  
  2767.     memcpy(order, &dat[0x60], ordNum);
  2768.     memcpy(chnsettings, &dat[0x40], 32);
  2769.  
  2770.     // load instrument headers
  2771.     memset(ins, 0, sizeof (ins));
  2772.     for (i = 0; i < insNum; i++)
  2773.     {
  2774.         offs = *(uint16_t *)&dat[0x60 + ordNum + (i * 2)] << 4;
  2775.         if (offs == 0)
  2776.             continue; // empty
  2777.  
  2778.         ptr8 = (uint8_t *)&dat[offs];
  2779.  
  2780.         ins[i].type = ptr8[0x00];
  2781.         ins[i].length = *(uint32_t *)&ptr8[0x10];
  2782.         ins[i].loopbeg = *(uint32_t *)&ptr8[0x14];
  2783.         loopEnd = *(uint32_t *)&ptr8[0x18];
  2784.         ins[i].vol = CLAMP((int8_t)ptr8[0x1C], 0, 63); // ST3 clamps smp. vol to 63 in replayer, do it here instead
  2785.         ins[i].flags = ptr8[0x1F];
  2786.         c2spd = *(uint32_t *)&ptr8[0x20];
  2787.  
  2788.         if (c2spd > 65535)
  2789.             c2spd = 65535;
  2790.  
  2791.         ins[i].c2spd = (uint16_t)c2spd;
  2792.  
  2793.         // reduce sample length if it overflows the module size (f.ex. "miracle man.s3m")
  2794.         offs = ((ptr8[0x0D] << 16) | (ptr8[0x0F] << 8) | ptr8[0x0E]) << 4;
  2795.         if (offs+ins[i].length >= modLen)
  2796.             ins[i].length = modLen - offs;
  2797.  
  2798.         if (loopEnd == ins[i].loopbeg)
  2799.             ins[i].flags &= 0xFE; // turn off loop
  2800.  
  2801.         if (loopEnd < ins[i].loopbeg)
  2802.             loopEnd = ins[i].loopbeg + 1;
  2803.  
  2804.         if (loopEnd > ins[i].length)
  2805.             loopEnd = ins[i].length;
  2806.  
  2807.         ins[i].looplen = loopEnd - ins[i].loopbeg;
  2808.         if (ins[i].looplen == 0 || ins[i].loopbeg+ins[i].looplen > ins[i].length)
  2809.             ins[i].flags &= 0xFE; // turn off loop
  2810.     }
  2811.  
  2812.     // load pattern data
  2813.     memset(patdata, 0, sizeof (patdata));
  2814.     for (i = 0; i < patNum; i++)
  2815.     {
  2816.         offs = *(uint16_t *)&dat[0x60 + ordNum + (insNum * 2) + (i * 2)] << 4;
  2817.         if (offs == 0)
  2818.             continue; // empty
  2819.  
  2820.         patDataLen = *(uint16_t *)&dat[offs];
  2821.         if (patDataLen > 0)
  2822.         {
  2823.             patdata[i] = (uint8_t *)malloc(patDataLen);
  2824.             if (patdata[i] == NULL)
  2825.             {
  2826.                 st3play_Close();
  2827.                 return false;
  2828.             }
  2829.  
  2830.             memcpy(patdata[i], &dat[offs+2], patDataLen);
  2831.         }
  2832.     }
  2833.  
  2834.     // load sample data
  2835.     for (i = 0; i < insNum; i++)
  2836.     {
  2837.         offs = *(uint16_t *)&dat[0x60 + ordNum + (i * 2)] << 4;
  2838.         if (offs == 0)
  2839.             continue; // empty
  2840.  
  2841.         if (ins[i].length <= 0 || ins[i].type != 1 || dat[offs + 0x1E] != 0)
  2842.             continue; // sample not supported
  2843.  
  2844.         offs = ((dat[offs + 0x0D] << 16) | (dat[offs + 0x0F] << 8) | dat[offs + 0x0E]) << 4;
  2845.         if (offs == 0)
  2846.             continue; // empty
  2847.  
  2848.         // offs now points to sample data
  2849.  
  2850.         if (ins[i].flags & 4) // 16-bit
  2851.             ins[i].data = (int8_t *)malloc((ins[i].length * 2) + LOOP_FIX_LEN);
  2852.         else
  2853.             ins[i].data = (int8_t *)malloc(ins[i].length + LOOP_FIX_LEN);
  2854.  
  2855.         if (ins[i].data == NULL)
  2856.         {
  2857.             st3play_Close();
  2858.             return false;
  2859.         }
  2860.  
  2861.         if (ins[i].flags & 4)
  2862.         {
  2863.             // 16-bit
  2864.             if (signedSamples)
  2865.             {
  2866.                 memcpy(ins[i].data, &dat[offs], ins[i].length * 2);
  2867.             }
  2868.             else
  2869.             {
  2870.                 smpReadPtr16 = (int16_t *)&dat[offs];
  2871.                 smpWritePtr16 = (int16_t *)ins[i].data;
  2872.  
  2873.                 for (j = 0; j < ins[i].length; j++)
  2874.                     smpWritePtr16[j] = smpReadPtr16[j] + 32768;
  2875.             }
  2876.         }
  2877.         else
  2878.         {
  2879.             // 8-bit
  2880.             if (signedSamples)
  2881.             {
  2882.                 memcpy(ins[i].data, &dat[offs], ins[i].length);
  2883.             }
  2884.             else
  2885.             {
  2886.                 for (j = 0; j < ins[i].length; j++)
  2887.                     ins[i].data[j] = dat[offs+j] + 128;
  2888.             }
  2889.         }
  2890.  
  2891.         // add wrapped samples after loop/end (for branchless mixer interpolation)
  2892.  
  2893.         smpWritePtr16 = (int16_t *)ins[i].data;
  2894.         if (ins[i].flags & 1)
  2895.         {
  2896.             // loop
  2897.  
  2898.             if (ins[i].flags & 4) // 16-bit?
  2899.             {
  2900.                 smpWritePtr16[ins[i].loopbeg+ins[i].looplen+0] = smpWritePtr16[ins[i].loopbeg+0];
  2901.                 smpWritePtr16[ins[i].loopbeg+ins[i].looplen+1] = smpWritePtr16[ins[i].loopbeg+1];
  2902.             }
  2903.             else
  2904.             {
  2905.                 ins[i].data[ins[i].loopbeg+ins[i].looplen+0] = ins[i].data[ins[i].loopbeg+0];
  2906.                 ins[i].data[ins[i].loopbeg+ins[i].looplen+1] = ins[i].data[ins[i].loopbeg+1];
  2907.             }
  2908.         }
  2909.         else
  2910.         {
  2911.             // no loop
  2912.  
  2913.             if (ins[i].flags & 4) // 16-bit?
  2914.             {
  2915.                 smpWritePtr16[ins[i].length+0] = 0;
  2916.                 smpWritePtr16[ins[i].length+1] = 0;
  2917.             }
  2918.             else
  2919.             {
  2920.                 ins[i].data[ins[i].length+0] = 0;
  2921.                 ins[i].data[ins[i].length+1] = 0;
  2922.             }
  2923.         }
  2924.     }
  2925.  
  2926.     // scan the song for panning commands, and enable GUS mode if found
  2927.     for (i = 0; i < patNum; i++)
  2928.     {
  2929.         np_patseg = patdata[i];
  2930.         if (np_patseg == NULL)
  2931.             continue;
  2932.  
  2933.         np_patoff = 0;
  2934.         for (j = 0; j < 64;)
  2935.         {
  2936.             ch = getnote1();
  2937.             if (ch != 255)
  2938.             {
  2939.                 if (chn[ch].cmd == 'S'-64 && (chn[ch].info & 0xF0) == 0x80) // S8x
  2940.                 {
  2941.                     soundcardtype = SOUNDCARD_GUS;
  2942.                     i = patNum; // stop seeking
  2943.                     break;
  2944.                 }
  2945.             }
  2946.             else j++; // end of channels/row
  2947.         }
  2948.     }
  2949.     np_patoff = 0;
  2950.     np_patseg = NULL;
  2951.  
  2952.     // set up pans
  2953.     for (i = 0; i < 32; i++)
  2954.     {
  2955.         chn[i].apanpos = 0x7;
  2956.         if (chnsettings[i] != 0xFF)
  2957.             chn[i].apanpos = (chnsettings[i] & 8) ? 0xC : 0x3;
  2958.  
  2959.         if (dat[0x35] == 252) // custom pannings follow, force GUS mode and set pans
  2960.         {
  2961.             soundcardtype = SOUNDCARD_GUS;
  2962.             pan = dat[0x60 + ordNum + (insNum * 2) + (patNum * 2) + i];
  2963.             if (pan & 32)
  2964.                 chn[i].apanpos = pan & 0x0F;
  2965.         }
  2966.     }
  2967.  
  2968.     setspeed(6);
  2969.     settempo(125);
  2970.     setglobalvol(64);
  2971.  
  2972.     amigalimits = (dat[0x26] & 0x10) ? true : false;
  2973.     oldstvib = dat[0x26] & 0x01;
  2974.     mastermul = dat[0x33];
  2975.     fastvolslide = (*(uint16_t *)&dat[0x28] == 0x1300) || (dat[0x26] & 0x40);
  2976.  
  2977.     if (signedSamples)
  2978.     {
  2979.         switch (mastermul)
  2980.         {
  2981.             case 0: mastermul = 0x10; break;
  2982.             case 1: mastermul = 0x20; break;
  2983.             case 2: mastermul = 0x30; break;
  2984.             case 3: mastermul = 0x40; break;
  2985.             case 4: mastermul = 0x50; break;
  2986.             case 5: mastermul = 0x60; break;
  2987.             case 6: mastermul = 0x70; break;
  2988.             case 7: mastermul = 0x7F; break;
  2989.             default: break;
  2990.         }
  2991.     }
  2992.  
  2993.     // taken from the ST3.21 loader, strange stuff...
  2994.     if (mastermul == 2) mastermul = 0x20;
  2995.     if (mastermul == 2+16) mastermul = 0x20 + 128;
  2996.  
  2997.     stereomode = mastermul & 128;
  2998.  
  2999.     mastermul &= 127;
  3000.     if (mastermul == 0)
  3001.         mastermul = 48; // default in ST3 when you play a song where mastermul=0
  3002.  
  3003.     // no mastermul in GUS, set to a low'ish value because GUS can be quiet (thus loud songs were made)
  3004.     if (soundcardtype == SOUNDCARD_GUS)
  3005.         mastermul = 32;
  3006.  
  3007.     mastermul *= 2; // upscale for st3play's audio mixer
  3008.  
  3009.     if (dat[0x32] > 0) settempo(dat[0x32]);
  3010.     if (dat[0x30] != 255) setglobalvol(dat[0x30]);
  3011.  
  3012.     if (dat[0x31] > 0 && dat[0x31] != 255)
  3013.         setspeed(dat[0x31]);
  3014.  
  3015.     if (amigalimits)
  3016.     {
  3017.         aspdmin = 907 / 2;
  3018.         aspdmax = 1712 * 2;
  3019.     }
  3020.     else
  3021.     {
  3022.         aspdmin = 64;
  3023.         aspdmax = 32767;
  3024.     }
  3025.  
  3026.     for (i = 0; i < 32; i++)
  3027.     {
  3028.         chn[i].channelnum = (int8_t)i;
  3029.         chn[i].achannelused = 0x80;
  3030.     }
  3031.  
  3032.     np_patseg = NULL;
  3033.     musiccount = 0;
  3034.     patterndelay = 0;
  3035.     patloopcount = 0;
  3036.     startrow = 0;
  3037.     breakpat = 0;
  3038.     volslidetype = 0;
  3039.     np_patoff = -1;
  3040.     jmptoord = -1;
  3041.  
  3042.     np_ord = 0;
  3043.     neworder();
  3044.  
  3045.     lastachannelused = 1;
  3046.     return true;
  3047. }
  3048.  
  3049. bool st3play_PlaySong(const uint8_t *moduleData, uint32_t dataLength, bool useInterpolationFlag, uint32_t audioFreq)
  3050. {
  3051.     int16_t i;
  3052.  
  3053.     st3play_Close();
  3054.     memset(songname, 0, sizeof (songname));
  3055.  
  3056.     if (audioFreq == 0)
  3057.         audioFreq = 44100;
  3058.  
  3059.     audioFreq = CLAMP(audioFreq, 11025, 96000);
  3060.  
  3061.     sampleCounter = 0;
  3062.     musicPaused = true;
  3063.     audioRate = audioFreq;
  3064.     soundBufferSize = MIX_BUF_SAMPLES;
  3065.     interpolationFlag = useInterpolationFlag ? true : false;
  3066.  
  3067.     memset(chn, 0, sizeof (chn));
  3068.     memset(voice, 0, sizeof (voice));
  3069.  
  3070.     mixBufferL = (int32_t *)malloc(MIX_BUF_SAMPLES * sizeof (int32_t));
  3071.     mixBufferR = (int32_t *)malloc(MIX_BUF_SAMPLES * sizeof (int32_t));
  3072.  
  3073.     if (mixBufferL == NULL || mixBufferR == NULL)
  3074.     {
  3075.         st3play_Close();
  3076.         return false;
  3077.     }
  3078.  
  3079.     if (!openMixer(audioRate))
  3080.     {
  3081.         st3play_Close();
  3082.         return false;
  3083.     }
  3084.  
  3085.     if (!loadS3M(moduleData, dataLength))
  3086.     {
  3087.         st3play_Close();
  3088.         return false;
  3089.     }
  3090.  
  3091.     // calculate lowPeriod2Delta table
  3092.     for (i = 64; i <= 218; i++)
  3093.         lowPeriod2Delta[i - 64] = (uint32_t)(((uint64_t)(14317056 / i) << 16) / audioRate);
  3094.  
  3095.     musicPaused = false;
  3096.     return true;
  3097. }
  3098.  
  3099. // the following must be changed if you want to use another audio API than WinMM
  3100.  
  3101. #ifndef WIN32_LEAN_AND_MEAN
  3102. #define WIN32_LEAN_AND_MEAN
  3103. #endif
  3104.  
  3105. #include <windows.h>
  3106. #include <mmsystem.h>
  3107.  
  3108. #define MIX_BUF_NUM 2
  3109.  
  3110. static volatile BOOL audioRunningFlag;
  3111. static uint8_t currBuffer;
  3112. static int16_t *mixBuffer[MIX_BUF_NUM];
  3113. static HANDLE hThread, hAudioSem;
  3114. static WAVEHDR waveBlocks[MIX_BUF_NUM];
  3115. static HWAVEOUT hWave;
  3116.  
  3117. static DWORD WINAPI mixThread(LPVOID lpParam)
  3118. {
  3119.     WAVEHDR *waveBlock;
  3120.  
  3121.     (void)lpParam;
  3122.  
  3123.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
  3124.  
  3125.     while (audioRunningFlag)
  3126.     {
  3127.         waveBlock = &waveBlocks[currBuffer];
  3128.         st3play_FillAudioBuffer((int16_t *)waveBlock->lpData, MIX_BUF_SAMPLES);
  3129.         waveOutWrite(hWave, waveBlock, sizeof (WAVEHDR));
  3130.         currBuffer = (currBuffer + 1) % MIX_BUF_NUM;
  3131.  
  3132.         // wait for buffer fill request
  3133.         WaitForSingleObject(hAudioSem, INFINITE);
  3134.     }
  3135.  
  3136.     return 0;
  3137. }
  3138.  
  3139. static void CALLBACK waveProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
  3140. {
  3141.     (void)hWaveOut;
  3142.     (void)uMsg;
  3143.     (void)dwInstance;
  3144.     (void)dwParam1;
  3145.     (void)dwParam2;
  3146.  
  3147.     if (uMsg == WOM_DONE)
  3148.         ReleaseSemaphore(hAudioSem, 1, NULL);
  3149. }
  3150.  
  3151. static void closeMixer(void)
  3152. {
  3153.     int32_t i;
  3154.  
  3155.     audioRunningFlag = false; // make thread end when it's done
  3156.  
  3157.     if (hAudioSem != NULL)
  3158.         ReleaseSemaphore(hAudioSem, 1, NULL);
  3159.  
  3160.     if (hThread != NULL)
  3161.     {
  3162.         WaitForSingleObject(hThread, INFINITE);
  3163.         CloseHandle(hThread);
  3164.         hThread = NULL;
  3165.     }
  3166.  
  3167.     if (hAudioSem != NULL)
  3168.     {
  3169.         CloseHandle(hAudioSem);
  3170.         hAudioSem = NULL;
  3171.     }
  3172.  
  3173.     if (hWave != NULL)
  3174.     {
  3175.         waveOutReset(hWave);
  3176.         for (i = 0; i < MIX_BUF_NUM; i++)
  3177.         {
  3178.             if (waveBlocks[i].dwUser != 0xFFFF)
  3179.                 waveOutUnprepareHeader(hWave, &waveBlocks[i], sizeof (WAVEHDR));
  3180.         }
  3181.  
  3182.         waveOutClose(hWave);
  3183.         hWave = NULL;
  3184.     }
  3185.  
  3186.     for (i = 0; i < MIX_BUF_NUM; i++)
  3187.     {
  3188.         if (mixBuffer[i] != NULL)
  3189.         {
  3190.             free(mixBuffer[i]);
  3191.             mixBuffer[i] = NULL;
  3192.         }
  3193.     }
  3194. }
  3195.  
  3196. static bool openMixer(uint32_t audioFreq)
  3197. {
  3198.     int32_t i;
  3199.     DWORD threadID;
  3200.     WAVEFORMATEX wfx;
  3201.  
  3202.     // don't unprepare headers on error
  3203.     for (i = 0; i < MIX_BUF_NUM; i++)
  3204.         waveBlocks[i].dwUser = 0xFFFF;
  3205.  
  3206.     closeMixer();
  3207.  
  3208.     ZeroMemory(&wfx, sizeof (wfx));
  3209.     wfx.nSamplesPerSec = audioFreq;
  3210.     wfx.wBitsPerSample = 16;
  3211.     wfx.nChannels = 2;
  3212.     wfx.wFormatTag = WAVE_FORMAT_PCM;
  3213.     wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8);
  3214.     wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
  3215.  
  3216.     samplesLeft = 0;
  3217.     currBuffer = 0;
  3218.  
  3219.     if (waveOutOpen(&hWave, WAVE_MAPPER, &wfx, (DWORD_PTR)&waveProc, 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
  3220.         goto omError;
  3221.  
  3222.     // create semaphore for buffer fill requests
  3223.     hAudioSem = CreateSemaphore(NULL, MIX_BUF_NUM - 1, MIX_BUF_NUM, NULL);
  3224.     if (hAudioSem == NULL)
  3225.         goto omError;
  3226.  
  3227.     // allocate WinMM mix buffers
  3228.     for (i = 0; i < MIX_BUF_NUM; i++)
  3229.     {
  3230.         mixBuffer[i] = (int16_t *)calloc(MIX_BUF_SAMPLES, wfx.nBlockAlign);
  3231.         if (mixBuffer[i] == NULL)
  3232.             goto omError;
  3233.     }
  3234.  
  3235.     // initialize WinMM mix headers
  3236.     memset(waveBlocks, 0, sizeof (waveBlocks));
  3237.     for (i = 0; i < MIX_BUF_NUM; i++)
  3238.     {
  3239.         waveBlocks[i].lpData = (LPSTR)mixBuffer[i];
  3240.         waveBlocks[i].dwBufferLength = MIX_BUF_SAMPLES * wfx.nBlockAlign;
  3241.         waveBlocks[i].dwFlags = WHDR_DONE;
  3242.  
  3243.         if (waveOutPrepareHeader(hWave, &waveBlocks[i], sizeof (WAVEHDR)) != MMSYSERR_NOERROR)
  3244.             goto omError;
  3245.     }
  3246.  
  3247.     // create main mixer thread
  3248.     audioRunningFlag = true;
  3249.     hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)mixThread, NULL, 0, &threadID);
  3250.     if (hThread == NULL)
  3251.         goto omError;
  3252.  
  3253.     return TRUE;
  3254.  
  3255. omError:
  3256.     closeMixer();
  3257.     return FALSE;
  3258. }
  3259.  
  3260. // ---------------------------------------------------------------------------
  3261.  
  3262. // END OF FILE (phew...)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top