SHARE
TWEET

ft2play v1.04

8bitbubsy Jan 27th, 2018 (edited) 999 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ** ft2play v1.04 - 17th of February 2020 - https://16-bits.org
  3. ** ===========================================================
  4. **                 - NOT BIG ENDIAN SAFE! -
  5. **
  6. ** Very accurate C port of Fasttracker 2's replayer (.XM/.MOD/.FT),
  7. ** by Olav "8bitbubsy" Sørensen. Using the original pascal+asm source
  8. ** codes by Fredrik "Mr.H" Huss (Triton). I have permission to make this
  9. ** C port public.
  10. **
  11. ** You need to link winmm.lib for this to compile (-lwinmm).
  12. ** Alternatively, you can change out the mixer functions at the bottom with
  13. ** your own for your OS.
  14. **
  15. ** Example of ft2play usage:
  16. ** #include "ft2play.h"
  17. ** #include "songdata.h"
  18. **
  19. ** ft2play_PlaySong(songData, songDataLength, true, true, 48000);
  20. ** mainLoop();
  21. ** ft2play_Close();
  22. **
  23. ** To turn a song into an include file like in the example, you can use my win32
  24. ** bin2h tool from here: https://16-bits.org/etc/bin2h.zip
  25. **
  26. ** Changes in v1.04:
  27. ** - Added ft2play_GetMasterVol() and ft2play_GetAmp()
  28. **
  29. ** Changes in v1.03:
  30. ** - Slightly finer volume precision during mixing
  31. ** - .MOD importer has been heavily improved on 15-sample formats
  32. ** - Added 1-bit triangular dithering to mixed audio output
  33. ** - Unpacked certain structs because they don't need to be packed
  34. **
  35. ** Changes in v1.02:
  36. ** - Added finer volume calculation resolution in audio mixer
  37. ** - Code cleanup
  38. **
  39. ** Changes in v1.01:
  40. ** - Fixed: The interpolation routine was slightly wrong when playing backwards
  41. **   on pingpong-samples.
  42. ** - Small mixer optimization for very tight sample loops
  43. ** - Some small fixes to the .MOD loader (15-sample format)
  44. **
  45. ** Changes in v1.00:
  46. ** - Fixed an overflow bug if pingpong-looped samples had a loop-length of 1
  47. ** - Code cleanup (uses the "bool" type now, spaces -> tabs, comment style
  48. **   change)
  49. **
  50. ** Changes in v0.99:
  51. ** - Resampling interpolation was changed from 2-tap linear to 3-tap quadratic
  52. **   for less muddy sound.
  53. **
  54. ** Changes in v0.98:
  55. ** - Some code cleanup to match the replayer code in the FT2 clone
  56. ** - Very minor optimization to the replayer rate calculation routine
  57. **
  58. ** Changes in v0.97:
  59. ** - Audio channel mixer optimizations
  60. **
  61. ** Changes in v0.96:
  62. ** - Removed some unneeded logic in the audio channel mixer
  63. **
  64. ** Changes in v0.95:
  65. ** - Turned some unneeded 64-bit calculations into 32-bit
  66. ** - Support loading .MODs with odd (1,3,5..31) channel numbers
  67. **
  68. ** Changes in v0.94:
  69. ** - .MOD/.FT playback was completely broken, sorry!
  70. **
  71. ** Changes in v0.93:
  72. ** - Linear interpolation is done with 16-bit fractional precision instead of
  73. **   15-bit.
  74. **
  75. ** Changes in v0.92:
  76. ** - Added a function to retrieve song name
  77. **
  78. ** Changes in v0.91:
  79. ** - Now uses much faster audio channel mixer from my FT2 clone project
  80. ** - Added support for loading .MOD/.FT files
  81. ** - WinMM mixer has been rewritten to be safe (don't use syscalls in callback)
  82. ** - Some small fixes
  83. ** - Some small changes to the ft2play functions (easier to use and safer!)
  84. */
  85.  
  86. /* ft2play.h:
  87.  
  88. #pragma once
  89.  
  90. #include <stdint.h>
  91. #include <stdbool.h>
  92.  
  93. bool ft2play_PlaySong(const uint8_t *moduleData, uint32_t dataLength, bool useInterpolationFlag, bool useVolumeRampingFlag, uint32_t audioFreq);
  94. void ft2play_Close(void);
  95. void ft2play_PauseSong(bool flag); // true/false
  96. void ft2play_TogglePause(void);
  97. void ft2play_SetMasterVol(uint16_t vol); // 0..256
  98. uint16_t ft2play_GetMasterVol(void); // 0..256
  99. void ft2play_SetAmp(uint8_t ampFactor); // 1..32 (10 = default)
  100. uint8_t ft2play_GetAmp(void); // 1..32
  101. void ft2play_SetInterpolation(bool flag); // true/false
  102. void ft2play_SetVolumeRamping(bool flag); // true/false
  103. char *ft2play_GetSongName(void); // max 20 chars (21 with '\0'), string is in code page 437
  104. uint32_t ft2play_GetMixerTicks(void); // returns the amount of milliseconds of mixed audio (not realtime)
  105. */
  106.  
  107. #define MIX_BUF_SAMPLES 4096
  108.  
  109. #ifndef _USE_MATH_DEFINES
  110. #define _USE_MATH_DEFINES
  111. #endif
  112.  
  113. #include <stdio.h>
  114. #include <stdlib.h>
  115. #include <string.h>
  116. #include <stdint.h>
  117. #include <stdbool.h>
  118. #include <math.h>
  119.  
  120. #define LOOP_FIX_LEN 4
  121.  
  122. #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
  123.  
  124. #define SWAP16(value) \
  125. ( \
  126.     (((uint16_t)((value) & 0x00FF)) << 8) | \
  127.     (((uint16_t)((value) & 0xFF00)) >> 8)   \
  128. )
  129.  
  130. // fast 32-bit -> 16-bit clamp
  131. #define CLAMP16(i) if ((int16_t)(i) != i) i = 0x7FFF ^ (i >> 31);
  132.  
  133. enum
  134. {
  135.     IS_Vol = 1,
  136.     IS_Period = 2,
  137.     IS_NyTon = 4,
  138.     IS_Pan = 8,
  139.     IS_QuickVol = 16
  140. };
  141.  
  142. #ifdef _MSC_VER
  143. #pragma pack(push)
  144. #pragma pack(1)
  145. #endif
  146. typedef struct songMODInstrHeaderTyp_t
  147. {
  148.     char name[22];
  149.     uint16_t len;
  150.     uint8_t fine, vol;
  151.     uint16_t repS, repL;
  152. }
  153. #ifdef __GNUC__
  154. __attribute__ ((packed))
  155. #endif
  156. songMODInstrHeaderTyp;
  157.  
  158. typedef struct songMOD31HeaderTyp_t
  159. {
  160.     char name[20];
  161.     songMODInstrHeaderTyp instr[31];
  162.     uint8_t len, repS, songTab[128];
  163.     char sig[4];
  164. }
  165. #ifdef __GNUC__
  166. __attribute__ ((packed))
  167. #endif
  168. songMOD31HeaderTyp;
  169.  
  170. typedef struct songMOD15HeaderTyp_t
  171. {
  172.     char name[20];
  173.     songMODInstrHeaderTyp instr[15];
  174.     uint8_t len, repS, songTab[128];
  175. }
  176. #ifdef __GNUC__
  177. __attribute__ ((packed))
  178. #endif
  179. songMOD15HeaderTyp;
  180.  
  181. typedef struct songHeaderTyp_t
  182. {
  183.     char sig[17], name[21], progName[20];
  184.     uint16_t ver;
  185.     int32_t headerSize;
  186.     uint16_t len, repS, antChn, antPtn, antInstrs, flags, defTempo, defSpeed;
  187.     uint8_t songTab[256];
  188. }
  189. #ifdef __GNUC__
  190. __attribute__ ((packed))
  191. #endif
  192. songHeaderTyp;
  193.  
  194. typedef struct sampleHeaderTyp_t
  195. {
  196.     int32_t len, repS, repL;
  197.     uint8_t vol;
  198.     int8_t fine;
  199.     uint8_t typ, pan;
  200.     int8_t relTon;
  201.     uint8_t skrap;
  202.     char name[22];
  203. }
  204. #ifdef __GNUC__
  205. __attribute__ ((packed))
  206. #endif
  207. sampleHeaderTyp;
  208.  
  209. typedef struct instrHeaderTyp_t
  210. {
  211.     int32_t instrSize;
  212.     char name[22];
  213.     uint8_t typ;
  214.     uint16_t antSamp;
  215.     int32_t sampleSize;
  216.     uint8_t ta[96];
  217.     int16_t envVP[12][2], envPP[12][2];
  218.     uint8_t envVPAnt, envPPAnt, envVSust, envVRepS, envVRepE, envPSust, envPRepS;
  219.     uint8_t envPRepE, envVTyp, envPTyp, vibTyp, vibSweep, vibDepth, vibRate;
  220.     uint16_t fadeOut;
  221.     uint8_t midiOn, midiChannel;
  222.     int16_t midiProgram, midiBend;
  223.     int8_t mute;
  224.     uint8_t reserved[15];
  225.     sampleHeaderTyp samp[32];
  226. }
  227. #ifdef __GNUC__
  228. __attribute__ ((packed))
  229. #endif
  230. instrHeaderTyp;
  231.  
  232. typedef struct patternHeaderTyp_t
  233. {
  234.     int32_t patternHeaderSize;
  235.     uint8_t typ;
  236.     uint16_t pattLen, dataLen;
  237. }
  238. #ifdef __GNUC__
  239. __attribute__ ((packed))
  240. #endif
  241. patternHeaderTyp;
  242. #ifdef _MSC_VER
  243. #pragma pack(pop)
  244. #endif
  245.  
  246. typedef struct songTyp_t
  247. {
  248.     uint8_t antChn, pattDelTime, pattDelTime2, pBreakPos, songTab[256];
  249.     bool pBreakFlag, posJumpFlag;
  250.     int16_t songPos, pattNr, pattPos, pattLen;
  251.     uint16_t len, repS, speed, tempo, globVol, timer, ver, initialSpeed;
  252.     char name[20+1];
  253. } songTyp;
  254.  
  255. typedef struct sampleTyp_t
  256. {
  257.     int32_t len, repS, repL;
  258.     uint8_t vol;
  259.     int8_t fine;
  260.     uint8_t typ, pan;
  261.     int8_t relTon;
  262.     char name[22+1];
  263.     int8_t *pek;
  264. } sampleTyp;
  265.  
  266. typedef struct instrTyp_t
  267. {
  268.     char name[22+1];
  269.     uint8_t ta[96];
  270.     int16_t envVP[12][2], envPP[12][2];
  271.     uint8_t envVPAnt, envPPAnt;
  272.     uint8_t envVSust, envVRepS, envVRepE;
  273.     uint8_t envPSust, envPRepS, envPRepE;
  274.     uint8_t envVTyp, envPTyp;
  275.     uint8_t vibTyp, vibSweep, vibDepth, vibRate;
  276.     uint16_t fadeOut;
  277.     uint8_t midiOn, midiChannel;
  278.     int16_t midiProgram, midiBend;
  279.     uint8_t mute, reserved[15];
  280.     int16_t antSamp;
  281.     sampleTyp samp[16];
  282. } instrTyp;
  283.  
  284. typedef struct stmTyp_t
  285. {
  286.     volatile uint8_t status, tmpStatus;
  287.     int8_t relTonNr, fineTune;
  288.     uint8_t sampleNr, stOff, effTyp, eff, smpOffset, tremorSave, tremorPos;
  289.     uint8_t globVolSlideSpeed, panningSlideSpeed, mute, waveCtrl, portaDir;
  290.     uint8_t glissFunk, vibPos, tremPos, vibSpeed, vibDepth, tremSpeed, tremDepth;
  291.     uint8_t pattPos, loopCnt, volSlideSpeed, fVolSlideUpSpeed, fVolSlideDownSpeed;
  292.     uint8_t fPortaUpSpeed, fPortaDownSpeed, ePortaUpSpeed, ePortaDownSpeed;
  293.     uint8_t portaUpSpeed, portaDownSpeed, retrigSpeed, retrigCnt, retrigVol;
  294.     uint8_t volKolVol, tonNr, envPPos, eVibPos, envVPos, realVol, oldVol, outVol;
  295.     uint8_t oldPan, outPan, finalPan;
  296.     bool envSustainActive;
  297.     int16_t realPeriod, envVIPValue, envPIPValue;
  298.     uint16_t finalVol, outPeriod, finalPeriod, instrNr, tonTyp, wantPeriod, portaSpeed;
  299.     uint16_t envVCnt, envVAmp, envPCnt, envPAmp, eVibAmp, eVibSweep;
  300.     uint16_t fadeOutAmp, fadeOutSpeed;
  301.     int32_t smpStartPos;
  302.     sampleTyp *smpPtr;
  303.     instrTyp *instrPtr;
  304. } stmTyp;
  305.  
  306. typedef struct tonTyp_t
  307. {
  308.     uint8_t ton, instr, vol, effTyp, eff;
  309. } tonTyp;
  310.  
  311. typedef void (*mixRoutine)(void *, int32_t);
  312.  
  313. typedef struct
  314. {
  315.     const int8_t *SBase8, *SRevBase8;
  316.     const int16_t *SBase16, *SRevBase16;
  317.     bool backwards, isFadeOutVoice;
  318.     uint8_t SPan;
  319.     uint16_t SVol;
  320.     int32_t SLVol1, SRVol1, SLVol2, SRVol2, SLVolIP, SRVolIP, SVolIPLen, SPos, SLen, SRepS, SRepL;
  321.     uint32_t SPosDec, SFrq, SFrqRev;
  322.     void (*mixRoutine)(void *, int32_t); // function pointer to mix routine
  323. } voice_t;
  324.  
  325. typedef struct
  326. {
  327.     uint8_t *_ptr, *_base;
  328.     bool _eof;
  329.     uint32_t _cnt, _bufsiz;
  330. } MEMFILE;
  331.  
  332. // .MOD types
  333. enum
  334. {
  335.     FORMAT_MK, // ProTracker or compatible
  336.     FORMAT_FLT, // StarTrekker (4-channel modules only)
  337.     FORMAT_FT2, // FT2 (or other trackers, multichannel)
  338.     FORMAT_STK, // The Ultimate SoundTracker (15 samples)
  339.     FORMAT_NT, // NoiseTracker
  340.     FORMAT_HMNT, // His Master's NoiseTracker (special one)
  341.  
  342.     FORMAT_UNKNOWN // may be The Ultimate Soundtracker (set to FORMAT_STK later)
  343. };
  344.  
  345. #define MAX_NOTES ((12 * 10 * 16) + 16)
  346. #define MAX_VOICES 32
  347. #define INSTR_SIZE 232
  348. #define INSTR_HEADER_SIZE 263
  349.  
  350. static const uint32_t panningTab[257] =
  351. {
  352.         0, 4096, 5793, 7094, 8192, 9159,10033,10837,11585,12288,12953,13585,14189,14768,15326,15864,
  353.     16384,16888,17378,17854,18318,18770,19212,19644,20066,20480,20886,21283,21674,22058,22435,22806,
  354.     23170,23530,23884,24232,24576,24915,25249,25580,25905,26227,26545,26859,27170,27477,27780,28081,
  355.     28378,28672,28963,29251,29537,29819,30099,30377,30652,30924,31194,31462,31727,31991,32252,32511,
  356.     32768,33023,33276,33527,33776,34024,34270,34514,34756,34996,35235,35472,35708,35942,36175,36406,
  357.     36636,36864,37091,37316,37540,37763,37985,38205,38424,38642,38858,39073,39287,39500,39712,39923,
  358.     40132,40341,40548,40755,40960,41164,41368,41570,41771,41972,42171,42369,42567,42763,42959,43154,
  359.     43348,43541,43733,43925,44115,44305,44494,44682,44869,45056,45242,45427,45611,45795,45977,46160,
  360.     46341,46522,46702,46881,47059,47237,47415,47591,47767,47942,48117,48291,48465,48637,48809,48981,
  361.     49152,49322,49492,49661,49830,49998,50166,50332,50499,50665,50830,50995,51159,51323,51486,51649,
  362.     51811,51972,52134,52294,52454,52614,52773,52932,53090,53248,53405,53562,53719,53874,54030,54185,
  363.     54340,54494,54647,54801,54954,55106,55258,55410,55561,55712,55862,56012,56162,56311,56459,56608,
  364.     56756,56903,57051,57198,57344,57490,57636,57781,57926,58071,58215,58359,58503,58646,58789,58931,
  365.     59073,59215,59357,59498,59639,59779,59919,60059,60199,60338,60477,60615,60753,60891,61029,61166,
  366.     61303,61440,61576,61712,61848,61984,62119,62254,62388,62523,62657,62790,62924,63057,63190,63323,
  367.     63455,63587,63719,63850,63982,64113,64243,64374,64504,64634,64763,64893,65022,65151,65279,65408,
  368.     65536
  369. };
  370.  
  371. static const uint16_t amigaPeriod[12 * 8] =
  372. {
  373.     4*1712,4*1616,4*1524,4*1440,4*1356,4*1280,4*1208,4*1140,4*1076,4*1016,4*960,4*906,
  374.     2*1712,2*1616,2*1524,2*1440,2*1356,2*1280,2*1208,2*1140,2*1076,2*1016,2*960,2*906,
  375.     1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906,
  376.     856,808,762,720,678,640,604,570,538,508,480,453,
  377.     428,404,381,360,339,320,302,285,269,254,240,226,
  378.     214,202,190,180,170,160,151,143,135,127,120,113,
  379.     107,101,95,90,85,80,75,71,67,63,60,56,
  380.     53,50,47,45,42,40,37,35,33,31,30,28
  381. };
  382.  
  383. static const uint16_t amigaFinePeriod[12 * 8] =
  384. {
  385.     907,900,894,887,881,875,868,862,856,850,844,838,
  386.     832,826,820,814,808,802,796,791,785,779,774,768,
  387.     762,757,752,746,741,736,730,725,720,715,709,704,
  388.     699,694,689,684,678,675,670,665,660,655,651,646,
  389.     640,636,632,628,623,619,614,610,604,601,597,592,
  390.     588,584,580,575,570,567,563,559,555,551,547,543,
  391.     538,535,532,528,524,520,516,513,508,505,502,498,
  392.     494,491,487,484,480,477,474,470,467,463,460,457
  393. };
  394.  
  395. static const uint8_t vibTab[32] =
  396. {
  397.     0,  24,  49, 74, 97,120,141,161,
  398.     180,197,212,224,235,244,250,253,
  399.     255,253,250,244,235,224,212,197,
  400.     180,161,141,120, 97, 74, 49, 24
  401. };
  402.  
  403. #define INITIAL_DITHER_SEED 0x12345000
  404.  
  405. static int8_t *vibSineTab;
  406. static volatile bool interpolationFlag, volumeRampingFlag, moduleLoaded, musicPaused, songPlaying;
  407. static bool linearFrqTab;
  408. static int16_t *linearPeriods, *amigaPeriods, *note2Period;
  409. static uint16_t pattLens[256], oldPeriod;
  410. static int32_t mixingVol = 256*10*2048, masterVol = 256, masterAmp = 10, quickVolSizeVal, pmpLeft, soundBufferSize, *mixBufferL, *mixBufferR;
  411. static int32_t prngStateL, prngStateR, randSeed = INITIAL_DITHER_SEED;
  412. static uint32_t *logTab, speedVal, sampleCounter, realReplayRate, frequenceDivFactor, frequenceMulFactor;
  413. static uint32_t oldRate, oldSFrq, oldSFrqRev = 0xFFFFFFFF;
  414. static songTyp song;
  415. static tonTyp *patt[256];
  416. static stmTyp stm[MAX_VOICES];
  417. static tonTyp nilPatternLine;
  418. static instrTyp *instr[1 + 128];
  419. static voice_t voice[MAX_VOICES * 2];
  420. static mixRoutine mixRoutineTable[24];
  421.  
  422. static MEMFILE *mopen(const uint8_t *src, uint32_t length);
  423. static void mclose(MEMFILE **buf);
  424. static size_t mread(void *buffer, size_t size, size_t count, MEMFILE *buf);
  425. static bool meof(MEMFILE *buf);
  426. static void mseek(MEMFILE *buf, int32_t offset, int32_t whence);
  427. static void mrewind(MEMFILE *buf);
  428.  
  429. static bool openMixer(uint32_t audioFreq);
  430. static void closeMixer(void);
  431.  
  432. // CODE START
  433.  
  434. static void setSpeed(uint16_t bpm)
  435. {
  436.     if (bpm > 0)
  437.         speedVal = ((realReplayRate + realReplayRate) + (realReplayRate >> 1)) / bpm;
  438. }
  439.  
  440. static void retrigVolume(stmTyp *ch)
  441. {
  442.     ch->realVol = ch->oldVol;
  443.     ch->outVol = ch->oldVol;
  444.     ch->outPan = ch->oldPan;
  445.     ch->status |= (IS_Vol + IS_Pan + IS_QuickVol);
  446. }
  447.  
  448. static void retrigEnvelopeVibrato(stmTyp *ch)
  449. {
  450.     instrTyp *ins;
  451.  
  452.     if (!(ch->waveCtrl & 0x04)) ch->vibPos = 0;
  453.     if (!(ch->waveCtrl & 0x40)) ch->tremPos = 0;
  454.  
  455.     ch->retrigCnt = 0;
  456.     ch->tremorPos = 0;
  457.  
  458.     ch->envSustainActive = true;
  459.  
  460.     ins = ch->instrPtr;
  461.  
  462.     if (ins->envVTyp & 1)
  463.     {
  464.         ch->envVCnt = 65535;
  465.         ch->envVPos = 0;
  466.     }
  467.  
  468.     if (ins->envPTyp & 1)
  469.     {
  470.         ch->envPCnt = 65535;
  471.         ch->envPPos = 0;
  472.     }
  473.  
  474.     ch->fadeOutSpeed = ins->fadeOut; // FT2 doesn't check if fadeout is more than 4095
  475.     ch->fadeOutAmp = 32768;
  476.  
  477.     if (ins->vibDepth > 0)
  478.     {
  479.         ch->eVibPos = 0;
  480.  
  481.         if (ins->vibSweep > 0)
  482.         {
  483.             ch->eVibAmp = 0;
  484.             ch->eVibSweep = (ins->vibDepth << 8) / ins->vibSweep;
  485.         }
  486.         else
  487.         {
  488.             ch->eVibAmp = ins->vibDepth << 8;
  489.             ch->eVibSweep = 0;
  490.         }
  491.     }
  492. }
  493.  
  494. static void keyOff(stmTyp *ch)
  495. {
  496.     instrTyp *ins;
  497.  
  498.     ch->envSustainActive = false;
  499.  
  500.     ins = ch->instrPtr;
  501.  
  502.     if (!(ins->envPTyp & 1)) // yes, FT2 does this (!)
  503.     {
  504.         if (ch->envPCnt >= ins->envPP[ch->envPPos][0])
  505.             ch->envPCnt = ins->envPP[ch->envPPos][0]-1;
  506.     }
  507.  
  508.     if (ins->envVTyp & 1)
  509.     {
  510.         if (ch->envVCnt >= ins->envVP[ch->envVPos][0])
  511.             ch->envVCnt = ins->envVP[ch->envVPos][0]-1;
  512.     }
  513.     else
  514.     {
  515.         ch->realVol = 0;
  516.         ch->outVol = 0;
  517.         ch->status |= (IS_Vol + IS_QuickVol);
  518.     }
  519. }
  520.  
  521. // 100% FT2-accurate routine, do not touch!
  522. static uint32_t getFrequenceValue(uint16_t period)
  523. {
  524.     uint8_t shift;
  525.     uint16_t index;
  526.     uint32_t rate;
  527.  
  528.     if (period == 0)
  529.         return 0;
  530.        
  531.     if (period == oldPeriod)
  532.         return oldRate; // added check: prevent this calculation if it would yield the same
  533.  
  534.     if (linearFrqTab)
  535.     {
  536.         index = (12 * 192 * 4) - period;
  537.         shift = (14 - (index / 768)) & 0x1F;
  538.  
  539.         // this converts to fast code even on x86 (imul + shrd)
  540.         rate = ((uint64_t)logTab[index % 768] * frequenceMulFactor) >> 24;
  541.         if (shift > 0)
  542.             rate >>= shift;
  543.     }
  544.     else
  545.     {
  546.         rate = frequenceDivFactor / period;
  547.     }
  548.    
  549.     oldPeriod = period;
  550.     oldRate = rate;
  551.  
  552.     return rate;
  553. }
  554.  
  555. static void startTone(uint8_t ton, uint8_t effTyp, uint8_t eff, stmTyp *ch)
  556. {
  557.     uint8_t smp;
  558.     uint16_t tmpTon;
  559.     sampleTyp *s;
  560.     instrTyp *ins;
  561.  
  562.     if (ton == 97)
  563.     {
  564.         keyOff(ch);
  565.         return;
  566.     }
  567.  
  568.     // if we came from Rxy (retrig), we didn't check note (Ton) yet
  569.     if (ton == 0)
  570.     {
  571.         ton = ch->tonNr;
  572.         if (ton == 0)
  573.             return; // if still no note, return
  574.     }
  575.  
  576.     ch->tonNr = ton;
  577.  
  578.     if (instr[ch->instrNr] != NULL)
  579.         ins = instr[ch->instrNr];
  580.     else
  581.         ins = instr[0]; // placeholder for empty instruments
  582.  
  583.     ch->instrPtr = ins;
  584.     ch->mute = ins->mute;
  585.  
  586.     if (ton > 96) // added security check
  587.         ton = 96;
  588.  
  589.     smp = ins->ta[ton-1] & 0x0F;
  590.  
  591.     s = &ins->samp[smp];
  592.     ch->smpPtr = s;
  593.     ch->relTonNr = s->relTon;
  594.  
  595.     ton += ch->relTonNr;
  596.     if (ton >= 12*10)
  597.         return;
  598.  
  599.     ch->oldVol = s->vol;
  600.     ch->oldPan = s->pan;
  601.  
  602.     if (effTyp == 0x0E && (eff & 0xF0) == 0x50)
  603.         ch->fineTune = ((eff & 0x0F) * 16) - 128; // result is now -128 .. 127
  604.     else
  605.         ch->fineTune = s->fine;
  606.  
  607.     if (ton > 0)
  608.     {
  609.         tmpTon = ((ton - 1) * 16) + (((ch->fineTune >> 3) + 16) & 0xFF);
  610.  
  611.         if (tmpTon < MAX_NOTES) // should always happen, but FT2 does this check
  612.         {
  613.             ch->realPeriod = note2Period[tmpTon];
  614.             ch->outPeriod = ch->realPeriod;
  615.         }
  616.     }
  617.  
  618.     ch->status |= (IS_Period + IS_Vol + IS_Pan + IS_NyTon + IS_QuickVol);
  619.  
  620.     if (effTyp == 9)
  621.     {
  622.         if (eff)
  623.             ch->smpOffset = ch->eff;
  624.  
  625.         ch->smpStartPos = ch->smpOffset * 256;
  626.     }
  627.     else
  628.     {
  629.         ch->smpStartPos = 0;
  630.     }
  631. }
  632.  
  633. static void multiRetrig(stmTyp *ch)
  634. {
  635.     uint8_t cnt;
  636.     int16_t vol;
  637.  
  638.     cnt = ch->retrigCnt + 1;
  639.     if (cnt < ch->retrigSpeed)
  640.     {
  641.         ch->retrigCnt = cnt;
  642.         return;
  643.     }
  644.  
  645.     ch->retrigCnt = 0;
  646.  
  647.     vol = ch->realVol;
  648.     switch (ch->retrigVol)
  649.     {
  650.         case 0x1: vol -= 1; break;
  651.         case 0x2: vol -= 2; break;
  652.         case 0x3: vol -= 4; break;
  653.         case 0x4: vol -= 8; break;
  654.         case 0x5: vol -= 16; break;
  655.         case 0x6: vol = (vol >> 1) + (vol >> 3) + (vol >> 4); break;
  656.         case 0x7: vol >>= 1; break;
  657.         case 0x8: break; // does not change the volume
  658.         case 0x9: vol += 1; break;
  659.         case 0xA: vol += 2; break;
  660.         case 0xB: vol += 4; break;
  661.         case 0xC: vol += 8; break;
  662.         case 0xD: vol += 16; break;
  663.         case 0xE: vol = (vol >> 1) + vol; break;
  664.         case 0xF: vol += vol; break;
  665.         default: break;
  666.     }
  667.     vol = CLAMP(vol, 0, 64);
  668.  
  669.     ch->realVol = (uint8_t)vol;
  670.     ch->outVol  = ch->realVol;
  671.  
  672.     if (ch->volKolVol >= 0x10 && ch->volKolVol <= 0x50)
  673.     {
  674.         ch->outVol  = ch->volKolVol - 0x10;
  675.         ch->realVol = ch->outVol;
  676.     }
  677.     else if (ch->volKolVol >= 0xC0 && ch->volKolVol <= 0xCF)
  678.     {
  679.         ch->outPan = (ch->volKolVol & 0x0F) << 4;
  680.     }
  681.  
  682.     startTone(0, 0, 0, ch);
  683. }
  684.  
  685. static void checkMoreEffects(stmTyp *ch)
  686. {
  687.     int8_t envPos;
  688.     bool envUpdate;
  689.     uint8_t tmpEff;
  690.     int16_t newEnvPos;
  691.     uint16_t i;
  692.     instrTyp *ins;
  693.  
  694.     ins = ch->instrPtr;
  695.  
  696.     // Bxx - position jump
  697.     if (ch->effTyp == 11)
  698.     {
  699.         song.songPos = (int16_t)ch->eff - 1;
  700.         song.pBreakPos = 0;
  701.         song.posJumpFlag = true;
  702.     }
  703.  
  704.     // Dxx - pattern break
  705.     else if (ch->effTyp == 13)
  706.     {
  707.         song.posJumpFlag = true;
  708.  
  709.         tmpEff = ((ch->eff >> 4) * 10) + (ch->eff & 0x0F);
  710.         if (tmpEff <= 63)
  711.             song.pBreakPos = tmpEff;
  712.         else
  713.             song.pBreakPos = 0;
  714.     }
  715.  
  716.     // Exx - E effects
  717.     else if (ch->effTyp == 14)
  718.     {
  719.         // E1x - fine period slide up
  720.         if ((ch->eff & 0xF0) == 0x10)
  721.         {
  722.             tmpEff = ch->eff & 0x0F;
  723.             if (tmpEff == 0)
  724.                 tmpEff = ch->fPortaUpSpeed;
  725.  
  726.             ch->fPortaUpSpeed = tmpEff;
  727.  
  728.             ch->realPeriod -= tmpEff * 4;
  729.             if (ch->realPeriod < 1)
  730.                 ch->realPeriod = 1;
  731.  
  732.             ch->outPeriod = ch->realPeriod;
  733.             ch->status |= IS_Period;
  734.         }
  735.  
  736.         // E2x - fine period slide down
  737.         else if ((ch->eff & 0xF0) == 0x20)
  738.         {
  739.             tmpEff = ch->eff & 0x0F;
  740.             if (tmpEff == 0)
  741.                 tmpEff = ch->fPortaDownSpeed;
  742.  
  743.             ch->fPortaDownSpeed = tmpEff;
  744.  
  745.             ch->realPeriod += tmpEff * 4;
  746.             if (ch->realPeriod > 32000-1)
  747.                 ch->realPeriod = 32000-1;
  748.  
  749.             ch->outPeriod = ch->realPeriod;
  750.             ch->status   |= IS_Period;
  751.         }
  752.  
  753.         // E3x - set glissando type
  754.         else if ((ch->eff & 0xF0) == 0x30) ch->glissFunk = ch->eff & 0x0F;
  755.  
  756.         // E4x - set vibrato waveform
  757.         else if ((ch->eff & 0xF0) == 0x40) ch->waveCtrl = (ch->waveCtrl & 0xF0) | (ch->eff & 0x0F);
  758.  
  759.         // E5x (set finetune) is handled in StartTone()
  760.  
  761.         // E6x - pattern loop
  762.         else if ((ch->eff & 0xF0) == 0x60)
  763.         {
  764.             if (ch->eff == 0x60) // E60, empty param
  765.             {
  766.                 ch->pattPos = song.pattPos & 0xFF;
  767.             }
  768.             else
  769.             {
  770.                 if (ch->loopCnt == 0)
  771.                 {
  772.                     ch->loopCnt = ch->eff & 0x0F;
  773.                     song.pBreakPos  = ch->pattPos;
  774.                     song.pBreakFlag = true;
  775.                 }
  776.                 else
  777.                 {
  778.                     if (--ch->loopCnt > 0)
  779.                     {
  780.                         song.pBreakPos  = ch->pattPos;
  781.                         song.pBreakFlag = true;
  782.                     }
  783.                 }
  784.             }
  785.         }
  786.  
  787.         // E7x - set tremolo waveform
  788.         else if ((ch->eff & 0xF0) == 0x70) ch->waveCtrl = ((ch->eff & 0x0F) << 4) | (ch->waveCtrl & 0x0F);
  789.  
  790.         // EAx - fine volume slide up
  791.         else if ((ch->eff & 0xF0) == 0xA0)
  792.         {
  793.             tmpEff = ch->eff & 0x0F;
  794.             if (tmpEff == 0)
  795.                 tmpEff = ch->fVolSlideUpSpeed;
  796.  
  797.             ch->fVolSlideUpSpeed = tmpEff;
  798.  
  799.             // unsigned clamp
  800.             if (ch->realVol <= 64-tmpEff)
  801.                 ch->realVol += tmpEff;
  802.             else
  803.                 ch->realVol = 64;
  804.  
  805.             ch->outVol = ch->realVol;
  806.             ch->status |= IS_Vol;
  807.         }
  808.  
  809.         // EBx - fine volume slide down
  810.         else if ((ch->eff & 0xF0) == 0xB0)
  811.         {
  812.             tmpEff = ch->eff & 0x0F;
  813.             if (tmpEff == 0)
  814.                 tmpEff = ch->fVolSlideDownSpeed;
  815.  
  816.             ch->fVolSlideDownSpeed = tmpEff;
  817.  
  818.             // unsigned clamp
  819.             if (ch->realVol >= tmpEff)
  820.                 ch->realVol -= tmpEff;
  821.             else
  822.                 ch->realVol = 0;
  823.  
  824.             ch->outVol = ch->realVol;
  825.             ch->status |= IS_Vol;
  826.         }
  827.  
  828.         // ECx - note cut
  829.         else if ((ch->eff & 0xF0) == 0xC0)
  830.         {
  831.             if (ch->eff == 0xC0) // empty param
  832.             {
  833.                 ch->realVol = 0;
  834.                 ch->outVol = 0;
  835.                 ch->status |= (IS_Vol + IS_QuickVol);
  836.             }
  837.         }
  838.  
  839.         // EEx - pattern delay
  840.         else if ((ch->eff & 0xF0) == 0xE0)
  841.         {
  842.             if (song.pattDelTime2 == 0)
  843.                 song.pattDelTime = (ch->eff & 0x0F) + 1;
  844.         }
  845.     }
  846.  
  847.     // Fxx - set speed/tempo
  848.     else if (ch->effTyp == 15)
  849.     {
  850.         if (ch->eff >= 32)
  851.         {
  852.             song.speed = ch->eff;
  853.             setSpeed(song.speed);
  854.         }
  855.         else
  856.         {
  857.             song.tempo = ch->eff;
  858.             song.timer = ch->eff;
  859.         }
  860.     }
  861.  
  862.     // Gxx - set global volume
  863.     else if (ch->effTyp == 16)
  864.     {
  865.         song.globVol = ch->eff;
  866.         if (song.globVol > 64)
  867.             song.globVol = 64;
  868.  
  869.         for (i = 0; i < song.antChn; i++) // update all voice volumes
  870.             stm[i].status |= IS_Vol;
  871.     }
  872.  
  873.     // Lxx - set vol and pan envelope position
  874.     else if (ch->effTyp == 21)
  875.     {
  876.         // *** VOLUME ENVELOPE ***
  877.         if (ins->envVTyp & 1)
  878.         {
  879.             ch->envVCnt = ch->eff - 1;
  880.  
  881.             envPos = 0;
  882.             envUpdate = true;
  883.             newEnvPos = ch->eff;
  884.  
  885.             if (ins->envVPAnt > 1)
  886.             {
  887.                 envPos++;
  888.                 for (i = 0; i < ins->envVPAnt-1; i++)
  889.                 {
  890.                     if (newEnvPos < ins->envVP[envPos][0])
  891.                     {
  892.                         envPos--;
  893.  
  894.                         newEnvPos -= ins->envVP[envPos][0];
  895.                         if (newEnvPos == 0)
  896.                         {
  897.                             envUpdate = false;
  898.                             break;
  899.                         }
  900.  
  901.                         if (ins->envVP[envPos+1][0] <= ins->envVP[envPos][0])
  902.                         {
  903.                             envUpdate = true;
  904.                             break;
  905.                         }
  906.  
  907.                         ch->envVIPValue = ((ins->envVP[envPos+1][1] - ins->envVP[envPos][1]) & 0xFF) << 8;
  908.                         ch->envVIPValue /= (ins->envVP[envPos+1][0] - ins->envVP[envPos][0]);
  909.  
  910.                         ch->envVAmp = (ch->envVIPValue * (newEnvPos - 1)) + ((ins->envVP[envPos][1] & 0xFF) << 8);
  911.  
  912.                         envPos++;
  913.  
  914.                         envUpdate = false;
  915.                         break;
  916.                     }
  917.  
  918.                     envPos++;
  919.                 }
  920.  
  921.                 if (envUpdate)
  922.                     envPos--;
  923.             }
  924.  
  925.             if (envUpdate)
  926.             {
  927.                 ch->envVIPValue = 0;
  928.                 ch->envVAmp = (ins->envVP[envPos][1] & 0xFF) << 8;
  929.             }
  930.  
  931.             if (envPos >= ins->envVPAnt)
  932.             {
  933.                 envPos = ins->envVPAnt - 1;
  934.                 if (envPos < 0)
  935.                     envPos = 0;
  936.             }
  937.  
  938.             ch->envVPos = envPos;
  939.         }
  940.  
  941.         // *** PANNING ENVELOPE ***
  942.         if (ins->envVTyp & 2) // probably an FT2 bug
  943.         {
  944.             ch->envPCnt = ch->eff - 1;
  945.  
  946.             envPos = 0;
  947.             envUpdate = true;
  948.             newEnvPos = ch->eff;
  949.  
  950.             if (ins->envPPAnt > 1)
  951.             {
  952.                 envPos++;
  953.                 for (i = 0; i < ins->envPPAnt-1; i++)
  954.                 {
  955.                     if (newEnvPos < ins->envPP[envPos][0])
  956.                     {
  957.                         envPos--;
  958.  
  959.                         newEnvPos -= ins->envPP[envPos][0];
  960.                         if (newEnvPos == 0)
  961.                         {
  962.                             envUpdate = false;
  963.                             break;
  964.                         }
  965.  
  966.                         if (ins->envPP[envPos+1][0] <= ins->envPP[envPos][0])
  967.                         {
  968.                             envUpdate = true;
  969.                             break;
  970.                         }
  971.  
  972.                         ch->envPIPValue = ((ins->envPP[envPos+1][1] - ins->envPP[envPos][1]) & 0xFF) << 8;
  973.                         ch->envPIPValue /= (ins->envPP[envPos+1][0] - ins->envPP[envPos][0]);
  974.  
  975.                         ch->envPAmp = (ch->envPIPValue * (newEnvPos - 1)) + ((ins->envPP[envPos][1] & 0xFF) << 8);
  976.  
  977.                         envPos++;
  978.  
  979.                         envUpdate = false;
  980.                         break;
  981.                     }
  982.  
  983.                     envPos++;
  984.                 }
  985.  
  986.                 if (envUpdate)
  987.                     envPos--;
  988.             }
  989.  
  990.             if (envUpdate)
  991.             {
  992.                 ch->envPIPValue = 0;
  993.                 ch->envPAmp = (ins->envPP[envPos][1] & 0xFF) << 8;
  994.             }
  995.  
  996.             if (envPos >= ins->envPPAnt)
  997.             {
  998.                 envPos = ins->envPPAnt - 1;
  999.                 if (envPos < 0)
  1000.                     envPos = 0;
  1001.             }
  1002.  
  1003.             ch->envPPos = envPos;
  1004.         }
  1005.     }
  1006. }
  1007.  
  1008. static void checkEffects(stmTyp *ch)
  1009. {
  1010.     uint8_t tmpEff, tmpEffHi, volKol;
  1011.  
  1012.     // this one is manipulated by vol column effects, then used for multiretrig (FT2 quirk)
  1013.     volKol = ch->volKolVol;
  1014.  
  1015.     // *** VOLUME COLUMN EFFECTS (TICK 0) ***
  1016.  
  1017.     // set volume
  1018.     if (ch->volKolVol >= 0x10 && ch->volKolVol <= 0x50)
  1019.     {
  1020.         volKol -= 16;
  1021.  
  1022.         ch->outVol = volKol;
  1023.         ch->realVol = volKol;
  1024.  
  1025.         ch->status |= (IS_Vol + IS_QuickVol);
  1026.     }
  1027.  
  1028.     // fine volume slide down
  1029.     else if ((ch->volKolVol & 0xF0) == 0x80)
  1030.     {
  1031.         volKol = ch->volKolVol & 0x0F;
  1032.  
  1033.         // unsigned clamp
  1034.         if (ch->realVol >= volKol)
  1035.             ch->realVol -= volKol;
  1036.         else
  1037.             ch->realVol = 0;
  1038.  
  1039.         ch->outVol  = ch->realVol;
  1040.         ch->status |= IS_Vol;
  1041.     }
  1042.  
  1043.     // fine volume slide up
  1044.     else if ((ch->volKolVol & 0xF0) == 0x90)
  1045.     {
  1046.         volKol = ch->volKolVol & 0x0F;
  1047.  
  1048.         // unsigned clamp
  1049.         if (ch->realVol <= 64-volKol)
  1050.             ch->realVol += volKol;
  1051.         else
  1052.             ch->realVol = 64;
  1053.  
  1054.         ch->outVol  = ch->realVol;
  1055.         ch->status |= IS_Vol;
  1056.     }
  1057.  
  1058.     // set vibrato speed
  1059.     else if ((ch->volKolVol & 0xF0) == 0xA0)
  1060.     {
  1061.         volKol = (ch->volKolVol & 0x0F) << 2;
  1062.         ch->vibSpeed = volKol;
  1063.     }
  1064.  
  1065.     // set panning
  1066.     else if ((ch->volKolVol & 0xF0) == 0xC0)
  1067.     {
  1068.         volKol <<= 4;
  1069.  
  1070.         ch->outPan = volKol;
  1071.         ch->status |= IS_Pan;
  1072.     }
  1073.  
  1074.     // *** MAIN EFFECTS (TICK 0) ***
  1075.  
  1076.     if (ch->effTyp == 0 && ch->eff == 0) return; // no effect
  1077.  
  1078.     // Cxx - set volume
  1079.     if (ch->effTyp == 12)
  1080.     {
  1081.         ch->realVol = ch->eff;
  1082.         if (ch->realVol > 64)
  1083.             ch->realVol = 64;
  1084.  
  1085.         ch->outVol = ch->realVol;
  1086.         ch->status |= (IS_Vol + IS_QuickVol);
  1087.  
  1088.         return;
  1089.     }
  1090.  
  1091.     // 8xx - set panning
  1092.     else if (ch->effTyp == 8)
  1093.     {
  1094.         ch->outPan  = ch->eff;
  1095.         ch->status |= IS_Pan;
  1096.  
  1097.         return;
  1098.     }
  1099.  
  1100.     // Rxy - note multi retrigger
  1101.     else if (ch->effTyp == 27)
  1102.     {
  1103.         tmpEff = ch->eff & 0x0F;
  1104.         if (tmpEff == 0)
  1105.             tmpEff = ch->retrigSpeed;
  1106.  
  1107.         ch->retrigSpeed = tmpEff;
  1108.  
  1109.         tmpEffHi = ch->eff >> 4;
  1110.         if (tmpEffHi == 0)
  1111.             tmpEffHi = ch->retrigVol;
  1112.  
  1113.         ch->retrigVol = tmpEffHi;
  1114.  
  1115.         if (volKol == 0)
  1116.             multiRetrig(ch);
  1117.  
  1118.         return;
  1119.     }
  1120.  
  1121.     // X1x - extra fine period slide up
  1122.     else if (ch->effTyp == 33 && (ch->eff & 0xF0) == 0x10)
  1123.     {
  1124.         tmpEff = ch->eff & 0x0F;
  1125.         if (tmpEff == 0)
  1126.             tmpEff = ch->ePortaUpSpeed;
  1127.  
  1128.         ch->ePortaUpSpeed = tmpEff;
  1129.  
  1130.         ch->realPeriod -= tmpEff;
  1131.         if (ch->realPeriod < 1)
  1132.             ch->realPeriod = 1;
  1133.  
  1134.         ch->outPeriod = ch->realPeriod;
  1135.         ch->status |= IS_Period;
  1136.  
  1137.         return;
  1138.     }
  1139.  
  1140.     // X2x - extra fine period slide down
  1141.     else if (ch->effTyp == 33 && (ch->eff & 0xF0) == 0x20)
  1142.     {
  1143.         tmpEff = ch->eff & 0x0F;
  1144.         if (tmpEff == 0)
  1145.             tmpEff = ch->ePortaDownSpeed;
  1146.  
  1147.         ch->ePortaDownSpeed = tmpEff;
  1148.  
  1149.         ch->realPeriod += tmpEff;
  1150.         if (ch->realPeriod > 32000-1)
  1151.             ch->realPeriod = 32000-1;
  1152.  
  1153.         ch->outPeriod = ch->realPeriod;
  1154.         ch->status |= IS_Period;
  1155.  
  1156.         return;
  1157.     }
  1158.  
  1159.     checkMoreEffects(ch);
  1160. }
  1161.  
  1162. static void fixTonePorta(stmTyp *ch, tonTyp *p, uint8_t inst)
  1163. {
  1164.     uint16_t portaTmp;
  1165.  
  1166.     if (p->ton > 0)
  1167.     {
  1168.         if (p->ton == 97)
  1169.         {
  1170.             keyOff(ch);
  1171.         }
  1172.         else
  1173.         {
  1174.             portaTmp = ((((p->ton - 1) + ch->relTonNr) & 0xFF) * 16) + (((ch->fineTune >> 3) + 16) & 0xFF);
  1175.             if (portaTmp < MAX_NOTES)
  1176.             {
  1177.                 ch->wantPeriod = note2Period[portaTmp];
  1178.  
  1179.                      if (ch->wantPeriod == ch->realPeriod) ch->portaDir = 0;
  1180.                 else if (ch->wantPeriod  > ch->realPeriod) ch->portaDir = 1;
  1181.                 else ch->portaDir = 2;
  1182.             }
  1183.         }
  1184.     }
  1185.  
  1186.     if (inst > 0)
  1187.     {
  1188.         retrigVolume(ch);
  1189.         if (p->ton != 97)
  1190.             retrigEnvelopeVibrato(ch);
  1191.     }
  1192. }
  1193.  
  1194. static void getNewNote(stmTyp *ch, tonTyp *p)
  1195. {
  1196.     uint8_t inst;
  1197.     bool checkEfx;
  1198.  
  1199.     ch->volKolVol = p->vol;
  1200.  
  1201.     if (ch->effTyp == 0)
  1202.     {
  1203.         if (ch->eff > 0)
  1204.         {
  1205.             // we have an arpeggio running, set period back
  1206.             ch->outPeriod = ch->realPeriod;
  1207.             ch->status |= IS_Period;
  1208.         }
  1209.     }
  1210.     else
  1211.     {
  1212.         if (ch->effTyp == 4 || ch->effTyp == 6)
  1213.         {
  1214.             // we have a vibrato running
  1215.             if (p->effTyp != 4 && p->effTyp != 6)
  1216.             {
  1217.                 // but it's ending at the next (this) row, so set period back
  1218.                 ch->outPeriod = ch->realPeriod;
  1219.                 ch->status |= IS_Period;
  1220.             }
  1221.         }
  1222.     }
  1223.  
  1224.     ch->effTyp = p->effTyp;
  1225.     ch->eff = p->eff;
  1226.     ch->tonTyp = (p->instr << 8) | p->ton;
  1227.  
  1228.     // 'inst' var is used for later if checks...
  1229.     inst = p->instr;
  1230.     if (inst > 0)
  1231.     {
  1232.         if (inst <= 128)
  1233.             ch->instrNr = inst;
  1234.         else
  1235.             inst = 0;
  1236.     }
  1237.  
  1238.     checkEfx = true;
  1239.     if (p->effTyp == 0x0E)
  1240.     {
  1241.         if (p->eff >= 0xD1 && p->eff <= 0xDF)
  1242.             return; // we have a note delay (ED1..EDF)
  1243.         else if (p->eff == 0x90)
  1244.             checkEfx = false;
  1245.     }
  1246.  
  1247.     if (checkEfx)
  1248.     {
  1249.         if ((ch->volKolVol & 0xF0) == 0xF0) // gxx
  1250.         {
  1251.             if ((ch->volKolVol & 0x0F) > 0)
  1252.                 ch->portaSpeed = (ch->volKolVol & 0x0F) << 6;
  1253.  
  1254.             fixTonePorta(ch, p, inst);
  1255.             checkEffects(ch);
  1256.  
  1257.             return;
  1258.         }
  1259.  
  1260.         if (p->effTyp == 3 || p->effTyp == 5) // 3xx or 5xx
  1261.         {
  1262.             if (p->effTyp != 5 && p->eff != 0)
  1263.                 ch->portaSpeed = p->eff << 2;
  1264.  
  1265.             fixTonePorta(ch, p, inst);
  1266.             checkEffects(ch);
  1267.  
  1268.             return;
  1269.         }
  1270.  
  1271.         if (p->effTyp == 0x14 && p->eff == 0) // K00 (KeyOff - only handle tick 0 here)
  1272.         {
  1273.             keyOff(ch);
  1274.  
  1275.             if (inst)
  1276.                 retrigVolume(ch);
  1277.  
  1278.             checkEffects(ch);
  1279.             return;
  1280.         }
  1281.  
  1282.         if (p->ton == 0)
  1283.         {
  1284.             if (inst > 0)
  1285.             {
  1286.                 retrigVolume(ch);
  1287.                 retrigEnvelopeVibrato(ch);
  1288.             }
  1289.  
  1290.             checkEffects(ch);
  1291.             return;
  1292.         }
  1293.     }
  1294.  
  1295.     if (p->ton == 97)
  1296.         keyOff(ch);
  1297.     else
  1298.         startTone(p->ton, p->effTyp, p->eff, ch);
  1299.  
  1300.     if (inst > 0)
  1301.     {
  1302.         retrigVolume(ch);
  1303.  
  1304.         if (p->ton != 97)
  1305.             retrigEnvelopeVibrato(ch);
  1306.     }
  1307.  
  1308.     checkEffects(ch);
  1309. }
  1310.  
  1311. static void fixaEnvelopeVibrato(stmTyp *ch)
  1312. {
  1313.     bool envInterpolateFlag, envDidInterpolate;
  1314.     uint8_t envPos;
  1315.     int16_t autoVibVal, panTmp;
  1316.     uint16_t autoVibAmp, tmpPeriod, envVal;
  1317.     int32_t vol;
  1318.     instrTyp *ins;
  1319.  
  1320.     ins = ch->instrPtr;
  1321.  
  1322.     // *** FADEOUT ***
  1323.     if (!ch->envSustainActive)
  1324.     {
  1325.         ch->status |= IS_Vol;
  1326.  
  1327.         // unsigned clamp + reset
  1328.         if (ch->fadeOutAmp >= ch->fadeOutSpeed)
  1329.         {
  1330.             ch->fadeOutAmp -= ch->fadeOutSpeed;
  1331.         }
  1332.         else
  1333.         {
  1334.             ch->fadeOutAmp = 0;
  1335.             ch->fadeOutSpeed = 0;
  1336.         }
  1337.     }
  1338.  
  1339.     if (ch->mute != 1)
  1340.     {
  1341.         // *** VOLUME ENVELOPE ***
  1342.         envVal = 0;
  1343.         if (ins->envVTyp & 1)
  1344.         {
  1345.             envDidInterpolate = false;
  1346.             envPos = ch->envVPos;
  1347.  
  1348.             if (++ch->envVCnt == ins->envVP[envPos][0])
  1349.             {
  1350.                 ch->envVAmp = ins->envVP[envPos][1] << 8;
  1351.  
  1352.                 envPos++;
  1353.                 if (ins->envVTyp & 4)
  1354.                 {
  1355.                     envPos--;
  1356.  
  1357.                     if (envPos == ins->envVRepE)
  1358.                     {
  1359.                         if (!(ins->envVTyp & 2) || envPos != ins->envVSust || ch->envSustainActive)
  1360.                         {
  1361.                             envPos = ins->envVRepS;
  1362.  
  1363.                             ch->envVCnt = ins->envVP[envPos][0];
  1364.                             ch->envVAmp = ins->envVP[envPos][1] << 8;
  1365.                         }
  1366.                     }
  1367.  
  1368.                     envPos++;
  1369.                 }
  1370.  
  1371.                 if (envPos < ins->envVPAnt)
  1372.                 {
  1373.                     envInterpolateFlag = true;
  1374.                     if ((ins->envVTyp & 2) && ch->envSustainActive)
  1375.                     {
  1376.                         if (envPos-1 == ins->envVSust)
  1377.                         {
  1378.                             envPos--;
  1379.                             ch->envVIPValue = 0;
  1380.                             envInterpolateFlag = false;
  1381.                         }
  1382.                     }
  1383.  
  1384.                     if (envInterpolateFlag)
  1385.                     {
  1386.                         ch->envVPos = envPos;
  1387.  
  1388.                         ch->envVIPValue = 0;
  1389.                         if (ins->envVP[envPos][0] > ins->envVP[envPos-1][0])
  1390.                         {
  1391.                             ch->envVIPValue = (ins->envVP[envPos][1] - ins->envVP[envPos-1][1]) << 8;
  1392.                             ch->envVIPValue /= (ins->envVP[envPos][0] - ins->envVP[envPos-1][0]);
  1393.  
  1394.                             envVal = ch->envVAmp;
  1395.                             envDidInterpolate = true;
  1396.                         }
  1397.                     }
  1398.                 }
  1399.                 else
  1400.                 {
  1401.                     ch->envVIPValue = 0;
  1402.                 }
  1403.             }
  1404.  
  1405.             if (!envDidInterpolate)
  1406.             {
  1407.                 ch->envVAmp += ch->envVIPValue;
  1408.  
  1409.                 envVal = ch->envVAmp;
  1410.                 if (envVal > 64*256)
  1411.                 {
  1412.                     if (envVal > 128*256)
  1413.                         envVal = 64*256;
  1414.                     else
  1415.                         envVal = 0;
  1416.  
  1417.                     ch->envVIPValue = 0;
  1418.                 }
  1419.             }
  1420.  
  1421.             /* calculate with 256 times more precision (vol = 0..65535)
  1422.             ** Also, vol envelope range is now 0..16384 instead of being shifted to 0..64
  1423.             */
  1424.  
  1425.             uint32_t vol1 = song.globVol * ch->outVol * ch->fadeOutAmp; // 0..64 * 0..64 * 0..32768 = 0..134217728
  1426.             uint32_t vol2 = envVal << 7; // 0..16384 * 2^7 = 0..2097152
  1427.  
  1428.             vol = ((uint64_t)vol1 * vol2) >> 32; // 0..65536
  1429.  
  1430.             ch->status |= IS_Vol;
  1431.         }
  1432.         else
  1433.         {
  1434.             /* original FT2 method with lower precision (finalVol = 0..256)
  1435.             vol = (song.globVol * (((ch->outVol << 4) * ch->fadeOutAmp) >> 16)) >> 7;
  1436.             */
  1437.  
  1438.             // calculate with four times more precision (finalVol = 0..2048)
  1439.             vol = (song.globVol * ch->outVol * ch->fadeOutAmp) >> 11; // 0..64 * 0..64 * 0..32768 = 0..65536
  1440.         }
  1441.        
  1442.         if (vol > 65535)
  1443.             vol = 65535; // range is now 0..65535 to prevent MUL overflow when voice volume is calculated
  1444.  
  1445.         ch->finalVol = (uint16_t)vol;
  1446.     }
  1447.     else
  1448.     {
  1449.         ch->finalVol = 0;
  1450.     }
  1451.  
  1452.     // *** PANNING ENVELOPE ***
  1453.  
  1454.     envVal = 0;
  1455.     if (ins->envPTyp & 1)
  1456.     {
  1457.         envDidInterpolate = false;
  1458.         envPos = ch->envPPos;
  1459.  
  1460.         if (++ch->envPCnt == ins->envPP[envPos][0])
  1461.         {
  1462.             ch->envPAmp = ins->envPP[envPos][1] << 8;
  1463.  
  1464.             envPos++;
  1465.             if (ins->envPTyp & 4)
  1466.             {
  1467.                 envPos--;
  1468.  
  1469.                 if (envPos == ins->envPRepE)
  1470.                 {
  1471.                     if (!(ins->envPTyp & 2) || envPos != ins->envPSust || ch->envSustainActive)
  1472.                     {
  1473.                         envPos = ins->envPRepS;
  1474.  
  1475.                         ch->envPCnt = ins->envPP[envPos][0];
  1476.                         ch->envPAmp = ins->envPP[envPos][1] << 8;
  1477.                     }
  1478.                 }
  1479.  
  1480.                 envPos++;
  1481.             }
  1482.  
  1483.             if (envPos < ins->envPPAnt)
  1484.             {
  1485.                 envInterpolateFlag = true;
  1486.                 if ((ins->envPTyp & 2) && ch->envSustainActive)
  1487.                 {
  1488.                     if (envPos-1 == ins->envPSust)
  1489.                     {
  1490.                         envPos--;
  1491.                         ch->envPIPValue = 0;
  1492.                         envInterpolateFlag = false;
  1493.                     }
  1494.                 }
  1495.  
  1496.                 if (envInterpolateFlag)
  1497.                 {
  1498.                     ch->envPPos = envPos;
  1499.  
  1500.                     ch->envPIPValue = 0;
  1501.                     if (ins->envPP[envPos][0] > ins->envPP[envPos-1][0])
  1502.                     {
  1503.                         ch->envPIPValue = (ins->envPP[envPos][1] - ins->envPP[envPos-1][1]) << 8;
  1504.                         ch->envPIPValue /= (ins->envPP[envPos][0] - ins->envPP[envPos-1][0]);
  1505.  
  1506.                         envVal = ch->envPAmp;
  1507.                         envDidInterpolate = true;
  1508.                     }
  1509.                 }
  1510.             }
  1511.             else
  1512.             {
  1513.                 ch->envPIPValue = 0;
  1514.             }
  1515.         }
  1516.  
  1517.         if (!envDidInterpolate)
  1518.         {
  1519.             ch->envPAmp += ch->envPIPValue;
  1520.  
  1521.             envVal = ch->envPAmp;
  1522.             if (envVal > 64*256)
  1523.             {
  1524.                 if (envVal > 128*256)
  1525.                     envVal = 64*256;
  1526.                 else
  1527.                     envVal = 0;
  1528.  
  1529.                 ch->envPIPValue = 0;
  1530.             }
  1531.         }
  1532.  
  1533.         panTmp = ch->outPan - 128;
  1534.         if (panTmp > 0)
  1535.             panTmp = 0 - panTmp;
  1536.         panTmp += 128;
  1537.  
  1538.         envVal -= 32*256;
  1539.  
  1540.         ch->finalPan = ch->outPan + (uint8_t)(((int16_t)envVal * panTmp) >> 13);
  1541.         ch->status |= IS_Pan;
  1542.     }
  1543.     else
  1544.     {
  1545.         ch->finalPan = ch->outPan;
  1546.     }
  1547.  
  1548.     // *** AUTO VIBRATO ***
  1549.     if (ins->vibDepth > 0)
  1550.     {
  1551.         if (ch->eVibSweep > 0)
  1552.         {
  1553.             autoVibAmp = ch->eVibSweep;
  1554.             if (ch->envSustainActive)
  1555.             {
  1556.                 autoVibAmp += ch->eVibAmp;
  1557.                 if ((autoVibAmp >> 8) > ins->vibDepth)
  1558.                 {
  1559.                     autoVibAmp = ins->vibDepth << 8;
  1560.                     ch->eVibSweep = 0;
  1561.                 }
  1562.  
  1563.                 ch->eVibAmp = autoVibAmp;
  1564.             }
  1565.         }
  1566.         else
  1567.         {
  1568.             autoVibAmp = ch->eVibAmp;
  1569.         }
  1570.  
  1571.         ch->eVibPos += ins->vibRate;
  1572.  
  1573.              if (ins->vibTyp == 1) autoVibVal = (ch->eVibPos > 127) ? 64 : -64; // square
  1574.         else if (ins->vibTyp == 2) autoVibVal = (((ch->eVibPos >> 1) + 64) & 127) - 64; // ramp up
  1575.         else if (ins->vibTyp == 3) autoVibVal = (((0 - (ch->eVibPos >> 1)) + 64) & 127) - 64; // ramp down
  1576.         else autoVibVal = vibSineTab[ch->eVibPos]; // sine
  1577.  
  1578.         autoVibVal <<= 2;
  1579.  
  1580.         tmpPeriod = ch->outPeriod + (int16_t)((autoVibVal * (int16_t)autoVibAmp) >> 16);
  1581.         if (tmpPeriod > 32000-1)
  1582.             tmpPeriod = 0;
  1583.  
  1584.         ch->finalPeriod = tmpPeriod;
  1585.         ch->status |= IS_Period;
  1586.     }
  1587.     else
  1588.     {
  1589.         ch->finalPeriod = ch->outPeriod;
  1590.     }
  1591. }
  1592.  
  1593. static int16_t relocateTon(int16_t period, int8_t relativeNote, stmTyp *ch)
  1594. {
  1595.     int8_t fineTune;
  1596.     int32_t loPeriod, hiPeriod, tmpPeriod, tableIndex;
  1597.  
  1598.     fineTune = (ch->fineTune >> 3) + 16;
  1599.     hiPeriod = 8 * 12 * 16;
  1600.     loPeriod = 0;
  1601.  
  1602.     for (int8_t i = 0; i < 8; i++)
  1603.     {
  1604.         tmpPeriod = (((loPeriod + hiPeriod) >> 1) & 0xFFFFFFF0) + fineTune;
  1605.  
  1606.         tableIndex = tmpPeriod - 8;
  1607.         if (tableIndex < 0) // added security check
  1608.             tableIndex = 0;
  1609.  
  1610.         if (period >= note2Period[tableIndex])
  1611.             hiPeriod = tmpPeriod - fineTune;
  1612.         else
  1613.             loPeriod = tmpPeriod - fineTune;
  1614.     }
  1615.  
  1616.     tmpPeriod = loPeriod + fineTune + (relativeNote << 4);
  1617.     if (tmpPeriod < 0) // added security check
  1618.         tmpPeriod = 0;
  1619.  
  1620.     if (tmpPeriod >= ((8*12*16)+15)-1) // FT2 bug: off-by-one edge case
  1621.         tmpPeriod = (8*12*16)+15;
  1622.  
  1623.     return note2Period[tmpPeriod];
  1624. }
  1625.  
  1626. static void tonePorta(stmTyp *ch)
  1627. {
  1628.     if (ch->portaDir == 0)
  1629.         return;
  1630.  
  1631.     if (ch->portaDir > 1)
  1632.     {
  1633.         ch->realPeriod -= ch->portaSpeed;
  1634.         if (ch->realPeriod <= ch->wantPeriod)
  1635.         {
  1636.             ch->portaDir = 1;
  1637.             ch->realPeriod = ch->wantPeriod;
  1638.         }
  1639.     }
  1640.     else
  1641.     {
  1642.         ch->realPeriod += ch->portaSpeed;
  1643.         if (ch->realPeriod >= ch->wantPeriod)
  1644.         {
  1645.             ch->portaDir = 1;
  1646.             ch->realPeriod = ch->wantPeriod;
  1647.         }
  1648.     }
  1649.  
  1650.     if (ch->glissFunk) // semi-tone slide flag
  1651.         ch->outPeriod = relocateTon(ch->realPeriod, 0, ch);
  1652.     else
  1653.         ch->outPeriod = ch->realPeriod;
  1654.  
  1655.     ch->status |= IS_Period;
  1656. }
  1657.  
  1658. static void volume(stmTyp *ch) // actually volume slide
  1659. {
  1660.     uint8_t tmpEff = ch->eff;
  1661.     if (tmpEff == 0)
  1662.         tmpEff = ch->volSlideSpeed;
  1663.  
  1664.     ch->volSlideSpeed = tmpEff;
  1665.  
  1666.     if ((tmpEff & 0xF0) == 0)
  1667.     {
  1668.         // unsigned clamp
  1669.         if (ch->realVol >= tmpEff)
  1670.             ch->realVol -= tmpEff;
  1671.         else
  1672.             ch->realVol = 0;
  1673.     }
  1674.     else
  1675.     {
  1676.         // unsigned clamp
  1677.         if (ch->realVol <= 64-(tmpEff>>4))
  1678.             ch->realVol += tmpEff >> 4;
  1679.         else
  1680.             ch->realVol = 64;
  1681.     }
  1682.  
  1683.     ch->outVol = ch->realVol;
  1684.     ch->status |= IS_Vol;
  1685. }
  1686.  
  1687. static void vibrato2(stmTyp *ch)
  1688. {
  1689.     uint8_t tmpVib = (ch->vibPos / 4) & 0x1F;
  1690.  
  1691.     switch (ch->waveCtrl & 0x03)
  1692.     {
  1693.         // 0: sine
  1694.         case 0: tmpVib = vibTab[tmpVib]; break;
  1695.  
  1696.         // 1: ramp
  1697.         case 1:
  1698.         {
  1699.             tmpVib *= 8;
  1700.             if (ch->vibPos >= 128)
  1701.                 tmpVib ^= 0xFF;
  1702.         }
  1703.         break;
  1704.  
  1705.         // 2/3: square
  1706.         default: tmpVib = 255; break;
  1707.     }
  1708.  
  1709.     tmpVib = (tmpVib * ch->vibDepth) / 32;
  1710.  
  1711.     if (ch->vibPos >= 128)
  1712.         ch->outPeriod = ch->realPeriod - tmpVib;
  1713.     else
  1714.         ch->outPeriod = ch->realPeriod + tmpVib;
  1715.  
  1716.     ch->status |= IS_Period;
  1717.     ch->vibPos += ch->vibSpeed;
  1718. }
  1719.  
  1720. static void vibrato(stmTyp *ch)
  1721. {
  1722.     if (ch->eff > 0)
  1723.     {
  1724.         if ((ch->eff & 0x0F) > 0) ch->vibDepth = ch->eff & 0x0F;
  1725.         if ((ch->eff & 0xF0) > 0) ch->vibSpeed = (ch->eff >> 4) * 4;
  1726.     }
  1727.  
  1728.     vibrato2(ch);
  1729. }
  1730.  
  1731. static void doEffects(stmTyp *ch)
  1732. {
  1733.     int8_t note;
  1734.     uint8_t tmpEff, tremorData, tremorSign, tmpTrem;
  1735.     int16_t tremVol;
  1736.     uint16_t i, tick;
  1737.  
  1738.     // *** VOLUME COLUMN EFFECTS (TICKS >0) ***
  1739.  
  1740.     // volume slide down
  1741.     if ((ch->volKolVol & 0xF0) == 0x60)
  1742.     {
  1743.         // unsigned clamp
  1744.         if (ch->realVol >= (ch->volKolVol & 0x0F))
  1745.             ch->realVol -= ch->volKolVol & 0x0F;
  1746.         else
  1747.             ch->realVol = 0;
  1748.  
  1749.         ch->outVol = ch->realVol;
  1750.         ch->status |= IS_Vol;
  1751.     }
  1752.  
  1753.     // volume slide up
  1754.     else if ((ch->volKolVol & 0xF0) == 0x70)
  1755.     {
  1756.         // unsigned clamp
  1757.         if (ch->realVol <= 64-(ch->volKolVol & 0x0F))
  1758.             ch->realVol += ch->volKolVol & 0x0F;
  1759.         else
  1760.             ch->realVol = 64;
  1761.  
  1762.         ch->outVol = ch->realVol;
  1763.         ch->status |= IS_Vol;
  1764.     }
  1765.  
  1766.     // vibrato (+ set vibrato depth)
  1767.     else if ((ch->volKolVol & 0xF0) == 0xB0)
  1768.     {
  1769.         if (ch->volKolVol != 0xB0)
  1770.             ch->vibDepth = ch->volKolVol & 0x0F;
  1771.  
  1772.         vibrato2(ch);
  1773.     }
  1774.  
  1775.     // pan slide left
  1776.     else if ((ch->volKolVol & 0xF0) == 0xD0)
  1777.     {
  1778.         // unsigned clamp + a bug when the parameter is 0
  1779.         if ((ch->volKolVol & 0x0F) == 0 || ch->outPan < (ch->volKolVol & 0x0F))
  1780.             ch->outPan = 0;
  1781.         else
  1782.             ch->outPan -= ch->volKolVol & 0x0F;
  1783.  
  1784.         ch->status |= IS_Pan;
  1785.     }
  1786.  
  1787.     // pan slide right
  1788.     else if ((ch->volKolVol & 0xF0) == 0xE0)
  1789.     {
  1790.         // unsigned clamp
  1791.         if (ch->outPan <= 255-(ch->volKolVol & 0x0F))
  1792.             ch->outPan += ch->volKolVol & 0x0F;
  1793.         else
  1794.             ch->outPan = 255;
  1795.  
  1796.         ch->status |= IS_Pan;
  1797.     }
  1798.  
  1799.     // tone portamento
  1800.     else if ((ch->volKolVol & 0xF0) == 0xF0) tonePorta(ch);
  1801.  
  1802.     // *** MAIN EFFECTS (TICKS >0) ***
  1803.  
  1804.     if ((ch->eff == 0 && ch->effTyp == 0) || ch->effTyp >= 36) return; // no effect
  1805.  
  1806.     // 0xy - Arpeggio
  1807.     if (ch->effTyp == 0)
  1808.     {
  1809.         tick = song.timer;
  1810.  
  1811.         // FT2 'out of boundary LUT read' arp simulation
  1812.              if (tick  < 16) tick %= 3;
  1813.         else if (tick == 16) tick  = 0;
  1814.         else tick = 2;
  1815.  
  1816.         if (tick == 0)
  1817.         {
  1818.             ch->outPeriod = ch->realPeriod;
  1819.         }
  1820.         else
  1821.         {
  1822.             if (tick == 1)
  1823.                 note = ch->eff >> 4;
  1824.             else
  1825.                 note = ch->eff & 0xF; // tick 2
  1826.  
  1827.             ch->outPeriod = relocateTon(ch->realPeriod, note, ch);
  1828.         }
  1829.  
  1830.         ch->status |= IS_Period;
  1831.     }
  1832.  
  1833.     // 1xx - period slide up
  1834.     else if (ch->effTyp == 1)
  1835.     {
  1836.         tmpEff = ch->eff;
  1837.         if (tmpEff == 0)
  1838.             tmpEff = ch->portaUpSpeed;
  1839.  
  1840.         ch->portaUpSpeed = tmpEff;
  1841.  
  1842.         ch->realPeriod -= tmpEff * 4;
  1843.         if (ch->realPeriod < 1)
  1844.             ch->realPeriod = 1;
  1845.  
  1846.         ch->outPeriod = ch->realPeriod;
  1847.         ch->status |= IS_Period;
  1848.     }
  1849.  
  1850.     // 2xx - period slide down
  1851.     else if (ch->effTyp == 2)
  1852.     {
  1853.         tmpEff = ch->eff;
  1854.         if (tmpEff == 0)
  1855.             tmpEff = ch->portaDownSpeed;
  1856.  
  1857.         ch->portaDownSpeed = tmpEff;
  1858.  
  1859.         ch->realPeriod += tmpEff * 4;
  1860.         if (ch->realPeriod > 32000-1)
  1861.             ch->realPeriod = 32000-1;
  1862.  
  1863.         ch->outPeriod = ch->realPeriod;
  1864.         ch->status |= IS_Period;
  1865.     }
  1866.  
  1867.     // 3xx - tone portamento
  1868.     else if (ch->effTyp == 3) tonePorta(ch);
  1869.  
  1870.     // 4xy - vibrato
  1871.     else if (ch->effTyp == 4) vibrato(ch);
  1872.  
  1873.     // 5xy - tone portamento + volume slide
  1874.     else if (ch->effTyp == 5)
  1875.     {
  1876.         tonePorta(ch);
  1877.         volume(ch);
  1878.     }
  1879.  
  1880.     // 6xy - vibrato + volume slide
  1881.     else if (ch->effTyp == 6)
  1882.     {
  1883.         vibrato2(ch);
  1884.         volume(ch);
  1885.     }
  1886.  
  1887.     // 7xy - tremolo
  1888.     else if (ch->effTyp == 7)
  1889.     {
  1890.         tmpEff = ch->eff;
  1891.         if (tmpEff > 0)
  1892.         {
  1893.             if ((tmpEff & 0x0F) > 0) ch->tremDepth = tmpEff & 0x0F;
  1894.             if ((tmpEff & 0xF0) > 0) ch->tremSpeed = (tmpEff >> 4) * 4;
  1895.         }
  1896.  
  1897.         tmpTrem = (ch->tremPos / 4) & 0x1F;
  1898.         switch ((ch->waveCtrl >> 4) & 3)
  1899.         {
  1900.             // 0: sine
  1901.             case 0: tmpTrem = vibTab[tmpTrem]; break;
  1902.  
  1903.             // 1: ramp
  1904.             case 1:
  1905.             {
  1906.                 tmpTrem *= 8;
  1907.                 if (ch->vibPos >= 128) tmpTrem ^= 0xFF; // FT2 bug, should've been TremPos
  1908.             }
  1909.             break;
  1910.  
  1911.             // 2/3: square
  1912.             default: tmpTrem = 255; break;
  1913.         }
  1914.         tmpTrem = (tmpTrem * ch->tremDepth) / 64;
  1915.  
  1916.         if (ch->tremPos >= 128)
  1917.         {
  1918.             tremVol = ch->realVol - tmpTrem;
  1919.             if (tremVol < 0)
  1920.                 tremVol = 0;
  1921.         }
  1922.         else
  1923.         {
  1924.             tremVol = ch->realVol + tmpTrem;
  1925.             if (tremVol > 64)
  1926.                 tremVol = 64;
  1927.         }
  1928.  
  1929.         ch->outVol = tremVol & 0xFF;
  1930.         ch->tremPos += ch->tremSpeed;
  1931.         ch->status |= IS_Vol;
  1932.     }
  1933.  
  1934.     // Axy - volume slide
  1935.     else if (ch->effTyp == 10) volume(ch); // actually volume slide
  1936.  
  1937.     // Exy - E effects
  1938.     else if (ch->effTyp == 14)
  1939.     {
  1940.         // E9x - note retrigger
  1941.         if ((ch->eff & 0xF0) == 0x90)
  1942.         {
  1943.             if (ch->eff != 0x90) // E90 is handled in getNewNote()
  1944.             {
  1945.                 if ((song.tempo-song.timer) % (ch->eff & 0x0F) == 0)
  1946.                 {
  1947.                     startTone(0, 0, 0, ch);
  1948.                     retrigEnvelopeVibrato(ch);
  1949.                 }
  1950.             }
  1951.         }
  1952.  
  1953.         // ECx - note cut
  1954.         else if ((ch->eff & 0xF0) == 0xC0)
  1955.         {
  1956.             if (((song.tempo-song.timer) & 0xFF) == (ch->eff & 0x0F))
  1957.             {
  1958.                 ch->outVol = 0;
  1959.                 ch->realVol = 0;
  1960.                 ch->status |= (IS_Vol + IS_QuickVol);
  1961.             }
  1962.         }
  1963.  
  1964.         // EDx - note delay
  1965.         else if ((ch->eff & 0xF0) == 0xD0)
  1966.         {
  1967.             if (((song.tempo-song.timer) & 0xFF) == (ch->eff & 0x0F))
  1968.             {
  1969.                 startTone(ch->tonTyp & 0xFF, 0, 0, ch);
  1970.  
  1971.                 if ((ch->tonTyp & 0xFF00) > 0)
  1972.                     retrigVolume(ch);
  1973.  
  1974.                 retrigEnvelopeVibrato(ch);
  1975.  
  1976.                 if (ch->volKolVol >= 0x10 && ch->volKolVol <= 0x50)
  1977.                 {
  1978.                     ch->outVol = ch->volKolVol - 16;
  1979.                     ch->realVol = ch->outVol;
  1980.                 }
  1981.                 else if (ch->volKolVol >= 0xC0 && ch->volKolVol <= 0xCF)
  1982.                 {
  1983.                     ch->outPan = (ch->volKolVol & 0x0F) << 4;
  1984.                 }
  1985.             }
  1986.         }
  1987.     }
  1988.  
  1989.     // Hxy - global volume slide
  1990.     else if (ch->effTyp == 17)
  1991.     {
  1992.         tmpEff = ch->eff;
  1993.         if (tmpEff == 0)
  1994.             tmpEff = ch->globVolSlideSpeed;
  1995.  
  1996.         ch->globVolSlideSpeed = tmpEff;
  1997.  
  1998.         if ((tmpEff & 0xF0) == 0)
  1999.         {
  2000.             // unsigned clamp
  2001.             if (song.globVol >= tmpEff)
  2002.                 song.globVol -= tmpEff;
  2003.             else
  2004.                 song.globVol = 0;
  2005.         }
  2006.         else
  2007.         {
  2008.             // unsigned clamp
  2009.             if (song.globVol <= 64-(tmpEff>>4))
  2010.                 song.globVol += tmpEff >> 4;
  2011.             else
  2012.                 song.globVol = 64;
  2013.         }
  2014.  
  2015.         for (i = 0; i < song.antChn; i++) // update all voice volumes
  2016.             stm[i].status |= IS_Vol;
  2017.     }
  2018.  
  2019.     // Kxx - key off
  2020.     else if (ch->effTyp == 20)
  2021.     {
  2022.         if (((song.tempo-song.timer) & 31) == (ch->eff & 0x0F))
  2023.             keyOff(ch);
  2024.     }
  2025.  
  2026.     // Pxy - panning slide
  2027.     else if (ch->effTyp == 25)
  2028.     {
  2029.         tmpEff = ch->eff;
  2030.         if (tmpEff == 0)
  2031.             tmpEff = ch->panningSlideSpeed;
  2032.  
  2033.         ch->panningSlideSpeed = tmpEff;
  2034.  
  2035.         if ((tmpEff & 0xF0) == 0)
  2036.         {
  2037.             // unsigned clamp
  2038.             if (ch->outPan >= tmpEff)
  2039.                 ch->outPan -= tmpEff;
  2040.             else
  2041.                 ch->outPan = 0;
  2042.         }
  2043.         else
  2044.         {
  2045.             tmpEff >>= 4;
  2046.  
  2047.             // unsigned clamp
  2048.             if (ch->outPan <= 255-tmpEff)
  2049.                 ch->outPan += tmpEff;
  2050.             else
  2051.                 ch->outPan = 255;
  2052.         }
  2053.  
  2054.         ch->status |= IS_Pan;
  2055.     }
  2056.  
  2057.     // Rxy - multi note retrig
  2058.     else if (ch->effTyp == 27) multiRetrig(ch);
  2059.  
  2060.     // Txy - tremor
  2061.     else if (ch->effTyp == 29)
  2062.     {
  2063.         tmpEff = ch->eff;
  2064.         if (tmpEff == 0)
  2065.             tmpEff = ch->tremorSave;
  2066.  
  2067.         ch->tremorSave = tmpEff;
  2068.  
  2069.         tremorSign = ch->tremorPos & 0x80;
  2070.         tremorData = ch->tremorPos & 0x7F;
  2071.  
  2072.         tremorData--;
  2073.         if ((tremorData & 0x80) > 0)
  2074.         {
  2075.             if (tremorSign == 0x80)
  2076.             {
  2077.                 tremorSign = 0x00;
  2078.                 tremorData = tmpEff & 0x0F;
  2079.             }
  2080.             else
  2081.             {
  2082.                 tremorSign = 0x80;
  2083.                 tremorData = tmpEff >> 4;
  2084.             }
  2085.         }
  2086.  
  2087.         ch->tremorPos = tremorData | tremorSign;
  2088.  
  2089.         ch->outVol = tremorSign ? ch->realVol : 0;
  2090.         ch->status |= (IS_Vol + IS_QuickVol);
  2091.     }
  2092. }
  2093.  
  2094. static void voiceUpdateVolumes(uint8_t i, uint8_t status)
  2095. {
  2096.     int32_t volL, volR;
  2097.     uint32_t vol;
  2098.     voice_t *v, *f;
  2099.  
  2100.     v = &voice[i];
  2101.  
  2102.     vol = v->SVol; // 0..65535
  2103.  
  2104.     // (0..65535 * 0..65536) >> 4 = 0..268431360
  2105.     volR = (vol * panningTab[    v->SPan]) >> 4;
  2106.     volL = (vol * panningTab[256-v->SPan]) >> 4;
  2107.  
  2108.     if (!volumeRampingFlag)
  2109.     {
  2110.         v->SLVol2 = volL;
  2111.         v->SRVol2 = volR;
  2112.     }
  2113.     else
  2114.     {
  2115.         v->SLVol1 = volL;
  2116.         v->SRVol1 = volR;
  2117.  
  2118.         if (status & IS_NyTon)
  2119.         {
  2120.             // sample is about to start, ramp out/in at the same time
  2121.  
  2122.             // setup "fade out" voice (only if current voice volume>0)
  2123.             if (v->SLVol2 > 0 || v->SRVol2 > 0)
  2124.             {
  2125.                 f = &voice[MAX_VOICES + i];
  2126.                
  2127.                 *f = *v; // copy voice
  2128.  
  2129.                 f->SVolIPLen = quickVolSizeVal;
  2130.                 f->SLVolIP = -f->SLVol2 / f->SVolIPLen;
  2131.                 f->SRVolIP = -f->SRVol2 / f->SVolIPLen;
  2132.  
  2133.                 f->isFadeOutVoice = true;
  2134.             }
  2135.  
  2136.             // make current voice fade in when it starts
  2137.             v->SLVol2 = 0;
  2138.             v->SRVol2 = 0;
  2139.         }
  2140.  
  2141.         // ramp volume changes
  2142.  
  2143.         /* FT2 has two internal volume ramping lengths:
  2144.         ** IS_QuickVol: 5ms (audioFreq / 200)
  2145.         ** Normal: The duration of a tick (speedVal)
  2146.         */
  2147.  
  2148.         if (volL == v->SLVol2 && volR == v->SRVol2)
  2149.         {
  2150.             v->SVolIPLen = 0; // there is no volume change
  2151.         }
  2152.         else
  2153.         {
  2154.             v->SVolIPLen = (status & IS_QuickVol) ? quickVolSizeVal : speedVal;
  2155.             v->SLVolIP = (volL - v->SLVol2) / v->SVolIPLen;
  2156.             v->SRVolIP = (volR - v->SRVol2) / v->SVolIPLen;
  2157.         }
  2158.     }
  2159. }
  2160.  
  2161. static void mix_SaveIPVolumes(void) // for volume ramping
  2162. {
  2163.     voice_t *v = voice;
  2164.     for (int32_t i = 0; i < MAX_VOICES; i++, v++)
  2165.     {
  2166.         v = &voice[i];
  2167.         v->SLVol2 = v->SLVol1;
  2168.         v->SRVol2 = v->SRVol1;
  2169.         v->SVolIPLen = 0;
  2170.     }
  2171. }
  2172.  
  2173. static void voiceTrigger(uint8_t i, sampleTyp *s, int32_t position)
  2174. {
  2175.     bool sampleIs16Bit;
  2176.     uint8_t loopType;
  2177.     int32_t oldSLen, length, loopBegin, loopLength;
  2178.     voice_t *v;
  2179.  
  2180.     v = &voice[i];
  2181.  
  2182.     length = s->len;
  2183.     loopBegin = s->repS;
  2184.     loopLength = s->repL;
  2185.     loopType = s->typ & 3;
  2186.     sampleIs16Bit = (s->typ >> 4) & 1;
  2187.  
  2188.     if (sampleIs16Bit)
  2189.     {
  2190.         length >>= 1;
  2191.         loopBegin >>= 1;
  2192.         loopLength >>= 1;
  2193.     }
  2194.  
  2195.     if (s->pek == NULL || length < 1)
  2196.     {
  2197.         v->mixRoutine = NULL; // shut down voice (illegal parameters)
  2198.         return;
  2199.     }
  2200.  
  2201.     if (loopLength < 1) // disable loop if loopLength is below 1
  2202.         loopType = 0;
  2203.  
  2204.     if (sampleIs16Bit)
  2205.     {
  2206.         v->SBase16 = (const int16_t *)s->pek;
  2207.         v->SRevBase16 = &v->SBase16[loopBegin + (loopBegin + loopLength)]; // for pingpong loops
  2208.     }
  2209.     else
  2210.     {
  2211.         v->SBase8 = s->pek;
  2212.         v->SRevBase8 = &v->SBase8[loopBegin + (loopBegin + loopLength)]; // for pingpong loops
  2213.     }
  2214.  
  2215.     v->backwards = false;
  2216.     v->SLen = (loopType > 0) ? (loopBegin + loopLength) : length;
  2217.     v->SRepS = loopBegin;
  2218.     v->SRepL = loopLength;
  2219.     v->SPos = position;
  2220.     v->SPosDec = 0; // position fraction
  2221.  
  2222.     // if 9xx position overflows, shut down voice
  2223.     oldSLen = (loopType > 0) ? (loopBegin + loopLength) : length;
  2224.     if (v->SPos >= oldSLen)
  2225.     {
  2226.         v->mixRoutine = NULL;
  2227.         return;
  2228.     }
  2229.  
  2230.     v->mixRoutine = mixRoutineTable[(sampleIs16Bit * 12) + (volumeRampingFlag * 6) + (interpolationFlag * 3) + loopType];
  2231. }
  2232.  
  2233. static void mix_UpdateChannelVolPanFrq(void)
  2234. {
  2235.     uint8_t status;
  2236.     uint16_t vol;
  2237.     stmTyp *ch;
  2238.     voice_t *v;
  2239.  
  2240.     for (uint8_t i = 0; i < song.antChn; i++)
  2241.     {
  2242.         ch = &stm[i];
  2243.         v  = &voice[i];
  2244.  
  2245.         status = ch->status;
  2246.         if (status != 0)
  2247.         {
  2248.             ch->status = 0;
  2249.  
  2250.             // volume change
  2251.             if (status & IS_Vol)
  2252.             {
  2253.                 vol = ch->finalVol;
  2254.                 if (vol > 0) // yes, FT2 does this! now it's 0..255 instead
  2255.                     vol--;
  2256.  
  2257.                 v->SVol = vol;
  2258.             }
  2259.  
  2260.             // panning change
  2261.             if (status & IS_Pan)
  2262.                 v->SPan = ch->finalPan;
  2263.  
  2264.             // update mixing volumes if vol/pan change
  2265.             if (status & (IS_Vol + IS_Pan))
  2266.                 voiceUpdateVolumes(i, status);
  2267.  
  2268.             // frequency change
  2269.             if (status & IS_Period)
  2270.             {
  2271.                 v->SFrq = getFrequenceValue(ch->finalPeriod);
  2272.  
  2273.                 if (v->SFrq != oldSFrq)
  2274.                 {
  2275.                     oldSFrq = v->SFrq;
  2276.  
  2277.                     oldSFrqRev = 0xFFFFFFFF;
  2278.                     if (oldSFrq != 0)
  2279.                         oldSFrqRev /= oldSFrq;
  2280.                 }
  2281.  
  2282.                 v->SFrqRev = oldSFrqRev;
  2283.             }
  2284.  
  2285.             // sample trigger (note)
  2286.             if (status & IS_NyTon)
  2287.                 voiceTrigger(i, ch->smpPtr, ch->smpStartPos);
  2288.         }
  2289.     }
  2290. }
  2291.  
  2292. /* ----------------------------------------------------------------------- */
  2293. /*                          GENERAL MIXER MACROS                           */
  2294. /* ----------------------------------------------------------------------- */
  2295.  
  2296. #define GET_VOL \
  2297.     CDA_LVol = v->SLVol2; \
  2298.     CDA_RVol = v->SRVol2; \
  2299.  
  2300. #define SET_VOL_BACK \
  2301.     v->SLVol2 = CDA_LVol; \
  2302.     v->SRVol2 = CDA_RVol; \
  2303.  
  2304. #define GET_DELTA delta = v->SFrq;
  2305.  
  2306. #define GET_MIXER_VARS \
  2307.     audioMixL = mixBufferL; \
  2308.     audioMixR = mixBufferR; \
  2309.     mixInMono = (CDA_LVol == CDA_RVol); \
  2310.     realPos = v->SPos; \
  2311.     pos = v->SPosDec; \
  2312.  
  2313. #define GET_MIXER_VARS_RAMP \
  2314.     audioMixL = mixBufferL; \
  2315.     audioMixR = mixBufferR; \
  2316.     CDA_LVolIP = v->SLVolIP; \
  2317.     CDA_RVolIP = v->SRVolIP; \
  2318.     mixInMono = (v->SLVol2 == v->SRVol2) && (CDA_LVolIP == CDA_RVolIP); \
  2319.     realPos = v->SPos; \
  2320.     pos = v->SPosDec; \
  2321.  
  2322. #define SET_BASE8 \
  2323.     CDA_LinearAdr = v->SBase8; \
  2324.     smpPtr = CDA_LinearAdr + realPos; \
  2325.  
  2326. #define SET_BASE16 \
  2327.     CDA_LinearAdr = v->SBase16; \
  2328.     smpPtr = CDA_LinearAdr + realPos; \
  2329.  
  2330. #define SET_BASE8_BIDI \
  2331.     CDA_LinearAdr = v->SBase8; \
  2332.     CDA_LinAdrRev = v->SRevBase8; \
  2333.  
  2334. #define SET_BASE16_BIDI \
  2335.     CDA_LinearAdr = v->SBase16; \
  2336.     CDA_LinAdrRev = v->SRevBase16; \
  2337.  
  2338. #define INC_POS \
  2339.     pos += delta; \
  2340.     smpPtr += pos >> 16; \
  2341.     pos &= 0xFFFF; \
  2342.  
  2343. #define INC_POS_BIDI \
  2344.     pos += CDA_IPValL; \
  2345.     smpPtr += pos >> 16; \
  2346.     smpPtr += CDA_IPValH; \
  2347.     pos &= 0xFFFF; \
  2348.  
  2349. #define SET_BACK_MIXER_POS \
  2350.     v->SPosDec = pos; \
  2351.     v->SPos = realPos; \
  2352.  
  2353. /* ----------------------------------------------------------------------- */
  2354. /*                          SAMPLE RENDERING MACROS                        */
  2355. /* ----------------------------------------------------------------------- */
  2356.  
  2357. #define VOLUME_RAMPING \
  2358.     CDA_LVol += CDA_LVolIP; \
  2359.     CDA_RVol += CDA_RVolIP; \
  2360.  
  2361. // all the 64-bit MULs here convert to fast logic on most 32-bit CPUs
  2362.  
  2363. #define RENDER_8BIT_SMP \
  2364.     sample = *smpPtr << 20; \
  2365.     *audioMixL++ += ((int64_t)sample * CDA_LVol) >> 32; \
  2366.     *audioMixR++ += ((int64_t)sample * CDA_RVol) >> 32; \
  2367.  
  2368. #define RENDER_8BIT_SMP_MONO \
  2369.     sample = *smpPtr << 20; \
  2370.     sample = ((int64_t)sample * CDA_LVol) >> 32; \
  2371.     *audioMixL++ += sample; \
  2372.     *audioMixR++ += sample; \
  2373.  
  2374. #define RENDER_16BIT_SMP \
  2375.     sample = *smpPtr << 12; \
  2376.     *audioMixL++ += ((int64_t)sample * CDA_LVol) >> 32; \
  2377.     *audioMixR++ += ((int64_t)sample * CDA_RVol) >> 32; \
  2378.  
  2379. #define RENDER_16BIT_SMP_MONO \
  2380.     sample = *smpPtr << 12; \
  2381.     sample = ((int64_t)sample * CDA_LVol) >> 32; \
  2382.     *audioMixL++ += sample; \
  2383.     *audioMixR++ += sample; \
  2384.  
  2385. // 3-tap quadratic interpolation (default - slower, but better quality)
  2386.  
  2387. // in: int32_t s1,s2,s3 = -128..127 | f = 0..65535 (frac) | out: s1 (will exceed 16-bits because of overshoot)
  2388. #define INTERPOLATE8(s1, s2, s3, f) \
  2389. { \
  2390.     int32_t s4, frac = f >> 1; \
  2391.     \
  2392.     s2 <<= 8; \
  2393.     s4 = ((s1 + s3) << (8 - 1)) - s2; \
  2394.     s4 = ((s4 * frac) >> 16) + s2; \
  2395.     s3 = (s1 + s3) << (8 - 1); \
  2396.     s1 <<= 8; \
  2397.     s3 = (s1 + s3) >> 1; \
  2398.     s1 += ((s4 - s3) * frac) >> 14; \
  2399. } \
  2400.  
  2401. // in: int32_t s1,s2,s3 = -32768..32767 | f = 0..65535 (frac) | out: s1 (will exceed 16-bits because of overshoot)
  2402. #define INTERPOLATE16(s1, s2, s3, f) \
  2403. { \
  2404.     int32_t s4, frac = f >> 1; \
  2405.     \
  2406.     s4 = ((s1 + s3) >> 1) - s2; \
  2407.     s4 = ((s4 * frac) >> 16) + s2; \
  2408.     s3 = (s1 + s3) >> 1; \
  2409.     s3 = (s1 + s3) >> 1; \
  2410.     s1 += ((s4 - s3) * frac) >> 14; \
  2411. } \
  2412.  
  2413. #define RENDER_8BIT_SMP_INTRP \
  2414.     sample = smpPtr[0]; \
  2415.     sample2 = smpPtr[1]; \
  2416.     sample3 = smpPtr[2]; \
  2417.     INTERPOLATE8(sample, sample2, sample3, pos) \
  2418.     sample <<= 12; \
  2419.     *audioMixL++ += ((int64_t)sample * CDA_LVol) >> 32; \
  2420.     *audioMixR++ += ((int64_t)sample * CDA_RVol) >> 32; \
  2421.  
  2422. #define RENDER_8BIT_SMP_MONO_INTRP \
  2423.     sample = smpPtr[0]; \
  2424.     sample2 = smpPtr[1]; \
  2425.     sample3 = smpPtr[2]; \
  2426.     INTERPOLATE8(sample, sample2, sample3, pos) \
  2427.     sample <<= 12; \
  2428.     sample = ((int64_t)sample * CDA_LVol) >> 32; \
  2429.     *audioMixL++ += sample; \
  2430.     *audioMixR++ += sample; \
  2431.  
  2432. #define RENDER_16BIT_SMP_INTRP \
  2433.     sample = smpPtr[0]; \
  2434.     sample2 = smpPtr[1]; \
  2435.     sample3 = smpPtr[2]; \
  2436.     INTERPOLATE16(sample, sample2, sample3, pos) \
  2437.     sample <<= 12; \
  2438.     *audioMixL++ += ((int64_t)sample * CDA_LVol) >> 32; \
  2439.     *audioMixR++ += ((int64_t)sample * CDA_RVol) >> 32; \
  2440.  
  2441. #define RENDER_16BIT_SMP_MONO_INTRP \
  2442.     sample = smpPtr[0]; \
  2443.     sample2 = smpPtr[1]; \
  2444.     sample3 = smpPtr[2]; \
  2445.     INTERPOLATE16(sample, sample2, sample3, pos) \
  2446.     sample <<= 12; \
  2447.     sample = ((int64_t)sample * CDA_LVol) >> 32; \
  2448.     *audioMixL++ += sample; \
  2449.     *audioMixR++ += sample; \
  2450.  
  2451. /* ----------------------------------------------------------------------- */
  2452. /*                      SAMPLES-TO-MIX LIMITING MACROS                     */
  2453. /* ----------------------------------------------------------------------- */
  2454.  
  2455. #define LIMIT_MIX_NUM \
  2456.     i = (v->SLen - 1) - realPos; \
  2457.     if (i > 65535) \
  2458.         i = 65535; \
  2459.     \
  2460.     samplesToMix = (((((uint64_t)i << 16) | (pos ^ 0xFFFF)) * v->SFrqRev) >> 32) + 1; \
  2461.     if (samplesToMix > (uint32_t)CDA_BytesLeft) \
  2462.         samplesToMix = CDA_BytesLeft; \
  2463.  
  2464. #define LIMIT_MIX_NUM_RAMP \
  2465.     if (v->SVolIPLen == 0) \
  2466.     { \
  2467.         CDA_LVolIP = 0; \
  2468.         CDA_RVolIP = 0; \
  2469.         \
  2470.         if (v->isFadeOutVoice) \
  2471.         { \
  2472.             v->mixRoutine = NULL; /* fade out voice is done, shut it down */ \
  2473.             return; \
  2474.         } \
  2475.     } \
  2476.     else \
  2477.     { \
  2478.         if (samplesToMix > (uint32_t)v->SVolIPLen) \
  2479.             samplesToMix = v->SVolIPLen; \
  2480.         \
  2481.         v->SVolIPLen -= samplesToMix; \
  2482.     } \
  2483.  
  2484. #define START_BIDI \
  2485.     if (v->backwards) \
  2486.     { \
  2487.         delta = 0 - v->SFrq; \
  2488.         CDA_IPValH = (int32_t)delta >> 16; \
  2489.         realPos = ~realPos; \
  2490.         smpPtr = CDA_LinAdrRev + realPos; \
  2491.         pos ^= 0xFFFF; \
  2492.     } \
  2493.     else \
  2494.     { \
  2495.         delta = v->SFrq; \
  2496.         CDA_IPValH = delta >> 16; \
  2497.         smpPtr = CDA_LinearAdr + realPos; \
  2498.     } \
  2499.     \
  2500.     CDA_IPValL = delta & 0xFFFF; \
  2501.  
  2502. #define END_BIDI \
  2503.     if (v->backwards) \
  2504.     { \
  2505.         pos ^= 0xFFFF; \
  2506.         realPos = (int32_t)(smpPtr - CDA_LinAdrRev); \
  2507.         realPos = ~realPos; \
  2508.     } \
  2509.     else \
  2510.     { \
  2511.         realPos = (int32_t)(smpPtr - CDA_LinearAdr); \
  2512.     } \
  2513.     \
  2514.  
  2515. /* ----------------------------------------------------------------------- */
  2516. /*                     SAMPLE END/LOOP WRAPPING MACROS                     */
  2517. /* ----------------------------------------------------------------------- */
  2518.  
  2519. #define HANDLE_SAMPLE_END \
  2520.     realPos = (int32_t)(smpPtr - CDA_LinearAdr); \
  2521.     if (realPos >= v->SLen) \
  2522.     { \
  2523.         v->mixRoutine = NULL; \
  2524.         return; \
  2525.     } \
  2526.  
  2527. #define WRAP_LOOP \
  2528.     realPos = (int32_t)(smpPtr - CDA_LinearAdr); \
  2529.     while (realPos >= v->SLen) \
  2530.         realPos -= v->SRepL; \
  2531.     smpPtr = CDA_LinearAdr + realPos; \
  2532.  
  2533. #define WRAP_BIDI_LOOP \
  2534.     while (realPos >= v->SLen) \
  2535.     { \
  2536.         realPos -= v->SRepL; \
  2537.         v->backwards ^= 1; \
  2538.     } \
  2539.  
  2540. /* ----------------------------------------------------------------------- */
  2541. /*                       VOLUME=0 OPTIMIZATION MACROS                      */
  2542. /* ----------------------------------------------------------------------- */
  2543.  
  2544. #define VOL0_OPTIMIZATION_NO_LOOP \
  2545.     pos = v->SPosDec + ((v->SFrq & 0xFFFF) * numSamples); \
  2546.     realPos = v->SPos + ((v->SFrq >> 16) * numSamples) + (pos >> 16); \
  2547.     \
  2548.     if (realPos >= v->SLen) \
  2549.     { \
  2550.         v->mixRoutine = NULL; /* shut down voice */ \
  2551.         return; \
  2552.     } \
  2553.     \
  2554.     pos &= 0xFFFF; \
  2555.     SET_BACK_MIXER_POS
  2556.  
  2557. #define VOL0_OPTIMIZATION_LOOP \
  2558.     pos  = v->SPosDec + ((v->SFrq & 0xFFFF) * numSamples); \
  2559.     realPos = v->SPos + ((v->SFrq >> 16) * numSamples) + (pos >> 16); \
  2560.     \
  2561.     while (realPos >= v->SLen) \
  2562.         realPos -= v->SRepL; \
  2563.     \
  2564.     pos &= 0xFFFF; \
  2565.     SET_BACK_MIXER_POS
  2566.  
  2567. #define VOL0_OPTIMIZATION_BIDI_LOOP \
  2568.     pos = v->SPosDec + ((v->SFrq & 0xFFFF) * numSamples); \
  2569.     realPos = v->SPos + ((v->SFrq >> 16) * numSamples) + (pos >> 16); \
  2570.     \
  2571.     while (realPos >= v->SLen) \
  2572.     { \
  2573.         realPos -= v->SRepL; \
  2574.         v->backwards ^= 1; \
  2575.     } \
  2576.     \
  2577.     pos &= 0xFFFF; \
  2578.     SET_BACK_MIXER_POS
  2579.  
  2580. /* ----------------------------------------------------------------------- */
  2581. /*                          8-BIT MIXING ROUTINES                          */
  2582. /* ----------------------------------------------------------------------- */
  2583.  
  2584. static void mix8bNoLoop(voice_t *v, uint32_t numSamples)
  2585. {
  2586.     const int8_t *CDA_LinearAdr;
  2587.     bool mixInMono;
  2588.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
  2589.     register const int8_t *smpPtr;
  2590.     register int32_t CDA_LVol, CDA_RVol;
  2591.     register uint32_t pos, delta;
  2592.     uint32_t i, samplesToMix;
  2593.  
  2594.     GET_VOL
  2595.  
  2596.     if ((CDA_LVol | CDA_RVol) == 0)
  2597.     {
  2598.         VOL0_OPTIMIZATION_NO_LOOP
  2599.         return;
  2600.     }
  2601.  
  2602.     GET_MIXER_VARS
  2603.     GET_DELTA
  2604.     SET_BASE8
  2605.  
  2606.     CDA_BytesLeft = numSamples;
  2607.     while (CDA_BytesLeft > 0)
  2608.     {
  2609.         LIMIT_MIX_NUM
  2610.         CDA_BytesLeft -= samplesToMix;
  2611.  
  2612.         if (mixInMono)
  2613.         {
  2614.             if (samplesToMix & 1)
  2615.             {
  2616.                 RENDER_8BIT_SMP_MONO
  2617.                 INC_POS
  2618.             }
  2619.             samplesToMix >>= 1;
  2620.             for (i = 0; i < samplesToMix; i++)
  2621.             {
  2622.                 RENDER_8BIT_SMP_MONO
  2623.                 INC_POS
  2624.                 RENDER_8BIT_SMP_MONO
  2625.                 INC_POS
  2626.             }
  2627.         }
  2628.         else
  2629.         {
  2630.             if (samplesToMix & 1)
  2631.             {
  2632.                 RENDER_8BIT_SMP
  2633.                 INC_POS
  2634.             }
  2635.             samplesToMix >>= 1;
  2636.             for (i = 0; i < samplesToMix; i++)
  2637.             {
  2638.                 RENDER_8BIT_SMP
  2639.                 INC_POS
  2640.                 RENDER_8BIT_SMP
  2641.                 INC_POS
  2642.             }
  2643.         }
  2644.  
  2645.         HANDLE_SAMPLE_END
  2646.     }
  2647.  
  2648.     SET_BACK_MIXER_POS
  2649. }
  2650.  
  2651. static void mix8bLoop(voice_t *v, uint32_t numSamples)
  2652. {
  2653.     const int8_t *CDA_LinearAdr;
  2654.     bool mixInMono;
  2655.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
  2656.     register const int8_t *smpPtr;
  2657.     register int32_t CDA_LVol, CDA_RVol;
  2658.     register uint32_t pos, delta;
  2659.     uint32_t i, samplesToMix;
  2660.  
  2661.     GET_VOL
  2662.  
  2663.     if ((CDA_LVol | CDA_RVol) == 0)
  2664.     {
  2665.         VOL0_OPTIMIZATION_LOOP
  2666.         return;
  2667.     }
  2668.  
  2669.     GET_MIXER_VARS
  2670.     GET_DELTA
  2671.     SET_BASE8
  2672.  
  2673.     CDA_BytesLeft = numSamples;
  2674.     while (CDA_BytesLeft > 0)
  2675.     {
  2676.         LIMIT_MIX_NUM
  2677.         CDA_BytesLeft -= samplesToMix;
  2678.  
  2679.         if (mixInMono)
  2680.         {
  2681.             if (samplesToMix & 1)
  2682.             {
  2683.                 RENDER_8BIT_SMP_MONO
  2684.                 INC_POS
  2685.             }
  2686.             samplesToMix >>= 1;
  2687.             for (i = 0; i < samplesToMix; i++)
  2688.             {
  2689.                 RENDER_8BIT_SMP_MONO
  2690.                 INC_POS
  2691.                 RENDER_8BIT_SMP_MONO
  2692.                 INC_POS
  2693.             }
  2694.         }
  2695.         else
  2696.         {
  2697.             if (samplesToMix & 1)
  2698.             {
  2699.                 RENDER_8BIT_SMP
  2700.                 INC_POS
  2701.             }
  2702.             samplesToMix >>= 1;
  2703.             for (i = 0; i < samplesToMix; i++)
  2704.             {
  2705.                 RENDER_8BIT_SMP
  2706.                 INC_POS
  2707.                 RENDER_8BIT_SMP
  2708.                 INC_POS
  2709.             }
  2710.         }
  2711.  
  2712.         WRAP_LOOP
  2713.     }
  2714.  
  2715.     SET_BACK_MIXER_POS
  2716. }
  2717.  
  2718. static void mix8bBidiLoop(voice_t *v, uint32_t numSamples)
  2719. {
  2720.     bool mixInMono;
  2721.     const int8_t *CDA_LinearAdr, *CDA_LinAdrRev;
  2722.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
  2723.     register const int8_t *smpPtr;
  2724.     register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
  2725.     register uint32_t pos;
  2726.     uint32_t delta, i, samplesToMix;
  2727.  
  2728.     GET_VOL
  2729.  
  2730.     if ((CDA_LVol | CDA_RVol) == 0)
  2731.     {
  2732.         VOL0_OPTIMIZATION_BIDI_LOOP
  2733.         return;
  2734.     }
  2735.  
  2736.     GET_MIXER_VARS
  2737.     SET_BASE8_BIDI
  2738.  
  2739.     CDA_BytesLeft = numSamples;
  2740.     while (CDA_BytesLeft > 0)
  2741.     {
  2742.         LIMIT_MIX_NUM
  2743.         CDA_BytesLeft -= samplesToMix;
  2744.  
  2745.         START_BIDI
  2746.         if (mixInMono)
  2747.         {
  2748.             if (samplesToMix & 1)
  2749.             {
  2750.                 RENDER_8BIT_SMP_MONO
  2751.                 INC_POS_BIDI
  2752.             }
  2753.             samplesToMix >>= 1;
  2754.             for (i = 0; i < samplesToMix; i++)
  2755.             {
  2756.                 RENDER_8BIT_SMP_MONO
  2757.                 INC_POS_BIDI
  2758.                 RENDER_8BIT_SMP_MONO
  2759.                 INC_POS_BIDI
  2760.             }
  2761.         }
  2762.         else
  2763.         {
  2764.             if (samplesToMix & 1)
  2765.             {
  2766.                 RENDER_8BIT_SMP
  2767.                 INC_POS_BIDI
  2768.             }
  2769.             samplesToMix >>= 1;
  2770.             for (i = 0; i < samplesToMix; i++)
  2771.             {
  2772.                 RENDER_8BIT_SMP
  2773.                 INC_POS_BIDI
  2774.                 RENDER_8BIT_SMP
  2775.                 INC_POS_BIDI
  2776.             }
  2777.         }
  2778.         END_BIDI
  2779.  
  2780.         WRAP_BIDI_LOOP
  2781.     }
  2782.     SET_BACK_MIXER_POS
  2783. }
  2784.  
  2785. static void mix8bNoLoopIntrp(voice_t *v, uint32_t numSamples)
  2786. {
  2787.     const int8_t *CDA_LinearAdr;
  2788.     bool mixInMono;
  2789.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft;
  2790.     register const int8_t *smpPtr;
  2791.     register int32_t CDA_LVol, CDA_RVol;
  2792.     register uint32_t pos, delta;
  2793.     uint32_t i, samplesToMix;
  2794.  
  2795.     GET_VOL
  2796.  
  2797.     if ((CDA_LVol | CDA_RVol) == 0)
  2798.     {
  2799.         VOL0_OPTIMIZATION_NO_LOOP
  2800.         return;
  2801.     }
  2802.  
  2803.     GET_MIXER_VARS
  2804.     GET_DELTA
  2805.     SET_BASE8
  2806.  
  2807.     CDA_BytesLeft = numSamples;
  2808.     while (CDA_BytesLeft > 0)
  2809.     {
  2810.         LIMIT_MIX_NUM
  2811.         CDA_BytesLeft -= samplesToMix;
  2812.  
  2813.         if (mixInMono)
  2814.         {
  2815.             if (samplesToMix & 1)
  2816.             {
  2817.                 RENDER_8BIT_SMP_MONO_INTRP
  2818.                 INC_POS
  2819.             }
  2820.             samplesToMix >>= 1;
  2821.             for (i = 0; i < samplesToMix; i++)
  2822.             {
  2823.                 RENDER_8BIT_SMP_MONO_INTRP
  2824.                 INC_POS
  2825.                 RENDER_8BIT_SMP_MONO_INTRP
  2826.                 INC_POS
  2827.             }
  2828.         }
  2829.         else
  2830.         {
  2831.             if (samplesToMix & 1)
  2832.             {
  2833.                 RENDER_8BIT_SMP_INTRP
  2834.                 INC_POS
  2835.             }
  2836.             samplesToMix >>= 1;
  2837.             for (i = 0; i < samplesToMix; i++)
  2838.             {
  2839.                 RENDER_8BIT_SMP_INTRP
  2840.                 INC_POS
  2841.                 RENDER_8BIT_SMP_INTRP
  2842.                 INC_POS
  2843.             }
  2844.         }
  2845.  
  2846.         HANDLE_SAMPLE_END
  2847.     }
  2848.  
  2849.     SET_BACK_MIXER_POS
  2850. }
  2851.  
  2852. static void mix8bLoopIntrp(voice_t *v, uint32_t numSamples)
  2853. {
  2854.     const int8_t *CDA_LinearAdr;
  2855.     bool mixInMono;
  2856.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft;
  2857.     register const int8_t *smpPtr;
  2858.     register int32_t CDA_LVol, CDA_RVol;
  2859.     register uint32_t pos, delta;
  2860.     uint32_t i, samplesToMix;
  2861.  
  2862.     GET_VOL
  2863.  
  2864.     if ((CDA_LVol | CDA_RVol) == 0)
  2865.     {
  2866.         VOL0_OPTIMIZATION_LOOP
  2867.         return;
  2868.     }
  2869.  
  2870.     GET_MIXER_VARS
  2871.     GET_DELTA
  2872.     SET_BASE8
  2873.  
  2874.     CDA_BytesLeft = numSamples;
  2875.     while (CDA_BytesLeft > 0)
  2876.     {
  2877.         LIMIT_MIX_NUM
  2878.         CDA_BytesLeft -= samplesToMix;
  2879.  
  2880.         if (mixInMono)
  2881.         {
  2882.             if (samplesToMix & 1)
  2883.             {
  2884.                 RENDER_8BIT_SMP_MONO_INTRP
  2885.                 INC_POS
  2886.             }
  2887.             samplesToMix >>= 1;
  2888.             for (i = 0; i < samplesToMix; i++)
  2889.             {
  2890.                 RENDER_8BIT_SMP_MONO_INTRP
  2891.                 INC_POS
  2892.                 RENDER_8BIT_SMP_MONO_INTRP
  2893.                 INC_POS
  2894.             }
  2895.         }
  2896.         else
  2897.         {
  2898.             if (samplesToMix & 1)
  2899.             {
  2900.                 RENDER_8BIT_SMP_INTRP
  2901.                 INC_POS
  2902.             }
  2903.             samplesToMix >>= 1;
  2904.             for (i = 0; i < samplesToMix; i++)
  2905.             {
  2906.                 RENDER_8BIT_SMP_INTRP
  2907.                 INC_POS
  2908.                 RENDER_8BIT_SMP_INTRP
  2909.                 INC_POS
  2910.             }
  2911.         }
  2912.  
  2913.         WRAP_LOOP
  2914.     }
  2915.  
  2916.     SET_BACK_MIXER_POS
  2917. }
  2918.  
  2919. static void mix8bBidiLoopIntrp(voice_t *v, uint32_t numSamples)
  2920. {
  2921.     bool mixInMono;
  2922.     const int8_t *CDA_LinearAdr, *CDA_LinAdrRev;
  2923.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft;
  2924.     register const int8_t *smpPtr;
  2925.     register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
  2926.     register uint32_t pos;
  2927.     uint32_t delta, i, samplesToMix;
  2928.  
  2929.     GET_VOL
  2930.  
  2931.     if ((CDA_LVol | CDA_RVol) == 0)
  2932.     {
  2933.         VOL0_OPTIMIZATION_BIDI_LOOP
  2934.         return;
  2935.     }
  2936.  
  2937.     GET_MIXER_VARS
  2938.     SET_BASE8_BIDI
  2939.  
  2940.     CDA_BytesLeft = numSamples;
  2941.     while (CDA_BytesLeft > 0)
  2942.     {
  2943.         LIMIT_MIX_NUM
  2944.         CDA_BytesLeft -= samplesToMix;
  2945.  
  2946.         START_BIDI
  2947.         if (mixInMono)
  2948.         {
  2949.             if (samplesToMix & 1)
  2950.             {
  2951.                 RENDER_8BIT_SMP_MONO_INTRP
  2952.                 INC_POS_BIDI
  2953.             }
  2954.             samplesToMix >>= 1;
  2955.             for (i = 0; i < samplesToMix; i++)
  2956.             {
  2957.                 RENDER_8BIT_SMP_MONO_INTRP
  2958.                 INC_POS_BIDI
  2959.                 RENDER_8BIT_SMP_MONO_INTRP
  2960.                 INC_POS_BIDI
  2961.             }
  2962.         }
  2963.         else
  2964.         {
  2965.             if (samplesToMix & 1)
  2966.             {
  2967.                 RENDER_8BIT_SMP_INTRP
  2968.                 INC_POS_BIDI
  2969.             }
  2970.             samplesToMix >>= 1;
  2971.             for (i = 0; i < samplesToMix; i++)
  2972.             {
  2973.                 RENDER_8BIT_SMP_INTRP
  2974.                 INC_POS_BIDI
  2975.                 RENDER_8BIT_SMP_INTRP
  2976.                 INC_POS_BIDI
  2977.             }
  2978.         }
  2979.         END_BIDI
  2980.  
  2981.         WRAP_BIDI_LOOP
  2982.     }
  2983.  
  2984.     SET_BACK_MIXER_POS
  2985. }
  2986.  
  2987. static void mix8bRampNoLoop(voice_t *v, uint32_t numSamples)
  2988. {
  2989.     const int8_t *CDA_LinearAdr;
  2990.     bool mixInMono;
  2991.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  2992.     register const int8_t *smpPtr;
  2993.     register int32_t CDA_LVol, CDA_RVol;
  2994.     register uint32_t pos, delta;
  2995.     uint32_t i, samplesToMix;
  2996.  
  2997.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  2998.     {
  2999.         VOL0_OPTIMIZATION_NO_LOOP
  3000.         return;
  3001.     }
  3002.  
  3003.     GET_MIXER_VARS_RAMP
  3004.     GET_DELTA
  3005.     SET_BASE8
  3006.  
  3007.     CDA_BytesLeft = numSamples;
  3008.     while (CDA_BytesLeft > 0)
  3009.     {
  3010.         LIMIT_MIX_NUM
  3011.         LIMIT_MIX_NUM_RAMP
  3012.         CDA_BytesLeft -= samplesToMix;
  3013.  
  3014.         GET_VOL
  3015.         if (mixInMono)
  3016.         {
  3017.             if (samplesToMix & 1)
  3018.             {
  3019.                 RENDER_8BIT_SMP_MONO
  3020.                 VOLUME_RAMPING
  3021.                 INC_POS
  3022.             }
  3023.             samplesToMix >>= 1;
  3024.             for (i = 0; i < samplesToMix; i++)
  3025.             {
  3026.                 RENDER_8BIT_SMP_MONO
  3027.                 VOLUME_RAMPING
  3028.                 INC_POS
  3029.                 RENDER_8BIT_SMP_MONO
  3030.                 VOLUME_RAMPING
  3031.                 INC_POS
  3032.             }
  3033.         }
  3034.         else
  3035.         {
  3036.             if (samplesToMix & 1)
  3037.             {
  3038.                 RENDER_8BIT_SMP
  3039.                 VOLUME_RAMPING
  3040.                 INC_POS
  3041.             }
  3042.             samplesToMix >>= 1;
  3043.             for (i = 0; i < samplesToMix; i++)
  3044.             {
  3045.                 RENDER_8BIT_SMP
  3046.                 VOLUME_RAMPING
  3047.                 INC_POS
  3048.                 RENDER_8BIT_SMP
  3049.                 VOLUME_RAMPING
  3050.                 INC_POS
  3051.             }
  3052.         }
  3053.         SET_VOL_BACK
  3054.  
  3055.         HANDLE_SAMPLE_END
  3056.     }
  3057.  
  3058.     SET_BACK_MIXER_POS
  3059. }
  3060.  
  3061. static void mix8bRampLoop(voice_t *v, uint32_t numSamples)
  3062. {
  3063.     const int8_t *CDA_LinearAdr;
  3064.     bool mixInMono;
  3065.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  3066.     register const int8_t *smpPtr;
  3067.     register int32_t CDA_LVol, CDA_RVol;
  3068.     register uint32_t pos, delta;
  3069.     uint32_t i, samplesToMix;
  3070.  
  3071.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  3072.     {
  3073.         VOL0_OPTIMIZATION_LOOP
  3074.         return;
  3075.     }
  3076.  
  3077.     GET_MIXER_VARS_RAMP
  3078.     GET_DELTA
  3079.     SET_BASE8
  3080.  
  3081.     CDA_BytesLeft = numSamples;
  3082.     while (CDA_BytesLeft > 0)
  3083.     {
  3084.         LIMIT_MIX_NUM
  3085.         LIMIT_MIX_NUM_RAMP
  3086.         CDA_BytesLeft -= samplesToMix;
  3087.  
  3088.         GET_VOL
  3089.         if (mixInMono)
  3090.         {
  3091.             if (samplesToMix & 1)
  3092.             {
  3093.                 RENDER_8BIT_SMP
  3094.                 VOLUME_RAMPING
  3095.                 INC_POS
  3096.             }
  3097.             samplesToMix >>= 1;
  3098.             for (i = 0; i < samplesToMix; i++)
  3099.             {
  3100.                 RENDER_8BIT_SMP_MONO
  3101.                 VOLUME_RAMPING
  3102.                 INC_POS
  3103.                 RENDER_8BIT_SMP_MONO
  3104.                 VOLUME_RAMPING
  3105.                 INC_POS
  3106.             }
  3107.         }
  3108.         else
  3109.         {
  3110.             if (samplesToMix & 1)
  3111.             {
  3112.                 RENDER_8BIT_SMP
  3113.                 VOLUME_RAMPING
  3114.                 INC_POS
  3115.             }
  3116.             samplesToMix >>= 1;
  3117.             for (i = 0; i < samplesToMix; i++)
  3118.             {
  3119.                 RENDER_8BIT_SMP
  3120.                 VOLUME_RAMPING
  3121.                 INC_POS
  3122.                 RENDER_8BIT_SMP
  3123.                 VOLUME_RAMPING
  3124.                 INC_POS
  3125.             }
  3126.         }
  3127.         SET_VOL_BACK
  3128.  
  3129.         WRAP_LOOP
  3130.     }
  3131.  
  3132.     SET_BACK_MIXER_POS
  3133. }
  3134.  
  3135. static void mix8bRampBidiLoop(voice_t *v, uint32_t numSamples)
  3136. {
  3137.     bool mixInMono;
  3138.     const int8_t *CDA_LinearAdr, *CDA_LinAdrRev;
  3139.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  3140.     register const int8_t *smpPtr;
  3141.     register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
  3142.     register uint32_t pos;
  3143.     uint32_t delta, i, samplesToMix;
  3144.  
  3145.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  3146.     {
  3147.         VOL0_OPTIMIZATION_BIDI_LOOP
  3148.         return;
  3149.     }
  3150.  
  3151.     GET_MIXER_VARS_RAMP
  3152.     SET_BASE8_BIDI
  3153.  
  3154.     CDA_BytesLeft = numSamples;
  3155.     while (CDA_BytesLeft > 0)
  3156.     {
  3157.         LIMIT_MIX_NUM
  3158.         LIMIT_MIX_NUM_RAMP
  3159.         CDA_BytesLeft -= samplesToMix;
  3160.  
  3161.         GET_VOL
  3162.         START_BIDI
  3163.         if (mixInMono)
  3164.         {
  3165.             if (samplesToMix & 1)
  3166.             {
  3167.                 RENDER_8BIT_SMP_MONO
  3168.                 VOLUME_RAMPING
  3169.                 INC_POS_BIDI
  3170.             }
  3171.             samplesToMix >>= 1;
  3172.             for (i = 0; i < samplesToMix; i++)
  3173.             {
  3174.                 RENDER_8BIT_SMP_MONO
  3175.                 VOLUME_RAMPING
  3176.                 INC_POS_BIDI
  3177.                 RENDER_8BIT_SMP_MONO
  3178.                 VOLUME_RAMPING
  3179.                 INC_POS_BIDI
  3180.             }
  3181.         }
  3182.         else
  3183.         {
  3184.             if (samplesToMix & 1)
  3185.             {
  3186.                 RENDER_8BIT_SMP
  3187.                 VOLUME_RAMPING
  3188.                 INC_POS_BIDI
  3189.             }
  3190.             samplesToMix >>= 1;
  3191.             for (i = 0; i < samplesToMix; i++)
  3192.             {
  3193.                 RENDER_8BIT_SMP
  3194.                 VOLUME_RAMPING
  3195.                 INC_POS_BIDI
  3196.                 RENDER_8BIT_SMP
  3197.                 VOLUME_RAMPING
  3198.                 INC_POS_BIDI
  3199.             }
  3200.         }
  3201.         END_BIDI
  3202.         SET_VOL_BACK
  3203.  
  3204.         WRAP_BIDI_LOOP
  3205.     }
  3206.  
  3207.     SET_BACK_MIXER_POS
  3208. }
  3209.  
  3210. static void mix8bRampNoLoopIntrp(voice_t *v, uint32_t numSamples)
  3211. {
  3212.     const int8_t *CDA_LinearAdr;
  3213.     bool mixInMono;
  3214.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  3215.     register const int8_t *smpPtr;
  3216.     register int32_t CDA_LVol, CDA_RVol;
  3217.     register uint32_t pos, delta;
  3218.     uint32_t i, samplesToMix;
  3219.  
  3220.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  3221.     {
  3222.         VOL0_OPTIMIZATION_NO_LOOP
  3223.         return;
  3224.     }
  3225.  
  3226.     GET_MIXER_VARS_RAMP
  3227.     GET_DELTA
  3228.     SET_BASE8
  3229.  
  3230.     CDA_BytesLeft = numSamples;
  3231.     while (CDA_BytesLeft > 0)
  3232.     {
  3233.         LIMIT_MIX_NUM
  3234.         LIMIT_MIX_NUM_RAMP
  3235.         CDA_BytesLeft -= samplesToMix;
  3236.  
  3237.         GET_VOL
  3238.         if (mixInMono)
  3239.         {
  3240.             if (samplesToMix & 1)
  3241.             {
  3242.                 RENDER_8BIT_SMP_MONO_INTRP
  3243.                 VOLUME_RAMPING
  3244.                 INC_POS
  3245.             }
  3246.             samplesToMix >>= 1;
  3247.             for (i = 0; i < samplesToMix; i++)
  3248.             {
  3249.                 RENDER_8BIT_SMP_MONO_INTRP
  3250.                 VOLUME_RAMPING
  3251.                 INC_POS
  3252.                 RENDER_8BIT_SMP_MONO_INTRP
  3253.                 VOLUME_RAMPING
  3254.                 INC_POS
  3255.             }
  3256.         }
  3257.         else
  3258.         {
  3259.             if (samplesToMix & 1)
  3260.             {
  3261.                 RENDER_8BIT_SMP_INTRP
  3262.                 VOLUME_RAMPING
  3263.                 INC_POS
  3264.             }
  3265.             samplesToMix >>= 1;
  3266.             for (i = 0; i < samplesToMix; i++)
  3267.             {
  3268.                 RENDER_8BIT_SMP_INTRP
  3269.                 VOLUME_RAMPING
  3270.                 INC_POS
  3271.                 RENDER_8BIT_SMP_INTRP
  3272.                 VOLUME_RAMPING
  3273.                 INC_POS
  3274.             }
  3275.         }
  3276.         SET_VOL_BACK
  3277.  
  3278.         HANDLE_SAMPLE_END
  3279.     }
  3280.  
  3281.     SET_BACK_MIXER_POS
  3282. }
  3283.  
  3284. static void mix8bRampLoopIntrp(voice_t *v, uint32_t numSamples)
  3285. {
  3286.     const int8_t *CDA_LinearAdr;
  3287.     bool mixInMono;
  3288.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  3289.     register const int8_t *smpPtr;
  3290.     register int32_t CDA_LVol, CDA_RVol;
  3291.     register uint32_t pos, delta;
  3292.     uint32_t i, samplesToMix;
  3293.  
  3294.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  3295.     {
  3296.         VOL0_OPTIMIZATION_LOOP
  3297.         return;
  3298.     }
  3299.  
  3300.     GET_MIXER_VARS_RAMP
  3301.     GET_DELTA
  3302.     SET_BASE8
  3303.  
  3304.     CDA_BytesLeft = numSamples;
  3305.     while (CDA_BytesLeft > 0)
  3306.     {
  3307.         LIMIT_MIX_NUM
  3308.         LIMIT_MIX_NUM_RAMP
  3309.         CDA_BytesLeft -= samplesToMix;
  3310.  
  3311.         GET_VOL
  3312.         if (mixInMono)
  3313.         {
  3314.             if (samplesToMix & 1)
  3315.             {
  3316.                 RENDER_8BIT_SMP_MONO_INTRP
  3317.                 VOLUME_RAMPING
  3318.                 INC_POS
  3319.             }
  3320.             samplesToMix >>= 1;
  3321.             for (i = 0; i < samplesToMix; i++)
  3322.             {
  3323.                 RENDER_8BIT_SMP_MONO_INTRP
  3324.                 VOLUME_RAMPING
  3325.                 INC_POS
  3326.                 RENDER_8BIT_SMP_MONO_INTRP
  3327.                 VOLUME_RAMPING
  3328.                 INC_POS
  3329.             }
  3330.         }
  3331.         else
  3332.         {
  3333.             if (samplesToMix & 1)
  3334.             {
  3335.                 RENDER_8BIT_SMP_INTRP
  3336.                 VOLUME_RAMPING
  3337.                 INC_POS
  3338.             }
  3339.             samplesToMix >>= 1;
  3340.             for (i = 0; i < samplesToMix; i++)
  3341.             {
  3342.                 RENDER_8BIT_SMP_INTRP
  3343.                 VOLUME_RAMPING
  3344.                 INC_POS
  3345.                 RENDER_8BIT_SMP_INTRP
  3346.                 VOLUME_RAMPING
  3347.                 INC_POS
  3348.             }
  3349.         }
  3350.         SET_VOL_BACK
  3351.  
  3352.         WRAP_LOOP
  3353.     }
  3354.  
  3355.     SET_BACK_MIXER_POS
  3356. }
  3357.  
  3358. static void mix8bRampBidiLoopIntrp(voice_t *v, uint32_t numSamples)
  3359. {
  3360.     bool mixInMono;
  3361.     const int8_t *CDA_LinearAdr, *CDA_LinAdrRev;
  3362.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  3363.     register const int8_t *smpPtr;
  3364.     register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
  3365.     register uint32_t pos;
  3366.     uint32_t delta, i, samplesToMix;
  3367.  
  3368.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  3369.     {
  3370.         VOL0_OPTIMIZATION_BIDI_LOOP
  3371.         return;
  3372.     }
  3373.  
  3374.     GET_MIXER_VARS_RAMP
  3375.     SET_BASE8_BIDI
  3376.  
  3377.     CDA_BytesLeft = numSamples;
  3378.     while (CDA_BytesLeft > 0)
  3379.     {
  3380.         LIMIT_MIX_NUM
  3381.         LIMIT_MIX_NUM_RAMP
  3382.         CDA_BytesLeft -= samplesToMix;
  3383.  
  3384.         GET_VOL
  3385.         START_BIDI
  3386.         if (mixInMono)
  3387.         {
  3388.             if (samplesToMix & 1)
  3389.             {
  3390.                 RENDER_8BIT_SMP_MONO_INTRP
  3391.                 VOLUME_RAMPING
  3392.                 INC_POS_BIDI
  3393.             }
  3394.             samplesToMix >>= 1;
  3395.             for (i = 0; i < samplesToMix; i++)
  3396.             {
  3397.                 RENDER_8BIT_SMP_MONO_INTRP
  3398.                 VOLUME_RAMPING
  3399.                 INC_POS_BIDI
  3400.                 RENDER_8BIT_SMP_MONO_INTRP
  3401.                 VOLUME_RAMPING
  3402.                 INC_POS_BIDI
  3403.             }
  3404.         }
  3405.         else
  3406.         {
  3407.             if (samplesToMix & 1)
  3408.             {
  3409.                 RENDER_8BIT_SMP_INTRP
  3410.                 VOLUME_RAMPING
  3411.                 INC_POS_BIDI
  3412.             }
  3413.             samplesToMix >>= 1;
  3414.             for (i = 0; i < samplesToMix; i++)
  3415.             {
  3416.                 RENDER_8BIT_SMP_INTRP
  3417.                 VOLUME_RAMPING
  3418.                 INC_POS_BIDI
  3419.                 RENDER_8BIT_SMP_INTRP
  3420.                 VOLUME_RAMPING
  3421.                 INC_POS_BIDI
  3422.             }
  3423.         }
  3424.         END_BIDI
  3425.         SET_VOL_BACK
  3426.  
  3427.         WRAP_BIDI_LOOP
  3428.     }
  3429.     SET_BACK_MIXER_POS
  3430. }
  3431.  
  3432. /* ----------------------------------------------------------------------- */
  3433. /*                          16-BIT MIXING ROUTINES                         */
  3434. /* ----------------------------------------------------------------------- */
  3435.  
  3436. static void mix16bNoLoop(voice_t *v, uint32_t numSamples)
  3437. {
  3438.     bool mixInMono;
  3439.     const int16_t *CDA_LinearAdr;
  3440.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
  3441.     register const int16_t *smpPtr;
  3442.     register int32_t CDA_LVol, CDA_RVol;
  3443.     register uint32_t pos, delta;
  3444.     uint32_t i, samplesToMix;
  3445.  
  3446.     GET_VOL
  3447.  
  3448.     if ((CDA_LVol | CDA_RVol) == 0)
  3449.     {
  3450.         VOL0_OPTIMIZATION_NO_LOOP
  3451.         return;
  3452.     }
  3453.  
  3454.     GET_MIXER_VARS
  3455.     GET_DELTA
  3456.     SET_BASE16
  3457.  
  3458.     CDA_BytesLeft = numSamples;
  3459.     while (CDA_BytesLeft > 0)
  3460.     {
  3461.         LIMIT_MIX_NUM
  3462.         CDA_BytesLeft -= samplesToMix;
  3463.  
  3464.         if (mixInMono)
  3465.         {
  3466.             if (samplesToMix & 1)
  3467.             {
  3468.                 RENDER_16BIT_SMP_MONO
  3469.                 INC_POS
  3470.             }
  3471.             samplesToMix >>= 1;
  3472.             for (i = 0; i < samplesToMix; i++)
  3473.             {
  3474.                 RENDER_16BIT_SMP_MONO
  3475.                 INC_POS
  3476.                 RENDER_16BIT_SMP_MONO
  3477.                 INC_POS
  3478.             }
  3479.         }
  3480.         else
  3481.         {
  3482.             if (samplesToMix & 1)
  3483.             {
  3484.                 RENDER_16BIT_SMP
  3485.                 INC_POS
  3486.             }
  3487.             samplesToMix >>= 1;
  3488.             for (i = 0; i < samplesToMix; i++)
  3489.             {
  3490.                 RENDER_16BIT_SMP
  3491.                 INC_POS
  3492.                 RENDER_16BIT_SMP
  3493.                 INC_POS
  3494.             }
  3495.         }
  3496.  
  3497.         HANDLE_SAMPLE_END
  3498.     }
  3499.  
  3500.     SET_BACK_MIXER_POS
  3501. }
  3502.  
  3503. static void mix16bLoop(voice_t *v, uint32_t numSamples)
  3504. {
  3505.     bool mixInMono;
  3506.     const int16_t *CDA_LinearAdr;
  3507.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
  3508.     register const int16_t *smpPtr;
  3509.     register int32_t CDA_LVol, CDA_RVol;
  3510.     register uint32_t pos, delta;
  3511.     uint32_t i, samplesToMix;
  3512.  
  3513.     GET_VOL
  3514.  
  3515.     if ((CDA_LVol | CDA_RVol) == 0)
  3516.     {
  3517.         VOL0_OPTIMIZATION_LOOP
  3518.         return;
  3519.     }
  3520.  
  3521.     GET_MIXER_VARS
  3522.     GET_DELTA
  3523.     SET_BASE16
  3524.  
  3525.     CDA_BytesLeft = numSamples;
  3526.     while (CDA_BytesLeft > 0)
  3527.     {
  3528.         LIMIT_MIX_NUM
  3529.         CDA_BytesLeft -= samplesToMix;
  3530.  
  3531.         if (mixInMono)
  3532.         {
  3533.             if (samplesToMix & 1)
  3534.             {
  3535.                 RENDER_16BIT_SMP_MONO
  3536.                 INC_POS
  3537.             }
  3538.             samplesToMix >>= 1;
  3539.             for (i = 0; i < samplesToMix; i++)
  3540.             {
  3541.                 RENDER_16BIT_SMP_MONO
  3542.                 INC_POS
  3543.                 RENDER_16BIT_SMP_MONO
  3544.                 INC_POS
  3545.             }
  3546.         }
  3547.         else
  3548.         {
  3549.             if (samplesToMix & 1)
  3550.             {
  3551.                 RENDER_16BIT_SMP
  3552.                 INC_POS
  3553.             }
  3554.             samplesToMix >>= 1;
  3555.             for (i = 0; i < samplesToMix; i++)
  3556.             {
  3557.                 RENDER_16BIT_SMP
  3558.                 INC_POS
  3559.                 RENDER_16BIT_SMP
  3560.                 INC_POS
  3561.             }
  3562.         }
  3563.  
  3564.         WRAP_LOOP
  3565.     }
  3566.  
  3567.     SET_BACK_MIXER_POS
  3568. }
  3569.  
  3570. static void mix16bBidiLoop(voice_t *v, uint32_t numSamples)
  3571. {
  3572.     bool mixInMono;
  3573.     const int16_t *CDA_LinearAdr, *CDA_LinAdrRev;
  3574.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
  3575.     register const int16_t *smpPtr;
  3576.     register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
  3577.     register uint32_t pos;
  3578.     uint32_t delta, i, samplesToMix;
  3579.  
  3580.     GET_VOL
  3581.  
  3582.     if ((CDA_LVol | CDA_RVol) == 0)
  3583.     {
  3584.         VOL0_OPTIMIZATION_BIDI_LOOP
  3585.         return;
  3586.     }
  3587.  
  3588.     GET_MIXER_VARS
  3589.     SET_BASE16_BIDI
  3590.  
  3591.     CDA_BytesLeft = numSamples;
  3592.     while (CDA_BytesLeft > 0)
  3593.     {
  3594.         LIMIT_MIX_NUM
  3595.         CDA_BytesLeft -= samplesToMix;
  3596.  
  3597.         START_BIDI
  3598.         if (mixInMono)
  3599.         {
  3600.             if (samplesToMix & 1)
  3601.             {
  3602.                 RENDER_16BIT_SMP_MONO
  3603.                 INC_POS_BIDI
  3604.             }
  3605.             samplesToMix >>= 1;
  3606.             for (i = 0; i < samplesToMix; i++)
  3607.             {
  3608.                 RENDER_16BIT_SMP_MONO
  3609.                 INC_POS_BIDI
  3610.                 RENDER_16BIT_SMP_MONO
  3611.                 INC_POS_BIDI
  3612.             }
  3613.         }
  3614.         else
  3615.         {
  3616.             if (samplesToMix & 1)
  3617.             {
  3618.                 RENDER_16BIT_SMP
  3619.                 INC_POS_BIDI
  3620.             }
  3621.             samplesToMix >>= 1;
  3622.             for (i = 0; i < samplesToMix; i++)
  3623.             {
  3624.                 RENDER_16BIT_SMP
  3625.                 INC_POS_BIDI
  3626.                 RENDER_16BIT_SMP
  3627.                 INC_POS_BIDI
  3628.             }
  3629.         }
  3630.         END_BIDI
  3631.  
  3632.         WRAP_BIDI_LOOP
  3633.     }
  3634.  
  3635.     SET_BACK_MIXER_POS
  3636. }
  3637.  
  3638. static void mix16bNoLoopIntrp(voice_t *v, uint32_t numSamples)
  3639. {
  3640.     bool mixInMono;
  3641.     const int16_t *CDA_LinearAdr;
  3642.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft;
  3643.     register const int16_t *smpPtr;
  3644.     register int32_t CDA_LVol, CDA_RVol;
  3645.     register uint32_t pos, delta;
  3646.     uint32_t i, samplesToMix;
  3647.  
  3648.     GET_VOL
  3649.  
  3650.     if ((CDA_LVol | CDA_RVol) == 0)
  3651.     {
  3652.         VOL0_OPTIMIZATION_NO_LOOP
  3653.         return;
  3654.     }
  3655.  
  3656.     GET_MIXER_VARS
  3657.     GET_DELTA
  3658.     SET_BASE16
  3659.  
  3660.     CDA_BytesLeft = numSamples;
  3661.     while (CDA_BytesLeft > 0)
  3662.     {
  3663.         LIMIT_MIX_NUM
  3664.         CDA_BytesLeft -= samplesToMix;
  3665.  
  3666.         if (mixInMono)
  3667.         {
  3668.             if (samplesToMix & 1)
  3669.             {
  3670.                 RENDER_16BIT_SMP_MONO_INTRP
  3671.                 INC_POS
  3672.             }
  3673.             samplesToMix >>= 1;
  3674.             for (i = 0; i < samplesToMix; i++)
  3675.             {
  3676.                 RENDER_16BIT_SMP_MONO_INTRP
  3677.                 INC_POS
  3678.                 RENDER_16BIT_SMP_MONO_INTRP
  3679.                 INC_POS
  3680.             }
  3681.         }
  3682.         else
  3683.         {
  3684.             if (samplesToMix & 1)
  3685.             {
  3686.                 RENDER_16BIT_SMP_INTRP
  3687.                 INC_POS
  3688.             }
  3689.             samplesToMix >>= 1;
  3690.             for (i = 0; i < samplesToMix; i++)
  3691.             {
  3692.                 RENDER_16BIT_SMP_INTRP
  3693.                 INC_POS
  3694.                 RENDER_16BIT_SMP_INTRP
  3695.                 INC_POS
  3696.             }
  3697.         }
  3698.  
  3699.         HANDLE_SAMPLE_END
  3700.     }
  3701.  
  3702.     SET_BACK_MIXER_POS
  3703. }
  3704.  
  3705. static void mix16bLoopIntrp(voice_t *v, uint32_t numSamples)
  3706. {
  3707.     bool mixInMono;
  3708.     const int16_t *CDA_LinearAdr;
  3709.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft;
  3710.     register const int16_t *smpPtr;
  3711.     register int32_t CDA_LVol, CDA_RVol;
  3712.     register uint32_t pos, delta;
  3713.     uint32_t i, samplesToMix;
  3714.  
  3715.     GET_VOL
  3716.  
  3717.     if ((CDA_LVol| CDA_RVol) == 0)
  3718.     {
  3719.         VOL0_OPTIMIZATION_LOOP
  3720.         return;
  3721.     }
  3722.  
  3723.     GET_MIXER_VARS
  3724.     GET_DELTA
  3725.     SET_BASE16
  3726.  
  3727.     CDA_BytesLeft = numSamples;
  3728.     while (CDA_BytesLeft > 0)
  3729.     {
  3730.         LIMIT_MIX_NUM
  3731.         CDA_BytesLeft -= samplesToMix;
  3732.  
  3733.         if (mixInMono)
  3734.         {
  3735.             if (samplesToMix & 1)
  3736.             {
  3737.                 RENDER_16BIT_SMP_MONO_INTRP
  3738.                 INC_POS
  3739.             }
  3740.             samplesToMix >>= 1;
  3741.             for (i = 0; i < samplesToMix; i++)
  3742.             {
  3743.                 RENDER_16BIT_SMP_MONO_INTRP
  3744.                 INC_POS
  3745.                 RENDER_16BIT_SMP_MONO_INTRP
  3746.                 INC_POS
  3747.             }
  3748.         }
  3749.         else
  3750.         {
  3751.             if (samplesToMix & 1)
  3752.             {
  3753.                 RENDER_16BIT_SMP_INTRP
  3754.                 INC_POS
  3755.             }
  3756.             samplesToMix >>= 1;
  3757.             for (i = 0; i < samplesToMix; i++)
  3758.             {
  3759.                 RENDER_16BIT_SMP_INTRP
  3760.                 INC_POS
  3761.                 RENDER_16BIT_SMP_INTRP
  3762.                 INC_POS
  3763.             }
  3764.         }
  3765.  
  3766.         WRAP_LOOP
  3767.     }
  3768.  
  3769.     SET_BACK_MIXER_POS
  3770. }
  3771.  
  3772. static void mix16bBidiLoopIntrp(voice_t *v, uint32_t numSamples)
  3773. {
  3774.     bool mixInMono;
  3775.     const int16_t *CDA_LinearAdr, *CDA_LinAdrRev;
  3776.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft;
  3777.     register const int16_t *smpPtr;
  3778.     register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
  3779.     register uint32_t pos;
  3780.     uint32_t delta, i, samplesToMix;
  3781.  
  3782.     GET_VOL
  3783.  
  3784.     if ((CDA_LVol | CDA_RVol) == 0)
  3785.     {
  3786.         VOL0_OPTIMIZATION_BIDI_LOOP
  3787.         return;
  3788.     }
  3789.  
  3790.     GET_MIXER_VARS
  3791.     SET_BASE16_BIDI
  3792.  
  3793.     CDA_BytesLeft = numSamples;
  3794.     while (CDA_BytesLeft > 0)
  3795.     {
  3796.         LIMIT_MIX_NUM
  3797.         CDA_BytesLeft -= samplesToMix;
  3798.  
  3799.         START_BIDI
  3800.         if (mixInMono)
  3801.         {
  3802.             if (samplesToMix & 1)
  3803.             {
  3804.                 RENDER_16BIT_SMP_MONO_INTRP
  3805.                 INC_POS_BIDI
  3806.             }
  3807.             samplesToMix >>= 1;
  3808.             for (i = 0; i < samplesToMix; i++)
  3809.             {
  3810.                 RENDER_16BIT_SMP_MONO_INTRP
  3811.                 INC_POS_BIDI
  3812.                 RENDER_16BIT_SMP_MONO_INTRP
  3813.                 INC_POS_BIDI
  3814.             }
  3815.         }
  3816.         else
  3817.         {
  3818.             if (samplesToMix & 1)
  3819.             {
  3820.                 RENDER_16BIT_SMP_INTRP
  3821.                 INC_POS_BIDI
  3822.             }
  3823.             samplesToMix >>= 1;
  3824.             for (i = 0; i < samplesToMix; i++)
  3825.             {
  3826.                 RENDER_16BIT_SMP_INTRP
  3827.                 INC_POS_BIDI
  3828.                 RENDER_16BIT_SMP_INTRP
  3829.                 INC_POS_BIDI
  3830.             }
  3831.         }
  3832.         END_BIDI
  3833.  
  3834.         WRAP_BIDI_LOOP
  3835.     }
  3836.  
  3837.     SET_BACK_MIXER_POS
  3838. }
  3839.  
  3840. static void mix16bRampNoLoop(voice_t *v, uint32_t numSamples)
  3841. {
  3842.     bool mixInMono;
  3843.     const int16_t *CDA_LinearAdr;
  3844.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  3845.     register const int16_t *smpPtr;
  3846.     register int32_t CDA_LVol, CDA_RVol;
  3847.     register uint32_t pos, delta;
  3848.     uint32_t i, samplesToMix;
  3849.  
  3850.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  3851.     {
  3852.         VOL0_OPTIMIZATION_NO_LOOP
  3853.         return;
  3854.     }
  3855.  
  3856.     GET_MIXER_VARS_RAMP
  3857.     GET_DELTA
  3858.     SET_BASE16
  3859.  
  3860.     CDA_BytesLeft = numSamples;
  3861.     while (CDA_BytesLeft > 0)
  3862.     {
  3863.         LIMIT_MIX_NUM
  3864.         LIMIT_MIX_NUM_RAMP
  3865.         CDA_BytesLeft -= samplesToMix;
  3866.  
  3867.         GET_VOL
  3868.         if (mixInMono)
  3869.         {
  3870.             if (samplesToMix & 1)
  3871.             {
  3872.                 RENDER_16BIT_SMP_MONO
  3873.                 VOLUME_RAMPING
  3874.                 INC_POS
  3875.             }
  3876.             samplesToMix >>= 1;
  3877.             for (i = 0; i < samplesToMix; i++)
  3878.             {
  3879.                 RENDER_16BIT_SMP_MONO
  3880.                 VOLUME_RAMPING
  3881.                 INC_POS
  3882.                 RENDER_16BIT_SMP_MONO
  3883.                 VOLUME_RAMPING
  3884.                 INC_POS
  3885.             }
  3886.         }
  3887.         else
  3888.         {
  3889.             if (samplesToMix & 1)
  3890.             {
  3891.                 RENDER_16BIT_SMP
  3892.                 VOLUME_RAMPING
  3893.                 INC_POS
  3894.             }
  3895.             samplesToMix >>= 1;
  3896.             for (i = 0; i < samplesToMix; i++)
  3897.             {
  3898.                 RENDER_16BIT_SMP
  3899.                 VOLUME_RAMPING
  3900.                 INC_POS
  3901.                 RENDER_16BIT_SMP
  3902.                 VOLUME_RAMPING
  3903.                 INC_POS
  3904.             }
  3905.         }
  3906.         SET_VOL_BACK
  3907.  
  3908.         HANDLE_SAMPLE_END
  3909.     }
  3910.  
  3911.     SET_BACK_MIXER_POS
  3912. }
  3913.  
  3914. static void mix16bRampLoop(voice_t *v, uint32_t numSamples)
  3915. {
  3916.     bool mixInMono;
  3917.     const int16_t *CDA_LinearAdr;
  3918.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  3919.     register const int16_t *smpPtr;
  3920.     register int32_t CDA_LVol, CDA_RVol;
  3921.     register uint32_t pos, delta;
  3922.     uint32_t i, samplesToMix;
  3923.  
  3924.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  3925.     {
  3926.         VOL0_OPTIMIZATION_LOOP
  3927.         return;
  3928.     }
  3929.  
  3930.     GET_MIXER_VARS_RAMP
  3931.     GET_DELTA
  3932.     SET_BASE16
  3933.  
  3934.     CDA_BytesLeft = numSamples;
  3935.     while (CDA_BytesLeft > 0)
  3936.     {
  3937.         LIMIT_MIX_NUM
  3938.         LIMIT_MIX_NUM_RAMP
  3939.         CDA_BytesLeft -= samplesToMix;
  3940.  
  3941.         GET_VOL
  3942.         if (mixInMono)
  3943.         {
  3944.             if (samplesToMix & 1)
  3945.             {
  3946.                 RENDER_16BIT_SMP_MONO
  3947.                 VOLUME_RAMPING
  3948.                 INC_POS
  3949.             }
  3950.             samplesToMix >>= 1;
  3951.             for (i = 0; i < samplesToMix; i++)
  3952.             {
  3953.                 RENDER_16BIT_SMP_MONO
  3954.                 VOLUME_RAMPING
  3955.                 INC_POS
  3956.                 RENDER_16BIT_SMP_MONO
  3957.                 VOLUME_RAMPING
  3958.                 INC_POS
  3959.             }
  3960.         }
  3961.         else
  3962.         {
  3963.             if (samplesToMix & 1)
  3964.             {
  3965.                 RENDER_16BIT_SMP
  3966.                 VOLUME_RAMPING
  3967.                 INC_POS
  3968.             }
  3969.             samplesToMix >>= 1;
  3970.             for (i = 0; i < samplesToMix; i++)
  3971.             {
  3972.                 RENDER_16BIT_SMP
  3973.                 VOLUME_RAMPING
  3974.                 INC_POS
  3975.                 RENDER_16BIT_SMP
  3976.                 VOLUME_RAMPING
  3977.                 INC_POS
  3978.             }
  3979.         }
  3980.         SET_VOL_BACK
  3981.  
  3982.         WRAP_LOOP
  3983.     }
  3984.  
  3985.     SET_BACK_MIXER_POS
  3986. }
  3987.  
  3988. static void mix16bRampBidiLoop(voice_t *v, uint32_t numSamples)
  3989. {
  3990.     bool mixInMono;
  3991.     const int16_t *CDA_LinearAdr, *CDA_LinAdrRev;
  3992.     int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  3993.     register const int16_t *smpPtr;
  3994.     register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
  3995.     register uint32_t pos;
  3996.     uint32_t delta, i, samplesToMix;
  3997.  
  3998.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  3999.     {
  4000.         VOL0_OPTIMIZATION_BIDI_LOOP
  4001.         return;
  4002.     }
  4003.  
  4004.     GET_MIXER_VARS_RAMP
  4005.     SET_BASE16_BIDI
  4006.  
  4007.     CDA_BytesLeft = numSamples;
  4008.     while (CDA_BytesLeft > 0)
  4009.     {
  4010.         LIMIT_MIX_NUM
  4011.         LIMIT_MIX_NUM_RAMP
  4012.         CDA_BytesLeft -= samplesToMix;
  4013.  
  4014.         GET_VOL
  4015.         START_BIDI
  4016.         if (mixInMono)
  4017.         {
  4018.             if (samplesToMix & 1)
  4019.             {
  4020.                 RENDER_16BIT_SMP_MONO
  4021.                 VOLUME_RAMPING
  4022.                 INC_POS_BIDI
  4023.             }
  4024.             samplesToMix >>= 1;
  4025.             for (i = 0; i < samplesToMix; i++)
  4026.             {
  4027.                 RENDER_16BIT_SMP_MONO
  4028.                 VOLUME_RAMPING
  4029.                 INC_POS_BIDI
  4030.                 RENDER_16BIT_SMP_MONO
  4031.                 VOLUME_RAMPING
  4032.                 INC_POS_BIDI
  4033.             }
  4034.         }
  4035.         else
  4036.         {
  4037.             if (samplesToMix & 1)
  4038.             {
  4039.                 RENDER_16BIT_SMP
  4040.                 VOLUME_RAMPING
  4041.                 INC_POS_BIDI
  4042.             }
  4043.             samplesToMix >>= 1;
  4044.             for (i = 0; i < samplesToMix; i++)
  4045.             {
  4046.                 RENDER_16BIT_SMP
  4047.                 VOLUME_RAMPING
  4048.                 INC_POS_BIDI
  4049.                 RENDER_16BIT_SMP
  4050.                 VOLUME_RAMPING
  4051.                 INC_POS_BIDI
  4052.             }
  4053.         }
  4054.         END_BIDI
  4055.         SET_VOL_BACK
  4056.  
  4057.         WRAP_BIDI_LOOP
  4058.     }
  4059.  
  4060.     SET_BACK_MIXER_POS
  4061. }
  4062.  
  4063. static void mix16bRampNoLoopIntrp(voice_t *v, uint32_t numSamples)
  4064. {
  4065.     bool mixInMono;
  4066.     const int16_t *CDA_LinearAdr;
  4067.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  4068.     register const int16_t *smpPtr;
  4069.     register int32_t CDA_LVol, CDA_RVol;
  4070.     register uint32_t pos, delta;
  4071.     uint32_t i, samplesToMix;
  4072.  
  4073.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  4074.     {
  4075.         VOL0_OPTIMIZATION_NO_LOOP
  4076.         return;
  4077.     }
  4078.  
  4079.     GET_MIXER_VARS_RAMP
  4080.     GET_DELTA
  4081.     SET_BASE16
  4082.  
  4083.     CDA_BytesLeft = numSamples;
  4084.     while (CDA_BytesLeft > 0)
  4085.     {
  4086.         LIMIT_MIX_NUM
  4087.         LIMIT_MIX_NUM_RAMP
  4088.         CDA_BytesLeft -= samplesToMix;
  4089.  
  4090.         GET_VOL
  4091.         if (mixInMono)
  4092.         {
  4093.             if (samplesToMix & 1)
  4094.             {
  4095.                 RENDER_16BIT_SMP_MONO_INTRP
  4096.                 VOLUME_RAMPING
  4097.                 INC_POS
  4098.             }
  4099.             samplesToMix >>= 1;
  4100.             for (i = 0; i < samplesToMix; i++)
  4101.             {
  4102.                 RENDER_16BIT_SMP_MONO_INTRP
  4103.                 VOLUME_RAMPING
  4104.                 INC_POS
  4105.                 RENDER_16BIT_SMP_MONO_INTRP
  4106.                 VOLUME_RAMPING
  4107.                 INC_POS
  4108.             }
  4109.         }
  4110.         else
  4111.         {
  4112.             if (samplesToMix & 1)
  4113.             {
  4114.                 RENDER_16BIT_SMP_INTRP
  4115.                 VOLUME_RAMPING
  4116.                 INC_POS
  4117.             }
  4118.             samplesToMix >>= 1;
  4119.             for (i = 0; i < samplesToMix; i++)
  4120.             {
  4121.                 RENDER_16BIT_SMP_INTRP
  4122.                 VOLUME_RAMPING
  4123.                 INC_POS
  4124.                 RENDER_16BIT_SMP_INTRP
  4125.                 VOLUME_RAMPING
  4126.                 INC_POS
  4127.             }
  4128.         }
  4129.         SET_VOL_BACK
  4130.  
  4131.         HANDLE_SAMPLE_END
  4132.     }
  4133.  
  4134.     SET_BACK_MIXER_POS
  4135. }
  4136.  
  4137. static void mix16bRampLoopIntrp(voice_t *v, uint32_t numSamples)
  4138. {
  4139.     bool mixInMono;
  4140.     const int16_t *CDA_LinearAdr;
  4141.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  4142.     register const int16_t *smpPtr;
  4143.     register int32_t CDA_LVol, CDA_RVol;
  4144.     register uint32_t pos, delta;
  4145.     uint32_t i, samplesToMix;
  4146.  
  4147.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  4148.     {
  4149.         VOL0_OPTIMIZATION_LOOP
  4150.         return;
  4151.     }
  4152.  
  4153.     GET_MIXER_VARS_RAMP
  4154.     GET_DELTA
  4155.     SET_BASE16
  4156.  
  4157.     CDA_BytesLeft = numSamples;
  4158.     while (CDA_BytesLeft > 0)
  4159.     {
  4160.         LIMIT_MIX_NUM
  4161.         LIMIT_MIX_NUM_RAMP
  4162.         CDA_BytesLeft -= samplesToMix;
  4163.  
  4164.         GET_VOL
  4165.         if (mixInMono)
  4166.         {
  4167.             if (samplesToMix & 1)
  4168.             {
  4169.                 RENDER_16BIT_SMP_MONO_INTRP
  4170.                 VOLUME_RAMPING
  4171.                 INC_POS
  4172.             }
  4173.             samplesToMix >>= 1;
  4174.             for (i = 0; i < samplesToMix; i++)
  4175.             {
  4176.                 RENDER_16BIT_SMP_MONO_INTRP
  4177.                 VOLUME_RAMPING
  4178.                 INC_POS
  4179.                 RENDER_16BIT_SMP_MONO_INTRP
  4180.                 VOLUME_RAMPING
  4181.                 INC_POS
  4182.             }
  4183.         }
  4184.         else
  4185.         {
  4186.             if (samplesToMix & 1)
  4187.             {
  4188.                 RENDER_16BIT_SMP_INTRP
  4189.                 VOLUME_RAMPING
  4190.                 INC_POS
  4191.             }
  4192.             samplesToMix >>= 1;
  4193.             for (i = 0; i < samplesToMix; i++)
  4194.             {
  4195.                 RENDER_16BIT_SMP_INTRP
  4196.                 VOLUME_RAMPING
  4197.                 INC_POS
  4198.                 RENDER_16BIT_SMP_INTRP
  4199.                 VOLUME_RAMPING
  4200.                 INC_POS
  4201.             }
  4202.         }
  4203.         SET_VOL_BACK
  4204.  
  4205.         WRAP_LOOP
  4206.     }
  4207.  
  4208.     SET_BACK_MIXER_POS
  4209. }
  4210.  
  4211. static void mix16bRampBidiLoopIntrp(voice_t *v, uint32_t numSamples)
  4212. {
  4213.     bool mixInMono;
  4214.     const int16_t *CDA_LinearAdr, *CDA_LinAdrRev;
  4215.     int32_t realPos, sample, sample2, sample3, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
  4216.     register const int16_t *smpPtr;
  4217.     register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
  4218.     register uint32_t pos;
  4219.     uint32_t delta, i, samplesToMix;
  4220.  
  4221.     if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
  4222.     {
  4223.         VOL0_OPTIMIZATION_BIDI_LOOP
  4224.         return;
  4225.     }
  4226.  
  4227.     GET_MIXER_VARS_RAMP
  4228.     SET_BASE16_BIDI
  4229.  
  4230.     CDA_BytesLeft = numSamples;
  4231.     while (CDA_BytesLeft > 0)
  4232.     {
  4233.         LIMIT_MIX_NUM
  4234.         LIMIT_MIX_NUM_RAMP
  4235.         CDA_BytesLeft -= samplesToMix;
  4236.  
  4237.         GET_VOL
  4238.         START_BIDI
  4239.         if (mixInMono)
  4240.         {
  4241.             if (samplesToMix & 1)
  4242.             {
  4243.                 RENDER_16BIT_SMP_MONO_INTRP
  4244.                 VOLUME_RAMPING
  4245.                 INC_POS_BIDI
  4246.             }
  4247.             samplesToMix >>= 1;
  4248.             for (i = 0; i < samplesToMix; i++)
  4249.             {
  4250.                 RENDER_16BIT_SMP_MONO_INTRP
  4251.                 VOLUME_RAMPING
  4252.                 INC_POS_BIDI
  4253.                 RENDER_16BIT_SMP_MONO_INTRP
  4254.                 VOLUME_RAMPING
  4255.                 INC_POS_BIDI
  4256.             }
  4257.         }
  4258.         else
  4259.         {
  4260.             if (samplesToMix & 1)
  4261.             {
  4262.                 RENDER_16BIT_SMP_INTRP
  4263.                 VOLUME_RAMPING
  4264.                 INC_POS_BIDI
  4265.             }
  4266.             samplesToMix >>= 1;
  4267.             for (i = 0; i < samplesToMix; i++)
  4268.             {
  4269.                 RENDER_16BIT_SMP_INTRP
  4270.                 VOLUME_RAMPING
  4271.                 INC_POS_BIDI
  4272.                 RENDER_16BIT_SMP_INTRP
  4273.                 VOLUME_RAMPING
  4274.                 INC_POS_BIDI
  4275.             }
  4276.         }
  4277.         END_BIDI
  4278.         SET_VOL_BACK
  4279.  
  4280.         WRAP_BIDI_LOOP
  4281.     }
  4282.  
  4283.     SET_BACK_MIXER_POS
  4284. }
  4285.  
  4286. mixRoutine mixRoutineTable[24] =
  4287. {
  4288.     (mixRoutine)mix8bNoLoop,
  4289.     (mixRoutine)mix8bLoop,
  4290.     (mixRoutine)mix8bBidiLoop,
  4291.     (mixRoutine)mix8bNoLoopIntrp,
  4292.     (mixRoutine)mix8bLoopIntrp,
  4293.     (mixRoutine)mix8bBidiLoopIntrp,
  4294.     (mixRoutine)mix8bRampNoLoop,
  4295.     (mixRoutine)mix8bRampLoop,
  4296.     (mixRoutine)mix8bRampBidiLoop,
  4297.     (mixRoutine)mix8bRampNoLoopIntrp,
  4298.     (mixRoutine)mix8bRampLoopIntrp,
  4299.     (mixRoutine)mix8bRampBidiLoopIntrp,
  4300.     (mixRoutine)mix16bNoLoop,
  4301.     (mixRoutine)mix16bLoop,
  4302.     (mixRoutine)mix16bBidiLoop,
  4303.     (mixRoutine)mix16bNoLoopIntrp,
  4304.     (mixRoutine)mix16bLoopIntrp,
  4305.     (mixRoutine)mix16bBidiLoopIntrp,
  4306.     (mixRoutine)mix16bRampNoLoop,
  4307.     (mixRoutine)mix16bRampLoop,
  4308.     (mixRoutine)mix16bRampBidiLoop,
  4309.     (mixRoutine)mix16bRampNoLoopIntrp,
  4310.     (mixRoutine)mix16bRampLoopIntrp,
  4311.     (mixRoutine)mix16bRampBidiLoopIntrp
  4312. };
  4313.  
  4314. // -----------------------------------------------------------------------
  4315.  
  4316. static inline void noNewAllChannels(void)
  4317. {
  4318.     for (uint8_t i = 0; i < song.antChn; i++)
  4319.     {
  4320.         doEffects(&stm[i]);
  4321.         fixaEnvelopeVibrato(&stm[i]);
  4322.     }
  4323. }
  4324.  
  4325. static void getNextPos(void)
  4326. {
  4327.     if (song.timer == 1)
  4328.     {
  4329.         song.pattPos++;
  4330.  
  4331.         if (song.pattDelTime > 0)
  4332.         {
  4333.             song.pattDelTime2 = song.pattDelTime;
  4334.             song.pattDelTime = 0;
  4335.         }
  4336.  
  4337.         if (song.pattDelTime2 > 0)
  4338.         {
  4339.             if (--song.pattDelTime2 > 0)
  4340.                 song.pattPos--;
  4341.         }
  4342.  
  4343.         if (song.pBreakFlag)
  4344.         {
  4345.             song.pBreakFlag = false;
  4346.             song.pattPos = song.pBreakPos;
  4347.         }
  4348.  
  4349.         if (song.pattPos >= song.pattLen || song.posJumpFlag)
  4350.         {
  4351.             song.pattPos = song.pBreakPos;
  4352.             song.pBreakPos = 0;
  4353.             song.posJumpFlag = false;
  4354.  
  4355.             if (++song.songPos >= song.len)
  4356.                 song.songPos = song.repS;
  4357.  
  4358.             song.pattNr = song.songTab[song.songPos & 0xFF];
  4359.             song.pattLen = pattLens[song.pattNr & 0xFF];
  4360.         }
  4361.     }
  4362. }
  4363.  
  4364. static void mainPlayer(void) // periodically called from mixer
  4365. {
  4366.     uint8_t i;
  4367.     bool readNewNote;
  4368.  
  4369.     if (!songPlaying)
  4370.         return;
  4371.  
  4372.     readNewNote = false;
  4373.     if (--song.timer == 0)
  4374.     {
  4375.         song.timer = song.tempo;
  4376.         readNewNote = true;
  4377.     }
  4378.  
  4379.     if (readNewNote)
  4380.     {
  4381.         if (song.pattDelTime2 == 0)
  4382.         {
  4383.             for (i = 0; i < song.antChn; i++)
  4384.             {
  4385.                 if (patt[song.pattNr] != NULL)
  4386.                     getNewNote(&stm[i], &patt[song.pattNr][(song.pattPos * song.antChn) + i]);
  4387.                 else
  4388.                     getNewNote(&stm[i], &nilPatternLine);
  4389.  
  4390.                 fixaEnvelopeVibrato(&stm[i]);
  4391.             }
  4392.         }
  4393.         else
  4394.         {
  4395.             noNewAllChannels();
  4396.         }
  4397.     }
  4398.     else
  4399.     {
  4400.         noNewAllChannels();
  4401.     }
  4402.  
  4403.     getNextPos();
  4404. }
  4405.  
  4406. static void stopVoice(uint8_t i)
  4407. {
  4408.     voice_t *v;
  4409.  
  4410.     v = &voice[i];
  4411.     memset(v, 0, sizeof (voice_t));
  4412.     v->SPan = 128;
  4413.  
  4414.     // clear "fade out" voice too
  4415.  
  4416.     v = &voice[MAX_VOICES + i];
  4417.     memset(v, 0, sizeof (voice_t));
  4418.     v->SPan = 128;
  4419. }
  4420.  
  4421. static void stopVoices(void)
  4422. {
  4423.     stmTyp *ch;
  4424.  
  4425.     for (uint8_t i = 0; i < song.antChn; i++)
  4426.     {
  4427.         ch = &stm[i];
  4428.  
  4429.         ch->tonTyp = 0;
  4430.         ch->relTonNr = 0;
  4431.         ch->instrNr = 0;
  4432.         ch->instrPtr = instr[0]; // placeholder instrument
  4433.         ch->status = IS_Vol;
  4434.         ch->realVol = 0;
  4435.         ch->outVol = 0;
  4436.         ch->oldVol = 0;
  4437.         ch->finalVol = 0;
  4438.         ch->oldPan = 128;
  4439.         ch->outPan = 128;
  4440.         ch->finalPan = 128;
  4441.         ch->vibDepth = 0;
  4442.         ch->smpPtr = NULL;
  4443.         ch->portaDir = 0; // FT2 bugfix: weird 3xx behavior if not used with note
  4444.  
  4445.         stopVoice(i);
  4446.     }
  4447.    
  4448.     oldPeriod = 0;
  4449.     oldRate = 0;
  4450.     oldSFrq = 0;
  4451.     oldSFrqRev = 0xFFFFFFFF;
  4452. }
  4453.  
  4454. static void setPos(int16_t songPos, int16_t pattPos)
  4455. {
  4456.     if (songPos > -1)
  4457.     {
  4458.         song.songPos = songPos;
  4459.         if (song.len > 0 && song.songPos >= song.len)
  4460.             song.songPos = song.len - 1;
  4461.  
  4462.         song.pattNr = song.songTab[songPos];
  4463.         song.pattLen = pattLens[song.pattNr];
  4464.     }
  4465.  
  4466.     if (pattPos > -1)
  4467.     {
  4468.         song.pattPos = pattPos;
  4469.         if (song.pattPos >= song.pattLen)
  4470.             song.pattPos = song.pattLen - 1;
  4471.     }
  4472.  
  4473.     song.timer = 1;
  4474. }
  4475.  
  4476. static void freeInstr(uint16_t ins)
  4477. {
  4478.     if (instr[ins] == NULL)
  4479.         return;
  4480.  
  4481.     for (uint8_t i = 0; i < 16; i++)
  4482.     {
  4483.         if (instr[ins]->samp[i].pek != NULL)
  4484.         {
  4485.             free(instr[ins]->samp[i].pek);
  4486.             instr[ins]->samp[i].pek = NULL;
  4487.         }
  4488.     }
  4489.  
  4490.     free(instr[ins]);
  4491.     instr[ins] = NULL;
  4492. }
  4493.  
  4494. static void freeAllInstr(void)
  4495. {
  4496.     for (uint16_t i = 0; i < 128; i++)
  4497.         freeInstr(i);
  4498. }
  4499.  
  4500. static void freeAllPatterns(void)
  4501. {
  4502.     for (uint16_t i = 0; i < 256; i++)
  4503.     {
  4504.         if (patt[i] != NULL)
  4505.         {
  4506.             free(patt[i]);
  4507.             patt[i] = NULL;
  4508.         }
  4509.     }
  4510. }
  4511.  
  4512. static bool allocateInstr(uint16_t i)
  4513. {
  4514.     instrTyp *p;
  4515.  
  4516.     if (instr[i] == NULL)
  4517.     {
  4518.         p = (instrTyp *)calloc(1, sizeof (instrTyp));
  4519.         if (p == NULL)
  4520.             return 0;
  4521.  
  4522.         for (uint8_t j = 0; j < 16; j++)
  4523.         {
  4524.             p->samp[j].pan = 128;
  4525.             p->samp[j].vol = 64;
  4526.         }
  4527.  
  4528.         instr[i] = p;
  4529.         return true;
  4530.     }
  4531.  
  4532.     return false;
  4533. }
  4534.  
  4535. static void delta2Samp(int8_t *p, uint32_t len, uint8_t typ)
  4536. {
  4537.     int8_t *p8, news8, olds8L, olds8R;
  4538.     int16_t *p16, news16, olds16L, olds16R;
  4539.     uint32_t i;
  4540.  
  4541.     if (typ & 16) len /= 2; // 16-bit
  4542.     if (typ & 32) len /= 2; // stereo
  4543.  
  4544.     if (typ & 32)
  4545.     {
  4546.         if (typ & 16)
  4547.         {
  4548.             p16 = (int16_t *)p;
  4549.  
  4550.             olds16L = 0;
  4551.             olds16R = 0;
  4552.  
  4553.             for (i = 0; i < len; i++)
  4554.             {
  4555.                 news16 = p16[i] + olds16L;
  4556.                 p16[i] = news16;
  4557.                 olds16L = news16;
  4558.  
  4559.                 news16 = p16[len+i] + olds16R;
  4560.                 p16[len+i] = news16;
  4561.                 olds16R = news16;
  4562.             }
  4563.         }
  4564.         else
  4565.         {
  4566.             p8 = (int8_t *)p;
  4567.  
  4568.             olds8L = 0;
  4569.             olds8R = 0;
  4570.  
  4571.             for (i = 0; i < len; i++)
  4572.             {
  4573.                 news8 = p8[i] + olds8L;
  4574.                 p8[i] = news8;
  4575.                 olds8L = news8;
  4576.  
  4577.                 news8 = p8[len+i] + olds8R;
  4578.                 p8[len+i] = news8;
  4579.                 olds8R = news8;
  4580.             }
  4581.         }
  4582.     }
  4583.     else
  4584.     {
  4585.         if (typ & 16)
  4586.         {
  4587.             p16 = (int16_t *)p;
  4588.  
  4589.             olds16L = 0;
  4590.             for (i = 0; i < len; i++)
  4591.             {
  4592.                 news16 = p16[i] + olds16L;
  4593.                 p16[i] = news16;
  4594.                 olds16L = news16;
  4595.             }
  4596.         }
  4597.         else
  4598.         {
  4599.             p8 = (int8_t *)p;
  4600.  
  4601.             olds8L = 0;
  4602.             for (i = 0; i < len; i++)
  4603.             {
  4604.                 news8 = p8[i] + olds8L;
  4605.                 p8[i] = news8;
  4606.                 olds8L = news8;
  4607.             }
  4608.         }
  4609.     }
  4610. }
  4611.  
  4612. static bool loadInstrHeader(MEMFILE *f, uint16_t i)
  4613. {
  4614.     uint8_t j;
  4615.     uint32_t readSize;
  4616.     instrHeaderTyp ih;
  4617.     instrTyp *ins;
  4618.     sampleHeaderTyp *src;
  4619.     sampleTyp *s;
  4620.  
  4621.     if (i > 128)
  4622.         return false;
  4623.  
  4624.     memset(&ih, 0, INSTR_HEADER_SIZE);
  4625.  
  4626.     mread(&ih.instrSize, 4, 1, f);
  4627.  
  4628.     readSize = ih.instrSize;
  4629.     if (readSize < 4 || readSize > INSTR_HEADER_SIZE)
  4630.         readSize = INSTR_HEADER_SIZE;
  4631.  
  4632.     // load instrument data into temp buffer
  4633.     mread(ih.name, readSize - 4, 1, f); // -4 = skip ih.instrSize
  4634.  
  4635.     // FT2 bugfix: skip instrument header data if instrSize is above INSTR_HEADER_SIZE
  4636.     if (ih.instrSize > INSTR_HEADER_SIZE)
  4637.         mseek(f, ih.instrSize - INSTR_HEADER_SIZE, SEEK_CUR);
  4638.  
  4639.     if (ih.antSamp > 16)
  4640.         return false;
  4641.  
  4642.     if (ih.antSamp > 0)
  4643.     {
  4644.         if (!allocateInstr(i))
  4645.             return false;
  4646.  
  4647.         // copy instrument header elements to our instrument struct
  4648.  
  4649.         ins = instr[i];
  4650.         memcpy(ins->ta, ih.ta, 96);
  4651.         memcpy(ins->envVP, ih.envVP, 12*2*sizeof(int16_t));
  4652.         memcpy(ins->envPP, ih.envPP, 12*2*sizeof(int16_t));
  4653.         ins->envVPAnt = ih.envVPAnt;
  4654.         ins->envPPAnt = ih.envPPAnt;
  4655.         ins->envVSust = ih.envVSust;
  4656.         ins->envVRepS = ih.envVRepS;
  4657.         ins->envVRepE = ih.envVRepE;
  4658.         ins->envPSust = ih.envPSust;
  4659.         ins->envPRepS = ih.envPRepS;
  4660.         ins->envPRepE = ih.envPRepE;
  4661.         ins->envVTyp = ih.envVTyp;
  4662.         ins->envPTyp = ih.envPTyp;
  4663.         ins->vibTyp = ih.vibTyp;
  4664.         ins->vibSweep = ih.vibSweep;
  4665.         ins->vibDepth = ih.vibDepth;
  4666.         ins->vibRate = ih.vibRate;
  4667.         ins->fadeOut = ih.fadeOut;
  4668.         ins->midiOn = (ih.midiOn > 0) ? true : false;
  4669.         ins->midiChannel = ih.midiChannel;
  4670.         ins->midiProgram = ih.midiProgram;
  4671.         ins->midiBend = ih.midiBend;
  4672.         ins->mute = (ih.mute > 0) ? true : false;
  4673.         ins->antSamp = ih.antSamp; // used in loadInstrSample()
  4674.  
  4675.         // sanitize stuff for broken/unsupported instruments
  4676.         ins->midiProgram = CLAMP(ins->midiProgram, 0, 127);
  4677.         ins->midiBend = CLAMP(ins->midiBend, 0, 36);
  4678.  
  4679.         if (ins->midiChannel > 15) ins->midiChannel = 15;
  4680.         if (ins->vibDepth > 0x0F) ins->vibDepth = 0x0F;
  4681.         if (ins->vibRate > 0x3F) ins->vibRate = 0x3F;
  4682.         if (ins->vibTyp > 3) ins->vibTyp = 0;
  4683.  
  4684.         for (j = 0; j < 96; j++)
  4685.         {
  4686.             if (ins->ta[j] > 15)
  4687.                 ins->ta[j] = 15;
  4688.         }
  4689.  
  4690.         if (ins->envVPAnt > 12) ins->envVPAnt = 12;
  4691.         if (ins->envVRepS > 11) ins->envVRepS = 11;
  4692.         if (ins->envVRepE > 11) ins->envVRepE = 11;
  4693.         if (ins->envVSust > 11) ins->envVSust = 11;
  4694.         if (ins->envPPAnt > 12) ins->envPPAnt = 12;
  4695.         if (ins->envPRepS > 11) ins->envPRepS = 11;
  4696.         if (ins->envPRepE > 11) ins->envPRepE = 11;
  4697.         if (ins->envPSust > 11) ins->envPSust = 11;
  4698.  
  4699.         for (j = 0; j < 12; j++)
  4700.         {
  4701.             if ((uint16_t)ins->envVP[j][0] > 32767) ins->envVP[j][0] = 32767;
  4702.             if ((uint16_t)ins->envPP[j][0] > 32767) ins->envPP[j][0] = 32767;
  4703.             if ((uint16_t)ins->envVP[j][1] > 64) ins->envVP[j][1] = 64;
  4704.             if ((uint16_t)ins->envPP[j][1] > 63) ins->envPP[j][1] = 63;
  4705.         }
  4706.  
  4707.         if (mread(ih.samp, ih.antSamp * sizeof (sampleHeaderTyp), 1, f) != 1)
  4708.             return false;
  4709.  
  4710.         for (j = 0; j < ih.antSamp; j++)
  4711.         {
  4712.             s = &instr[i]->samp[j];
  4713.             src = &ih.samp[j];
  4714.  
  4715.             // copy sample header elements to our sample struct
  4716.  
  4717.             s->len = src->len;
  4718.             s->repS = src->repS;
  4719.             s->repL = src->repL;
  4720.             s->vol = src->vol;
  4721.             s->fine = src->fine;
  4722.             s->typ = src->typ;
  4723.             s->pan = src->pan;
  4724.             s->relTon = src->relTon;
  4725.             memcpy(s->name, src->name, 22);
  4726.             s->name[22] = '\0';
  4727.  
  4728.             // dst->pek is set up later
  4729.  
  4730.             // trim off spaces at end of name
  4731.             for (int32_t k = 21; k >= 0; k--)
  4732.             {
  4733.                 if (s->name[k] == ' ' || s->name[k] == 0x1A)
  4734.                     s->name[k] = '\0';
  4735.                 else
  4736.                     break;
  4737.             }
  4738.  
  4739.             // sanitize stuff broken/unsupported samples
  4740.             if (s->vol > 64)
  4741.                 s->vol = 64;
  4742.  
  4743.             s->relTon = CLAMP(s->relTon, -48, 71);
  4744.         }
  4745.     }
  4746.  
  4747.     return true;
  4748. }
  4749.  
  4750. // adds wrapped samples after loop/end (for branchless mixer interpolation)
  4751. static void fixSample(sampleTyp *s)
  4752. {
  4753.     uint8_t loopType;
  4754.     int16_t *ptr16;
  4755.     int32_t loopStart, loopLen, loopEnd, len;
  4756.  
  4757.     if (s->pek == NULL)
  4758.         return; // empty sample
  4759.  
  4760.     loopType = s->typ & 3;
  4761.     if (loopType == 0)
  4762.     {
  4763.         len = s->len;
  4764.  
  4765.         // no loop (don't mess with fixed, fixSpar of fixedPos)
  4766.  
  4767.         if (s->typ & 16)
  4768.         {
  4769.             if (len < 2)
  4770.                 return;
  4771.  
  4772.             len  /= 2;
  4773.             ptr16 = (int16_t *)(s->pek);
  4774.  
  4775.             ptr16[len+0] = 0;
  4776.             ptr16[len+1] = 0;
  4777.         }
  4778.         else
  4779.         {
  4780.             if (len < 1)
  4781.                 return;
  4782.  
  4783.             s->pek[len+0] = 0;
  4784.             s->pek[len+1] = 0;
  4785.         }
  4786.  
  4787.         return;
  4788.     }
  4789.     else if (loopType == 1)
  4790.     {
  4791.         // forward loop
  4792.  
  4793.         if (s->typ & 16)
  4794.         {
  4795.             // 16-bit sample
  4796.  
  4797.             if (s->repL < 2)
  4798.                 return;
  4799.  
  4800.             loopStart = s->repS / 2;
  4801.             loopEnd = (s->repS + s->repL) / 2;
  4802.             ptr16 = (int16_t *)s->pek;
  4803.  
  4804.             ptr16[loopEnd+0] = ptr16[loopStart+0];
  4805.             ptr16[loopEnd+1] = ptr16[loopStart+1];
  4806.         }
  4807.         else
  4808.         {
  4809.             // 8-bit sample
  4810.  
  4811.             if (s->repL < 1)
  4812.                 return;
  4813.  
  4814.             loopStart = s->repS;
  4815.             loopEnd = s->repS + s->repL;
  4816.  
  4817.             s->pek[loopEnd+0] = s->pek[loopStart+0];
  4818.             s->pek[loopEnd+1] = s->pek[loopStart+1];
  4819.         }
  4820.     }
  4821.     else
  4822.     {
  4823.         // pingpong loop
  4824.  
  4825.         if (s->typ & 16)
  4826.         {
  4827.             // 16-bit sample
  4828.  
  4829.             if (s->repL < 2)
  4830.                 return;
  4831.  
  4832.             loopStart = s->repS / 2;
  4833.             loopLen = s->repL / 2;
  4834.             loopEnd = loopStart + loopLen;
  4835.             ptr16 = (int16_t *)s->pek;
  4836.  
  4837.             ptr16[loopEnd+0] = ptr16[loopEnd-1];
  4838.             if (loopLen >= 2)
  4839.                 ptr16[loopEnd+1] = ptr16[loopEnd-2];
  4840.             else
  4841.                 ptr16[loopEnd+1] = ptr16[loopStart];
  4842.         }
  4843.         else
  4844.         {
  4845.             // 8-bit sample
  4846.  
  4847.             if (s->repL < 1)
  4848.                 return;
  4849.  
  4850.             loopStart = s->repS;
  4851.             loopLen = s->repL;
  4852.             loopEnd = loopStart + loopLen;
  4853.  
  4854.             s->pek[loopEnd+0] = s->pek[loopEnd-1];
  4855.             if (loopLen >= 2)
  4856.                 s->pek[loopEnd+1] = s->pek[loopEnd-2];
  4857.             else
  4858.                 s->pek[loopEnd+1] = s->pek[loopStart];
  4859.         }
  4860.     }
  4861. }
  4862.  
  4863. static void checkSampleRepeat(sampleTyp *s)
  4864. {
  4865.     if (s->repS < 0) s->repS = 0;
  4866.     if (s->repL < 0) s->repL = 0;
  4867.     if (s->repS > s->len) s->repS = s->len;
  4868.     if (s->repS+s->repL > s->len) s->repL = s->len - s->repS;
  4869.     if (s->repL == 0) s->typ &= ~3; // non-FT2 fix: force loop off if looplen is 0
  4870. }
  4871.  
  4872. static bool loadInstrSample(MEMFILE *f, uint16_t i)
  4873. {
  4874.     int8_t *newPtr;
  4875.     int32_t l;
  4876.     sampleTyp *s;
  4877.  
  4878.     if (i > 128)
  4879.         return false;
  4880.  
  4881.     if (instr[i] == NULL)
  4882.         return true; // empty instrument
  4883.  
  4884.     for (uint16_t j = 0; j < instr[i]->antSamp; j++)
  4885.     {
  4886.         s = &instr[i]->samp[j];
  4887.  
  4888.         // if a sample has both forward loop and pingpong loop set, make it pingpong loop only (FT2 behavior)
  4889.         if ((s->typ & 3) == 3)
  4890.             s->typ &= 0xFE;
  4891.  
  4892.         l = s->len;
  4893.         if (l <= 0)
  4894.         {
  4895.             s->pek = NULL;
  4896.             s->len = 0;
  4897.             s->repL = 0;
  4898.             s->repS = 0;
  4899.  
  4900.             if (s->typ & 32)
  4901.                 s->typ &= ~32; // remove stereo flag
  4902.         }
  4903.         else
  4904.         {
  4905.             s->pek = (int8_t *)malloc(l + LOOP_FIX_LEN);
  4906.             if (s->pek == NULL)
  4907.                 return false;
  4908.  
  4909.             int32_t bytesRead = (int32_t)mread(s->pek, 1, l, f);
  4910.             if (bytesRead < l)
  4911.             {
  4912.                 int32_t bytesToClear = l - bytesRead;
  4913.                 memset(&s->pek[bytesRead], 0, bytesToClear);
  4914.             }
  4915.  
  4916.             delta2Samp(s->pek, l, s->typ);
  4917.  
  4918.             if (s->typ & 32) // stereo sample - already downmixed to mono in delta2samp()
  4919.             {
  4920.                 s->typ &= ~32; // remove stereo flag
  4921.  
  4922.                 s->len /= 2;
  4923.                 s->repL /= 2;
  4924.                 s->repS /= 2;
  4925.  
  4926.                 newPtr = (int8_t *)realloc(s->pek, s->len + LOOP_FIX_LEN);
  4927.                 if (newPtr != NULL)
  4928.                     s->pek = newPtr;
  4929.             }
  4930.         }
  4931.  
  4932.         // NON-FT2 FIX: align to 2-byte if 16-bit sample
  4933.         if (s->typ & 16)
  4934.         {
  4935.             s->repL &= 0xFFFFFFFE;
  4936.             s->repS &= 0xFFFFFFFE;
  4937.             s->len &= 0xFFFFFFFE;
  4938.         }
  4939.  
  4940.         checkSampleRepeat(s);
  4941.         fixSample(s);
  4942.     }
  4943.  
  4944.     return true;
  4945. }
  4946.  
  4947. static void unpackPatt(uint8_t *dst, uint16_t inn, uint16_t len, uint8_t antChn)
  4948. {
  4949.     uint8_t note, data, *src;
  4950.     int32_t srcEnd, srcIdx;
  4951.  
  4952.     if (dst == NULL)
  4953.         return;
  4954.  
  4955.     src = dst + inn;
  4956.     srcEnd = len * (sizeof (tonTyp) * antChn);
  4957.     srcIdx = 0;
  4958.  
  4959.     for (int32_t i = 0; i < len; i++)
  4960.     {
  4961.         for (int32_t j = 0; j < antChn; j++)
  4962.         {
  4963.             if (srcIdx >= srcEnd)
  4964.                 return; // error!
  4965.  
  4966.             note = *src++;
  4967.             if (note & 0x80)
  4968.             {
  4969.                 data = 0; if (note & 0x01) data = *src++; *dst++ = data;
  4970.                 data = 0; if (note & 0x02) data = *src++; *dst++ = data;
  4971.                 data = 0; if (note & 0x04) data = *src++; *dst++ = data;
  4972.                 data = 0; if (note & 0x08) data = *src++; *dst++ = data;
  4973.                 data = 0; if (note & 0x10) data = *src++; *dst++ = data;
  4974.             }
  4975.             else
  4976.             {
  4977.                 *dst++ = note;
  4978.                 *dst++ = *src++;
  4979.                 *dst++ = *src++;
  4980.                 *dst++ = *src++;
  4981.                 *dst++ = *src++;
  4982.             }
  4983.  
  4984.             // if note is overflowing (>97), remove it
  4985.             if (*(dst-5) > 97)
  4986.                 *(dst-5) = 0;
  4987.  
  4988.             // non-FT2 security fix: if effect is above 35 (Z), clear effect and parameter
  4989.             if (*(dst-2) > 35)
  4990.             {
  4991.                 *(dst-2) = 0;
  4992.                 *(dst-1) = 0;
  4993.             }
  4994.  
  4995.             srcIdx += sizeof (tonTyp);
  4996.         }
  4997.     }
  4998. }
  4999.  
  5000. static bool patternEmpty(uint16_t nr)
  5001. {
  5002.     uint8_t *scanPtr;
  5003.     uint32_t scanLen;
  5004.  
  5005.     if (patt[nr] == NULL)
  5006.         return true;
  5007.  
  5008.     scanPtr = (uint8_t *)patt[nr];
  5009.     scanLen = pattLens[nr] * (song.antChn * 5);
  5010.  
  5011.     for (uint32_t i = 0; i < scanLen; i++)
  5012.     {
  5013.         if (scanPtr[i] != 0)
  5014.             return false;
  5015.     }
  5016.  
  5017.     return true;
  5018. }
  5019.  
  5020. static bool loadPatterns(MEMFILE *f, uint16_t antPtn)
  5021. {
  5022.     uint8_t tmpLen, *pattPtr;
  5023.     uint16_t a;
  5024.     patternHeaderTyp ph;
  5025.  
  5026.     for (uint16_t i = 0; i < antPtn; i++)
  5027.     {
  5028.         mread(&ph.patternHeaderSize, 4, 1, f);
  5029.         mread(&ph.typ, 1, 1, f);
  5030.  
  5031.         ph.pattLen = 0;
  5032.         if (song.ver == 0x0102)
  5033.         {
  5034.             mread(&tmpLen, 1, 1, f);
  5035.             mread(&ph.dataLen, 2, 1, f);
  5036.             ph.pattLen = (uint16_t)tmpLen + 1; // +1 in v1.02
  5037.  
  5038.             if (ph.patternHeaderSize > 8)
  5039.                 mseek(f, ph.patternHeaderSize - 8, SEEK_CUR);
  5040.         }
  5041.         else
  5042.         {
  5043.             mread(&ph.pattLen, 2, 1, f);
  5044.             mread(&ph.dataLen, 2, 1, f);
  5045.  
  5046.             if (ph.patternHeaderSize > 9)
  5047.                 mseek(f, ph.patternHeaderSize - 9, SEEK_CUR);
  5048.         }
  5049.  
  5050.         if (meof(f))
  5051.         {
  5052.             mclose(&f);
  5053.             return false;
  5054.         }
  5055.  
  5056.         pattLens[i] = ph.pattLen;
  5057.         if (ph.dataLen)
  5058.         {
  5059.             a = ph.pattLen * (sizeof (tonTyp) * song.antChn);
  5060.  
  5061.             patt[i] = (tonTyp *)malloc(a + 16); // + 16 = a little extra for safety
  5062.             if (patt[i] == NULL)
  5063.                 return false;
  5064.  
  5065.             pattPtr = (uint8_t *)patt[i];
  5066.  
  5067.             memset(pattPtr, 0, a);
  5068.             mread(&pattPtr[a - ph.dataLen], 1, ph.dataLen, f);
  5069.             unpackPatt(pattPtr, a - ph.dataLen, ph.pattLen, song.antChn);
  5070.         }
  5071.  
  5072.         if (patternEmpty(i))
  5073.         {
  5074.             if (patt[i] != NULL)
  5075.             {
  5076.                 free(patt[i]);
  5077.                 patt[i] = NULL;
  5078.             }
  5079.  
  5080.             pattLens[i] = 64;
  5081.         }
  5082.  
  5083.         if (pattLens[i] > 256)
  5084.             pattLens[i] = 64;
  5085.     }
  5086.  
  5087.     return true;
  5088. }
  5089.  
  5090. #define IS_ID(s, b) !strncmp(s, b, 4)
  5091.  
  5092. static uint8_t getModType(uint8_t *numChannels, const char *id)
  5093. {
  5094.     uint8_t modFormat = FORMAT_UNKNOWN;
  5095.     *numChannels = 4;
  5096.  
  5097.     if (IS_ID("M.K.", id) || IS_ID("M!K!", id) || IS_ID("NSMS", id) || IS_ID("LARD", id) || IS_ID("PATT", id))
  5098.     {
  5099.         modFormat = FORMAT_MK; // ProTracker or compatible 
  5100.     }
  5101.     else if (id[1] == 'C' && id[2] == 'H' && id[3] == 'N')
  5102.     {
  5103.         modFormat = FORMAT_FT2; // FT2 or generic multichannel
  5104.         *numChannels = id[0] - '0';
  5105.     }
  5106.     else if (id[2] == 'C' && (id[3] == 'H' || id[3] == 'N'))
  5107.     {
  5108.         modFormat = FORMAT_FT2; // FT2 or generic multichannel
  5109.         *numChannels = ((id[0] - '0') * 10) + (id[1] - '0');
  5110.     }
  5111.     else if (IS_ID("FLT4", id))
  5112.     {
  5113.         modFormat = FORMAT_FLT; // StarTrekker (4-channel modules only)
  5114.     }
  5115.     else if (IS_ID("FLT8", id))
  5116.     {
  5117.         modFormat = FORMAT_FLT; // StarTrekker (4-channel modules only)
  5118.         *numChannels = 8;
  5119.     }
  5120.     else if (IS_ID("N.T.", id))
  5121.     {
  5122.         modFormat = FORMAT_NT; // NoiseTracker
  5123.     }
  5124.     else if (IS_ID("M&K!", id) || IS_ID("FEST", id))
  5125.     {
  5126.         modFormat = FORMAT_HMNT; // His Master's NoiseTracker
  5127.     }
  5128.  
  5129.     return modFormat;
  5130. }
  5131.  
  5132. static bool loadMusicMOD(MEMFILE *f, uint32_t fileLength)
  5133. {
  5134.     bool mightBeSTK, lateSTKVerFlag, veryLateSTKVerFlag;
  5135.     uint8_t bytes[4], modFormat, numChannels;
  5136.     int16_t i, j, k, ai;
  5137.     uint16_t a, b, period;
  5138.     tonTyp *ton;
  5139.     sampleTyp *s;
  5140.     songMOD31HeaderTyp h_MOD31;
  5141.     songMOD15HeaderTyp h_MOD15;
  5142.  
  5143.     veryLateSTKVerFlag = false; // "DFJ SoundTracker III" nad later
  5144.     lateSTKVerFlag = false; // "TJC SoundTracker II" and later
  5145.     mightBeSTK = false;
  5146.  
  5147.     memset(&h_MOD31, 0, sizeof (songMOD31HeaderTyp));
  5148.     memset(&h_MOD15, 0, sizeof (songMOD15HeaderTyp));
  5149.  
  5150.     // start loading MOD
  5151.  
  5152.     if (fileLength < 1596 || fileLength > 20842494) // minimum and maximum possible size for an FT2 .mod
  5153.     {
  5154.         mclose(&f);
  5155.         return false;
  5156.     }
  5157.  
  5158.     mrewind(f);
  5159.     mseek(f, 0, SEEK_SET);
  5160.  
  5161.     if (mread(&h_MOD31, 1, sizeof (h_MOD31), f) != sizeof (h_MOD31))
  5162.         goto modLoadError;
  5163.  
  5164.     modFormat = getModType(&numChannels, h_MOD31.sig);
  5165.     if (modFormat == FORMAT_FLT && numChannels == 8)
  5166.         goto modLoadError;
  5167.  
  5168.     if (modFormat != FORMAT_UNKNOWN)
  5169.     {
  5170.         if (fileLength < sizeof (h_MOD31))
  5171.             goto modLoadError;
  5172.  
  5173.         song.antChn = numChannels;
  5174.         song.len = h_MOD31.len;
  5175.         song.repS = h_MOD31.repS;
  5176.         memcpy(song.songTab, h_MOD31.songTab, 128);
  5177.         ai = 31;
  5178.     }
  5179.     else
  5180.     {
  5181.         mightBeSTK = true;
  5182.         if (fileLength < sizeof (h_MOD15))
  5183.             goto modLoadError;
  5184.  
  5185.         mrewind(f);
  5186.         if (mread(&h_MOD15, 1, sizeof (h_MOD15), f) != sizeof (h_MOD15))
  5187.             goto modLoadError;
  5188.  
  5189.         song.antChn = numChannels;
  5190.         song.len = h_MOD15.len;
  5191.         song.repS = h_MOD15.repS;
  5192.         memcpy(song.songTab, h_MOD15.songTab, 128);
  5193.         ai = 15;
  5194.     }
  5195.  
  5196.     if (modFormat == FORMAT_MK && song.len == 129)
  5197.         song.len = 127; // fixes a specific copy of beatwave.mod
  5198.  
  5199.     if (song.antChn == 0 || song.len < 1 || song.len > 128 || (mightBeSTK && song.repS > 220))
  5200.         goto modLoadError;
  5201.  
  5202.     if (!strncmp(h_MOD31.sig, "M.K.", 4) && song.len == 129)
  5203.         song.len = 127; // fixes a specific copy of beatwave.mod by Sidewinder
  5204.  
  5205.     for (a = 0; a < ai; a++)
  5206.     {
  5207.         songMODInstrHeaderTyp *smp = &h_MOD31.instr[a];
  5208.  
  5209.         /* Only late versions of Ultimate SoundTracker could have samples larger than 9999 bytes.
  5210.         ** If found, we know for sure that this is a late STK module.
  5211.         */
  5212.         if (mightBeSTK && 2*SWAP16(smp->len) > 9999)
  5213.             lateSTKVerFlag = true;
  5214.     }
  5215.  
  5216.     song.initialSpeed = 125;
  5217.     if (mightBeSTK)
  5218.     {
  5219.         /* If we're still here at this point and the mightBeSTK flag is set,
  5220.         ** then it's most likely a proper The Ultimate SoundTracker (STK/UST) module.
  5221.         */
  5222.         modFormat = FORMAT_STK;
  5223.  
  5224.         if (h_MOD15.repS == 0)
  5225.             h_MOD15.repS = 120;
  5226.  
  5227.         // jjk55.mod by Jesper Kyd has a bogus STK tempo value that should be ignored
  5228.         if (!strcmp("jjk55", h_MOD31.name))
  5229.             h_MOD15.repS = 120;
  5230.  
  5231.         // The "restart pos" field in STK is the inital tempo (must be converted to BPM first)
  5232.         if (h_MOD15.repS != 120) // 120 is a special case and means 50Hz (125BPM)
  5233.         {
  5234.             if (h_MOD15.repS > 220)
  5235.                 h_MOD15.repS = 220;
  5236.  
  5237.             // convert UST tempo to BPM
  5238.             uint16_t ciaPeriod = (240 - song.repS) * 122;
  5239.             double dHz = 709379.0 / ciaPeriod;
  5240.             int32_t BPM = (int32_t)((dHz * (125.0 / 50.0)) + 0.5);
  5241.  
  5242.             song.initialSpeed = (uint16_t)BPM;
  5243.         }
  5244.  
  5245.         song.repS = 0;
  5246.     }
  5247.     else if (song.repS >= song.len)
  5248.     {
  5249.         song.repS = 0;
  5250.     }
  5251.  
  5252.     // trim off spaces at end of name
  5253.     for (i = 19; i >= 0; i--)
  5254.     {
  5255.         if (h_MOD31.name[i] == ' ' || h_MOD31.name[i] == 0x1A)
  5256.             h_MOD31.name[i] = '\0';
  5257.         else
  5258.             break;
  5259.     }
  5260.  
  5261.     memcpy(song.name, h_MOD31.name, 20);
  5262.     song.name[20] = '\0';
  5263.  
  5264.     // count number of patterns
  5265.     b = 0;
  5266.     for (a = 0; a < 128; a++)
  5267.     {
  5268.         if (song.songTab[a] > b)
  5269.             b = song.songTab[a];
  5270.     }
  5271.     b++;
  5272.  
  5273.     for (a = 0; a < b; a++)
  5274.     {
  5275.         patt[a] = (tonTyp *)calloc(64 * song.antChn, sizeof (tonTyp));
  5276.         if (patt[a] == NULL)
  5277.             goto modLoadError;
  5278.  
  5279.         pattLens[a] = 64;
  5280.         for (j = 0; j < 64; j++)
  5281.         {
  5282.             for (k = 0; k < song.antChn; k++)
  5283.             {
  5284.                 ton = &patt[a][(j * song.antChn) + k];
  5285.  
  5286.                 if (mread(bytes, 1, 4, f) != 4)
  5287.                     goto modLoadError;
  5288.  
  5289.                 // period to note
  5290.                 period = ((bytes[0] & 0x0F) << 8) | bytes[1];
  5291.                 for (i = 0; i < 8*12; i++)
  5292.                 {
  5293.                     if (period >= amigaPeriod[i])
  5294.                     {
  5295.                         ton->ton = (uint8_t)i + 1;
  5296.                         break;
  5297.                     }
  5298.                 }
  5299.  
  5300.                 ton->instr = (bytes[0] & 0xF0) | (bytes[2] >> 4);
  5301.                 ton->effTyp = bytes[2] & 0x0F;
  5302.                 ton->eff = bytes[3];
  5303.  
  5304.                 if (mightBeSTK)
  5305.                 {
  5306.                     if (ton->effTyp == 0xC || ton->effTyp == 0xD || ton->effTyp == 0xE)
  5307.                     {
  5308.                         // "TJC SoundTracker II" and later
  5309.                         lateSTKVerFlag = true;
  5310.                     }
  5311.  
  5312.                     if (ton->effTyp == 0xF)
  5313.                     {
  5314.                         // "DFJ SoundTracker III" and later
  5315.                         lateSTKVerFlag = true;
  5316.                         veryLateSTKVerFlag = true;
  5317.                     }
  5318.                 }
  5319.  
  5320.                 if (ton->effTyp == 0xC)
  5321.                 {
  5322.                     if (ton->eff > 64)
  5323.                         ton->eff = 64;
  5324.                 }
  5325.                 else if (ton->effTyp == 0x1)
  5326.                 {
  5327.                     if (ton->eff == 0)
  5328.                         ton->effTyp = 0;
  5329.                 }
  5330.                 else if (ton->effTyp == 0x2)
  5331.                 {
  5332.                     if (ton->eff == 0)
  5333.                         ton->effTyp = 0;
  5334.                 }
  5335.                 else if (ton->effTyp == 0x5)
  5336.                 {
  5337.                     if (ton->eff == 0)
  5338.                         ton->effTyp = 0x3;
  5339.                 }
  5340.                 else if (ton->effTyp == 0x6)
  5341.                 {
  5342.                     if (ton->eff == 0)
  5343.                         ton->effTyp = 0x4;
  5344.                 }
  5345.                 else if (ton->effTyp == 0xA)
  5346.                 {
  5347.                     if (ton->eff == 0)
  5348.                         ton->effTyp = 0;
  5349.                 }
  5350.                 else if (ton->effTyp == 0xE)
  5351.                 {
  5352.                     // check if certain E commands are empty
  5353.                     if (ton->eff == 0x10 || ton->eff == 0x20 || ton->eff == 0xA0 || ton->eff == 0xB0)
  5354.                     {
  5355.                         ton->effTyp = 0;
  5356.                         ton->eff = 0;
  5357.                     }
  5358.                 }
  5359.             }
  5360.         }
  5361.  
  5362.         if (patternEmpty(a))
  5363.         {
  5364.             if (patt[a] != NULL)
  5365.             {
  5366.                 free(patt[a]);
  5367.                 patt[a] = NULL;
  5368.             }
  5369.         }
  5370.     }
  5371.  
  5372.     // pattern command conversion for non-PT formats
  5373.     if (modFormat == FORMAT_STK || modFormat == FORMAT_FT2 || modFormat == FORMAT_NT || modFormat == FORMAT_HMNT || modFormat == FORMAT_FLT)
  5374.     {
  5375.         for (a = 0; a < b; a++)
  5376.         {
  5377.             if (patt[a] == NULL)
  5378.                 continue;
  5379.  
  5380.             for (j = 0; j < 64; j++)
  5381.             {
  5382.                 for (k = 0; k < song.antChn; k++)
  5383.                 {
  5384.                     ton = &patt[a][(j * song.antChn) + k];
  5385.  
  5386.                     if (modFormat == FORMAT_NT || modFormat == FORMAT_HMNT)
  5387.                     {
  5388.                         // any Dxx == D00 in NT/HMNT
  5389.                         if (ton->effTyp == 0xD)
  5390.                             ton->eff = 0;
  5391.  
  5392.                         // effect F with param 0x00 does nothing in NT/HMNT
  5393.                         if (ton->effTyp == 0xF && ton->eff == 0)
  5394.                             ton->effTyp = 0;
  5395.                     }
  5396.                     else if (modFormat == FORMAT_FLT) // Startrekker
  5397.                     {
  5398.                         if (ton->effTyp == 0xE) // remove unsupported "assembly macros" command
  5399.                         {
  5400.                             ton->effTyp = 0;
  5401.                             ton->eff = 0;
  5402.                         }
  5403.  
  5404.                         // Startrekker is always in vblank mode, and limits speed to 0x1F
  5405.                         if (ton->effTyp == 0xF && ton->eff > 0x1F)
  5406.                             ton->eff = 0x1F;
  5407.                     }
  5408.                     else if (modFormat == FORMAT_STK)
  5409.                     {
  5410.                         // convert STK effects to PT effects
  5411.  
  5412.                         if (!lateSTKVerFlag)
  5413.                         {
  5414.                             // old SoundTracker 1.x commands
  5415.  
  5416.                             if (ton->effTyp == 1)
  5417.                             {
  5418.                                 // arpeggio
  5419.                                 ton->effTyp = 0;
  5420.                             }
  5421.                             else if (ton->effTyp == 2)
  5422.                             {
  5423.                                 // pitch slide
  5424.                                 if (ton->eff & 0xF0)
  5425.                                 {
  5426.                                     // pitch slide down
  5427.                                     ton->effTyp = 2;
  5428.                                     ton->eff >>= 4;
  5429.                                 }
  5430.                                 else if (ton->eff & 0x0F)
  5431.                                 {
  5432.                                     // pitch slide up
  5433.                                     ton->effTyp = 1;
  5434.                                 }
  5435.                             }
  5436.                         }
  5437.                         else
  5438.                         {
  5439.                             // "DFJ SoundTracker II" or later
  5440.  
  5441.                             if (ton->effTyp == 0xD)
  5442.                             {
  5443.                                 if (veryLateSTKVerFlag) // "DFJ SoundTracker III" or later
  5444.                                 {
  5445.                                     // pattern break w/ no param (param must be cleared to fix some songs)
  5446.                                     ton->eff = 0;
  5447.                                 }
  5448.                                 else
  5449.                                 {
  5450.                                     // volume slide
  5451.                                     ton->effTyp = 0xA;
  5452.                                 }
  5453.                             }
  5454.                         }
  5455.  
  5456.                         // effect F with param 0x00 does nothing in UST/STK (I think?)
  5457.                         if (ton->effTyp == 0xF && ton->eff == 0)
  5458.                             ton->effTyp = 0;
  5459.                     }
  5460.                 }
  5461.             }
  5462.         }
  5463.     }
  5464.  
  5465.     for (a = 0; a < ai; a++)
  5466.     {
  5467.         if (h_MOD31.instr[a].len == 0)
  5468.             continue;
  5469.  
  5470.         if (!allocateInstr(1+a))
  5471.             goto modLoadError;
  5472.  
  5473.         s = &instr[1+a]->samp[0];
  5474.  
  5475.         if (modFormat != FORMAT_HMNT) // most of "His Master's Noisetracker" songs have junk sample names, so let's not load them
  5476.         {
  5477.             // trim off spaces at end of name
  5478.             for (i = 21; i >= 0; i--)
  5479.             {
  5480.                 if (s->name[i] == ' ' || s->name[i] == 0x1A)
  5481.                     s->name[i] = '\0';
  5482.                 else
  5483.                     break;
  5484.             }
  5485.  
  5486.             memcpy(instr[1+a]->name, s->name, 22);
  5487.             instr[1+a]->name[22] = '\0';
  5488.         }
  5489.  
  5490.         s->len = 2 * SWAP16(h_MOD31.instr[a].len);
  5491.  
  5492.         s->pek = (int8_t *)malloc(s->len + LOOP_FIX_LEN);
  5493.         if (s->pek == NULL)
  5494.             goto modLoadError;
  5495.  
  5496.         if (modFormat == FORMAT_HMNT) // finetune in "His Master's NoiseTracker" is different
  5497.             h_MOD31.instr[a].fine = (uint8_t)((-h_MOD31.instr[a].fine & 0x1F) / 2); // one more bit of precision, + inverted
  5498.  
  5499.         if (modFormat != FORMAT_STK)
  5500.             s->fine = 8 * ((2 * ((h_MOD31.instr[a].fine & 0xF) ^ 8)) - 16);
  5501.  
  5502.         s->pan = 128;
  5503.  
  5504.         s->vol = h_MOD31.instr[a].vol;
  5505.         if (s->vol > 64)
  5506.             s->vol = 64;
  5507.  
  5508.         s->repS = 2 * SWAP16(h_MOD31.instr[a].repS);
  5509.         s->repL = 2 * SWAP16(h_MOD31.instr[a].repL);
  5510.  
  5511.         if (s->repL < 2)
  5512.             s->repL = 2;
  5513.  
  5514.         // in The Ultimate SoundTracker, sample loop start is in bytes, not words
  5515.         if (mightBeSTK)
  5516.             s->repS /= 2;
  5517.  
  5518.         // fix for poorly converted STK (< v2.5) -> PT/NT modules (FIXME: Worth keeping or not?)
  5519.         if (!mightBeSTK && s->repL > 2 && s->repS+s->repL > s->len)
  5520.         {
  5521.             if ((s->repS/2) + s->repL <= s->len)
  5522.                 s->repS /= 2;
  5523.         }
  5524.  
  5525.         // fix overflown loop
  5526.         if (s->repS+s->repL > s->len)
  5527.         {
  5528.             if (s->repS >= s->len)
  5529.             {
  5530.                 s->repS = 0;
  5531.                 s->repL = 0;
  5532.             }
  5533.             else
  5534.             {
  5535.                 s->repL = s->len - s->repS;
  5536.             }
  5537.         }
  5538.  
  5539.         if (s->repS+s->repL > 2)
  5540.             s->typ = 1; // enable loop
  5541.  
  5542.         /* For Ultimate SoundTracker modules, only the loop area of a looped sample is played.
  5543.         ** Skip loading of eventual data present before loop start.
  5544.         */
  5545.         if (modFormat == FORMAT_STK && (s->repS > 0 && s->repL < s->len))
  5546.         {
  5547.             s->len -= s->repS;
  5548.             mseek(f, s->repS, SEEK_CUR);
  5549.             s->repS = 0;
  5550.         }
  5551.  
  5552.         int32_t bytesRead = (int32_t)mread(s->pek, 1, s->len, f);
  5553.         if (bytesRead < s->len)
  5554.         {
  5555.             int32_t bytesToClear = s->len - bytesRead;
  5556.             memset(&s->pek[bytesRead], 0, bytesToClear);
  5557.         }
  5558.  
  5559.         fixSample(s);
  5560.     }
  5561.  
  5562.     mclose(&f);
  5563.  
  5564.     song.tempo = 6;
  5565.  
  5566.     note2Period = amigaPeriods;
  5567.  
  5568.     // instr 0 is a placeholder for empty instruments
  5569.     allocateInstr(0);
  5570.     instr[0]->samp[0].vol = 0;
  5571.  
  5572.     moduleLoaded = true;
  5573.     return true;
  5574.  
  5575. modLoadError:
  5576.     if (f != NULL)
  5577.         mclose(&f);
  5578.  
  5579.     freeAllPatterns();
  5580.     freeAllInstr();
  5581.  
  5582.     moduleLoaded = false;
  5583.     return false;
  5584. }
  5585.  
  5586. static bool loadMusic(const uint8_t *moduleData, uint32_t dataLength)
  5587. {
  5588.     uint16_t i;
  5589.     songHeaderTyp h;
  5590.     MEMFILE *f;
  5591.  
  5592.     freeAllInstr();
  5593.     freeAllPatterns();
  5594.     memset(&song, 0, sizeof (song));
  5595.  
  5596.     moduleLoaded = false;
  5597.  
  5598.     linearFrqTab = 0;
  5599.  
  5600.     f = mopen(moduleData, dataLength);
  5601.     if (f == NULL) return false;
  5602.  
  5603.     // start loading
  5604.     mread(&h, sizeof (h), 1, f);
  5605.  
  5606.     if (memcmp(h.sig, "Extended Module: ", 17) != 0)
  5607.         return loadMusicMOD(f, dataLength);
  5608.  
  5609.     if (h.ver < 0x0102 || h.ver > 0x104)
  5610.     {
  5611.         mclose(&f);
  5612.         return false;
  5613.     }
  5614.  
  5615.     if (h.len > 256 || h.antPtn > 256 || h.antChn == 0 || h.antChn > MAX_VOICES || h.antInstrs > 128)
  5616.     {
  5617.         mclose(&f);
  5618.         return false;
  5619.     }
  5620.  
  5621.     mseek(f, 60 + h.headerSize, SEEK_SET);
  5622.     if (meof(f))
  5623.     {
  5624.         mclose(&f);
  5625.         return false;
  5626.     }
  5627.  
  5628.     memcpy(song.name, h.name, 20);
  5629.     song.name[20] = '\0';
  5630.  
  5631.     song.len = h.len;
  5632.     song.repS = h.repS;
  5633.     song.antChn = (uint8_t)h.antChn;
  5634.     song.speed = h.defSpeed ? h.defSpeed : 125;
  5635.     song.tempo = h.defTempo ? h.defTempo : 6;
  5636.     song.ver = h.ver;
  5637.     linearFrqTab = h.flags & 1;
  5638.  
  5639.     song.speed = CLAMP(song.speed, 32, 255);
  5640.     if (song.tempo > 31)
  5641.         song.tempo = 31;
  5642.  
  5643.     if (song.globVol > 64)
  5644.         song.globVol = 64;
  5645.  
  5646.     if (song.len == 0)
  5647.         song.len = 1; // songTmp.songTab is already empty
  5648.     else
  5649.         memcpy(song.songTab, h.songTab, song.len);
  5650.  
  5651.     if (song.ver < 0x0104)
  5652.     {
  5653.         // old FT2 format
  5654.  
  5655.         for (i = 1; i <= h.antInstrs; i++)
  5656.         {
  5657.             if (!loadInstrHeader(f, i))
  5658.             {
  5659.                 freeAllInstr();
  5660.                 mclose(&f);
  5661.                 return false;
  5662.             }
  5663.         }
  5664.  
  5665.         if (!loadPatterns(f, h.antPtn))
  5666.         {
  5667.             freeAllInstr();
  5668.             mclose(&f);
  5669.             return false;
  5670.         }
  5671.  
  5672.         for (i = 1; i <= h.antInstrs; i++)
  5673.         {
  5674.             if (!loadInstrSample(f, i))
  5675.             {
  5676.                 freeAllInstr();
  5677.                 mclose(&f);
  5678.                 return false;
  5679.             }
  5680.         }
  5681.     }
  5682.     else
  5683.     {
  5684.         // current FT2 format
  5685.  
  5686.         if (!loadPatterns(f, h.antPtn))
  5687.         {
  5688.             mclose(&f);
  5689.             return false;
  5690.         }
  5691.  
  5692.         for (i = 1; i <= h.antInstrs; i++)
  5693.         {
  5694.             if (!loadInstrHeader(f, i))
  5695.             {
  5696.                 freeAllInstr();
  5697.                 mclose(&f);
  5698.                 return false;
  5699.             }
  5700.  
  5701.             if (!loadInstrSample(f, i))
  5702.             {
  5703.                 freeAllInstr();
  5704.                 mclose(&f);
  5705.                 return false;
  5706.             }
  5707.         }
  5708.     }
  5709.  
  5710.     mclose(&f);
  5711.  
  5712.     note2Period = linearFrqTab ? linearPeriods : amigaPeriods;
  5713.  
  5714.     if (song.repS > song.len)
  5715.         song.repS = 0;
  5716.  
  5717.     song.initialSpeed = song.speed;
  5718.  
  5719.     // instr 0 is a placeholder for empty instruments
  5720.     allocateInstr(0);
  5721.     instr[0]->samp[0].vol = 0;
  5722.  
  5723.     moduleLoaded = true;
  5724.     return true;
  5725. }
  5726.  
  5727. void ft2play_SetMasterVol(uint16_t vol)
  5728. {
  5729.     if (vol > 256)
  5730.         vol = 256;
  5731.  
  5732.     masterVol = vol;
  5733.  
  5734.     if (masterAmp == 0)
  5735.         masterAmp = 10; // default;
  5736.  
  5737.     mixingVol = masterVol * masterAmp * 2048;
  5738. }
  5739.  
  5740. uint16_t ft2play_GetMasterVol(void)
  5741. {
  5742.     return (uint16_t)masterVol;
  5743. }
  5744.  
  5745. void ft2play_SetAmp(uint8_t ampFactor)
  5746. {
  5747.     ampFactor = CLAMP(ampFactor, 1, 32);
  5748.     masterAmp = ampFactor;
  5749.  
  5750.     if (masterVol == 0)
  5751.         masterVol = 256; // default;
  5752.  
  5753.     mixingVol = masterVol * masterAmp * 2048;
  5754. }
  5755.  
  5756. uint8_t ft2play_GetAmp(void)
  5757. {
  5758.     return (uint8_t)masterAmp;
  5759. }
  5760.  
  5761. void ft2play_SetInterpolation(bool flag)
  5762. {
  5763.     interpolationFlag = flag;
  5764.     stopVoices();
  5765. }
  5766.  
  5767. void ft2play_SetVolumeRamping(bool flag)
  5768. {
  5769.     volumeRampingFlag = flag;
  5770.     stopVoices();
  5771. }
  5772.  
  5773. char *ft2play_GetSongName(void)
  5774. {
  5775.     return song.name;
  5776. }
  5777.  
  5778. static inline uint32_t random32(void)
  5779. {
  5780.     // LCG 32-bit random
  5781.     randSeed *= 134775813;
  5782.     randSeed++;
  5783.  
  5784.     return randSeed;
  5785. }
  5786.  
  5787. static void mixAudio(int16_t *stream, int32_t sampleBlockLength)
  5788. {
  5789.     int32_t i, out32, prng;
  5790.     voice_t *v, *r;
  5791.  
  5792.     if (musicPaused)
  5793.     {
  5794.         memset(stream, 0, sampleBlockLength * sizeof (int16_t) * 2);
  5795.         return;
  5796.     }
  5797.  
  5798.     memset(mixBufferL, 0, sampleBlockLength * sizeof (int32_t));
  5799.     memset(mixBufferR, 0, sampleBlockLength * sizeof (int32_t));
  5800.  
  5801.     // mix channels
  5802.  
  5803.     v = voice; // normal voices
  5804.     r = &voice[MAX_VOICES]; // volume ramp voices
  5805.  
  5806.     for (i = 0; i < song.antChn; i++, v++, r++)
  5807.     {
  5808.         // call the mixing routine currently set for the voice
  5809.         if (v->mixRoutine != NULL) v->mixRoutine(v, sampleBlockLength); // mix normal voice
  5810.         if (r->mixRoutine != NULL) r->mixRoutine(r, sampleBlockLength); // mix volume ramp voice
  5811.     }
  5812.  
  5813.     for (i = 0; i < sampleBlockLength; i++)
  5814.     {
  5815.         // left channel - 1-bit triangular dithering
  5816.         prng = random32();
  5817.         out32 = ((((int64_t)mixBufferL[i] * mixingVol) + prng) - prngStateL) >> 32;
  5818.         prngStateL = prng;
  5819.         CLAMP16(out32);
  5820.         *stream++ = (int16_t)out32;
  5821.  
  5822.         // right channel - 1-bit triangular dithering
  5823.         prng = random32();
  5824.         out32 = ((((int64_t)mixBufferR[i] * mixingVol) + prng) - prngStateR) >> 32;
  5825.         prngStateR = prng;
  5826.         CLAMP16(out32);
  5827.         *stream++ = (int16_t)out32;
  5828.     }
  5829. }
  5830.  
  5831. static bool ft2play_FillAudioBuffer(int16_t *buffer, uint16_t samples)
  5832. {
  5833.     int32_t a, b;
  5834.  
  5835.     // this must NOT exceed 65535 because of possible overflow in mixer
  5836.     if (samples > 65535)
  5837.         return false;
  5838.  
  5839.     a = samples;
  5840.     while (a > 0)
  5841.     {
  5842.         if (pmpLeft == 0)
  5843.         {
  5844.             // new replayer tick
  5845.             if (!musicPaused)
  5846.             {
  5847.                 if (volumeRampingFlag)
  5848.                     mix_SaveIPVolumes();
  5849.  
  5850.                 mainPlayer();
  5851.                 mix_UpdateChannelVolPanFrq();
  5852.             }
  5853.  
  5854.             pmpLeft = speedVal;
  5855.         }
  5856.  
  5857.         b = a;
  5858.         if (b > pmpLeft)
  5859.             b = pmpLeft;
  5860.  
  5861.         mixAudio(buffer, b);
  5862.         buffer += (uint32_t)b * 2;
  5863.  
  5864.         a -= b;
  5865.         pmpLeft -= b;
  5866.     }
  5867.  
  5868.     sampleCounter += samples;
  5869.     return true;
  5870. }
  5871.  
  5872. void ft2play_Close(void)
  5873. {
  5874.     closeMixer();
  5875.  
  5876.     freeAllInstr();
  5877.     freeAllPatterns();
  5878.  
  5879.     if (mixBufferL != NULL)
  5880.     {
  5881.         free(mixBufferL);
  5882.         mixBufferL = NULL;
  5883.     }
  5884.  
  5885.     if (mixBufferR != NULL)
  5886.     {
  5887.         free(mixBufferR);
  5888.         mixBufferR = NULL;
  5889.     }
  5890.  
  5891.     if (logTab != NULL)
  5892.     {
  5893.         free(logTab);
  5894.         logTab = NULL;
  5895.     }
  5896.  
  5897.     if (vibSineTab != NULL)
  5898.     {
  5899.         free(vibSineTab);
  5900.         vibSineTab = NULL;
  5901.     }
  5902.  
  5903.     if (amigaPeriods != NULL)
  5904.     {
  5905.         free(amigaPeriods);
  5906.         amigaPeriods = NULL;
  5907.     }
  5908.  
  5909.     if (linearPeriods != NULL)
  5910.     {
  5911.         free(linearPeriods);
  5912.         linearPeriods = NULL;
  5913.     }
  5914. }
  5915.  
  5916. void ft2play_PauseSong(bool flag)
  5917. {
  5918.     musicPaused = flag;
  5919. }
  5920.  
  5921. void ft2play_TogglePause(void)
  5922. {
  5923.     musicPaused ^= 1;
  5924. }
  5925.  
  5926. uint32_t ft2play_GetMixerTicks(void)
  5927. {
  5928.     if (realReplayRate < 1000)
  5929.         return 0;
  5930.  
  5931.     return sampleCounter / (realReplayRate / 1000);
  5932. }
  5933.  
  5934. bool ft2play_PlaySong(const uint8_t *moduleData, uint32_t dataLength, bool useInterpolationFlag, bool useVolumeRampingFlag, uint32_t audioFreq)
  5935. {
  5936.     int16_t noteVal;
  5937.     uint16_t i, k;
  5938.  
  5939.     if (audioFreq == 0)
  5940.         audioFreq = 44100;
  5941.  
  5942.     audioFreq = CLAMP(audioFreq, 11025, 96000);
  5943.  
  5944.     musicPaused = true;
  5945.  
  5946.     ft2play_Close();
  5947.     memset(song.name, 0, sizeof (song.name));
  5948.  
  5949.     sampleCounter = 0;
  5950.  
  5951.     // initialize replayer and mixer
  5952.  
  5953.     mixBufferL = (int32_t *)malloc(MIX_BUF_SAMPLES * sizeof (int32_t));
  5954.     mixBufferR = (int32_t *)malloc(MIX_BUF_SAMPLES * sizeof (int32_t));
  5955.  
  5956.     if (mixBufferL == NULL || mixBufferR == NULL)
  5957.     {
  5958.         ft2play_Close();
  5959.         return false;
  5960.     }
  5961.  
  5962.     // allocate memory for pointers
  5963.  
  5964.     if (linearPeriods == NULL)
  5965.         linearPeriods = (int16_t *)malloc(sizeof (int16_t) * ((12 * 10 * 16) + 16));
  5966.  
  5967.     if (amigaPeriods == NULL)
  5968.         amigaPeriods = (int16_t *)malloc(sizeof (int16_t) * ((12 * 10 * 16) + 16));
  5969.  
  5970.     if (vibSineTab == NULL)
  5971.         vibSineTab = (int8_t *)malloc(256);
  5972.  
  5973.     if (logTab == NULL)
  5974.         logTab = (uint32_t *)malloc(sizeof (uint32_t) * 768);
  5975.  
  5976.     if (linearPeriods == NULL || amigaPeriods == NULL || vibSineTab == NULL || logTab == NULL)
  5977.     {
  5978.         ft2play_Close();
  5979.         return false;
  5980.     }
  5981.  
  5982.     // generate tables, bit-exact to original FT2
  5983.  
  5984.     // log table
  5985.     for (i = 0; i < 768; i++)
  5986.         logTab[i] = (uint32_t)round(16777216.0 * exp((i / 768.0) * M_LN2));
  5987.  
  5988.     // linear table
  5989.     for (i = 0; i < (12*10*16)+16; i++)
  5990.         linearPeriods[i] = (((12 * 10 * 16) + 16) * 4) - (i * 4);
  5991.  
  5992.     /* amiga period table
  5993.     ** This has a LUT read overflow in real FT2 making the last 17 values trash. We patch those later. */
  5994.     k = 0;
  5995.     for (i = 0; i < 10; i++)
  5996.     {
  5997.         for (uint16_t j = 0; j < 96; j++)
  5998.         {
  5999.             noteVal = ((amigaFinePeriod[j] * 64) + (-1 + (1 << i))) >> (i + 1);
  6000.  
  6001.             amigaPeriods[k++] = noteVal;
  6002.             amigaPeriods[k++] = noteVal; // copy for interpolation applied later
  6003.         }
  6004.     }
  6005.  
  6006.     // interpolate between points
  6007.     for (i = 0; i < (12*10*8)+7; i++)
  6008.         amigaPeriods[(i * 2) + 1] = (amigaPeriods[i * 2] + amigaPeriods[(i * 2) + 2]) / 2;
  6009.  
  6010.     // the following 17 values are confirmed to be the correct table LUT overflow values in real FT2
  6011.     amigaPeriods[1919] = 22; amigaPeriods[1920] = 16; amigaPeriods[1921] =  8; amigaPeriods[1922] =  0;
  6012.     amigaPeriods[1923] = 16; amigaPeriods[1924] = 32; amigaPeriods[1925] = 24; amigaPeriods[1926] = 16;
  6013.     amigaPeriods[1927] =  8; amigaPeriods[1928] =  0; amigaPeriods[1929] = 16; amigaPeriods[1930] = 32;
  6014.     amigaPeriods[1931] = 24; amigaPeriods[1932] = 16; amigaPeriods[1933] =  8; amigaPeriods[1934] =  0;
  6015.     amigaPeriods[1935] =  0;
  6016.  
  6017.     // generate auto-vibrato table (value-exact to FT2's table)
  6018.     for (i = 0; i < 256; i++)
  6019.         vibSineTab[i] = (int8_t)round(64.0 * sin((-i * (2.0 * M_PI)) / 256.0));
  6020.  
  6021.     if (!loadMusic(moduleData, dataLength))
  6022.     {
  6023.         ft2play_Close();
  6024.         return false;
  6025.     }
  6026.  
  6027.     realReplayRate = audioFreq;
  6028.     soundBufferSize = MIX_BUF_SAMPLES * 4; // samples -> bytes
  6029.     interpolationFlag = useInterpolationFlag ? true : false;
  6030.     volumeRampingFlag = useVolumeRampingFlag ? true : false;
  6031.  
  6032.     // for voice delta calculation
  6033.     frequenceDivFactor = (uint32_t)round(65536.0 * 1712.0 / realReplayRate * 8363.0);
  6034.     frequenceMulFactor = (uint32_t)round(256.0 * 65536.0 / realReplayRate * 8363.0);
  6035.  
  6036.     // for volume ramping
  6037.     quickVolSizeVal = realReplayRate / 200;
  6038.  
  6039.     ft2play_SetAmp(10);
  6040.     ft2play_SetMasterVol(256);
  6041.  
  6042.     stopVoices();
  6043.  
  6044.     song.globVol = 64;
  6045.  
  6046.     if (song.initialSpeed == 0)
  6047.         song.initialSpeed = 125;
  6048.  
  6049.     setSpeed(song.initialSpeed);
  6050.  
  6051.     setPos(0, 0);
  6052.     songPlaying = true;
  6053.  
  6054.     if (!openMixer(realReplayRate))
  6055.     {
  6056.         ft2play_Close();
  6057.         return false;
  6058.     }
  6059.  
  6060.     randSeed = INITIAL_DITHER_SEED;
  6061.     prngStateL = 0;
  6062.     prngStateR = 0;
  6063.  
  6064.     musicPaused = false;
  6065.     return true;
  6066. }
  6067.  
  6068. static MEMFILE *mopen(const uint8_t *src, uint32_t length)
  6069. {
  6070.     MEMFILE *b;
  6071.  
  6072.     if (src == NULL || length == 0)
  6073.         return NULL;
  6074.  
  6075.     b = (MEMFILE *)malloc(sizeof (MEMFILE));
  6076.     if (b == NULL)
  6077.         return NULL;
  6078.  
  6079.     b->_base = (uint8_t *)src;
  6080.     b->_ptr = (uint8_t *)src;
  6081.     b->_cnt = length;
  6082.     b->_bufsiz = length;
  6083.     b->_eof = false;
  6084.  
  6085.     return b;
  6086. }
  6087.  
  6088. static void mclose(MEMFILE **buf)
  6089. {
  6090.     if (*buf != NULL)
  6091.     {
  6092.         free(*buf);
  6093.         *buf = NULL;
  6094.     }
  6095. }
  6096.  
  6097. static size_t mread(void *buffer, size_t size, size_t count, MEMFILE *buf)
  6098. {
  6099.     size_t wrcnt;
  6100.     int32_t pcnt;
  6101.  
  6102.     if (buf == NULL || buf->_ptr == NULL)
  6103.         return 0;
  6104.  
  6105.     wrcnt = size * count;
  6106.     if (size == 0 || buf->_eof)
  6107.         return 0;
  6108.  
  6109.     pcnt = ((uint32_t)buf->_cnt > wrcnt) ? wrcnt : buf->_cnt;
  6110.     memcpy(buffer, buf->_ptr, pcnt);
  6111.  
  6112.     buf->_cnt -= pcnt;
  6113.     buf->_ptr += pcnt;
  6114.  
  6115.     if (buf->_cnt <= 0)
  6116.     {
  6117.         buf->_ptr = buf->_base + buf->_bufsiz;
  6118.         buf->_cnt = 0;
  6119.         buf->_eof = true;
  6120.     }
  6121.  
  6122.     return pcnt / size;
  6123. }
  6124.  
  6125. static bool meof(MEMFILE *buf)
  6126. {
  6127.     if (buf == NULL)
  6128.         return true;
  6129.  
  6130.     return buf->_eof;
  6131. }
  6132.  
  6133. static void mseek(MEMFILE *buf, int32_t offset, int32_t whence)
  6134. {
  6135.     if (buf == NULL)
  6136.         return;
  6137.  
  6138.     if (buf->_base)
  6139.     {
  6140.         switch (whence)
  6141.         {
  6142.             case SEEK_SET: buf->_ptr = buf->_base + offset; break;
  6143.             case SEEK_CUR: buf->_ptr += offset; break;
  6144.             case SEEK_END: buf->_ptr = buf->_base + buf->_bufsiz + offset; break;
  6145.             default: break;
  6146.         }
  6147.  
  6148.         buf->_eof = false;
  6149.         if (buf->_ptr >= buf->_base+buf->_bufsiz)
  6150.         {
  6151.             buf->_ptr = buf->_base + buf->_bufsiz;
  6152.             buf->_eof = true;
  6153.         }
  6154.  
  6155.         buf->_cnt = (buf->_base + buf->_bufsiz) - buf->_ptr;
  6156.     }
  6157. }
  6158.  
  6159. static void mrewind(MEMFILE *buf)
  6160. {
  6161.     mseek(buf, 0, SEEK_SET);
  6162. }
  6163.  
  6164.  
  6165. // the following must be changed if you want to use another audio API than WinMM
  6166.  
  6167. #ifndef WIN32_LEAN_AND_MEAN
  6168. #define WIN32_LEAN_AND_MEAN
  6169. #endif
  6170.  
  6171. #include <windows.h>
  6172. #include <mmsystem.h>
  6173.  
  6174. #define MIX_BUF_NUM 2
  6175.  
  6176. static volatile BOOL audioRunningFlag;
  6177. static uint8_t currBuffer;
  6178. static int16_t *mixBuffer[MIX_BUF_NUM];
  6179. static HANDLE hThread, hAudioSem;
  6180. static WAVEHDR waveBlocks[MIX_BUF_NUM];
  6181. static HWAVEOUT hWave;
  6182.  
  6183. static DWORD WINAPI mixThread(LPVOID lpParam)
  6184. {
  6185.     WAVEHDR *waveBlock;
  6186.  
  6187.     (void)lpParam;
  6188.  
  6189.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
  6190.  
  6191.     while (audioRunningFlag)
  6192.     {
  6193.         waveBlock = &waveBlocks[currBuffer];
  6194.         ft2play_FillAudioBuffer((int16_t *)waveBlock->lpData, MIX_BUF_SAMPLES);
  6195.         waveOutWrite(hWave, waveBlock, sizeof (WAVEHDR));
  6196.         currBuffer = (currBuffer + 1) % MIX_BUF_NUM;
  6197.  
  6198.         // wait for buffer fill request
  6199.         WaitForSingleObject(hAudioSem, INFINITE);
  6200.     }
  6201.  
  6202.     return 0;
  6203. }
  6204.  
  6205. static void CALLBACK waveProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
  6206. {
  6207.     (void)hWaveOut;
  6208.     (void)uMsg;
  6209.     (void)dwInstance;
  6210.     (void)dwParam1;
  6211.     (void)dwParam2;
  6212.  
  6213.     if (uMsg == WOM_DONE)
  6214.         ReleaseSemaphore(hAudioSem, 1, NULL);
  6215. }
  6216.  
  6217. static void closeMixer(void)
  6218. {
  6219.     int32_t i;
  6220.  
  6221.     audioRunningFlag = false; // make thread end when it's done
  6222.  
  6223.     if (hAudioSem != NULL)
  6224.         ReleaseSemaphore(hAudioSem, 1, NULL);
  6225.  
  6226.     if (hThread != NULL)
  6227.     {
  6228.         WaitForSingleObject(hThread, INFINITE);
  6229.         CloseHandle(hThread);
  6230.         hThread = NULL;
  6231.     }
  6232.  
  6233.     if (hAudioSem != NULL)
  6234.     {
  6235.         CloseHandle(hAudioSem);
  6236.         hAudioSem = NULL;
  6237.     }
  6238.  
  6239.     if (hWave != NULL)
  6240.     {
  6241.         waveOutReset(hWave);
  6242.  
  6243.         for (i = 0; i < MIX_BUF_NUM; i++)
  6244.         {
  6245.             if (waveBlocks[i].dwUser != 0xFFFF)
  6246.                 waveOutUnprepareHeader(hWave, &waveBlocks[i], sizeof (WAVEHDR));
  6247.         }
  6248.  
  6249.         waveOutClose(hWave);
  6250.         hWave = NULL;
  6251.     }
  6252.  
  6253.     for (i = 0; i < MIX_BUF_NUM; i++)
  6254.     {
  6255.         if (mixBuffer[i] != NULL)
  6256.         {
  6257.             free(mixBuffer[i]);
  6258.             mixBuffer[i] = NULL;
  6259.         }
  6260.     }
  6261. }
  6262.  
  6263. static bool openMixer(uint32_t audioFreq)
  6264. {
  6265.     int32_t i;
  6266.     DWORD threadID;
  6267.     WAVEFORMATEX wfx;
  6268.  
  6269.     // don't unprepare headers on error
  6270.     for (i = 0; i < MIX_BUF_NUM; i++)
  6271.         waveBlocks[i].dwUser = 0xFFFF;
  6272.  
  6273.     closeMixer();
  6274.  
  6275.     ZeroMemory(&wfx, sizeof (wfx));
  6276.     wfx.nSamplesPerSec = audioFreq;
  6277.     wfx.wBitsPerSample = 16;
  6278.     wfx.nChannels = 2;
  6279.     wfx.wFormatTag = WAVE_FORMAT_PCM;
  6280.     wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8);
  6281.     wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
  6282.  
  6283.     pmpLeft = 0;
  6284.     currBuffer = 0;
  6285.  
  6286.     if (waveOutOpen(&hWave, WAVE_MAPPER, &wfx, (DWORD_PTR)&waveProc, 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
  6287.         goto omError;
  6288.  
  6289.     // create semaphore for buffer fill requests
  6290.     hAudioSem = CreateSemaphore(NULL, MIX_BUF_NUM - 1, MIX_BUF_NUM, NULL);
  6291.     if (hAudioSem == NULL)
  6292.         goto omError;
  6293.  
  6294.     // allocate WinMM mix buffers
  6295.     for (i = 0; i < MIX_BUF_NUM; i++)
  6296.     {
  6297.         mixBuffer[i] = (int16_t *)calloc(MIX_BUF_SAMPLES, wfx.nBlockAlign);
  6298.         if (mixBuffer[i] == NULL)
  6299.             goto omError;
  6300.     }
  6301.  
  6302.     // initialize WinMM mix headers
  6303.     memset(waveBlocks, 0, sizeof (waveBlocks));
  6304.     for (i = 0; i < MIX_BUF_NUM; i++)
  6305.     {
  6306.         waveBlocks[i].lpData = (LPSTR)mixBuffer[i];
  6307.         waveBlocks[i].dwBufferLength = MIX_BUF_SAMPLES * wfx.nBlockAlign;
  6308.         waveBlocks[i].dwFlags = WHDR_DONE;
  6309.  
  6310.         if (waveOutPrepareHeader(hWave, &waveBlocks[i], sizeof (WAVEHDR)) != MMSYSERR_NOERROR)
  6311.             goto omError;
  6312.     }
  6313.  
  6314.     // create main mixer thread
  6315.     audioRunningFlag = true;
  6316.     hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)mixThread, NULL, 0, &threadID);
  6317.     if (hThread == NULL)
  6318.       &