daily pastebin goal
2%
SHARE
TWEET

ft2play v0.98

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