8bitbubsy

pt2play v1.61

Sep 29th, 2013 (edited)
1,882
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×