daily pastebin goal
94%
SHARE
TWEET

ahx1play v0.27

8bitbubsy Oct 5th, 2017 (edited) 254 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ** AHX1PLAY v0.27 - 31st of October 2018 - https://16-bits.org
  3. ** ===========================================================
  4. **                 - NOT BIG ENDIAN SAFE! -
  5. **
  6. ** C port of AHX.cpp (Bartman of Abyss) by Olav "8bitbubsy" Sørensen.
  7. ** Includes additional fixes from hively tracker (current github code).
  8. **
  9. ** The BLEP (Band-Limited Step) and high-pass filter were coded by aciddose.
  10. ** This makes the replayer sound much similar to a real Amiga 1200.
  11. **
  12. ** You need to link winmm.lib for this to compile (-lwinmm).
  13. ** Alternatively, you can change out the mixer functions at the bottom with
  14. ** your own for your OS.
  15. **
  16. ** Example of ahx1play usage:
  17. ** #include "ahx1play.h"
  18. ** #include "songdata.h"
  19. **
  20. ** ahx1play_PlaySong(songData, songDataLength, 0, 44100);
  21. ** mainLoop();
  22. ** ahx1play_Close();
  23. **
  24. ** To turn a song into an include file like in the example, you can use my win32
  25. ** bin2h tool from here: https://16-bits.org/etc/bin2h.zip
  26. **
  27. ** Changes in v0.27:
  28. ** - Some code cleanup
  29. ** - Small optimziation to audio mixer
  30. **
  31. ** Changes in v0.26:
  32. ** - Added a function to retrieve song name
  33. **
  34. ** Changes in v0.25:
  35. ** - WinMM mixer has been rewritten to be safe (DON'T use syscalls in callback -MSDN)
  36. ** - Some small changes to the ahx1play functions (easier to use and safer!)
  37. */
  38.  
  39. /* ahx1play.h:
  40.  
  41. #ifndef __AHX1PLAY_H
  42. #define __AHX1PLAY_H
  43.  
  44. #include <stdint.h>
  45.  
  46. int8_t ahx1play_PlaySong(const uint8_t *moduleData, uint32_t dataLength, int32_t subSongNr, uint32_t audioFreq);
  47. void ahx1play_Close(void);
  48. void ahx1play_PauseSong(int8_t flag); // true/false
  49. void ahx1play_TogglePause(void);
  50. void ahx1play_SetStereoSep(uint8_t percentage); // 0..100
  51. char *ahx1play_GetSongName(void); // max 64 chars (65 with '\0'), string is in latin1
  52. uint32_t ahx1play_GetMixerTicks(void); // returns the amount of milliseconds of mixed audio (not realtime)
  53.  
  54. #endif
  55. */
  56.  
  57. /* == USER ADJUSTABLE SETTINGS == */
  58. #define STEREO_SEP (20)    /* --> Stereo separation in percent - 0 = mono, 100 = hard pan (like Amiga) */
  59. #define USE_HIGHPASS       /* --> 5.2Hz high-pass filter present in all Amigas - comment out for a speed-up */
  60. #define USE_BLEP           /* --> Reduces some unwanted aliasing (closer to real Amiga) - comment out to disable */
  61. #define MIX_BUF_SAMPLES 4096
  62.  
  63. #ifndef _USE_MATH_DEFINES
  64. #define _USE_MATH_DEFINES
  65. #endif
  66.  
  67. #ifdef _MSC_VER
  68. #define inline __forceinline
  69. #endif
  70.  
  71. #include <stdio.h>
  72. #include <stdlib.h>
  73. #include <string.h>
  74. #include <stdint.h>
  75. #include <stdbool.h>
  76. #include <math.h> /* tanf() */
  77.  
  78. #define PAULA_PAL_CLK 3546895
  79. #define AMIGA_VBLANK_RATE 50 /* 60 for NTSC replay speed */
  80. #define PAULA_VOICES 4
  81.  
  82. /* don't modify these defines! */
  83. #define NUM_WAVEFORMS (6 + 6 + 32 + 1)
  84. #define FILTER_ITERATIONS 31
  85.  
  86. /* BLEP CONSTANTS */
  87. #define BLEP_ZC 8
  88. #define BLEP_OS 5
  89. #define BLEP_SP 5
  90. #define BLEP_NS (BLEP_ZC * BLEP_OS / BLEP_SP)
  91. #define BLEP_RNS 7
  92.  
  93. /* STRUCTS */
  94. #ifdef USE_BLEP
  95. typedef struct blep_t
  96. {
  97.     int32_t index, samplesLeft;
  98.     float fBuffer[BLEP_RNS + 1], fLastValue;
  99. } blep_t;
  100. #endif
  101.  
  102. #define LERP(x, y, z) ((x) + ((y) - (x)) * (z))
  103. #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
  104.  
  105. #define CLAMP16(i) \
  106.     if ((int16_t)(i) != i) \
  107.         i = 0x7FFF ^ (i >> 31); \
  108.  
  109. typedef struct
  110. {
  111.     int16_t Note, Fixed, Waveform, FX[2], FXParam[2];
  112. } AHXPListEntry;
  113.  
  114. typedef struct
  115. {
  116.     int16_t Speed, Length;
  117.     AHXPListEntry *Entries;
  118. } AHXPList;
  119.  
  120. typedef struct
  121. {
  122.     int16_t aFrames, aVolume;
  123.     int16_t dFrames, dVolume;
  124.     int16_t sFrames;
  125.     int16_t rFrames, rVolume;
  126. } AHXEnvelope;
  127.  
  128. typedef struct
  129. {
  130.     char *Name;
  131.     int16_t Volume, WaveLength;
  132.     int16_t FilterLowerLimit, FilterUpperLimit, FilterSpeed;
  133.     int16_t SquareLowerLimit, SquareUpperLimit, SquareSpeed;
  134.     int16_t VibratoDelay, VibratoDepth, VibratoSpeed;
  135.     int16_t HardCutRelease, HardCutReleaseFrames;
  136.     AHXEnvelope Envelope;
  137.     AHXPList PList;
  138. } AHXInstrument;
  139.  
  140. typedef struct
  141. {
  142.     int16_t Track[PAULA_VOICES], Transpose[PAULA_VOICES];
  143. } AHXPosition;
  144.  
  145. typedef struct
  146. {
  147.     int16_t Note, Instrument, FX, FXParam;
  148. } AHXStep;
  149.  
  150. typedef struct
  151. {
  152.     int8_t VoiceBuffer[0x280], SquareTempBuffer[0x80], *AudioPointer, *AudioSource;
  153.     int16_t InstrPeriod, TrackPeriod, VibratoPeriod;
  154.     int16_t VoiceVolume, VoicePeriod;
  155.     int16_t Track, Transpose;
  156.     int16_t NextTrack, NextTranspose;
  157.     int16_t ADSRVolume;
  158.     int16_t NoteMaxVolume, PerfSubVolume, TrackMasterVolume;
  159.     int16_t NewWaveform, Waveform, PlantSquare, PlantPeriod, IgnoreSquare;
  160.     int16_t TrackOn, FixedNote;
  161.     int16_t VolumeSlideUp, VolumeSlideDown;
  162.     int16_t HardCut, HardCutRelease, HardCutReleaseF;
  163.     int16_t PeriodSlideSpeed, PeriodSlidePeriod, PeriodSlideLimit, PeriodSlideOn, PeriodSlideWithLimit;
  164.     int16_t PeriodPerfSlideSpeed, PeriodPerfSlidePeriod, PeriodPerfSlideOn;
  165.     int16_t VibratoDelay, VibratoCurrent, VibratoDepth, VibratoSpeed;
  166.     int16_t SquareOn, SquareInit, SquareWait, SquareLowerLimit, SquareUpperLimit, SquarePos, SquareSign, SquareSlidingIn, SquareReverse;
  167.     int16_t FilterOn, FilterInit, FilterWait, FilterLowerLimit, FilterUpperLimit, FilterPos, FilterSign, FilterSpeed, FilterSlidingIn, IgnoreFilter;
  168.     int16_t PerfCurrent, PerfSpeed, PerfWait;
  169.     int16_t WaveLength;
  170.     int16_t NoteDelayWait, NoteDelayOn, NoteCutWait, NoteCutOn;
  171.     int16_t AudioPeriod, AudioVolume;
  172.     AHXEnvelope ADSR;
  173.     AHXInstrument *Instrument;
  174.     AHXPList *PerfList;
  175. } AHXVoice;
  176.  
  177. static struct
  178. {
  179.     char *Name;
  180.     int16_t *Subsongs;
  181.     int16_t Restart, PositionNr, TrackLength, TrackNr, InstrumentNr, SubsongNr;
  182.     int16_t Revision, SpeedMultiplier;
  183.     AHXPosition *Positions;
  184.     AHXStep **Tracks;
  185.     AHXInstrument *Instruments;
  186. } Song;
  187.  
  188. static struct
  189. {
  190.     int8_t LowPasses[(0xFC + 0xFC + 0x80 * 0x1F + 0x80 + 3 * 0x280) * FILTER_ITERATIONS];
  191.     int8_t Triangle04[0x04], Triangle08[0x08], Triangle10[0x10], Triangle20[0x20], Triangle40[0x40], Triangle80[0x80];
  192.     int8_t Sawtooth04[0x04], Sawtooth08[0x08], Sawtooth10[0x10], Sawtooth20[0x20], Sawtooth40[0x40], Sawtooth80[0x80];
  193.     int8_t Squares[0x80 * 32];
  194.     int8_t WhiteNoiseBig[0x280 * 3];
  195.     int8_t HighPasses[(0xFC + 0xFC + 0x80 * 0x1F + 0x80 + 3 * 0x280) * FILTER_ITERATIONS];
  196. } Waves;
  197.  
  198. typedef struct paulaVoice_t
  199. {
  200.     volatile uint8_t active;
  201.     const int8_t *newData, *currData;
  202.     int32_t newLength, currLength, readPos;
  203.     float fVolume, fDelta, fPhase, fPanL, fPanR;
  204. #ifdef USE_BLEP
  205.     float fLastDelta, fLastFrac;
  206. #endif
  207. } paulaVoice_t;
  208.  
  209. #if defined(USE_HIGHPASS)
  210. typedef struct lossyIntegrator_t
  211. {
  212.     float fBuffer[2], fCoeff[2];
  213. } lossyIntegrator_t;
  214. #endif
  215.  
  216. static char songName[64 + 1];
  217. static int8_t *WaveformTab[4], musicPaused;
  218. static uint8_t stereoSep = STEREO_SEP;
  219. static const int16_t midFilterTable[31 * (6 + 6 + 0x20 + 1)], lowFilterTable[31 * (6 + 6 + 0x20 + 1)];
  220. static int16_t StepWaitFrames, GetNewPosition, SongEndReached, PatternBreak, MaxTrack;
  221. static int16_t MainVolume, Tempo, PosNr, PosJump, NoteNr, PosJumpNote;
  222. static int16_t soundBufferSize, samplesPerFrame, samplesPerFrameLeft;
  223. static int32_t WNRandom;
  224. static uint32_t audioRate, sampleCounter;
  225. static float fAudioRate, *fMixerBufferL, *fMixerBufferR;
  226. static paulaVoice_t paula[PAULA_VOICES];
  227. static AHXVoice Voices[PAULA_VOICES];
  228. #ifdef USE_BLEP
  229. static blep_t blep[PAULA_VOICES], blepVol[PAULA_VOICES];
  230. #endif
  231. #ifdef USE_HIGHPASS
  232. static lossyIntegrator_t filterHi;
  233. #endif
  234.  
  235. static const int8_t Offsets[6] = { 0x00, 0x04, 0x04+0x08, 0x04+0x08+0x10, 0x04+0x08+0x10+0x20, 0x04+0x08+0x10+0x20+0x40 };
  236.  
  237. static const uint16_t waveformLen[NUM_WAVEFORMS] =
  238. {
  239.     0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* sawtooth */
  240.     0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* triangle */
  241.  
  242.     /* squarewave */
  243.     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  244.     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  245.     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  246.     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  247.  
  248.     0x280 * 3 /* whitenoise */
  249. };
  250.  
  251. static const int16_t VibratoTable[64] =
  252. {
  253.     0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255,
  254.     253,250,244,235,224,212,197,180,161,141,120,97,74,49,24,
  255.     0,-24,-49,-74,-97,-120,-141,-161,-180,-197,-212,-224,-235,-244,-250,-253,-255,
  256.     -253,-250,-244,-235,-224,-212,-197,-180,-161,-141,-120,-97,-74,-49,-24
  257. };
  258.  
  259. static const int16_t PeriodTable[1 + (5 * 12)] =
  260. {
  261.     0x0000, 0x0D60, 0x0CA0, 0x0BE8, 0x0B40, 0x0A98, 0x0A00, 0x0970,
  262.     0x08E8, 0x0868, 0x07F0, 0x0780, 0x0714, 0x06B0, 0x0650, 0x05F4,
  263.     0x05A0, 0x054C, 0x0500, 0x04B8, 0x0474, 0x0434, 0x03F8, 0x03C0,
  264.     0x038A, 0x0358, 0x0328, 0x02FA, 0x02D0, 0x02A6, 0x0280, 0x025C,
  265.     0x023A, 0x021A, 0x01FC, 0x01E0, 0x01C5, 0x01AC, 0x0194, 0x017D,
  266.     0x0168, 0x0153, 0x0140, 0x012E, 0x011D, 0x010D, 0x00FE, 0x00F0,
  267.     0x00E2, 0x00D6, 0x00CA, 0x00BE, 0x00B4, 0x00AA, 0x00A0, 0x0097,
  268.     0x008F, 0x0087, 0x007F, 0x0078, 0x0071
  269. };
  270.  
  271. #ifdef USE_BLEP
  272.  
  273. /* Why this table is not represented as readable float numbers:
  274. /* Accurate float representation in string format requires at least 7 digits and normalized
  275. ** (scientific) notation, notwithstanding compiler issues with precision or rounding error.
  276. ** Also, don't touch this table ever, just keep it exactly identical!
  277. */
  278.  
  279. static const uint32_t fBlepData[48] =
  280. {
  281.     0x3F7FE1F1, 0x3F7FD548, 0x3F7FD6A3, 0x3F7FD4E3, 0x3F7FAD85, 0x3F7F2152,
  282.     0x3F7DBFAE, 0x3F7ACCDF, 0x3F752F1E, 0x3F6B7384, 0x3F5BFBCB, 0x3F455CF2,
  283.     0x3F26E524, 0x3F0128C4, 0x3EACC7DC, 0x3E29E86B, 0x3C1C1D29, 0xBDE4BBE6,
  284.     0xBE3AAE04, 0xBE48DEDD, 0xBE22AD7E, 0xBDB2309A, 0xBB82B620, 0x3D881411,
  285.     0x3DDADBF3, 0x3DE2C81D, 0x3DAAA01F, 0x3D1E769A, 0xBBC116D7, 0xBD1402E8,
  286.     0xBD38A069, 0xBD0C53BB, 0xBC3FFB8C, 0x3C465FD2, 0x3CEA5764, 0x3D0A51D6,
  287.     0x3CEAE2D5, 0x3C92AC5A, 0x3BE4CBF7, 0x00000000, 0x00000000, 0x00000000,
  288.     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
  289. };
  290. #endif
  291.  
  292. static void GenerateWaves(void);
  293. static void ProcessStep(int16_t v);
  294. static void ProcessFrame(int16_t v);
  295. static void SetAudio(int32_t v);
  296. static void PListCommandParse(int16_t v, int16_t FX, int16_t FXParam);
  297. static void PlayIRQ(void);
  298.  
  299. static int8_t openMixer(uint32_t audioFreq);
  300. static void closeMixer(void);
  301.  
  302. static void paulaStartDMA(uint8_t i)
  303. {
  304.     paulaVoice_t *v;
  305.  
  306.     v = &paula[i];
  307.  
  308.     v->fPhase     = 0.0f;
  309.     v->readPos    = 0;
  310.     v->currData   = v->newData;
  311.     v->currLength = v->newLength;
  312.     v->active     = true;
  313. }
  314.  
  315. static void paulaSetPeriod(uint8_t i, uint16_t period)
  316. {
  317.     paulaVoice_t *v;
  318.  
  319.     v = &paula[i];
  320.  
  321.     if (period == 0)
  322.     {
  323.         v->fDelta = 0.0f;
  324.     }
  325.     else
  326.     {
  327.         /* confirmed Paula behavior */
  328.         if (period < 113)
  329.             period = 113;
  330.  
  331.         v->fDelta = ((float)(PAULA_PAL_CLK) / period) / fAudioRate;
  332.     }
  333.  
  334. #ifdef USE_BLEP
  335.     if (v->fLastDelta == 0.0f)
  336.         v->fLastDelta = v->fDelta;
  337. #endif
  338. }
  339.  
  340. static void paulaSetVolume(uint8_t i, uint16_t vol)
  341. {
  342.     vol &= 0x007F;
  343.     if (vol > 0x40)
  344.         vol = 0x40;
  345.  
  346.     paula[i].fVolume = vol * (1.0f / 64.0f);
  347. }
  348.  
  349. static void paulaSetLength(uint8_t i, uint16_t len)
  350. {
  351.     paula[i].newLength = len * 2;
  352. }
  353.  
  354. static void paulaSetData(uint8_t i, const int8_t *src)
  355. {
  356.     paula[i].newData = src;
  357. }
  358.  
  359. #if defined(USE_HIGHPASS)
  360. static void calcCoeffLossyIntegrator(float fSr, float fHz, lossyIntegrator_t *filter)
  361. {
  362.     filter->fCoeff[0] = tanf((3.1415927f * fHz) / fSr);
  363.     filter->fCoeff[1] = 1.0f / (1.0f + filter->fCoeff[0]);
  364. }
  365.  
  366. static void clearLossyIntegrator(lossyIntegrator_t *filter)
  367. {
  368.     filter->fBuffer[0] = 0.0f;
  369.     filter->fBuffer[1] = 0.0f;
  370. }
  371.  
  372. static inline void lossyIntegrator(lossyIntegrator_t *filter, float *fIn, float *fOut)
  373. {
  374.     float fOutput;
  375.  
  376.     /* left channel */
  377.     fOutput = (filter->fCoeff[0] * fIn[0] + filter->fBuffer[0]) * filter->fCoeff[1];
  378.     filter->fBuffer[0] = filter->fCoeff[0] * (fIn[0] - fOutput) + fOutput + 1e-10f;
  379.     fOut[0] = fOutput;
  380.  
  381.     /* right channel */
  382.     fOutput = (filter->fCoeff[0] * fIn[1] + filter->fBuffer[1]) * filter->fCoeff[1];
  383.     filter->fBuffer[1] = filter->fCoeff[0] * (fIn[1] - fOutput) + fOutput + 1e-10f;
  384.     fOut[1] = fOutput;
  385. }
  386.  
  387. static inline void lossyIntegratorHighPass(lossyIntegrator_t *filter, float *fIn, float *fOut)
  388. {
  389.     float fLow[2];
  390.  
  391.     lossyIntegrator(filter, fIn, fLow);
  392.  
  393.     fOut[0] = fIn[0] - fLow[0];
  394.     fOut[1] = fIn[1] - fLow[1];
  395. }
  396. #endif
  397.  
  398. #ifdef USE_BLEP
  399. static inline void blepAdd(blep_t *b, float offset_f, float amplitude_f)
  400. {
  401.     int8_t n;
  402.     int32_t i;
  403.     const float *fBlepSrc;
  404.     float f;
  405.  
  406.     f = offset_f * BLEP_SP;
  407.  
  408.     i = (int32_t)(f); /* get integer part of f (should use SSE on x86/x86_64) */
  409.     fBlepSrc = (const float *)(&fBlepData[i + BLEP_OS]);
  410.     f -= i; /* remove integer part of f (should also use SSE) */
  411.  
  412.     i = b->index;
  413.  
  414.     n = BLEP_NS;
  415.     while (n--)
  416.     {
  417.         b->fBuffer[i] += (amplitude_f * LERP(fBlepSrc[0], fBlepSrc[1], f));
  418.         i = (i + 1) & BLEP_RNS;
  419.  
  420.         fBlepSrc += BLEP_SP;
  421.     }
  422.  
  423.     b->samplesLeft = BLEP_NS;
  424. }
  425.  
  426. static inline float blepRun(blep_t *b)
  427. {
  428.     float fBlepOutput;
  429.  
  430.     fBlepOutput = b->fBuffer[b->index];
  431.     b->fBuffer[b->index] = 0.0f;
  432.  
  433.     b->index = (b->index + 1) & BLEP_RNS;
  434.  
  435.     b->samplesLeft--;
  436.     return (fBlepOutput);
  437. }
  438. #endif
  439.  
  440. static void freeSong(void)
  441. {
  442.     int32_t i;
  443.  
  444.     if (Song.Name != NULL)
  445.     {
  446.         free(Song.Name);
  447.         Song.Name = NULL;
  448.     }
  449.  
  450.     if (Song.Subsongs != NULL)
  451.     {
  452.         free(Song.Subsongs);
  453.         Song.Subsongs = NULL;
  454.     }
  455.  
  456.     if (Song.Positions != NULL)
  457.     {
  458.         free(Song.Positions);
  459.         Song.Positions = NULL;
  460.     }
  461.  
  462.     if (Song.Tracks != NULL)
  463.     {
  464.         for (i = 0; i <= MaxTrack; ++i)
  465.         {
  466.             if (Song.Tracks[i] != NULL)
  467.             {
  468.                 free(Song.Tracks[i]);
  469.                 Song.Tracks[i] = NULL;
  470.             }
  471.         }
  472.  
  473.         free(Song.Tracks);
  474.         Song.Tracks = NULL;
  475.     }
  476.  
  477.     if (Song.Instruments != NULL)
  478.     {
  479.         for (i = 1; i <= Song.InstrumentNr; ++i)
  480.         {
  481.             if (Song.Instruments[i].Name != NULL)
  482.             {
  483.                 free(Song.Instruments[i].Name);
  484.                 Song.Instruments[i].Name = NULL;
  485.             }
  486.  
  487.             if (Song.Instruments[i].PList.Entries != NULL)
  488.             {
  489.                 free(Song.Instruments[i].PList.Entries);
  490.                 Song.Instruments[i].PList.Entries = NULL;
  491.             }
  492.         }
  493.  
  494.         free(Song.Instruments);
  495.         Song.Instruments = NULL;
  496.     }
  497. }
  498.  
  499. static void PlayIRQ(void)
  500. {
  501.     uint8_t i;
  502.     int16_t NextPos;
  503.     AHXVoice *voice;
  504.  
  505.     if (StepWaitFrames <= 0)
  506.     {
  507.         if (GetNewPosition)
  508.         {
  509.             NextPos = PosNr + 1;
  510.             if (NextPos == Song.PositionNr)
  511.                 NextPos = 0;
  512.  
  513.             for (i = 0; i < PAULA_VOICES; ++i)
  514.             {
  515.                 voice = &Voices[i];
  516.  
  517.                 voice->Track         = Song.Positions[PosNr].Track[i];
  518.                 voice->Transpose     = Song.Positions[PosNr].Transpose[i];
  519.                 voice->NextTrack     = Song.Positions[NextPos].Track[i];
  520.                 voice->NextTranspose = Song.Positions[NextPos].Transpose[i];
  521.             }
  522.  
  523.             GetNewPosition = false;
  524.         }
  525.  
  526.         for (i = 0; i < PAULA_VOICES; ++i)
  527.             ProcessStep(i);
  528.  
  529.         StepWaitFrames = Tempo;
  530.     }
  531.  
  532.     for (i = 0; i < PAULA_VOICES; ++i)
  533.         ProcessFrame(i);
  534.  
  535.     if ((Tempo > 0) && (--StepWaitFrames <= 0))
  536.     {
  537.         if (!PatternBreak)
  538.         {
  539.             NoteNr++;
  540.             if (NoteNr >= Song.TrackLength)
  541.             {
  542.                 PosJump      = PosNr + 1;
  543.                 PosJumpNote  = 0;
  544.                 PatternBreak = true;
  545.             }
  546.         }
  547.  
  548.         if (PatternBreak)
  549.         {
  550.             PatternBreak = false;
  551.  
  552.             PosNr  = PosJump;
  553.             NoteNr = PosJumpNote;
  554.  
  555.             PosJumpNote = 0;
  556.             PosJump     = 0;
  557.  
  558.             if (PosNr == Song.PositionNr)
  559.             {
  560.                 SongEndReached = true;
  561.                 PosNr = Song.Restart;
  562.             }
  563.  
  564.             GetNewPosition = true;
  565.         }
  566.     }
  567.  
  568.     for (i = 0; i < PAULA_VOICES; ++i)
  569.         SetAudio(i);
  570. }
  571.  
  572. static void CalcADSR(AHXVoice *v)
  573. {
  574.     int16_t af, df, rf;
  575.  
  576.     af = v->ADSR.aFrames = v->Instrument->Envelope.aFrames;
  577.     df = v->ADSR.dFrames = v->Instrument->Envelope.dFrames;
  578.          v->ADSR.sFrames = v->Instrument->Envelope.sFrames;
  579.     rf = v->ADSR.rFrames = v->Instrument->Envelope.rFrames;
  580.  
  581.     if (af == 0) af = 1;
  582.     if (df == 0) df = 1;
  583.     if (rf == 0) rf = 0;
  584.  
  585.     v->ADSR.aVolume =  (v->Instrument->Envelope.aVolume << 8) / af;
  586.     v->ADSR.dVolume = ((v->Instrument->Envelope.dVolume - v->Instrument->Envelope.aVolume) << 8) / df;
  587.     v->ADSR.rVolume = ((v->Instrument->Envelope.rVolume  -v->Instrument->Envelope.dVolume) << 8) / rf;
  588. }
  589.  
  590. static void ProcessStep(int16_t v)
  591. {
  592.     int16_t i, Note, Instrument, FX, FXParam, t, Neue, Alte, SquareLower, SquareUpper, d3, d4, d6;
  593.     AHXVoice *voice;
  594.     AHXStep *step;
  595.  
  596.     voice = &Voices[v];
  597.  
  598.     if (!voice->TrackOn)
  599.         return;
  600.  
  601.     voice->VolumeSlideUp = voice->VolumeSlideDown = 0;
  602.  
  603.     step = &Song.Tracks[Song.Positions[PosNr].Track[v]][NoteNr];
  604.  
  605.     Note       = step->Note;
  606.     Instrument = step->Instrument;
  607.     FX         = step->FX;
  608.     FXParam    = step->FXParam;
  609.  
  610.     switch (FX)
  611.     {
  612.         case 0x00: /* Position Jump HI */
  613.         {
  614.             if (((FXParam & 0x0F) > 0) && ((FXParam & 0x0F) <= 9))
  615.                 PosJump = FXParam & 0x0F;
  616.         }
  617.         break;
  618.  
  619.         case 0x05: /* Volume Slide + Tone Portamento */
  620.         case 0x0A: /* Volume Slide */
  621.         {
  622.             voice->VolumeSlideDown = FXParam & 0x0F;
  623.             voice->VolumeSlideUp   = FXParam >> 4;
  624.         }
  625.         break;
  626.  
  627.         case 0x0B: /* Position Jump */
  628.         {
  629.             PosJump = (PosJump * 100) + (FXParam & 0x0F) + ((FXParam >> 4) * 10);
  630.             PatternBreak = true;
  631.         }
  632.         break;
  633.  
  634.         case 0x0D: /* Patternbreak */
  635.         {
  636.             PosJump = PosNr + 1;
  637.  
  638.             PosJumpNote = (FXParam & 0x0F) + (FXParam >> 4) * 10;
  639.             if (PosJumpNote > Song.TrackLength)
  640.                 PosJumpNote = 0;
  641.  
  642.             PatternBreak = true;
  643.         }
  644.         break;
  645.  
  646.         case 0x0E: /* Enhanced commands */
  647.         {
  648.             switch (FXParam >> 4)
  649.             {
  650.                 case 0xC: /* Note Cut */
  651.                 {
  652.                     if ((FXParam & 0x0F) < Tempo)
  653.                     {
  654.                         voice->NoteCutWait = FXParam & 0x0F;
  655.                         if(voice->NoteCutWait)
  656.                         {
  657.                             voice->NoteCutOn      = true;
  658.                             voice->HardCutRelease = false;
  659.                         }
  660.                     }
  661.                 }
  662.                 break;
  663.  
  664.                 case 0xD: /* Note Delay */
  665.                 {
  666.                     if (voice->NoteDelayOn)
  667.                     {
  668.                         voice->NoteDelayOn = false;
  669.                     }
  670.                     else
  671.                     {
  672.                         if ((FXParam & 0x0F) < Tempo)
  673.                         {
  674.                             voice->NoteDelayWait = FXParam & 0x0F;
  675.                             if (voice->NoteDelayWait)
  676.                             {
  677.                                 voice->NoteDelayOn = true;
  678.                                 return;
  679.                             }
  680.                         }
  681.                     }
  682.                 }
  683.                 break;
  684.             }
  685.         }
  686.         break;
  687.  
  688.         case 0x0F: /* Speed */
  689.             Tempo = FXParam;
  690.         break;
  691.     }
  692.  
  693.     if (Instrument && (Instrument <= Song.InstrumentNr))
  694.     {
  695.         voice->PerfSubVolume    = 0x40;
  696.         voice->PeriodSlideSpeed = voice->PeriodSlidePeriod = voice->PeriodSlideLimit = 0;
  697.         voice->ADSRVolume       = 0;
  698.         voice->Instrument       = &Song.Instruments[Instrument];
  699.  
  700.         CalcADSR(voice);
  701.  
  702.         voice->WaveLength     = voice->Instrument->WaveLength;
  703.         voice->NoteMaxVolume  = voice->Instrument->Volume;
  704.         voice->VibratoCurrent = 0;
  705.         voice->VibratoDelay   = voice->Instrument->VibratoDelay;
  706.         voice->VibratoDepth   = voice->Instrument->VibratoDepth;
  707.         voice->VibratoSpeed   = voice->Instrument->VibratoSpeed;
  708.         voice->VibratoPeriod  = 0;
  709.         voice->HardCutRelease = voice->Instrument->HardCutRelease;
  710.         voice->HardCut        = voice->Instrument->HardCutReleaseFrames;
  711.         voice->IgnoreSquare   = voice->SquareSlidingIn = 0;
  712.         voice->SquareWait     = voice->SquareOn = 0;
  713.  
  714.         SquareLower = voice->Instrument->SquareLowerLimit >> (5 - voice->WaveLength);
  715.         SquareUpper = voice->Instrument->SquareUpperLimit >> (5 - voice->WaveLength);
  716.  
  717.         if (SquareUpper < SquareLower)
  718.         {
  719.             t = SquareUpper;
  720.             SquareUpper = SquareLower;
  721.             SquareLower = t;
  722.         }
  723.  
  724.         voice->SquareUpperLimit = SquareUpper;
  725.         voice->SquareLowerLimit = SquareLower;
  726.         voice->IgnoreFilter     = voice->FilterWait = voice->FilterOn = 0;
  727.         voice->FilterSlidingIn  = false;
  728.  
  729.         d6 = voice->Instrument->FilterSpeed;
  730.         d3 = voice->Instrument->FilterLowerLimit;
  731.         d4 = voice->Instrument->FilterUpperLimit;
  732.  
  733.         if (d3 & 0x80) d6 |= 0x20;
  734.         if (d4 & 0x80) d6 |= 0x40;
  735.  
  736.         voice->FilterSpeed = d6;
  737.  
  738.         d3 &= ~0x80;
  739.         d4 &= ~0x80;
  740.  
  741.         if (d3 > d4)
  742.         {
  743.             t  = d3;
  744.             d3 = d4;
  745.             d4 = t;
  746.         }
  747.  
  748.         voice->FilterUpperLimit = d4;
  749.         voice->FilterLowerLimit = d3;
  750.  
  751.         voice->FilterPos = 32;
  752.         voice->PerfWait  = voice->PerfCurrent = 0;
  753.         voice->PerfSpeed = voice->Instrument->PList.Speed;
  754.         voice->PerfList  = &voice->Instrument->PList;
  755.     }
  756.  
  757.     voice->PeriodSlideOn = false;
  758.  
  759.     FX &= 0x0F;
  760.     switch (FX)
  761.     {
  762.         case 0x09: /* Set Squarewave-Offset */
  763.         {
  764.             voice->SquarePos    = FXParam >> (5 - voice->WaveLength);
  765.             //voice->PlantSquare  = true;   (bug?)
  766.             voice->IgnoreSquare = true;
  767.         }
  768.         break;
  769.  
  770.         case 0x03: /* Tone Portamento (Period Slide Up/Down w/ Limit) */
  771.         {
  772.             if (FXParam != 0)
  773.                 voice->PeriodSlideSpeed = FXParam;
  774.         }
  775.         /* fall through */
  776.  
  777.         case 0x05: /* Tone Portamento + Volume Slide */
  778.         {
  779.             if (Note)
  780.             {
  781.                 Neue = PeriodTable[Note];
  782.                 Alte = PeriodTable[voice->TrackPeriod];
  783.                 Alte -= Neue;
  784.                 Neue = Alte + voice->PeriodSlidePeriod;
  785.                 if (Neue)
  786.                     voice->PeriodSlideLimit = -Alte;
  787.             }
  788.  
  789.             voice->PeriodSlideOn        = true;
  790.             voice->PeriodSlideWithLimit = true;
  791.  
  792.             Note = 0;
  793.         }
  794.         break;
  795.     }
  796.  
  797.     if (Note)
  798.     {
  799.         voice->TrackPeriod = Note;
  800.         voice->PlantPeriod = true;
  801.     }
  802.  
  803.     switch (FX)
  804.     {
  805.         case 0x01: /* Portamento up (Period slide down) */
  806.         {
  807.             voice->PeriodSlideSpeed     = -FXParam;
  808.             voice->PeriodSlideOn        = true;
  809.             voice->PeriodSlideWithLimit = false;
  810.         }
  811.         break;
  812.  
  813.         case 0x02: /* Portamento down (Period slide up) */
  814.         {
  815.             voice->PeriodSlideSpeed     = FXParam;
  816.             voice->PeriodSlideOn        = true;
  817.             voice->PeriodSlideWithLimit = false;
  818.         }
  819.         break;
  820.  
  821.         case 0x04: /* Filter override */
  822.         {
  823.             if ((FXParam == 0) || (FXParam == 0x40))
  824.                 break;
  825.  
  826.             if (FXParam < 0x40)
  827.             {
  828.                 voice->IgnoreFilter = FXParam;
  829.                 break;
  830.             }
  831.  
  832.             if (FXParam > 0x7F)
  833.                 break;
  834.  
  835.             voice->FilterPos = FXParam - 0x40;
  836.         }
  837.         break;
  838.  
  839.         case 0x0C: /* Volume */
  840.         {
  841.             FXParam &= 0xFF;
  842.             if (FXParam <= 0x40)
  843.             {
  844.                 voice->NoteMaxVolume = FXParam;
  845.             }
  846.             else
  847.             {
  848.                 FXParam -= 0x50;
  849.                 if (FXParam <= 0x40)
  850.                 {
  851.                     for (i = 0; i < PAULA_VOICES; ++i)
  852.                         Voices[i].TrackMasterVolume = FXParam;
  853.                 }
  854.                 else
  855.                 {
  856.                     FXParam -= 0xa0 - 0x50;
  857.                     if (FXParam <= 0x40)
  858.                         voice->TrackMasterVolume = FXParam;
  859.                 }
  860.             }
  861.         }
  862.         break;
  863.  
  864.         case 0x0E: /* Extended commands */
  865.         {
  866.             switch (FXParam >> 4)
  867.             {
  868.                 case 0x1: /* Fineslide up (Period fineslide down) */
  869.                 {
  870.                     voice->PeriodSlidePeriod -= (FXParam & 0x0F);
  871.                     voice->PlantPeriod = true;
  872.                 }
  873.                 break;
  874.  
  875.                 case 0x2: /* Fineslide down (Period fineslide up) */
  876.                 {
  877.                     voice->PeriodSlidePeriod += (FXParam & 0x0F);
  878.                     voice->PlantPeriod = true;
  879.                 }
  880.                 break;
  881.  
  882.                 case 0x4: /* Vibrato control */
  883.                     voice->VibratoDepth = FXParam & 0x0F;
  884.                 break;
  885.  
  886.                 case 0xA: /* Finevolume up */
  887.                 {
  888.                     voice->NoteMaxVolume += (FXParam & 0x0F);
  889.                     if (voice->NoteMaxVolume > 0x40)
  890.                         voice->NoteMaxVolume = 0x40;
  891.                 }
  892.                 break;
  893.  
  894.                 case 0xB: /* Finevolume down */
  895.                 {
  896.                     voice->NoteMaxVolume -= (FXParam & 0x0F);
  897.                     if (voice->NoteMaxVolume < 0)
  898.                         voice->NoteMaxVolume = 0;
  899.                 }
  900.                 break;
  901.             }
  902.         }
  903.         break;
  904.     }
  905. }
  906.  
  907. static void ProcessFrame(int16_t v)
  908. {
  909.     int8_t *SquarePtr, *AudioSource;
  910.     int16_t i, d0, d1, d2, d3, NextInstrument, Cur, FMax, Delta, X;
  911.     AHXVoice *voice;
  912.  
  913.     voice = &Voices[v];
  914.  
  915.     if (!voice->TrackOn)
  916.         return;
  917.  
  918.     if (voice->NoteDelayOn)
  919.     {
  920.         if (voice->NoteDelayWait <= 0)
  921.             ProcessStep(v);
  922.         else
  923.             voice->NoteDelayWait--;
  924.     }
  925.  
  926.     if (voice->HardCut)
  927.     {
  928.         if ((NoteNr + 1) < Song.TrackLength)
  929.             NextInstrument = Song.Tracks[voice->Track][NoteNr + 1].Instrument;
  930.         else
  931.             NextInstrument = Song.Tracks[voice->NextTrack][0].Instrument;
  932.  
  933.         if (NextInstrument)
  934.         {
  935.             d1 = Tempo - voice->HardCut;
  936.             if (d1 < 0)
  937.                 d1 = 0;
  938.  
  939.             if (!voice->NoteCutOn)
  940.             {
  941.                 voice->NoteCutOn       = true;
  942.                 voice->NoteCutWait     = d1;
  943.                 voice->HardCutReleaseF = -(d1 - Tempo);
  944.             }
  945.             else
  946.             {
  947.                 voice->HardCut = 0;
  948.             }
  949.         }
  950.     }
  951.  
  952.     if (voice->NoteCutOn)
  953.     {
  954.         if (voice->NoteCutWait <= 0)
  955.         {
  956.             voice->NoteCutOn = false;
  957.  
  958.             if (voice->HardCutRelease)
  959.             {
  960.                 voice->ADSR.rVolume = -(voice->ADSRVolume - (voice->Instrument->Envelope.rVolume << 8)) / voice->HardCutReleaseF;
  961.                 voice->ADSR.rFrames = voice->HardCutReleaseF;
  962.                 voice->ADSR.aFrames = voice->ADSR.dFrames = voice->ADSR.sFrames = 0;
  963.             }
  964.             else
  965.             {
  966.                 voice->NoteMaxVolume = 0;
  967.             }
  968.         }
  969.         else
  970.         {
  971.             voice->NoteCutWait--;
  972.         }
  973.     }
  974.  
  975.     if (voice->ADSR.aFrames)
  976.     {
  977.         voice->ADSRVolume += voice->ADSR.aVolume;
  978.  
  979.         voice->ADSR.aFrames--;
  980.         if (voice->ADSR.aFrames <= 0)
  981.               voice->ADSRVolume = voice->Instrument->Envelope.aVolume << 8;
  982.     }
  983.     else if (voice->ADSR.dFrames)
  984.     {
  985.         voice->ADSRVolume += voice->ADSR.dVolume;
  986.  
  987.         voice->ADSR.dFrames--;
  988.         if (voice->ADSR.dFrames <= 0)
  989.               voice->ADSRVolume = voice->Instrument->Envelope.dVolume << 8;
  990.     }
  991.     else if (voice->ADSR.sFrames)
  992.     {
  993.         voice->ADSR.sFrames--;
  994.     }
  995.     else if (voice->ADSR.rFrames)
  996.     {
  997.         voice->ADSRVolume += voice->ADSR.rVolume;
  998.  
  999.         voice->ADSR.rFrames--;
  1000.         if (voice->ADSR.rFrames <= 0)
  1001.               voice->ADSRVolume = voice->Instrument->Envelope.rVolume << 8;
  1002.     }
  1003.  
  1004.     voice->NoteMaxVolume = voice->NoteMaxVolume + voice->VolumeSlideUp - voice->VolumeSlideDown;
  1005.     voice->NoteMaxVolume = CLAMP(voice->NoteMaxVolume, 0, 64);
  1006.  
  1007.     if (voice->PeriodSlideOn)
  1008.     {
  1009.         if (voice->PeriodSlideWithLimit)
  1010.         {
  1011.             d0 = voice->PeriodSlidePeriod - voice->PeriodSlideLimit;
  1012.             d2 = voice->PeriodSlideSpeed;
  1013.  
  1014.             if (d0 > 0)
  1015.                 d2 = -d2;
  1016.  
  1017.             if (d0)
  1018.             {
  1019.                 d3 = (d0 + d2) ^ d0;
  1020.                 if (d3 >= 0)
  1021.                     d0 = voice->PeriodSlidePeriod + d2;
  1022.                 else
  1023.                     d0 = voice->PeriodSlideLimit;
  1024.  
  1025.                 voice->PeriodSlidePeriod = d0;
  1026.                 voice->PlantPeriod       = true;
  1027.             }
  1028.         }
  1029.         else
  1030.         {
  1031.             voice->PeriodSlidePeriod += voice->PeriodSlideSpeed;
  1032.             voice->PlantPeriod = true;
  1033.         }
  1034.     }
  1035.  
  1036.     if (voice->VibratoDepth)
  1037.     {
  1038.         if (voice->VibratoDelay <= 0)
  1039.         {
  1040.             voice->VibratoPeriod  = (VibratoTable[voice->VibratoCurrent] * voice->VibratoDepth) >> 7;
  1041.             voice->PlantPeriod    = true;
  1042.             voice->VibratoCurrent = (voice->VibratoCurrent + voice->VibratoSpeed) & 0x3F;
  1043.         }
  1044.         else
  1045.         {
  1046.             voice->VibratoDelay--;
  1047.         }
  1048.     }
  1049.  
  1050.     if (voice->PerfList != NULL)
  1051.     {
  1052.         if (voice->Instrument && (voice->PerfCurrent < voice->Instrument->PList.Length))
  1053.         {
  1054.             voice->PerfWait--;
  1055.             if (voice->PerfWait <= 0)
  1056.             {
  1057.                 Cur = voice->PerfCurrent++;
  1058.                 voice->PerfWait = voice->PerfSpeed;
  1059.  
  1060.                 if (voice->PerfList->Entries[Cur].Waveform)
  1061.                 {
  1062.                     voice->Waveform             = voice->PerfList->Entries[Cur].Waveform - 1;
  1063.                     voice->NewWaveform          = true;
  1064.                     voice->PeriodPerfSlideSpeed = voice->PeriodPerfSlidePeriod = 0;
  1065.                 }
  1066.  
  1067.                 voice->PeriodPerfSlideOn = false;
  1068.                 for (i = 0; i < 2; ++i)
  1069.                     PListCommandParse(v, voice->PerfList->Entries[Cur].FX[i] & 0xFF, voice->PerfList->Entries[Cur].FXParam[i] & 0xFF);
  1070.  
  1071.                 if (voice->PerfList->Entries[Cur].Note)
  1072.                 {
  1073.                     voice->InstrPeriod = voice->PerfList->Entries[Cur].Note;
  1074.                     voice->PlantPeriod = true;
  1075.                     voice->FixedNote   = voice->PerfList->Entries[Cur].Fixed;
  1076.                 }
  1077.             }
  1078.         }
  1079.         else
  1080.         {
  1081.             if (voice->PerfWait)
  1082.                 voice->PerfWait--;
  1083.             else
  1084.                 voice->PeriodPerfSlideSpeed = 0;
  1085.         }
  1086.     }
  1087.  
  1088.     if (voice->PeriodPerfSlideOn)
  1089.     {
  1090.         voice->PeriodPerfSlidePeriod -= voice->PeriodPerfSlideSpeed;
  1091.         if (voice->PeriodPerfSlidePeriod)
  1092.             voice->PlantPeriod = true;
  1093.     }
  1094.  
  1095.     if ((voice->Waveform == (3 - 1)) && voice->SquareOn)
  1096.     {
  1097.         voice->SquareWait--;
  1098.         if (voice->SquareWait <= 0)
  1099.         {
  1100.             d1 = voice->SquareLowerLimit;
  1101.             d2 = voice->SquareUpperLimit;
  1102.             d3 = voice->SquarePos;
  1103.  
  1104.             if (voice->SquareInit)
  1105.             {
  1106.                 voice->SquareInit = false;
  1107.  
  1108.                 if (d3 <= d1)
  1109.                 {
  1110.                     voice->SquareSlidingIn = true;
  1111.                     voice->SquareSign      = 1;
  1112.                 }
  1113.                 else if (d3 >= d2)
  1114.                 {
  1115.                     voice->SquareSlidingIn = true;
  1116.                     voice->SquareSign      = -1;
  1117.                 }
  1118.             }
  1119.  
  1120.             if ((d1 == d3) || (d2 == d3))
  1121.             {
  1122.                 if (voice->SquareSlidingIn)
  1123.                     voice->SquareSlidingIn = false;
  1124.                 else
  1125.                     voice->SquareSign = -voice->SquareSign;
  1126.             }
  1127.  
  1128.             d3 += voice->SquareSign;
  1129.  
  1130.             voice->SquarePos   = d3;
  1131.             voice->PlantSquare = true;
  1132.             voice->SquareWait  = voice->Instrument->SquareSpeed;
  1133.         }
  1134.     }
  1135.  
  1136.     if (voice->FilterOn && (--voice->FilterWait <= 0))
  1137.     {
  1138.         d1 = voice->FilterLowerLimit;
  1139.         d2 = voice->FilterUpperLimit;
  1140.         d3 = voice->FilterPos;
  1141.  
  1142.         if (voice->FilterInit)
  1143.         {
  1144.             voice->FilterInit = false;
  1145.  
  1146.             if (d3 <= d1)
  1147.             {
  1148.                 voice->FilterSlidingIn = true;
  1149.                 voice->FilterSign      = 1;
  1150.             }
  1151.             else if (d3 >= d2)
  1152.             {
  1153.                 voice->FilterSlidingIn = true;
  1154.                 voice->FilterSign      = -1;
  1155.             }
  1156.         }
  1157.  
  1158.         FMax = (voice->FilterSpeed < 3) ? (5 - voice->FilterSpeed) : 1;
  1159.         for (i = 0; i < FMax; ++i)
  1160.         {
  1161.             if ((d1 == d3) || (d2 == d3))
  1162.             {
  1163.                 if (voice->FilterSlidingIn)
  1164.                     voice->FilterSlidingIn = false;
  1165.                 else
  1166.                     voice->FilterSign = -voice->FilterSign;
  1167.             }
  1168.  
  1169.             d3 += voice->FilterSign;
  1170.         }
  1171.  
  1172.         d3 = CLAMP(d3, 1, 63);
  1173.  
  1174.         voice->FilterPos   = d3;
  1175.         voice->NewWaveform = true;
  1176.  
  1177.         voice->FilterWait = voice->FilterSpeed - 3;
  1178.         if (voice->FilterWait < 1)
  1179.             voice->FilterWait = 1;
  1180.     }
  1181.  
  1182.     if ((voice->Waveform == (3 - 1)) || voice->PlantSquare)
  1183.     {
  1184.         SquarePtr = &Waves.Squares[(voice->FilterPos - 0x20) * (0xFC + 0xFC + 0x80 * 0x1F + 0x80 + 0x280 * 3)];
  1185.  
  1186.         X = voice->SquarePos << (5 - voice->WaveLength);
  1187.         if (X > 0x20)
  1188.         {
  1189.             X = 0x40 - X;
  1190.             voice->SquareReverse = true;
  1191.         }
  1192.  
  1193.         if (X > 0)
  1194.             SquarePtr += ((X - 1) << 7);
  1195.  
  1196.         Delta = 32 >> voice->WaveLength;
  1197.  
  1198.         WaveformTab[2] = voice->SquareTempBuffer;
  1199.         for (i = 0; i < ((1 << voice->WaveLength) * 4); ++i)
  1200.         {
  1201.             voice->SquareTempBuffer[i] = *SquarePtr;
  1202.             SquarePtr += Delta;
  1203.         }
  1204.  
  1205.         voice->NewWaveform = true;
  1206.         voice->Waveform    = 3 - 1;
  1207.         voice->PlantSquare = false;
  1208.     }
  1209.  
  1210.     if (voice->Waveform == (4 - 1))
  1211.         voice->NewWaveform = true;
  1212.  
  1213.     if (voice->NewWaveform)
  1214.     {
  1215.         AudioSource = WaveformTab[voice->Waveform];
  1216.         if (voice->Waveform != (3 - 1))
  1217.             AudioSource += (voice->FilterPos - 0x20) * (0xFC + 0xFC + 0x80 * 0x1F + 0x80 + 0x280 * 3);
  1218.  
  1219.         if (voice->Waveform < (3 - 1))
  1220.             AudioSource += Offsets[voice->WaveLength];
  1221.  
  1222.         if (voice->Waveform == (4 - 1))
  1223.         {
  1224.             AudioSource += (WNRandom & (2 * 0x280 - 1)) & ~1;
  1225.             WNRandom    += 2239384;
  1226.             WNRandom     = ((((WNRandom >> 8) | (WNRandom << 24)) + 782323) ^ 75) - 6735;
  1227.         }
  1228.  
  1229.         voice->AudioSource = AudioSource;
  1230.     }
  1231.  
  1232.     voice->AudioPeriod = voice->InstrPeriod;
  1233.     if (!voice->FixedNote)
  1234.         voice->AudioPeriod += (voice->Transpose + voice->TrackPeriod - 1);
  1235.  
  1236.     voice->AudioPeriod = CLAMP(voice->AudioPeriod, 0, 5 * 12);
  1237.     voice->AudioPeriod = PeriodTable[voice->AudioPeriod];
  1238.  
  1239.     if (!voice->FixedNote)
  1240.         voice->AudioPeriod += voice->PeriodSlidePeriod;
  1241.  
  1242.     voice->AudioPeriod += (voice->PeriodPerfSlidePeriod + voice->VibratoPeriod);
  1243.     voice->AudioPeriod = CLAMP(voice->AudioPeriod, 0x0071, 0x0D60);
  1244.  
  1245.     voice->AudioVolume = ((((((((voice->ADSRVolume >> 8) * voice->NoteMaxVolume) >> 6) * voice->PerfSubVolume) >> 6) * voice->TrackMasterVolume) >> 6) * MainVolume) >> 6;
  1246. }
  1247.  
  1248. static void SetAudio(int32_t v)
  1249. {
  1250.     int16_t i, WaveLoops;
  1251.  
  1252.     if (!Voices[v].TrackOn)
  1253.     {
  1254.         paulaSetVolume(v, 0);
  1255.         return;
  1256.     }
  1257.  
  1258.     if (Voices[v].PlantPeriod)
  1259.     {
  1260.         Voices[v].PlantPeriod = false;
  1261.         paulaSetPeriod(v, Voices[v].AudioPeriod);
  1262.     }
  1263.  
  1264.     if (Voices[v].NewWaveform)
  1265.     {
  1266.         Voices[v].NewWaveform = false;
  1267.  
  1268.         if (Voices[v].Waveform == (4 - 1))
  1269.         {
  1270.             memcpy(Voices[v].VoiceBuffer, Voices[v].AudioSource, 0x280);
  1271.         }
  1272.         else
  1273.         {
  1274.             WaveLoops = (1 << (5 - Voices[v].WaveLength)) * 5;
  1275.             for (i = 0; i < WaveLoops; ++i)
  1276.             {
  1277.                 memcpy(&Voices[v].VoiceBuffer[i * (4 * (1 << Voices[v].WaveLength))],
  1278.                         Voices[v].AudioSource,     4 * (1 << Voices[v].WaveLength));
  1279.             }
  1280.         }
  1281.     }
  1282.  
  1283.     paulaSetVolume(v, Voices[v].AudioVolume);
  1284. }
  1285.  
  1286. static void PListCommandParse(int16_t v, int16_t FX, int16_t FXParam)
  1287. {
  1288.     switch (FX)
  1289.     {
  1290.         case 0x00:
  1291.         {
  1292.             if ((Song.Revision > 0) && (FXParam > 0) && (FXParam < 0x40))
  1293.             {
  1294.                 if (Voices[v].IgnoreFilter)
  1295.                 {
  1296.                     Voices[v].FilterPos    = Voices[v].IgnoreFilter;
  1297.                     Voices[v].IgnoreFilter = false;
  1298.                 }
  1299.                 else
  1300.                 {
  1301.                     Voices[v].FilterPos = FXParam;
  1302.                 }
  1303.  
  1304.                 Voices[v].NewWaveform = true;
  1305.             }
  1306.         }
  1307.         break;
  1308.  
  1309.         case 0x01:
  1310.         {
  1311.             Voices[v].PeriodPerfSlideSpeed = FXParam;
  1312.             Voices[v].PeriodPerfSlideOn    = true;
  1313.         }
  1314.         break;
  1315.  
  1316.         case 0x02:
  1317.         {
  1318.             Voices[v].PeriodPerfSlideSpeed = -FXParam;
  1319.             Voices[v].PeriodPerfSlideOn    = true;
  1320.         }
  1321.         break;
  1322.  
  1323.         case 0x03: /* Init Square Modulation */
  1324.         {
  1325.             if (!Voices[v].IgnoreSquare)
  1326.                 Voices[v].SquarePos = FXParam >> (5 - Voices[v].WaveLength);
  1327.             else
  1328.                 Voices[v].IgnoreSquare = false;
  1329.         }
  1330.         break;
  1331.  
  1332.         case 0x04: /* Start/Stop Modulation */
  1333.         {
  1334.             if ((Song.Revision == 0) || (FXParam == 0))
  1335.             {
  1336.                 Voices[v].SquareOn ^= 1;
  1337.                 Voices[v].SquareInit = Voices[v].SquareOn;
  1338.                 Voices[v].SquareSign = 1;
  1339.             }
  1340.             else
  1341.             {
  1342.                 if (FXParam & 0x0F)
  1343.                 {
  1344.                     Voices[v].SquareOn ^= 1;
  1345.                     Voices[v].SquareInit = Voices[v].SquareOn;
  1346.  
  1347.                     Voices[v].SquareSign = 1;
  1348.                     if ((FXParam & 0x0F) == 0x0F)
  1349.                         Voices[v].SquareSign = -1;
  1350.                 }
  1351.  
  1352.                 if (FXParam & 0xF0)
  1353.                 {
  1354.                     Voices[v].FilterOn ^= 1;
  1355.                     Voices[v].FilterInit = Voices[v].FilterOn;
  1356.  
  1357.                     Voices[v].FilterSign = 1;
  1358.                     if ((FXParam & 0xF0) == 0xF0)
  1359.                         Voices[v].FilterSign = -1;
  1360.                 }
  1361.             }
  1362.         }
  1363.         break;
  1364.  
  1365.         case 0x05: /* Jump to Step [xx] */
  1366.             Voices[v].PerfCurrent = FXParam;
  1367.         break;
  1368.  
  1369.         case 0x06: /* Set Volume */
  1370.         {
  1371.             if (FXParam > 0x40)
  1372.             {
  1373.                 FXParam -= 0x50;
  1374.                 if (FXParam >= 0)
  1375.                 {
  1376.                     if (FXParam <= 0x40)
  1377.                     {
  1378.                         Voices[v].PerfSubVolume = FXParam;
  1379.                     }
  1380.                     else
  1381.                     {
  1382.                         FXParam -= (0xA0 - 0x50);
  1383.                         if (FXParam >= 0)
  1384.                         {
  1385.                             if (FXParam <= 0x40)
  1386.                                 Voices[v].TrackMasterVolume = FXParam;
  1387.                         }
  1388.                     }
  1389.                 }
  1390.             }
  1391.             else
  1392.             {
  1393.                 Voices[v].NoteMaxVolume = FXParam;
  1394.             }
  1395.         }
  1396.         break;
  1397.  
  1398.         case 0x07: /* Set Speed */
  1399.             Voices[v].PerfSpeed = Voices[v].PerfWait = FXParam;
  1400.         break;
  1401.     }
  1402. }
  1403.  
  1404. static inline int32_t clipShifted8(int32_t in)
  1405. {
  1406.     int16_t top;
  1407.  
  1408.     top = (int16_t)(in >> 16);
  1409.  
  1410.          if (top >  127) in =   127 << 16;
  1411.     else if (top < -128) in = -(128 << 16);
  1412.  
  1413.     return (in);
  1414. }
  1415.  
  1416. static void GenerateFilterWaveforms(int8_t *buf, int8_t *loBuf, int8_t *hiBuf)
  1417. {
  1418.     const int16_t *midTablePtr = midFilterTable;
  1419.     const int16_t *lowTablePtr = lowFilterTable;
  1420.     const int8_t *waveformPtr;
  1421.     int32_t freq, i, wv, mid, low, j, in, high, fre;
  1422.  
  1423.     freq = 25;
  1424.     for (i = 0; i < FILTER_ITERATIONS; ++i)
  1425.     {
  1426.         waveformPtr = buf;
  1427.         for (wv = 0; wv < NUM_WAVEFORMS; ++wv)
  1428.         {
  1429.             mid = (*midTablePtr++) << 8;
  1430.             low = (*lowTablePtr++) << 8;
  1431.  
  1432.             for (j = 0; j < waveformLen[wv]; ++j)
  1433.             {
  1434.                 in = (*waveformPtr++) << 16;
  1435.  
  1436.                 high = clipShifted8(in - mid - low);
  1437.                 fre  = (high >> 8) * freq;
  1438.                 mid  = clipShifted8(mid + fre);
  1439.                 fre  = (mid  >> 8) * freq;
  1440.                 low  = clipShifted8(low + fre);
  1441.  
  1442.                 *loBuf++ = (int8_t)(low  >> 16);
  1443.                 *hiBuf++ = (int8_t)(high >> 16);
  1444.             }
  1445.         }
  1446.  
  1447.         freq += 9;
  1448.     }
  1449. }
  1450.  
  1451. static void GenerateTriangle(int8_t *buf, int16_t len)
  1452. {
  1453.     int8_t c, *buf2;
  1454.     int16_t i, d2, d5, d1, d4, val;
  1455.  
  1456.     d2  = len;
  1457.     d5  = len / 4;
  1458.     d1  = 128 / d5;
  1459.     d4  = -(d2 / 2);
  1460.     val = 0;
  1461.  
  1462.     for (i = 0; i < d5; ++i)
  1463.     {
  1464.         *buf++ = (int8_t)(val);
  1465.         val   += d1;
  1466.     }
  1467.  
  1468.     *buf++ = 0x7F;
  1469.  
  1470.     if (d5 != 1)
  1471.     {
  1472.         val = 128;
  1473.         for (i = 0; i < (d5 - 1); ++i)
  1474.         {
  1475.             val   -= d1;
  1476.             *buf++ = (int8_t)(val);
  1477.         }
  1478.     }
  1479.  
  1480.     buf2 = buf + d4;
  1481.     for (i = 0; i < (d5 * 2); ++i)
  1482.     {
  1483.         c = *buf2++;
  1484.         if (c == 0x7F)
  1485.             c = 0x80;
  1486.         else
  1487.             c = -c;
  1488.  
  1489.         *buf++ = c;
  1490.     }
  1491. }
  1492.  
  1493. static void GenerateSquare(int8_t *buf)
  1494. {
  1495.     int16_t i, j;
  1496.  
  1497.     for (i = 1; i <= 32; ++i)
  1498.     {
  1499.         for (j = 0; j < ((64 - i) * 2); ++j)
  1500.             *buf++ = 0x80;
  1501.  
  1502.         for (j = 0; j < (i * 2); ++j)
  1503.             *buf++ = 0x7F;
  1504.     }
  1505. }
  1506.  
  1507. static void GenerateSawtooth(int8_t *buf, int16_t len)
  1508. {
  1509.     int8_t val;
  1510.     int16_t i;
  1511.  
  1512.     val = -128;
  1513.     for (i = 0; i < len; ++i)
  1514.     {
  1515.         *buf++ = val;
  1516.         val   += (256 / (len - 1));
  1517.     }
  1518. }
  1519.  
  1520. static void GenerateWhiteNoise(int8_t *buf, int16_t len)
  1521. {
  1522.     int8_t s;
  1523.     int16_t i;
  1524.     uint16_t ax, bx;
  1525.     uint32_t ays;
  1526.  
  1527.     ays = 0x41595321; /* seed "AYS!" */
  1528.     for (i = 0; i < len; ++i)
  1529.     {
  1530.         s = ays;
  1531.         if (ays & 0x100)
  1532.         {
  1533.             s = 0x7f;
  1534.             if (ays & 0x8000)
  1535.                 s = 0x80;
  1536.         }
  1537.  
  1538.         *buf++ = s;
  1539.  
  1540.         ays  = (ays >> 5) | (ays << 27);
  1541.         ays  = (ays & 0xFFFFFF00) | ((ays & 0xFF) ^ 0x9A);
  1542.         bx   = ays;
  1543.         ays  = (ays << 2) | (ays >> 30);
  1544.         ax   = ays;
  1545.         bx  += ax;
  1546.         ax  ^= bx;
  1547.         ays  = (ays & 0xFFFF0000) | ax;
  1548.         ays  = (ays >> 3) | (ays << 29);
  1549.     }
  1550. }
  1551.  
  1552. static void GenerateWaves(void)
  1553. {
  1554.     /* generates bit-perfect waveforms to the original Amiga replayer */
  1555.     GenerateSawtooth(Waves.Sawtooth04, 0x04);
  1556.     GenerateSawtooth(Waves.Sawtooth08, 0x08);
  1557.     GenerateSawtooth(Waves.Sawtooth10, 0x10);
  1558.     GenerateSawtooth(Waves.Sawtooth20, 0x20);
  1559.     GenerateSawtooth(Waves.Sawtooth40, 0x40);
  1560.     GenerateSawtooth(Waves.Sawtooth80, 0x80);
  1561.     GenerateTriangle(Waves.Triangle04, 0x04);
  1562.     GenerateTriangle(Waves.Triangle08, 0x08);
  1563.     GenerateTriangle(Waves.Triangle10, 0x10);
  1564.     GenerateTriangle(Waves.Triangle20, 0x20);
  1565.     GenerateTriangle(Waves.Triangle40, 0x40);
  1566.     GenerateTriangle(Waves.Triangle80, 0x80);
  1567.     GenerateSquare(Waves.Squares);
  1568.     GenerateWhiteNoise(Waves.WhiteNoiseBig, 0x280 * 3);
  1569.     GenerateFilterWaveforms(Waves.Triangle04, Waves.LowPasses, Waves.HighPasses);
  1570. }
  1571.  
  1572. static void mixAudio(int16_t *stream, int32_t sampleBlockLength)
  1573. {
  1574.     int32_t i, j, smpL, smpR;
  1575.     float fSample, fVolume, fOut[2];
  1576.     paulaVoice_t *v;
  1577. #ifdef USE_BLEP
  1578.     blep_t *bSmp, *bVol;
  1579. #endif
  1580.  
  1581.     memset(fMixerBufferL, 0, sizeof (float) * sampleBlockLength);
  1582.     memset(fMixerBufferR, 0, sizeof (float) * sampleBlockLength);
  1583.  
  1584.     if (musicPaused)
  1585.     {
  1586.         memset(stream, 0, sampleBlockLength * sizeof (int16_t) * 2);
  1587.         return;
  1588.     }
  1589.  
  1590.     for (i = 0; i < PAULA_VOICES; ++i)
  1591.     {
  1592.         v = &paula[i];
  1593.         if (!v->active || (v->currLength < 2) || (v->currData == NULL))
  1594.             continue;
  1595.  
  1596. #ifdef USE_BLEP
  1597.         bSmp = &blep[i];
  1598.         bVol = &blepVol[i];
  1599. #endif
  1600.         for (j = 0; j < sampleBlockLength; ++j)
  1601.         {
  1602.             fSample = v->currData[v->readPos] * (1.0f / 128.0f);
  1603.             fVolume = v->fVolume;
  1604.  
  1605. #ifdef USE_BLEP
  1606.             if (fSample != bSmp->fLastValue)
  1607.             {
  1608.                 if ((v->fLastDelta > 0.0f) && (v->fLastDelta > v->fLastFrac))
  1609.                     blepAdd(bSmp, v->fLastFrac / v->fLastDelta, bSmp->fLastValue - fSample);
  1610.  
  1611.                 bSmp->fLastValue = fSample;
  1612.             }
  1613.  
  1614.             if (fVolume != bVol->fLastValue)
  1615.             {
  1616.                 blepAdd(bVol, 0.0f, bVol->fLastValue - fVolume);
  1617.                 bVol->fLastValue = fVolume;
  1618.             }
  1619.  
  1620.             if (bSmp->samplesLeft) fSample += blepRun(bSmp);
  1621.             if (bVol->samplesLeft) fVolume += blepRun(bVol);
  1622. #endif
  1623.             fSample *= fVolume;
  1624.  
  1625.             fMixerBufferL[j] += (fSample * v->fPanL);
  1626.             fMixerBufferR[j] += (fSample * v->fPanR);
  1627.  
  1628.             v->fPhase += v->fDelta;
  1629.             if (v->fPhase >= 1.0f)
  1630.             {
  1631.                 v->fPhase -= 1.0f;
  1632. #ifdef USE_BLEP
  1633.                 v->fLastFrac  = v->fPhase;
  1634.                 v->fLastDelta = v->fDelta;
  1635. #endif
  1636.                 v->readPos++;
  1637.                 if (v->readPos >= v->currLength)
  1638.                 {
  1639.                     v->readPos = 0;
  1640.  
  1641.                     /* re-fetch Paula register values now */
  1642.                     v->currLength = v->newLength;
  1643.                     v->currData   = v->newData;
  1644.                 }
  1645.             }
  1646.         }
  1647.     }
  1648.  
  1649.     for (j = 0; j < sampleBlockLength; ++j)
  1650.     {
  1651.         fOut[0] = fMixerBufferL[j];
  1652.         fOut[1] = fMixerBufferR[j];
  1653.  
  1654. #ifdef USE_LOWPASS
  1655.         lossyIntegrator(&filterLo, fOut, fOut);
  1656. #endif
  1657.  
  1658. #ifdef USE_HIGHPASS
  1659.         lossyIntegratorHighPass(&filterHi, fOut, fOut);
  1660. #endif
  1661.  
  1662.         /* normalize amplitude */
  1663.         fOut[0] *= (32768.0f / 4.0f);
  1664.         fOut[1] *= (32768.0f / 4.0f);
  1665.  
  1666.         /* truncate to signed 32-bit integer */
  1667.         smpL = (int32_t)(fOut[0]);
  1668.         smpR = (int32_t)(fOut[1]);
  1669.  
  1670.         /* clamp to 16-bit */
  1671.         CLAMP16(smpL);
  1672.         CLAMP16(smpR);
  1673.  
  1674.         /* truncate to 16-bit integer and store in output buffer */
  1675.         *stream++ = (int16_t)(smpL);
  1676.         *stream++ = (int16_t)(smpR);
  1677.     }
  1678. }
  1679.  
  1680. static float sinApx(float x)
  1681. {
  1682.     x = x * (2.0f - x);
  1683.     return (x * 1.09742972f + x * x * 0.31678383f);
  1684. }
  1685.  
  1686. static float cosApx(float x)
  1687. {
  1688.     x = (1.0f - x) * (1.0f + x);
  1689.     return (x * 1.09742972f + x * x * 0.31678383f);
  1690. }
  1691.  
  1692. static void calculatePans(uint8_t stereoSeparation)
  1693. {
  1694.     uint8_t scaledPanPos;
  1695.     float p;
  1696.  
  1697.     if (stereoSeparation > 100)
  1698.         stereoSeparation = 100;
  1699.  
  1700.     scaledPanPos = (stereoSeparation * 128) / 100;
  1701.  
  1702.     p = (128 - scaledPanPos) * (1.0f / 256.0f);
  1703.     paula[0].fPanL = cosApx(p);
  1704.     paula[0].fPanR = sinApx(p);
  1705.     paula[3].fPanL = cosApx(p);
  1706.     paula[3].fPanR = sinApx(p);
  1707.  
  1708.     p = (128 + scaledPanPos) * (1.0f / 256.0f);
  1709.     paula[1].fPanL = cosApx(p);
  1710.     paula[1].fPanR = sinApx(p);
  1711.     paula[2].fPanL = cosApx(p);
  1712.     paula[2].fPanR = sinApx(p);
  1713. }
  1714.  
  1715. static void ahx1play_FillAudioBuffer(int16_t *buffer, int32_t numSamples)
  1716. {
  1717.     int32_t a, b;
  1718.  
  1719.     a = numSamples;
  1720.     while (a > 0)
  1721.     {
  1722.         if (samplesPerFrameLeft == 0)
  1723.         {
  1724.             if (!musicPaused)
  1725.                 PlayIRQ();
  1726.  
  1727.             samplesPerFrameLeft = samplesPerFrame;
  1728.         }
  1729.  
  1730.         b = a;
  1731.         if (b > samplesPerFrameLeft)
  1732.             b = samplesPerFrameLeft;
  1733.  
  1734.         mixAudio(buffer, b);
  1735.         buffer += (b * 2);
  1736.  
  1737.         a -= b;
  1738.         samplesPerFrameLeft -= b;
  1739.     }
  1740.  
  1741.     sampleCounter += numSamples;
  1742. }
  1743.  
  1744. void ahx1play_Close(void)
  1745. {
  1746.     freeSong();
  1747.  
  1748.     closeMixer();
  1749.  
  1750.     if (fMixerBufferL != NULL)
  1751.     {
  1752.         free(fMixerBufferL);
  1753.         fMixerBufferL = NULL;
  1754.     }
  1755.  
  1756.     if (fMixerBufferR != NULL)
  1757.     {
  1758.         free(fMixerBufferR);
  1759.         fMixerBufferR = NULL;
  1760.     }
  1761. }
  1762.  
  1763. void ahx1play_PauseSong(int8_t flag)
  1764. {
  1765.     musicPaused = flag ? true : false;
  1766. }
  1767.  
  1768. void ahx1play_TogglePause(void)
  1769. {
  1770.     musicPaused ^= 1;
  1771. }
  1772.  
  1773. void ahx1play_SetStereoSep(uint8_t percentage)
  1774. {
  1775.     stereoSep = percentage;
  1776.     if (stereoSep > 100)
  1777.         stereoSep = 100;
  1778.  
  1779.     calculatePans(stereoSep);
  1780. }
  1781.  
  1782. char *ahx1play_GetSongName(void)
  1783. {
  1784.     return (songName);
  1785. }
  1786.  
  1787. uint32_t ahx1play_GetMixerTicks(void)
  1788. {
  1789.     if (audioRate < 1000)
  1790.         return (0);
  1791.  
  1792.     return (sampleCounter / (audioRate / 1000));
  1793. }
  1794.  
  1795. static int8_t LoadSong(void *Buffer, int32_t Len)
  1796. {
  1797.     char *NamePtr;
  1798.     uint8_t *SongBuffer, *SBPtr;
  1799.     int32_t i, j, SongLength;
  1800.     AHXInstrument *ins;
  1801.     AHXPListEntry *plist;
  1802.     AHXStep *step;
  1803.     AHXPosition *pos;
  1804.  
  1805.     SongLength = Len;
  1806.     SongBuffer = (uint8_t *)(Buffer);
  1807.     SBPtr      = &SongBuffer[14];
  1808.  
  1809.     if ((SongLength < 14) || (SongLength > 65535))
  1810.         return (false);
  1811.  
  1812.     if ((SongBuffer[0] != 'T') && (SongBuffer[1] != 'H') && (SongBuffer[2] != 'X'))
  1813.         return (false);
  1814.  
  1815.     if (SongBuffer[3] > 1)
  1816.         return (false);
  1817.  
  1818.     NamePtr              = (char *)(&SongBuffer[(SongBuffer[4] << 8) | SongBuffer[5]]);
  1819.     Song.Name            = _strdup(NamePtr); NamePtr += (strlen(NamePtr) + 1);
  1820.     Song.Revision        = SongBuffer[3];
  1821.     Song.SpeedMultiplier = ((SongBuffer[6] >> 5) & 3) + 1;
  1822.     Song.PositionNr      = ((SongBuffer[6] & 0x0F) << 8) | SongBuffer[7];
  1823.     Song.Restart         = (SongBuffer[8] << 8) | SongBuffer[9];
  1824.     Song.TrackLength     = SongBuffer[10];
  1825.     Song.TrackNr         = SongBuffer[11];
  1826.     Song.InstrumentNr    = SongBuffer[12];
  1827.     Song.SubsongNr       = SongBuffer[13];
  1828.  
  1829.     if (Song.Restart >= Song.PositionNr)
  1830.         Song.Restart  = Song.PositionNr - 1;
  1831.  
  1832.     strncpy(songName, Song.Name, sizeof (songName) - 1);
  1833.  
  1834.     Song.Subsongs = (int16_t *)(malloc(sizeof (int16_t) * Song.SubsongNr));
  1835.     if (Song.Subsongs == NULL)
  1836.     {
  1837.         freeSong();
  1838.         return (false);
  1839.     }
  1840.  
  1841.     for (i = 0; i < Song.SubsongNr; ++i)
  1842.     {
  1843.         if ((SBPtr - SongBuffer) > SongLength)
  1844.             return (false);
  1845.  
  1846.         Song.Subsongs[i] = (SBPtr[0] << 8) | SBPtr[1];
  1847.         SBPtr += 2;
  1848.     }
  1849.  
  1850.     Song.Positions = (AHXPosition *)(malloc(sizeof (AHXPosition) * Song.PositionNr));
  1851.     if (Song.Positions == NULL)
  1852.     {
  1853.         freeSong();
  1854.         return (false);
  1855.     }
  1856.  
  1857.     for (i = 0; i < Song.PositionNr; ++i)
  1858.     {
  1859.         for (j = 0; j < PAULA_VOICES; ++j)
  1860.         {
  1861.             if ((SBPtr - SongBuffer) > SongLength)
  1862.                 return (false);
  1863.  
  1864.             pos = &Song.Positions[i];
  1865.  
  1866.             pos->Track[j]     = *SBPtr++;
  1867.             pos->Transpose[j] = *((int8_t *)(SBPtr++));
  1868.         }
  1869.     }
  1870.  
  1871.     MaxTrack = Song.TrackNr;
  1872.  
  1873.     Song.Tracks = (AHXStep **)(malloc(sizeof (AHXStep) * (MaxTrack + 1)));
  1874.     if (Song.Tracks == NULL)
  1875.     {
  1876.         freeSong();
  1877.         return (false);
  1878.     }
  1879.  
  1880.     for (i = 0; i <= MaxTrack; i++)
  1881.     {
  1882.         Song.Tracks[i] = (AHXStep *)(malloc(sizeof (AHXStep) * Song.TrackLength));
  1883.  
  1884.         if (((SongBuffer[6] & 0x80) == 0x80) && (i == 0))
  1885.         {
  1886.             memset(Song.Tracks[i], 0, Song.TrackLength * sizeof (AHXStep));
  1887.             continue;
  1888.         }
  1889.  
  1890.         for (j = 0; j < Song.TrackLength; ++j)
  1891.         {
  1892.             if ((SBPtr - SongBuffer) > SongLength)
  1893.                 return (false);
  1894.  
  1895.             step = &Song.Tracks[i][j];
  1896.  
  1897.             step->Note       = (SBPtr[0] >> 2) & 0x3F;
  1898.             step->Instrument = ((SBPtr[0] & 0x3) << 4) | (SBPtr[1] >> 4);
  1899.             step->FX         = SBPtr[1] & 0x0F;
  1900.             step->FXParam    = SBPtr[2];
  1901.  
  1902.             SBPtr += 3;
  1903.         }
  1904.     }
  1905.  
  1906.     Song.Instruments = (AHXInstrument *)(malloc(sizeof (AHXInstrument) * (Song.InstrumentNr + 1)));
  1907.     if (Song.Instruments == NULL)
  1908.     {
  1909.         freeSong();
  1910.         return (false);
  1911.     }
  1912.  
  1913.     for (i = 1; i <= Song.InstrumentNr; ++i)
  1914.     {
  1915.         ins = &Song.Instruments[i];
  1916.  
  1917.         ins->Name = _strdup(NamePtr); NamePtr += (strlen(NamePtr) + 1);
  1918.         if ((SBPtr - SongBuffer) > SongLength)
  1919.             return (false);
  1920.  
  1921.         ins->Volume               = SBPtr[0];
  1922.         ins->FilterSpeed          = ((SBPtr[1] >> 3) & 0x1F) | ((SBPtr[12] >> 2) & 0x20);
  1923.         ins->WaveLength           = SBPtr[1] & 7;
  1924.         ins->Envelope.aFrames     = SBPtr[2];
  1925.         ins->Envelope.aVolume     = SBPtr[3];
  1926.         ins->Envelope.dFrames     = SBPtr[4];
  1927.         ins->Envelope.dVolume     = SBPtr[5];
  1928.         ins->Envelope.sFrames     = SBPtr[6];
  1929.         ins->Envelope.rFrames     = SBPtr[7];
  1930.         ins->Envelope.rVolume     = SBPtr[8];
  1931.         ins->FilterLowerLimit     = SBPtr[12] & 0x7F;
  1932.         ins->VibratoDelay         = SBPtr[13];
  1933.         ins->HardCutReleaseFrames = (SBPtr[14] >> 4) & 7;
  1934.         ins->HardCutRelease       = (SBPtr[14] & 0x80) ? true : false;
  1935.         ins->VibratoDepth         = SBPtr[14] & 0x0F;
  1936.         ins->VibratoSpeed         = SBPtr[15];
  1937.         ins->SquareLowerLimit     = SBPtr[16];
  1938.         ins->SquareUpperLimit     = SBPtr[17];
  1939.         ins->SquareSpeed          = SBPtr[18];
  1940.         ins->FilterUpperLimit     = SBPtr[19] & 0x3F;
  1941.         ins->PList.Speed          = SBPtr[20];
  1942.         ins->PList.Length         = SBPtr[21];
  1943.  
  1944.         SBPtr += 22;
  1945.  
  1946.         ins->PList.Entries = (AHXPListEntry *)(malloc(sizeof (AHXPListEntry) * ins->PList.Length));
  1947.         if (ins->PList.Entries == NULL)
  1948.         {
  1949.             freeSong();
  1950.             return (false);
  1951.         }
  1952.  
  1953.         for (j = 0; j < ins->PList.Length; ++j)
  1954.         {
  1955.             if ((SBPtr - SongBuffer) > SongLength)
  1956.                 return (false);
  1957.  
  1958.             plist = &ins->PList.Entries[j];
  1959.  
  1960.             plist->FX[1]      = (SBPtr[0] >> 5) & 7;
  1961.             plist->FX[0]      = (SBPtr[0] >> 2) & 7;
  1962.             plist->Waveform   = ((SBPtr[0] << 1) & 6) | (SBPtr[1] >> 7);
  1963.             plist->Fixed      = (SBPtr[1] >> 6) & 1;
  1964.             plist->Note       = SBPtr[1] & 0x3F;
  1965.             plist->FXParam[0] = SBPtr[2];
  1966.             plist->FXParam[1] = SBPtr[3];
  1967.  
  1968.             SBPtr += 4;
  1969.         }
  1970.     }
  1971.  
  1972.     return (true);
  1973. }
  1974.  
  1975. int8_t ahx1play_PlaySong(const uint8_t *moduleData, uint32_t dataLength, int32_t subSongNr, uint32_t audioFreq)
  1976. {
  1977.     uint8_t i;
  1978.     AHXVoice *v;
  1979.  
  1980.     if (audioFreq == 0)
  1981.         audioFreq = 44100;
  1982.  
  1983.     musicPaused = true;
  1984.  
  1985.     ahx1play_Close();
  1986.     memset(songName, 0, sizeof (songName));
  1987.  
  1988.     sampleCounter = 0;
  1989.  
  1990.     if (!LoadSong((uint8_t *)(moduleData), dataLength))
  1991.     {
  1992.         ahx1play_Close();
  1993.         return (false);
  1994.     }
  1995.  
  1996.     fMixerBufferL = (float *)(malloc(MIX_BUF_SAMPLES * sizeof (float)));
  1997.     fMixerBufferR = (float *)(malloc(MIX_BUF_SAMPLES * sizeof (float)));
  1998.  
  1999.     if ((fMixerBufferL == NULL) || (fMixerBufferR == NULL))
  2000.     {
  2001.         ahx1play_Close();
  2002.         return (false);
  2003.     }
  2004.  
  2005.     /* rates below 32kHz will mess up the BLEP synthesis */
  2006.     audioFreq = CLAMP(audioFreq, 32000, 96000);
  2007.  
  2008.     if (!openMixer(audioFreq))
  2009.     {
  2010.         ahx1play_Close();
  2011.         return (false);
  2012.     }
  2013.  
  2014.     audioRate       = audioFreq;
  2015.     fAudioRate      = (float)(audioFreq);
  2016.     soundBufferSize = MIX_BUF_SAMPLES;
  2017.  
  2018.     calculatePans(stereoSep);
  2019.  
  2020. #ifdef USE_HIGHPASS
  2021.     // Amiga 500 RC high-pass filter (R = 1390 ohm, C = 22uF)
  2022.     // hz = 1 / (2pi * R * C)    = ~5.2Hz
  2023.     calcCoeffLossyIntegrator(fAudioRate, 5.2f, &filterHi);
  2024. #endif
  2025.  
  2026.     GenerateWaves();
  2027.  
  2028.     WaveformTab[0] = Waves.Triangle04;
  2029.     WaveformTab[1] = Waves.Sawtooth04;
  2030.     WaveformTab[3] = Waves.WhiteNoiseBig;
  2031.  
  2032.     if (subSongNr > Song.SubsongNr)
  2033.         subSongNr = Song.SubsongNr;
  2034.  
  2035.     PosNr = (subSongNr <= 0) ? 0 : Song.Subsongs[subSongNr - 1];
  2036.     PosJump = 0;
  2037.     PatternBreak = false;
  2038.     MainVolume = 0x40;
  2039.     NoteNr = PosJumpNote = 0;
  2040.     Tempo = 6;
  2041.     StepWaitFrames = 0;
  2042.     GetNewPosition = true;
  2043.     SongEndReached = false;
  2044.  
  2045. #ifdef USE_HIGHPASS
  2046.     clearLossyIntegrator(&filterHi);
  2047. #endif
  2048.  
  2049. #ifdef USE_BLEP
  2050.     memset(blep,    0, sizeof (blep_t));
  2051.     memset(blepVol, 0, sizeof (blep_t));
  2052. #endif
  2053.  
  2054.     for (i = 0; i < PAULA_VOICES; ++i)
  2055.     {
  2056.         v = &Voices[i];
  2057.  
  2058.         memset(v, 0, sizeof (AHXVoice));
  2059.         v->TrackOn = true;
  2060.         v->TrackMasterVolume = 0x40;
  2061.  
  2062.         paulaSetPeriod(i, 0x88); /* original asm replayer does this! */
  2063.         paulaSetVolume(i, 0);
  2064.         paulaSetData(i, v->VoiceBuffer);
  2065.         paulaSetLength(i, 0x280 / 2);
  2066.         paulaStartDMA(i);
  2067.     }
  2068.  
  2069.     samplesPerFrame = (int32_t)(((fAudioRate / 50.0f) / Song.SpeedMultiplier) + 0.5f);
  2070.  
  2071.     musicPaused = false;
  2072.     return (true);
  2073. }
  2074.  
  2075. static const int16_t midFilterTable[NUM_WAVEFORMS * FILTER_ITERATIONS] =
  2076. {
  2077.     0xFB77,0xEEC3,0xE407,0xCCDA,0x027B,0x33C7,0x088D,0x1901,0x2351,
  2078.     0x3F02,0x3494,0x14F0,0x18CD,0x319B,0x4A69,0x6336,0x7700,0x7F00,
  2079.     0x7F00,0x7F03,0x7B89,0x743C,0x6A16,0x5DFC,0x50BB,0x4304,0x3692,
  2080.     0x2C6F,0x242F,0x1D77,0x17FE,0x138A,0x0FEA,0x0CF6,0x0A8E,0x0882,
  2081.     0x06DB,0x0587,0x0475,0x038D,0x02CC,0x0233,0x01BC,0x014B,0xFD67,
  2082.     0xF7DE,0xE7E6,0xDBED,0xCACA,0x3101,0x2591,0x0F6F,0x2099,0x2BEE,
  2083.     0x4836,0x1B05,0x0F08,0x21BB,0x4377,0x6533,0x7DA3,0x7F00,0x7EC7,
  2084.     0x780E,0x6B20,0x5A61,0x47DD,0x362D,0x28BD,0x1EA3,0x1709,0x1153,
  2085.     0x0D07,0x09CB,0x075D,0x056D,0x03FF,0x02D0,0x0212,0x0161,0x0104,
  2086.     0x00AD,0x0060,0x0020,0xFFEE,0xFFC9,0xFFB1,0xFFA4,0xFFA1,0xFCBA,
  2087.     0xF363,0xE37E,0xCF9E,0xE43D,0x367A,0x1965,0x1752,0x23AD,0x3A63,
  2088.     0x41F1,0x17C1,0x0BE8,0x2AA9,0x5553,0x7A8B,0x7F00,0x7D44,0x70C0,
  2089.     0x5C86,0x4508,0x2FC9,0x2115,0x16E6,0x0FDA,0x0AF9,0x0798,0x0542,
  2090.     0x0384,0x0259,0x0173,0x00DF,0x0089,0x0040,0x0007,0xFFDE,0xFFC6,
  2091.     0xFFBB,0xFFBA,0xFFC1,0xFFCC,0xFFD9,0xFFE6,0xFFF2,0xFFFB,0x1378,
  2092.     0xEE84,0xE05A,0xC5D4,0x0B4E,0x31B3,0x1313,0x1F4A,0x2616,0x45DF,
  2093.     0x2E0E,0x13EB,0x09D8,0x3397,0x672F,0x7F00,0x7EC9,0x7012,0x564D,
  2094.     0x3949,0x2460,0x1719,0x0EAA,0x0950,0x05E9,0x038F,0x0224,0x014A,
  2095.     0x008F,0x0003,0xFFAA,0xFF7E,0xFF75,0xFF83,0xFF9F,0xFFBF,0xFFDD,
  2096.     0xFFF5,0x0006,0x000F,0x0013,0x0013,0x0010,0x000C,0x0008,0x1ADD,
  2097.     0xE985,0xDC57,0xC2A3,0x25E9,0x2A8D,0x103D,0x269A,0x2A91,0x4B24,
  2098.     0x1FD9,0x10BD,0x0865,0x3C85,0x779A,0x7F00,0x760C,0x599E,0x377B,
  2099.     0x2031,0x12AD,0x0AD6,0x0649,0x03A5,0x01F5,0x00DC,0x0051,0x0023,
  2100.     0x0002,0xFFEE,0xFFE6,0xFFE7,0xFFEC,0xFFF3,0xFFF9,0xFFFF,0x0002,
  2101.     0x0004,0x0004,0x0003,0x0002,0x0001,0x0000,0x0000,0xFFFF,0x097F,
  2102.     0xE4D4,0xD636,0xC6FE,0x31B0,0x2314,0x0E82,0x2A8C,0x314E,0x4C62,
  2103.     0x1B03,0x0EA1,0x0750,0x4573,0x7F00,0x7F6E,0x66AE,0x3FAE,0x219D,
  2104.     0x11BE,0x095D,0x04F1,0x0257,0x011B,0x002D,0xFFA4,0xFF73,0xFF7D,
  2105.     0xFFA3,0xFFCF,0xFFF2,0x0008,0x0012,0x0012,0x000E,0x0008,0x0003,
  2106.     0x0000,0xFFFE,0xFFFD,0xFFFE,0xFFFE,0xFFFF,0x0000,0x0000,0xF1BA,
  2107.     0xE0B8,0xCE39,0xD4B0,0x3539,0x1CAE,0x0D02,0x2C42,0x3A0B,0x4951,
  2108.     0x1954,0x0CF7,0x067C,0x4E61,0x7F00,0x77EB,0x5274,0x2978,0x13D3,
  2109.     0x0979,0x0487,0x01DD,0x00C4,0x0001,0xFFA3,0xFF93,0xFFAE,0xFFD4,
  2110.     0xFFF4,0x0007,0x000E,0x000D,0x0009,0x0004,0x0000,0xFFFE,0xFFFE,
  2111.     0xFFFF,0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xE1AB,
  2112.     0xDD5D,0xC593,0xE91A,0x34EE,0x17FB,0x0BAC,0x2C14,0x429E,0x40DA,
  2113.     0x1781,0x0BA3,0x05D1,0x574F,0x7F00,0x6DB3,0x3CD8,0x1A34,0x0B48,
  2114.     0x04DB,0x0217,0x00BC,0x0020,0xFFD1,0xFFC0,0xFFD1,0xFFEA,0xFFFD,
  2115.     0x0007,0x0008,0x0005,0x0003,0x0000,0xFFFF,0xFFFF,0xFFFF,0x0000,
  2116.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xDC89,
  2117.     0xDAC4,0xBDC0,0xFEB1,0x32C9,0x14D5,0x0A90,0x2BB8,0x4936,0x3581,
  2118.     0x1551,0x0A8F,0x0547,0x603D,0x7F00,0x5FEC,0x2A63,0x1059,0x064E,
  2119.     0x026E,0x00B8,0x000F,0xFFC7,0xFFC5,0xFFDE,0xFFF7,0x0005,0x0008,
  2120.     0x0006,0x0002,0x0000,0xFFFF,0xFFFF,0x0000,0x0000,0x0000,0x0000,
  2121.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xDE80,
  2122.     0xD8C5,0xB789,0x1114,0x2F9E,0x12C9,0x09A8,0x2BDE,0x4D5B,0x2BA2,
  2123.     0x1359,0x09A9,0x04D4,0x692B,0x7F00,0x5057,0x1D06,0x09F6,0x036B,
  2124.     0x00D4,0x0033,0xFFE2,0xFFD5,0xFFE7,0xFFFA,0x0003,0x0005,0x0003,
  2125.     0x0001,0x0000,0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2126.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xE4D0,
  2127.     0xD70B,0xB2E4,0x1EB8,0x2BD7,0x1161,0x08E7,0x2D67,0x4F9C,0x2510,
  2128.     0x11C9,0x08E8,0x0474,0x7219,0x7C55,0x3F6B,0x133C,0x05D5,0x01C4,
  2129.     0x0056,0xFFF9,0xFFE0,0xFFEC,0xFFFB,0x0002,0x0003,0x0002,0x0000,
  2130.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2131.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xED7D,
  2132.     0xD522,0xB289,0x2800,0x27CE,0x1049,0x0842,0x30EC,0x50A9,0x2153,
  2133.     0x1082,0x0842,0x0421,0x7B07,0x73E8,0x2E8C,0x0C60,0x0349,0x0079,
  2134.     0x0011,0xFFEA,0xFFEE,0xFFFB,0x0002,0x0002,0x0001,0x0000,0x0000,
  2135.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2136.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xF6E3,
  2137.     0xD287,0xB4A8,0x2DF5,0x23D7,0x0F53,0x07B3,0x3641,0x50A6,0x1F47,
  2138.     0x0F66,0x07B3,0x03D9,0x7F00,0x6B22,0x20FE,0x079D,0x01C1,0x002D,
  2139.     0xFFF5,0xFFF0,0xFFFB,0x0001,0x0001,0x0001,0x0000,0x0000,0x0000,
  2140.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2141.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001D,
  2142.     0xCEB8,0xB9CD,0x3192,0x2037,0x0E6D,0x0736,0x3D2E,0x4F2F,0x1DEA,
  2143.     0x0E6C,0x0736,0x039B,0x7F00,0x622C,0x188C,0x04DD,0x00F6,0xFFB9,
  2144.     0xFFB2,0xFFEF,0x0008,0x0007,0x0001,0xFFFF,0x0000,0x0000,0x0000,
  2145.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2146.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x08B8,
  2147.     0xC94F,0xC47E,0x338E,0x1D17,0x0D96,0x06C8,0x4401,0x4BD3,0x1CA4,
  2148.     0x0D90,0x06C8,0x0364,0x7F00,0x5811,0x1100,0x02DB,0x0012,0xFF8B,
  2149.     0xFFD8,0x0008,0x0009,0x0002,0xFFFF,0xFFFF,0x0000,0x0000,0x0000,
  2150.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2151.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1065,
  2152.     0xC224,0xD328,0x3460,0x1A87,0x0CD1,0x0667,0x4B18,0x469A,0x1B42,
  2153.     0x0CCC,0x0667,0x0333,0x7F00,0x4CC9,0x0A92,0x017C,0xFF6C,0xFFAA,
  2154.     0x0002,0x000D,0x0003,0xFFFE,0x0000,0x0000,0x0000,0x0000,0x0000,
  2155.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2156.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x16E7,
  2157.     0xBA2A,0xDB0C,0x344D,0x187E,0x0C20,0x060F,0x5204,0x402F,0x19D8,
  2158.     0x0C1E,0x060F,0x0308,0x7F00,0x40F9,0x0781,0x00DD,0xFFA1,0xFFD9,
  2159.     0x0005,0x0005,0x0000,0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,
  2160.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2161.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1C0C,
  2162.     0xB0D2,0xE7CE,0x337D,0x16EA,0x0B82,0x05C1,0x5814,0x399A,0x1881,
  2163.     0x0B82,0x05C1,0x02E1,0x7F00,0x3535,0x04EF,0x0074,0xFFCB,0xFFF1,
  2164.     0x0004,0x0002,0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2165.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2166.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1FB5,
  2167.     0xAD77,0xF515,0x3209,0x15AE,0x0AF4,0x057A,0x5CA5,0x340E,0x174A,
  2168.     0x0AF4,0x057A,0x02BD,0x7F00,0x29BF,0x0308,0xFFC8,0xFFC8,0x0004,
  2169.     0x0004,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2170.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2171.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2170,
  2172.     0xB20F,0x01FC,0x300B,0x14AF,0x0A73,0x0539,0x6215,0x2FE7,0x1634,
  2173.     0x0A73,0x053A,0x029D,0x7F00,0x1EE1,0x01B1,0xFFDC,0xFFEA,0x0003,
  2174.     0x0001,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2175.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2176.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2128,
  2177.     0xB6D5,0x0E58,0x2D9F,0x13D8,0x09FE,0x04FF,0x68E7,0x2CD8,0x153A,
  2178.     0x09FD,0x04FF,0x027F,0x7F00,0x14ED,0x00D4,0xFFA1,0x0000,0x0004,
  2179.     0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2180.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2181.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1F29,
  2182.     0xA209,0x1989,0x2AEA,0x1313,0x0992,0x04C9,0x6FC3,0x2AA6,0x1456,
  2183.     0x0992,0x04C9,0x0264,0x7F00,0x0C3B,0x0053,0xFFDD,0x0002,0x0001,
  2184.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2185.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2186.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1BB0,
  2187.     0x8888,0x235E,0x2819,0x1258,0x092F,0x0498,0x7023,0x28FE,0x1384,
  2188.     0x092F,0x0497,0x024C,0x7F00,0x0780,0xFF65,0xFFF3,0x0004,0xFFFF,
  2189.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2190.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2191.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1740,
  2192.     0x808D,0x2BF1,0x255C,0x11A7,0x08D4,0x046A,0x7006,0x2781,0x12C3,
  2193.     0x08D4,0x046A,0x0235,0x7F00,0x0423,0xFFB7,0xFFFF,0x0000,0x0000,
  2194.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2195.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2196.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1215,
  2197.     0x800F,0x338F,0x22E6,0x10FF,0x087F,0x0440,0x6F1E,0x262F,0x120F,
  2198.     0x087F,0x043F,0x0220,0x7F00,0x01B2,0xFFEA,0x0001,0x0000,0x0000,
  2199.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2200.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2201.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0C3C,
  2202.     0x8000,0x3B79,0x20EE,0x1062,0x0831,0x0419,0x780C,0x24DF,0x1168,
  2203.     0x0831,0x0419,0x020C,0x7F00,0x004B,0xFFFA,0x0000,0x0000,0x0000,
  2204.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2205.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2206.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0541,
  2207.     0x8000,0x417D,0x1FAB,0x0FD0,0x07E9,0x03F4,0x7F00,0x2398,0x10CE,
  2208.     0x07E9,0x03F4,0x01FA,0x7E81,0x0188,0x0005,0x0000,0x0000,0x0000,
  2209.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2210.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2211.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFD3E,
  2212.     0x8000,0x45D7,0x1F45,0x0F49,0x07A4,0x03D2,0x7F00,0x228B,0x103D,
  2213.     0x07A5,0x03D2,0x01E9,0x79D0,0x0687,0x007A,0x000A,0x0000,0x0000,
  2214.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2215.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2216.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xF416,
  2217.     0x8000,0x49EB,0x1FE3,0x0ED7,0x0765,0x03B2,0x7F00,0x21A5,0x0FB6,
  2218.     0x0765,0x03B1,0x01D9,0x74CF,0x0C02,0x013C,0x0034,0x000B,0x0003,
  2219.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2220.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2221.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xE94C,
  2222.     0x8000,0x4D8B,0x21B2,0x0E9B,0x0729,0x0395,0x7F00,0x1F2E,0x0F31,
  2223.     0x0729,0x0394,0x01CB,0x6F7D,0x11D7,0x02DB,0x00CE,0x0042,0x0017,
  2224.     0x0008,0x0001,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2225.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  2226.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xDBED,
  2227.     0x8000,0x506B,0x24C0,0x0F01,0x06F8,0x0379,0x7F00,0x1956,0x0E68,
  2228.     0x06F0,0x0379,0x01BF,0x69DB,0x17E0,0x0563,0x0139,0x0087,0x0041,
  2229.     0x0021,0x0011,0x0007,0x0004,0x0002,0x0002,0x0002,0x0002,0x0002,
  2230.     0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
  2231.     0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0xCE57
  2232. };
  2233.  
  2234. static const int16_t lowFilterTable[NUM_WAVEFORMS * FILTER_ITERATIONS] =
  2235. {
  2236.     0x04A4,0x0526,0xFB66,0xEF30,0x9930,0xC5AD,0xF94C,0xFA32,0x09BE,
  2237.     0x0E1B,0x5703,0x6B3A,0x83A1,0x8C1C,0x996E,0xAB98,0xC1F8,0xDAA8,
  2238.     0xF375,0x0C42,0x2499,0x3BB1,0x50ED,0x63E3,0x744E,0x7F00,0x7F00,
  2239.     0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,
  2240.     0x7F00,0x7F00,0x7FEC,0x7F58,0x7FEE,0x7F36,0x7F93,0x7FDA,0x22B6,
  2241.     0x06E2,0x01FA,0xF97F,0xD0B0,0x9FBF,0xDEBF,0xF750,0x00F7,0x0CD8,
  2242.     0x26C6,0x64BB,0x70ED,0x86B8,0x9666,0xAF0A,0xCF0C,0xF0C8,0x127D,
  2243.     0x32F3,0x5058,0x6982,0x7DD7,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,
  2244.     0x7F00,0x7F00,0x7FFA,0x7FB8,0x7F87,0x7F00,0x7F99,0x7F00,0x7F4B,
  2245.     0x7F7E,0x7F9D,0x7FA9,0x7FA7,0x7F9B,0x7F88,0x7F70,0x7F56,0x1827,
  2246.     0x085D,0xFD8A,0xF58E,0xAAA0,0xB87E,0xE9B1,0xF78F,0x089F,0x1097,
  2247.     0x44D0,0x676B,0x7417,0x8ABF,0xA3D4,0xCA53,0xF4FD,0x1F5D,0x4681,
  2248.     0x6766,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7FE2,
  2249.     0x7F97,0x7F64,0x7FF4,0x7F25,0x7F5A,0x7F75,0x7F7C,0x7F74,0x7F62,
  2250.     0x7F4C,0x7F34,0x7F1E,0x7F0C,0x7EFE,0x7EF4,0x7EEE,0x7EEC,0x0E14,
  2251.     0x08C8,0xFA29,0xEA14,0x9750,0xCB17,0xED77,0xFA92,0x0D73,0x1B3D,
  2252.     0x5BC7,0x6C4C,0x7626,0x8FB7,0xB465,0xE741,0x1ACD,0x4A39,0x7012,
  2253.     0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F9B,
  2254.     0x7FE7,0x7FF5,0x7FDA,0x7FA9,0x7F70,0x7F3C,0x7F11,0x7EF4,0x7EE2,
  2255.     0x7EDC,0x7EDD,0x7EE2,0x7EE9,0x7EF1,0x7EF8,0x7EFD,0x7F01,0x1F29,
  2256.     0x07B7,0xF8BB,0xD9E8,0x9ADB,0xD85A,0xEF6F,0x0056,0x105E,0x2993,
  2257.     0x6293,0x6F41,0x779A,0x95A1,0xC7C2,0x0448,0x3E6E,0x6CE0,0x7F00,
  2258.     0x7F00,0x7F00,0x7F00,0x7F00,0x7FDE,0x7F77,0x7FFF,0x7F13,0x7F29,
  2259.     0x7F2D,0x7F27,0x7F1B,0x7F0F,0x7F04,0x7EFD,0x7EF9,0x7EF8,0x7EF9,
  2260.     0x7EFA,0x7EFC,0x7EFE,0x7EFF,0x7F00,0x7F00,0x7F00,0x7EFF,0x38C1,
  2261.     0x056D,0xF814,0xC623,0xA713,0xE15B,0xF142,0x07C2,0x1262,0x38E2,
  2262.     0x63C5,0x715B,0x78AE,0x9C7C,0xDBB2,0x2144,0x5DAB,0x7F00,0x7F00,
  2263.     0x7F00,0x7F00,0x7F00,0x7F00,0x7FC4,0x7FFA,0x7FD7,0x7F8E,0x7F43,
  2264.     0x7F0A,0x7EEA,0x7EDE,0x7EE0,0x7EE8,0x7EF2,0x7EFB,0x7F00,0x7F03,
  2265.     0x7F03,0x7F02,0x7F01,0x7F00,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x44FF,
  2266.     0x022D,0xF638,0xB1EC,0xB3D3,0xE6DC,0xF2F4,0x1027,0x1555,0x4964,
  2267.     0x65A0,0x7308,0x7983,0xA447,0xEFC0,0x3BF3,0x755D,0x7F00,0x7F00,
  2268.     0x7F00,0x7F00,0x7F00,0x7FA2,0x7FBC,0x7F8E,0x7F4A,0x7F13,0x7EF2,
  2269.     0x7EE6,0x7EE8,0x7EF0,0x7EF8,0x7EFE,0x7F01,0x7F02,0x7F01,0x7F00,
  2270.     0x7EFF,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x3F9E,
  2271.     0xFE6E,0xF23E,0xA271,0xBEFF,0xEA01,0xF459,0x186B,0x1AB5,0x58FD,
  2272.     0x6858,0x745C,0x7A2D,0xAD04,0x0454,0x552E,0x7F00,0x7F00,0x7F00,
  2273.     0x7F00,0x7FB7,0x7F40,0x7F6E,0x7F58,0x7F2D,0x7F08,0x7EF5,0x7EF0,
  2274.     0x7EF4,0x7EF9,0x7EFD,0x7F00,0x7F00,0x7F00,0x7EFF,0x7EFE,0x7EFE,
  2275.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x347C,
  2276.     0xFAB9,0xED47,0x9AA4,0xC870,0xEBE1,0xF572,0x1E07,0x2265,0x6469,
  2277.     0x6AD4,0x7570,0x7AB7,0xB6B2,0x16F0,0x681C,0x7F00,0x7F00,0x7F00,
  2278.     0x7FEB,0x7F45,0x7F6C,0x7F4A,0x7F1C,0x7EFC,0x7EF1,0x7EF3,0x7EF9,
  2279.     0x7EFE,0x7F00,0x7F00,0x7F00,0x7EFF,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2280.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x28BB,
  2281.     0xF78E,0xE420,0x99DD,0xD05D,0xED36,0xF656,0x2213,0x2B5A,0x6A73,
  2282.     0x6CB8,0x7655,0x7B2A,0xC151,0x2A7D,0x790E,0x7F00,0x7F00,0x7F00,
  2283.     0x7F00,0x7F48,0x7F3B,0x7F18,0x7EFF,0x7EF6,0x7EF7,0x7EFB,0x7EFE,
  2284.     0x7F00,0x7F00,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2285.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x1E75,
  2286.     0xF544,0xD834,0x9DAA,0xD6E9,0xEE5D,0xF717,0x24B5,0x34A1,0x6D21,
  2287.     0x6E35,0x7717,0x7B8B,0xCCE1,0x3DC8,0x7F00,0x7F00,0x7F00,0x7FCB,
  2288.     0x7F26,0x7F30,0x7F16,0x7F00,0x7EF9,0x7EFA,0x7EFC,0x7EFF,0x7EFF,
  2289.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2290.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x16D0,
  2291.     0xF3F4,0xCBF1,0xA3BF,0xDC27,0xEF79,0xF7BC,0x26A4,0x3DE3,0x6E84,
  2292.     0x6F7A,0x77BC,0x7BDE,0xD962,0x4F0B,0x7F00,0x7F00,0x7F00,0x7F00,
  2293.     0x7F26,0x7F16,0x7F02,0x7EFB,0x7EFB,0x7EFE,0x7EFF,0x7EFF,0x7EFF,
  2294.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2295.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x11F0,
  2296.     0xF371,0xC1E6,0xAAA0,0xE033,0xF08A,0xF84C,0x28A1,0x4735,0x6FC4,
  2297.     0x7098,0x784C,0x7C25,0xE441,0x5DE5,0x7F00,0x7F00,0x7FE9,0x7F17,
  2298.     0x7F16,0x7F05,0x7EFC,0x7EFC,0x7EFD,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2299.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2300.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x0F7C,
  2301.     0xF342,0xB6DF,0xB189,0xE338,0xF187,0xF8C9,0x2B06,0x509A,0x7144,
  2302.     0x7193,0x78C8,0x7C63,0xED84,0x6A6B,0x7F00,0x7F00,0x7F88,0x7F73,
  2303.     0x7F12,0x7EEF,0x7EF4,0x7EFE,0x7F00,0x7F00,0x7EFF,0x7EFF,0x7EFF,
  2304.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2305.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x0F12,
  2306.     0xF2B4,0xAA33,0xB822,0xE56F,0xF269,0xF936,0x2EE9,0x59B0,0x72F5,
  2307.     0x726E,0x7936,0x7C9A,0xF717,0x75F2,0x7F00,0x7F00,0x7FBB,0x7F39,
  2308.     0x7EF0,0x7EF0,0x7EFD,0x7F01,0x7F00,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2309.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2310.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x1051,
  2311.     0xF0E3,0xA18C,0xBE4C,0xE714,0xF330,0xF998,0x33B3,0x61CB,0x74A7,
  2312.     0x7332,0x7998,0x7CCB,0x00FB,0x7FF6,0x7F00,0x7FED,0x7F8C,0x7EFC,
  2313.     0x7EEA,0x7EFB,0x7F01,0x7F00,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2314.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2315.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x12E5,
  2316.     0xECCF,0x98BC,0xC3FC,0xE858,0xF3E1,0xF9EF,0x39A7,0x6850,0x7630,
  2317.     0x73E0,0x79EF,0x7CF7,0x0B2F,0x7F00,0x7F00,0x7F91,0x7F44,0x7EF7,
  2318.     0x7EF5,0x7EFE,0x7F00,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2319.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2320.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x167B,
  2321.     0xE76E,0x93CA,0xC92C,0xE964,0xF47D,0xFA3E,0x40A5,0x6D08,0x778A,
  2322.     0x747D,0x7A3E,0x7D1E,0x15B3,0x7F00,0x7F00,0x7F50,0x7F1D,0x7EF9,
  2323.     0x7EFB,0x7EFF,0x7EFF,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2324.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2325.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x1AF2,
  2326.     0xDD31,0x9374,0xCDD7,0xEA52,0xF50B,0xFA85,0x484D,0x700F,0x78BA,
  2327.     0x750B,0x7A84,0x7D42,0x2088,0x7F00,0x7F00,0x7F6F,0x7EFF,0x7EF6,
  2328.     0x7EFE,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2329.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2330.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x1FAB,
  2331.     0xD337,0x963B,0xD1F3,0xEB33,0xF58C,0xFAC5,0x4D79,0x721D,0x79CB,
  2332.     0x758C,0x7AC5,0x7D62,0x2BAD,0x7F00,0x7F00,0x7F31,0x7EFC,0x7EFC,
  2333.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2334.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2335.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x241F,
  2336.     0xCC6D,0x9B30,0xD57A,0xEC0B,0xF601,0xFB00,0x5244,0x73C4,0x7AC4,
  2337.     0x7601,0x7B00,0x7D7F,0x3722,0x7F00,0x7FA9,0x7F11,0x7EF6,0x7EFF,
  2338.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2339.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2340.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x280C,
  2341.     0xBE21,0xA145,0xD867,0xECDA,0xF66D,0xFB36,0x55B1,0x7546,0x7BA8,
  2342.     0x766D,0x7B36,0x7D9A,0x42E8,0x7F00,0x7F45,0x7F02,0x7EFC,0x7EFF,
  2343.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2344.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2345.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x2B18,
  2346.     0xA865,0xA7BA,0xDAC1,0xED9F,0xF6CF,0xFB67,0x5207,0x76C6,0x7C7B,
  2347.     0x76CF,0x7B67,0x7DB3,0x4EFE,0x7F00,0x7F4F,0x7EF5,0x7EFF,0x7EFF,
  2348.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2349.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2350.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x2D13,
  2351.     0xB2BE,0xAE1E,0xDC9C,0xEE56,0xF72B,0xFB95,0x4C1E,0x7845,0x7D3D,
  2352.     0x772B,0x7B95,0x7DC9,0x5B64,0x7F00,0x7F17,0x7EFC,0x7EFF,0x7EFF,
  2353.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2354.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2355.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x2E1B,
  2356.     0xCE29,0xB467,0xDE0E,0xEEFF,0xF77F,0xFBBF,0x4843,0x79BD,0x7DF0,
  2357.     0x777F,0x7BBE,0x7DDE,0x681B,0x7F00,0x7F02,0x7EFF,0x7EFF,0x7EFF,
  2358.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2359.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2360.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x2E32,
  2361.     0xE25E,0xBB9A,0xDF40,0xEF9C,0xF7CD,0xFBE6,0x68ED,0x7B21,0x7E96,
  2362.     0x77CD,0x7BE6,0x7DF1,0x7522,0x7F49,0x7EFE,0x7EFF,0x7EFF,0x7EFF,
  2363.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2364.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,
  2365.     0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x7EFF,0x2D4F,
  2366.     0xF4E0,0xC241,0xE05F,0xF02D,0xF817,0xFC0A,0x77E5,0x7C6A,0x7F31,
  2367.     0x7817,0x7C0B,0x7E05,0x7F00,0x7F0C,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2368.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2369.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2370.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x2B1D,
  2371.     0xEB4A,0xC91D,0xE1A6,0xF0B7,0xF85A,0xFC2C,0x6D81,0x7DA5,0x7FC1,
  2372.     0x785A,0x7C2D,0x7E16,0x7F00,0x7FD9,0x7F18,0x7F01,0x7EFE,0x7EFE,
  2373.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2374.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2375.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x2782,
  2376.     0xE163,0xCFFB,0xE34C,0xF13A,0xF89A,0xFC4C,0x615E,0x7ED9,0x7F00,
  2377.     0x7899,0x7C4B,0x7E26,0x7F00,0x7F00,0x7F44,0x7F0F,0x7F03,0x7F00,
  2378.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2379.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2380.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x2237,
  2381.     0xD728,0xD6A1,0xE592,0xF1CA,0xF8D5,0xFC6B,0x5DFA,0x7F58,0x7F00,
  2382.     0x78D6,0x7C6A,0x7E35,0x7F00,0x7F00,0x7FD9,0x7F4F,0x7F19,0x7F08,
  2383.     0x7F02,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2384.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,
  2385.     0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x7EFE,0x1A9B,
  2386.     0xCC9C,0xDCAB,0xE8B3,0xF2A3,0xF910,0xFC86,0x7B5E,0x7DF6,0x7F00,
  2387.     0x790C,0x7C86,0x7E44,0x7F00,0x7F00,0x7F00,0x7F74,0x7F3D,0x7F1D,
  2388.     0x7F0E,0x7F06,0x7F02,0x7F01,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,
  2389.     0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,
  2390.     0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x7F00,0x12E3
  2391. };
  2392.  
  2393. /* the following must be changed if you want to use another audio API than WinMM */
  2394.  
  2395. #ifndef WIN32_LEAN_AND_MEAN
  2396. #define WIN32_LEAN_AND_MEAN
  2397. #endif
  2398.  
  2399. #include <windows.h>
  2400. #include <mmsystem.h>
  2401.  
  2402. #define MIX_BUF_NUM 2
  2403.  
  2404. static volatile BOOL audioRunningFlag;
  2405. static uint8_t currBuffer;
  2406. static int16_t *mixBuffer[MIX_BUF_NUM];
  2407. static HANDLE hThread, hAudioSem;
  2408. static WAVEHDR waveBlocks[MIX_BUF_NUM];
  2409. static HWAVEOUT hWave;
  2410.  
  2411. static DWORD WINAPI mixThread(LPVOID lpParam)
  2412. {
  2413.     WAVEHDR *waveBlock;
  2414.  
  2415.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
  2416.  
  2417.     while (audioRunningFlag)
  2418.     {
  2419.         waveBlock = &waveBlocks[currBuffer];
  2420.         ahx1play_FillAudioBuffer((int16_t *)(waveBlock->lpData), MIX_BUF_SAMPLES);
  2421.         waveOutWrite(hWave, waveBlock, sizeof (WAVEHDR));
  2422.         currBuffer = (currBuffer + 1) % MIX_BUF_NUM;
  2423.  
  2424.         /* wait for buffer fill request */
  2425.         WaitForSingleObject(hAudioSem, INFINITE);
  2426.     }
  2427.  
  2428.     (void)(lpParam); /* make compiler happy! */
  2429.  
  2430.     return (0);
  2431. }
  2432.  
  2433. static void CALLBACK waveProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
  2434. {
  2435.     if (uMsg == WOM_DONE)
  2436.         ReleaseSemaphore(hAudioSem, 1, NULL);
  2437.  
  2438.     /* make compiler happy! */
  2439.     (void)(hWaveOut);
  2440.     (void)(uMsg);
  2441.     (void)(dwInstance);
  2442.     (void)(dwParam1);
  2443.     (void)(dwParam2);
  2444. }
  2445.  
  2446. static void closeMixer(void)
  2447. {
  2448.     int32_t i;
  2449.  
  2450.     audioRunningFlag = false; /* make thread end when it's done */
  2451.  
  2452.     if (hAudioSem != NULL)
  2453.         ReleaseSemaphore(hAudioSem, 1, NULL);
  2454.  
  2455.     if (hThread != NULL)
  2456.     {
  2457.         WaitForSingleObject(hThread, INFINITE);
  2458.         CloseHandle(hThread);
  2459.         hThread = NULL;
  2460.     }
  2461.  
  2462.     if (hAudioSem != NULL)
  2463.     {
  2464.         CloseHandle(hAudioSem);
  2465.         hAudioSem = NULL;
  2466.     }
  2467.  
  2468.     if (hWave != NULL)
  2469.     {
  2470.         waveOutReset(hWave);
  2471.  
  2472.         for (i = 0; i < MIX_BUF_NUM; ++i)
  2473.         {
  2474.             if (waveBlocks[i].dwUser != 0xFFFF)
  2475.                 waveOutUnprepareHeader(hWave, &waveBlocks[i], sizeof (WAVEHDR));
  2476.         }
  2477.  
  2478.         waveOutClose(hWave);
  2479.         hWave = NULL;
  2480.     }
  2481.  
  2482.     for (i = 0; i < MIX_BUF_NUM; ++i)
  2483.     {
  2484.         if (mixBuffer[i] != NULL)
  2485.         {
  2486.             free(mixBuffer[i]);
  2487.             mixBuffer[i] = NULL;
  2488.         }
  2489.     }
  2490. }
  2491.  
  2492. static int8_t openMixer(uint32_t audioFreq)
  2493. {
  2494.     int32_t i;
  2495.     DWORD threadID;
  2496.     WAVEFORMATEX wfx;
  2497.  
  2498.     /* don't unprepare headers on error */
  2499.     for (i = 0; i < MIX_BUF_NUM; ++i)
  2500.         waveBlocks[i].dwUser = 0xFFFF;
  2501.  
  2502.     closeMixer();
  2503.  
  2504.     ZeroMemory(&wfx, sizeof (wfx));
  2505.     wfx.nSamplesPerSec  = audioFreq;
  2506.     wfx.wBitsPerSample  = 16;
  2507.     wfx.nChannels       = 2;
  2508.     wfx.wFormatTag      = WAVE_FORMAT_PCM;
  2509.     wfx.nBlockAlign     = wfx.nChannels * (wfx.wBitsPerSample / 8);
  2510.     wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
  2511.  
  2512.     samplesPerFrameLeft = 0;
  2513.     currBuffer = 0;
  2514.  
  2515.     if (waveOutOpen(&hWave, WAVE_MAPPER, &wfx, (DWORD_PTR)(&waveProc), 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
  2516.         goto omError;
  2517.  
  2518.     /* create semaphore for buffer fill requests */
  2519.     hAudioSem = CreateSemaphore(NULL, MIX_BUF_NUM - 1, MIX_BUF_NUM, NULL);
  2520.     if (hAudioSem == NULL)
  2521.         goto omError;
  2522.  
  2523.     /* allocate WinMM mix buffers */
  2524.     for (i = 0; i < MIX_BUF_NUM; ++i)
  2525.     {
  2526.         mixBuffer[i] = (int16_t *)(calloc(MIX_BUF_SAMPLES, wfx.nBlockAlign));
  2527.         if (mixBuffer[i] == NULL)
  2528.             goto omError;
  2529.     }
  2530.  
  2531.     /* initialize WinMM mix headers */
  2532.     memset(waveBlocks, 0, sizeof (waveBlocks));
  2533.     for (i = 0; i < MIX_BUF_NUM; ++i)
  2534.     {
  2535.         waveBlocks[i].lpData = (LPSTR)(mixBuffer[i]);
  2536.         waveBlocks[i].dwBufferLength = MIX_BUF_SAMPLES * wfx.nBlockAlign;
  2537.         waveBlocks[i].dwFlags = WHDR_DONE;
  2538.  
  2539.         if (waveOutPrepareHeader(hWave, &waveBlocks[i], sizeof (WAVEHDR)) != MMSYSERR_NOERROR)
  2540.             goto omError;
  2541.     }
  2542.  
  2543.     /* create main mixer thread */
  2544.     audioRunningFlag = true;
  2545.     hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(mixThread), NULL, 0, &threadID);
  2546.     if (hThread == NULL)
  2547.         goto omError;
  2548.  
  2549.     return (TRUE);
  2550.  
  2551. omError:
  2552.     closeMixer();
  2553.     return (FALSE);
  2554. }
  2555.  
  2556. /* --------------------------------------------------------------------------- */
  2557.  
  2558. /* END OF FILE (phew...) */
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top