gosu 0.15.1 → 1.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/COPYING +1 -1
  4. data/dependencies/SDL/include/SDL.h +138 -0
  5. data/dependencies/SDL/include/SDL_assert.h +293 -0
  6. data/dependencies/SDL/include/SDL_atomic.h +295 -0
  7. data/dependencies/SDL/include/SDL_audio.h +859 -0
  8. data/dependencies/SDL/include/SDL_bits.h +121 -0
  9. data/dependencies/SDL/include/SDL_blendmode.h +123 -0
  10. data/dependencies/SDL/include/SDL_clipboard.h +71 -0
  11. data/dependencies/SDL/include/SDL_config.h +55 -0
  12. data/dependencies/SDL/include/SDL_config_android.h +182 -0
  13. data/dependencies/SDL/include/SDL_config_iphoneos.h +207 -0
  14. data/dependencies/SDL/include/SDL_config_macosx.h +266 -0
  15. data/dependencies/SDL/include/SDL_config_minimal.h +85 -0
  16. data/dependencies/SDL/include/SDL_config_os2.h +188 -0
  17. data/dependencies/SDL/include/SDL_config_pandora.h +135 -0
  18. data/dependencies/SDL/include/SDL_config_psp.h +165 -0
  19. data/dependencies/SDL/include/SDL_config_windows.h +288 -0
  20. data/dependencies/SDL/include/SDL_config_winrt.h +243 -0
  21. data/dependencies/SDL/include/SDL_config_wiz.h +149 -0
  22. data/dependencies/SDL/include/SDL_copying.h +20 -0
  23. data/dependencies/SDL/include/SDL_cpuinfo.h +299 -0
  24. data/dependencies/SDL/include/SDL_egl.h +1676 -0
  25. data/dependencies/SDL/include/SDL_endian.h +263 -0
  26. data/dependencies/SDL/include/SDL_error.h +112 -0
  27. data/dependencies/SDL/include/SDL_events.h +827 -0
  28. data/dependencies/SDL/include/SDL_filesystem.h +136 -0
  29. data/dependencies/SDL/include/SDL_gamecontroller.h +541 -0
  30. data/dependencies/SDL/include/SDL_gesture.h +87 -0
  31. data/dependencies/SDL/include/SDL_haptic.h +1247 -0
  32. data/dependencies/SDL/include/SDL_hints.h +1578 -0
  33. data/dependencies/SDL/include/SDL_joystick.h +499 -0
  34. data/dependencies/SDL/include/SDL_keyboard.h +217 -0
  35. data/dependencies/SDL/include/SDL_keycode.h +351 -0
  36. data/dependencies/SDL/include/SDL_loadso.h +81 -0
  37. data/dependencies/SDL/include/SDL_locale.h +101 -0
  38. data/dependencies/SDL/include/SDL_log.h +211 -0
  39. data/dependencies/SDL/include/SDL_main.h +180 -0
  40. data/dependencies/SDL/include/SDL_messagebox.h +146 -0
  41. data/dependencies/SDL/include/SDL_metal.h +117 -0
  42. data/dependencies/SDL/include/SDL_misc.h +75 -0
  43. data/dependencies/SDL/include/SDL_mouse.h +302 -0
  44. data/dependencies/SDL/include/SDL_mutex.h +251 -0
  45. data/dependencies/SDL/include/SDL_name.h +33 -0
  46. data/dependencies/SDL/include/SDL_opengl.h +2183 -0
  47. data/dependencies/SDL/include/SDL_opengl_glext.h +11180 -0
  48. data/dependencies/SDL/include/SDL_opengles.h +39 -0
  49. data/dependencies/SDL/include/SDL_opengles2.h +52 -0
  50. data/dependencies/SDL/include/SDL_opengles2_gl2.h +621 -0
  51. data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +2050 -0
  52. data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +30 -0
  53. data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +282 -0
  54. data/dependencies/SDL/include/SDL_pixels.h +479 -0
  55. data/dependencies/SDL/include/SDL_platform.h +198 -0
  56. data/dependencies/SDL/include/SDL_power.h +75 -0
  57. data/dependencies/SDL/include/SDL_quit.h +58 -0
  58. data/dependencies/SDL/include/SDL_rect.h +174 -0
  59. data/dependencies/SDL/include/SDL_render.h +1158 -0
  60. data/dependencies/SDL/include/SDL_revision.h +2 -0
  61. data/dependencies/SDL/include/SDL_rwops.h +283 -0
  62. data/dependencies/SDL/include/SDL_scancode.h +413 -0
  63. data/dependencies/SDL/include/SDL_sensor.h +267 -0
  64. data/dependencies/SDL/include/SDL_shape.h +144 -0
  65. data/dependencies/SDL/include/SDL_stdinc.h +647 -0
  66. data/dependencies/SDL/include/SDL_surface.h +563 -0
  67. data/dependencies/SDL/include/SDL_system.h +325 -0
  68. data/dependencies/SDL/include/SDL_syswm.h +354 -0
  69. data/dependencies/SDL/include/SDL_test.h +69 -0
  70. data/dependencies/SDL/include/SDL_test_assert.h +105 -0
  71. data/dependencies/SDL/include/SDL_test_common.h +218 -0
  72. data/dependencies/SDL/include/SDL_test_compare.h +69 -0
  73. data/dependencies/SDL/include/SDL_test_crc32.h +124 -0
  74. data/dependencies/SDL/include/SDL_test_font.h +81 -0
  75. data/dependencies/SDL/include/SDL_test_fuzzer.h +384 -0
  76. data/dependencies/SDL/include/SDL_test_harness.h +134 -0
  77. data/dependencies/SDL/include/SDL_test_images.h +78 -0
  78. data/dependencies/SDL/include/SDL_test_log.h +67 -0
  79. data/dependencies/SDL/include/SDL_test_md5.h +129 -0
  80. data/dependencies/SDL/include/SDL_test_memory.h +63 -0
  81. data/dependencies/SDL/include/SDL_test_random.h +115 -0
  82. data/dependencies/SDL/include/SDL_thread.h +366 -0
  83. data/dependencies/SDL/include/SDL_timer.h +115 -0
  84. data/dependencies/SDL/include/SDL_touch.h +102 -0
  85. data/dependencies/SDL/include/SDL_types.h +29 -0
  86. data/dependencies/SDL/include/SDL_version.h +162 -0
  87. data/dependencies/SDL/include/SDL_video.h +1282 -0
  88. data/dependencies/SDL/include/SDL_vulkan.h +276 -0
  89. data/dependencies/SDL/include/begin_code.h +166 -0
  90. data/dependencies/SDL/include/close_code.h +40 -0
  91. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  92. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  93. data/dependencies/SDL_sound/SDL_sound.c +795 -0
  94. data/dependencies/SDL_sound/SDL_sound.h +725 -0
  95. data/dependencies/SDL_sound/SDL_sound_aiff.c +537 -0
  96. data/dependencies/SDL_sound/SDL_sound_au.c +352 -0
  97. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +747 -0
  98. data/dependencies/SDL_sound/SDL_sound_flac.c +182 -0
  99. data/dependencies/SDL_sound/SDL_sound_internal.h +304 -0
  100. data/dependencies/SDL_sound/SDL_sound_modplug.c +228 -0
  101. data/dependencies/SDL_sound/SDL_sound_mp3.c +184 -0
  102. data/dependencies/SDL_sound/SDL_sound_raw.c +164 -0
  103. data/dependencies/SDL_sound/SDL_sound_shn.c +1309 -0
  104. data/dependencies/SDL_sound/SDL_sound_voc.c +550 -0
  105. data/dependencies/SDL_sound/SDL_sound_vorbis.c +223 -0
  106. data/dependencies/SDL_sound/SDL_sound_wav.c +783 -0
  107. data/dependencies/SDL_sound/dr_flac.h +5906 -0
  108. data/dependencies/SDL_sound/dr_mp3.h +2832 -0
  109. data/dependencies/SDL_sound/libmodplug/fastmix.c +1748 -0
  110. data/dependencies/SDL_sound/libmodplug/libmodplug.h +1001 -0
  111. data/dependencies/SDL_sound/libmodplug/load_669.c +188 -0
  112. data/dependencies/SDL_sound/libmodplug/load_abc.c +4725 -0
  113. data/dependencies/SDL_sound/libmodplug/load_amf.c +403 -0
  114. data/dependencies/SDL_sound/libmodplug/load_ams.c +587 -0
  115. data/dependencies/SDL_sound/libmodplug/load_dbm.c +357 -0
  116. data/dependencies/SDL_sound/libmodplug/load_dmf.c +531 -0
  117. data/dependencies/SDL_sound/libmodplug/load_dsm.c +232 -0
  118. data/dependencies/SDL_sound/libmodplug/load_far.c +253 -0
  119. data/dependencies/SDL_sound/libmodplug/load_it.c +796 -0
  120. data/dependencies/SDL_sound/libmodplug/load_mdl.c +488 -0
  121. data/dependencies/SDL_sound/libmodplug/load_med.c +757 -0
  122. data/dependencies/SDL_sound/libmodplug/load_mid.c +1405 -0
  123. data/dependencies/SDL_sound/libmodplug/load_mod.c +269 -0
  124. data/dependencies/SDL_sound/libmodplug/load_mt2.c +546 -0
  125. data/dependencies/SDL_sound/libmodplug/load_mtm.c +142 -0
  126. data/dependencies/SDL_sound/libmodplug/load_okt.c +192 -0
  127. data/dependencies/SDL_sound/libmodplug/load_pat.c +1143 -0
  128. data/dependencies/SDL_sound/libmodplug/load_pat.h +25 -0
  129. data/dependencies/SDL_sound/libmodplug/load_psm.c +350 -0
  130. data/dependencies/SDL_sound/libmodplug/load_ptm.c +204 -0
  131. data/dependencies/SDL_sound/libmodplug/load_s3m.c +325 -0
  132. data/dependencies/SDL_sound/libmodplug/load_stm.c +180 -0
  133. data/dependencies/SDL_sound/libmodplug/load_ult.c +206 -0
  134. data/dependencies/SDL_sound/libmodplug/load_umx.c +51 -0
  135. data/dependencies/SDL_sound/libmodplug/load_xm.c +554 -0
  136. data/dependencies/SDL_sound/libmodplug/mmcmp.c +382 -0
  137. data/dependencies/SDL_sound/libmodplug/modplug.c +170 -0
  138. data/dependencies/SDL_sound/libmodplug/modplug.h +90 -0
  139. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +301 -0
  140. data/dependencies/SDL_sound/libmodplug/snd_flt.c +63 -0
  141. data/dependencies/SDL_sound/libmodplug/snd_fx.c +2350 -0
  142. data/dependencies/SDL_sound/libmodplug/sndfile.c +1169 -0
  143. data/dependencies/SDL_sound/libmodplug/sndmix.c +1034 -0
  144. data/dependencies/SDL_sound/libmodplug/tables.h +371 -0
  145. data/{src/stb_vorbis.c → dependencies/SDL_sound/stb_vorbis.h} +143 -78
  146. data/dependencies/al_soft/AL/al.h +655 -0
  147. data/dependencies/al_soft/AL/alc.h +270 -0
  148. data/dependencies/al_soft/AL/alext.h +585 -0
  149. data/dependencies/al_soft/AL/efx-creative.h +3 -0
  150. data/dependencies/al_soft/AL/efx-presets.h +402 -0
  151. data/dependencies/al_soft/AL/efx.h +762 -0
  152. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  153. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  154. data/{src → dependencies/stb}/stb_image.h +330 -127
  155. data/{src → dependencies/stb}/stb_image_write.h +156 -85
  156. data/{src → dependencies/stb}/stb_truetype.h +192 -69
  157. data/{src → dependencies/utf8proc}/utf8proc.c +0 -0
  158. data/{src → dependencies/utf8proc}/utf8proc.h +0 -0
  159. data/{src → dependencies/utf8proc}/utf8proc_data.h +0 -0
  160. data/ext/gosu/extconf.rb +53 -39
  161. data/{Gosu → include/Gosu}/Audio.hpp +6 -8
  162. data/include/Gosu/Bitmap.hpp +100 -0
  163. data/{Gosu → include/Gosu}/Buttons.hpp +104 -44
  164. data/{Gosu → include/Gosu}/Color.hpp +0 -0
  165. data/{Gosu → include/Gosu}/Directories.hpp +0 -0
  166. data/{Gosu → include/Gosu}/Font.hpp +1 -1
  167. data/{Gosu → include/Gosu}/Fwd.hpp +0 -5
  168. data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
  169. data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
  170. data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
  171. data/{Gosu → include/Gosu}/IO.hpp +0 -0
  172. data/{Gosu → include/Gosu}/Image.hpp +7 -6
  173. data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
  174. data/{Gosu → include/Gosu}/Input.hpp +39 -51
  175. data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
  176. data/{Gosu → include/Gosu}/Math.hpp +0 -0
  177. data/{Gosu → include/Gosu}/Platform.hpp +0 -0
  178. data/{Gosu → include/Gosu}/Text.hpp +0 -0
  179. data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
  180. data/{Gosu → include/Gosu}/Timing.hpp +0 -0
  181. data/{Gosu → include/Gosu}/Utility.hpp +15 -4
  182. data/{Gosu → include/Gosu}/Version.hpp +3 -3
  183. data/{Gosu → include/Gosu}/Window.hpp +46 -34
  184. data/lib/OpenAL32.dll +0 -0
  185. data/lib/SDL2.dll +0 -0
  186. data/lib/gosu.rb +0 -3
  187. data/lib/gosu/patches.rb +0 -23
  188. data/lib/gosu/preview.rb +1 -3
  189. data/lib/gosu/swig_patches.rb +6 -8
  190. data/lib64/OpenAL32.dll +0 -0
  191. data/lib64/SDL2.dll +0 -0
  192. data/rdoc/gosu.rb +112 -23
  193. data/src/Audio.cpp +50 -224
  194. data/src/AudioFile.hpp +20 -37
  195. data/src/AudioFileAudioToolbox.cpp +237 -0
  196. data/src/AudioFileSDLSound.cpp +147 -0
  197. data/src/AudioImpl.cpp +3 -12
  198. data/src/AudioImpl.hpp +3 -1
  199. data/src/Bitmap.cpp +85 -83
  200. data/src/BitmapIO.cpp +52 -58
  201. data/src/Font.cpp +4 -1
  202. data/src/Graphics.cpp +7 -4
  203. data/src/Image.cpp +13 -16
  204. data/src/Input.cpp +412 -164
  205. data/src/LargeImageData.cpp +2 -1
  206. data/src/MarkupParser.cpp +2 -1
  207. data/src/Resolution.cpp +8 -8
  208. data/src/RubyGosu.cxx +1184 -352
  209. data/src/RubyGosu.h +3 -2
  210. data/src/TexChunk.cpp +1 -1
  211. data/src/Text.cpp +1 -0
  212. data/src/TextBuilder.cpp +3 -1
  213. data/src/Texture.cpp +1 -1
  214. data/src/TrueTypeFont.cpp +2 -1
  215. data/src/TrueTypeFontWin.cpp +3 -3
  216. data/src/Utility.cpp +11 -7
  217. data/src/Window.cpp +90 -62
  218. data/src/WindowUIKit.cpp +21 -9
  219. metadata +195 -46
  220. data/Gosu/AutoLink.hpp +0 -14
  221. data/Gosu/Bitmap.hpp +0 -113
  222. data/lib/gosu/zen.rb +0 -89
  223. data/src/AudioToolboxFile.hpp +0 -210
  224. data/src/MPEGFile.hpp +0 -90
  225. data/src/OggFile.hpp +0 -92
  226. data/src/SndFile.hpp +0 -174
  227. data/src/WinMain.cpp +0 -64
@@ -0,0 +1,1748 @@
1
+ /*
2
+ * This source code is public domain.
3
+ *
4
+ * Authors: Olivier Lapicque <olivierl@jps.net>
5
+ * Markus Fick <webmaster@mark-f.de> spline + fir-resampler
6
+ */
7
+
8
+ #include "libmodplug.h"
9
+ #include <math.h>
10
+
11
+ // 4x256 taps polyphase FIR resampling filter
12
+ extern short int gFastSinc[];
13
+ extern short int gKaiserSinc[]; // 8-taps polyphase
14
+ /*
15
+ *-----------------------------------------------------------------------------
16
+ cubic spline interpolation doc,
17
+ (derived from "digital image warping", g. wolberg)
18
+
19
+ interpolation polynomial: f(x) = A3*(x-floor(x))**3 + A2*(x-floor(x))**2 +
20
+ A1*(x-floor(x)) + A0
21
+
22
+ with Y = equispaced data points (dist=1), YD = first derivates of data points and IP = floor(x)
23
+ the A[0..3] can be found by solving
24
+ A0 = Y[IP]
25
+ A1 = YD[IP]
26
+ A2 = 3*(Y[IP+1]-Y[IP])-2.0*YD[IP]-YD[IP+1]
27
+ A3 = -2.0 * (Y[IP+1]-Y[IP]) + YD[IP] - YD[IP+1]
28
+
29
+ with the first derivates as
30
+ YD[IP] = 0.5 * (Y[IP+1] - Y[IP-1]);
31
+ YD[IP+1] = 0.5 * (Y[IP+2] - Y[IP])
32
+
33
+ the coefs becomes
34
+ A0 = Y[IP]
35
+ A1 = YD[IP]
36
+ = 0.5*(Y[IP+1] - Y[IP-1]);
37
+ A2 = 3.0*(Y[IP+1]-Y[IP])-2.0*YD[IP]-YD[IP+1]
38
+ = 3.0*(Y[IP+1]-Y[IP]) - 0.5*2.0*(Y[IP+1]-Y[IP-1]) - 0.5*(Y[IP+2]-Y[IP])
39
+ = 3.0*Y[IP+1] - 3.0*Y[IP] - Y[IP+1] + Y[IP-1] - 0.5*Y[IP+2] + 0.5*Y[IP]
40
+ = -0.5*Y[IP+2] + 2.0 * Y[IP+1] - 2.5*Y[IP] + Y[IP-1]
41
+ = Y[IP-1] + 2 * Y[IP+1] - 0.5 * (5.0 * Y[IP] + Y[IP+2])
42
+ A3 = -2.0*(Y[IP+1]-Y[IP]) + YD[IP] + YD[IP+1]
43
+ = -2.0*Y[IP+1] + 2.0*Y[IP] + 0.5*(Y[IP+1]-Y[IP-1]) + 0.5*(Y[IP+2]-Y[IP])
44
+ = -2.0*Y[IP+1] + 2.0*Y[IP] + 0.5*Y[IP+1] - 0.5*Y[IP-1] + 0.5*Y[IP+2] - 0.5*Y[IP]
45
+ = 0.5 * Y[IP+2] - 1.5 * Y[IP+1] + 1.5 * Y[IP] - 0.5 * Y[IP-1]
46
+ = 0.5 * (3.0 * (Y[IP] - Y[IP+1]) - Y[IP-1] + YP[IP+2])
47
+
48
+ then interpolated data value is (horner rule)
49
+ out = (((A3*x)+A2)*x+A1)*x+A0
50
+
51
+ this gives parts of data points Y[IP-1] to Y[IP+2] of
52
+ part x**3 x**2 x**1 x**0
53
+ Y[IP-1] -0.5 1 -0.5 0
54
+ Y[IP] 1.5 -2.5 0 1
55
+ Y[IP+1] -1.5 2 0.5 0
56
+ Y[IP+2] 0.5 -0.5 0 0
57
+ *---------------------------------------------------------------------------
58
+ */
59
+ // number of bits used to scale spline coefs
60
+ #define SPLINE_QUANTBITS 14
61
+ #define SPLINE_QUANTSCALE (1L<<SPLINE_QUANTBITS)
62
+ #define SPLINE_8SHIFT (SPLINE_QUANTBITS-8)
63
+ #define SPLINE_16SHIFT (SPLINE_QUANTBITS)
64
+ // forces coefsset to unity gain
65
+ #define SPLINE_CLAMPFORUNITY
66
+ // log2(number) of precalculated splines (range is [4..14])
67
+ #define SPLINE_FRACBITS 10
68
+ #define SPLINE_LUTLEN (1L<<SPLINE_FRACBITS)
69
+
70
+ signed short CzCUBICSPLINE_lut[4*(1L<<SPLINE_FRACBITS)];
71
+
72
+ static void initCzCUBICSPLINE()
73
+ {
74
+ int _LIi;
75
+ int _LLen = (1L<<SPLINE_FRACBITS);
76
+ float _LFlen = 1.0f / (float)_LLen;
77
+ float _LScale = (float)SPLINE_QUANTSCALE;
78
+ for(_LIi=0;_LIi<_LLen;_LIi++)
79
+ { float _LCm1, _LC0, _LC1, _LC2;
80
+ float _LX = ((float)_LIi)*_LFlen;
81
+ int _LSum,_LIdx = _LIi<<2;
82
+ _LCm1 = (float)floor( 0.5 + _LScale*(-0.5*_LX*_LX*_LX + 1.0*_LX*_LX - 0.5*_LX ) );
83
+ _LC0 = (float)floor( 0.5 + _LScale*( 1.5*_LX*_LX*_LX - 2.5*_LX*_LX + 1.0 ) );
84
+ _LC1 = (float)floor( 0.5 + _LScale*(-1.5*_LX*_LX*_LX + 2.0*_LX*_LX + 0.5*_LX ) );
85
+ _LC2 = (float)floor( 0.5 + _LScale*( 0.5*_LX*_LX*_LX - 0.5*_LX*_LX) );
86
+ CzCUBICSPLINE_lut[_LIdx+0] = (signed short)( (_LCm1 < -_LScale) ? -_LScale : ((_LCm1 > _LScale) ? _LScale : _LCm1) );
87
+ CzCUBICSPLINE_lut[_LIdx+1] = (signed short)( (_LC0 < -_LScale) ? -_LScale : ((_LC0 > _LScale) ? _LScale : _LC0 ) );
88
+ CzCUBICSPLINE_lut[_LIdx+2] = (signed short)( (_LC1 < -_LScale) ? -_LScale : ((_LC1 > _LScale) ? _LScale : _LC1 ) );
89
+ CzCUBICSPLINE_lut[_LIdx+3] = (signed short)( (_LC2 < -_LScale) ? -_LScale : ((_LC2 > _LScale) ? _LScale : _LC2 ) );
90
+ #ifdef SPLINE_CLAMPFORUNITY
91
+ _LSum = CzCUBICSPLINE_lut[_LIdx+0]+CzCUBICSPLINE_lut[_LIdx+1]+CzCUBICSPLINE_lut[_LIdx+2]+CzCUBICSPLINE_lut[_LIdx+3];
92
+ if( _LSum != SPLINE_QUANTSCALE )
93
+ { int _LMax = _LIdx;
94
+ if( CzCUBICSPLINE_lut[_LIdx+1]>CzCUBICSPLINE_lut[_LMax] ) _LMax = _LIdx+1;
95
+ if( CzCUBICSPLINE_lut[_LIdx+2]>CzCUBICSPLINE_lut[_LMax] ) _LMax = _LIdx+2;
96
+ if( CzCUBICSPLINE_lut[_LIdx+3]>CzCUBICSPLINE_lut[_LMax] ) _LMax = _LIdx+3;
97
+ CzCUBICSPLINE_lut[_LMax] += ((signed short)SPLINE_QUANTSCALE-_LSum);
98
+ }
99
+ #endif
100
+ }
101
+ }
102
+
103
+ /*
104
+ ------------------------------------------------------------------------------
105
+ fir interpolation doc,
106
+ (derived from "an engineer's guide to fir digital filters", n.j. loy)
107
+
108
+ calculate coefficients for ideal lowpass filter (with cutoff = fc in
109
+ 0..1 (mapped to 0..nyquist))
110
+ c[-N..N] = (i==0) ? fc : SDL_sin(fc*pi*i)/(pi*i)
111
+
112
+ then apply selected window to coefficients
113
+ c[-N..N] *= w(0..N)
114
+ with n in 2*N and w(n) being a window function (see loy)
115
+
116
+ then calculate gain and scale filter coefs to have unity gain.
117
+ ------------------------------------------------------------------------------
118
+ */
119
+ // quantizer scale of window coefs
120
+ #define WFIR_QUANTBITS 15
121
+ #define WFIR_QUANTSCALE (1L<<WFIR_QUANTBITS)
122
+ #define WFIR_8SHIFT (WFIR_QUANTBITS-8)
123
+ #define WFIR_16BITSHIFT (WFIR_QUANTBITS)
124
+ // log2(number)-1 of precalculated taps range is [4..12]
125
+ #define WFIR_FRACBITS 10
126
+ #define WFIR_LUTLEN ((1L<<(WFIR_FRACBITS+1))+1)
127
+ // number of samples in window
128
+ #define WFIR_LOG2WIDTH 3
129
+ #define WFIR_WIDTH (1L<<WFIR_LOG2WIDTH)
130
+ #define WFIR_SMPSPERWING ((WFIR_WIDTH-1)>>1)
131
+ // cutoff (1.0 == pi/2)
132
+ #define WFIR_CUTOFF 0.90f
133
+ // wfir type
134
+ #define WFIR_HANN 0
135
+ #define WFIR_HAMMING 1
136
+ #define WFIR_BLACKMANEXACT 2
137
+ #define WFIR_BLACKMAN3T61 3
138
+ #define WFIR_BLACKMAN3T67 4
139
+ #define WFIR_BLACKMAN4T92 5
140
+ #define WFIR_BLACKMAN4T74 6
141
+ #define WFIR_KAISER4T 7
142
+ #define WFIR_TYPE WFIR_BLACKMANEXACT
143
+ // wfir help
144
+ #ifndef M_zPI
145
+ #define M_zPI 3.1415926535897932384626433832795
146
+ #endif
147
+ #define M_zEPS 1e-8
148
+ #define M_zBESSELEPS 1e-21
149
+
150
+ static float CzWINDOWEDFIR_coef( int _PCnr, float _POfs, float _PCut, int _PWidth, int _PType )
151
+ //OLD args to coef: float _PPos, float _PFc, int _PLen )
152
+ {
153
+ double _LWidthM1 = _PWidth-1;
154
+ double _LWidthM1Half = 0.5*_LWidthM1;
155
+ double _LPosU = ((double)_PCnr - _POfs);
156
+ double _LPos = _LPosU-_LWidthM1Half;
157
+ double _LPIdl = 2.0*M_zPI/_LWidthM1;
158
+ double _LWc,_LSi;
159
+ if( SDL_fabs(_LPos)<M_zEPS ) {
160
+ _LWc = 1.0;
161
+ _LSi = _PCut;
162
+ } else {
163
+ switch( _PType )
164
+ {
165
+ case WFIR_HANN:
166
+ _LWc = 0.50 - 0.50 * SDL_cos(_LPIdl*_LPosU);
167
+ break;
168
+ case WFIR_HAMMING:
169
+ _LWc = 0.54 - 0.46 * SDL_cos(_LPIdl*_LPosU);
170
+ break;
171
+ case WFIR_BLACKMANEXACT:
172
+ _LWc = 0.42 - 0.50 * SDL_cos(_LPIdl*_LPosU) +
173
+ 0.08 * SDL_cos(2.0*_LPIdl*_LPosU);
174
+ break;
175
+ case WFIR_BLACKMAN3T61:
176
+ _LWc = 0.44959 - 0.49364 * SDL_cos(_LPIdl*_LPosU) +
177
+ 0.05677 * SDL_cos(2.0*_LPIdl*_LPosU);
178
+ break;
179
+ case WFIR_BLACKMAN3T67:
180
+ _LWc = 0.42323 - 0.49755 * SDL_cos(_LPIdl*_LPosU) +
181
+ 0.07922 * SDL_cos(2.0*_LPIdl*_LPosU);
182
+ break;
183
+ case WFIR_BLACKMAN4T92:
184
+ _LWc = 0.35875 - 0.48829 * SDL_cos(_LPIdl*_LPosU) +
185
+ 0.14128 * SDL_cos(2.0*_LPIdl*_LPosU) -
186
+ 0.01168 * SDL_cos(3.0*_LPIdl*_LPosU);
187
+ break;
188
+ case WFIR_BLACKMAN4T74:
189
+ _LWc = 0.40217 - 0.49703 * SDL_cos(_LPIdl*_LPosU) +
190
+ 0.09392 * SDL_cos(2.0*_LPIdl*_LPosU) -
191
+ 0.00183 * SDL_cos(3.0*_LPIdl*_LPosU);
192
+ break;
193
+ case WFIR_KAISER4T:
194
+ _LWc = 0.40243 - 0.49804 * SDL_cos(_LPIdl*_LPosU) +
195
+ 0.09831 * SDL_cos(2.0*_LPIdl*_LPosU) -
196
+ 0.00122 * SDL_cos(3.0*_LPIdl*_LPosU);
197
+ break;
198
+ default:
199
+ _LWc = 1.0;
200
+ break;
201
+ }
202
+ _LPos *= M_zPI;
203
+ _LSi = SDL_sin(_PCut*_LPos)/_LPos;
204
+ }
205
+ return (float)(_LWc*_LSi);
206
+ }
207
+
208
+ static signed short CzWINDOWEDFIR_lut[WFIR_LUTLEN*WFIR_WIDTH];
209
+
210
+ static void initCzWINDOWEDFIR()
211
+ {
212
+ int _LPcl;
213
+ float _LPcllen = (float)(1L<<WFIR_FRACBITS); // number of precalculated lines for 0..1 (-1..0)
214
+ float _LNorm = 1.0f / (float)(2.0f * _LPcllen);
215
+ float _LCut = WFIR_CUTOFF;
216
+ float _LScale = (float)WFIR_QUANTSCALE;
217
+ for( _LPcl=0;_LPcl<WFIR_LUTLEN;_LPcl++ )
218
+ {
219
+ float _LGain,_LCoefs[WFIR_WIDTH];
220
+ float _LOfs = ((float)_LPcl-_LPcllen)*_LNorm;
221
+ int _LCc,_LIdx = _LPcl<<WFIR_LOG2WIDTH;
222
+ for( _LCc=0,_LGain=0.0f;_LCc<WFIR_WIDTH;_LCc++ )
223
+ { _LGain += (_LCoefs[_LCc] = CzWINDOWEDFIR_coef( _LCc, _LOfs, _LCut, WFIR_WIDTH, WFIR_TYPE ));
224
+ }
225
+ _LGain = 1.0f/_LGain;
226
+ for( _LCc=0;_LCc<WFIR_WIDTH;_LCc++ )
227
+ { float _LCoef = (float)floor( 0.5 + _LScale*_LCoefs[_LCc]*_LGain );
228
+ CzWINDOWEDFIR_lut[_LIdx+_LCc] = (signed short)( (_LCoef<-_LScale)?-_LScale:((_LCoef>_LScale)?_LScale:_LCoef) );
229
+ }
230
+ }
231
+ }
232
+
233
+ void init_modplug_filters(void)
234
+ {
235
+ static int inited_filters = 0;
236
+ if (inited_filters) return;
237
+ inited_filters = 1;
238
+ initCzCUBICSPLINE();
239
+ initCzWINDOWEDFIR();
240
+ }
241
+
242
+ // ----------------------------------------------------------------------------
243
+ // MIXING MACROS
244
+ // ----------------------------------------------------------------------------
245
+ #define SNDMIX_BEGINSAMPLELOOP8\
246
+ register MODCHANNEL * const pChn = pChannel;\
247
+ nPos = pChn->nPosLo;\
248
+ const signed char *p = (signed char *)(pChn->pCurrentSample+pChn->nPos);\
249
+ if (pChn->dwFlags & CHN_STEREO) p += pChn->nPos;\
250
+ int *pvol = pbuffer;\
251
+ do {
252
+
253
+ #define SNDMIX_BEGINSAMPLELOOP16\
254
+ register MODCHANNEL * const pChn = pChannel;\
255
+ nPos = pChn->nPosLo;\
256
+ const signed short *p = (signed short *)(pChn->pCurrentSample+(pChn->nPos*2));\
257
+ if (pChn->dwFlags & CHN_STEREO) p += pChn->nPos;\
258
+ int *pvol = pbuffer;\
259
+ do {
260
+
261
+ #define SNDMIX_ENDSAMPLELOOP\
262
+ nPos += pChn->nInc;\
263
+ } while (pvol < pbufmax);\
264
+ pChn->nPos += nPos >> 16;\
265
+ pChn->nPosLo = nPos & 0xFFFF;
266
+
267
+ #define SNDMIX_ENDSAMPLELOOP8 SNDMIX_ENDSAMPLELOOP
268
+ #define SNDMIX_ENDSAMPLELOOP16 SNDMIX_ENDSAMPLELOOP
269
+
270
+ //////////////////////////////////////////////////////////////////////////////
271
+ // Mono
272
+
273
+ // No interpolation
274
+ #define SNDMIX_GETMONOVOL8NOIDO\
275
+ int vol = p[nPos >> 16] << 8;
276
+
277
+ #define SNDMIX_GETMONOVOL16NOIDO\
278
+ int vol = p[nPos >> 16];
279
+
280
+ // Linear Interpolation
281
+ #define SNDMIX_GETMONOVOL8LINEAR\
282
+ int poshi = nPos >> 16;\
283
+ int poslo = (nPos >> 8) & 0xFF;\
284
+ int srcvol = p[poshi];\
285
+ int destvol = p[poshi+1];\
286
+ int vol = (srcvol<<8) + ((int)(poslo * (destvol - srcvol)));
287
+
288
+ #define SNDMIX_GETMONOVOL16LINEAR\
289
+ int poshi = nPos >> 16;\
290
+ int poslo = (nPos >> 8) & 0xFF;\
291
+ int srcvol = p[poshi];\
292
+ int destvol = p[poshi+1];\
293
+ int vol = srcvol + ((int)(poslo * (destvol - srcvol)) >> 8);
294
+
295
+ // spline interpolation (2 guard bits should be enough???)
296
+ #define SPLINE_FRACSHIFT ((16-SPLINE_FRACBITS)-2)
297
+ #define SPLINE_FRACMASK (((1L<<(16-SPLINE_FRACSHIFT))-1)&~3)
298
+
299
+ #define SNDMIX_GETMONOVOL8SPLINE \
300
+ int poshi = nPos >> 16; \
301
+ int poslo = (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
302
+ int vol = (CzCUBICSPLINE_lut[poslo ]*(int)p[poshi-1] + \
303
+ CzCUBICSPLINE_lut[poslo+1]*(int)p[poshi ] + \
304
+ CzCUBICSPLINE_lut[poslo+3]*(int)p[poshi+2] + \
305
+ CzCUBICSPLINE_lut[poslo+2]*(int)p[poshi+1]) >> SPLINE_8SHIFT;
306
+
307
+ #define SNDMIX_GETMONOVOL16SPLINE \
308
+ int poshi = nPos >> 16; \
309
+ int poslo = (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
310
+ int vol = (CzCUBICSPLINE_lut[poslo ]*(int)p[poshi-1] + \
311
+ CzCUBICSPLINE_lut[poslo+1]*(int)p[poshi ] + \
312
+ CzCUBICSPLINE_lut[poslo+3]*(int)p[poshi+2] + \
313
+ CzCUBICSPLINE_lut[poslo+2]*(int)p[poshi+1]) >> SPLINE_16SHIFT;
314
+
315
+
316
+ // fir interpolation
317
+ #define WFIR_FRACSHIFT (16-(WFIR_FRACBITS+1+WFIR_LOG2WIDTH))
318
+ #define WFIR_FRACMASK ((((1L<<(17-WFIR_FRACSHIFT))-1)&~((1L<<WFIR_LOG2WIDTH)-1)))
319
+ #define WFIR_FRACHALVE (1L<<(16-(WFIR_FRACBITS+2)))
320
+
321
+ #define SNDMIX_GETMONOVOL8FIRFILTER \
322
+ int poshi = nPos >> 16;\
323
+ int poslo = (nPos & 0xFFFF);\
324
+ int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
325
+ int vol = (CzWINDOWEDFIR_lut[firidx+0]*(int)p[poshi+1-4]); \
326
+ vol += (CzWINDOWEDFIR_lut[firidx+1]*(int)p[poshi+2-4]); \
327
+ vol += (CzWINDOWEDFIR_lut[firidx+2]*(int)p[poshi+3-4]); \
328
+ vol += (CzWINDOWEDFIR_lut[firidx+3]*(int)p[poshi+4-4]); \
329
+ vol += (CzWINDOWEDFIR_lut[firidx+4]*(int)p[poshi+5-4]); \
330
+ vol += (CzWINDOWEDFIR_lut[firidx+5]*(int)p[poshi+6-4]); \
331
+ vol += (CzWINDOWEDFIR_lut[firidx+6]*(int)p[poshi+7-4]); \
332
+ vol += (CzWINDOWEDFIR_lut[firidx+7]*(int)p[poshi+8-4]); \
333
+ vol >>= WFIR_8SHIFT;
334
+
335
+ #define SNDMIX_GETMONOVOL16FIRFILTER \
336
+ int poshi = nPos >> 16;\
337
+ int poslo = (nPos & 0xFFFF);\
338
+ int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
339
+ int vol1 = (CzWINDOWEDFIR_lut[firidx+0]*(int)p[poshi+1-4]); \
340
+ vol1 += (CzWINDOWEDFIR_lut[firidx+1]*(int)p[poshi+2-4]); \
341
+ vol1 += (CzWINDOWEDFIR_lut[firidx+2]*(int)p[poshi+3-4]); \
342
+ vol1 += (CzWINDOWEDFIR_lut[firidx+3]*(int)p[poshi+4-4]); \
343
+ int vol2 = (CzWINDOWEDFIR_lut[firidx+4]*(int)p[poshi+5-4]); \
344
+ vol2 += (CzWINDOWEDFIR_lut[firidx+5]*(int)p[poshi+6-4]); \
345
+ vol2 += (CzWINDOWEDFIR_lut[firidx+6]*(int)p[poshi+7-4]); \
346
+ vol2 += (CzWINDOWEDFIR_lut[firidx+7]*(int)p[poshi+8-4]); \
347
+ int vol = ((vol1>>1)+(vol2>>1)) >> (WFIR_16BITSHIFT-1);
348
+
349
+ /////////////////////////////////////////////////////////////////////////////
350
+ // Stereo
351
+
352
+ // No interpolation
353
+ #define SNDMIX_GETSTEREOVOL8NOIDO\
354
+ int vol_l = p[(nPos>>16)*2] << 8;\
355
+ int vol_r = p[(nPos>>16)*2+1] << 8;
356
+
357
+ #define SNDMIX_GETSTEREOVOL16NOIDO\
358
+ int vol_l = p[(nPos>>16)*2];\
359
+ int vol_r = p[(nPos>>16)*2+1];
360
+
361
+ // Linear Interpolation
362
+ #define SNDMIX_GETSTEREOVOL8LINEAR\
363
+ int poshi = nPos >> 16;\
364
+ int poslo = (nPos >> 8) & 0xFF;\
365
+ int srcvol_l = p[poshi*2];\
366
+ int vol_l = (srcvol_l<<8) + ((int)(poslo * (p[poshi*2+2] - srcvol_l)));\
367
+ int srcvol_r = p[poshi*2+1];\
368
+ int vol_r = (srcvol_r<<8) + ((int)(poslo * (p[poshi*2+3] - srcvol_r)));
369
+
370
+ #define SNDMIX_GETSTEREOVOL16LINEAR\
371
+ int poshi = nPos >> 16;\
372
+ int poslo = (nPos >> 8) & 0xFF;\
373
+ int srcvol_l = p[poshi*2];\
374
+ int vol_l = srcvol_l + ((int)(poslo * (p[poshi*2+2] - srcvol_l)) >> 8);\
375
+ int srcvol_r = p[poshi*2+1];\
376
+ int vol_r = srcvol_r + ((int)(poslo * (p[poshi*2+3] - srcvol_r)) >> 8);\
377
+
378
+ // Spline Interpolation
379
+ #define SNDMIX_GETSTEREOVOL8SPLINE \
380
+ int poshi = nPos >> 16; \
381
+ int poslo = (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
382
+ int vol_l = (CzCUBICSPLINE_lut[poslo ]*(int)p[(poshi-1)*2 ] + \
383
+ CzCUBICSPLINE_lut[poslo+1]*(int)p[(poshi )*2 ] + \
384
+ CzCUBICSPLINE_lut[poslo+2]*(int)p[(poshi+1)*2 ] + \
385
+ CzCUBICSPLINE_lut[poslo+3]*(int)p[(poshi+2)*2 ]) >> SPLINE_8SHIFT; \
386
+ int vol_r = (CzCUBICSPLINE_lut[poslo ]*(int)p[(poshi-1)*2+1] + \
387
+ CzCUBICSPLINE_lut[poslo+1]*(int)p[(poshi )*2+1] + \
388
+ CzCUBICSPLINE_lut[poslo+2]*(int)p[(poshi+1)*2+1] + \
389
+ CzCUBICSPLINE_lut[poslo+3]*(int)p[(poshi+2)*2+1]) >> SPLINE_8SHIFT;
390
+
391
+ #define SNDMIX_GETSTEREOVOL16SPLINE \
392
+ int poshi = nPos >> 16; \
393
+ int poslo = (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
394
+ int vol_l = (CzCUBICSPLINE_lut[poslo ]*(int)p[(poshi-1)*2 ] + \
395
+ CzCUBICSPLINE_lut[poslo+1]*(int)p[(poshi )*2 ] + \
396
+ CzCUBICSPLINE_lut[poslo+2]*(int)p[(poshi+1)*2 ] + \
397
+ CzCUBICSPLINE_lut[poslo+3]*(int)p[(poshi+2)*2 ]) >> SPLINE_16SHIFT; \
398
+ int vol_r = (CzCUBICSPLINE_lut[poslo ]*(int)p[(poshi-1)*2+1] + \
399
+ CzCUBICSPLINE_lut[poslo+1]*(int)p[(poshi )*2+1] + \
400
+ CzCUBICSPLINE_lut[poslo+2]*(int)p[(poshi+1)*2+1] + \
401
+ CzCUBICSPLINE_lut[poslo+3]*(int)p[(poshi+2)*2+1]) >> SPLINE_16SHIFT;
402
+
403
+ // fir interpolation
404
+ #define SNDMIX_GETSTEREOVOL8FIRFILTER \
405
+ int poshi = nPos >> 16;\
406
+ int poslo = (nPos & 0xFFFF);\
407
+ int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
408
+ int vol_l = (CzWINDOWEDFIR_lut[firidx+0]*(int)p[(poshi+1-4)*2 ]); \
409
+ vol_l += (CzWINDOWEDFIR_lut[firidx+1]*(int)p[(poshi+2-4)*2 ]); \
410
+ vol_l += (CzWINDOWEDFIR_lut[firidx+2]*(int)p[(poshi+3-4)*2 ]); \
411
+ vol_l += (CzWINDOWEDFIR_lut[firidx+3]*(int)p[(poshi+4-4)*2 ]); \
412
+ vol_l += (CzWINDOWEDFIR_lut[firidx+4]*(int)p[(poshi+5-4)*2 ]); \
413
+ vol_l += (CzWINDOWEDFIR_lut[firidx+5]*(int)p[(poshi+6-4)*2 ]); \
414
+ vol_l += (CzWINDOWEDFIR_lut[firidx+6]*(int)p[(poshi+7-4)*2 ]); \
415
+ vol_l += (CzWINDOWEDFIR_lut[firidx+7]*(int)p[(poshi+8-4)*2 ]); \
416
+ vol_l >>= WFIR_8SHIFT; \
417
+ int vol_r = (CzWINDOWEDFIR_lut[firidx+0]*(int)p[(poshi+1-4)*2+1]); \
418
+ vol_r += (CzWINDOWEDFIR_lut[firidx+1]*(int)p[(poshi+2-4)*2+1]); \
419
+ vol_r += (CzWINDOWEDFIR_lut[firidx+2]*(int)p[(poshi+3-4)*2+1]); \
420
+ vol_r += (CzWINDOWEDFIR_lut[firidx+3]*(int)p[(poshi+4-4)*2+1]); \
421
+ vol_r += (CzWINDOWEDFIR_lut[firidx+4]*(int)p[(poshi+5-4)*2+1]); \
422
+ vol_r += (CzWINDOWEDFIR_lut[firidx+5]*(int)p[(poshi+6-4)*2+1]); \
423
+ vol_r += (CzWINDOWEDFIR_lut[firidx+6]*(int)p[(poshi+7-4)*2+1]); \
424
+ vol_r += (CzWINDOWEDFIR_lut[firidx+7]*(int)p[(poshi+8-4)*2+1]); \
425
+ vol_r >>= WFIR_8SHIFT;
426
+
427
+ #define SNDMIX_GETSTEREOVOL16FIRFILTER \
428
+ int poshi = nPos >> 16;\
429
+ int poslo = (nPos & 0xFFFF);\
430
+ int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
431
+ int vol1_l = (CzWINDOWEDFIR_lut[firidx+0]*(int)p[(poshi+1-4)*2 ]); \
432
+ vol1_l += (CzWINDOWEDFIR_lut[firidx+1]*(int)p[(poshi+2-4)*2 ]); \
433
+ vol1_l += (CzWINDOWEDFIR_lut[firidx+2]*(int)p[(poshi+3-4)*2 ]); \
434
+ vol1_l += (CzWINDOWEDFIR_lut[firidx+3]*(int)p[(poshi+4-4)*2 ]); \
435
+ int vol2_l = (CzWINDOWEDFIR_lut[firidx+4]*(int)p[(poshi+5-4)*2 ]); \
436
+ vol2_l += (CzWINDOWEDFIR_lut[firidx+5]*(int)p[(poshi+6-4)*2 ]); \
437
+ vol2_l += (CzWINDOWEDFIR_lut[firidx+6]*(int)p[(poshi+7-4)*2 ]); \
438
+ vol2_l += (CzWINDOWEDFIR_lut[firidx+7]*(int)p[(poshi+8-4)*2 ]); \
439
+ int vol_l = ((vol1_l>>1)+(vol2_l>>1)) >> (WFIR_16BITSHIFT-1); \
440
+ int vol1_r = (CzWINDOWEDFIR_lut[firidx+0]*(int)p[(poshi+1-4)*2+1]); \
441
+ vol1_r += (CzWINDOWEDFIR_lut[firidx+1]*(int)p[(poshi+2-4)*2+1]); \
442
+ vol1_r += (CzWINDOWEDFIR_lut[firidx+2]*(int)p[(poshi+3-4)*2+1]); \
443
+ vol1_r += (CzWINDOWEDFIR_lut[firidx+3]*(int)p[(poshi+4-4)*2+1]); \
444
+ int vol2_r = (CzWINDOWEDFIR_lut[firidx+4]*(int)p[(poshi+5-4)*2+1]); \
445
+ vol2_r += (CzWINDOWEDFIR_lut[firidx+5]*(int)p[(poshi+6-4)*2+1]); \
446
+ vol2_r += (CzWINDOWEDFIR_lut[firidx+6]*(int)p[(poshi+7-4)*2+1]); \
447
+ vol2_r += (CzWINDOWEDFIR_lut[firidx+7]*(int)p[(poshi+8-4)*2+1]); \
448
+ int vol_r = ((vol1_r>>1)+(vol2_r>>1)) >> (WFIR_16BITSHIFT-1);
449
+
450
+ /////////////////////////////////////////////////////////////////////////////
451
+
452
+ #define SNDMIX_STOREMONOVOL\
453
+ pvol[0] += vol * pChn->nRightVol;\
454
+ pvol[1] += vol * pChn->nLeftVol;\
455
+ pvol += 2;
456
+
457
+ #define SNDMIX_STORESTEREOVOL\
458
+ pvol[0] += vol_l * pChn->nRightVol;\
459
+ pvol[1] += vol_r * pChn->nLeftVol;\
460
+ pvol += 2;
461
+
462
+ #define SNDMIX_STOREFASTMONOVOL\
463
+ int v = vol * pChn->nRightVol;\
464
+ pvol[0] += v;\
465
+ pvol[1] += v;\
466
+ pvol += 2;
467
+
468
+ #define SNDMIX_RAMPMONOVOL\
469
+ nRampLeftVol += pChn->nLeftRamp;\
470
+ nRampRightVol += pChn->nRightRamp;\
471
+ pvol[0] += vol * (nRampRightVol >> VOLUMERAMPPRECISION);\
472
+ pvol[1] += vol * (nRampLeftVol >> VOLUMERAMPPRECISION);\
473
+ pvol += 2;
474
+
475
+ #define SNDMIX_RAMPFASTMONOVOL\
476
+ nRampRightVol += pChn->nRightRamp;\
477
+ int fastvol = vol * (nRampRightVol >> VOLUMERAMPPRECISION);\
478
+ pvol[0] += fastvol;\
479
+ pvol[1] += fastvol;\
480
+ pvol += 2;
481
+
482
+ #define SNDMIX_RAMPSTEREOVOL\
483
+ nRampLeftVol += pChn->nLeftRamp;\
484
+ nRampRightVol += pChn->nRightRamp;\
485
+ pvol[0] += vol_l * (nRampRightVol >> VOLUMERAMPPRECISION);\
486
+ pvol[1] += vol_r * (nRampLeftVol >> VOLUMERAMPPRECISION);\
487
+ pvol += 2;
488
+
489
+
490
+ ///////////////////////////////////////////////////
491
+ // Resonant Filters
492
+
493
+ // Mono
494
+ #define MIX_BEGIN_FILTER\
495
+ int fy1 = pChannel->nFilter_Y1;\
496
+ int fy2 = pChannel->nFilter_Y2;\
497
+
498
+ #define MIX_END_FILTER\
499
+ pChannel->nFilter_Y1 = fy1;\
500
+ pChannel->nFilter_Y2 = fy2;
501
+
502
+ #define SNDMIX_PROCESSFILTER\
503
+ vol = (vol * pChn->nFilter_A0 + fy1 * pChn->nFilter_B0 + fy2 * pChn->nFilter_B1 + 4096) >> 13;\
504
+ fy2 = fy1;\
505
+ fy1 = vol;\
506
+
507
+ // Stereo
508
+ #define MIX_BEGIN_STEREO_FILTER\
509
+ int fy1 = pChannel->nFilter_Y1;\
510
+ int fy2 = pChannel->nFilter_Y2;\
511
+ int fy3 = pChannel->nFilter_Y3;\
512
+ int fy4 = pChannel->nFilter_Y4;\
513
+
514
+ #define MIX_END_STEREO_FILTER\
515
+ pChannel->nFilter_Y1 = fy1;\
516
+ pChannel->nFilter_Y2 = fy2;\
517
+ pChannel->nFilter_Y3 = fy3;\
518
+ pChannel->nFilter_Y4 = fy4;\
519
+
520
+ #define SNDMIX_PROCESSSTEREOFILTER\
521
+ vol_l = (vol_l * pChn->nFilter_A0 + fy1 * pChn->nFilter_B0 + fy2 * pChn->nFilter_B1 + 4096) >> 13;\
522
+ vol_r = (vol_r * pChn->nFilter_A0 + fy3 * pChn->nFilter_B0 + fy4 * pChn->nFilter_B1 + 4096) >> 13;\
523
+ fy2 = fy1; fy1 = vol_l;\
524
+ fy4 = fy3; fy3 = vol_r;\
525
+
526
+ //////////////////////////////////////////////////////////
527
+ // Interfaces
528
+
529
+ typedef VOID (MPPASMCALL * LPMIXINTERFACE)(MODCHANNEL *, int *, int *);
530
+
531
+ #define BEGIN_MIX_INTERFACE(func)\
532
+ VOID MPPASMCALL func(MODCHANNEL *pChannel, int *pbuffer, int *pbufmax)\
533
+ {\
534
+ LONG nPos;
535
+
536
+ #define END_MIX_INTERFACE()\
537
+ SNDMIX_ENDSAMPLELOOP\
538
+ }
539
+
540
+ // Volume Ramps
541
+ #define BEGIN_RAMPMIX_INTERFACE(func)\
542
+ BEGIN_MIX_INTERFACE(func)\
543
+ LONG nRampRightVol = pChannel->nRampRightVol;\
544
+ LONG nRampLeftVol = pChannel->nRampLeftVol;
545
+
546
+ #define END_RAMPMIX_INTERFACE()\
547
+ SNDMIX_ENDSAMPLELOOP\
548
+ pChannel->nRampRightVol = nRampRightVol;\
549
+ pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
550
+ pChannel->nRampLeftVol = nRampLeftVol;\
551
+ pChannel->nLeftVol = nRampLeftVol >> VOLUMERAMPPRECISION;\
552
+ }
553
+
554
+ #define BEGIN_FASTRAMPMIX_INTERFACE(func)\
555
+ BEGIN_MIX_INTERFACE(func)\
556
+ LONG nRampRightVol = pChannel->nRampRightVol;
557
+
558
+ #define END_FASTRAMPMIX_INTERFACE()\
559
+ SNDMIX_ENDSAMPLELOOP\
560
+ pChannel->nRampRightVol = nRampRightVol;\
561
+ pChannel->nRampLeftVol = nRampRightVol;\
562
+ pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
563
+ pChannel->nLeftVol = pChannel->nRightVol;\
564
+ }
565
+
566
+
567
+ // Mono Resonant Filters
568
+ #define BEGIN_MIX_FLT_INTERFACE(func)\
569
+ BEGIN_MIX_INTERFACE(func)\
570
+ MIX_BEGIN_FILTER
571
+
572
+
573
+ #define END_MIX_FLT_INTERFACE()\
574
+ SNDMIX_ENDSAMPLELOOP\
575
+ MIX_END_FILTER\
576
+ }
577
+
578
+ #define BEGIN_RAMPMIX_FLT_INTERFACE(func)\
579
+ BEGIN_MIX_INTERFACE(func)\
580
+ LONG nRampRightVol = pChannel->nRampRightVol;\
581
+ LONG nRampLeftVol = pChannel->nRampLeftVol;\
582
+ MIX_BEGIN_FILTER
583
+
584
+ #define END_RAMPMIX_FLT_INTERFACE()\
585
+ SNDMIX_ENDSAMPLELOOP\
586
+ MIX_END_FILTER\
587
+ pChannel->nRampRightVol = nRampRightVol;\
588
+ pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
589
+ pChannel->nRampLeftVol = nRampLeftVol;\
590
+ pChannel->nLeftVol = nRampLeftVol >> VOLUMERAMPPRECISION;\
591
+ }
592
+
593
+ // Stereo Resonant Filters
594
+ #define BEGIN_MIX_STFLT_INTERFACE(func)\
595
+ BEGIN_MIX_INTERFACE(func)\
596
+ MIX_BEGIN_STEREO_FILTER
597
+
598
+
599
+ #define END_MIX_STFLT_INTERFACE()\
600
+ SNDMIX_ENDSAMPLELOOP\
601
+ MIX_END_STEREO_FILTER\
602
+ }
603
+
604
+ #define BEGIN_RAMPMIX_STFLT_INTERFACE(func)\
605
+ BEGIN_MIX_INTERFACE(func)\
606
+ LONG nRampRightVol = pChannel->nRampRightVol;\
607
+ LONG nRampLeftVol = pChannel->nRampLeftVol;\
608
+ MIX_BEGIN_STEREO_FILTER
609
+
610
+ #define END_RAMPMIX_STFLT_INTERFACE()\
611
+ SNDMIX_ENDSAMPLELOOP\
612
+ MIX_END_STEREO_FILTER\
613
+ pChannel->nRampRightVol = nRampRightVol;\
614
+ pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
615
+ pChannel->nRampLeftVol = nRampLeftVol;\
616
+ pChannel->nLeftVol = nRampLeftVol >> VOLUMERAMPPRECISION;\
617
+ }
618
+
619
+
620
+ /////////////////////////////////////////////////////
621
+ //
622
+
623
+ void MPPASMCALL X86_InitMixBuffer(int *pBuffer, UINT nSamples);
624
+ void MPPASMCALL X86_EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples);
625
+ void MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs);
626
+ void X86_StereoMixToFloat(const int *, float *, float *, UINT nCount);
627
+ void X86_FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount);
628
+
629
+ /////////////////////////////////////////////////////
630
+ // Mono samples functions
631
+
632
+ BEGIN_MIX_INTERFACE(Mono8BitMix)
633
+ SNDMIX_BEGINSAMPLELOOP8
634
+ SNDMIX_GETMONOVOL8NOIDO
635
+ SNDMIX_STOREMONOVOL
636
+ END_MIX_INTERFACE()
637
+
638
+ BEGIN_MIX_INTERFACE(Mono16BitMix)
639
+ SNDMIX_BEGINSAMPLELOOP16
640
+ SNDMIX_GETMONOVOL16NOIDO
641
+ SNDMIX_STOREMONOVOL
642
+ END_MIX_INTERFACE()
643
+
644
+ BEGIN_MIX_INTERFACE(Mono8BitLinearMix)
645
+ SNDMIX_BEGINSAMPLELOOP8
646
+ SNDMIX_GETMONOVOL8LINEAR
647
+ SNDMIX_STOREMONOVOL
648
+ END_MIX_INTERFACE()
649
+
650
+ BEGIN_MIX_INTERFACE(Mono16BitLinearMix)
651
+ SNDMIX_BEGINSAMPLELOOP16
652
+ SNDMIX_GETMONOVOL16LINEAR
653
+ SNDMIX_STOREMONOVOL
654
+ END_MIX_INTERFACE()
655
+
656
+ BEGIN_MIX_INTERFACE(Mono8BitSplineMix)
657
+ SNDMIX_BEGINSAMPLELOOP8
658
+ SNDMIX_GETMONOVOL8SPLINE
659
+ SNDMIX_STOREMONOVOL
660
+ END_MIX_INTERFACE()
661
+
662
+ BEGIN_MIX_INTERFACE(Mono16BitSplineMix)
663
+ SNDMIX_BEGINSAMPLELOOP16
664
+ SNDMIX_GETMONOVOL16SPLINE
665
+ SNDMIX_STOREMONOVOL
666
+ END_MIX_INTERFACE()
667
+
668
+ BEGIN_MIX_INTERFACE(Mono8BitFirFilterMix)
669
+ SNDMIX_BEGINSAMPLELOOP8
670
+ SNDMIX_GETMONOVOL8FIRFILTER
671
+ SNDMIX_STOREMONOVOL
672
+ END_MIX_INTERFACE()
673
+
674
+ BEGIN_MIX_INTERFACE(Mono16BitFirFilterMix)
675
+ SNDMIX_BEGINSAMPLELOOP16
676
+ SNDMIX_GETMONOVOL16FIRFILTER
677
+ SNDMIX_STOREMONOVOL
678
+ END_MIX_INTERFACE()
679
+
680
+
681
+ // Volume Ramps
682
+ BEGIN_RAMPMIX_INTERFACE(Mono8BitRampMix)
683
+ SNDMIX_BEGINSAMPLELOOP8
684
+ SNDMIX_GETMONOVOL8NOIDO
685
+ SNDMIX_RAMPMONOVOL
686
+ END_RAMPMIX_INTERFACE()
687
+
688
+ BEGIN_RAMPMIX_INTERFACE(Mono16BitRampMix)
689
+ SNDMIX_BEGINSAMPLELOOP16
690
+ SNDMIX_GETMONOVOL16NOIDO
691
+ SNDMIX_RAMPMONOVOL
692
+ END_RAMPMIX_INTERFACE()
693
+
694
+ BEGIN_RAMPMIX_INTERFACE(Mono8BitLinearRampMix)
695
+ SNDMIX_BEGINSAMPLELOOP8
696
+ SNDMIX_GETMONOVOL8LINEAR
697
+ SNDMIX_RAMPMONOVOL
698
+ END_RAMPMIX_INTERFACE()
699
+
700
+ BEGIN_RAMPMIX_INTERFACE(Mono16BitLinearRampMix)
701
+ SNDMIX_BEGINSAMPLELOOP16
702
+ SNDMIX_GETMONOVOL16LINEAR
703
+ SNDMIX_RAMPMONOVOL
704
+ END_RAMPMIX_INTERFACE()
705
+
706
+ BEGIN_RAMPMIX_INTERFACE(Mono8BitSplineRampMix)
707
+ SNDMIX_BEGINSAMPLELOOP8
708
+ SNDMIX_GETMONOVOL8SPLINE
709
+ SNDMIX_RAMPMONOVOL
710
+ END_RAMPMIX_INTERFACE()
711
+
712
+ BEGIN_RAMPMIX_INTERFACE(Mono16BitSplineRampMix)
713
+ SNDMIX_BEGINSAMPLELOOP16
714
+ SNDMIX_GETMONOVOL16SPLINE
715
+ SNDMIX_RAMPMONOVOL
716
+ END_RAMPMIX_INTERFACE()
717
+
718
+ BEGIN_RAMPMIX_INTERFACE(Mono8BitFirFilterRampMix)
719
+ SNDMIX_BEGINSAMPLELOOP8
720
+ SNDMIX_GETMONOVOL8FIRFILTER
721
+ SNDMIX_RAMPMONOVOL
722
+ END_RAMPMIX_INTERFACE()
723
+
724
+ BEGIN_RAMPMIX_INTERFACE(Mono16BitFirFilterRampMix)
725
+ SNDMIX_BEGINSAMPLELOOP16
726
+ SNDMIX_GETMONOVOL16FIRFILTER
727
+ SNDMIX_RAMPMONOVOL
728
+ END_RAMPMIX_INTERFACE()
729
+
730
+
731
+ //////////////////////////////////////////////////////
732
+ // Fast mono mix for leftvol=rightvol (1 less imul)
733
+
734
+ BEGIN_MIX_INTERFACE(FastMono8BitMix)
735
+ SNDMIX_BEGINSAMPLELOOP8
736
+ SNDMIX_GETMONOVOL8NOIDO
737
+ SNDMIX_STOREFASTMONOVOL
738
+ END_MIX_INTERFACE()
739
+
740
+ BEGIN_MIX_INTERFACE(FastMono16BitMix)
741
+ SNDMIX_BEGINSAMPLELOOP16
742
+ SNDMIX_GETMONOVOL16NOIDO
743
+ SNDMIX_STOREFASTMONOVOL
744
+ END_MIX_INTERFACE()
745
+
746
+ BEGIN_MIX_INTERFACE(FastMono8BitLinearMix)
747
+ SNDMIX_BEGINSAMPLELOOP8
748
+ SNDMIX_GETMONOVOL8LINEAR
749
+ SNDMIX_STOREFASTMONOVOL
750
+ END_MIX_INTERFACE()
751
+
752
+ BEGIN_MIX_INTERFACE(FastMono16BitLinearMix)
753
+ SNDMIX_BEGINSAMPLELOOP16
754
+ SNDMIX_GETMONOVOL16LINEAR
755
+ SNDMIX_STOREFASTMONOVOL
756
+ END_MIX_INTERFACE()
757
+
758
+ BEGIN_MIX_INTERFACE(FastMono8BitSplineMix)
759
+ SNDMIX_BEGINSAMPLELOOP8
760
+ SNDMIX_GETMONOVOL8SPLINE
761
+ SNDMIX_STOREFASTMONOVOL
762
+ END_MIX_INTERFACE()
763
+
764
+ BEGIN_MIX_INTERFACE(FastMono16BitSplineMix)
765
+ SNDMIX_BEGINSAMPLELOOP16
766
+ SNDMIX_GETMONOVOL16SPLINE
767
+ SNDMIX_STOREFASTMONOVOL
768
+ END_MIX_INTERFACE()
769
+
770
+ BEGIN_MIX_INTERFACE(FastMono8BitFirFilterMix)
771
+ SNDMIX_BEGINSAMPLELOOP8
772
+ SNDMIX_GETMONOVOL8FIRFILTER
773
+ SNDMIX_STOREFASTMONOVOL
774
+ END_MIX_INTERFACE()
775
+
776
+ BEGIN_MIX_INTERFACE(FastMono16BitFirFilterMix)
777
+ SNDMIX_BEGINSAMPLELOOP16
778
+ SNDMIX_GETMONOVOL16FIRFILTER
779
+ SNDMIX_STOREFASTMONOVOL
780
+ END_MIX_INTERFACE()
781
+
782
+
783
+ // Fast Ramps
784
+ BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitRampMix)
785
+ SNDMIX_BEGINSAMPLELOOP8
786
+ SNDMIX_GETMONOVOL8NOIDO
787
+ SNDMIX_RAMPFASTMONOVOL
788
+ END_FASTRAMPMIX_INTERFACE()
789
+
790
+ BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitRampMix)
791
+ SNDMIX_BEGINSAMPLELOOP16
792
+ SNDMIX_GETMONOVOL16NOIDO
793
+ SNDMIX_RAMPFASTMONOVOL
794
+ END_FASTRAMPMIX_INTERFACE()
795
+
796
+ BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitLinearRampMix)
797
+ SNDMIX_BEGINSAMPLELOOP8
798
+ SNDMIX_GETMONOVOL8LINEAR
799
+ SNDMIX_RAMPFASTMONOVOL
800
+ END_FASTRAMPMIX_INTERFACE()
801
+
802
+ BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitLinearRampMix)
803
+ SNDMIX_BEGINSAMPLELOOP16
804
+ SNDMIX_GETMONOVOL16LINEAR
805
+ SNDMIX_RAMPFASTMONOVOL
806
+ END_FASTRAMPMIX_INTERFACE()
807
+
808
+ BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitSplineRampMix)
809
+ SNDMIX_BEGINSAMPLELOOP8
810
+ SNDMIX_GETMONOVOL8SPLINE
811
+ SNDMIX_RAMPFASTMONOVOL
812
+ END_FASTRAMPMIX_INTERFACE()
813
+
814
+ BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitSplineRampMix)
815
+ SNDMIX_BEGINSAMPLELOOP16
816
+ SNDMIX_GETMONOVOL16SPLINE
817
+ SNDMIX_RAMPFASTMONOVOL
818
+ END_FASTRAMPMIX_INTERFACE()
819
+
820
+ BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitFirFilterRampMix)
821
+ SNDMIX_BEGINSAMPLELOOP8
822
+ SNDMIX_GETMONOVOL8FIRFILTER
823
+ SNDMIX_RAMPFASTMONOVOL
824
+ END_FASTRAMPMIX_INTERFACE()
825
+
826
+ BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitFirFilterRampMix)
827
+ SNDMIX_BEGINSAMPLELOOP16
828
+ SNDMIX_GETMONOVOL16FIRFILTER
829
+ SNDMIX_RAMPFASTMONOVOL
830
+ END_FASTRAMPMIX_INTERFACE()
831
+
832
+
833
+ //////////////////////////////////////////////////////
834
+ // Stereo samples
835
+
836
+ BEGIN_MIX_INTERFACE(Stereo8BitMix)
837
+ SNDMIX_BEGINSAMPLELOOP8
838
+ SNDMIX_GETSTEREOVOL8NOIDO
839
+ SNDMIX_STORESTEREOVOL
840
+ END_MIX_INTERFACE()
841
+
842
+ BEGIN_MIX_INTERFACE(Stereo16BitMix)
843
+ SNDMIX_BEGINSAMPLELOOP16
844
+ SNDMIX_GETSTEREOVOL16NOIDO
845
+ SNDMIX_STORESTEREOVOL
846
+ END_MIX_INTERFACE()
847
+
848
+ BEGIN_MIX_INTERFACE(Stereo8BitLinearMix)
849
+ SNDMIX_BEGINSAMPLELOOP8
850
+ SNDMIX_GETSTEREOVOL8LINEAR
851
+ SNDMIX_STORESTEREOVOL
852
+ END_MIX_INTERFACE()
853
+
854
+ BEGIN_MIX_INTERFACE(Stereo16BitLinearMix)
855
+ SNDMIX_BEGINSAMPLELOOP16
856
+ SNDMIX_GETSTEREOVOL16LINEAR
857
+ SNDMIX_STORESTEREOVOL
858
+ END_MIX_INTERFACE()
859
+
860
+ BEGIN_MIX_INTERFACE(Stereo8BitSplineMix)
861
+ SNDMIX_BEGINSAMPLELOOP8
862
+ SNDMIX_GETSTEREOVOL8SPLINE
863
+ SNDMIX_STORESTEREOVOL
864
+ END_MIX_INTERFACE()
865
+
866
+ BEGIN_MIX_INTERFACE(Stereo16BitSplineMix)
867
+ SNDMIX_BEGINSAMPLELOOP16
868
+ SNDMIX_GETSTEREOVOL16SPLINE
869
+ SNDMIX_STORESTEREOVOL
870
+ END_MIX_INTERFACE()
871
+
872
+ BEGIN_MIX_INTERFACE(Stereo8BitFirFilterMix)
873
+ SNDMIX_BEGINSAMPLELOOP8
874
+ SNDMIX_GETSTEREOVOL8FIRFILTER
875
+ SNDMIX_STORESTEREOVOL
876
+ END_MIX_INTERFACE()
877
+
878
+ BEGIN_MIX_INTERFACE(Stereo16BitFirFilterMix)
879
+ SNDMIX_BEGINSAMPLELOOP16
880
+ SNDMIX_GETSTEREOVOL16FIRFILTER
881
+ SNDMIX_STORESTEREOVOL
882
+ END_MIX_INTERFACE()
883
+
884
+
885
+ // Volume Ramps
886
+ BEGIN_RAMPMIX_INTERFACE(Stereo8BitRampMix)
887
+ SNDMIX_BEGINSAMPLELOOP8
888
+ SNDMIX_GETSTEREOVOL8NOIDO
889
+ SNDMIX_RAMPSTEREOVOL
890
+ END_RAMPMIX_INTERFACE()
891
+
892
+ BEGIN_RAMPMIX_INTERFACE(Stereo16BitRampMix)
893
+ SNDMIX_BEGINSAMPLELOOP16
894
+ SNDMIX_GETSTEREOVOL16NOIDO
895
+ SNDMIX_RAMPSTEREOVOL
896
+ END_RAMPMIX_INTERFACE()
897
+
898
+ BEGIN_RAMPMIX_INTERFACE(Stereo8BitLinearRampMix)
899
+ SNDMIX_BEGINSAMPLELOOP8
900
+ SNDMIX_GETSTEREOVOL8LINEAR
901
+ SNDMIX_RAMPSTEREOVOL
902
+ END_RAMPMIX_INTERFACE()
903
+
904
+ BEGIN_RAMPMIX_INTERFACE(Stereo16BitLinearRampMix)
905
+ SNDMIX_BEGINSAMPLELOOP16
906
+ SNDMIX_GETSTEREOVOL16LINEAR
907
+ SNDMIX_RAMPSTEREOVOL
908
+ END_RAMPMIX_INTERFACE()
909
+
910
+ BEGIN_RAMPMIX_INTERFACE(Stereo8BitSplineRampMix)
911
+ SNDMIX_BEGINSAMPLELOOP8
912
+ SNDMIX_GETSTEREOVOL8SPLINE
913
+ SNDMIX_RAMPSTEREOVOL
914
+ END_RAMPMIX_INTERFACE()
915
+
916
+ BEGIN_RAMPMIX_INTERFACE(Stereo16BitSplineRampMix)
917
+ SNDMIX_BEGINSAMPLELOOP16
918
+ SNDMIX_GETSTEREOVOL16SPLINE
919
+ SNDMIX_RAMPSTEREOVOL
920
+ END_RAMPMIX_INTERFACE()
921
+
922
+ BEGIN_RAMPMIX_INTERFACE(Stereo8BitFirFilterRampMix)
923
+ SNDMIX_BEGINSAMPLELOOP8
924
+ SNDMIX_GETSTEREOVOL8FIRFILTER
925
+ SNDMIX_RAMPSTEREOVOL
926
+ END_RAMPMIX_INTERFACE()
927
+
928
+ BEGIN_RAMPMIX_INTERFACE(Stereo16BitFirFilterRampMix)
929
+ SNDMIX_BEGINSAMPLELOOP16
930
+ SNDMIX_GETSTEREOVOL16FIRFILTER
931
+ SNDMIX_RAMPSTEREOVOL
932
+ END_RAMPMIX_INTERFACE()
933
+
934
+
935
+
936
+ //////////////////////////////////////////////////////
937
+ // Resonant Filter Mix
938
+
939
+ #ifndef NO_FILTER
940
+
941
+ // Mono Filter Mix
942
+ BEGIN_MIX_FLT_INTERFACE(FilterMono8BitMix)
943
+ SNDMIX_BEGINSAMPLELOOP8
944
+ SNDMIX_GETMONOVOL8NOIDO
945
+ SNDMIX_PROCESSFILTER
946
+ SNDMIX_STOREMONOVOL
947
+ END_MIX_FLT_INTERFACE()
948
+
949
+ BEGIN_MIX_FLT_INTERFACE(FilterMono16BitMix)
950
+ SNDMIX_BEGINSAMPLELOOP16
951
+ SNDMIX_GETMONOVOL16NOIDO
952
+ SNDMIX_PROCESSFILTER
953
+ SNDMIX_STOREMONOVOL
954
+ END_MIX_FLT_INTERFACE()
955
+
956
+ BEGIN_MIX_FLT_INTERFACE(FilterMono8BitLinearMix)
957
+ SNDMIX_BEGINSAMPLELOOP8
958
+ SNDMIX_GETMONOVOL8LINEAR
959
+ SNDMIX_PROCESSFILTER
960
+ SNDMIX_STOREMONOVOL
961
+ END_MIX_FLT_INTERFACE()
962
+
963
+ BEGIN_MIX_FLT_INTERFACE(FilterMono16BitLinearMix)
964
+ SNDMIX_BEGINSAMPLELOOP16
965
+ SNDMIX_GETMONOVOL16LINEAR
966
+ SNDMIX_PROCESSFILTER
967
+ SNDMIX_STOREMONOVOL
968
+ END_MIX_FLT_INTERFACE()
969
+
970
+ BEGIN_MIX_FLT_INTERFACE(FilterMono8BitSplineMix)
971
+ SNDMIX_BEGINSAMPLELOOP8
972
+ SNDMIX_GETMONOVOL8SPLINE
973
+ SNDMIX_PROCESSFILTER
974
+ SNDMIX_STOREMONOVOL
975
+ END_MIX_FLT_INTERFACE()
976
+
977
+ BEGIN_MIX_FLT_INTERFACE(FilterMono16BitSplineMix)
978
+ SNDMIX_BEGINSAMPLELOOP16
979
+ SNDMIX_GETMONOVOL16SPLINE
980
+ SNDMIX_PROCESSFILTER
981
+ SNDMIX_STOREMONOVOL
982
+ END_MIX_FLT_INTERFACE()
983
+
984
+ BEGIN_MIX_FLT_INTERFACE(FilterMono8BitFirFilterMix)
985
+ SNDMIX_BEGINSAMPLELOOP8
986
+ SNDMIX_GETMONOVOL8FIRFILTER
987
+ SNDMIX_PROCESSFILTER
988
+ SNDMIX_STOREMONOVOL
989
+ END_MIX_FLT_INTERFACE()
990
+
991
+ BEGIN_MIX_FLT_INTERFACE(FilterMono16BitFirFilterMix)
992
+ SNDMIX_BEGINSAMPLELOOP16
993
+ SNDMIX_GETMONOVOL16FIRFILTER
994
+ SNDMIX_PROCESSFILTER
995
+ SNDMIX_STOREMONOVOL
996
+ END_MIX_FLT_INTERFACE()
997
+
998
+ // Filter + Ramp
999
+ BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitRampMix)
1000
+ SNDMIX_BEGINSAMPLELOOP8
1001
+ SNDMIX_GETMONOVOL8NOIDO
1002
+ SNDMIX_PROCESSFILTER
1003
+ SNDMIX_RAMPMONOVOL
1004
+ END_RAMPMIX_FLT_INTERFACE()
1005
+
1006
+ BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitRampMix)
1007
+ SNDMIX_BEGINSAMPLELOOP16
1008
+ SNDMIX_GETMONOVOL16NOIDO
1009
+ SNDMIX_PROCESSFILTER
1010
+ SNDMIX_RAMPMONOVOL
1011
+ END_RAMPMIX_FLT_INTERFACE()
1012
+
1013
+ BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitLinearRampMix)
1014
+ SNDMIX_BEGINSAMPLELOOP8
1015
+ SNDMIX_GETMONOVOL8LINEAR
1016
+ SNDMIX_PROCESSFILTER
1017
+ SNDMIX_RAMPMONOVOL
1018
+ END_RAMPMIX_FLT_INTERFACE()
1019
+
1020
+ BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitLinearRampMix)
1021
+ SNDMIX_BEGINSAMPLELOOP16
1022
+ SNDMIX_GETMONOVOL16LINEAR
1023
+ SNDMIX_PROCESSFILTER
1024
+ SNDMIX_RAMPMONOVOL
1025
+ END_RAMPMIX_FLT_INTERFACE()
1026
+
1027
+ BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitSplineRampMix)
1028
+ SNDMIX_BEGINSAMPLELOOP8
1029
+ SNDMIX_GETMONOVOL8SPLINE
1030
+ SNDMIX_PROCESSFILTER
1031
+ SNDMIX_RAMPMONOVOL
1032
+ END_RAMPMIX_FLT_INTERFACE()
1033
+
1034
+ BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitSplineRampMix)
1035
+ SNDMIX_BEGINSAMPLELOOP16
1036
+ SNDMIX_GETMONOVOL16SPLINE
1037
+ SNDMIX_PROCESSFILTER
1038
+ SNDMIX_RAMPMONOVOL
1039
+ END_RAMPMIX_FLT_INTERFACE()
1040
+
1041
+ BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitFirFilterRampMix)
1042
+ SNDMIX_BEGINSAMPLELOOP8
1043
+ SNDMIX_GETMONOVOL8FIRFILTER
1044
+ SNDMIX_PROCESSFILTER
1045
+ SNDMIX_RAMPMONOVOL
1046
+ END_RAMPMIX_FLT_INTERFACE()
1047
+
1048
+ BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitFirFilterRampMix)
1049
+ SNDMIX_BEGINSAMPLELOOP16
1050
+ SNDMIX_GETMONOVOL16FIRFILTER
1051
+ SNDMIX_PROCESSFILTER
1052
+ SNDMIX_RAMPMONOVOL
1053
+ END_RAMPMIX_FLT_INTERFACE()
1054
+
1055
+
1056
+ // Stereo Filter Mix
1057
+ BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitMix)
1058
+ SNDMIX_BEGINSAMPLELOOP8
1059
+ SNDMIX_GETSTEREOVOL8NOIDO
1060
+ SNDMIX_PROCESSSTEREOFILTER
1061
+ SNDMIX_STORESTEREOVOL
1062
+ END_MIX_STFLT_INTERFACE()
1063
+
1064
+ BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitMix)
1065
+ SNDMIX_BEGINSAMPLELOOP16
1066
+ SNDMIX_GETSTEREOVOL16NOIDO
1067
+ SNDMIX_PROCESSSTEREOFILTER
1068
+ SNDMIX_STORESTEREOVOL
1069
+ END_MIX_STFLT_INTERFACE()
1070
+
1071
+ BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitLinearMix)
1072
+ SNDMIX_BEGINSAMPLELOOP8
1073
+ SNDMIX_GETSTEREOVOL8LINEAR
1074
+ SNDMIX_PROCESSSTEREOFILTER
1075
+ SNDMIX_STORESTEREOVOL
1076
+ END_MIX_STFLT_INTERFACE()
1077
+
1078
+ BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitLinearMix)
1079
+ SNDMIX_BEGINSAMPLELOOP16
1080
+ SNDMIX_GETSTEREOVOL16LINEAR
1081
+ SNDMIX_PROCESSSTEREOFILTER
1082
+ SNDMIX_STORESTEREOVOL
1083
+ END_MIX_STFLT_INTERFACE()
1084
+
1085
+ BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitSplineMix)
1086
+ SNDMIX_BEGINSAMPLELOOP8
1087
+ SNDMIX_GETSTEREOVOL8SPLINE
1088
+ SNDMIX_PROCESSSTEREOFILTER
1089
+ SNDMIX_STORESTEREOVOL
1090
+ END_MIX_STFLT_INTERFACE()
1091
+
1092
+ BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitSplineMix)
1093
+ SNDMIX_BEGINSAMPLELOOP16
1094
+ SNDMIX_GETSTEREOVOL16SPLINE
1095
+ SNDMIX_PROCESSSTEREOFILTER
1096
+ SNDMIX_STORESTEREOVOL
1097
+ END_MIX_STFLT_INTERFACE()
1098
+
1099
+ BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitFirFilterMix)
1100
+ SNDMIX_BEGINSAMPLELOOP8
1101
+ SNDMIX_GETSTEREOVOL8FIRFILTER
1102
+ SNDMIX_PROCESSSTEREOFILTER
1103
+ SNDMIX_STORESTEREOVOL
1104
+ END_MIX_STFLT_INTERFACE()
1105
+
1106
+ BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitFirFilterMix)
1107
+ SNDMIX_BEGINSAMPLELOOP16
1108
+ SNDMIX_GETSTEREOVOL16FIRFILTER
1109
+ SNDMIX_PROCESSSTEREOFILTER
1110
+ SNDMIX_STORESTEREOVOL
1111
+ END_MIX_STFLT_INTERFACE()
1112
+
1113
+ // Stereo Filter + Ramp
1114
+ BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitRampMix)
1115
+ SNDMIX_BEGINSAMPLELOOP8
1116
+ SNDMIX_GETSTEREOVOL8NOIDO
1117
+ SNDMIX_PROCESSSTEREOFILTER
1118
+ SNDMIX_RAMPSTEREOVOL
1119
+ END_RAMPMIX_STFLT_INTERFACE()
1120
+
1121
+ BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitRampMix)
1122
+ SNDMIX_BEGINSAMPLELOOP16
1123
+ SNDMIX_GETSTEREOVOL16NOIDO
1124
+ SNDMIX_PROCESSSTEREOFILTER
1125
+ SNDMIX_RAMPSTEREOVOL
1126
+ END_RAMPMIX_STFLT_INTERFACE()
1127
+
1128
+ BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitLinearRampMix)
1129
+ SNDMIX_BEGINSAMPLELOOP8
1130
+ SNDMIX_GETSTEREOVOL8LINEAR
1131
+ SNDMIX_PROCESSSTEREOFILTER
1132
+ SNDMIX_RAMPSTEREOVOL
1133
+ END_RAMPMIX_STFLT_INTERFACE()
1134
+
1135
+ BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitLinearRampMix)
1136
+ SNDMIX_BEGINSAMPLELOOP16
1137
+ SNDMIX_GETSTEREOVOL16LINEAR
1138
+ SNDMIX_PROCESSSTEREOFILTER
1139
+ SNDMIX_RAMPSTEREOVOL
1140
+ END_RAMPMIX_STFLT_INTERFACE()
1141
+
1142
+ BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitSplineRampMix)
1143
+ SNDMIX_BEGINSAMPLELOOP8
1144
+ SNDMIX_GETSTEREOVOL8SPLINE
1145
+ SNDMIX_PROCESSSTEREOFILTER
1146
+ SNDMIX_RAMPSTEREOVOL
1147
+ END_RAMPMIX_STFLT_INTERFACE()
1148
+
1149
+ BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitSplineRampMix)
1150
+ SNDMIX_BEGINSAMPLELOOP16
1151
+ SNDMIX_GETSTEREOVOL16SPLINE
1152
+ SNDMIX_PROCESSSTEREOFILTER
1153
+ SNDMIX_RAMPSTEREOVOL
1154
+ END_RAMPMIX_STFLT_INTERFACE()
1155
+
1156
+ BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitFirFilterRampMix)
1157
+ SNDMIX_BEGINSAMPLELOOP8
1158
+ SNDMIX_GETSTEREOVOL8FIRFILTER
1159
+ SNDMIX_PROCESSSTEREOFILTER
1160
+ SNDMIX_RAMPSTEREOVOL
1161
+ END_RAMPMIX_STFLT_INTERFACE()
1162
+
1163
+ BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitFirFilterRampMix)
1164
+ SNDMIX_BEGINSAMPLELOOP16
1165
+ SNDMIX_GETSTEREOVOL16FIRFILTER
1166
+ SNDMIX_PROCESSSTEREOFILTER
1167
+ SNDMIX_RAMPSTEREOVOL
1168
+ END_RAMPMIX_STFLT_INTERFACE()
1169
+
1170
+
1171
+ #else
1172
+ // Mono
1173
+ #define FilterMono8BitMix Mono8BitMix
1174
+ #define FilterMono16BitMix Mono16BitMix
1175
+ #define FilterMono8BitLinearMix Mono8BitLinearMix
1176
+ #define FilterMono16BitLinearMix Mono16BitLinearMix
1177
+ #define FilterMono8BitSplineMix Mono8BitSplineMix
1178
+ #define FilterMono16BitSplineMix Mono16BitSplineMix
1179
+ #define FilterMono8BitFirFilterMix Mono8BitFirFilterMix
1180
+ #define FilterMono16BitFirFilterMix Mono16BitFirFilterMix
1181
+ #define FilterMono8BitRampMix Mono8BitRampMix
1182
+ #define FilterMono16BitRampMix Mono16BitRampMix
1183
+ #define FilterMono8BitLinearRampMix Mono8BitLinearRampMix
1184
+ #define FilterMono16BitLinearRampMix Mono16BitLinearRampMix
1185
+ #define FilterMono8BitSplineRampMix Mono8BitSplineRampMix
1186
+ #define FilterMono16BitSplineRampMix Mono16BitSplineRampMix
1187
+ #define FilterMono8BitFirFilterRampMix Mono8BitFirFilterRampMix
1188
+ #define FilterMono16BitFirFilterRampMix Mono16BitFirFilterRampMix
1189
+ // Stereo
1190
+ #define FilterStereo8BitMix Stereo8BitMix
1191
+ #define FilterStereo16BitMix Stereo16BitMix
1192
+ #define FilterStereo8BitLinearMix Stereo8BitLinearMix
1193
+ #define FilterStereo16BitLinearMix Stereo16BitLinearMix
1194
+ #define FilterStereo8BitSplineMix Stereo8BitSplineMix
1195
+ #define FilterStereo16BitSplineMix Stereo16BitSplineMix
1196
+ #define FilterStereo8BitFirFilterMix Stereo8BitFirFilterMix
1197
+ #define FilterStereo16BitFirFilterMix Stereo16BitFirFilterMix
1198
+ #define FilterStereo8BitRampMix Stereo8BitRampMix
1199
+ #define FilterStereo16BitRampMix Stereo16BitRampMix
1200
+ #define FilterStereo8BitLinearRampMix Stereo8BitLinearRampMix
1201
+ #define FilterStereo16BitLinearRampMix Stereo16BitLinearRampMix
1202
+ #define FilterStereo8BitSplineRampMix Stereo8BitSplineRampMix
1203
+ #define FilterStereo16BitSplineRampMix Stereo16BitSplineRampMix
1204
+ #define FilterStereo8BitFirFilterRampMix Stereo8BitFirFilterRampMix
1205
+ #define FilterStereo16BitFirFilterRampMix Stereo16BitFirFilterRampMix
1206
+
1207
+ #endif
1208
+
1209
+ ///////////////////////////////////////////////////////////////////////////////
1210
+ //
1211
+ // Mix function tables
1212
+ //
1213
+ //
1214
+ // Index is as follow:
1215
+ // [b1-b0] format (8-bit-mono, 16-bit-mono, 8-bit-stereo, 16-bit-stereo)
1216
+ // [b2] ramp
1217
+ // [b3] filter
1218
+ // [b5-b4] src type
1219
+ //
1220
+
1221
+ #define MIXNDX_16BIT 0x01
1222
+ #define MIXNDX_STEREO 0x02
1223
+ #define MIXNDX_RAMP 0x04
1224
+ #define MIXNDX_FILTER 0x08
1225
+ #define MIXNDX_LINEARSRC 0x10
1226
+ #define MIXNDX_SPLINESRC 0x20
1227
+ #define MIXNDX_FIRSRC 0x30
1228
+
1229
+ const LPMIXINTERFACE gpMixFunctionTable[2*2*16] =
1230
+ {
1231
+ // No SRC
1232
+ Mono8BitMix, Mono16BitMix, Stereo8BitMix, Stereo16BitMix,
1233
+ Mono8BitRampMix, Mono16BitRampMix, Stereo8BitRampMix,
1234
+ Stereo16BitRampMix,
1235
+ // No SRC, Filter
1236
+ FilterMono8BitMix, FilterMono16BitMix, FilterStereo8BitMix,
1237
+ FilterStereo16BitMix, FilterMono8BitRampMix, FilterMono16BitRampMix,
1238
+ FilterStereo8BitRampMix, FilterStereo16BitRampMix,
1239
+ // Linear SRC
1240
+ Mono8BitLinearMix, Mono16BitLinearMix, Stereo8BitLinearMix,
1241
+ Stereo16BitLinearMix, Mono8BitLinearRampMix, Mono16BitLinearRampMix,
1242
+ Stereo8BitLinearRampMix,Stereo16BitLinearRampMix,
1243
+ // Linear SRC, Filter
1244
+ FilterMono8BitLinearMix, FilterMono16BitLinearMix,
1245
+ FilterStereo8BitLinearMix, FilterStereo16BitLinearMix,
1246
+ FilterMono8BitLinearRampMix, FilterMono16BitLinearRampMix,
1247
+ FilterStereo8BitLinearRampMix, FilterStereo16BitLinearRampMix,
1248
+
1249
+ // FirFilter SRC
1250
+ Mono8BitSplineMix, Mono16BitSplineMix, Stereo8BitSplineMix,
1251
+ Stereo16BitSplineMix, Mono8BitSplineRampMix, Mono16BitSplineRampMix,
1252
+ Stereo8BitSplineRampMix,Stereo16BitSplineRampMix,
1253
+ // Spline SRC, Filter
1254
+ FilterMono8BitSplineMix, FilterMono16BitSplineMix,
1255
+ FilterStereo8BitSplineMix, FilterStereo16BitSplineMix,
1256
+ FilterMono8BitSplineRampMix, FilterMono16BitSplineRampMix,
1257
+ FilterStereo8BitSplineRampMix, FilterStereo16BitSplineRampMix,
1258
+
1259
+ // FirFilter SRC
1260
+ Mono8BitFirFilterMix, Mono16BitFirFilterMix, Stereo8BitFirFilterMix,
1261
+ Stereo16BitFirFilterMix, Mono8BitFirFilterRampMix,
1262
+ Mono16BitFirFilterRampMix, Stereo8BitFirFilterRampMix,
1263
+ Stereo16BitFirFilterRampMix,
1264
+ // FirFilter SRC, Filter
1265
+ FilterMono8BitFirFilterMix, FilterMono16BitFirFilterMix,
1266
+ FilterStereo8BitFirFilterMix, FilterStereo16BitFirFilterMix,
1267
+ FilterMono8BitFirFilterRampMix, FilterMono16BitFirFilterRampMix,
1268
+ FilterStereo8BitFirFilterRampMix, FilterStereo16BitFirFilterRampMix
1269
+ };
1270
+
1271
+ const LPMIXINTERFACE gpFastMixFunctionTable[2*2*16] =
1272
+ {
1273
+ // No SRC
1274
+ FastMono8BitMix, FastMono16BitMix, Stereo8BitMix, Stereo16BitMix,
1275
+ FastMono8BitRampMix, FastMono16BitRampMix, Stereo8BitRampMix,
1276
+ Stereo16BitRampMix,
1277
+ // No SRC, Filter
1278
+ FilterMono8BitMix, FilterMono16BitMix, FilterStereo8BitMix,
1279
+ FilterStereo16BitMix, FilterMono8BitRampMix, FilterMono16BitRampMix,
1280
+ FilterStereo8BitRampMix, FilterStereo16BitRampMix,
1281
+ // Linear SRC
1282
+ FastMono8BitLinearMix, FastMono16BitLinearMix, Stereo8BitLinearMix,
1283
+ Stereo16BitLinearMix, FastMono8BitLinearRampMix,
1284
+ FastMono16BitLinearRampMix, Stereo8BitLinearRampMix,
1285
+ Stereo16BitLinearRampMix,
1286
+ // Linear SRC, Filter
1287
+ FilterMono8BitLinearMix, FilterMono16BitLinearMix,
1288
+ FilterStereo8BitLinearMix, FilterStereo16BitLinearMix,
1289
+ FilterMono8BitLinearRampMix, FilterMono16BitLinearRampMix,
1290
+ FilterStereo8BitLinearRampMix, FilterStereo16BitLinearRampMix,
1291
+
1292
+ // Spline SRC
1293
+ Mono8BitSplineMix, Mono16BitSplineMix, Stereo8BitSplineMix,
1294
+ Stereo16BitSplineMix, Mono8BitSplineRampMix, Mono16BitSplineRampMix,
1295
+ Stereo8BitSplineRampMix, Stereo16BitSplineRampMix,
1296
+ // Spline SRC, Filter
1297
+ FilterMono8BitSplineMix, FilterMono16BitSplineMix,
1298
+ FilterStereo8BitSplineMix, FilterStereo16BitSplineMix,
1299
+ FilterMono8BitSplineRampMix, FilterMono16BitSplineRampMix,
1300
+ FilterStereo8BitSplineRampMix, FilterStereo16BitSplineRampMix,
1301
+
1302
+ // FirFilter SRC
1303
+ Mono8BitFirFilterMix, Mono16BitFirFilterMix, Stereo8BitFirFilterMix,
1304
+ Stereo16BitFirFilterMix, Mono8BitFirFilterRampMix,
1305
+ Mono16BitFirFilterRampMix, Stereo8BitFirFilterRampMix,
1306
+ Stereo16BitFirFilterRampMix,
1307
+ // FirFilter SRC, Filter
1308
+ FilterMono8BitFirFilterMix, FilterMono16BitFirFilterMix,
1309
+ FilterStereo8BitFirFilterMix, FilterStereo16BitFirFilterMix,
1310
+ FilterMono8BitFirFilterRampMix, FilterMono16BitFirFilterRampMix,
1311
+ FilterStereo8BitFirFilterRampMix, FilterStereo16BitFirFilterRampMix,
1312
+ };
1313
+
1314
+
1315
+ /////////////////////////////////////////////////////////////////////////
1316
+
1317
+ static LONG MPPFASTCALL GetSampleCount(MODCHANNEL *pChn, LONG nSamples)
1318
+ //---------------------------------------------------------------------
1319
+ {
1320
+ LONG nLoopStart = (pChn->dwFlags & CHN_LOOP) ? pChn->nLoopStart : 0;
1321
+ LONG nInc = pChn->nInc;
1322
+
1323
+ if ((nSamples <= 0) || (!nInc) || (!pChn->nLength)) return 0;
1324
+ // Under zero ?
1325
+ if ((LONG)pChn->nPos < nLoopStart)
1326
+ {
1327
+ if (nInc < 0)
1328
+ {
1329
+ // Invert loop for bidi loops
1330
+ LONG nDelta = ((nLoopStart - pChn->nPos) << 16) - (pChn->nPosLo & 0xffff);
1331
+ pChn->nPos = nLoopStart | (nDelta>>16);
1332
+ pChn->nPosLo = nDelta & 0xffff;
1333
+ if (((LONG)pChn->nPos < nLoopStart) ||
1334
+ (pChn->nPos >= (nLoopStart+pChn->nLength)/2))
1335
+ {
1336
+ pChn->nPos = nLoopStart; pChn->nPosLo = 0;
1337
+ }
1338
+ nInc = -nInc;
1339
+ pChn->nInc = nInc;
1340
+ pChn->dwFlags &= ~(CHN_PINGPONGFLAG); // go forward
1341
+ if ((!(pChn->dwFlags & CHN_LOOP)) || (pChn->nPos >= pChn->nLength))
1342
+ {
1343
+ pChn->nPos = pChn->nLength;
1344
+ pChn->nPosLo = 0;
1345
+ return 0;
1346
+ }
1347
+ } else
1348
+ {
1349
+ // We probably didn't hit the loop end yet
1350
+ // (first loop), so we do nothing
1351
+ if ((LONG)pChn->nPos < 0) pChn->nPos = 0;
1352
+ }
1353
+ } else
1354
+ // Past the end
1355
+ if (pChn->nPos >= pChn->nLength)
1356
+ {
1357
+ if (!(pChn->dwFlags & CHN_LOOP)) return 0; // not looping -> stop this channel
1358
+ if (pChn->dwFlags & CHN_PINGPONGLOOP)
1359
+ {
1360
+ // Invert loop
1361
+ if (nInc > 0)
1362
+ {
1363
+ nInc = -nInc;
1364
+ pChn->nInc = nInc;
1365
+ }
1366
+ pChn->dwFlags |= CHN_PINGPONGFLAG;
1367
+ // adjust loop position
1368
+ LONG nDeltaHi = (pChn->nPos - pChn->nLength);
1369
+ LONG nDeltaLo = 0x10000 - (pChn->nPosLo & 0xffff);
1370
+ pChn->nPos = pChn->nLength - nDeltaHi - (nDeltaLo>>16);
1371
+ pChn->nPosLo = nDeltaLo & 0xffff;
1372
+ if ((pChn->nPos <= pChn->nLoopStart) ||
1373
+ (pChn->nPos >= pChn->nLength))
1374
+ pChn->nPos = pChn->nLength-1;
1375
+ } else
1376
+ {
1377
+ if (nInc < 0) // This is a bug
1378
+ {
1379
+ nInc = -nInc;
1380
+ pChn->nInc = nInc;
1381
+ }
1382
+ // Restart at loop start
1383
+ pChn->nPos += nLoopStart - pChn->nLength;
1384
+ if ((LONG)pChn->nPos < nLoopStart)
1385
+ pChn->nPos = pChn->nLoopStart;
1386
+ }
1387
+ }
1388
+ LONG nPos = pChn->nPos;
1389
+ // too big increment, and/or too small loop length
1390
+ if (nPos < nLoopStart)
1391
+ {
1392
+ if ((nPos < 0) || (nInc < 0)) return 0;
1393
+ }
1394
+ if ((nPos < 0) || (nPos >= (LONG)pChn->nLength)) return 0;
1395
+ LONG nPosLo = (USHORT)pChn->nPosLo, nSmpCount = nSamples;
1396
+ if (nInc < 0)
1397
+ {
1398
+ LONG nInv = -nInc;
1399
+ LONG maxsamples = 16384 / ((nInv>>16)+1);
1400
+ if (maxsamples < 2) maxsamples = 2;
1401
+ if (nSamples > maxsamples) nSamples = maxsamples;
1402
+ LONG nDeltaHi = (nInv>>16) * (nSamples - 1);
1403
+ LONG nDeltaLo = (nInv&0xffff) * (nSamples - 1);
1404
+ LONG nPosDest = nPos - nDeltaHi + ((nPosLo - nDeltaLo) >> 16);
1405
+ if (nPosDest < nLoopStart)
1406
+ {
1407
+ nSmpCount = (ULONG)(((((LONGLONG)nPos - nLoopStart) << 16) + nPosLo - 1) / nInv) + 1;
1408
+ }
1409
+ } else
1410
+ {
1411
+ LONG maxsamples = 16384 / ((nInc>>16)+1);
1412
+ if (maxsamples < 2) maxsamples = 2;
1413
+ if (nSamples > maxsamples) nSamples = maxsamples;
1414
+ LONG nDeltaHi = (nInc>>16) * (nSamples - 1);
1415
+ LONG nDeltaLo = (nInc&0xffff) * (nSamples - 1);
1416
+ LONG nPosDest = nPos + nDeltaHi + ((nPosLo + nDeltaLo)>>16);
1417
+ if (nPosDest >= (LONG)pChn->nLength)
1418
+ {
1419
+ nSmpCount = (ULONG)(((((LONGLONG)pChn->nLength - nPos) << 16) - nPosLo - 1) / nInc) + 1;
1420
+ }
1421
+ }
1422
+ if (nSmpCount <= 1) return 1;
1423
+ if (nSmpCount > nSamples) return nSamples;
1424
+ return nSmpCount;
1425
+ }
1426
+
1427
+
1428
+ UINT CSoundFile_CreateStereoMix(CSoundFile *_this, int count)
1429
+ //-----------------------------------------
1430
+ {
1431
+ LPLONG pOfsL, pOfsR;
1432
+ DWORD nchused, nchmixed;
1433
+ UINT nrampsamples;
1434
+
1435
+ if (!count) return 0;
1436
+ if (_this->gnChannels > 2) X86_InitMixBuffer(_this->MixRearBuffer, count*2);
1437
+ nchused = nchmixed = 0;
1438
+ for (UINT nChn=0; nChn<_this->m_nMixChannels; nChn++)
1439
+ {
1440
+ const LPMIXINTERFACE *pMixFuncTable;
1441
+ MODCHANNEL * const pChannel = &_this->Chn[_this->ChnMix[nChn]];
1442
+ UINT nFlags, nMasterCh;
1443
+ LONG nSmpCount;
1444
+ int nsamples;
1445
+ int *pbuffer;
1446
+
1447
+ if (!pChannel->pCurrentSample) continue;
1448
+ nMasterCh = (_this->ChnMix[nChn] < _this->m_nChannels) ? _this->ChnMix[nChn]+1 : pChannel->nMasterChn;
1449
+ pOfsR = &_this->gnDryROfsVol;
1450
+ pOfsL = &_this->gnDryLOfsVol;
1451
+ nFlags = 0;
1452
+ if (pChannel->dwFlags & CHN_16BIT) nFlags |= MIXNDX_16BIT;
1453
+ if (pChannel->dwFlags & CHN_STEREO) nFlags |= MIXNDX_STEREO;
1454
+ #ifndef NO_FILTER
1455
+ if (pChannel->dwFlags & CHN_FILTER) nFlags |= MIXNDX_FILTER;
1456
+ #endif
1457
+ if (!(pChannel->dwFlags & CHN_NOIDO))
1458
+ {
1459
+ // use hq-fir mixer?
1460
+ if( (_this->gdwSoundSetup & (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE)) ==
1461
+ (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE) )
1462
+ nFlags += MIXNDX_FIRSRC;
1463
+ else if( (_this->gdwSoundSetup & (SNDMIX_HQRESAMPLER)) == SNDMIX_HQRESAMPLER )
1464
+ nFlags += MIXNDX_SPLINESRC;
1465
+ else
1466
+ nFlags += MIXNDX_LINEARSRC; // use
1467
+ }
1468
+ if ((nFlags < 0x40) && (pChannel->nLeftVol == pChannel->nRightVol)
1469
+ && ((!pChannel->nRampLength) || (pChannel->nLeftRamp == pChannel->nRightRamp)))
1470
+ {
1471
+ pMixFuncTable = gpFastMixFunctionTable;
1472
+ } else
1473
+ {
1474
+ pMixFuncTable = gpMixFunctionTable;
1475
+ }
1476
+ nsamples = count;
1477
+ #ifndef MODPLUG_NO_REVERB
1478
+ pbuffer = (_this->gdwSoundSetup & SNDMIX_REVERB) ? _this->MixReverbBuffer : _this->MixSoundBuffer;
1479
+ if (pChannel->dwFlags & CHN_NOREVERB) pbuffer = _this->MixSoundBuffer;
1480
+ if (pChannel->dwFlags & CHN_REVERB) pbuffer = _this->MixReverbBuffer;
1481
+ if (pbuffer == _this->MixReverbBuffer)
1482
+ {
1483
+ if (!_this->gnReverbSend) SDL_memset(_this->MixReverbBuffer, 0, count * 8);
1484
+ _this->gnReverbSend += count;
1485
+ }
1486
+ #else
1487
+ pbuffer = _this->MixSoundBuffer;
1488
+ #endif
1489
+ nchused++;
1490
+ ////////////////////////////////////////////////////
1491
+ SampleLooping:
1492
+ nrampsamples = nsamples;
1493
+ if (pChannel->nRampLength > 0)
1494
+ {
1495
+ if ((LONG)nrampsamples > pChannel->nRampLength) nrampsamples = pChannel->nRampLength;
1496
+ }
1497
+ if ((nSmpCount = GetSampleCount(pChannel, nrampsamples)) <= 0)
1498
+ {
1499
+ // Stopping the channel
1500
+ pChannel->pCurrentSample = NULL;
1501
+ pChannel->nLength = 0;
1502
+ pChannel->nPos = 0;
1503
+ pChannel->nPosLo = 0;
1504
+ pChannel->nRampLength = 0;
1505
+ X86_EndChannelOfs(pChannel, pbuffer, nsamples);
1506
+ *pOfsR += pChannel->nROfs;
1507
+ *pOfsL += pChannel->nLOfs;
1508
+ pChannel->nROfs = pChannel->nLOfs = 0;
1509
+ pChannel->dwFlags &= ~CHN_PINGPONGFLAG;
1510
+ continue;
1511
+ }
1512
+ // Should we mix this channel ?
1513
+ UINT naddmix;
1514
+ if (((nchmixed >= _this->m_nMaxMixChannels) && (!(_this->gdwSoundSetup & SNDMIX_DIRECTTODISK)))
1515
+ || ((!pChannel->nRampLength) && (!(pChannel->nLeftVol|pChannel->nRightVol))))
1516
+ {
1517
+ LONG delta = (pChannel->nInc * (LONG)nSmpCount) + (LONG)pChannel->nPosLo;
1518
+ pChannel->nPosLo = delta & 0xFFFF;
1519
+ pChannel->nPos += (delta >> 16);
1520
+ pChannel->nROfs = pChannel->nLOfs = 0;
1521
+ pbuffer += nSmpCount*2;
1522
+ naddmix = 0;
1523
+ } else
1524
+ // Do mixing
1525
+ {
1526
+ // Choose function for mixing
1527
+ LPMIXINTERFACE pMixFunc;
1528
+ pMixFunc = (pChannel->nRampLength) ? pMixFuncTable[nFlags|MIXNDX_RAMP] : pMixFuncTable[nFlags];
1529
+ int *pbufmax = pbuffer + (nSmpCount*2);
1530
+ pChannel->nROfs = - *(pbufmax-2);
1531
+ pChannel->nLOfs = - *(pbufmax-1);
1532
+ pMixFunc(pChannel, pbuffer, pbufmax);
1533
+ pChannel->nROfs += *(pbufmax-2);
1534
+ pChannel->nLOfs += *(pbufmax-1);
1535
+ pbuffer = pbufmax;
1536
+ naddmix = 1;
1537
+
1538
+ }
1539
+ nsamples -= nSmpCount;
1540
+ if (pChannel->nRampLength)
1541
+ {
1542
+ pChannel->nRampLength -= nSmpCount;
1543
+ if (pChannel->nRampLength <= 0)
1544
+ {
1545
+ pChannel->nRampLength = 0;
1546
+ pChannel->nRightVol = pChannel->nNewRightVol;
1547
+ pChannel->nLeftVol = pChannel->nNewLeftVol;
1548
+ pChannel->nRightRamp = pChannel->nLeftRamp = 0;
1549
+ if ((pChannel->dwFlags & CHN_NOTEFADE) && (!(pChannel->nFadeOutVol)))
1550
+ {
1551
+ pChannel->nLength = 0;
1552
+ pChannel->pCurrentSample = NULL;
1553
+ }
1554
+ }
1555
+ }
1556
+ if (nsamples > 0) goto SampleLooping;
1557
+ nchmixed += naddmix;
1558
+ }
1559
+ return nchused;
1560
+ }
1561
+
1562
+
1563
+ // Clip and convert to 8 bit
1564
+ //---GCCFIX: Asm replaced with C function
1565
+ // The C version was written by Rani Assaf <rani@magic.metawire.com>, I believe
1566
+ DWORD MPPASMCALL X86_Convert32To8(LPVOID lp8, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
1567
+ {
1568
+ int vumin = *lpMin, vumax = *lpMax;
1569
+ unsigned char *p = (unsigned char *)lp8;
1570
+ for (UINT i=0; i<lSampleCount; i++)
1571
+ {
1572
+ int n = pBuffer[i];
1573
+ if (n < MIXING_CLIPMIN)
1574
+ n = MIXING_CLIPMIN;
1575
+ else if (n > MIXING_CLIPMAX)
1576
+ n = MIXING_CLIPMAX;
1577
+ if (n < vumin)
1578
+ vumin = n;
1579
+ else if (n > vumax)
1580
+ vumax = n;
1581
+ p[i] = (n >> (24-MIXING_ATTENUATION)) ^ 0x80; // 8-bit unsigned
1582
+ }
1583
+ *lpMin = vumin;
1584
+ *lpMax = vumax;
1585
+ return lSampleCount;
1586
+ }
1587
+
1588
+
1589
+ // Clip and convert to 16 bit
1590
+ //---GCCFIX: Asm replaced with C function
1591
+ // The C version was written by Rani Assaf <rani@magic.metawire.com>, I believe
1592
+ DWORD MPPASMCALL X86_Convert32To16(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
1593
+ {
1594
+ int vumin = *lpMin, vumax = *lpMax;
1595
+ signed short *p = (signed short *)lp16;
1596
+ for (UINT i=0; i<lSampleCount; i++)
1597
+ {
1598
+ int n = pBuffer[i];
1599
+ if (n < MIXING_CLIPMIN)
1600
+ n = MIXING_CLIPMIN;
1601
+ else if (n > MIXING_CLIPMAX)
1602
+ n = MIXING_CLIPMAX;
1603
+ if (n < vumin)
1604
+ vumin = n;
1605
+ else if (n > vumax)
1606
+ vumax = n;
1607
+ p[i] = n >> (16-MIXING_ATTENUATION); // 16-bit signed
1608
+ }
1609
+ *lpMin = vumin;
1610
+ *lpMax = vumax;
1611
+ return lSampleCount * 2;
1612
+ }
1613
+
1614
+ // Clip and convert to 24 bit
1615
+ //---GCCFIX: Asm replaced with C function
1616
+ DWORD MPPASMCALL X86_Convert32To24(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
1617
+ {
1618
+ UINT i ;
1619
+ int vumin = *lpMin, vumax = *lpMax;
1620
+ int n,p ;
1621
+ unsigned char* buf = (unsigned char*)lp16 ;
1622
+
1623
+ for ( i=0; i<lSampleCount; i++)
1624
+ {
1625
+ n = pBuffer[i];
1626
+ if (n < MIXING_CLIPMIN)
1627
+ n = MIXING_CLIPMIN;
1628
+ else if (n > MIXING_CLIPMAX)
1629
+ n = MIXING_CLIPMAX;
1630
+ if (n < vumin)
1631
+ vumin = n;
1632
+ else if (n > vumax)
1633
+ vumax = n;
1634
+ p = n >> (8-MIXING_ATTENUATION) ; // 24-bit signed
1635
+ #ifdef WORDS_BIGENDIAN
1636
+ buf[i*3+0] = p & 0xFF0000 >> 24;
1637
+ buf[i*3+1] = p & 0x00FF00 >> 16 ;
1638
+ buf[i*3+2] = p & 0x0000FF ;
1639
+ #else
1640
+ buf[i*3+0] = p & 0x0000FF ;
1641
+ buf[i*3+1] = p & 0x00FF00 >> 16;
1642
+ buf[i*3+2] = p & 0xFF0000 >> 24;
1643
+ #endif
1644
+ }
1645
+ *lpMin = vumin;
1646
+ *lpMax = vumax;
1647
+ return lSampleCount * 3;
1648
+ }
1649
+
1650
+ // Clip and convert to 32 bit
1651
+ //---GCCFIX: Asm replaced with C function
1652
+ DWORD MPPASMCALL X86_Convert32To32(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LPLONG lpMin, LPLONG lpMax)
1653
+ {
1654
+ UINT i ;
1655
+ int vumin = *lpMin, vumax = *lpMax;
1656
+ int32_t *p = (int32_t *)lp16;
1657
+
1658
+ for ( i=0; i<lSampleCount; i++)
1659
+ {
1660
+ int n = pBuffer[i];
1661
+ if (n < MIXING_CLIPMIN)
1662
+ n = MIXING_CLIPMIN;
1663
+ else if (n > MIXING_CLIPMAX)
1664
+ n = MIXING_CLIPMAX;
1665
+ if (n < vumin)
1666
+ vumin = n;
1667
+ else if (n > vumax)
1668
+ vumax = n;
1669
+ p[i] = n << MIXING_ATTENUATION; // 32-bit signed
1670
+ }
1671
+ *lpMin = vumin;
1672
+ *lpMax = vumax;
1673
+ return lSampleCount * 4;
1674
+ }
1675
+
1676
+ //---GCCFIX: Asm replaced with C function
1677
+ // Will fill in later.
1678
+ void MPPASMCALL X86_InitMixBuffer(int *pBuffer, UINT nSamples)
1679
+ {
1680
+ SDL_memset(pBuffer, 0, nSamples * sizeof(int));
1681
+ }
1682
+
1683
+
1684
+ //---GCCFIX: Asm replaced with C function
1685
+ // Multichannel not supported.
1686
+ void MPPASMCALL X86_InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples)
1687
+ {
1688
+ }
1689
+
1690
+ //---GCCFIX: Asm replaced with C function
1691
+ VOID MPPASMCALL X86_MonoFromStereo(int *pMixBuf, UINT nSamples)
1692
+ {
1693
+ UINT j;
1694
+ for(UINT i = 0; i < nSamples; i++)
1695
+ {
1696
+ j = i << 1;
1697
+ pMixBuf[i] = (pMixBuf[j] + pMixBuf[j + 1]) >> 1;
1698
+ }
1699
+ }
1700
+
1701
+ //---GCCFIX: Asm replaced with C function
1702
+ #define OFSDECAYSHIFT 8
1703
+ #define OFSDECAYMASK 0xFF
1704
+ void MPPASMCALL X86_StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs)
1705
+ //----------------------------------------------------------------------------
1706
+ {
1707
+ int rofs = *lpROfs;
1708
+ int lofs = *lpLOfs;
1709
+
1710
+ if ((!rofs) && (!lofs))
1711
+ {
1712
+ X86_InitMixBuffer(pBuffer, nSamples*2);
1713
+ return;
1714
+ }
1715
+ for (UINT i=0; i<nSamples; i++)
1716
+ {
1717
+ int x_r = (rofs + (((-rofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
1718
+ int x_l = (lofs + (((-lofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
1719
+ rofs -= x_r;
1720
+ lofs -= x_l;
1721
+ pBuffer[i*2] = x_r;
1722
+ pBuffer[i*2+1] = x_l;
1723
+ }
1724
+ *lpROfs = rofs;
1725
+ *lpLOfs = lofs;
1726
+ }
1727
+
1728
+ //---GCCFIX: Asm replaced with C function
1729
+ // Will fill in later.
1730
+ void MPPASMCALL X86_EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples)
1731
+ {
1732
+ int rofs = pChannel->nROfs;
1733
+ int lofs = pChannel->nLOfs;
1734
+
1735
+ if ((!rofs) && (!lofs)) return;
1736
+ for (UINT i=0; i<nSamples; i++)
1737
+ {
1738
+ int x_r = (rofs + (((-rofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
1739
+ int x_l = (lofs + (((-lofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
1740
+ rofs -= x_r;
1741
+ lofs -= x_l;
1742
+ pBuffer[i*2] += x_r;
1743
+ pBuffer[i*2+1] += x_l;
1744
+ }
1745
+ pChannel->nROfs = rofs;
1746
+ pChannel->nLOfs = lofs;
1747
+ }
1748
+