SHARE
TWEET

st3play v0.94

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