gosu 0.15.1 → 1.1.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+