8bitbubsy

st3play v1.01

Dec 26th, 2013 (edited)
1,143
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

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×