Need a unique gift idea?
A Pastebin account makes a great Christmas gift
SHARE
TWEET

ft2play v0.97

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