Advertisement
8bitbubsy

pt2play v1.61

Sep 29th, 2013 (edited)
2,872
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 54.51 KB | None | 0 0
  1. /*
  2. ** pt2play v1.61 - 14th of December 2020 - https://16-bits.org
  3. ** ===========================================================
  4. **              - NOT BIG ENDIAN SAFE! -
  5. **
  6. ** Very accurate C port of ProTracker 2.3D's replayer, by
  7. ** Olav "8bitbubsy" Sorensen. Based on a ProTracker 2.3D disassembly
  8. ** using the PT1.2A source code for labels (names).
  9. **
  10. ** NOTE: This replayer does not support 15-sample formats!
  11. **
  12. ** The BLEP (Band-Limited Step) and filter routines were coded by aciddose.
  13. ** This makes the replayer sound much closer to a real Amiga.
  14. **
  15. ** You need to link winmm.lib for this to compile (-lwinmm).
  16. ** Alternatively, you can change out the mixer functions at the bottom with
  17. ** your own for your OS.
  18. **
  19. ** Example of pt2play usage:
  20. ** #include "pt2play.h"
  21. ** #include "songdata.h"
  22. **
  23. ** pt2play_PlaySong(songData, songDataLength, CIA_TEMPO_MODE, 48000);
  24. ** mainLoop();
  25. ** pt2play_Close();
  26. **
  27. ** To turn a song into an include file like in the example, you can use my win32
  28. ** bin2h tool from here: https://16-bits.org/etc/bin2h.zip
  29. **
  30. ** Changes in v1.61:
  31. ** - In SetSpeed(), only reset Counter if not setting the BPM
  32. ** - Small logic cleanup in PlayVoice()
  33. **
  34. ** Changes in v1.60:
  35. ** - Removed fiter cutoff tweaks, and added new RC filter + "LED" filter routines
  36. ** - The arpeggio effect is now 100% accurate in its overflow behavior
  37. ** - Some cosmetic changes to the code
  38. **
  39. ** Changes in v1.59:
  40. ** - Added pt2play_SetMasterVol() and pt2play_GetMasterVol()
  41. **
  42. ** Changes in v1.58:
  43. ** - Fixed a serious bug where most songs would not play unless they had a tempo
  44. **   command issued.
  45. ** - Audio mixer has been slightly optimized
  46. ** - Audio dithering has been improved (rectangular -> triangular)
  47. **
  48. ** Changes in v1.57:
  49. ** - Audio signal phase is now inverted on output, like on A500/1200.
  50. **   This can actually change the bass response depending on your speaker elements.
  51. **   In my case, on Sennheiser HD598, I get deeper bass (same as on my Amigas).
  52. ** - All filters (low-pass, "LED", high-pass) have been hand-tweaked to better
  53. **   match A500 and A1200 from intensive testing and waveform comparison.
  54. **   Naturally, the analog filters vary from unit to unit because of component
  55. **   tolerance and aging components, but I am quite confident that this is a
  56. **   closer match than before anyway.
  57. ** - Added audio mixer dithering
  58. **
  59. ** Changes in v1.56:
  60. ** - Fixed EDx (Note Delay) not working
  61. ** - Minor code cleanup
  62. **
  63. ** Changes in v1.55:
  64. ** - Mixer is now using double-precision instead of single-precision accuracy.
  65. **
  66. ** Changes in v1.54:
  67. ** - Code cleanup (uses the "bool" type now, spaces -> tabs, comment style change)
  68. **
  69. ** Changes in v1.53:
  70. ** - Some code cleanup
  71. ** - Small optimziation to audio mixer
  72. **
  73. ** Changes in v1.52:
  74. ** - Added a function to retrieve song name
  75. **
  76. ** Changes in v1.51:
  77. ** - WinMM mixer has been rewritten to be safe (don't use syscalls in callback)
  78. ** - Some small changes to the pt2play functions (easier to use and safer!)
  79. */
  80.  
  81. /* pt2play.h:
  82.  
  83. #pragma once
  84.  
  85. #include <stdint.h>
  86. #include <stdbool.h>
  87.  
  88. enum
  89. {
  90.     CIA_TEMPO_MODE = 0, // default
  91.     VBLANK_TEMPO_MODE = 1
  92. };
  93.  
  94. bool pt2play_PlaySong(const uint8_t *moduleData, uint32_t dataLength, int8_t tempoMode, uint32_t audioFreq);
  95. void pt2play_Close(void);
  96. void pt2play_PauseSong(bool flag); // true/false
  97. void pt2play_TogglePause(void);
  98. void pt2play_SetStereoSep(uint8_t percentage); // 0..100
  99. void pt2play_SetMasterVol(uint16_t vol); // 0..256
  100. uint16_t pt2play_GetMasterVol(void); // 0..256
  101. char *pt2play_GetSongName(void); // max 20 chars (21 with '\0'), string is in latin1
  102. uint32_t pt2play_GetMixerTicks(void); // returns the amount of milliseconds of mixed audio (not realtime)
  103. */
  104.  
  105. // == USER ADJUSTABLE SETTINGS ==
  106. #define STEREO_SEP (20)    /* --> Stereo separation in percent - 0 = mono, 100 = hard pan (like Amiga) */
  107. #define USE_HIGHPASS       /* --> ~5.2Hz HP filter present in all Amigas */
  108. //#define USE_LOWPASS      /* --> ~4.42kHz LP filter present in all Amigas (except A1200) - comment out for sharper sound */
  109. #define USE_BLEP           /* --> Reduces some aliasing in the sound (closer to real Amiga) - comment out for a speed-up */
  110. //#define ENABLE_E8_EFFECT /* --> Enable E8x (Karplus-Strong) - comment out this line if E8x is used for something else */
  111. #define LED_FILTER         /* --> Process the Amiga "LED" filter - comment out to disable */
  112. #define MIX_BUF_SAMPLES 4096
  113.  
  114. #include <stdio.h>
  115. #include <stdlib.h>
  116. #include <string.h>
  117. #include <stdint.h>
  118. #include <stdbool.h>
  119. #include <math.h> // tan()
  120.  
  121. enum
  122. {
  123.     CIA_TEMPO_MODE = 0,
  124.     VBLANK_TEMPO_MODE = 1
  125. };
  126.  
  127. // main crystal oscillator
  128. #define AMIGA_PAL_XTAL_HZ 28375160
  129.  
  130. #define PAULA_PAL_CLK (AMIGA_PAL_XTAL_HZ / 8)
  131. #define CIA_PAL_CLK (AMIGA_PAL_XTAL_HZ / 40)
  132.  
  133. #define MAX_SAMPLE_LEN (0xFFFF*2)
  134. #define AMIGA_VOICES 4
  135.  
  136. #define INITIAL_DITHER_SEED 0x12345000
  137.  
  138. #ifdef USE_BLEP // do not change these!
  139. #define BLEP_ZC 16
  140. #define BLEP_OS 16
  141. #define BLEP_SP 16
  142. #define BLEP_NS (BLEP_ZC * BLEP_OS / BLEP_SP)
  143. #define BLEP_RNS 31 // RNS = (2^ > NS) - 1
  144. #endif
  145.  
  146. #ifdef USE_BLEP
  147. typedef struct blep_t
  148. {
  149.     int32_t index, samplesLeft;
  150.     double dBuffer[BLEP_RNS + 1], dLastValue;
  151. } blep_t;
  152. #endif
  153.  
  154. typedef struct ptChannel_t
  155. {
  156.     int8_t *n_start, *n_wavestart, *n_loopstart, n_chanindex, n_volume;
  157.     int8_t n_toneportdirec, n_pattpos, n_loopcount;
  158.     uint8_t n_wavecontrol, n_glissfunk, n_sampleoffset, n_toneportspeed;
  159.     uint8_t n_vibratocmd, n_tremolocmd, n_finetune, n_funkoffset;
  160.     uint8_t n_vibratopos, n_tremolopos;
  161.     int16_t n_period, n_note, n_wantedperiod;
  162.     uint16_t n_cmd, n_length, n_replen;
  163. } ptChannel_t;
  164.  
  165. typedef struct paulaVoice_t
  166. {
  167.     volatile bool active;
  168.     const int8_t *data, *newData;
  169.     int32_t length, newLength, pos;
  170.     double dVolume, dDelta, dPhase, dPanL, dPanR;
  171. #ifdef USE_BLEP
  172.     double dDeltaMul, dLastDelta, dLastPhase, dLastDeltaMul;
  173. #endif
  174. } paulaVoice_t;
  175.  
  176. #if defined(USE_HIGHPASS) || defined(USE_LOWPASS)
  177. typedef struct rcFilter_t
  178. {
  179.     double buffer[2];
  180.     double c, c2, g, cg;
  181. } rcFilter_t;
  182. #endif
  183.  
  184. #ifdef LED_FILTER
  185.  
  186. #define DENORMAL_OFFSET 1e-10
  187. typedef struct ledFilter_t
  188. {
  189.     double buffer[4];
  190.     double c, ci, feedback, bg, cg, c2;
  191. } ledFilter_t;
  192. #endif
  193.  
  194. static char songName[20 + 1];
  195. static volatile bool musicPaused, SongPlaying;
  196. static bool PBreakFlag, PosJumpAssert;
  197. static int8_t *SampleStarts[31], *SampleData, TempoMode, SongPosition, EmptySample[MAX_SAMPLE_LEN];
  198. static int8_t PBreakPosition, PattDelTime, PattDelTime2;
  199. static uint8_t SetBPMFlag, *SongDataPtr, LowMask, Counter, CurrSpeed, stereoSep = STEREO_SEP;
  200. static uint16_t PatternPos, bpmTab[256-32];
  201. static int32_t soundBufferSize, audioRate, samplesPerTickLeft, samplesPerTick, oldPeriod;
  202. static int32_t randSeed = INITIAL_DITHER_SEED, masterVol = 256;
  203. static uint32_t PattPosOff, sampleCounter;
  204. static double dOldVoiceDelta, dPeriodToDeltaDiv, *dMixBufferL, *dMixBufferR;
  205. static double dPrngStateL, dPrngStateR;
  206. static ptChannel_t ChanTemp[AMIGA_VOICES];
  207. static paulaVoice_t paula[AMIGA_VOICES];
  208. #ifdef USE_BLEP
  209. static double dOldVoiceDeltaMul;
  210. static blep_t blep[AMIGA_VOICES], blepVol[AMIGA_VOICES];
  211. #endif
  212. #ifdef USE_HIGHPASS
  213. static rcFilter_t filterHi;
  214. #endif
  215. #ifdef USE_LOWPASS
  216. static rcFilter_t filterLo;
  217. #endif
  218. #ifdef LED_FILTER
  219. static ledFilter_t filterLED;
  220. static bool LEDFilterOn;
  221. #endif
  222.  
  223. static const uint8_t ArpTickTable[32] = // not from PT2 replayer
  224. {
  225.     0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,
  226.     0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,
  227.     0,1
  228. };
  229.  
  230. static const uint8_t FunkTable[16] =
  231. {
  232.     0x00, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0D,
  233.     0x10, 0x13, 0x16, 0x1A, 0x20, 0x2B, 0x40, 0x80
  234. };
  235.  
  236. static const uint8_t VibratoTable[32] =
  237. {
  238.     0x00, 0x18, 0x31, 0x4A, 0x61, 0x78, 0x8D, 0xA1,
  239.     0xB4, 0xC5, 0xD4, 0xE0, 0xEB, 0xF4, 0xFA, 0xFD,
  240.     0xFF, 0xFD, 0xFA, 0xF4, 0xEB, 0xE0, 0xD4, 0xC5,
  241.     0xB4, 0xA1, 0x8D, 0x78, 0x61, 0x4A, 0x31, 0x18
  242. };
  243.  
  244. static const int16_t PeriodTable[(37*16)+15] =
  245. {
  246.     856,808,762,720,678,640,604,570,538,508,480,453,
  247.     428,404,381,360,339,320,302,285,269,254,240,226,
  248.     214,202,190,180,170,160,151,143,135,127,120,113,0,
  249.     850,802,757,715,674,637,601,567,535,505,477,450,
  250.     425,401,379,357,337,318,300,284,268,253,239,225,
  251.     213,201,189,179,169,159,150,142,134,126,119,113,0,
  252.     844,796,752,709,670,632,597,563,532,502,474,447,
  253.     422,398,376,355,335,316,298,282,266,251,237,224,
  254.     211,199,188,177,167,158,149,141,133,125,118,112,0,
  255.     838,791,746,704,665,628,592,559,528,498,470,444,
  256.     419,395,373,352,332,314,296,280,264,249,235,222,
  257.     209,198,187,176,166,157,148,140,132,125,118,111,0,
  258.     832,785,741,699,660,623,588,555,524,495,467,441,
  259.     416,392,370,350,330,312,294,278,262,247,233,220,
  260.     208,196,185,175,165,156,147,139,131,124,117,110,0,
  261.     826,779,736,694,655,619,584,551,520,491,463,437,
  262.     413,390,368,347,328,309,292,276,260,245,232,219,
  263.     206,195,184,174,164,155,146,138,130,123,116,109,0,
  264.     820,774,730,689,651,614,580,547,516,487,460,434,
  265.     410,387,365,345,325,307,290,274,258,244,230,217,
  266.     205,193,183,172,163,154,145,137,129,122,115,109,0,
  267.     814,768,725,684,646,610,575,543,513,484,457,431,
  268.     407,384,363,342,323,305,288,272,256,242,228,216,
  269.     204,192,181,171,161,152,144,136,128,121,114,108,0,
  270.     907,856,808,762,720,678,640,604,570,538,508,480,
  271.     453,428,404,381,360,339,320,302,285,269,254,240,
  272.     226,214,202,190,180,170,160,151,143,135,127,120,0,
  273.     900,850,802,757,715,675,636,601,567,535,505,477,
  274.     450,425,401,379,357,337,318,300,284,268,253,238,
  275.     225,212,200,189,179,169,159,150,142,134,126,119,0,
  276.     894,844,796,752,709,670,632,597,563,532,502,474,
  277.     447,422,398,376,355,335,316,298,282,266,251,237,
  278.     223,211,199,188,177,167,158,149,141,133,125,118,0,
  279.     887,838,791,746,704,665,628,592,559,528,498,470,
  280.     444,419,395,373,352,332,314,296,280,264,249,235,
  281.     222,209,198,187,176,166,157,148,140,132,125,118,0,
  282.     881,832,785,741,699,660,623,588,555,524,494,467,
  283.     441,416,392,370,350,330,312,294,278,262,247,233,
  284.     220,208,196,185,175,165,156,147,139,131,123,117,0,
  285.     875,826,779,736,694,655,619,584,551,520,491,463,
  286.     437,413,390,368,347,328,309,292,276,260,245,232,
  287.     219,206,195,184,174,164,155,146,138,130,123,116,0,
  288.     868,820,774,730,689,651,614,580,547,516,487,460,
  289.     434,410,387,365,345,325,307,290,274,258,244,230,
  290.     217,205,193,183,172,163,154,145,137,129,122,115,0,
  291.     862,814,768,725,684,646,610,575,543,513,484,457,
  292.     431,407,384,363,342,323,305,288,272,256,242,228,
  293.     216,203,192,181,171,161,152,144,136,128,121,114,0,
  294.  
  295.     /* Arpeggio on -1 finetuned samples can do an overflown read from
  296.     ** the period table. Here's the correct overflow values from the
  297.     ** "CursorPosTable" and "UnshiftedKeymap" table, which are located
  298.     ** right after the period table. These tables and their order didn't
  299.     ** seem to change in the different PT1.x/PT2.x versions (I checked
  300.     ** the source codes).
  301.     ** PS: This is not a guess, these values *are* correct!
  302.     */
  303.     774,1800,2314,3087,4113,4627,5400,6426,6940,7713,
  304.     8739,9253,24625,12851,13365
  305. };
  306.  
  307. #ifdef USE_BLEP
  308. /* Why this table is not represented as readable floating-point numbers:
  309. ** Accurate double representation in string format requires at least 14 digits and normalized
  310. ** (scientific) notation, notwithstanding compiler issues with precision or rounding error.
  311. ** Also, don't touch this table ever, just keep it exactly identical!
  312. */
  313. static const uint64_t minblepdata[] =
  314. {
  315.     0x3FF000320C7E95A6,0x3FF00049BE220FD5,0x3FF0001B92A41ACA,0x3FEFFF4425AA9724,
  316.     0x3FEFFDABDF6CF05C,0x3FEFFB5AF233EF1A,0x3FEFF837E2AE85F3,0x3FEFF4217B80E938,
  317.     0x3FEFEEECEB4E0444,0x3FEFE863A8358B5F,0x3FEFE04126292670,0x3FEFD63072A0D592,
  318.     0x3FEFC9C9CD36F56F,0x3FEFBA90594BD8C3,0x3FEFA7F008BA9F13,0x3FEF913BE2A0E0E2,
  319.     0x3FEF75ACCB01A327,0x3FEF5460F06A4E8F,0x3FEF2C5C0389BD3C,0x3FEEFC8859BF6BCB,
  320.     0x3FEEC3B916FD8D19,0x3FEE80AD74F0AD16,0x3FEE32153552E2C7,0x3FEDD69643CB9778,
  321.     0x3FED6CD380FFA864,0x3FECF374A4D2961A,0x3FEC692F19B34E54,0x3FEBCCCFA695DD5C,
  322.     0x3FEB1D44B168764A,0x3FEA59A8D8E4527F,0x3FE9814D9B10A9A3,0x3FE893C5B62135F2,
  323.     0x3FE790EEEBF9DABD,0x3FE678FACDEE27FF,0x3FE54C763699791A,0x3FE40C4F1B1EB7A3,
  324.     0x3FE2B9D863D4E0F3,0x3FE156CB86586B0B,0x3FDFCA8F5005B828,0x3FDCCF9C3F455DAC,
  325.     0x3FD9C2787F20D06E,0x3FD6A984CAD0F3E5,0x3FD38BB0C452732E,0x3FD0705EC7135366,
  326.     0x3FCABE86754E238F,0x3FC4C0801A6E9A04,0x3FBDECF490C5EA17,0x3FB2DFFACE9CE44B,
  327.     0x3FA0EFD4449F4620,0xBF72F4A65E22806D,0xBFA3F872D761F927,0xBFB1D89F0FD31F7C,
  328.     0xBFB8B1EA652EC270,0xBFBE79B82A37C92D,0xBFC1931B697E685E,0xBFC359383D4C8ADA,
  329.     0xBFC48F3BFF81B06B,0xBFC537BBA8D6B15C,0xBFC557CEF2168326,0xBFC4F6F781B3347A,
  330.     0xBFC41EF872F0E009,0xBFC2DB9F119D54D3,0xBFC13A7E196CB44F,0xBFBE953A67843504,
  331.     0xBFBA383D9C597E74,0xBFB57FBD67AD55D6,0xBFB08E18234E5CB3,0xBFA70B06D699FFD1,
  332.     0xBF9A1CFB65370184,0xBF7B2CEB901D2067,0x3F86D5DE2C267C78,0x3F9C1D9EF73F384D,
  333.     0x3FA579C530950503,0x3FABD1E5FFF9B1D0,0x3FB07DCDC3A4FB5B,0x3FB2724A856EEC1B,
  334.     0x3FB3C1F7199FC822,0x3FB46D0979F5043B,0x3FB47831387E0110,0x3FB3EC4A58A3D527,
  335.     0x3FB2D5F45F8889B3,0x3FB145113E25B749,0x3FAE9860D18779BC,0x3FA9FFD5F5AB96EA,
  336.     0x3FA4EC6C4F47777E,0x3F9F16C5B2604C3A,0x3F9413D801124DB7,0x3F824F668CBB5BDF,
  337.     0xBF55B3FA2EE30D66,0xBF86541863B38183,0xBF94031BBBD551DE,0xBF9BAFC27DC5E769,
  338.     0xBFA102B3683C57EC,0xBFA3731E608CC6E4,0xBFA520C9F5B5DEBD,0xBFA609DC89BE6ECE,
  339.     0xBFA632B83BC5F52F,0xBFA5A58885841AD4,0xBFA471A5D2FF02F3,0xBFA2AAD5CD0377C7,
  340.     0xBFA0686FFE4B9B05,0xBF9B88DE413ACB69,0xBF95B4EF6D93F1C5,0xBF8F1B72860B27FA,
  341.     0xBF8296A865CDF612,0xBF691BEEDABE928B,0x3F65C04E6AF9D4F1,0x3F8035D8FFCDB0F8,
  342.     0x3F89BED23C431BE3,0x3F90E737811A1D21,0x3F941C2040BD7CB1,0x3F967046EC629A09,
  343.     0x3F97DE27ECE9ED89,0x3F98684DE31E7040,0x3F9818C4B07718FA,0x3F97005261F91F60,
  344.     0x3F95357FDD157646,0x3F92D37C696C572A,0x3F8FF1CFF2BEECB5,0x3F898D20C7A72AC4,
  345.     0x3F82BC5B3B0AE2DF,0x3F7784A1B8E9E667,0x3F637BB14081726B,0xBF4B2DACA70C60A9,
  346.     0xBF6EFB00AD083727,0xBF7A313758DC6AE9,0xBF819D6A99164BE0,0xBF8533F57533403B,
  347.     0xBF87CD120DB5D340,0xBF89638549CD25DE,0xBF89FB8B8D37B1BB,0xBF89A21163F9204E,
  348.     0xBF886BA8931297D4,0xBF8673477783D71E,0xBF83D8E1CB165DB8,0xBF80BFEA7216142A,
  349.     0xBF7A9B9BC2E40EBF,0xBF7350E806435A7E,0xBF67D35D3734AB5E,0xBF52ADE8FEAB8DB9,
  350.     0x3F415669446478E4,0x3F60C56A092AFB48,0x3F6B9F4334A4561F,0x3F724FB908FD87AA,
  351.     0x3F75CC56DFE382EA,0x3F783A0C23969A7B,0x3F799833C40C3B82,0x3F79F02721981BF3,
  352.     0x3F7954212AB35261,0x3F77DDE0C5FC15C9,0x3F75AD1C98FE0777,0x3F72E5DACC0849F2,
  353.     0x3F6F5D7E69DFDE1B,0x3F685EC2CA09E1FD,0x3F611D750E54DF3A,0x3F53C6E392A46D17,
  354.     0x3F37A046885F3365,0xBF3BB034D2EE45C2,0xBF5254267B04B482,0xBF5C0516F9CECDC6,
  355.     0xBF61E5736853564D,0xBF64C464B9CC47AB,0xBF669C1AEF258F56,0xBF67739985DD0E60,
  356.     0xBF675AFD6446395B,0xBF666A0C909B4F78,0xBF64BE9879A7A07B,0xBF627AC74B119DBD,
  357.     0xBF5F86B04069DC9B,0xBF597BE8F754AF5E,0xBF531F3EAAE9A1B1,0xBF496D3DE6AD7EA3,
  358.     0xBF3A05FFDE4670CF,0xBF06DF95C93A85CA,0x3F31EE2B2C6547AC,0x3F41E694A378C129,
  359.     0x3F4930BF840E23C9,0x3F4EBB5D05A0D47D,0x3F51404DA0539855,0x3F524698F56B3F33,
  360.     0x3F527EF85309E28F,0x3F51FE70FE2513DE,0x3F50DF1642009B74,0x3F4E7CDA93517CAE,
  361.     0x3F4A77AE24F9A533,0x3F45EE226AA69E10,0x3F411DB747374F52,0x3F387F39D229D97F,
  362.     0x3F2E1B3D39AF5F8B,0x3F18F557BB082715,0xBEFAC04896E68DDB,0xBF20F5BC77DF558A,
  363.     0xBF2C1B6DF3EE94A4,0xBF3254602A816876,0xBF354E90F6EAC26B,0xBF3709F2E5AF1624,
  364.     0xBF379FCCB331CE8E,0xBF37327192ADDAD3,0xBF35EA998A894237,0xBF33F4C4977B3489,
  365.     0xBF317EC5F68E887B,0xBF2D6B1F793EB773,0xBF2786A226B076D9,0xBF219BE6CEC2CA36,
  366.     0xBF17D7F36D2A3A18,0xBF0AAEC5BBAB42AB,0xBEF01818DC224040,0x3EEF2F6E21093846,
  367.     0x3F049D6E0060B71F,0x3F0E598CCAFABEFD,0x3F128BC14BE97261,0x3F148703BC70EF6A,
  368.     0x3F1545E1579CAA25,0x3F14F7DDF5F8D766,0x3F13D10FF9A1BE0C,0x3F1206D5738ECE3A,
  369.     0x3F0F99F6BF17C5D4,0x3F0AA6D7EA524E96,0x3F0588DDF740E1F4,0x3F0086FB6FEA9839,
  370.     0x3EF7B28F6D6F5EED,0x3EEEA300DCBAF74A,0x3EE03F904789777C,0x3EC1BFEB320501ED,
  371.     0xBEC310D8E585A031,0xBED6F55ECA7E151F,0xBEDFDAA5DACDD0B7,0xBEE26944F3CF6E90,
  372.     0xBEE346894453BD1F,0xBEE2E099305CD5A8,0xBEE190385A7EA8B2,0xBEDF4D5FA2FB6BA2,
  373.     0xBEDAD4F371257BA0,0xBED62A9CDEB0AB32,0xBED1A6DF97B88316,0xBECB100096894E58,
  374.     0xBEC3E8A76257D275,0xBEBBF6C29A5150C9,0xBEB296292998088E,0xBEA70A10498F0E5E,
  375.     0xBE99E52D02F887A1,0xBE88C17F4066D432,0xBE702A716CFF56CA,0x3E409F820F781F78,
  376.     0x3E643EA99B770FE7,0x3E67DE40CDE0A550,0x3E64F4D534A2335C,0x3E5F194536BDDF7A,
  377.     0x3E5425CEBE1FA40A,0x3E46D7B7CC631E73,0x3E364746B6582E54,0x3E21FC07B13031DE,
  378.     0x3E064C3D91CF7665,0x3DE224F901A0AFC7,0x3DA97D57859C74A4,0x0000000000000000,
  379.  
  380.     // extra padding needed for interpolation
  381.     0x0000000000000000
  382. };
  383.  
  384. #define LERP(x, y, z) ((x) + ((y) - (x)) * (z))
  385. const double *get_minblep_table(void) { return (const double *)minblepdata; }
  386. #endif
  387.  
  388. #define SWAP16(x) ((uint16_t)(((x) << 8) | ((x) >> 8)))
  389. #define PTR2WORD(x) ((uint16_t *)(x))
  390. #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
  391. #define CLAMP16(i) if ((int16_t)i != i) i = 0x7FFF ^ (i >> 31);
  392.  
  393. static bool openMixer(uint32_t audioFreq);
  394. static void closeMixer(void);
  395.  
  396. static void paulaStartDMA(int32_t ch)
  397. {
  398.     const int8_t *data;
  399.     int32_t length;
  400.     paulaVoice_t *v = &paula[ch];
  401.  
  402.     data = v->newData;
  403.     if (data == NULL)
  404.         data = EmptySample;
  405.  
  406.     length = v->newLength;
  407.     if (length < 2)
  408.         length = 2; // for safety
  409.  
  410.     v->dPhase = 0.0;
  411.     v->pos = 0;
  412.     v->data = data;
  413.     v->length = length;
  414.     v->active = true;
  415. }
  416.  
  417. static void paulaSetPeriod(int32_t ch, uint16_t period)
  418. {
  419.     int32_t realPeriod;
  420.     paulaVoice_t *v = &paula[ch];
  421.  
  422.     if (period == 0)
  423.         realPeriod = 1+65535; // confirmed behavior on real Amiga
  424.     else if (period < 113)
  425.         realPeriod = 113; // close to what happens on real Amiga (and needed for BLEP synthesis)
  426.     else
  427.         realPeriod = period;
  428.  
  429.     // if the new period was the same as the previous period, use cached deltas
  430.     if (realPeriod != oldPeriod)
  431.     {
  432.         oldPeriod = realPeriod;
  433.  
  434.         // cache these
  435.         dOldVoiceDelta = dPeriodToDeltaDiv / realPeriod;
  436. #ifdef USE_BLEP
  437.         dOldVoiceDeltaMul = 1.0 / dOldVoiceDelta;
  438. #endif
  439.     }
  440.  
  441.     v->dDelta = dOldVoiceDelta;
  442.  
  443. #ifdef USE_BLEP
  444.     v->dDeltaMul = dOldVoiceDeltaMul;
  445.     if (v->dLastDelta == 0.0) v->dLastDelta = v->dDelta;
  446.     if (v->dLastDeltaMul == 0.0) v->dLastDeltaMul = v->dDeltaMul;
  447. #endif
  448. }
  449.  
  450. static void paulaSetVolume(int32_t ch, uint16_t vol)
  451. {
  452.     vol &= 127; // confirmed behavior on real Amiga
  453.  
  454.     if (vol > 64)
  455.         vol = 64; // confirmed behavior on real Amiga
  456.  
  457.     paula[ch].dVolume = vol * (1.0 / 64.0);
  458. }
  459.  
  460. static void paulaSetLength(int32_t ch, uint16_t len)
  461. {
  462.     paula[ch].newLength = len << 1; // our mixer works with bytes, not words
  463. }
  464.  
  465. static void paulaSetData(int32_t ch, const int8_t *src)
  466. {
  467.     if (src == NULL)
  468.         src = EmptySample;
  469.  
  470.     paula[ch].newData = src;
  471. }
  472.  
  473. #if defined(USE_HIGHPASS) || defined(USE_LOWPASS)
  474. static void calcRCFilterCoeffs(double dSr, double dHz, rcFilter_t *f)
  475. {
  476.     f->c = tan((M_PI * dHz) / dSr);
  477.     f->c2 = f->c * 2.0;
  478.     f->g = 1.0 / (1.0 + f->c);
  479.     f->cg = f->c * f->g;
  480. }
  481.  
  482. void clearRCFilterState(rcFilter_t *f)
  483. {
  484.     f->buffer[0] = 0.0; // left channel
  485.     f->buffer[1] = 0.0; // right channel
  486. }
  487.  
  488. // aciddose: input 0 is resistor side of capacitor (low-pass), input 1 is reference side (high-pass)
  489. static inline double getLowpassOutput(rcFilter_t *f, const double input_0, const double input_1, const double buffer)
  490. {
  491.     return buffer * f->g + input_0 * f->cg + input_1 * (1.0 - f->cg);
  492. }
  493.  
  494. static void inline RCLowPassFilter(rcFilter_t *f, const double *in, double *out)
  495. {
  496.     double output;
  497.  
  498.     // left channel RC low-pass
  499.     output = getLowpassOutput(f, in[0], 0.0, f->buffer[0]);
  500.     f->buffer[0] += (in[0] - output) * f->c2;
  501.     out[0] = output;
  502.  
  503.     // right channel RC low-pass
  504.     output = getLowpassOutput(f, in[1], 0.0, f->buffer[1]);
  505.     f->buffer[1] += (in[1] - output) * f->c2;
  506.     out[1] = output;
  507. }
  508.  
  509. void RCHighPassFilter(rcFilter_t *f, const double *in, double *out)
  510. {
  511.     double low[2];
  512.  
  513.     RCLowPassFilter(f, in, low);
  514.  
  515.     out[0] = in[0] - low[0]; // left channel high-pass
  516.     out[1] = in[1] - low[1]; // right channel high-pass
  517. }
  518. #endif
  519.  
  520. #ifdef LED_FILTER
  521. static void clearLEDFilterState(void)
  522. {
  523.     filterLED.buffer[0] = 0.0; // left channel
  524.     filterLED.buffer[1] = 0.0;
  525.     filterLED.buffer[2] = 0.0; // right channel
  526.     filterLED.buffer[3] = 0.0;
  527. }
  528.  
  529. /* Imperfect "LED" filter implementation. This may be further improved in the future.
  530. ** Based upon ideas posted by mystran @ the kvraudio.com forum.
  531. **
  532. ** This filter may not function correctly used outside the fixed-cutoff context here!
  533. */
  534.  
  535. static double sigmoid(double x, double coefficient)
  536. {
  537.     /* Coefficient from:
  538.     **   0.0 to  inf (linear)
  539.     **  -1.0 to -inf (linear)
  540.     */
  541.     return x / (x + coefficient) * (coefficient + 1.0);
  542. }
  543.  
  544. static void calcLEDFilterCoeffs(const double sr, const double hz, const double fb, ledFilter_t *filter)
  545. {
  546.     /* tan() may produce NaN or other bad results in some cases!
  547.     ** It appears to work correctly with these specific coefficients.
  548.     */
  549.     const double c = (hz < (sr / 2.0)) ? tan((M_PI * hz) / sr) : 1.0;
  550.     const double g = 1.0 / (1.0 + c);
  551.  
  552.     // dirty compensation
  553.     const double s = 0.5;
  554.     const double t = 0.5;
  555.     const double ic = c > t ? 1.0 / ((1.0 - s*t) + s*c) : 1.0;
  556.     const double cg = c * g;
  557.     const double fbg = 1.0 / (1.0 + fb * cg*cg);
  558.  
  559.     filter->c = c;
  560.     filter->ci = g;
  561.     filter->feedback = 2.0 * sigmoid(fb, 0.5);
  562.     filter->bg = fbg * filter->feedback * ic;
  563.     filter->cg = cg;
  564.     filter->c2 = c * 2.0;
  565. }
  566.  
  567. static inline void LEDFilter(ledFilter_t *f, const double *in, double *out)
  568. {
  569.     const double in_1 = DENORMAL_OFFSET;
  570.     const double in_2 = DENORMAL_OFFSET;
  571.  
  572.     const double c = f->c;
  573.     const double g = f->ci;
  574.     const double cg = f->cg;
  575.     const double bg = f->bg;
  576.     const double c2 = f->c2;
  577.  
  578.     double *v = f->buffer;
  579.  
  580.     // left channel
  581.     const double estimate_L = in_2 + g*(v[1] + c*(in_1 + g*(v[0] + c*in[0])));
  582.     const double y0_L = v[0]*g + in[0]*cg + in_1 + estimate_L * bg;
  583.     const double y1_L = v[1]*g + y0_L*cg + in_2;
  584.  
  585.     v[0] += c2 * (in[0] - y0_L);
  586.     v[1] += c2 * (y0_L - y1_L);
  587.     out[0] = y1_L;
  588.  
  589.     // right channel
  590.     const double estimate_R = in_2 + g*(v[3] + c*(in_1 + g*(v[2] + c*in[1])));
  591.     const double y0_R = v[2]*g + in[1]*cg + in_1 + estimate_R * bg;
  592.     const double y1_R = v[3]*g + y0_R*cg + in_2;
  593.  
  594.     v[2] += c2 * (in[1] - y0_R);
  595.     v[3] += c2 * (y0_R - y1_R);
  596.     out[1] = y1_R;
  597. }
  598. #endif
  599.  
  600. #ifdef USE_BLEP
  601. static inline void blepAdd(blep_t *b, double dOffset, double dAmplitude)
  602. {
  603.     double f = dOffset * BLEP_SP;
  604.  
  605.     int32_t i = (int32_t)f; // get integer part of f
  606.     const double *dBlepSrc = get_minblep_table() + i;
  607.     f -= i; // remove integer part from f
  608.  
  609.     i = b->index;
  610.     for (int32_t n = 0; n < BLEP_NS; n++)
  611.     {
  612.         b->dBuffer[i] += dAmplitude * LERP(dBlepSrc[0], dBlepSrc[1], f);
  613.         dBlepSrc += BLEP_SP;
  614.  
  615.         i = (i + 1) & BLEP_RNS;
  616.     }
  617.  
  618.     b->samplesLeft = BLEP_NS;
  619. }
  620.  
  621. /* 8bitbubsy: simplified, faster version of blepAdd for blep'ing voice volume.
  622. ** Result is identical! (confirmed with binary comparison)
  623. */
  624. void blepVolAdd(blep_t *b, double dAmplitude)
  625. {
  626.     const double *dBlepSrc = get_minblep_table();
  627.  
  628.     int32_t i = b->index;
  629.     for (int32_t n = 0; n < BLEP_NS; n++)
  630.     {
  631.         b->dBuffer[i] += dAmplitude * (*dBlepSrc);
  632.         dBlepSrc += BLEP_SP;
  633.  
  634.         i = (i + 1) & BLEP_RNS;
  635.     }
  636.  
  637.     b->samplesLeft = BLEP_NS;
  638. }
  639.  
  640. static inline double blepRun(blep_t *b, double dInput)
  641. {
  642.     double dBlepOutput = dInput + b->dBuffer[b->index];
  643.     b->dBuffer[b->index] = 0.0;
  644.  
  645.     b->index = (b->index + 1) & BLEP_RNS;
  646.  
  647.     b->samplesLeft--;
  648.     return dBlepOutput;
  649. }
  650. #endif
  651.  
  652. static void SetReplayerBPM(uint8_t bpm)
  653. {
  654.     if (bpm < 32)
  655.         return;
  656.  
  657.     samplesPerTick = bpmTab[bpm-32];
  658. }
  659.  
  660. static void UpdateFunk(ptChannel_t *ch)
  661. {
  662.     const int8_t funkspeed = ch->n_glissfunk >> 4;
  663.     if (funkspeed == 0)
  664.         return;
  665.  
  666.     ch->n_funkoffset += FunkTable[funkspeed];
  667.     if (ch->n_funkoffset >= 128)
  668.     {
  669.         ch->n_funkoffset = 0;
  670.  
  671.         if (ch->n_loopstart != NULL && ch->n_wavestart != NULL) // non-PT2 bug fix
  672.         {
  673.             if (++ch->n_wavestart >= ch->n_loopstart + (ch->n_replen << 1))
  674.                 ch->n_wavestart = ch->n_loopstart;
  675.  
  676.             *ch->n_wavestart = -1 - *ch->n_wavestart;
  677.         }
  678.     }
  679. }
  680.  
  681. static void SetGlissControl(ptChannel_t *ch)
  682. {
  683.     ch->n_glissfunk = (ch->n_glissfunk & 0xF0) | (ch->n_cmd & 0x0F);
  684. }
  685.  
  686. static void SetVibratoControl(ptChannel_t *ch)
  687. {
  688.     ch->n_wavecontrol = (ch->n_wavecontrol & 0xF0) | (ch->n_cmd & 0x0F);
  689. }
  690.  
  691. static void SetFineTune(ptChannel_t *ch)
  692. {
  693.     ch->n_finetune = ch->n_cmd & 0xF;
  694. }
  695.  
  696. static void JumpLoop(ptChannel_t *ch)
  697. {
  698.     if (Counter != 0)
  699.         return;
  700.  
  701.     if ((ch->n_cmd & 0xF) == 0)
  702.     {
  703.         ch->n_pattpos = (PatternPos >> 4) & 63;
  704.     }
  705.     else
  706.     {
  707.         if (ch->n_loopcount == 0)
  708.             ch->n_loopcount = ch->n_cmd & 0xF;
  709.         else if (--ch->n_loopcount == 0)
  710.             return;
  711.  
  712.         PBreakPosition = ch->n_pattpos;
  713.         PBreakFlag = true;
  714.     }
  715. }
  716.  
  717. static void SetTremoloControl(ptChannel_t *ch)
  718. {
  719.     ch->n_wavecontrol = ((ch->n_cmd & 0xF) << 4) | (ch->n_wavecontrol & 0xF);
  720. }
  721.  
  722. static void KarplusStrong(ptChannel_t *ch)
  723. {
  724. #ifdef ENABLE_E8_EFFECT
  725.     int8_t *smpPtr;
  726.     uint16_t len;
  727.  
  728.     smpPtr = ch->n_loopstart;
  729.     if (smpPtr != NULL) // SAFETY BUG FIX
  730.     {
  731.         len = ((ch->n_replen * 2) & 0xFFFF) - 1;
  732.         while (len--)
  733.             *smpPtr++ = (int8_t)((smpPtr[1] + smpPtr[0]) >> 1);
  734.  
  735.         *smpPtr = (int8_t)((ch->n_loopstart[0] + smpPtr[0]) >> 1);
  736.     }
  737. #else
  738.     (void)(ch);
  739. #endif
  740. }
  741.  
  742. static void DoRetrg(ptChannel_t *ch)
  743. {
  744.     paulaSetData(ch->n_chanindex, ch->n_start); // n_start is increased on 9xx
  745.     paulaSetLength(ch->n_chanindex, ch->n_length);
  746.     paulaSetPeriod(ch->n_chanindex, ch->n_period);
  747.     paulaStartDMA(ch->n_chanindex);
  748.  
  749.     // these take effect after the current cycle is done
  750.     paulaSetData(ch->n_chanindex, ch->n_loopstart);
  751.     paulaSetLength(ch->n_chanindex, ch->n_replen);
  752. }
  753.  
  754. static void RetrigNote(ptChannel_t *ch)
  755. {
  756.     if ((ch->n_cmd & 0xF) > 0)
  757.     {
  758.         if (Counter == 0 && (ch->n_note & 0xFFF) > 0)
  759.             return;
  760.  
  761.         if (Counter % (ch->n_cmd & 0xF) == 0)
  762.             DoRetrg(ch);
  763.     }
  764. }
  765.  
  766. static void VolumeSlide(ptChannel_t *ch)
  767. {
  768.     uint8_t cmd = ch->n_cmd & 0xFF;
  769.  
  770.     if ((cmd & 0xF0) == 0)
  771.     {
  772.         ch->n_volume -= cmd & 0xF;
  773.         if (ch->n_volume < 0)
  774.             ch->n_volume = 0;
  775.     }
  776.     else
  777.     {
  778.         ch->n_volume += cmd >> 4;
  779.         if (ch->n_volume > 64)
  780.             ch->n_volume = 64;
  781.     }
  782. }
  783.  
  784. static void VolumeFineUp(ptChannel_t *ch)
  785. {
  786.     if (Counter == 0)
  787.     {
  788.         ch->n_volume += ch->n_cmd & 0xF;
  789.         if (ch->n_volume > 64)
  790.             ch->n_volume = 64;
  791.     }
  792. }
  793.  
  794. static void VolumeFineDown(ptChannel_t *ch)
  795. {
  796.     if (Counter == 0)
  797.     {
  798.         ch->n_volume -= ch->n_cmd & 0xF;
  799.         if (ch->n_volume < 0)
  800.             ch->n_volume = 0;
  801.     }
  802. }
  803.  
  804. static void NoteCut(ptChannel_t *ch)
  805. {
  806.     if (Counter == (ch->n_cmd & 0xF))
  807.         ch->n_volume = 0;
  808. }
  809.  
  810. static void NoteDelay(ptChannel_t *ch)
  811. {
  812.     if (Counter == (ch->n_cmd & 0xF) && (ch->n_note & 0xFFF) > 0)
  813.         DoRetrg(ch);
  814. }
  815.  
  816. static void PatternDelay(ptChannel_t *ch)
  817. {
  818.     if (Counter == 0 && PattDelTime2 == 0)
  819.         PattDelTime = (ch->n_cmd & 0xF) + 1;
  820. }
  821.  
  822. static void FunkIt(ptChannel_t *ch)
  823. {
  824.     if (Counter == 0)
  825.     {
  826.         ch->n_glissfunk = ((ch->n_cmd & 0xF) << 4) | (ch->n_glissfunk & 0xF);
  827.         if ((ch->n_glissfunk & 0xF0) > 0)
  828.             UpdateFunk(ch);
  829.     }
  830. }
  831.  
  832. static void PositionJump(ptChannel_t *ch)
  833. {
  834.     SongPosition = (ch->n_cmd & 0xFF) - 1; // 0xFF (B00) jumps to pat 0
  835.     PBreakPosition = 0;
  836.     PosJumpAssert = true;
  837. }
  838.  
  839. static void VolumeChange(ptChannel_t *ch)
  840. {
  841.     ch->n_volume = ch->n_cmd & 0xFF;
  842.     if ((uint8_t)ch->n_volume > 64)
  843.         ch->n_volume = 64;
  844. }
  845.  
  846. static void PatternBreak(ptChannel_t *ch)
  847. {
  848.     PBreakPosition = (((ch->n_cmd & 0xF0) >> 4) * 10) + (ch->n_cmd & 0x0F);
  849.     if ((uint8_t)PBreakPosition > 63)
  850.         PBreakPosition = 0;
  851.  
  852.     PosJumpAssert = true;
  853. }
  854.  
  855. static void SetSpeed(ptChannel_t *ch)
  856. {
  857.     const uint8_t param = ch->n_cmd & 0xFF;
  858.     if (param > 0)
  859.     {
  860.         if (TempoMode == VBLANK_TEMPO_MODE || param < 32)
  861.         {
  862.             Counter = 0;
  863.             CurrSpeed = param;
  864.         }
  865.         else
  866.         {
  867.             SetBPMFlag = param; // CIA doesn't refresh its registers until the next interrupt, so change it later
  868.         }
  869.     }
  870. }
  871.  
  872. static void Arpeggio(ptChannel_t *ch)
  873. {
  874.     uint8_t arpTick, arpNote;
  875.     const int16_t *periods;
  876.  
  877.     arpTick = ArpTickTable[Counter]; // 0, 1, 2
  878.     if (arpTick == 1)
  879.     {
  880.         arpNote = (uint8_t)(ch->n_cmd >> 4);
  881.     }
  882.     else if (arpTick == 2)
  883.     {
  884.         arpNote = ch->n_cmd & 0xF;
  885.     }
  886.     else // arpTick 0
  887.     {
  888.         paulaSetPeriod(ch->n_chanindex, ch->n_period);
  889.         return;
  890.     }
  891.  
  892.     /* 8bitbubsy: If the finetune is -1, this can overflow up to
  893.     ** 15 words outside of the table. The table is padded with
  894.     ** the correct overflow values to allow this to safely happen
  895.     ** and sound correct at the same time.
  896.     */
  897.     periods = &PeriodTable[ch->n_finetune * 37];
  898.     for (int32_t baseNote = 0; baseNote < 37; baseNote++)
  899.     {
  900.         if (ch->n_period >= periods[baseNote])
  901.         {
  902.             paulaSetPeriod(ch->n_chanindex, periods[baseNote+arpNote]);
  903.             break;
  904.         }
  905.     }
  906. }
  907.  
  908. static void PortaUp(ptChannel_t *ch)
  909. {
  910.     ch->n_period -= (ch->n_cmd & 0xFF) & LowMask;
  911.     LowMask = 0xFF;
  912.  
  913.     if ((ch->n_period & 0xFFF) < 113)
  914.         ch->n_period = (ch->n_period & 0xF000) | 113;
  915.  
  916.     paulaSetPeriod(ch->n_chanindex, ch->n_period & 0xFFF);
  917. }
  918.  
  919. static void PortaDown(ptChannel_t *ch)
  920. {
  921.     ch->n_period += (ch->n_cmd & 0xFF) & LowMask;
  922.     LowMask = 0xFF;
  923.  
  924.     if ((ch->n_period & 0xFFF) > 856)
  925.         ch->n_period = (ch->n_period & 0xF000) | 856;
  926.  
  927.     paulaSetPeriod(ch->n_chanindex, ch->n_period & 0xFFF);
  928. }
  929.  
  930. static void FilterOnOff(ptChannel_t *ch)
  931. {
  932. #ifdef LED_FILTER
  933.     LEDFilterOn = !(ch->n_cmd & 1);
  934. #else
  935.     (void)ch;
  936. #endif
  937. }
  938.  
  939. static void FinePortaUp(ptChannel_t *ch)
  940. {
  941.     if (Counter == 0)
  942.     {
  943.         LowMask = 0xF;
  944.         PortaUp(ch);
  945.     }
  946. }
  947.  
  948. static void FinePortaDown(ptChannel_t *ch)
  949. {
  950.     if (Counter == 0)
  951.     {
  952.         LowMask = 0xF;
  953.         PortaDown(ch);
  954.     }
  955. }
  956.  
  957. static void SetTonePorta(ptChannel_t *ch)
  958. {
  959.     uint8_t i;
  960.     const int16_t *portaPointer;
  961.     uint16_t note;
  962.  
  963.     note = ch->n_note & 0xFFF;
  964.     portaPointer = &PeriodTable[ch->n_finetune * 37];
  965.  
  966.     i = 0;
  967.     while (true)
  968.     {
  969.         // portaPointer[36] = 0, so i=36 is safe
  970.         if (note >= portaPointer[i])
  971.             break;
  972.  
  973.         if (++i >= 37)
  974.         {
  975.             i = 35;
  976.             break;
  977.         }
  978.     }
  979.  
  980.     if ((ch->n_finetune & 8) && i > 0)
  981.         i--;
  982.  
  983.     ch->n_wantedperiod  = portaPointer[i];
  984.     ch->n_toneportdirec = 0;
  985.  
  986.          if (ch->n_period == ch->n_wantedperiod) ch->n_wantedperiod = 0;
  987.     else if (ch->n_period > ch->n_wantedperiod) ch->n_toneportdirec = 1;
  988. }
  989.  
  990. static void TonePortNoChange(ptChannel_t *ch)
  991. {
  992.     uint8_t i;
  993.     const int16_t *portaPointer;
  994.  
  995.     if (ch->n_wantedperiod <= 0)
  996.         return;
  997.  
  998.     if (ch->n_toneportdirec > 0)
  999.     {
  1000.         ch->n_period -= ch->n_toneportspeed;
  1001.         if (ch->n_period <= ch->n_wantedperiod)
  1002.         {
  1003.             ch->n_period = ch->n_wantedperiod;
  1004.             ch->n_wantedperiod = 0;
  1005.         }
  1006.     }
  1007.     else
  1008.     {
  1009.         ch->n_period += ch->n_toneportspeed;
  1010.         if (ch->n_period >= ch->n_wantedperiod)
  1011.         {
  1012.             ch->n_period = ch->n_wantedperiod;
  1013.             ch->n_wantedperiod = 0;
  1014.         }
  1015.     }
  1016.  
  1017.     if ((ch->n_glissfunk & 0xF) == 0)
  1018.     {
  1019.         paulaSetPeriod(ch->n_chanindex, ch->n_period);
  1020.     }
  1021.     else
  1022.     {
  1023.         portaPointer = &PeriodTable[ch->n_finetune * 37];
  1024.  
  1025.         i = 0;
  1026.         while (true)
  1027.         {
  1028.             // portaPointer[36] = 0, so i=36 is safe
  1029.             if (ch->n_period >= portaPointer[i])
  1030.                 break;
  1031.  
  1032.             if (++i >= 37)
  1033.             {
  1034.                 i = 35;
  1035.                 break;
  1036.             }
  1037.         }
  1038.  
  1039.         paulaSetPeriod(ch->n_chanindex, portaPointer[i]);
  1040.     }
  1041. }
  1042.  
  1043. static void TonePortamento(ptChannel_t *ch)
  1044. {
  1045.     if ((ch->n_cmd & 0xFF) > 0)
  1046.     {
  1047.         ch->n_toneportspeed = ch->n_cmd & 0xFF;
  1048.         ch->n_cmd &= 0xFF00;
  1049.     }
  1050.  
  1051.     TonePortNoChange(ch);
  1052. }
  1053.  
  1054. static void Vibrato2(ptChannel_t *ch)
  1055. {
  1056.     uint16_t vibratoData;
  1057.  
  1058.     const uint8_t vibratoPos = (ch->n_vibratopos >> 2) & 0x1F;
  1059.     const uint8_t vibratoType = ch->n_wavecontrol & 3;
  1060.  
  1061.     if (vibratoType == 0) // Sine
  1062.     {
  1063.         vibratoData = VibratoTable[vibratoPos];
  1064.     }
  1065.     else
  1066.     {
  1067.         if (vibratoType == 1) // Ramp
  1068.         {
  1069.             if (ch->n_vibratopos < 128)
  1070.                 vibratoData = vibratoPos << 3;
  1071.             else
  1072.                 vibratoData = 255 - (vibratoPos << 3);
  1073.         }
  1074.         else // Square
  1075.         {
  1076.             vibratoData = 255;
  1077.         }
  1078.     }
  1079.  
  1080.     vibratoData = (vibratoData * (ch->n_vibratocmd & 0xF)) >> 7;
  1081.  
  1082.     if (ch->n_vibratopos < 128)
  1083.         vibratoData = ch->n_period + vibratoData;
  1084.     else
  1085.         vibratoData = ch->n_period - vibratoData;
  1086.  
  1087.     paulaSetPeriod(ch->n_chanindex, vibratoData);
  1088.  
  1089.     ch->n_vibratopos += (ch->n_vibratocmd >> 2) & 0x3C;
  1090. }
  1091.  
  1092. static void Vibrato(ptChannel_t *ch)
  1093. {
  1094.     if ((ch->n_cmd & 0x0F) > 0)
  1095.         ch->n_vibratocmd = (ch->n_vibratocmd & 0xF0) | (ch->n_cmd & 0x0F);
  1096.  
  1097.     if ((ch->n_cmd & 0xF0) > 0)
  1098.         ch->n_vibratocmd = (ch->n_cmd & 0xF0) | (ch->n_vibratocmd & 0x0F);
  1099.  
  1100.     Vibrato2(ch);
  1101. }
  1102.  
  1103. static void TonePlusVolSlide(ptChannel_t *ch)
  1104. {
  1105.     TonePortNoChange(ch);
  1106.     VolumeSlide(ch);
  1107. }
  1108.  
  1109. static void VibratoPlusVolSlide(ptChannel_t *ch)
  1110. {
  1111.     Vibrato2(ch);
  1112.     VolumeSlide(ch);
  1113. }
  1114.  
  1115. static void Tremolo(ptChannel_t *ch)
  1116. {
  1117.     int16_t tremoloData;
  1118.  
  1119.     if ((ch->n_cmd & 0x0F) > 0)
  1120.         ch->n_tremolocmd = (ch->n_tremolocmd & 0xF0) | (ch->n_cmd & 0x0F);
  1121.  
  1122.     if ((ch->n_cmd & 0xF0) > 0)
  1123.         ch->n_tremolocmd = (ch->n_cmd & 0xF0) | (ch->n_tremolocmd & 0x0F);
  1124.  
  1125.     const uint8_t tremoloPos = (ch->n_tremolopos >> 2) & 0x1F;
  1126.     const uint8_t tremoloType = (ch->n_wavecontrol >> 4) & 3;
  1127.  
  1128.     if (tremoloType == 0) // Sine
  1129.     {
  1130.         tremoloData = VibratoTable[tremoloPos];
  1131.     }
  1132.     else
  1133.     {
  1134.         if (tremoloType == 1) // Ramp
  1135.         {
  1136.             if (ch->n_vibratopos < 128) // PT bug, should've been n_tremolopos
  1137.                 tremoloData = tremoloPos << 3;
  1138.             else
  1139.                 tremoloData = 255 - (tremoloPos << 3);
  1140.         }
  1141.         else // Square
  1142.         {
  1143.             tremoloData = 255;
  1144.         }
  1145.     }
  1146.  
  1147.     tremoloData = ((uint16_t)tremoloData * (ch->n_tremolocmd & 0xF)) >> 6;
  1148.  
  1149.     if (ch->n_tremolopos < 128)
  1150.     {
  1151.         tremoloData = ch->n_volume + tremoloData;
  1152.         if (tremoloData > 64)
  1153.             tremoloData = 64;
  1154.     }
  1155.     else
  1156.     {
  1157.         tremoloData = ch->n_volume - tremoloData;
  1158.         if (tremoloData < 0)
  1159.             tremoloData = 0;
  1160.     }
  1161.  
  1162.     paulaSetVolume(ch->n_chanindex, tremoloData);
  1163.  
  1164.     ch->n_tremolopos += (ch->n_tremolocmd >> 2) & 0x3C;
  1165. }
  1166.  
  1167. static void SampleOffset(ptChannel_t *ch)
  1168. {
  1169.     if ((ch->n_cmd & 0xFF) > 0)
  1170.         ch->n_sampleoffset = ch->n_cmd & 0xFF;
  1171.  
  1172.     uint16_t newOffset = ch->n_sampleoffset << 7;
  1173.  
  1174.     if ((int16_t)newOffset < ch->n_length)
  1175.     {
  1176.         ch->n_length -= newOffset;
  1177.         ch->n_start += newOffset << 1;
  1178.     }
  1179.     else
  1180.     {
  1181.         ch->n_length = 1;
  1182.     }
  1183. }
  1184.  
  1185. static void E_Commands(ptChannel_t *ch)
  1186. {
  1187.     switch ((ch->n_cmd & 0xF0) >> 4)
  1188.     {
  1189.         case 0x0: FilterOnOff(ch);       break;
  1190.         case 0x1: FinePortaUp(ch);       break;
  1191.         case 0x2: FinePortaDown(ch);     break;
  1192.         case 0x3: SetGlissControl(ch);   break;
  1193.         case 0x4: SetVibratoControl(ch); break;
  1194.         case 0x5: SetFineTune(ch);       break;
  1195.         case 0x6: JumpLoop(ch);          break;
  1196.         case 0x7: SetTremoloControl(ch); break;
  1197.         case 0x8: KarplusStrong(ch);     break;
  1198.         case 0x9: RetrigNote(ch);        break;
  1199.         case 0xA: VolumeFineUp(ch);      break;
  1200.         case 0xB: VolumeFineDown(ch);    break;
  1201.         case 0xC: NoteCut(ch);           break;
  1202.         case 0xD: NoteDelay(ch);         break;
  1203.         case 0xE: PatternDelay(ch);      break;
  1204.         case 0xF: FunkIt(ch);            break;
  1205.         default: break;
  1206.     }
  1207. }
  1208.  
  1209. static void CheckMoreEffects(ptChannel_t *ch)
  1210. {
  1211.     switch ((ch->n_cmd & 0xF00) >> 8)
  1212.     {
  1213.         case 0x9: SampleOffset(ch); break;
  1214.         case 0xB: PositionJump(ch); break;
  1215.         case 0xD: PatternBreak(ch); break;
  1216.         case 0xE: E_Commands(ch);   break;
  1217.         case 0xF: SetSpeed(ch);     break;
  1218.         case 0xC: VolumeChange(ch); break;
  1219.  
  1220.         default: paulaSetPeriod(ch->n_chanindex, ch->n_period); break;
  1221.     }
  1222. }
  1223.  
  1224. static void CheckEffects(ptChannel_t *ch)
  1225. {
  1226.     uint8_t effect;
  1227.  
  1228.     UpdateFunk(ch);
  1229.  
  1230.     effect = (ch->n_cmd & 0xF00) >> 8;
  1231.     if ((ch->n_cmd & 0xFFF) > 0)
  1232.     {
  1233.         switch (effect)
  1234.         {
  1235.             case 0x0: Arpeggio(ch);            break;
  1236.             case 0x1: PortaUp(ch);             break;
  1237.             case 0x2: PortaDown(ch);           break;
  1238.             case 0x3: TonePortamento(ch);      break;
  1239.             case 0x4: Vibrato(ch);             break;
  1240.             case 0x5: TonePlusVolSlide(ch);    break;
  1241.             case 0x6: VibratoPlusVolSlide(ch); break;
  1242.             case 0xE: E_Commands(ch);          break;
  1243.             case 0x7:
  1244.                 paulaSetPeriod(ch->n_chanindex, ch->n_period);
  1245.                 Tremolo(ch);
  1246.             break;
  1247.             case 0xA:
  1248.                 paulaSetPeriod(ch->n_chanindex, ch->n_period);
  1249.                 VolumeSlide(ch);
  1250.             break;
  1251.  
  1252.             default: paulaSetPeriod(ch->n_chanindex, ch->n_period); break;
  1253.         }
  1254.     }
  1255.  
  1256.     if (effect != 0x7)
  1257.         paulaSetVolume(ch->n_chanindex, ch->n_volume);
  1258. }
  1259.  
  1260. static void SetPeriod(ptChannel_t *ch)
  1261. {
  1262.     int32_t i;
  1263.  
  1264.     uint16_t note = ch->n_note & 0xFFF;
  1265.     for (i = 0; i < 37; i++)
  1266.     {
  1267.         // PeriodTable[36] = 0, so i=36 is safe
  1268.         if (note >= PeriodTable[i])
  1269.             break;
  1270.     }
  1271.  
  1272.     // yes it's safe if i=37 because of zero-padding
  1273.     ch->n_period = PeriodTable[(ch->n_finetune * 37) + i];
  1274.  
  1275.     if ((ch->n_cmd & 0xFF0) != 0xED0) // no note delay
  1276.     {
  1277.         if ((ch->n_wavecontrol & 0x04) == 0) ch->n_vibratopos = 0;
  1278.         if ((ch->n_wavecontrol & 0x40) == 0) ch->n_tremolopos = 0;
  1279.  
  1280.         paulaSetLength(ch->n_chanindex, ch->n_length);
  1281.         paulaSetData(ch->n_chanindex, ch->n_start);
  1282.  
  1283.         if (ch->n_start == NULL)
  1284.         {
  1285.             ch->n_loopstart = NULL;
  1286.             paulaSetLength(ch->n_chanindex, 1);
  1287.             ch->n_replen = 1;
  1288.         }
  1289.  
  1290.         paulaSetPeriod(ch->n_chanindex, ch->n_period);
  1291.         paulaStartDMA(ch->n_chanindex);
  1292.     }
  1293.  
  1294.     CheckMoreEffects(ch);
  1295. }
  1296.  
  1297. static void PlayVoice(ptChannel_t *ch)
  1298. {
  1299.     uint8_t *dataPtr, sample, cmd;
  1300.     uint16_t sampleOffset, repeat;
  1301.  
  1302.     if (ch->n_note == 0 && ch->n_cmd == 0)
  1303.         paulaSetPeriod(ch->n_chanindex, ch->n_period);
  1304.  
  1305.     dataPtr = &SongDataPtr[PattPosOff];
  1306.  
  1307.     ch->n_note = (dataPtr[0] << 8) | dataPtr[1];
  1308.     ch->n_cmd  = (dataPtr[2] << 8) | dataPtr[3];
  1309.  
  1310.     sample = (dataPtr[0] & 0xF0) | (dataPtr[2] >> 4);
  1311.     if (sample >= 1 && sample <= 31) // SAFETY BUG FIX: don't handle sample-numbers >31
  1312.     {
  1313.         sample--;
  1314.         sampleOffset = 42 + (30 * sample);
  1315.  
  1316.         ch->n_start = SampleStarts[sample];
  1317.         ch->n_finetune = SongDataPtr[sampleOffset + 2] & 0xF;
  1318.         ch->n_volume = SongDataPtr[sampleOffset + 3];
  1319.         ch->n_length = *PTR2WORD(&SongDataPtr[sampleOffset + 0]);
  1320.         ch->n_replen = *PTR2WORD(&SongDataPtr[sampleOffset + 6]);
  1321.  
  1322.         repeat = *PTR2WORD(&SongDataPtr[sampleOffset + 4]);
  1323.         if (repeat > 0)
  1324.         {
  1325.             ch->n_loopstart = ch->n_start + (repeat << 1);
  1326.             ch->n_wavestart = ch->n_loopstart;
  1327.             ch->n_length = repeat + ch->n_replen;
  1328.         }
  1329.         else
  1330.         {
  1331.             ch->n_loopstart = ch->n_start;
  1332.             ch->n_wavestart = ch->n_start;
  1333.         }
  1334.  
  1335.         // non-PT2 quirk
  1336.         if (ch->n_length == 0)
  1337.             ch->n_loopstart = ch->n_wavestart = EmptySample;
  1338.     }
  1339.  
  1340.     if ((ch->n_note & 0xFFF) > 0)
  1341.     {
  1342.         if ((ch->n_cmd & 0xFF0) == 0xE50) // set finetune
  1343.         {
  1344.             SetFineTune(ch);
  1345.             SetPeriod(ch);
  1346.         }
  1347.         else
  1348.         {
  1349.             cmd = (ch->n_cmd & 0xF00) >> 8;
  1350.             if (cmd == 3 || cmd == 5)
  1351.             {
  1352.                 SetTonePorta(ch);
  1353.                 CheckMoreEffects(ch);
  1354.             }
  1355.             else
  1356.             {
  1357.                 if (cmd == 9)
  1358.                     CheckMoreEffects(ch);
  1359.  
  1360.                 SetPeriod(ch);
  1361.             }
  1362.         }
  1363.     }
  1364.     else
  1365.     {
  1366.         CheckMoreEffects(ch);
  1367.     }
  1368.  
  1369.     PattPosOff += 4;
  1370. }
  1371.  
  1372. static void NextPosition(void)
  1373. {
  1374.     PatternPos = (uint8_t)PBreakPosition << 4;
  1375.     PBreakPosition = 0;
  1376.     PosJumpAssert = false;
  1377.  
  1378.     SongPosition = (SongPosition + 1) & 0x7F;
  1379.     if (SongPosition >= SongDataPtr[950])
  1380.         SongPosition = 0;
  1381. }
  1382.  
  1383. static void tickReplayer(void)
  1384. {
  1385.     int32_t i;
  1386.  
  1387.     if (!SongPlaying)
  1388.         return;
  1389.  
  1390.     // PT quirk: CIA refreshes its timer values on the next interrupt, so do the real tempo change here
  1391.     if (SetBPMFlag != 0)
  1392.     {
  1393.         SetReplayerBPM(SetBPMFlag);
  1394.         SetBPMFlag = 0;
  1395.     }
  1396.  
  1397.     Counter++;
  1398.     if (Counter >= CurrSpeed)
  1399.     {
  1400.         Counter = 0;
  1401.  
  1402.         if (PattDelTime2 == 0)
  1403.         {
  1404.             PattPosOff = (1084 + (SongDataPtr[952 + SongPosition] * 1024)) + PatternPos;
  1405.  
  1406.             for (i = 0; i < AMIGA_VOICES; i++)
  1407.             {
  1408.                 PlayVoice(&ChanTemp[i]);
  1409.                 paulaSetVolume(i, ChanTemp[i].n_volume);
  1410.  
  1411.                 // these take effect after the current cycle is done
  1412.                 paulaSetData(i, ChanTemp[i].n_loopstart);
  1413.                 paulaSetLength(i, ChanTemp[i].n_replen);
  1414.             }
  1415.         }
  1416.         else
  1417.         {
  1418.             for (i = 0; i < AMIGA_VOICES; i++)
  1419.                 CheckEffects(&ChanTemp[i]);
  1420.         }
  1421.  
  1422.         PatternPos += 16;
  1423.  
  1424.         if (PattDelTime > 0)
  1425.         {
  1426.             PattDelTime2 = PattDelTime;
  1427.             PattDelTime = 0;
  1428.         }
  1429.  
  1430.         if (PattDelTime2 > 0)
  1431.         {
  1432.             if (--PattDelTime2 > 0)
  1433.                 PatternPos -= 16;
  1434.         }
  1435.  
  1436.         if (PBreakFlag)
  1437.         {
  1438.             PBreakFlag = false;
  1439.  
  1440.             PatternPos = PBreakPosition * 16;
  1441.             PBreakPosition = 0;
  1442.         }
  1443.  
  1444.         if (PatternPos >= 1024 || PosJumpAssert)
  1445.             NextPosition();
  1446.     }
  1447.     else
  1448.     {
  1449.         for (i = 0; i < AMIGA_VOICES; i++)
  1450.             CheckEffects(&ChanTemp[i]);
  1451.  
  1452.         if (PosJumpAssert)
  1453.             NextPosition();
  1454.     }
  1455. }
  1456.  
  1457. static int8_t moduleInit(const uint8_t *moduleData, uint32_t dataLength)
  1458. {
  1459.     int8_t pattNum, *songSampleData;
  1460.     uint8_t i;
  1461.     uint16_t *p;
  1462.     int32_t loopOverflowVal, totalSampleSize, sampleDataOffset;
  1463.     ptChannel_t *ch;
  1464.  
  1465.     if (SampleData != NULL)
  1466.     {
  1467.         free(SampleData);
  1468.         SampleData = NULL;
  1469.     }
  1470.  
  1471.     for (i = 0; i < AMIGA_VOICES; i++)
  1472.     {
  1473.         ch = &ChanTemp[i];
  1474.  
  1475.         ch->n_chanindex = i;
  1476.         ch->n_start = NULL;
  1477.         ch->n_wavestart = NULL;
  1478.         ch->n_loopstart = NULL;
  1479.     }
  1480.  
  1481.     SongDataPtr = (uint8_t *)malloc(dataLength);
  1482.     if (SongDataPtr == NULL)
  1483.         return false;
  1484.  
  1485.     memcpy(SongDataPtr, moduleData, dataLength);
  1486.  
  1487.     memcpy(songName, SongDataPtr, 20);
  1488.     songName[20] = '\0';
  1489.  
  1490.     pattNum = 0;
  1491.     for (i = 0; i < 128; i++)
  1492.     {
  1493.         if (SongDataPtr[952+i] > pattNum)
  1494.             pattNum = SongDataPtr[952+i];
  1495.     }
  1496.     pattNum++;
  1497.  
  1498.     // first count total sample size to allocate
  1499.     totalSampleSize = 0;
  1500.     for (i = 0; i < 31; i++)
  1501.     {
  1502.         p = PTR2WORD(&SongDataPtr[42 + (i * 30)]);
  1503.         totalSampleSize += (SWAP16(p[0]) * 2);
  1504.     }
  1505.  
  1506.     SampleData = (int8_t *)malloc(totalSampleSize);
  1507.     if (SampleData == NULL)
  1508.         return false;
  1509.  
  1510.     // setup and load samples
  1511.     songSampleData = (int8_t *)&SongDataPtr[1084 + (pattNum * 1024)];
  1512.  
  1513.     sampleDataOffset = 0;
  1514.     for (i = 0; i < 31; i++)
  1515.     {
  1516.         p = PTR2WORD(&SongDataPtr[42 + (i * 30)]);
  1517.  
  1518.         // swap bytes in words (Amiga word -> Intel word)
  1519.         p[0] = SWAP16(p[0]); // n_length
  1520.         p[2] = SWAP16(p[2]); // n_repeat
  1521.         p[3] = SWAP16(p[3]); // n_replen
  1522.  
  1523.         // set up sample pointer and load sample
  1524.         if (p[0] == 0)
  1525.         {
  1526.             SampleStarts[i] = EmptySample;
  1527.         }
  1528.         else
  1529.         {
  1530.             SampleStarts[i] = &SampleData[sampleDataOffset];
  1531.             memcpy(SampleStarts[i], songSampleData, p[0] * 2);
  1532.  
  1533.             sampleDataOffset += p[0] * 2;
  1534.             songSampleData += p[0] * 2;
  1535.         }
  1536.  
  1537.         if (p[3] == 0)
  1538.             p[3] = 1; // fix illegal loop length (f.ex. from "Fasttracker II" .MODs)
  1539.  
  1540.         // adjust sample length if loop was overflowing
  1541.         if (p[3] > 1 && p[2]+p[3] > p[0])
  1542.         {
  1543.             loopOverflowVal = (p[2] + p[3]) - p[0];
  1544.             if ((p[0] + loopOverflowVal) <= MAX_SAMPLE_LEN/2)
  1545.             {
  1546.                 p[0] += (uint16_t)loopOverflowVal;
  1547.             }
  1548.             else
  1549.             {
  1550.                 p[2] = 0;
  1551.                 p[3] = 2;
  1552.             }
  1553.         }
  1554.  
  1555.         if (p[0] >= 1 && p[2]+p[3] <= 1)
  1556.         {
  1557.             // if no loop, zero first two samples of data to prevent "beep"
  1558.             SampleStarts[i][0] = 0;
  1559.             SampleStarts[i][1] = 0;
  1560.         }
  1561.     }
  1562.  
  1563.     return true;
  1564. }
  1565.  
  1566. // MIXER RELATED CODE
  1567.  
  1568. // these are used to create equal powered stereo separation
  1569. static double sinApx(double fX)
  1570. {
  1571.     fX = fX * (2.0 - fX);
  1572.     return fX * 1.09742972 + fX * fX * 0.31678383;
  1573. }
  1574.  
  1575. static double cosApx(double fX)
  1576. {
  1577.     fX = (1.0 - fX) * (1.0 + fX);
  1578.     return fX * 1.09742972 + fX * fX * 0.31678383;
  1579. }
  1580. // -------------------------------------------------
  1581.  
  1582. static void calculatePans(int8_t stereoSeparation)
  1583. {
  1584.     uint8_t scaledPanPos;
  1585.     double p;
  1586.  
  1587.     if (stereoSeparation > 100)
  1588.         stereoSeparation = 100;
  1589.  
  1590.     scaledPanPos = (stereoSeparation * 128) / 100;
  1591.  
  1592.     p = (128 - scaledPanPos) * (1.0 / 256.0);
  1593.     paula[0].dPanL = cosApx(p);
  1594.     paula[0].dPanR = sinApx(p);
  1595.     paula[3].dPanL = cosApx(p);
  1596.     paula[3].dPanR = sinApx(p);
  1597.  
  1598.     p = (128 + scaledPanPos) * (1.0 / 256.0);
  1599.     paula[1].dPanL = cosApx(p);
  1600.     paula[1].dPanR = sinApx(p);
  1601.     paula[2].dPanL = cosApx(p);
  1602.     paula[2].dPanR = sinApx(p);
  1603. }
  1604.  
  1605. static void resetAudioDithering(void)
  1606. {
  1607.     randSeed = INITIAL_DITHER_SEED;
  1608.     dPrngStateL = 0.0;
  1609.     dPrngStateR = 0.0;
  1610. }
  1611.  
  1612. static inline int32_t random32(void)
  1613. {
  1614.     // LCG random 32-bit generator (quite good and fast)
  1615.     randSeed = randSeed * 134775813 + 1;
  1616.     return randSeed;
  1617. }
  1618.  
  1619. #define POST_MIX_STAGE_1 \
  1620.     dOut[0] = dMixBufferL[i]; \
  1621.     dOut[1] = dMixBufferR[i]; \
  1622.  
  1623. #define POST_MIX_STAGE_2 \
  1624.     /* normalize and flip phase (A500/A1200 has an inverted audio signal) */ \
  1625.     dOut[0] *= (-INT16_MAX / (double)AMIGA_VOICES); \
  1626.     dOut[1] *= (-INT16_MAX / (double)AMIGA_VOICES); \
  1627.     \
  1628.     /* left channel - 1-bit triangular dithering (high-pass filtered) */ \
  1629.     dPrng = random32() * (0.5 / INT32_MAX); /* -0.5..0.5 */ \
  1630.     dOut[0] = (dOut[0] + dPrng) - dPrngStateL; \
  1631.     dPrngStateL = dPrng; \
  1632.     smp32 = (int32_t)dOut[0]; \
  1633.     smp32 = (smp32 * masterVol) >> 8; \
  1634.     CLAMP16(smp32); \
  1635.     *stream++ = (int16_t)smp32; \
  1636.     \
  1637.     /* right channel */ \
  1638.     dPrng = random32() * (0.5 / INT32_MAX); \
  1639.     dOut[1] = (dOut[1] + dPrng) - dPrngStateR; \
  1640.     dPrngStateR = dPrng; \
  1641.     smp32 = (int32_t)dOut[1]; \
  1642.     smp32 = (smp32 * masterVol) >> 8; \
  1643.     CLAMP16(smp32); \
  1644.     *stream++ = (int16_t)smp32; \
  1645.  
  1646. static void mixAudio(int16_t *stream, int32_t sampleBlockLength)
  1647. {
  1648.     int32_t i, j, smp32;
  1649.     double dPrng, dSmp, dVol, dOut[2];
  1650.     paulaVoice_t *v;
  1651. #ifdef USE_BLEP
  1652.     blep_t *bSmp, *bVol;
  1653. #endif
  1654.  
  1655.     memset(dMixBufferL, 0, sampleBlockLength * sizeof (double));
  1656.     memset(dMixBufferR, 0, sampleBlockLength * sizeof (double));
  1657.  
  1658.     if (musicPaused)
  1659.     {
  1660.         memset(stream, 0, sampleBlockLength * (sizeof (int16_t) * 2));
  1661.         return;
  1662.     }
  1663.  
  1664.     v = paula;
  1665.     for (i = 0; i < AMIGA_VOICES; i++, v++)
  1666.     {
  1667.         if (!v->active)
  1668.             continue;
  1669.  
  1670. #ifdef USE_BLEP
  1671.         bSmp = &blep[i];
  1672.         bVol = &blepVol[i];
  1673. #endif
  1674.         for (j = 0; j < sampleBlockLength; j++)
  1675.         {
  1676.             dSmp = v->data[v->pos] * (1.0 / 128.0);
  1677.             dVol = v->dVolume;
  1678.  
  1679. #ifdef USE_BLEP
  1680.             if (dSmp != bSmp->dLastValue)
  1681.             {
  1682.                 if (v->dLastDelta > v->dLastPhase)
  1683.                 {
  1684.                     // div->mul trick: v->dLastDeltaMul is 1.0 / v->dLastDelta
  1685.                     blepAdd(bSmp, v->dLastPhase * v->dLastDeltaMul, bSmp->dLastValue - dSmp);
  1686.                 }
  1687.  
  1688.                 bSmp->dLastValue = dSmp;
  1689.             }
  1690.  
  1691.             if (dVol != bVol->dLastValue)
  1692.             {
  1693.                 blepVolAdd(bVol, bVol->dLastValue - dVol);
  1694.                 bVol->dLastValue = dVol;
  1695.             }
  1696.  
  1697.             if (bSmp->samplesLeft > 0) dSmp = blepRun(bSmp, dSmp);
  1698.             if (bVol->samplesLeft > 0) dVol = blepRun(bVol, dVol);
  1699. #endif
  1700.             dSmp *= dVol;
  1701.  
  1702.             dMixBufferL[j] += dSmp * v->dPanL;
  1703.             dMixBufferR[j] += dSmp * v->dPanR;
  1704.  
  1705.             v->dPhase += v->dDelta;
  1706.             if (v->dPhase >= 1.0)
  1707.             {
  1708.                 v->dPhase -= 1.0;
  1709. #ifdef USE_BLEP
  1710.                 v->dLastPhase = v->dPhase;
  1711.                 v->dLastDelta = v->dDelta;
  1712.                 v->dLastDeltaMul = v->dDeltaMul;
  1713. #endif
  1714.                 if (++v->pos >= v->length)
  1715.                 {
  1716.                     v->pos = 0;
  1717.  
  1718.                     // re-fetch Paula register values now
  1719.                     v->length = v->newLength;
  1720.                     v->data = v->newData;
  1721.                 }
  1722.             }
  1723.         }
  1724.     }
  1725.  
  1726. #ifdef LED_FILTER
  1727.     if (LEDFilterOn)
  1728.     {
  1729.         for (i = 0; i < sampleBlockLength; i++)
  1730.         {
  1731.             POST_MIX_STAGE_1
  1732.  
  1733. #ifdef USE_LOWPASS
  1734.             RCLowPassFilter(&filterLo, dOut, dOut);
  1735. #endif
  1736.  
  1737. #ifdef LED_FILTER
  1738.             LEDFilter(&filterLED, dOut, dOut);
  1739. #endif
  1740.  
  1741. #ifdef USE_HIGHPASS
  1742.             RCHighPassFilter(&filterHi, dOut, dOut);
  1743. #endif
  1744.  
  1745.             POST_MIX_STAGE_2
  1746.         }
  1747.     }
  1748.     else
  1749. #endif
  1750.     {
  1751.         for (i = 0; i < sampleBlockLength; i++)
  1752.         {
  1753.             POST_MIX_STAGE_1
  1754.  
  1755. #ifdef USE_LOWPASS
  1756.             RCLowPassFilter(&filterLo, dOut, dOut);
  1757. #endif
  1758.  
  1759. #ifdef USE_HIGHPASS
  1760.             RCHighPassFilter(&filterHi, dOut, dOut);
  1761. #endif
  1762.  
  1763.             POST_MIX_STAGE_2
  1764.         }
  1765.     }
  1766. }
  1767.  
  1768. void pt2play_PauseSong(bool flag)
  1769. {
  1770.     musicPaused = flag;
  1771. }
  1772.  
  1773. void pt2play_TogglePause(void)
  1774. {
  1775.     musicPaused ^= 1;
  1776. }
  1777.  
  1778. void pt2play_Close(void)
  1779. {
  1780.     closeMixer();
  1781.  
  1782.     if (SampleData != NULL)
  1783.     {
  1784.         free(SampleData);
  1785.         SampleData = NULL;
  1786.     }
  1787.  
  1788.     if (dMixBufferL != NULL)
  1789.     {
  1790.         free(dMixBufferL);
  1791.         dMixBufferL = NULL;
  1792.     }
  1793.  
  1794.     if (dMixBufferR != NULL)
  1795.     {
  1796.         free(dMixBufferR);
  1797.         dMixBufferR = NULL;
  1798.     }
  1799.  
  1800.     if (SongDataPtr != NULL)
  1801.     {
  1802.         free(SongDataPtr);
  1803.         SongDataPtr = NULL;
  1804.     }
  1805. }
  1806.  
  1807. bool pt2play_PlaySong(const uint8_t *moduleData, uint32_t dataLength, int8_t tempoMode, uint32_t audioFreq)
  1808. {
  1809.     if (audioFreq == 0)
  1810.         audioFreq = 44100;
  1811.  
  1812.     musicPaused = true;
  1813.  
  1814.     pt2play_Close();
  1815.     memset(songName, 0, sizeof (songName));
  1816.  
  1817.     oldPeriod = -1;
  1818.     sampleCounter = 0;
  1819.     SongPlaying = false;
  1820.  
  1821.     dMixBufferL = (double *)malloc(MIX_BUF_SAMPLES * sizeof (double));
  1822.     dMixBufferR = (double *)malloc(MIX_BUF_SAMPLES * sizeof (double));
  1823.  
  1824.     if (dMixBufferL == NULL || dMixBufferR == NULL)
  1825.     {
  1826.         pt2play_Close();
  1827.         return false;
  1828.     }
  1829.  
  1830.     // rates below 32kHz will mess up the BLEP synthesis
  1831.     audioFreq = CLAMP(audioFreq, 32000, 96000);
  1832.  
  1833.     audioRate = audioFreq;
  1834.     dPeriodToDeltaDiv = (double)PAULA_PAL_CLK / audioRate;
  1835.     soundBufferSize = MIX_BUF_SAMPLES;
  1836.  
  1837. #if defined(USE_HIGHPASS) || defined(USE_LOWPASS)
  1838.     double R, C, fc;
  1839. #endif
  1840.  
  1841. #ifdef USE_LOWPASS
  1842.     // A500 one-pole 6db/oct static RC low-pass filter:
  1843.     R = 360.0; // R321 (360 ohm resistor)
  1844.     C = 1e-7;  // C321 (0.1uF capacitor)
  1845.     fc = 1.0 / (2.0 * M_PI * R * C); // ~4420.97Hz
  1846.     calcRCFilterCoeffs(audioRate, fc, &filterLo);
  1847. #endif
  1848.  
  1849. #ifdef LED_FILTER
  1850.     double R1, R2, C1, C2, fb;
  1851.  
  1852.     // A500/A1200 Sallen-Key filter ("LED"):
  1853.     R1 = 10000.0; // R322 (10K ohm resistor)
  1854.     R2 = 10000.0; // R323 (10K ohm resistor)
  1855.     C1 = 6.8e-9;  // C322 (6800pF capacitor)
  1856.     C2 = 3.9e-9;  // C323 (3900pF capacitor)
  1857.     fc = 1.0 / (2.0 * M_PI * sqrt(R1 * R2 * C1 * C2)); // ~3090.53Hz
  1858.     fb = 0.125; // Fb = 0.125 : Q ~= 1/sqrt(2) (Butterworth)
  1859.     calcLEDFilterCoeffs(audioRate, fc, fb, &filterLED);
  1860. #endif
  1861.  
  1862. #ifdef USE_HIGHPASS
  1863.     // A500/A1200 one-pole 6db/oct static RC high-pass filter:
  1864.     R = 1000.0 + 390.0; // R324 (1K ohm resistor) + R325 (390 ohm resistor)
  1865.     C = 2.2e-5;         // C334 (22uF capacitor) (+ C324 (0.33uF capacitor) if A500)
  1866.     fc = 1.0 / (2.0 * M_PI * R * C); // ~5.20Hz
  1867.     calcRCFilterCoeffs(audioRate, fc, &filterHi);
  1868. #endif
  1869.  
  1870.     if (!moduleInit(moduleData, dataLength))
  1871.     {
  1872.         pt2play_Close();
  1873.         return false;
  1874.     }
  1875.  
  1876.     memset(paula, 0, sizeof (paula));
  1877.     calculatePans(stereoSep);
  1878.  
  1879. #ifdef USE_BLEP
  1880.     memset(blep, 0, sizeof (blep));
  1881.     memset(blepVol, 0, sizeof (blepVol));
  1882. #endif
  1883.  
  1884. #ifdef USE_LOWPASS
  1885.     clearRCFilterState(&filterLo);
  1886. #endif
  1887.  
  1888. #ifdef LED_FILTER
  1889.     clearLEDFilterState();
  1890. #endif
  1891.  
  1892. #ifdef USE_HIGHPASS
  1893.     clearRCFilterState(&filterHi);
  1894. #endif
  1895.  
  1896.     resetAudioDithering();
  1897.  
  1898.     CurrSpeed = 6;
  1899.     Counter = 0;
  1900.     SongPosition = 0;
  1901.     PatternPos = 0;
  1902.     PattDelTime = 0;
  1903.     PattDelTime2 = 0;
  1904.     PBreakPosition = 0;
  1905.     PosJumpAssert = false;
  1906.     PBreakFlag = false;
  1907.     LowMask = 0xFF;
  1908.     TempoMode = tempoMode ? VBLANK_TEMPO_MODE : CIA_TEMPO_MODE;
  1909.     SongPlaying = true;
  1910.     musicPaused = false;
  1911.  
  1912. #ifdef LED_FILTER
  1913.     LEDFilterOn = false;
  1914. #endif
  1915.  
  1916.     if (!openMixer(audioRate))
  1917.     {
  1918.         pt2play_Close();
  1919.         return false;
  1920.     }
  1921.  
  1922.     SetReplayerBPM(125);
  1923.     musicPaused = false;
  1924.     return true;
  1925. }
  1926.  
  1927. void pt2play_SetStereoSep(uint8_t percentage)
  1928. {
  1929.     stereoSep = percentage;
  1930.     if (stereoSep > 100)
  1931.         stereoSep = 100;
  1932.  
  1933.     calculatePans(stereoSep);
  1934. }
  1935.  
  1936. void pt2play_SetMasterVol(uint16_t vol)
  1937. {
  1938.     masterVol = CLAMP(vol, 0, 256);
  1939. }
  1940.  
  1941. uint16_t pt2play_GetMasterVol(void)
  1942. {
  1943.     return (uint16_t)masterVol;
  1944. }
  1945.  
  1946. char *pt2play_GetSongName(void)
  1947. {
  1948.     return songName;
  1949. }
  1950.  
  1951. uint32_t pt2play_GetMixerTicks(void)
  1952. {
  1953.     if (audioRate < 1000)
  1954.         return 0;
  1955.  
  1956.     return sampleCounter / (audioRate / 1000);
  1957. }
  1958.  
  1959. static void pt2play_FillAudioBuffer(int16_t *buffer, int32_t samples)
  1960. {
  1961.     int32_t a, b;
  1962.  
  1963.     a = samples;
  1964.     while (a > 0)
  1965.     {
  1966.         if (samplesPerTickLeft == 0)
  1967.         {
  1968.             if (!musicPaused)
  1969.                 tickReplayer();
  1970.  
  1971.             samplesPerTickLeft = samplesPerTick;
  1972.         }
  1973.  
  1974.         b = a;
  1975.         if (b > samplesPerTickLeft)
  1976.             b = samplesPerTickLeft;
  1977.  
  1978.         mixAudio(buffer, b);
  1979.         buffer += (uint32_t)b << 1;
  1980.  
  1981.         a -= b;
  1982.         samplesPerTickLeft -= b;
  1983.     }
  1984.  
  1985.     sampleCounter += samples;
  1986. }
  1987.  
  1988. // the following must be changed if you want to use another audio API than WinMM
  1989.  
  1990. #ifndef WIN32_LEAN_AND_MEAN
  1991. #define WIN32_LEAN_AND_MEAN
  1992. #endif
  1993.  
  1994. #include <windows.h>
  1995. #include <mmsystem.h>
  1996.  
  1997. #define MIX_BUF_NUM 2
  1998.  
  1999. static volatile BOOL audioRunningFlag;
  2000. static uint8_t currBuffer;
  2001. static int16_t *mixBuffer[MIX_BUF_NUM];
  2002. static HANDLE hThread, hAudioSem;
  2003. static WAVEHDR waveBlocks[MIX_BUF_NUM];
  2004. static HWAVEOUT hWave;
  2005.  
  2006. static DWORD WINAPI mixThread(LPVOID lpParam)
  2007. {
  2008.     WAVEHDR *waveBlock;
  2009.  
  2010.     (void)lpParam;
  2011.  
  2012.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
  2013.  
  2014.     while (audioRunningFlag)
  2015.     {
  2016.         waveBlock = &waveBlocks[currBuffer];
  2017.         pt2play_FillAudioBuffer((int16_t *)waveBlock->lpData, MIX_BUF_SAMPLES);
  2018.         waveOutWrite(hWave, waveBlock, sizeof (WAVEHDR));
  2019.         currBuffer = (currBuffer + 1) % MIX_BUF_NUM;
  2020.  
  2021.         // wait for buffer fill request
  2022.         WaitForSingleObject(hAudioSem, INFINITE);
  2023.     }
  2024.  
  2025.     return 0;
  2026. }
  2027.  
  2028. static void CALLBACK waveProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
  2029. {
  2030.     (void)hWaveOut;
  2031.     (void)uMsg;
  2032.     (void)dwInstance;
  2033.     (void)dwParam1;
  2034.     (void)dwParam2;
  2035.  
  2036.     if (uMsg == WOM_DONE)
  2037.         ReleaseSemaphore(hAudioSem, 1, NULL);
  2038. }
  2039.  
  2040. static void closeMixer(void)
  2041. {
  2042.     int32_t i;
  2043.  
  2044.     audioRunningFlag = false; // make thread end when it's done
  2045.  
  2046.     if (hAudioSem != NULL)
  2047.         ReleaseSemaphore(hAudioSem, 1, NULL);
  2048.  
  2049.     if (hThread != NULL)
  2050.     {
  2051.         WaitForSingleObject(hThread, INFINITE);
  2052.         CloseHandle(hThread);
  2053.         hThread = NULL;
  2054.     }
  2055.  
  2056.     if (hAudioSem != NULL)
  2057.     {
  2058.         CloseHandle(hAudioSem);
  2059.         hAudioSem = NULL;
  2060.     }
  2061.  
  2062.     if (hWave != NULL)
  2063.     {
  2064.         waveOutReset(hWave);
  2065.  
  2066.         for (i = 0; i < MIX_BUF_NUM; i++)
  2067.         {
  2068.             if (waveBlocks[i].dwUser != 0xFFFF)
  2069.                 waveOutUnprepareHeader(hWave, &waveBlocks[i], sizeof (WAVEHDR));
  2070.         }
  2071.  
  2072.         waveOutClose(hWave);
  2073.         hWave = NULL;
  2074.     }
  2075.  
  2076.     for (i = 0; i < MIX_BUF_NUM; i++)
  2077.     {
  2078.         if (mixBuffer[i] != NULL)
  2079.         {
  2080.             free(mixBuffer[i]);
  2081.             mixBuffer[i] = NULL;
  2082.         }
  2083.     }
  2084. }
  2085.  
  2086. static uint16_t bpm2SmpsPerTick(uint32_t bpm, uint32_t audioFreq)
  2087. {
  2088.     uint32_t ciaVal;
  2089.     double dFreqMul;
  2090.  
  2091.     if (bpm == 0)
  2092.         return 0;
  2093.  
  2094.     ciaVal = (uint32_t)(1773447 / bpm); // yes, PT truncates here
  2095.     dFreqMul = ciaVal * (1.0 / CIA_PAL_CLK);
  2096.  
  2097.     return (uint16_t)((audioFreq * dFreqMul) + 0.5);
  2098. }
  2099.  
  2100. static bool openMixer(uint32_t audioFreq)
  2101. {
  2102.     int32_t i;
  2103.     DWORD threadID;
  2104.     WAVEFORMATEX wfx;
  2105.  
  2106.     // don't unprepare headers on error
  2107.     for (i = 0; i < MIX_BUF_NUM; i++)
  2108.         waveBlocks[i].dwUser = 0xFFFF;
  2109.  
  2110.     closeMixer();
  2111.  
  2112.     ZeroMemory(&wfx, sizeof (wfx));
  2113.     wfx.nSamplesPerSec = audioFreq;
  2114.     wfx.wBitsPerSample = 16;
  2115.     wfx.nChannels = 2;
  2116.     wfx.wFormatTag = WAVE_FORMAT_PCM;
  2117.     wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8);
  2118.     wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
  2119.  
  2120.     samplesPerTickLeft = 0;
  2121.     currBuffer = 0;
  2122.  
  2123.     if (waveOutOpen(&hWave, WAVE_MAPPER, &wfx, (DWORD_PTR)&waveProc, 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
  2124.         goto omError;
  2125.  
  2126.     // create semaphore for buffer fill requests
  2127.     hAudioSem = CreateSemaphore(NULL, MIX_BUF_NUM - 1, MIX_BUF_NUM, NULL);
  2128.     if (hAudioSem == NULL)
  2129.         goto omError;
  2130.  
  2131.     // allocate WinMM mix buffers
  2132.     for (i = 0; i < MIX_BUF_NUM; i++)
  2133.     {
  2134.         mixBuffer[i] = (int16_t *)calloc(MIX_BUF_SAMPLES, wfx.nBlockAlign);
  2135.         if (mixBuffer[i] == NULL)
  2136.             goto omError;
  2137.     }
  2138.  
  2139.     // initialize WinMM mix headers
  2140.     memset(waveBlocks, 0, sizeof (waveBlocks));
  2141.     for (i = 0; i < MIX_BUF_NUM; i++)
  2142.     {
  2143.         waveBlocks[i].lpData = (LPSTR)mixBuffer[i];
  2144.         waveBlocks[i].dwBufferLength = MIX_BUF_SAMPLES * wfx.nBlockAlign;
  2145.         waveBlocks[i].dwFlags = WHDR_DONE;
  2146.  
  2147.         if (waveOutPrepareHeader(hWave, &waveBlocks[i], sizeof (WAVEHDR)) != MMSYSERR_NOERROR)
  2148.             goto omError;
  2149.     }
  2150.  
  2151.     // create main mixer thread
  2152.     audioRunningFlag = true;
  2153.     hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)mixThread, NULL, 0, &threadID);
  2154.     if (hThread == NULL)
  2155.         goto omError;
  2156.  
  2157.     for (i = 32; i <= 255; i++)
  2158.         bpmTab[i-32] = bpm2SmpsPerTick(i, audioFreq);
  2159.  
  2160.     return TRUE;
  2161.  
  2162. omError:
  2163.     closeMixer();
  2164.     return FALSE;
  2165. }
  2166. // ---------------------------------------------------------------------------
  2167.  
  2168. // END OF FILE
  2169.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement