gosu 0.15.2 → 1.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (234) hide show
  1. checksums.yaml +4 -4
  2. data/dependencies/SDL/include/SDL.h +138 -0
  3. data/dependencies/SDL/include/SDL_assert.h +293 -0
  4. data/dependencies/SDL/include/SDL_atomic.h +295 -0
  5. data/dependencies/SDL/include/SDL_audio.h +859 -0
  6. data/dependencies/SDL/include/SDL_bits.h +121 -0
  7. data/dependencies/SDL/include/SDL_blendmode.h +123 -0
  8. data/dependencies/SDL/include/SDL_clipboard.h +71 -0
  9. data/dependencies/SDL/include/SDL_config.h +55 -0
  10. data/dependencies/SDL/include/SDL_config_android.h +182 -0
  11. data/dependencies/SDL/include/SDL_config_iphoneos.h +207 -0
  12. data/dependencies/SDL/include/SDL_config_macosx.h +266 -0
  13. data/dependencies/SDL/include/SDL_config_minimal.h +85 -0
  14. data/dependencies/SDL/include/SDL_config_os2.h +188 -0
  15. data/dependencies/SDL/include/SDL_config_pandora.h +135 -0
  16. data/dependencies/SDL/include/SDL_config_psp.h +165 -0
  17. data/dependencies/SDL/include/SDL_config_windows.h +288 -0
  18. data/dependencies/SDL/include/SDL_config_winrt.h +243 -0
  19. data/dependencies/SDL/include/SDL_config_wiz.h +149 -0
  20. data/dependencies/SDL/include/SDL_copying.h +20 -0
  21. data/dependencies/SDL/include/SDL_cpuinfo.h +299 -0
  22. data/dependencies/SDL/include/SDL_egl.h +1676 -0
  23. data/dependencies/SDL/include/SDL_endian.h +263 -0
  24. data/dependencies/SDL/include/SDL_error.h +112 -0
  25. data/dependencies/SDL/include/SDL_events.h +827 -0
  26. data/dependencies/SDL/include/SDL_filesystem.h +136 -0
  27. data/dependencies/SDL/include/SDL_gamecontroller.h +541 -0
  28. data/dependencies/SDL/include/SDL_gesture.h +87 -0
  29. data/dependencies/SDL/include/SDL_haptic.h +1247 -0
  30. data/dependencies/SDL/include/SDL_hints.h +1578 -0
  31. data/dependencies/SDL/include/SDL_joystick.h +499 -0
  32. data/dependencies/SDL/include/SDL_keyboard.h +217 -0
  33. data/dependencies/SDL/include/SDL_keycode.h +351 -0
  34. data/dependencies/SDL/include/SDL_loadso.h +81 -0
  35. data/dependencies/SDL/include/SDL_locale.h +101 -0
  36. data/dependencies/SDL/include/SDL_log.h +211 -0
  37. data/dependencies/SDL/include/SDL_main.h +180 -0
  38. data/dependencies/SDL/include/SDL_messagebox.h +146 -0
  39. data/dependencies/SDL/include/SDL_metal.h +117 -0
  40. data/dependencies/SDL/include/SDL_misc.h +75 -0
  41. data/dependencies/SDL/include/SDL_mouse.h +302 -0
  42. data/dependencies/SDL/include/SDL_mutex.h +251 -0
  43. data/dependencies/SDL/include/SDL_name.h +33 -0
  44. data/dependencies/SDL/include/SDL_opengl.h +2183 -0
  45. data/dependencies/SDL/include/SDL_opengl_glext.h +11180 -0
  46. data/dependencies/SDL/include/SDL_opengles.h +39 -0
  47. data/dependencies/SDL/include/SDL_opengles2.h +52 -0
  48. data/dependencies/SDL/include/SDL_opengles2_gl2.h +621 -0
  49. data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +2050 -0
  50. data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +30 -0
  51. data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +282 -0
  52. data/dependencies/SDL/include/SDL_pixels.h +479 -0
  53. data/dependencies/SDL/include/SDL_platform.h +198 -0
  54. data/dependencies/SDL/include/SDL_power.h +75 -0
  55. data/dependencies/SDL/include/SDL_quit.h +58 -0
  56. data/dependencies/SDL/include/SDL_rect.h +174 -0
  57. data/dependencies/SDL/include/SDL_render.h +1158 -0
  58. data/dependencies/SDL/include/SDL_revision.h +2 -0
  59. data/dependencies/SDL/include/SDL_rwops.h +283 -0
  60. data/dependencies/SDL/include/SDL_scancode.h +413 -0
  61. data/dependencies/SDL/include/SDL_sensor.h +267 -0
  62. data/dependencies/SDL/include/SDL_shape.h +144 -0
  63. data/dependencies/SDL/include/SDL_stdinc.h +647 -0
  64. data/dependencies/SDL/include/SDL_surface.h +563 -0
  65. data/dependencies/SDL/include/SDL_system.h +325 -0
  66. data/dependencies/SDL/include/SDL_syswm.h +354 -0
  67. data/dependencies/SDL/include/SDL_test.h +69 -0
  68. data/dependencies/SDL/include/SDL_test_assert.h +105 -0
  69. data/dependencies/SDL/include/SDL_test_common.h +218 -0
  70. data/dependencies/SDL/include/SDL_test_compare.h +69 -0
  71. data/dependencies/SDL/include/SDL_test_crc32.h +124 -0
  72. data/dependencies/SDL/include/SDL_test_font.h +81 -0
  73. data/dependencies/SDL/include/SDL_test_fuzzer.h +384 -0
  74. data/dependencies/SDL/include/SDL_test_harness.h +134 -0
  75. data/dependencies/SDL/include/SDL_test_images.h +78 -0
  76. data/dependencies/SDL/include/SDL_test_log.h +67 -0
  77. data/dependencies/SDL/include/SDL_test_md5.h +129 -0
  78. data/dependencies/SDL/include/SDL_test_memory.h +63 -0
  79. data/dependencies/SDL/include/SDL_test_random.h +115 -0
  80. data/dependencies/SDL/include/SDL_thread.h +366 -0
  81. data/dependencies/SDL/include/SDL_timer.h +115 -0
  82. data/dependencies/SDL/include/SDL_touch.h +102 -0
  83. data/dependencies/SDL/include/SDL_types.h +29 -0
  84. data/dependencies/SDL/include/SDL_version.h +162 -0
  85. data/dependencies/SDL/include/SDL_video.h +1282 -0
  86. data/dependencies/SDL/include/SDL_vulkan.h +276 -0
  87. data/dependencies/SDL/include/begin_code.h +166 -0
  88. data/dependencies/SDL/include/close_code.h +40 -0
  89. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  90. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  91. data/dependencies/SDL_sound/SDL_sound.c +795 -0
  92. data/dependencies/SDL_sound/SDL_sound.h +725 -0
  93. data/dependencies/SDL_sound/SDL_sound_aiff.c +537 -0
  94. data/dependencies/SDL_sound/SDL_sound_au.c +352 -0
  95. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +747 -0
  96. data/dependencies/SDL_sound/SDL_sound_flac.c +182 -0
  97. data/dependencies/SDL_sound/SDL_sound_internal.h +304 -0
  98. data/dependencies/SDL_sound/SDL_sound_modplug.c +228 -0
  99. data/dependencies/SDL_sound/SDL_sound_mp3.c +184 -0
  100. data/dependencies/SDL_sound/SDL_sound_raw.c +164 -0
  101. data/dependencies/SDL_sound/SDL_sound_shn.c +1309 -0
  102. data/dependencies/SDL_sound/SDL_sound_voc.c +550 -0
  103. data/dependencies/SDL_sound/SDL_sound_vorbis.c +223 -0
  104. data/dependencies/SDL_sound/SDL_sound_wav.c +783 -0
  105. data/dependencies/SDL_sound/dr_flac.h +5906 -0
  106. data/dependencies/SDL_sound/dr_mp3.h +2832 -0
  107. data/dependencies/SDL_sound/libmodplug/fastmix.c +1748 -0
  108. data/dependencies/SDL_sound/libmodplug/libmodplug.h +1001 -0
  109. data/dependencies/SDL_sound/libmodplug/load_669.c +188 -0
  110. data/dependencies/SDL_sound/libmodplug/load_abc.c +4725 -0
  111. data/dependencies/SDL_sound/libmodplug/load_amf.c +403 -0
  112. data/dependencies/SDL_sound/libmodplug/load_ams.c +587 -0
  113. data/dependencies/SDL_sound/libmodplug/load_dbm.c +357 -0
  114. data/dependencies/SDL_sound/libmodplug/load_dmf.c +531 -0
  115. data/dependencies/SDL_sound/libmodplug/load_dsm.c +232 -0
  116. data/dependencies/SDL_sound/libmodplug/load_far.c +253 -0
  117. data/dependencies/SDL_sound/libmodplug/load_it.c +796 -0
  118. data/dependencies/SDL_sound/libmodplug/load_mdl.c +488 -0
  119. data/dependencies/SDL_sound/libmodplug/load_med.c +757 -0
  120. data/dependencies/SDL_sound/libmodplug/load_mid.c +1405 -0
  121. data/dependencies/SDL_sound/libmodplug/load_mod.c +269 -0
  122. data/dependencies/SDL_sound/libmodplug/load_mt2.c +546 -0
  123. data/dependencies/SDL_sound/libmodplug/load_mtm.c +142 -0
  124. data/dependencies/SDL_sound/libmodplug/load_okt.c +192 -0
  125. data/dependencies/SDL_sound/libmodplug/load_pat.c +1143 -0
  126. data/dependencies/SDL_sound/libmodplug/load_pat.h +25 -0
  127. data/dependencies/SDL_sound/libmodplug/load_psm.c +350 -0
  128. data/dependencies/SDL_sound/libmodplug/load_ptm.c +204 -0
  129. data/dependencies/SDL_sound/libmodplug/load_s3m.c +325 -0
  130. data/dependencies/SDL_sound/libmodplug/load_stm.c +180 -0
  131. data/dependencies/SDL_sound/libmodplug/load_ult.c +206 -0
  132. data/dependencies/SDL_sound/libmodplug/load_umx.c +51 -0
  133. data/dependencies/SDL_sound/libmodplug/load_xm.c +554 -0
  134. data/dependencies/SDL_sound/libmodplug/mmcmp.c +382 -0
  135. data/dependencies/SDL_sound/libmodplug/modplug.c +170 -0
  136. data/dependencies/SDL_sound/libmodplug/modplug.h +90 -0
  137. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +301 -0
  138. data/dependencies/SDL_sound/libmodplug/snd_flt.c +63 -0
  139. data/dependencies/SDL_sound/libmodplug/snd_fx.c +2350 -0
  140. data/dependencies/SDL_sound/libmodplug/sndfile.c +1169 -0
  141. data/dependencies/SDL_sound/libmodplug/sndmix.c +1034 -0
  142. data/dependencies/SDL_sound/libmodplug/tables.h +371 -0
  143. data/{src/stb_vorbis.c → dependencies/SDL_sound/stb_vorbis.h} +143 -78
  144. data/dependencies/al_soft/AL/al.h +655 -0
  145. data/dependencies/al_soft/AL/alc.h +270 -0
  146. data/dependencies/al_soft/AL/alext.h +585 -0
  147. data/dependencies/al_soft/AL/efx-creative.h +3 -0
  148. data/dependencies/al_soft/AL/efx-presets.h +402 -0
  149. data/dependencies/al_soft/AL/efx.h +762 -0
  150. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  151. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  152. data/{src → dependencies/stb}/stb_image.h +330 -127
  153. data/{src → dependencies/stb}/stb_image_write.h +156 -85
  154. data/{src → dependencies/stb}/stb_truetype.h +192 -69
  155. data/{src → dependencies/utf8proc}/utf8proc.c +0 -0
  156. data/{src → dependencies/utf8proc}/utf8proc.h +0 -0
  157. data/{src → dependencies/utf8proc}/utf8proc_data.h +0 -0
  158. data/ext/gosu/extconf.rb +56 -22
  159. data/{Gosu → include/Gosu}/Audio.hpp +6 -8
  160. data/{Gosu → include/Gosu}/AutoLink.hpp +0 -0
  161. data/include/Gosu/Bitmap.hpp +100 -0
  162. data/{Gosu → include/Gosu}/Buttons.hpp +94 -35
  163. data/{Gosu → include/Gosu}/Channel.h +0 -0
  164. data/{Gosu → include/Gosu}/Color.h +0 -0
  165. data/{Gosu → include/Gosu}/Color.hpp +0 -0
  166. data/{Gosu → include/Gosu}/Directories.hpp +0 -0
  167. data/{Gosu → include/Gosu}/Font.h +0 -0
  168. data/{Gosu → include/Gosu}/Font.hpp +0 -0
  169. data/{Gosu → include/Gosu}/Fwd.hpp +0 -0
  170. data/{Gosu → include/Gosu}/Gosu.h +3 -0
  171. data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
  172. data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
  173. data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
  174. data/{Gosu → include/Gosu}/IO.hpp +0 -0
  175. data/{Gosu → include/Gosu}/Image.h +0 -0
  176. data/{Gosu → include/Gosu}/Image.hpp +7 -6
  177. data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
  178. data/{Gosu → include/Gosu}/Input.hpp +30 -15
  179. data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
  180. data/{Gosu → include/Gosu}/Math.hpp +0 -0
  181. data/{Gosu → include/Gosu}/Platform.hpp +0 -0
  182. data/{Gosu → include/Gosu}/Sample.h +0 -0
  183. data/{Gosu → include/Gosu}/Song.h +0 -0
  184. data/{Gosu → include/Gosu}/Text.hpp +0 -0
  185. data/{Gosu → include/Gosu}/TextInput.h +0 -0
  186. data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
  187. data/{Gosu → include/Gosu}/Timing.hpp +0 -0
  188. data/{Gosu → include/Gosu}/Utility.hpp +1 -1
  189. data/{Gosu → include/Gosu}/Version.hpp +0 -0
  190. data/{Gosu → include/Gosu}/Window.h +2 -0
  191. data/{Gosu → include/Gosu}/Window.hpp +21 -13
  192. data/lib/OpenAL32.dll +0 -0
  193. data/lib/SDL2.dll +0 -0
  194. data/lib/gosu.rb +0 -3
  195. data/lib/gosu/patches.rb +0 -9
  196. data/lib/gosu/swig_patches.rb +3 -2
  197. data/lib/libmpg123.dll +0 -0
  198. data/lib/libsndfile.dll +0 -0
  199. data/lib64/OpenAL32.dll +0 -0
  200. data/lib64/SDL2.dll +0 -0
  201. data/lib64/libmpg123.dll +0 -0
  202. data/lib64/libsndfile.dll +0 -0
  203. data/rdoc/gosu.rb +95 -20
  204. data/src/Audio.cpp +50 -224
  205. data/src/AudioFile.hpp +17 -37
  206. data/src/AudioFileAudioToolbox.cpp +237 -0
  207. data/src/AudioFileSDLSound.cpp +147 -0
  208. data/src/AudioImpl.cpp +3 -12
  209. data/src/AudioImpl.hpp +3 -1
  210. data/src/Bitmap.cpp +85 -83
  211. data/src/BitmapIO.cpp +52 -58
  212. data/src/Constants.cpp +80 -33
  213. data/src/Font.cpp +3 -1
  214. data/src/GosuWrapper.cpp +19 -0
  215. data/src/Graphics.cpp +7 -4
  216. data/src/Image.cpp +13 -16
  217. data/src/Input.cpp +408 -159
  218. data/src/LargeImageData.cpp +1 -1
  219. data/src/MarkupParser.cpp +2 -1
  220. data/src/RubyGosu.cxx +349 -83
  221. data/src/RubyGosu.h +4 -2
  222. data/src/TexChunk.cpp +1 -1
  223. data/src/TextBuilder.cpp +3 -1
  224. data/src/Texture.cpp +1 -1
  225. data/src/TrueTypeFont.cpp +1 -1
  226. data/src/Utility.cpp +11 -7
  227. data/src/Window.cpp +30 -39
  228. data/src/WindowWrapper.cpp +28 -0
  229. metadata +207 -52
  230. data/Gosu/Bitmap.hpp +0 -113
  231. data/src/AudioToolboxFile.hpp +0 -210
  232. data/src/OggFile.hpp +0 -92
  233. data/src/SndFile.hpp +0 -174
  234. data/src/WinMain.cpp +0 -64
@@ -0,0 +1,1034 @@
1
+ /*
2
+ * This source code is public domain.
3
+ *
4
+ * Authors: Olivier Lapicque <olivierl@jps.net>
5
+ */
6
+
7
+ #include "libmodplug.h"
8
+ #include "tables.h"
9
+
10
+ // Volume ramp length, in 1/10 ms
11
+ #define VOLUMERAMPLEN 146 // 1.46ms = 64 samples at 44.1kHz
12
+
13
+ typedef DWORD (MPPASMCALL * LPCONVERTPROC)(LPVOID, int *, DWORD, LPLONG, LPLONG);
14
+
15
+ extern DWORD MPPASMCALL X86_Convert32To8(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
16
+ extern DWORD MPPASMCALL X86_Convert32To16(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
17
+ extern DWORD MPPASMCALL X86_Convert32To24(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
18
+ extern DWORD MPPASMCALL X86_Convert32To32(LPVOID lpBuffer, int *, DWORD nSamples, LPLONG, LPLONG);
19
+ extern UINT MPPASMCALL X86_AGC(int *pBuffer, UINT nSamples, UINT nAGC);
20
+ extern VOID MPPASMCALL X86_Dither(int *pBuffer, UINT nSamples, UINT nBits);
21
+ extern VOID MPPASMCALL X86_InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples);
22
+ extern VOID MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs);
23
+ extern VOID MPPASMCALL X86_MonoFromStereo(int *pMixBuf, UINT nSamples);
24
+
25
+
26
+ // Log tables for pre-amp
27
+ // We don't want the tracker to get too loud
28
+ const UINT PreAmpTable[16] =
29
+ {
30
+ 0x60, 0x60, 0x60, 0x70, // 0-7
31
+ 0x80, 0x88, 0x90, 0x98, // 8-15
32
+ 0xA0, 0xA4, 0xA8, 0xB0, // 16-23
33
+ 0xB4, 0xB8, 0xBC, 0xC0, // 24-31
34
+ };
35
+
36
+ const UINT PreAmpAGCTable[16] =
37
+ {
38
+ 0x60, 0x60, 0x60, 0x60,
39
+ 0x68, 0x70, 0x78, 0x80,
40
+ 0x84, 0x88, 0x8C, 0x90,
41
+ 0x94, 0x98, 0x9C, 0xA0,
42
+ };
43
+
44
+
45
+ // Return (a*b)/c - no divide error
46
+ int _muldiv(long a, long b, long c)
47
+ {
48
+ return ((uint64_t) a * (uint64_t) b ) / c;
49
+ }
50
+
51
+
52
+ // Return (a*b+c/2)/c - no divide error
53
+ int _muldivr(long a, long b, long c)
54
+ {
55
+ return ((uint64_t) a * (uint64_t) b + (c >> 1)) / c;
56
+ }
57
+
58
+
59
+ BOOL CSoundFile_InitPlayer(CSoundFile *_this, BOOL bReset)
60
+ //--------------------------------------
61
+ {
62
+ if (_this->m_nMaxMixChannels > MAX_CHANNELS) _this->m_nMaxMixChannels = MAX_CHANNELS;
63
+ if (_this->gdwMixingFreq < 4000) _this->gdwMixingFreq = 4000;
64
+ if (_this->gdwMixingFreq > MAX_SAMPLE_RATE) _this->gdwMixingFreq = MAX_SAMPLE_RATE;
65
+ _this->gnVolumeRampSamples = (_this->gdwMixingFreq * VOLUMERAMPLEN) / 100000;
66
+ if (_this->gnVolumeRampSamples < 8) _this->gnVolumeRampSamples = 8;
67
+ _this->gnDryROfsVol = _this->gnDryLOfsVol = 0;
68
+ _this->gnRvbROfsVol = _this->gnRvbLOfsVol = 0;
69
+ _this->gbInitPlugins = (bReset) ? 3 : 1;
70
+ CSoundFile_InitializeDSP(_this, bReset);
71
+ return TRUE;
72
+ }
73
+
74
+
75
+ BOOL CSoundFile_FadeSong(CSoundFile *_this, UINT msec)
76
+ //----------------------------------
77
+ {
78
+ LONG nsamples = _muldiv(msec, _this->gdwMixingFreq, 1000);
79
+ if (nsamples <= 0) return FALSE;
80
+ if (nsamples > 0x100000) nsamples = 0x100000;
81
+ _this->m_nBufferCount = nsamples;
82
+ LONG nRampLength = _this->m_nBufferCount;
83
+ // Ramp everything down
84
+ for (UINT noff=0; noff < _this->m_nMixChannels; noff++)
85
+ {
86
+ MODCHANNEL *pramp = &_this->Chn[_this->ChnMix[noff]];
87
+ if (!pramp) continue;
88
+ pramp->nNewLeftVol = pramp->nNewRightVol = 0;
89
+ pramp->nRightRamp = (-pramp->nRightVol << VOLUMERAMPPRECISION) / nRampLength;
90
+ pramp->nLeftRamp = (-pramp->nLeftVol << VOLUMERAMPPRECISION) / nRampLength;
91
+ pramp->nRampRightVol = pramp->nRightVol << VOLUMERAMPPRECISION;
92
+ pramp->nRampLeftVol = pramp->nLeftVol << VOLUMERAMPPRECISION;
93
+ pramp->nRampLength = nRampLength;
94
+ pramp->dwFlags |= CHN_VOLUMERAMP;
95
+ }
96
+ _this->m_dwSongFlags |= SONG_FADINGSONG;
97
+ return TRUE;
98
+ }
99
+
100
+
101
+ BOOL CSoundFile_GlobalFadeSong(CSoundFile *_this, UINT msec)
102
+ //----------------------------------------
103
+ {
104
+ if (_this->m_dwSongFlags & SONG_GLOBALFADE) return FALSE;
105
+ _this->m_nGlobalFadeMaxSamples = _muldiv(msec, _this->gdwMixingFreq, 1000);
106
+ _this->m_nGlobalFadeSamples = _this->m_nGlobalFadeMaxSamples;
107
+ _this->m_dwSongFlags |= SONG_GLOBALFADE;
108
+ return TRUE;
109
+ }
110
+
111
+
112
+ UINT CSoundFile_Read(CSoundFile *_this, LPVOID lpDestBuffer, UINT cbBuffer)
113
+ //-------------------------------------------------------
114
+ {
115
+ LPBYTE lpBuffer = (LPBYTE)lpDestBuffer;
116
+ LPCONVERTPROC pCvt = X86_Convert32To8;
117
+ UINT lRead, lMax, lSampleSize, lCount, lSampleCount, nStat=0;
118
+ LONG nVUMeterMin = 0x7FFFFFFF, nVUMeterMax = -0x7FFFFFFF;
119
+
120
+ _this->m_nMixStat = 0;
121
+ lSampleSize = _this->gnChannels;
122
+ if (_this->gnBitsPerSample == 16) { lSampleSize *= 2; pCvt = X86_Convert32To16; }
123
+ else if (_this->gnBitsPerSample == 24) { lSampleSize *= 3; pCvt = X86_Convert32To24; }
124
+ else if (_this->gnBitsPerSample == 32) { lSampleSize *= 4; pCvt = X86_Convert32To32; }
125
+ lMax = cbBuffer / lSampleSize;
126
+ if ((!lMax) || (!lpBuffer) || (!_this->m_nChannels)) return 0;
127
+ lRead = lMax;
128
+ if (_this->m_dwSongFlags & SONG_ENDREACHED) goto MixDone;
129
+ while (lRead > 0)
130
+ {
131
+ // Update Channel Data
132
+ if (!_this->m_nBufferCount)
133
+ {
134
+ if (_this->m_dwSongFlags & SONG_FADINGSONG)
135
+ {
136
+ _this->m_dwSongFlags |= SONG_ENDREACHED;
137
+ _this->m_nBufferCount = lRead;
138
+ } else
139
+ if (!CSoundFile_ReadNote(_this))
140
+ {
141
+ if (!CSoundFile_FadeSong(_this, FADESONGDELAY))
142
+ {
143
+ _this->m_dwSongFlags |= SONG_ENDREACHED;
144
+ if (lRead == lMax) goto MixDone;
145
+ _this->m_nBufferCount = lRead;
146
+ }
147
+ }
148
+ }
149
+ lCount = _this->m_nBufferCount;
150
+ if (lCount > MIXBUFFERSIZE) lCount = MIXBUFFERSIZE;
151
+ if (lCount > lRead) lCount = lRead;
152
+ if (!lCount) break;
153
+ lSampleCount = lCount;
154
+ #ifndef MODPLUG_NO_REVERB
155
+ _this->gnReverbSend = 0;
156
+ #endif
157
+ // Resetting sound buffer
158
+ X86_StereoFill(_this->MixSoundBuffer, lSampleCount, &_this->gnDryROfsVol, &_this->gnDryLOfsVol);
159
+ if (_this->gnChannels >= 2)
160
+ {
161
+ lSampleCount *= 2;
162
+ _this->m_nMixStat += CSoundFile_CreateStereoMix(_this, lCount);
163
+ CSoundFile_ProcessStereoDSP(_this, lCount);
164
+ } else
165
+ {
166
+ _this->m_nMixStat += CSoundFile_CreateStereoMix(_this, lCount);
167
+ CSoundFile_ProcessStereoDSP(_this, lCount);
168
+ X86_MonoFromStereo(_this->MixSoundBuffer, lCount);
169
+ }
170
+ nStat++;
171
+ UINT lTotalSampleCount = lSampleCount;
172
+ // Multichannel
173
+ if (_this->gnChannels > 2)
174
+ {
175
+ X86_InterleaveFrontRear(_this->MixSoundBuffer, _this->MixRearBuffer, lSampleCount);
176
+ lTotalSampleCount *= 2;
177
+ }
178
+ // Perform clipping + VU-Meter
179
+ lpBuffer += pCvt(lpBuffer, _this->MixSoundBuffer, lTotalSampleCount, &nVUMeterMin, &nVUMeterMax);
180
+ // Buffer ready
181
+ lRead -= lCount;
182
+ _this->m_nBufferCount -= lCount;
183
+ }
184
+ MixDone:
185
+ if (lRead) SDL_memset(lpBuffer, (_this->gnBitsPerSample == 8) ? 0x80 : 0, lRead * lSampleSize);
186
+ if (nStat) { _this->m_nMixStat += nStat-1; _this->m_nMixStat /= nStat; }
187
+ return lMax - lRead;
188
+ }
189
+
190
+
191
+
192
+ /////////////////////////////////////////////////////////////////////////////
193
+ // Handles navigation/effects
194
+
195
+ BOOL CSoundFile_ProcessRow(CSoundFile *_this)
196
+ //---------------------------
197
+ {
198
+ if (++_this->m_nTickCount >= _this->m_nMusicSpeed * (_this->m_nPatternDelay+1) + _this->m_nFrameDelay)
199
+ {
200
+ _this->m_nPatternDelay = 0;
201
+ _this->m_nFrameDelay = 0;
202
+ _this->m_nTickCount = 0;
203
+ _this->m_nRow = _this->m_nNextRow;
204
+ // Reset Pattern Loop Effect
205
+ if (_this->m_nCurrentPattern != _this->m_nNextPattern) _this->m_nCurrentPattern = _this->m_nNextPattern;
206
+ // Check if pattern is valid
207
+ if (!(_this->m_dwSongFlags & SONG_PATTERNLOOP))
208
+ {
209
+ _this->m_nPattern = (_this->m_nCurrentPattern < MAX_ORDERS) ? _this->Order[_this->m_nCurrentPattern] : 0xFF;
210
+ if ((_this->m_nPattern < MAX_PATTERNS) && (!_this->Patterns[_this->m_nPattern])) _this->m_nPattern = 0xFE;
211
+ while (_this->m_nPattern >= MAX_PATTERNS)
212
+ {
213
+ // End of song ?
214
+ if ((_this->m_nPattern == 0xFF) || (_this->m_nCurrentPattern >= MAX_ORDERS))
215
+ {
216
+ //if (!_this->m_nRepeatCount)
217
+ return FALSE; //never repeat entire song
218
+ if (!_this->m_nRestartPos)
219
+ {
220
+ _this->m_nMusicSpeed = _this->m_nDefaultSpeed;
221
+ _this->m_nMusicTempo = _this->m_nDefaultTempo;
222
+ _this->m_nGlobalVolume = _this->m_nDefaultGlobalVolume;
223
+ for (UINT i=0; i<MAX_CHANNELS; i++)
224
+ {
225
+ _this->Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF;
226
+ _this->Chn[i].nFadeOutVol = 0;
227
+ if (i < _this->m_nChannels)
228
+ {
229
+ _this->Chn[i].nGlobalVol = _this->ChnSettings[i].nVolume;
230
+ _this->Chn[i].nVolume = _this->ChnSettings[i].nVolume;
231
+ _this->Chn[i].nPan = _this->ChnSettings[i].nPan;
232
+ _this->Chn[i].nPanSwing = _this->Chn[i].nVolSwing = 0;
233
+ _this->Chn[i].nOldVolParam = 0;
234
+ _this->Chn[i].nOldOffset = 0;
235
+ _this->Chn[i].nOldHiOffset = 0;
236
+ _this->Chn[i].nPortamentoDest = 0;
237
+ if (!_this->Chn[i].nLength)
238
+ {
239
+ _this->Chn[i].dwFlags = _this->ChnSettings[i].dwFlags;
240
+ _this->Chn[i].nLoopStart = 0;
241
+ _this->Chn[i].nLoopEnd = 0;
242
+ _this->Chn[i].pHeader = NULL;
243
+ _this->Chn[i].pSample = NULL;
244
+ _this->Chn[i].pInstrument = NULL;
245
+ }
246
+ }
247
+ }
248
+ }
249
+ // if (_this->m_nRepeatCount > 0) _this->m_nRepeatCount--;
250
+ _this->m_nCurrentPattern = _this->m_nRestartPos;
251
+ _this->m_nRow = 0;
252
+ if ((_this->Order[_this->m_nCurrentPattern] >= MAX_PATTERNS) || (!_this->Patterns[_this->Order[_this->m_nCurrentPattern]])) return FALSE;
253
+ } else
254
+ {
255
+ _this->m_nCurrentPattern++;
256
+ }
257
+ _this->m_nPattern = (_this->m_nCurrentPattern < MAX_ORDERS) ? _this->Order[_this->m_nCurrentPattern] : 0xFF;
258
+ if ((_this->m_nPattern < MAX_PATTERNS) && (!_this->Patterns[_this->m_nPattern])) _this->m_nPattern = 0xFE;
259
+ }
260
+ _this->m_nNextPattern = _this->m_nCurrentPattern;
261
+ }
262
+ // Weird stuff?
263
+ if ((_this->m_nPattern >= MAX_PATTERNS) || (!_this->Patterns[_this->m_nPattern])) return FALSE;
264
+ // Should never happen
265
+ if (_this->m_nRow >= _this->PatternSize[_this->m_nPattern]) _this->m_nRow = 0;
266
+ _this->m_nNextRow = _this->m_nRow + 1;
267
+ if (_this->m_nNextRow >= _this->PatternSize[_this->m_nPattern])
268
+ {
269
+ if (!(_this->m_dwSongFlags & SONG_PATTERNLOOP)) _this->m_nNextPattern = _this->m_nCurrentPattern + 1;
270
+ _this->m_nNextRow = 0;
271
+ }
272
+ // Reset channel values
273
+ MODCHANNEL *pChn = _this->Chn;
274
+ MODCOMMAND *m = _this->Patterns[_this->m_nPattern] + _this->m_nRow * _this->m_nChannels;
275
+ for (UINT nChn=0; nChn<_this->m_nChannels; pChn++, nChn++, m++)
276
+ {
277
+ pChn->nRowNote = m->note;
278
+ pChn->nRowInstr = m->instr;
279
+ pChn->nRowVolCmd = m->volcmd;
280
+ pChn->nRowVolume = m->vol;
281
+ pChn->nRowCommand = m->command;
282
+ pChn->nRowParam = m->param;
283
+
284
+ pChn->nLeftVol = pChn->nNewLeftVol;
285
+ pChn->nRightVol = pChn->nNewRightVol;
286
+ pChn->dwFlags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO | CHN_PANBRELLO);
287
+ pChn->nCommand = 0;
288
+ }
289
+ }
290
+ // Should we process tick0 effects?
291
+ if (!_this->m_nMusicSpeed) _this->m_nMusicSpeed = 1;
292
+ _this->m_dwSongFlags |= SONG_FIRSTTICK;
293
+ if (_this->m_nTickCount)
294
+ {
295
+ _this->m_dwSongFlags &= ~SONG_FIRSTTICK;
296
+ if ((!(_this->m_nType & MOD_TYPE_XM)) && (_this->m_nTickCount < _this->m_nMusicSpeed * (1 + _this->m_nPatternDelay)))
297
+ {
298
+ if (!(_this->m_nTickCount % _this->m_nMusicSpeed)) _this->m_dwSongFlags |= SONG_FIRSTTICK;
299
+ }
300
+
301
+ }
302
+ // Update Effects
303
+ return CSoundFile_ProcessEffects(_this);
304
+ }
305
+
306
+
307
+ ////////////////////////////////////////////////////////////////////////////////////////////
308
+ // Handles envelopes & mixer setup
309
+
310
+ BOOL CSoundFile_ReadNote(CSoundFile *_this)
311
+ //-------------------------
312
+ {
313
+ if (!CSoundFile_ProcessRow(_this)) return FALSE;
314
+ ////////////////////////////////////////////////////////////////////////////////////
315
+ _this->m_nTotalCount++;
316
+ if (!_this->m_nMusicTempo) return FALSE;
317
+ _this->m_nBufferCount = (_this->gdwMixingFreq * 5 * _this->m_nTempoFactor) / (_this->m_nMusicTempo << 8);
318
+ // Master Volume + Pre-Amplification / Attenuation setup
319
+ DWORD nMasterVol;
320
+ {
321
+ int nchn32 = (_this->m_nChannels < 32) ? _this->m_nChannels : 31;
322
+ if ((_this->m_nType & MOD_TYPE_IT) && (_this->m_nInstruments) && (nchn32 < 6)) nchn32 = 6;
323
+ int realmastervol = _this->m_nMasterVolume;
324
+ if (realmastervol > 0x80)
325
+ {
326
+ realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32+4)) / 16;
327
+ }
328
+ UINT attenuation = (_this->gdwSoundSetup & SNDMIX_AGC) ? PreAmpAGCTable[nchn32>>1] : PreAmpTable[nchn32>>1];
329
+ DWORD mastervol = (realmastervol * (_this->m_nSongPreAmp + 0x10)) >> 6;
330
+ if (mastervol > 0x200) mastervol = 0x200;
331
+ if ((_this->m_dwSongFlags & SONG_GLOBALFADE) && (_this->m_nGlobalFadeMaxSamples))
332
+ {
333
+ mastervol = _muldiv(mastervol, _this->m_nGlobalFadeSamples, _this->m_nGlobalFadeMaxSamples);
334
+ }
335
+ nMasterVol = (mastervol << 7) / attenuation;
336
+ if (nMasterVol > 0x180) nMasterVol = 0x180;
337
+ }
338
+ ////////////////////////////////////////////////////////////////////////////////////
339
+ // Update channels data
340
+ _this->m_nMixChannels = 0;
341
+ MODCHANNEL *pChn = _this->Chn;
342
+ for (UINT nChn=0; nChn<MAX_CHANNELS; nChn++,pChn++)
343
+ {
344
+ if ((pChn->dwFlags & CHN_NOTEFADE) && (!(pChn->nFadeOutVol|pChn->nRightVol|pChn->nLeftVol)))
345
+ {
346
+ pChn->nLength = 0;
347
+ pChn->nROfs = pChn->nLOfs = 0;
348
+ }
349
+ // Check for unused channel
350
+ if ((pChn->dwFlags & CHN_MUTE) || ((nChn >= _this->m_nChannels) && (!pChn->nLength)))
351
+ {
352
+ continue;
353
+ }
354
+ // Reset channel data
355
+ pChn->nInc = 0;
356
+ pChn->nRealVolume = 0;
357
+ pChn->nRealPan = pChn->nPan + pChn->nPanSwing;
358
+ if (pChn->nRealPan < 0) pChn->nRealPan = 0;
359
+ if (pChn->nRealPan > 256) pChn->nRealPan = 256;
360
+ pChn->nRampLength = 0;
361
+ // Calc Frequency
362
+ if ((pChn->nPeriod) && (pChn->nLength))
363
+ {
364
+ int vol = pChn->nVolume + pChn->nVolSwing;
365
+
366
+ if (vol < 0) vol = 0;
367
+ if (vol > 256) vol = 256;
368
+ // Tremolo
369
+ if (pChn->dwFlags & CHN_TREMOLO)
370
+ {
371
+ UINT trempos = pChn->nTremoloPos & 0x3F;
372
+ if (vol > 0)
373
+ {
374
+ int tremattn = (_this->m_nType & MOD_TYPE_XM) ? 5 : 6;
375
+ switch (pChn->nTremoloType & 0x03)
376
+ {
377
+ case 1:
378
+ vol += (ModRampDownTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
379
+ break;
380
+ case 2:
381
+ vol += (ModSquareTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
382
+ break;
383
+ case 3:
384
+ vol += (ModRandomTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
385
+ break;
386
+ default:
387
+ vol += (ModSinusTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
388
+ }
389
+ }
390
+ if ((_this->m_nTickCount) || ((_this->m_nType & (MOD_TYPE_STM|MOD_TYPE_S3M|MOD_TYPE_IT)) && (!(_this->m_dwSongFlags & SONG_ITOLDEFFECTS))))
391
+ {
392
+ pChn->nTremoloPos = (trempos + pChn->nTremoloSpeed) & 0x3F;
393
+ }
394
+ }
395
+ // Tremor
396
+ if (pChn->nCommand == CMD_TREMOR)
397
+ {
398
+ UINT n = (pChn->nTremorParam >> 4) + (pChn->nTremorParam & 0x0F);
399
+ UINT ontime = pChn->nTremorParam >> 4;
400
+ if ((!(_this->m_nType & MOD_TYPE_IT)) || (_this->m_dwSongFlags & SONG_ITOLDEFFECTS)) { n += 2; ontime++; }
401
+ UINT tremcount = (UINT)pChn->nTremorCount;
402
+ if (tremcount >= n) tremcount = 0;
403
+ if ((_this->m_nTickCount) || (_this->m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT)))
404
+ {
405
+ if (tremcount >= ontime) vol = 0;
406
+ pChn->nTremorCount = (BYTE)(tremcount + 1);
407
+ }
408
+ pChn->dwFlags |= CHN_FASTVOLRAMP;
409
+ }
410
+ // Clip volume
411
+ if (vol < 0) vol = 0;
412
+ if (vol > 0x100) vol = 0x100;
413
+ vol <<= 6;
414
+ // Process Envelopes
415
+ if (pChn->pHeader)
416
+ {
417
+ INSTRUMENTHEADER *penv = pChn->pHeader;
418
+ // Volume Envelope
419
+ if ((pChn->dwFlags & CHN_VOLENV) && (penv->nVolEnv))
420
+ {
421
+ int envpos = pChn->nVolEnvPosition;
422
+ UINT pt = penv->nVolEnv - 1;
423
+ for (UINT i=0; i<(UINT)(penv->nVolEnv-1); i++)
424
+ {
425
+ if (envpos <= penv->VolPoints[i])
426
+ {
427
+ pt = i;
428
+ break;
429
+ }
430
+ }
431
+ int x2 = penv->VolPoints[pt];
432
+ int x1, envvol;
433
+ if (envpos >= x2)
434
+ {
435
+ envvol = penv->VolEnv[pt] << 2;
436
+ x1 = x2;
437
+ } else
438
+ if (pt)
439
+ {
440
+ envvol = penv->VolEnv[pt-1] << 2;
441
+ x1 = penv->VolPoints[pt-1];
442
+ } else
443
+ {
444
+ envvol = 0;
445
+ x1 = 0;
446
+ }
447
+ if (envpos > x2) envpos = x2;
448
+ if ((x2 > x1) && (envpos > x1))
449
+ {
450
+ envvol += ((envpos - x1) * (((int)penv->VolEnv[pt]<<2) - envvol)) / (x2 - x1);
451
+ }
452
+ if (envvol < 0) envvol = 0;
453
+ if (envvol > 256) envvol = 256;
454
+ vol = (vol * envvol) >> 8;
455
+ }
456
+ // Panning Envelope
457
+ if ((pChn->dwFlags & CHN_PANENV) && (penv->nPanEnv))
458
+ {
459
+ int envpos = pChn->nPanEnvPosition;
460
+ UINT pt = penv->nPanEnv - 1;
461
+ for (UINT i=0; i<(UINT)(penv->nPanEnv-1); i++)
462
+ {
463
+ if (envpos <= penv->PanPoints[i])
464
+ {
465
+ pt = i;
466
+ break;
467
+ }
468
+ }
469
+ int x2 = penv->PanPoints[pt], y2 = penv->PanEnv[pt];
470
+ int x1, envpan;
471
+ if (envpos >= x2)
472
+ {
473
+ envpan = y2;
474
+ x1 = x2;
475
+ } else
476
+ if (pt)
477
+ {
478
+ envpan = penv->PanEnv[pt-1];
479
+ x1 = penv->PanPoints[pt-1];
480
+ } else
481
+ {
482
+ envpan = 128;
483
+ x1 = 0;
484
+ }
485
+ if ((x2 > x1) && (envpos > x1))
486
+ {
487
+ envpan += ((envpos - x1) * (y2 - envpan)) / (x2 - x1);
488
+ }
489
+ if (envpan < 0) envpan = 0;
490
+ if (envpan > 64) envpan = 64;
491
+ int pan = pChn->nPan;
492
+ if (pan >= 128)
493
+ {
494
+ pan += ((envpan - 32) * (256 - pan)) / 32;
495
+ } else
496
+ {
497
+ pan += ((envpan - 32) * (pan)) / 32;
498
+ }
499
+ if (pan < 0) pan = 0;
500
+ if (pan > 256) pan = 256;
501
+ pChn->nRealPan = pan;
502
+ }
503
+ // FadeOut volume
504
+ if (pChn->dwFlags & CHN_NOTEFADE)
505
+ {
506
+ UINT fadeout = penv->nFadeOut;
507
+ if (fadeout)
508
+ {
509
+ pChn->nFadeOutVol -= fadeout << 1;
510
+ if (pChn->nFadeOutVol <= 0) pChn->nFadeOutVol = 0;
511
+ vol = (vol * pChn->nFadeOutVol) >> 16;
512
+ } else
513
+ if (!pChn->nFadeOutVol)
514
+ {
515
+ vol = 0;
516
+ }
517
+ }
518
+ // Pitch/Pan separation
519
+ if ((penv->nPPS) && (pChn->nRealPan) && (pChn->nNote))
520
+ {
521
+ int pandelta = (int)pChn->nRealPan + (int)((int)(pChn->nNote - penv->nPPC - 1) * (int)penv->nPPS) / (int)8;
522
+ if (pandelta < 0) pandelta = 0;
523
+ if (pandelta > 256) pandelta = 256;
524
+ pChn->nRealPan = pandelta;
525
+ }
526
+ } else
527
+ {
528
+ // No Envelope: key off => note cut
529
+ if (pChn->dwFlags & CHN_NOTEFADE) // 1.41-: CHN_KEYOFF|CHN_NOTEFADE
530
+ {
531
+ pChn->nFadeOutVol = 0;
532
+ vol = 0;
533
+ }
534
+ }
535
+ // vol is 14-bits
536
+ if (vol)
537
+ {
538
+ // IMPORTANT: pChn->nRealVolume is 14 bits !!!
539
+ // -> _muldiv( 14+8, 6+6, 18); => RealVolume: 14-bit result (22+12-20)
540
+ pChn->nRealVolume = _muldiv(vol * _this->m_nGlobalVolume, pChn->nGlobalVol * pChn->nInsVol, 1 << 20);
541
+ }
542
+ if (pChn->nPeriod < _this->m_nMinPeriod) pChn->nPeriod = _this->m_nMinPeriod;
543
+ int period = pChn->nPeriod;
544
+ if ((pChn->dwFlags & (CHN_GLISSANDO|CHN_PORTAMENTO)) == (CHN_GLISSANDO|CHN_PORTAMENTO))
545
+ {
546
+ period = CSoundFile_GetPeriodFromNote(_this, CSoundFile_GetNoteFromPeriod(_this, period), pChn->nFineTune, pChn->nC4Speed);
547
+ }
548
+
549
+ // Arpeggio ?
550
+ if (pChn->nCommand == CMD_ARPEGGIO)
551
+ {
552
+ switch(_this->m_nTickCount % 3)
553
+ {
554
+ case 1: period = CSoundFile_GetPeriodFromNote(_this, pChn->nNote + (pChn->nArpeggio >> 4), pChn->nFineTune, pChn->nC4Speed); break;
555
+ case 2: period = CSoundFile_GetPeriodFromNote(_this, pChn->nNote + (pChn->nArpeggio & 0x0F), pChn->nFineTune, pChn->nC4Speed); break;
556
+ }
557
+ }
558
+
559
+ if (_this->m_dwSongFlags & SONG_AMIGALIMITS)
560
+ {
561
+ if (period < 113*4) period = 113*4;
562
+ if (period > 856*4) period = 856*4;
563
+ }
564
+
565
+ // Pitch/Filter Envelope
566
+ if ((pChn->pHeader) && (pChn->dwFlags & CHN_PITCHENV) && (pChn->pHeader->nPitchEnv))
567
+ {
568
+ INSTRUMENTHEADER *penv = pChn->pHeader;
569
+ int envpos = pChn->nPitchEnvPosition;
570
+ UINT pt = penv->nPitchEnv - 1;
571
+ for (UINT i=0; i<(UINT)(penv->nPitchEnv-1); i++)
572
+ {
573
+ if (envpos <= penv->PitchPoints[i])
574
+ {
575
+ pt = i;
576
+ break;
577
+ }
578
+ }
579
+ int x2 = penv->PitchPoints[pt];
580
+ int x1, envpitch;
581
+ if (envpos >= x2)
582
+ {
583
+ envpitch = (((int)penv->PitchEnv[pt]) - 32) * 8;
584
+ x1 = x2;
585
+ } else
586
+ if (pt)
587
+ {
588
+ envpitch = (((int)penv->PitchEnv[pt-1]) - 32) * 8;
589
+ x1 = penv->PitchPoints[pt-1];
590
+ } else
591
+ {
592
+ envpitch = 0;
593
+ x1 = 0;
594
+ }
595
+ if (envpos > x2) envpos = x2;
596
+ if ((x2 > x1) && (envpos > x1))
597
+ {
598
+ int envpitchdest = (((int)penv->PitchEnv[pt]) - 32) * 8;
599
+ envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1);
600
+ }
601
+ if (envpitch < -256) envpitch = -256;
602
+ if (envpitch > 256) envpitch = 256;
603
+ // Filter Envelope: controls cutoff frequency
604
+ if (penv->dwFlags & ENV_FILTER)
605
+ {
606
+ #ifndef NO_FILTER
607
+ CSoundFile_SetupChannelFilter(_this, pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE, envpitch);
608
+ #endif // NO_FILTER
609
+ } else
610
+ // Pitch Envelope
611
+ {
612
+ int l = envpitch;
613
+ if (l < 0)
614
+ {
615
+ l = -l;
616
+ if (l > 255) l = 255;
617
+ period = _muldiv(period, LinearSlideUpTable[l], 0x10000);
618
+ } else
619
+ {
620
+ if (l > 255) l = 255;
621
+ period = _muldiv(period, LinearSlideDownTable[l], 0x10000);
622
+ }
623
+ }
624
+ }
625
+
626
+ // Vibrato
627
+ if (pChn->dwFlags & CHN_VIBRATO)
628
+ {
629
+ UINT vibpos = pChn->nVibratoPos;
630
+ LONG vdelta;
631
+ switch (pChn->nVibratoType & 0x03)
632
+ {
633
+ case 1:
634
+ vdelta = ModRampDownTable[vibpos];
635
+ break;
636
+ case 2:
637
+ vdelta = ModSquareTable[vibpos];
638
+ break;
639
+ case 3:
640
+ vdelta = ModRandomTable[vibpos];
641
+ break;
642
+ default:
643
+ vdelta = ModSinusTable[vibpos];
644
+ }
645
+ UINT vdepth = ((_this->m_nType != MOD_TYPE_IT) || (_this->m_dwSongFlags & SONG_ITOLDEFFECTS)) ? 6 : 7;
646
+ vdelta = (vdelta * (int)pChn->nVibratoDepth) >> vdepth;
647
+ if ((_this->m_dwSongFlags & SONG_LINEARSLIDES) && (_this->m_nType & MOD_TYPE_IT))
648
+ {
649
+ LONG l = vdelta;
650
+ if (l < 0)
651
+ {
652
+ l = -l;
653
+ vdelta = _muldiv(period, LinearSlideDownTable[l >> 2], 0x10000) - period;
654
+ if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideDownTable[l & 0x03], 0x10000) - period;
655
+
656
+ } else
657
+ {
658
+ vdelta = _muldiv(period, LinearSlideUpTable[l >> 2], 0x10000) - period;
659
+ if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideUpTable[l & 0x03], 0x10000) - period;
660
+
661
+ }
662
+ }
663
+ period += vdelta;
664
+ if ((_this->m_nTickCount) || ((_this->m_nType & MOD_TYPE_IT) && (!(_this->m_dwSongFlags & SONG_ITOLDEFFECTS))))
665
+ {
666
+ pChn->nVibratoPos = (vibpos + pChn->nVibratoSpeed) & 0x3F;
667
+ }
668
+ }
669
+ // Panbrello
670
+ if (pChn->dwFlags & CHN_PANBRELLO)
671
+ {
672
+ UINT panpos = ((pChn->nPanbrelloPos+0x10) >> 2) & 0x3F;
673
+ LONG pdelta;
674
+ switch (pChn->nPanbrelloType & 0x03)
675
+ {
676
+ case 1:
677
+ pdelta = ModRampDownTable[panpos];
678
+ break;
679
+ case 2:
680
+ pdelta = ModSquareTable[panpos];
681
+ break;
682
+ case 3:
683
+ pdelta = ModRandomTable[panpos];
684
+ break;
685
+ default:
686
+ pdelta = ModSinusTable[panpos];
687
+ }
688
+ pChn->nPanbrelloPos += pChn->nPanbrelloSpeed;
689
+ pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3;
690
+ pdelta += pChn->nRealPan;
691
+ if (pdelta < 0) pdelta = 0;
692
+ if (pdelta > 256) pdelta = 256;
693
+ pChn->nRealPan = pdelta;
694
+ }
695
+ int nPeriodFrac = 0;
696
+ // Instrument Auto-Vibrato
697
+ if ((pChn->pInstrument) && (pChn->pInstrument->nVibDepth))
698
+ {
699
+ MODINSTRUMENT *pins = pChn->pInstrument;
700
+ if (pins->nVibSweep == 0)
701
+ {
702
+ pChn->nAutoVibDepth = pins->nVibDepth << 8;
703
+ } else
704
+ {
705
+ if (_this->m_nType & MOD_TYPE_IT)
706
+ {
707
+ pChn->nAutoVibDepth += pins->nVibSweep << 3;
708
+ } else
709
+ if (!(pChn->dwFlags & CHN_KEYOFF))
710
+ {
711
+ pChn->nAutoVibDepth += (pins->nVibDepth << 8) / pins->nVibSweep;
712
+ }
713
+ if ((pChn->nAutoVibDepth >> 8) > pins->nVibDepth)
714
+ pChn->nAutoVibDepth = pins->nVibDepth << 8;
715
+ }
716
+ pChn->nAutoVibPos += pins->nVibRate;
717
+ int val;
718
+ switch(pins->nVibType)
719
+ {
720
+ case 4: // Random
721
+ val = ModRandomTable[pChn->nAutoVibPos & 0x3F];
722
+ pChn->nAutoVibPos++;
723
+ break;
724
+ case 3: // Ramp Down
725
+ val = ((0x40 - (pChn->nAutoVibPos >> 1)) & 0x7F) - 0x40;
726
+ break;
727
+ case 2: // Ramp Up
728
+ val = ((0x40 + (pChn->nAutoVibPos >> 1)) & 0x7f) - 0x40;
729
+ break;
730
+ case 1: // Square
731
+ val = (pChn->nAutoVibPos & 128) ? +64 : -64;
732
+ break;
733
+ default: // Sine
734
+ val = ft2VibratoTable[pChn->nAutoVibPos & 255];
735
+ }
736
+ int n = ((val * pChn->nAutoVibDepth) >> 8);
737
+ if (_this->m_nType & MOD_TYPE_IT)
738
+ {
739
+ int df1, df2;
740
+ if (n < 0)
741
+ {
742
+ n = -n;
743
+ UINT n1 = n >> 8;
744
+ df1 = LinearSlideUpTable[n1];
745
+ df2 = LinearSlideUpTable[n1+1];
746
+ } else
747
+ {
748
+ UINT n1 = n >> 8;
749
+ df1 = LinearSlideDownTable[n1];
750
+ df2 = LinearSlideDownTable[n1+1];
751
+ }
752
+ n >>= 2;
753
+ period = _muldiv(period, df1 + ((df2-df1)*(n&0x3F)>>6), 256);
754
+ nPeriodFrac = period & 0xFF;
755
+ period >>= 8;
756
+ } else
757
+ {
758
+ period += (n >> 6);
759
+ }
760
+ }
761
+ // Final Period
762
+ if (period <= _this->m_nMinPeriod)
763
+ {
764
+ if (_this->m_nType & MOD_TYPE_S3M) pChn->nLength = 0;
765
+ period = _this->m_nMinPeriod;
766
+ }
767
+ if (period > _this->m_nMaxPeriod)
768
+ {
769
+ if ((_this->m_nType & MOD_TYPE_IT) || (period >= 0x100000))
770
+ {
771
+ pChn->nFadeOutVol = 0;
772
+ pChn->dwFlags |= CHN_NOTEFADE;
773
+ pChn->nRealVolume = 0;
774
+ }
775
+ period = _this->m_nMaxPeriod;
776
+ nPeriodFrac = 0;
777
+ }
778
+ UINT freq = CSoundFile_GetFreqFromPeriod(_this, period, pChn->nC4Speed, nPeriodFrac);
779
+ if ((_this->m_nType & MOD_TYPE_IT) && (freq < 256))
780
+ {
781
+ pChn->nFadeOutVol = 0;
782
+ pChn->dwFlags |= CHN_NOTEFADE;
783
+ pChn->nRealVolume = 0;
784
+ }
785
+ UINT ninc = _muldiv(freq, 0x10000, _this->gdwMixingFreq);
786
+ if ((ninc >= 0xFFB0) && (ninc <= 0x10090)) ninc = 0x10000;
787
+ if (_this->m_nFreqFactor != 128) ninc = (ninc * _this->m_nFreqFactor) >> 7;
788
+ if (ninc > 0xFF0000) ninc = 0xFF0000;
789
+ pChn->nInc = (ninc+1) & ~3;
790
+ }
791
+
792
+ // Increment envelope position
793
+ if (pChn->pHeader)
794
+ {
795
+ INSTRUMENTHEADER *penv = pChn->pHeader;
796
+ // Volume Envelope
797
+ if (pChn->dwFlags & CHN_VOLENV)
798
+ {
799
+ // Increase position
800
+ pChn->nVolEnvPosition++;
801
+ // Volume Loop ?
802
+ if (penv->dwFlags & ENV_VOLLOOP)
803
+ {
804
+ UINT volloopend = penv->VolPoints[penv->nVolLoopEnd];
805
+ if (_this->m_nType != MOD_TYPE_XM) volloopend++;
806
+ if (pChn->nVolEnvPosition == volloopend)
807
+ {
808
+ pChn->nVolEnvPosition = penv->VolPoints[penv->nVolLoopStart];
809
+ if ((penv->nVolLoopEnd == penv->nVolLoopStart) && (!penv->VolEnv[penv->nVolLoopStart])
810
+ && ((!(_this->m_nType & MOD_TYPE_XM)) || (penv->nVolLoopEnd+1 == penv->nVolEnv)))
811
+ {
812
+ pChn->dwFlags |= CHN_NOTEFADE;
813
+ pChn->nFadeOutVol = 0;
814
+ }
815
+ }
816
+ }
817
+ // Volume Sustain ?
818
+ if ((penv->dwFlags & ENV_VOLSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF)))
819
+ {
820
+ if (pChn->nVolEnvPosition == (UINT)penv->VolPoints[penv->nVolSustainEnd]+1)
821
+ pChn->nVolEnvPosition = penv->VolPoints[penv->nVolSustainBegin];
822
+ } else
823
+ // End of Envelope ?
824
+ if (pChn->nVolEnvPosition > penv->VolPoints[penv->nVolEnv - 1])
825
+ {
826
+ if ((_this->m_nType & MOD_TYPE_IT) || (pChn->dwFlags & CHN_KEYOFF)) pChn->dwFlags |= CHN_NOTEFADE;
827
+ pChn->nVolEnvPosition = penv->VolPoints[penv->nVolEnv - 1];
828
+ if ((!penv->VolEnv[penv->nVolEnv-1]) && ((nChn >= _this->m_nChannels) || (_this->m_nType & MOD_TYPE_IT)))
829
+ {
830
+ pChn->dwFlags |= CHN_NOTEFADE;
831
+ pChn->nFadeOutVol = 0;
832
+
833
+ pChn->nRealVolume = 0;
834
+ }
835
+ }
836
+ }
837
+ // Panning Envelope
838
+ if (pChn->dwFlags & CHN_PANENV)
839
+ {
840
+ pChn->nPanEnvPosition++;
841
+ if (penv->dwFlags & ENV_PANLOOP)
842
+ {
843
+ UINT panloopend = penv->PanPoints[penv->nPanLoopEnd];
844
+ if (_this->m_nType != MOD_TYPE_XM) panloopend++;
845
+ if (pChn->nPanEnvPosition == panloopend)
846
+ pChn->nPanEnvPosition = penv->PanPoints[penv->nPanLoopStart];
847
+ }
848
+ // Panning Sustain ?
849
+ if ((penv->dwFlags & ENV_PANSUSTAIN) && (pChn->nPanEnvPosition == (UINT)penv->PanPoints[penv->nPanSustainEnd]+1)
850
+ && (!(pChn->dwFlags & CHN_KEYOFF)))
851
+ {
852
+ // Panning sustained
853
+ pChn->nPanEnvPosition = penv->PanPoints[penv->nPanSustainBegin];
854
+ } else
855
+ {
856
+ if (pChn->nPanEnvPosition > penv->PanPoints[penv->nPanEnv - 1])
857
+ pChn->nPanEnvPosition = penv->PanPoints[penv->nPanEnv - 1];
858
+ }
859
+ }
860
+ // Pitch Envelope
861
+ if (pChn->dwFlags & CHN_PITCHENV)
862
+ {
863
+ // Increase position
864
+ pChn->nPitchEnvPosition++;
865
+ // Pitch Loop ?
866
+ if (penv->dwFlags & ENV_PITCHLOOP)
867
+ {
868
+ if (pChn->nPitchEnvPosition >= penv->PitchPoints[penv->nPitchLoopEnd])
869
+ pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchLoopStart];
870
+ }
871
+ // Pitch Sustain ?
872
+ if ((penv->dwFlags & ENV_PITCHSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF)))
873
+ {
874
+ if (pChn->nPitchEnvPosition == (UINT)penv->PitchPoints[penv->nPitchSustainEnd]+1)
875
+ pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchSustainBegin];
876
+ } else
877
+ {
878
+ if (pChn->nPitchEnvPosition > penv->PitchPoints[penv->nPitchEnv - 1])
879
+ pChn->nPitchEnvPosition = penv->PitchPoints[penv->nPitchEnv - 1];
880
+ }
881
+ }
882
+ }
883
+ // Volume ramping
884
+ pChn->dwFlags &= ~CHN_VOLUMERAMP;
885
+ if ((pChn->nRealVolume) || (pChn->nLeftVol) || (pChn->nRightVol))
886
+ pChn->dwFlags |= CHN_VOLUMERAMP;
887
+ // Check for too big nInc
888
+ if (((pChn->nInc >> 16) + 1) >= (LONG)(pChn->nLoopEnd - pChn->nLoopStart)) pChn->dwFlags &= ~CHN_LOOP;
889
+ pChn->nNewRightVol = pChn->nNewLeftVol = 0;
890
+ pChn->pCurrentSample = ((pChn->pSample) && (pChn->nLength) && (pChn->nInc)) ? pChn->pSample : NULL;
891
+ if (pChn->pCurrentSample)
892
+ {
893
+ #ifdef MODPLUG_TRACKER
894
+ UINT kChnMasterVol = (pChn->dwFlags & CHN_EXTRALOUD) ? 0x100 : nMasterVol;
895
+ #else
896
+ #define kChnMasterVol nMasterVol
897
+ #endif // MODPLUG_TRACKER
898
+ // Adjusting volumes
899
+ if (_this->gnChannels >= 2)
900
+ {
901
+ int pan = ((int)pChn->nRealPan) - 128;
902
+ pan *= (int)_this->m_nStereoSeparation;
903
+ pan /= 128;
904
+ pan += 128;
905
+
906
+ if (pan < 0) pan = 0;
907
+ if (pan > 256) pan = 256;
908
+ if (_this->gdwSoundSetup & SNDMIX_REVERSESTEREO) pan = 256 - pan;
909
+ LONG realvol = (pChn->nRealVolume * kChnMasterVol) >> (8-1);
910
+ if (_this->gdwSoundSetup & SNDMIX_SOFTPANNING)
911
+ {
912
+ if (pan < 128)
913
+ {
914
+ pChn->nNewLeftVol = (realvol * pan) >> 8;
915
+ pChn->nNewRightVol = (realvol * 128) >> 8;
916
+ } else
917
+ {
918
+ pChn->nNewLeftVol = (realvol * 128) >> 8;
919
+ pChn->nNewRightVol = (realvol * (256 - pan)) >> 8;
920
+ }
921
+ } else
922
+ {
923
+ pChn->nNewLeftVol = (realvol * pan) >> 8;
924
+ pChn->nNewRightVol = (realvol * (256 - pan)) >> 8;
925
+ }
926
+ } else
927
+ {
928
+ pChn->nNewRightVol = (pChn->nRealVolume * kChnMasterVol) >> 8;
929
+ pChn->nNewLeftVol = pChn->nNewRightVol;
930
+ }
931
+ // Clipping volumes
932
+ if (pChn->nNewRightVol > 0xFFFF) pChn->nNewRightVol = 0xFFFF;
933
+ if (pChn->nNewLeftVol > 0xFFFF) pChn->nNewLeftVol = 0xFFFF;
934
+ // Check IDO
935
+ if (_this->gdwSoundSetup & SNDMIX_NORESAMPLING)
936
+ {
937
+ pChn->dwFlags |= CHN_NOIDO;
938
+ } else
939
+ {
940
+ pChn->dwFlags &= ~(CHN_NOIDO|CHN_HQSRC);
941
+ if( pChn->nInc == 0x10000 )
942
+ { pChn->dwFlags |= CHN_NOIDO;
943
+ }
944
+ else
945
+ { if( ((_this->gdwSoundSetup & SNDMIX_HQRESAMPLER) == 0) && ((_this->gdwSoundSetup & SNDMIX_ULTRAHQSRCMODE) == 0) )
946
+ { if (pChn->nInc >= 0xFF00) pChn->dwFlags |= CHN_NOIDO;
947
+ }
948
+ }
949
+ }
950
+ pChn->nNewRightVol >>= MIXING_ATTENUATION;
951
+ pChn->nNewLeftVol >>= MIXING_ATTENUATION;
952
+ pChn->nRightRamp = pChn->nLeftRamp = 0;
953
+ // Dolby Pro-Logic Surround
954
+ if ((pChn->dwFlags & CHN_SURROUND) && (_this->gnChannels <= 2)) pChn->nNewLeftVol = - pChn->nNewLeftVol;
955
+ // Checking Ping-Pong Loops
956
+ if (pChn->dwFlags & CHN_PINGPONGFLAG) pChn->nInc = -pChn->nInc;
957
+ // Setting up volume ramp
958
+ if ((pChn->dwFlags & CHN_VOLUMERAMP)
959
+ && ((pChn->nRightVol != pChn->nNewRightVol)
960
+ || (pChn->nLeftVol != pChn->nNewLeftVol)))
961
+ {
962
+ LONG nRampLength = _this->gnVolumeRampSamples;
963
+ LONG nRightDelta = ((pChn->nNewRightVol - pChn->nRightVol) << VOLUMERAMPPRECISION);
964
+ LONG nLeftDelta = ((pChn->nNewLeftVol - pChn->nLeftVol) << VOLUMERAMPPRECISION);
965
+ if ((_this->gdwSoundSetup & SNDMIX_DIRECTTODISK) || (_this->gdwSoundSetup & SNDMIX_HQRESAMPLER))
966
+ {
967
+ if ((pChn->nRightVol|pChn->nLeftVol) && (pChn->nNewRightVol|pChn->nNewLeftVol) && (!(pChn->dwFlags & CHN_FASTVOLRAMP)))
968
+ {
969
+ nRampLength = _this->m_nBufferCount;
970
+ if (nRampLength > (1 << (VOLUMERAMPPRECISION-1))) nRampLength = (1 << (VOLUMERAMPPRECISION-1));
971
+ if (nRampLength < (LONG)_this->gnVolumeRampSamples) nRampLength = _this->gnVolumeRampSamples;
972
+ }
973
+ }
974
+ pChn->nRightRamp = nRightDelta / nRampLength;
975
+ pChn->nLeftRamp = nLeftDelta / nRampLength;
976
+ pChn->nRightVol = pChn->nNewRightVol - ((pChn->nRightRamp * nRampLength) >> VOLUMERAMPPRECISION);
977
+ pChn->nLeftVol = pChn->nNewLeftVol - ((pChn->nLeftRamp * nRampLength) >> VOLUMERAMPPRECISION);
978
+ if (pChn->nRightRamp|pChn->nLeftRamp)
979
+ {
980
+ pChn->nRampLength = nRampLength;
981
+ } else
982
+ {
983
+ pChn->dwFlags &= ~CHN_VOLUMERAMP;
984
+ pChn->nRightVol = pChn->nNewRightVol;
985
+ pChn->nLeftVol = pChn->nNewLeftVol;
986
+ }
987
+ } else
988
+ {
989
+ pChn->dwFlags &= ~CHN_VOLUMERAMP;
990
+ pChn->nRightVol = pChn->nNewRightVol;
991
+ pChn->nLeftVol = pChn->nNewLeftVol;
992
+ }
993
+ pChn->nRampRightVol = pChn->nRightVol << VOLUMERAMPPRECISION;
994
+ pChn->nRampLeftVol = pChn->nLeftVol << VOLUMERAMPPRECISION;
995
+ // Adding the channel in the channel list
996
+ _this->ChnMix[_this->m_nMixChannels++] = nChn;
997
+ if (_this->m_nMixChannels >= MAX_CHANNELS) break;
998
+ } else
999
+ {
1000
+ pChn->nLeftVol = pChn->nRightVol = 0;
1001
+ pChn->nLength = 0;
1002
+ }
1003
+ }
1004
+ // Checking Max Mix Channels reached: ordering by volume
1005
+ if ((_this->m_nMixChannels >= _this->m_nMaxMixChannels) && (!(_this->gdwSoundSetup & SNDMIX_DIRECTTODISK)))
1006
+ {
1007
+ for (UINT i=0; i<_this->m_nMixChannels; i++)
1008
+ {
1009
+ UINT j=i;
1010
+ while ((j+1<_this->m_nMixChannels) && (_this->Chn[_this->ChnMix[j]].nRealVolume < _this->Chn[_this->ChnMix[j+1]].nRealVolume))
1011
+ {
1012
+ UINT n = _this->ChnMix[j];
1013
+ _this->ChnMix[j] = _this->ChnMix[j+1];
1014
+ _this->ChnMix[j+1] = n;
1015
+ j++;
1016
+ }
1017
+ }
1018
+ }
1019
+ if (_this->m_dwSongFlags & SONG_GLOBALFADE)
1020
+ {
1021
+ if (!_this->m_nGlobalFadeSamples)
1022
+ {
1023
+ _this->m_dwSongFlags |= SONG_ENDREACHED;
1024
+ return FALSE;
1025
+ }
1026
+ if (_this->m_nGlobalFadeSamples > _this->m_nBufferCount)
1027
+ _this->m_nGlobalFadeSamples -= _this->m_nBufferCount;
1028
+ else
1029
+ _this->m_nGlobalFadeSamples = 0;
1030
+ }
1031
+ return TRUE;
1032
+ }
1033
+
1034
+