daily pastebin goal
35%
SHARE
TWEET

ft2play v1.00

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