SHARE
TWEET

fc14play v1.2

8bitbubsy Nov 17th, 2015 (edited) 328 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ** FC14PLAY v1.2 - 17th of April 2017 - http://16-bits.org
  3. ** =======================================================
  4. ** - NOT BIG ENDIAN SAFE! -
  5. **
  6. ** Very accurate C port of Future Composer 1.4's replayer,
  7. ** by Olav "8bitbubsy" Sørensen, using a FC1.4 disassembly (its supplied replayer code was buggy).
  8. ** Works perfectly with v1.0..v1.3 modules as well.
  9. **
  10. ** The BLEP (Band-Limited Step) and filter routines were coded by aciddose.
  11. **
  12. **
  13. ** You need to link winmm.lib for this to compile (-lwinmm)
  14. **
  15. ** User functions:
  16. **
  17. ** #include <stdint.h>
  18. **
  19. ** int8_t fc14play_Init(uint32_t outputFreq, const uint8_t *moduleData);
  20. ** void fc14play_Close(void);
  21. ** void fc14play_PauseSong(int8_t pause);
  22. ** void fc14play_PlaySong(void);
  23. ** void fc14play_SetStereoSep(uint8_t percentage);
  24. */
  25.  
  26. /* == USER ADJUSTABLE SETTINGS == */
  27. #define STEREO_SEP (15)    /* --> Initial stereo separation in percent - 0 = mono, 100 = hard pan (like Amiga) */
  28. #define NORM_FACTOR (4.0f) /* --> Slightly increase this value if the song is too loud. Decrease if too quiet... */
  29. #define USE_HIGHPASS       /* --> 5.2Hz high-pass filter present in all Amigas - comment out for a speed-up  */
  30. //#define USE_LOWPASS      /* --> 4.4kHz low-pass filter in all Amigas except A1200 - comment out for sharper sound */
  31. #define ROUND_SAMPLES      /* --> Round mixed float samples before converting to 16-bit int - comment out for a speed-up */
  32. #define USE_BLEP           /* --> Reduces some unwanted aliasing (closer to real Amiga) - comment out for a speed-up */
  33.  
  34. /* for the best possible audio quality, enable everything except USE_LOWPASS */
  35. /* ------------------------------ */
  36.  
  37. #ifdef _MSC_VER
  38. #define inline __forceinline
  39. #endif
  40.  
  41. /* used for faster windows.h parsing when compiling */
  42. #ifndef WIN32_LEAN_AND_MEAN
  43. #define WIN32_LEAN_AND_MEAN
  44. #endif
  45.  
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <stdint.h>
  49. #include <math.h>     /* tanf() */
  50. #include <windows.h>  /* win32 audio mixer */
  51. #include <mmsystem.h> /* win32 audio mixer */
  52.  
  53. #define PAULA_PAL_CLK 3546895
  54. #define AMIGA_VBLANK_RATE 50 /* 60 for NTSC replay speed */
  55.  
  56. /* don't change these two unless you know what you're doing... */
  57. #define MIX_BUF_NUM 7
  58. #define MIX_BUF_LEN 2048
  59.  
  60. #define SEQ_SIZE 13
  61. #define PAT_MAX_SIZE 64
  62. #define PAT_END_MARKER 0x49
  63. #define VOL_TAB_SIZE 64
  64. #define FREQ_TAB_SIZE 64
  65. #define NUM_SAMPLES 10
  66. #define NUM_WAVEFORMS 80
  67. #define NUM_WAVEFORMS_SMOD 47
  68.  
  69. /* BLEP CONSTANTS */
  70. #define BLEP_ZC 8
  71. #define BLEP_OS 5
  72. #define BLEP_SP 5
  73. #define BLEP_NS (BLEP_ZC * BLEP_OS / BLEP_SP)
  74. #define BLEP_RNS 7 /* RNS = (2^ > NS) - 1 */
  75.  
  76. /* STRUCTS */
  77. typedef struct blep_t
  78. {
  79.     int32_t index, samplesLeft;
  80.     float buffer[BLEP_RNS + 1], lastValue;
  81. } blep_t;
  82.  
  83. typedef struct lossyIntegrator_t
  84. {
  85.     float buffer[2], coeff[2];
  86. } lossyIntegrator_t;
  87.  
  88. typedef struct ledFilter_t
  89. {
  90.     float led[4];
  91. } ledFilter_t;
  92.  
  93. typedef struct ledFilterCoeff_t
  94. {
  95.     float led, ledFb;
  96. } ledFilterCoeff_t;
  97.  
  98. typedef struct paulaVoice_t
  99. {
  100.     const int8_t *SRC_DAT;
  101.     int8_t DMA_ON;
  102.     const int8_t *DMA_DAT;
  103.     uint32_t DMA_LEN, DMA_POS, SRC_LEN;
  104.     float SRC_VOL, DELTA, FRAC, LASTDELTA, LASTFRAC, PANL, PANR;
  105. } paulaVoice_t;
  106.  
  107. typedef struct soundInfo_t
  108. {
  109.     /* don't change the order of these */
  110.     int8_t *data;
  111.     uint16_t length;
  112.     int8_t *repeat;
  113.     uint16_t replen;
  114. } soundInfo_t;
  115.  
  116. typedef struct fcChannel_t
  117. {
  118.     int8_t pitchBendValue, pitchBendCounter, note;
  119.     int8_t noteTranspose, soundTranspose, *loopStart;
  120.     int8_t volume, periodTranspose;
  121.     uint8_t voiceIndex, *seqStartPtr, *patPtr, *freqTabPtr;
  122.     uint8_t freqSusCounter, *volTabPtr, volSusCounter, DMAWaitFrames;
  123.     uint8_t pitchBendDelay, vibratoSpeed, vibratoDepth, vibratoCounter;
  124.     uint8_t vibratoDelay, vibratoUp, volSlideSpeed, volSlideDelay;
  125.     uint8_t volSlideCounter, portaParam, portaDelay, volDelayCounter;
  126.     uint8_t volDelayLength;
  127.     int16_t portaValue;
  128.     uint16_t loopLength, freqTabPos, volTabPos, patPos;
  129.     uint32_t seqPos;
  130. } fcChannel_t;
  131.  
  132. /* STATIC DATA */
  133.  
  134. static volatile int8_t mixingMutex, isMixing;
  135. static int8_t initdone, *ptr8s_1, *ptr8s_1, *mixerBuffer;
  136. static uint8_t spdtemp, spdtemp2, respcnt,  repspd, onoff, fc14;
  137. static uint8_t *SEQpoint, *PATpoint, *FRQpoint, *VOLpoint;
  138. static uint8_t *ptr8u_1, *ptr8u_2, *ptr8u_3;
  139. static uint16_t audtemp, *ptr16u_1, *ptr16u_2, *ptr16u_3;
  140. static int32_t soundBufferSize, samplesLeft;
  141. static uint32_t numSequences;
  142. static volatile uint32_t samplesPerFrame;
  143. static float *masterBufferL, *masterBufferR, f_outputFreq;
  144. static paulaVoice_t AUD[4] =
  145. { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  146. static fcChannel_t Channel[4];
  147. static soundInfo_t samples[NUM_SAMPLES + NUM_WAVEFORMS];
  148. static WAVEHDR waveBlocks[MIX_BUF_NUM];
  149. static HWAVEOUT hWaveOut;
  150. static WAVEFORMATEX wfx;
  151.  
  152. #ifdef USE_BLEP
  153. static blep_t blep[4], blepVol[4];
  154. #endif
  155. #ifdef USE_HIGHPASS
  156. static lossyIntegrator_t filterHi;
  157. #endif
  158. #ifdef USE_LOWPASS
  159. static lossyIntegrator_t filterLo;
  160. #endif
  161.  
  162. /* MACROS */
  163.  
  164. #define LERP(x, y, z) ((x) + ((y) - (x)) * (z))
  165. #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
  166. #define ROUND_SMP_F(x) (((x) >= 0.0f) ? (floorf(x + 0.5f)) : (ceilf(x - 0.5f)))
  167. #define CLAMP16(i) \
  168. { \
  169.     if ((int16_t)(i) != i) \
  170.         i = 0x7FFF ^ (i >> 31); \
  171. }
  172. #define PTR2LONG(x) ((uint32_t *)(x))
  173. #define PTR2WORD(x) ((uint16_t *)(x))
  174. #define SWAP16(x) ((uint16_t)(((x) << 8) | ((x) >> 8)))
  175. #define SWAP32(value) \
  176. ( \
  177.     (((uint32_t)((value) & 0x000000FF)) << 24) | \
  178.     (((uint32_t)((value) & 0x0000FF00)) <<  8) | \
  179.     (((uint32_t)((value) & 0x00FF0000)) >>  8) | \
  180.     (((uint32_t)((value) & 0xFF000000)) >> 24)   \
  181. )
  182.  
  183. /* TABLES */
  184.  
  185. static uint8_t silentTable[8] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1 };
  186.  
  187. static const uint16_t periods[128] =
  188. {
  189.     // 1.0..1.3 periods
  190.     0x06B0, 0x0650, 0x05F4, 0x05A0, 0x054C, 0x0500, 0x04B8, 0x0474,
  191.     0x0434, 0x03F8, 0x03C0, 0x038A, 0x0358, 0x0328, 0x02FA, 0x02D0,
  192.     0x02A6, 0x0280, 0x025C, 0x023A, 0x021A, 0x01FC, 0x01E0, 0x01C5,
  193.     0x01AC, 0x0194, 0x017D, 0x0168, 0x0153, 0x0140, 0x012E, 0x011D,
  194.     0x010D, 0x00FE, 0x00F0, 0x00E2, 0x00D6, 0x00CA, 0x00BE, 0x00B4,
  195.     0x00AA, 0x00A0, 0x0097, 0x008F, 0x0087, 0x007F, 0x0078, 0x0071,
  196.     0x0071, 0x0071, 0x0071, 0x0071, 0x0071, 0x0071, 0x0071, 0x0071,
  197.     0x0071, 0x0071, 0x0071, 0x0071,
  198.  
  199.     // 1.4 periods
  200.     0x0D60, 0x0CA0, 0x0BE8, 0x0B40, 0x0A98, 0x0A00, 0x0970, 0x08E8,
  201.     0x0868, 0x07F0, 0x0780, 0x0714, 0x06B0, 0x0650, 0x05F4, 0x05A0,
  202.     0x054C, 0x0500, 0x04B8, 0x0474, 0x0434, 0x03F8, 0x03C0, 0x038A,
  203.     0x0358, 0x0328, 0x02FA, 0x02D0, 0x02A6, 0x0280, 0x025C, 0x023A,
  204.     0x021A, 0x01FC, 0x01E0, 0x01C5, 0x01AC, 0x0194, 0x017D, 0x0168,
  205.     0x0153, 0x0140, 0x012E, 0x011D, 0x010D, 0x00FE, 0x00F0, 0x00E2,
  206.     0x00D6, 0x00CA, 0x00BE, 0x00B4, 0x00AA, 0x00A0, 0x0097, 0x008F,
  207.     0x0087, 0x007F, 0x0078, 0x0071, 0x0071, 0x0071, 0x0071, 0x0071,
  208.     0x0071, 0x0071, 0x0071, 0x0071
  209. };
  210.  
  211. static const int8_t waveformDatas[1344] =
  212. {
  213.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  214.     0x3F,0x37,0x2F,0x27,0x1F,0x17,0x0F,0x07,0xFF,0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  215.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  216.     0xC0,0x37,0x2F,0x27,0x1F,0x17,0x0F,0x07,0xFF,0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  217.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  218.     0xC0,0xB8,0x2F,0x27,0x1F,0x17,0x0F,0x07,0xFF,0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  219.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  220.     0xC0,0xB8,0xB0,0x27,0x1F,0x17,0x0F,0x07,0xFF,0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  221.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  222.     0xC0,0xB8,0xB0,0xA8,0x1F,0x17,0x0F,0x07,0xFF,0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  223.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  224.     0xC0,0xB8,0xB0,0xA8,0xA0,0x17,0x0F,0x07,0xFF,0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  225.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  226.     0xC0,0xB8,0xB0,0xA8,0xA0,0x98,0x0F,0x07,0xFF,0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  227.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  228.     0xC0,0xB8,0xB0,0xA8,0xA0,0x98,0x90,0x07,0xFF,0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  229.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  230.     0xC0,0xB8,0xB0,0xA8,0xA0,0x98,0x90,0x88,0xFF,0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  231.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  232.     0xC0,0xB8,0xB0,0xA8,0xA0,0x98,0x90,0x88,0x80,0x07,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  233.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  234.     0xC0,0xB8,0xB0,0xA8,0xA0,0x98,0x90,0x88,0x80,0x88,0x0F,0x17,0x1F,0x27,0x2F,0x37,
  235.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  236.     0xC0,0xB8,0xB0,0xA8,0xA0,0x98,0x90,0x88,0x80,0x88,0x90,0x17,0x1F,0x27,0x2F,0x37,
  237.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  238.     0xC0,0xB8,0xB0,0xA8,0xA0,0x98,0x90,0x88,0x80,0x88,0x90,0x98,0x1F,0x27,0x2F,0x37,
  239.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  240.     0xC0,0xB8,0xB0,0xA8,0xA0,0x98,0x90,0x88,0x80,0x88,0x90,0x98,0xA0,0x27,0x2F,0x37,
  241.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  242.     0xC0,0xB8,0xB0,0xA8,0xA0,0x98,0x90,0x88,0x80,0x88,0x90,0x98,0xA0,0xA8,0x2F,0x37,
  243.     0xC0,0xC0,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,0x00,0xF8,0xF0,0xE8,0xE0,0xD8,0xD0,0xC8,
  244.     0xC0,0xB8,0xB0,0xA8,0xA0,0x98,0x90,0x88,0x80,0x88,0x90,0x98,0xA0,0xA8,0xB0,0x37,
  245.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  246.     0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  247.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  248.     0x81,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  249.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  250.     0x81,0x81,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  251.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  252.     0x81,0x81,0x81,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  253.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  254.     0x81,0x81,0x81,0x81,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  255.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  256.     0x81,0x81,0x81,0x81,0x81,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  257.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  258.     0x81,0x81,0x81,0x81,0x81,0x81,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  259.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  260.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  261.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  262.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  263.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  264.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  265.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  266.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  267.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  268.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x7F,0x7F,0x7F,0x7F,0x7F,
  269.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  270.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x7F,0x7F,0x7F,0x7F,
  271.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
  272.     0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x7F,0x7F,0x7F,
  273.     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
  274.     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7F,0x7F,
  275.     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
  276.     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7F,
  277.     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  278.     0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  279.     0x80,0x80,0x80,0x80,0x80,0x80,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  280.     0x80,0x80,0x80,0x80,0x80,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  281.     0x80,0x80,0x80,0x80,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  282.     0x80,0x80,0x80,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  283.     0x80,0x80,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  284.     0x80,0x80,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
  285.     0x80,0x80,0x90,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,
  286.     0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x7F,
  287.     0x80,0x80,0xA0,0xB0,0xC0,0xD0,0xE0,0xF0,0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,
  288.     0x45,0x45,0x79,0x7D,0x7A,0x77,0x70,0x66,0x61,0x58,0x53,0x4D,0x2C,0x20,0x18,0x12,
  289.     0x04,0xDB,0xD3,0xCD,0xC6,0xBC,0xB5,0xAE,0xA8,0xA3,0x9D,0x99,0x93,0x8E,0x8B,0x8A,
  290.     0x45,0x45,0x79,0x7D,0x7A,0x77,0x70,0x66,0x5B,0x4B,0x43,0x37,0x2C,0x20,0x18,0x12,
  291.     0x04,0xF8,0xE8,0xDB,0xCF,0xC6,0xBE,0xB0,0xA8,0xA4,0x9E,0x9A,0x95,0x94,0x8D,0x83,
  292.     0x00,0x00,0x40,0x60,0x7F,0x60,0x40,0x20,0x00,0xE0,0xC0,0xA0,0x80,0xA0,0xC0,0xE0,
  293.     0x00,0x00,0x40,0x60,0x7F,0x60,0x40,0x20,0x00,0xE0,0xC0,0xA0,0x80,0xA0,0xC0,0xE0,
  294.     0x80,0x80,0x90,0x98,0xA0,0xA8,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,0xF8,
  295.     0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x7F,
  296.     0x80,0x80,0xA0,0xB0,0xC0,0xD0,0xE0,0xF0,0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70
  297. };
  298.  
  299. #ifdef USE_BLEP
  300. static const uint32_t blepData[48] =
  301. {
  302.     0x3F7FE1F1, 0x3F7FD548, 0x3F7FD6A3, 0x3F7FD4E3, 0x3F7FAD85, 0x3F7F2152,
  303.     0x3F7DBFAE, 0x3F7ACCDF, 0x3F752F1E, 0x3F6B7384, 0x3F5BFBCB, 0x3F455CF2,
  304.     0x3F26E524, 0x3F0128C4, 0x3EACC7DC, 0x3E29E86B, 0x3C1C1D29, 0xBDE4BBE6,
  305.     0xBE3AAE04, 0xBE48DEDD, 0xBE22AD7E, 0xBDB2309A, 0xBB82B620, 0x3D881411,
  306.     0x3DDADBF3, 0x3DE2C81D, 0x3DAAA01F, 0x3D1E769A, 0xBBC116D7, 0xBD1402E8,
  307.     0xBD38A069, 0xBD0C53BB, 0xBC3FFB8C, 0x3C465FD2, 0x3CEA5764, 0x3D0A51D6,
  308.     0x3CEAE2D5, 0x3C92AC5A, 0x3BE4CBF7, 0x00000000, 0x00000000, 0x00000000,
  309.     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
  310. };
  311. #endif
  312.  
  313. static const uint8_t waveformLengths[47] =
  314. {
  315.     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
  316.     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
  317.     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
  318.     0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  319.     0x10, 0x08, 0x10, 0x10, 0x08, 0x08, 0x18
  320. };
  321.  
  322. /* CODE START */
  323.  
  324. static void PaulaTurnOffDMA(uint8_t i)
  325. {
  326.     AUD[i].DMA_ON = 0;
  327. }
  328.  
  329. static void PaulaRestartDMA(uint8_t i)
  330. {
  331.     AUD[i].FRAC    = 0.0f;
  332.     AUD[i].DMA_POS = 0;
  333.     AUD[i].DMA_DAT = AUD[i].SRC_DAT;
  334.     AUD[i].DMA_LEN = AUD[i].SRC_LEN;
  335.     AUD[i].DMA_ON  = 1;
  336. }
  337.  
  338. static void PaulaSetPeriod(uint8_t i, uint16_t period)
  339. {
  340.     if (period == 0)
  341.     {
  342.         AUD[i].DELTA = 0.0f;
  343.     }
  344.     else
  345.     {
  346.         if (period < 113)
  347.             period = 113;
  348.  
  349.         AUD[i].DELTA = ((float)(PAULA_PAL_CLK) / period) / f_outputFreq;
  350.     }
  351. }
  352.  
  353. static void PaulaSetVolume(uint8_t i, uint16_t vol)
  354. {
  355.     if (vol & (1 << 6))
  356.         vol = 0x0040;
  357.     else
  358.         vol &= 0x003F;
  359.  
  360.     AUD[i].SRC_VOL = vol * (1.0f / 64.0f);
  361. }
  362.  
  363. static void PaulaSetLength(uint8_t i, uint16_t len)
  364. {
  365.     AUD[i].SRC_LEN = len * 2;
  366. }
  367.  
  368. static void PaulaSetData(uint8_t i, const int8_t *src)
  369. {
  370.     AUD[i].SRC_DAT = src;
  371. }
  372.  
  373. #if defined(USE_HIGHPASS) || defined(USE_LOWPASS)
  374. static void calcCoeffLossyIntegrator(float sr, float hz, lossyIntegrator_t *filter)
  375. {
  376.     filter->coeff[0] = tanf((3.1415927f * hz) / sr);
  377.     filter->coeff[1] = 1.0f / (1.0f + filter->coeff[0]);
  378. }
  379.  
  380. static void clearLossyIntegrator(lossyIntegrator_t *filter)
  381. {
  382.     filter->buffer[0] = 0.0f;
  383.     filter->buffer[1] = 0.0f;
  384. }
  385.  
  386. static inline void lossyIntegrator(lossyIntegrator_t *filter, float *in, float *out)
  387. {
  388.     float output;
  389.  
  390.     /* left channel low-pass */
  391.     output = (filter->coeff[0] * in[0] + filter->buffer[0]) * filter->coeff[1];
  392.     filter->buffer[0] = filter->coeff[0] * (in[0] - output) + output + 1e-10f;
  393.     out[0] = output;
  394.  
  395.     /* right channel low-pass */
  396.     output = (filter->coeff[0] * in[1] + filter->buffer[1]) * filter->coeff[1];
  397.     filter->buffer[1] = filter->coeff[0] * (in[1] - output) + output + 1e-10f;
  398.     out[1] = output;
  399. }
  400.  
  401. static inline void lossyIntegratorHighPass(lossyIntegrator_t *filter, float *in, float *out)
  402. {
  403.     float low[2];
  404.  
  405.     lossyIntegrator(filter, in, low);
  406.  
  407.     out[0] = in[0] - low[0];
  408.     out[1] = in[1] - low[1];
  409. }
  410. #endif
  411.  
  412. #ifdef USE_BLEP
  413. static inline void blepAdd(blep_t *b, float offset, float amplitude)
  414. {
  415.     int8_t n;
  416.     uint32_t i;
  417.     const float *blepSrc;
  418.     float f;
  419.  
  420.     i  = (uint32_t)(offset * BLEP_SP);
  421.     blepSrc = (const float *)(blepData) + i + BLEP_OS;
  422.  
  423.     f = (offset * BLEP_SP) - i;
  424.     i = b->index;
  425.     n = BLEP_NS;
  426.  
  427.     while (n--)
  428.     {
  429.         b->buffer[i] += (amplitude * LERP(blepSrc[0], blepSrc[1], f));
  430.         blepSrc += BLEP_SP;
  431.  
  432.         i++;
  433.         i &= BLEP_RNS;
  434.     }
  435.  
  436.     b->samplesLeft = BLEP_NS;
  437. }
  438.  
  439. static inline float blepRun(blep_t *b)
  440. {
  441.     float blepOutput;
  442.  
  443.     blepOutput = b->buffer[b->index];
  444.     b->buffer[b->index] = 0.0f;
  445.  
  446.     b->index++;
  447.     b->index &= BLEP_RNS;
  448.  
  449.     b->samplesLeft--;
  450.  
  451.     return (blepOutput);
  452. }
  453. #endif
  454.  
  455. static int8_t init_music(const uint8_t *moduleData)
  456. {
  457.     uint8_t i;
  458.  
  459.     /* "SMOD" and "FC14" */
  460.     if ((*PTR2LONG(&moduleData[0]) != 0x444F4D53) && (*PTR2LONG(&moduleData[0]) != 0x34314346))
  461.         return (0);
  462.  
  463.     fc14 = (*PTR2LONG(&moduleData[0]) == 0x34314346);
  464.  
  465.     /* setup pointers... */
  466.  
  467.     SEQpoint = (uint8_t *)(&moduleData[fc14 ? 180 : 100]);
  468.     PATpoint = (uint8_t *)(&moduleData[SWAP32(*PTR2LONG(&moduleData[8]))]);
  469.     FRQpoint = (uint8_t *)(&moduleData[SWAP32(*PTR2LONG(&moduleData[16]))]);
  470.     VOLpoint = (uint8_t *)(&moduleData[SWAP32(*PTR2LONG(&moduleData[24]))]);
  471.  
  472.     /* load samples */
  473.  
  474.     ptr8s_1 =  (int8_t *)(&moduleData[SWAP32(*PTR2LONG(&moduleData[32]))]);
  475.     ptr8u_2 = (uint8_t *)(&moduleData[40]);
  476.     for (i = 0; i < NUM_SAMPLES; ++i)
  477.     {
  478.         samples[i].data   = ptr8s_1;
  479.         samples[i].length = SWAP16(*PTR2WORD(ptr8u_2));                   ptr8u_2 += 2;
  480.         samples[i].repeat = &samples[i].data[SWAP16(*PTR2WORD(ptr8u_2))]; ptr8u_2 += 2;
  481.         samples[i].replen = SWAP16(*PTR2WORD(ptr8u_2));                   ptr8u_2 += 2;
  482.  
  483.         /* fix endless beep on non-looping samples (FC14 doesn't do this) */
  484.         if (samples[i].replen <= 1)
  485.         {
  486.             samples[i].replen = 1;
  487.             if (samples[i].length >= 1)
  488.             {
  489.                 if (*PTR2LONG(samples[i].data) != 0x504D5353) /* "SSMP" */
  490.                     *PTR2WORD(samples[i].data)  = 0;
  491.             }
  492.         }
  493.  
  494.         ptr8s_1 += ((samples[i].length * 2) + 2);
  495.     }
  496.  
  497.     /* load waveforms */
  498.  
  499.     if (fc14)
  500.     {
  501.         ptr8s_1 =  (int8_t *)(&moduleData[SWAP32(*PTR2LONG(&moduleData[36]))]);
  502.         ptr8u_2 = (uint8_t *)(&moduleData[100]);
  503.         for (i = 0; i < NUM_WAVEFORMS; ++i)
  504.         {
  505.             samples[NUM_SAMPLES + i].data   = ptr8s_1;
  506.             samples[NUM_SAMPLES + i].length = *ptr8u_2++;
  507.             samples[NUM_SAMPLES + i].repeat = &samples[NUM_SAMPLES + i].data[0];
  508.             samples[NUM_SAMPLES + i].replen = samples[NUM_SAMPLES + i].length;
  509.  
  510.             ptr8s_1 += (samples[NUM_SAMPLES + i].length * 2);
  511.         }
  512.     }
  513.     else
  514.     {
  515.         ptr8s_1 = (int8_t *)(waveformDatas);
  516.         for (i = 0; i < NUM_WAVEFORMS; ++i)
  517.         {
  518.             if (i < NUM_WAVEFORMS_SMOD)
  519.             {
  520.                 samples[NUM_SAMPLES + i].data   = ptr8s_1;
  521.                 samples[NUM_SAMPLES + i].length = waveformLengths[i];
  522.                 samples[NUM_SAMPLES + i].repeat = &samples[NUM_SAMPLES + i].data[0];
  523.                 samples[NUM_SAMPLES + i].replen = samples[NUM_SAMPLES + i].length;
  524.  
  525.                 ptr8s_1 += (samples[NUM_SAMPLES + i].length * 2);
  526.             }
  527.             else
  528.             {
  529.                 samples[NUM_SAMPLES + i].data   = NULL;
  530.                 samples[NUM_SAMPLES + i].length = 0;
  531.                 samples[NUM_SAMPLES + i].repeat = NULL;
  532.                 samples[NUM_SAMPLES + i].replen = 1;
  533.             }
  534.         }
  535.     }
  536.  
  537.     /* initialize channels */
  538.  
  539.     /* get number of sequences and make it a multiple of 13 (SEQ_SIZE) */
  540.     numSequences = (uint32_t)(SWAP32(*PTR2LONG(&moduleData[4])) / SEQ_SIZE) * SEQ_SIZE;
  541.  
  542.     memset(&Channel, 0, sizeof (Channel));
  543.     for (i = 0; i < 4; ++i)
  544.     {
  545.         Channel[i].voiceIndex      = (unsigned)(i);
  546.         Channel[i].loopStart       = NULL;
  547.         Channel[i].volTabPtr       = silentTable;
  548.         Channel[i].freqTabPtr      = silentTable;
  549.         Channel[i].volDelayCounter = 1;
  550.         Channel[i].volDelayLength  = 1;
  551.         Channel[i].pitchBendDelay  = 1;
  552.         Channel[i].seqPos          = SEQ_SIZE; /* yes */
  553.         Channel[i].seqStartPtr     = &SEQpoint[3 * i];
  554.         Channel[i].patPtr          = &PATpoint[Channel[i].seqStartPtr[0] * PAT_MAX_SIZE];
  555.         Channel[i].noteTranspose   = (signed)(Channel[i].seqStartPtr[1]);
  556.         Channel[i].soundTranspose  = (signed)(Channel[i].seqStartPtr[2]);
  557.     }
  558.  
  559.     repspd  = SEQpoint[12] ? SEQpoint[12] : 3;
  560.     respcnt = repspd;
  561.  
  562.     spdtemp  = 0;
  563.     spdtemp2 = 0;
  564.     initdone = 1;
  565.  
  566.     return (1);
  567. }
  568.  
  569. static void new_note(fcChannel_t *ch)
  570. {
  571.     uint8_t *tmpSeqPtr, *tmpPatPtr, note, info;
  572.  
  573.     tmpPatPtr = &ch->patPtr[ch->patPos]; /* temp pattern pointer */
  574.  
  575.     if ((fc14 && ((*tmpPatPtr & 0x7F) == PAT_END_MARKER)) || (ch->patPos == PAT_MAX_SIZE))
  576.     {
  577.         ch->patPos = 0;
  578.         if (ch->seqPos >= numSequences)
  579.             ch->seqPos = 0;
  580.  
  581.         tmpSeqPtr = &ch->seqStartPtr[ch->seqPos];
  582.         ch->patPtr = &PATpoint[tmpSeqPtr[0] * PAT_MAX_SIZE];
  583.         ch->noteTranspose = (signed)(tmpSeqPtr[1]);
  584.         ch->soundTranspose = (signed)(tmpSeqPtr[2]);
  585.  
  586.         if (++spdtemp == 4)
  587.         {
  588.             /* we've read all channels now, let's increase the pos used for RS */
  589.  
  590.             spdtemp = 0;
  591.             if (++spdtemp2 == (numSequences / SEQ_SIZE)) /* numSequences is a multiple of SEQ_SIZE */
  592.                 spdtemp2 = 0; /* wrap sequence position */
  593.         }
  594.  
  595.         /* read current RS (replay speed. only update if non-zero) */
  596.         if (SEQpoint[(spdtemp2 * 13) + 12] != 0)
  597.         {
  598.             repspd  = SEQpoint[(spdtemp2 * 13) + 12];
  599.             respcnt = repspd;
  600.         }
  601.  
  602.         ch->seqPos += SEQ_SIZE;
  603.         tmpPatPtr = ch->patPtr; /* set new temp pattern pointer */
  604.     }
  605.  
  606.     note = tmpPatPtr[0];
  607.     info = tmpPatPtr[1];
  608.  
  609.     if (note == 0)
  610.     {
  611.         info &= 0xC0;
  612.         if (info != 0)
  613.         {
  614.             ch->portaParam = 0;
  615.             if (info & (1 << 7))
  616.                 ch->portaParam = tmpPatPtr[3];
  617.         }
  618.     }
  619.     else
  620.     {
  621.         ch->portaValue = 0;
  622.         ch->portaParam = 0;
  623.         if (info & (1 << 7))
  624.             ch->portaParam = tmpPatPtr[3];
  625.     }
  626.  
  627.     note &= 0x7F;
  628.     if (note != 0)
  629.     {
  630.         ptr8u_1 = &VOLpoint[(((tmpPatPtr[1] & 0x3F) + ch->soundTranspose) & 0x3F) * VOL_TAB_SIZE];
  631.  
  632.         ch->note            = note;
  633.         ch->volDelayLength  = ptr8u_1[0];
  634.         ch->volDelayCounter = ch->volDelayLength;
  635.         ch->freqTabPtr      = &FRQpoint[(ptr8u_1[1] & 0x3F) * FREQ_TAB_SIZE];
  636.         ch->freqTabPos      = 0;
  637.         ch->freqSusCounter  = 0;
  638.         ch->vibratoSpeed    = ptr8u_1[2];
  639.         ch->vibratoDepth    = ptr8u_1[3];
  640.         ch->vibratoDelay    = ptr8u_1[4];
  641.         ch->vibratoCounter  = ch->vibratoDepth;
  642.         ch->vibratoUp       = 1; /* default initial state on new note */
  643.         ch->volTabPtr       = &ptr8u_1[5];
  644.         ch->volTabPos       = 0;
  645.         ch->volSusCounter   = 0;
  646.  
  647.         PaulaTurnOffDMA(ch->voiceIndex); /* yes, this is important */
  648.     }
  649.  
  650.     ch->patPos += 2;
  651. }
  652.  
  653. static void doFreqModulation(fcChannel_t *ch)
  654. {
  655.     uint8_t doTranspose, *tabPtr, *tmpPtr;
  656.     soundInfo_t sample;
  657.  
  658. testsustain:
  659.     if (ch->freqSusCounter > 0)
  660.     {
  661.         ch->freqSusCounter--;
  662.     }
  663.     else
  664.     {
  665.         tabPtr = &ch->freqTabPtr[ch->freqTabPos];
  666.  
  667. testeffects:
  668.         if (tabPtr[0] != 0xE1)
  669.         {
  670.             doTranspose = 1;
  671.  
  672.             if (tabPtr[0] == 0xE0) /* freq pos jump */
  673.             {
  674.                 ch->freqTabPos = tabPtr[1] & 0x3F;
  675.                 tabPtr = &ch->freqTabPtr[ch->freqTabPos];
  676.             }
  677.  
  678.             if (tabPtr[0] == 0xE2) /* set waveform */
  679.             {
  680.                 if (tabPtr[1] < (NUM_SAMPLES + NUM_WAVEFORMS))
  681.                 {
  682.                     sample = samples[tabPtr[1]];
  683.  
  684.                     ch->loopStart  = sample.repeat;
  685.                     ch->loopLength = sample.replen;
  686.  
  687.                     PaulaSetData(ch->voiceIndex, sample.data);
  688.                     PaulaSetLength(ch->voiceIndex, sample.length);
  689.                     PaulaRestartDMA(ch->voiceIndex);
  690.  
  691.                     ch->DMAWaitFrames = 3;
  692.                     ch->volTabPos = 0;
  693.                     ch->volDelayCounter = 1;
  694.                 }
  695.  
  696.                 ch->freqTabPos += 2;
  697.             }
  698.             else if (tabPtr[0] == 0xE4) /* update waveform */
  699.             {
  700.                 if (tabPtr[1] < (NUM_SAMPLES + NUM_WAVEFORMS))
  701.                 {
  702.                     sample = samples[tabPtr[1]];
  703.  
  704.                     ch->loopStart  = sample.repeat;
  705.                     ch->loopLength = sample.replen;
  706.  
  707.                     PaulaSetData(ch->voiceIndex, sample.data);
  708.                     PaulaSetLength(ch->voiceIndex, sample.length);
  709.  
  710.                     ch->DMAWaitFrames = 3;
  711.                 }
  712.  
  713.                 ch->freqTabPos += 2;
  714.             }
  715.             else if (tabPtr[0] == 0xE9) /* set packed waveform */
  716.             {
  717.                 if (tabPtr[1] < (NUM_SAMPLES + NUM_WAVEFORMS))
  718.                 {
  719.                     sample = samples[tabPtr[1]];
  720.                     if (*PTR2LONG(sample.data) == 0x504D5353) /* "SSMP" */
  721.                     {
  722.                         tmpPtr = (uint8_t *)(&sample.data[4 + (tabPtr[2] * 16)]);
  723.  
  724.                         ch->loopStart  = &sample.data[(4 + 320 + *PTR2LONG(&tmpPtr[0])) + *PTR2WORD(&tmpPtr[6])];
  725.                         ch->loopLength = *PTR2WORD(&tmpPtr[8]);
  726.  
  727.                         /* fix endless beep on non-looping samples (FC14 doesn't do this) */
  728.                         if (ch->loopLength <= 1)
  729.                         {
  730.                             ch->loopLength = 1;
  731.                             if (*PTR2WORD(&tmpPtr[4]) >= 1) /* sample length */
  732.                                 *PTR2WORD(&sample.data[4 + 320 + *PTR2LONG(&tmpPtr[0])]) = 0;
  733.                         }
  734.  
  735.                         PaulaSetData(ch->voiceIndex,  &sample.data[4 + 320 + *PTR2LONG(&tmpPtr[0])]);
  736.                         PaulaSetLength(ch->voiceIndex, *PTR2WORD(&tmpPtr[4]));
  737.                         PaulaRestartDMA(ch->voiceIndex);
  738.  
  739.                         ch->DMAWaitFrames = 3;
  740.                         ch->volTabPos = 0;
  741.                         ch->volDelayCounter = 1;
  742.                     }
  743.                 }
  744.  
  745.                 ch->freqTabPos += 3;
  746.             }
  747.             else if (tabPtr[0] == 0xE7) /* new freq pos */
  748.             {
  749.                 tabPtr = &FRQpoint[(tabPtr[1] & 0x3F) * FREQ_TAB_SIZE];
  750.                 ch->freqTabPtr = tabPtr;
  751.                 ch->freqTabPos = 0;
  752.  
  753.                 goto testeffects;
  754.             }
  755.             else if (tabPtr[0] == 0xE8) /* set freq sustain */
  756.             {
  757.                 ch->freqSusCounter = tabPtr[1];
  758.  
  759.                 ch->freqTabPos += 2;
  760.                 goto testsustain;
  761.             }
  762.             else if (tabPtr[0] == 0xE3) /* set vibrato */
  763.             {
  764.                 ch->freqTabPos += 3;
  765.  
  766.                 ch->vibratoSpeed = tabPtr[1];
  767.                 ch->vibratoDepth = tabPtr[2];
  768.  
  769.                 doTranspose = 0; /* don't do period transpose here */
  770.             }
  771.             else if (tabPtr[0] == 0xEA) /* set pitch bend */
  772.             {
  773.                 ch->pitchBendValue   = (signed)(tabPtr[1]);
  774.                 ch->pitchBendCounter = (signed)(tabPtr[2]);
  775.  
  776.                 ch->freqTabPos += 3;
  777.             }
  778.  
  779.             if (doTranspose)
  780.                 ch->periodTranspose = (signed)(ch->freqTabPtr[ch->freqTabPos++]);
  781.         }
  782.     }
  783. }
  784.  
  785. static void do_VOLbend(fcChannel_t *ch)
  786. {
  787.     ch->volSlideDelay = !ch->volSlideDelay;
  788.     if (ch->volSlideDelay)
  789.     {
  790.         ch->volSlideCounter--;
  791.  
  792.         ch->volume += ch->volSlideSpeed;
  793.         if (ch->volume < 0)
  794.         {
  795.             ch->volSlideCounter = 0;
  796.             ch->volume = 0;
  797.         }
  798.     }
  799. }
  800.  
  801. static void doVolModulation(fcChannel_t *ch)
  802. {
  803.     uint8_t *tabPtr;
  804.  
  805. VOLUfx:
  806.     if (ch->volSusCounter > 0)
  807.     {
  808.         ch->volSusCounter--;
  809.     }
  810.     else
  811.     {
  812.         if (ch->volSlideCounter > 0)
  813.         {
  814.             do_VOLbend(ch);
  815.         }
  816.         else
  817.         {
  818.             /* fun potential bug: ch->volDelayCounter==0 = mega delay... */
  819.             if (--ch->volDelayCounter == 0)
  820.             {
  821.                 ch->volDelayCounter = ch->volDelayLength;
  822. volu_cmd:
  823.                 tabPtr = &ch->volTabPtr[ch->volTabPos];
  824.  
  825.                 if (tabPtr[0] != 0xE1)
  826.                 {
  827.                     if (tabPtr[0] == 0xE8) /* set vol sustain */
  828.                     {
  829.                         ch->volSusCounter = tabPtr[1];
  830.                         ch->volTabPos += 2;
  831.  
  832.                         goto VOLUfx;
  833.                     }
  834.                     else if (tabPtr[0] == 0xEA) /* set vol slide */
  835.                     {
  836.                         ch->volSlideSpeed   = tabPtr[1];
  837.                         ch->volSlideCounter = tabPtr[2];
  838.  
  839.                         ch->volTabPos += 3;
  840.                         do_VOLbend(ch);
  841.                     }
  842.                     else if (tabPtr[0] == 0xE0) /* set vol pos */
  843.                     {
  844.                         if (((tabPtr[1] & 0x3F) - 5) < 0)
  845.                             ch->volTabPos = 0;
  846.                         else
  847.                             ch->volTabPos = (tabPtr[1] & 0x3F) - 5;
  848.  
  849.                         goto volu_cmd;
  850.                     }
  851.                     else
  852.                     {
  853.                         ch->volume = (signed)(ch->volTabPtr[ch->volTabPos++]);
  854.                     }
  855.                 }
  856.             }
  857.         }
  858.     }
  859. }
  860.  
  861. static void effects(fcChannel_t *ch)
  862. {
  863.     int8_t tmpNote;
  864.     int16_t tmpVibPeriod, tmpPeriod;
  865.     uint16_t tmpVibNote;
  866.  
  867.     doFreqModulation(ch);
  868.     doVolModulation(ch);
  869.  
  870.     /* get period from note and transposes... */
  871.     tmpNote = ch->periodTranspose;
  872.     if (tmpNote >= 0)
  873.     {
  874.         tmpNote += ch->note;
  875.         tmpNote += ch->noteTranspose;
  876.     }
  877.     tmpNote &= 0x7F;
  878.  
  879.     tmpPeriod = periods[tmpNote];
  880.  
  881.     /* apply vibrato to period */
  882.     if (ch->vibratoDelay > 0)
  883.     {
  884.         ch->vibratoDelay--;
  885.     }
  886.     else
  887.     {
  888.         tmpVibPeriod = ch->vibratoCounter;
  889.         if (!ch->vibratoUp)
  890.         {
  891.             tmpVibPeriod -= ch->vibratoSpeed;
  892.             if (tmpVibPeriod < 0)
  893.             {
  894.                 tmpVibPeriod  = 0;
  895.                 ch->vibratoUp = 1;
  896.             }
  897.         }
  898.         else
  899.         {
  900.             tmpVibPeriod += ch->vibratoSpeed;
  901.             if (tmpVibPeriod > (ch->vibratoDepth * 2))
  902.             {
  903.                 tmpVibPeriod  = ch->vibratoDepth * 2;
  904.                 ch->vibratoUp = 0;
  905.             }
  906.         }
  907.         ch->vibratoCounter = tmpVibPeriod & 0x00FF;
  908.  
  909.         tmpVibPeriod -= ch->vibratoDepth;
  910.  
  911.         tmpVibNote = tmpNote * 2;
  912.         while (tmpVibNote < (12 * 8))
  913.         {
  914.             tmpVibPeriod *= 2;
  915.             tmpVibNote   += (12 * 2);
  916.         }
  917.  
  918.         tmpPeriod += tmpVibPeriod;
  919.     }
  920.  
  921.     /* update portamento value (twice as slow on FC1.4) */
  922.     ch->portaDelay = !ch->portaDelay;
  923.     if (!fc14 || ch->portaDelay)
  924.     {
  925.         if (ch->portaParam > 0)
  926.         {
  927.             if (ch->portaParam > 0x1F)
  928.                 ch->portaValue += (ch->portaParam & 0x1F);
  929.             else
  930.                 ch->portaValue -= ch->portaParam;
  931.         }
  932.     }
  933.  
  934.     /* apply pitch bend to portamento value  */
  935.     ch->pitchBendDelay = !ch->pitchBendDelay;
  936.     if (ch->pitchBendDelay)
  937.     {
  938.         if (ch->pitchBendCounter > 0)
  939.         {
  940.             ch->pitchBendCounter--;
  941.             ch->portaValue -= ch->pitchBendValue;
  942.         }
  943.     }
  944.  
  945.     tmpPeriod += ch->portaValue;
  946.  
  947.     PaulaSetPeriod(ch->voiceIndex, CLAMP(tmpPeriod, 0x0071, fc14 ? 0x0D60 : 0x06B0));
  948.     PaulaSetVolume(ch->voiceIndex, ch->volume);
  949. }
  950.  
  951. static void play_music(void)
  952. {
  953.     uint8_t i;
  954.  
  955.     if (--respcnt == 0)
  956.     {
  957.         respcnt = repspd;
  958.  
  959.         new_note(&Channel[0]);
  960.         new_note(&Channel[1]);
  961.         new_note(&Channel[2]);
  962.         new_note(&Channel[3]);
  963.     }
  964.  
  965.     for (i = 0; i < 4; ++i)
  966.     {
  967.         effects(&Channel[i]);
  968.  
  969.         if (Channel[i].DMAWaitFrames > 0)
  970.         {
  971.             if (--Channel[i].DMAWaitFrames == 0)
  972.             {
  973.                 /* these take effect when the current DMA cycle is done */
  974.                 PaulaSetData(i, Channel[i].loopStart);
  975.                 PaulaSetLength(i, Channel[i].loopLength);
  976.             }
  977.         }
  978.     }
  979. }
  980.  
  981. static void mixSampleBlock(int16_t *streamOut, uint32_t numSamples)
  982. {
  983.     uint8_t i;
  984.     int16_t *sndOut;
  985.     uint16_t j;
  986.     int32_t smpL, smpR;
  987.     float tempSample, tempVolume, out_f[2];
  988.     paulaVoice_t *v;
  989.  
  990. #ifdef USE_BLEP
  991.     blep_t *bSmp, *bVol;
  992. #endif
  993.  
  994.     memset(masterBufferL, 0, sizeof (float) * numSamples);
  995.     memset(masterBufferR, 0, sizeof (float) * numSamples);
  996.  
  997.     for (i = 0; i < 4; ++i)
  998.     {
  999.         v = &AUD[i];
  1000.  
  1001. #ifdef USE_BLEP
  1002.         bSmp = &blep[i];
  1003.         bVol = &blepVol[i];
  1004. #endif
  1005.         if (v->DMA_ON && (v->DMA_LEN > 0) && (v->DELTA > 0.0f))
  1006.         {
  1007.             for (j = 0; j < numSamples; ++j)
  1008.             {
  1009.                 tempSample = (v->DMA_DAT == NULL) ? 0.0f : (v->DMA_DAT[v->DMA_POS] * (1.0f / 128.0f));
  1010.                 tempVolume = (v->DMA_DAT == NULL) ? 0.0f : v->SRC_VOL;
  1011.  
  1012. #ifdef USE_BLEP
  1013.                 if (tempSample != bSmp->lastValue)
  1014.                 {
  1015.                     if ((v->LASTDELTA > 0.0f) && (v->LASTDELTA > v->LASTFRAC))
  1016.                         blepAdd(bSmp, v->LASTFRAC / v->LASTDELTA, bSmp->lastValue - tempSample);
  1017.  
  1018.                     bSmp->lastValue = tempSample;
  1019.                 }
  1020.  
  1021.                 if (tempVolume != bVol->lastValue)
  1022.                 {
  1023.                     blepAdd(bVol, 0.0f, bVol->lastValue - tempVolume);
  1024.                     bVol->lastValue = tempVolume;
  1025.                 }
  1026.  
  1027.                 if (bSmp->samplesLeft) tempSample += blepRun(bSmp);
  1028.                 if (bVol->samplesLeft) tempVolume += blepRun(bVol);
  1029. #endif
  1030.                 tempSample *= tempVolume;
  1031.                 masterBufferL[j] += (tempSample * v->PANL);
  1032.                 masterBufferR[j] += (tempSample * v->PANR);
  1033.  
  1034.                 v->FRAC += v->DELTA;
  1035.                 if (v->FRAC >= 1.0f)
  1036.                 {
  1037.                     v->FRAC -= 1.0f;
  1038.  
  1039.                     v->LASTFRAC  = v->FRAC;
  1040.                     v->LASTDELTA = v->DELTA;
  1041.  
  1042.                     if (++v->DMA_POS >= v->DMA_LEN)
  1043.                     {
  1044.                         v->DMA_POS = 0;
  1045.  
  1046.                         /* re-fetch Paula register values now */
  1047.                         v->DMA_LEN = v->SRC_LEN;
  1048.                         v->DMA_DAT = v->SRC_DAT;
  1049.                     }
  1050.                 }
  1051.             }
  1052.         }
  1053.     }
  1054.  
  1055.     sndOut = streamOut;
  1056.     for (j = 0; j < numSamples; ++j)
  1057.     {
  1058.         if (onoff)
  1059.         {
  1060.             out_f[0] = masterBufferL[j];
  1061.             out_f[1] = masterBufferR[j];
  1062.  
  1063. #ifdef USE_LOWPASS
  1064.             lossyIntegrator(&filterLo, out_f, out_f);
  1065. #endif
  1066.  
  1067. #ifdef USE_HIGHPASS
  1068.             lossyIntegratorHighPass(&filterHi, out_f, out_f);
  1069. #endif
  1070.             /* normalize amplitude (also invert waveform, like on a real Amiga) */
  1071.             out_f[0] *= (-32767.0f / NORM_FACTOR);
  1072.             out_f[1] *= (-32767.0f / NORM_FACTOR);
  1073.  
  1074.             /* round float sample */
  1075. #ifdef ROUND_SAMPLES
  1076.             out_f[0] = ROUND_SMP_F(out_f[0]);
  1077.             out_f[1] = ROUND_SMP_F(out_f[1]);
  1078. #endif
  1079.             /* truncate to signed 32-bit integer */
  1080.             smpL = (int32_t)(out_f[0]);
  1081.             smpR = (int32_t)(out_f[1]);
  1082.  
  1083.             /* clamp to 16-bit signed range */
  1084.             CLAMP16(smpL);
  1085.             CLAMP16(smpR);
  1086.  
  1087.             /* truncate to signed 16-bit integer and store in output buffer */
  1088.             *sndOut++ = (int16_t)(smpL);
  1089.             *sndOut++ = (int16_t)(smpR);
  1090.         }
  1091.         else
  1092.         {
  1093.             *sndOut++ = 0;
  1094.             *sndOut++ = 0;
  1095.         }
  1096.     }
  1097. }
  1098.  
  1099. static void CALLBACK waveOutProc(HWAVEOUT _hWaveOut, UINT uMsg,
  1100.     DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
  1101. {
  1102.     int16_t *outputStream;
  1103.     int32_t  sampleBlock, samplesTodo;
  1104.     WAVEHDR *waveBlockHeader;
  1105.  
  1106.     /* make compiler happy! (warning C4100) */
  1107.     (void)(dwParam2);
  1108.     (void)(dwInstance);
  1109.  
  1110.     if (uMsg == MM_WOM_DONE)
  1111.     {
  1112.         mixingMutex = 1;
  1113.  
  1114.         waveBlockHeader = (WAVEHDR *)(dwParam1);
  1115.         waveOutUnprepareHeader(_hWaveOut, waveBlockHeader, sizeof (WAVEHDR));
  1116.  
  1117.         if (isMixing)
  1118.         {
  1119.             memcpy(waveBlockHeader->lpData, mixerBuffer, soundBufferSize);
  1120.  
  1121.             waveOutPrepareHeader(_hWaveOut, waveBlockHeader, sizeof (WAVEHDR));
  1122.             waveOutWrite(_hWaveOut, waveBlockHeader, sizeof (WAVEHDR));
  1123.  
  1124.             outputStream = (int16_t *)(mixerBuffer);
  1125.             sampleBlock  = soundBufferSize / 4;
  1126.  
  1127.             while (sampleBlock)
  1128.             {
  1129.                 samplesTodo = (sampleBlock < samplesLeft) ? sampleBlock : samplesLeft;
  1130.                 if (samplesTodo > soundBufferSize)
  1131.                     samplesTodo = soundBufferSize;
  1132.  
  1133.                 if (samplesTodo > 0)
  1134.                 {
  1135.                     mixSampleBlock(outputStream, samplesTodo);
  1136.                     outputStream += (samplesTodo * 2);
  1137.  
  1138.                     sampleBlock -= samplesTodo;
  1139.                     samplesLeft -= samplesTodo;
  1140.                 }
  1141.                 else
  1142.                 {
  1143.                     if (onoff)
  1144.                         play_music();
  1145.  
  1146.                     samplesLeft = samplesPerFrame;
  1147.                 }
  1148.             }
  1149.         }
  1150.  
  1151.         mixingMutex = 0;
  1152.     }
  1153. }
  1154.  
  1155. void fc14play_PauseSong(int8_t pause)
  1156. {
  1157.     onoff = pause ? 0 : 1;
  1158. }
  1159.  
  1160. /* these are used to create an equal powered panning */
  1161. static float sinApx(float x)
  1162. {
  1163.     x = x * (2.0f - x);
  1164.     return (x * 1.09742972f + x * x * 0.31678383f);
  1165. }
  1166.  
  1167. static float cosApx(float x)
  1168. {
  1169.     x = (1.0f - x) * (1.0f + x);
  1170.     return (x * 1.09742972f + x * x * 0.31678383f);
  1171. }
  1172. /* ------------------------------------------------- */
  1173.  
  1174. static void init_pans(uint8_t stereoSeparation)
  1175. {
  1176.     uint8_t scaledPanPos;
  1177.     float p;
  1178.  
  1179.     if (stereoSeparation > 100)
  1180.         stereoSeparation = 100;
  1181.  
  1182.     scaledPanPos = (stereoSeparation * 128) / 100;
  1183.  
  1184.     p = (128 - scaledPanPos) * (1.0f / 256.0f);
  1185.     AUD[0].PANL = cosApx(p);
  1186.     AUD[0].PANR = sinApx(p);
  1187.     AUD[3].PANL = cosApx(p);
  1188.     AUD[3].PANR = sinApx(p);
  1189.  
  1190.     p = (128 + scaledPanPos) * (1.0f / 256.0f);
  1191.     AUD[1].PANL = cosApx(p);
  1192.     AUD[1].PANR = sinApx(p);
  1193.     AUD[2].PANL = cosApx(p);
  1194.     AUD[2].PANR = sinApx(p);
  1195. }
  1196.  
  1197. void fc14play_PlaySong(void)
  1198. {
  1199.     uint8_t i;
  1200.  
  1201.     if (initdone)
  1202.     {
  1203.         onoff = 0;
  1204.  
  1205. #ifdef USE_BLEP
  1206.         memset(&blep,    0, sizeof (blep));
  1207.         memset(&blepVol, 0, sizeof (blepVol));
  1208. #endif
  1209.  
  1210. #ifdef USE_LOWPASS
  1211.         clearLossyIntegrator(&filterLo);
  1212. #endif
  1213.  
  1214. #ifdef USE_HIGHPASS
  1215.         clearLossyIntegrator(&filterHi);
  1216. #endif
  1217.  
  1218.         memset(AUD, 0, sizeof (AUD));
  1219.         for (i = 0; i < 4; ++i)
  1220.         {
  1221.             AUD[i].DMA_DAT = NULL;
  1222.             AUD[i].SRC_DAT = NULL;
  1223.         }
  1224.  
  1225.         init_pans(STEREO_SEP);
  1226.  
  1227.         onoff = 1;
  1228.     }
  1229. }
  1230.  
  1231. static int8_t openMixer(uint32_t _samplingFrequency, uint32_t _soundBufferSize)
  1232. {
  1233.     uint8_t i;
  1234.     MMRESULT r;
  1235.  
  1236.     if (!hWaveOut)
  1237.     {
  1238.         f_outputFreq        = (float)(_samplingFrequency);
  1239.         soundBufferSize     = _soundBufferSize;
  1240.         masterBufferL       = (float *)(malloc(soundBufferSize * sizeof (float)));
  1241.         masterBufferR       = (float *)(malloc(soundBufferSize * sizeof (float)));
  1242.         wfx.nSamplesPerSec  = _samplingFrequency;
  1243.         wfx.wBitsPerSample  = 16;
  1244.         wfx.nChannels       = 2;
  1245.         wfx.cbSize          = 0;
  1246.         wfx.wFormatTag      = WAVE_FORMAT_PCM;
  1247.         wfx.nBlockAlign     = (wfx.wBitsPerSample * wfx.nChannels) / 8;
  1248.         wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
  1249.  
  1250.         if ((masterBufferL == NULL) || (masterBufferR == NULL))
  1251.             return (0); /* gets free'd later */
  1252.  
  1253.         r = waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, (DWORD_PTR)(waveOutProc), 0L, CALLBACK_FUNCTION);
  1254.         if (r != MMSYSERR_NOERROR) return (0);
  1255.  
  1256.         for (i = 0; i < MIX_BUF_NUM; ++i)
  1257.         {
  1258.             waveBlocks[i].dwBufferLength = soundBufferSize;
  1259.             waveBlocks[i].lpData = (LPSTR)(calloc(soundBufferSize, 1));
  1260.             if (waveBlocks[i].lpData == NULL)
  1261.                 return (0); /* gets free'd later */
  1262.  
  1263.             waveOutPrepareHeader(hWaveOut, &waveBlocks[i], sizeof (WAVEHDR));
  1264.             waveOutWrite(hWaveOut, &waveBlocks[i], sizeof (WAVEHDR));
  1265.         }
  1266.  
  1267.         mixerBuffer = (int8_t *)(calloc(soundBufferSize, 1));
  1268.         if (mixerBuffer == NULL)
  1269.             return (0); /* gets free'd later */
  1270.  
  1271.         samplesPerFrame = (uint32_t)((f_outputFreq / AMIGA_VBLANK_RATE) + 0.5f);
  1272.  
  1273. #ifdef USE_LOWPASS
  1274.         // Amiga 500 RC low-pass filter (R = 360 ohm, C = 0.1uF)
  1275.         // hz = 1 / (2pi * R * C)    = ~4421.0Hz
  1276.         calcCoeffLossyIntegrator(f_outputFreq, 4421.0f, &filterLo);
  1277. #endif
  1278.  
  1279. #ifdef USE_HIGHPASS
  1280.         // Amiga 500 RC high-pass filter (R = 1390 ohm, C = 22uF)
  1281.         // hz = 1 / (2pi * R * C)    = ~5.2Hz
  1282.         calcCoeffLossyIntegrator(f_outputFreq, 5.2f, &filterHi);
  1283. #endif
  1284.  
  1285.         isMixing = 1;
  1286.         return (1);
  1287.     }
  1288.  
  1289.     return (1);
  1290. }
  1291.  
  1292. void fc14play_Close(void)
  1293. {
  1294.     uint8_t i;
  1295.  
  1296.     onoff = 0;
  1297.  
  1298.     if (isMixing)
  1299.     {
  1300.         isMixing = 0;
  1301.         while (mixingMutex);
  1302.  
  1303.         if (hWaveOut)
  1304.         {
  1305.             for (i = 0; i < MIX_BUF_NUM; ++i)
  1306.                 waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof (WAVEHDR));
  1307.  
  1308.             for (i = 0; i < MIX_BUF_NUM; ++i)
  1309.             {
  1310.                 while (waveBlocks[i].dwFlags & WHDR_PREPARED);
  1311.                 if (waveBlocks[i].lpData != NULL)
  1312.                 {
  1313.                     free(waveBlocks[i].lpData);
  1314.                     waveBlocks[i].lpData = NULL;
  1315.                 }
  1316.             }
  1317.  
  1318.             waveOutReset(hWaveOut);
  1319.             waveOutClose(hWaveOut);
  1320.  
  1321.             hWaveOut = 0;
  1322.  
  1323.             if (mixerBuffer != NULL)
  1324.             {
  1325.                 free(mixerBuffer);
  1326.                 mixerBuffer = NULL;
  1327.             }
  1328.  
  1329.             if (masterBufferL != NULL)
  1330.             {
  1331.                 free(masterBufferL);
  1332.                 masterBufferL = NULL;
  1333.             }
  1334.  
  1335.             if (masterBufferR != NULL)
  1336.             {
  1337.                 free(masterBufferR);
  1338.                 masterBufferR = NULL;
  1339.             }
  1340.         }
  1341.     }
  1342. }
  1343.  
  1344. void fc14play_SetStereoSep(uint8_t percentage)
  1345. {
  1346.     init_pans(percentage);
  1347. }
  1348.  
  1349. int8_t fc14play_Init(uint32_t outputFreq, const uint8_t *moduleData)
  1350. {
  1351.     if (!init_music(moduleData))
  1352.         return (0);
  1353.  
  1354.     if (!openMixer(outputFreq, MIX_BUF_LEN))
  1355.     {
  1356.         fc14play_Close();
  1357.         return (0);
  1358.     }
  1359.  
  1360.     return (1);
  1361. }
  1362.  
  1363. /* END OF FILE */
RAW Paste Data
Want to get better at C?
Learn to code C in 2017
Pastebin PRO Summer Special!
Get 40% OFF on Pastebin PRO accounts!
Top