8bitbubsy

st3play v1.01

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