Diffstat (limited to 'core/multimedia/opieplayer/modplug/snd_dsp.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/modplug/snd_dsp.cpp | 488 |
1 files changed, 488 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/modplug/snd_dsp.cpp b/core/multimedia/opieplayer/modplug/snd_dsp.cpp new file mode 100644 index 0000000..c14194e --- a/dev/null +++ b/core/multimedia/opieplayer/modplug/snd_dsp.cpp | |||
@@ -0,0 +1,488 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and modify it | ||
3 | * under the terms of the GNU General Public License as published by the | ||
4 | * Free Software Foundation; either version 2 of the license or (at your | ||
5 | * option) any later version. | ||
6 | * | ||
7 | * Authors: Olivier Lapicque <olivierl@jps.net> | ||
8 | */ | ||
9 | |||
10 | #include "stdafx.h" | ||
11 | #include "sndfile.h" | ||
12 | |||
13 | #ifdef FASTSOUNDLIB | ||
14 | #define NO_REVERB | ||
15 | #endif | ||
16 | |||
17 | |||
18 | // Delayed Surround Filters | ||
19 | #ifndef FASTSOUNDLIB | ||
20 | #define nDolbyHiFltAttn 6 | ||
21 | #define nDolbyHiFltMask 3 | ||
22 | #define DOLBYATTNROUNDUP31 | ||
23 | #else | ||
24 | #define nDolbyHiFltAttn 3 | ||
25 | #define nDolbyHiFltMask 3 | ||
26 | #define DOLBYATTNROUNDUP3 | ||
27 | #endif | ||
28 | |||
29 | // Bass Expansion | ||
30 | #define XBASS_DELAY 14// 2.5 ms | ||
31 | |||
32 | // Buffer Sizes | ||
33 | #define XBASSBUFFERSIZE 64 // 2 ms at 50KHz | ||
34 | #define FILTERBUFFERSIZE 64 // 1.25 ms | ||
35 | #define SURROUNDBUFFERSIZE((MAX_SAMPLE_RATE * 50) / 1000) | ||
36 | #define REVERBBUFFERSIZE((MAX_SAMPLE_RATE * 200) / 1000) | ||
37 | #define REVERBBUFFERSIZE2((REVERBBUFFERSIZE*13) / 17) | ||
38 | #define REVERBBUFFERSIZE3((REVERBBUFFERSIZE*7) / 13) | ||
39 | #define REVERBBUFFERSIZE4((REVERBBUFFERSIZE*7) / 19) | ||
40 | |||
41 | |||
42 | // DSP Effects: PUBLIC members | ||
43 | UINT CSoundFile::m_nXBassDepth = 6; | ||
44 | UINT CSoundFile::m_nXBassRange = XBASS_DELAY; | ||
45 | UINT CSoundFile::m_nReverbDepth = 1; | ||
46 | UINT CSoundFile::m_nReverbDelay = 100; | ||
47 | UINT CSoundFile::m_nProLogicDepth = 12; | ||
48 | UINT CSoundFile::m_nProLogicDelay = 20; | ||
49 | |||
50 | //////////////////////////////////////////////////////////////////// | ||
51 | // DSP Effects internal state | ||
52 | |||
53 | // Bass Expansion: low-pass filter | ||
54 | static LONG nXBassSum = 0; | ||
55 | static LONG nXBassBufferPos = 0; | ||
56 | static LONG nXBassDlyPos = 0; | ||
57 | static LONG nXBassMask = 0; | ||
58 | |||
59 | // Noise Reduction: simple low-pass filter | ||
60 | static LONG nLeftNR = 0; | ||
61 | static LONG nRightNR = 0; | ||
62 | |||
63 | // Surround Encoding: 1 delay line + low-pass filter + high-pass filter | ||
64 | static LONG nSurroundSize = 0; | ||
65 | static LONG nSurroundPos = 0; | ||
66 | static LONG nDolbyDepth = 0; | ||
67 | static LONG nDolbyLoDlyPos = 0; | ||
68 | static LONG nDolbyLoFltPos = 0; | ||
69 | static LONG nDolbyLoFltSum = 0; | ||
70 | static LONG nDolbyHiFltPos = 0; | ||
71 | static LONG nDolbyHiFltSum = 0; | ||
72 | |||
73 | // Reverb: 4 delay lines + high-pass filter + low-pass filter | ||
74 | #ifndef NO_REVERB | ||
75 | static LONG nReverbSize = 0; | ||
76 | static LONG nReverbBufferPos = 0; | ||
77 | static LONG nReverbSize2 = 0; | ||
78 | static LONG nReverbBufferPos2 = 0; | ||
79 | static LONG nReverbSize3 = 0; | ||
80 | static LONG nReverbBufferPos3 = 0; | ||
81 | static LONG nReverbSize4 = 0; | ||
82 | static LONG nReverbBufferPos4 = 0; | ||
83 | static LONG nReverbLoFltSum = 0; | ||
84 | static LONG nReverbLoFltPos = 0; | ||
85 | static LONG nReverbLoDlyPos = 0; | ||
86 | static LONG nFilterAttn = 0; | ||
87 | static LONG gRvbLowPass[8]; | ||
88 | static LONG gRvbLPPos = 0; | ||
89 | static LONG gRvbLPSum = 0; | ||
90 | static LONG ReverbLoFilterBuffer[XBASSBUFFERSIZE]; | ||
91 | static LONG ReverbLoFilterDelay[XBASSBUFFERSIZE]; | ||
92 | static LONG ReverbBuffer[REVERBBUFFERSIZE]; | ||
93 | static LONG ReverbBuffer2[REVERBBUFFERSIZE2]; | ||
94 | static LONG ReverbBuffer3[REVERBBUFFERSIZE3]; | ||
95 | static LONG ReverbBuffer4[REVERBBUFFERSIZE4]; | ||
96 | #endif | ||
97 | static LONG XBassBuffer[XBASSBUFFERSIZE]; | ||
98 | static LONG XBassDelay[XBASSBUFFERSIZE]; | ||
99 | static LONG DolbyLoFilterBuffer[XBASSBUFFERSIZE]; | ||
100 | static LONG DolbyLoFilterDelay[XBASSBUFFERSIZE]; | ||
101 | static LONG DolbyHiFilterBuffer[FILTERBUFFERSIZE]; | ||
102 | static LONG SurroundBuffer[SURROUNDBUFFERSIZE]; | ||
103 | |||
104 | // Access the main temporary mix buffer directly: avoids an extra pointer | ||
105 | extern int MixSoundBuffer[MIXBUFFERSIZE*2]; | ||
106 | //cextern int MixReverbBuffer[MIXBUFFERSIZE*2]; | ||
107 | extern int MixReverbBuffer[MIXBUFFERSIZE*2]; | ||
108 | |||
109 | static UINT GetMaskFromSize(UINT len) | ||
110 | //----------------------------------- | ||
111 | { | ||
112 | UINT n = 2; | ||
113 | while (n <= len) n <<= 1; | ||
114 | return ((n >> 1) - 1); | ||
115 | } | ||
116 | |||
117 | |||
118 | void CSoundFile::InitializeDSP(BOOL bReset) | ||
119 | //----------------------------------------- | ||
120 | { | ||
121 | if (!m_nReverbDelay) m_nReverbDelay = 100; | ||
122 | if (!m_nXBassRange) m_nXBassRange = XBASS_DELAY; | ||
123 | if (!m_nProLogicDelay) m_nProLogicDelay = 20; | ||
124 | if (m_nXBassDepth > 8) m_nXBassDepth = 8; | ||
125 | if (m_nXBassDepth < 2) m_nXBassDepth = 2; | ||
126 | if (bReset) | ||
127 | { | ||
128 | // Noise Reduction | ||
129 | nLeftNR = nRightNR = 0; | ||
130 | } | ||
131 | // Pro-Logic Surround | ||
132 | nSurroundPos = nSurroundSize = 0; | ||
133 | nDolbyLoFltPos = nDolbyLoFltSum = nDolbyLoDlyPos = 0; | ||
134 | nDolbyHiFltPos = nDolbyHiFltSum = 0; | ||
135 | if (gdwSoundSetup & SNDMIX_SURROUND) | ||
136 | { | ||
137 | memset(DolbyLoFilterBuffer, 0, sizeof(DolbyLoFilterBuffer)); | ||
138 | memset(DolbyHiFilterBuffer, 0, sizeof(DolbyHiFilterBuffer)); | ||
139 | memset(DolbyLoFilterDelay, 0, sizeof(DolbyLoFilterDelay)); | ||
140 | memset(SurroundBuffer, 0, sizeof(SurroundBuffer)); | ||
141 | nSurroundSize = (gdwMixingFreq * m_nProLogicDelay) / 1000; | ||
142 | if (nSurroundSize > SURROUNDBUFFERSIZE) nSurroundSize = SURROUNDBUFFERSIZE; | ||
143 | if (m_nProLogicDepth < 8) nDolbyDepth = (32 >> m_nProLogicDepth) + 32; | ||
144 | else nDolbyDepth = (m_nProLogicDepth < 16) ? (8 + (m_nProLogicDepth - 8) * 7) : 64; | ||
145 | nDolbyDepth >>= 2; | ||
146 | } | ||
147 | // Reverb Setup | ||
148 | #ifndef NO_REVERB | ||
149 | if (gdwSoundSetup & SNDMIX_REVERB) | ||
150 | { | ||
151 | UINT nrs = (gdwMixingFreq * m_nReverbDelay) / 1000; | ||
152 | UINT nfa = m_nReverbDepth+1; | ||
153 | if (nrs > REVERBBUFFERSIZE) nrs = REVERBBUFFERSIZE; | ||
154 | if ((bReset) || (nrs != (UINT)nReverbSize) || (nfa != (UINT)nFilterAttn)) | ||
155 | { | ||
156 | nFilterAttn = nfa; | ||
157 | nReverbSize = nrs; | ||
158 | nReverbBufferPos = nReverbBufferPos2 = nReverbBufferPos3 = nReverbBufferPos4 = 0; | ||
159 | nReverbLoFltSum = nReverbLoFltPos = nReverbLoDlyPos = 0; | ||
160 | gRvbLPSum = gRvbLPPos = 0; | ||
161 | nReverbSize2 = (nReverbSize * 13) / 17; | ||
162 | if (nReverbSize2 > REVERBBUFFERSIZE2) nReverbSize2 = REVERBBUFFERSIZE2; | ||
163 | nReverbSize3 = (nReverbSize * 7) / 13; | ||
164 | if (nReverbSize3 > REVERBBUFFERSIZE3) nReverbSize3 = REVERBBUFFERSIZE3; | ||
165 | nReverbSize4 = (nReverbSize * 7) / 19; | ||
166 | if (nReverbSize4 > REVERBBUFFERSIZE4) nReverbSize4 = REVERBBUFFERSIZE4; | ||
167 | memset(ReverbLoFilterBuffer, 0, sizeof(ReverbLoFilterBuffer)); | ||
168 | memset(ReverbLoFilterDelay, 0, sizeof(ReverbLoFilterDelay)); | ||
169 | memset(ReverbBuffer, 0, sizeof(ReverbBuffer)); | ||
170 | memset(ReverbBuffer2, 0, sizeof(ReverbBuffer2)); | ||
171 | memset(ReverbBuffer3, 0, sizeof(ReverbBuffer3)); | ||
172 | memset(ReverbBuffer4, 0, sizeof(ReverbBuffer4)); | ||
173 | memset(gRvbLowPass, 0, sizeof(gRvbLowPass)); | ||
174 | } | ||
175 | } else nReverbSize = 0; | ||
176 | #endif | ||
177 | BOOL bResetBass = FALSE; | ||
178 | // Bass Expansion Reset | ||
179 | if (gdwSoundSetup & SNDMIX_MEGABASS) | ||
180 | { | ||
181 | UINT nXBassSamples = (gdwMixingFreq * m_nXBassRange) / 10000; | ||
182 | if (nXBassSamples > XBASSBUFFERSIZE) nXBassSamples = XBASSBUFFERSIZE; | ||
183 | UINT mask = GetMaskFromSize(nXBassSamples); | ||
184 | if ((bReset) || (mask != (UINT)nXBassMask)) | ||
185 | { | ||
186 | nXBassMask = mask; | ||
187 | bResetBass = TRUE; | ||
188 | } | ||
189 | } else | ||
190 | { | ||
191 | nXBassMask = 0; | ||
192 | bResetBass = TRUE; | ||
193 | } | ||
194 | if (bResetBass) | ||
195 | { | ||
196 | nXBassSum = nXBassBufferPos = nXBassDlyPos = 0; | ||
197 | memset(XBassBuffer, 0, sizeof(XBassBuffer)); | ||
198 | memset(XBassDelay, 0, sizeof(XBassDelay)); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | |||
203 | void CSoundFile::ProcessStereoDSP(int count) | ||
204 | //------------------------------------------ | ||
205 | { | ||
206 | #ifndef NO_REVERB | ||
207 | // Reverb | ||
208 | if (gdwSoundSetup & SNDMIX_REVERB) | ||
209 | { | ||
210 | int *pr = MixSoundBuffer, *pin = MixReverbBuffer, rvbcount = count; | ||
211 | do | ||
212 | { | ||
213 | int echo = ReverbBuffer[nReverbBufferPos] + ReverbBuffer2[nReverbBufferPos2] | ||
214 | + ReverbBuffer3[nReverbBufferPos3] + ReverbBuffer4[nReverbBufferPos4];// echo = reverb signal | ||
215 | // Delay line and remove Low Frequencies // v = original signal | ||
216 | int echodly = ReverbLoFilterDelay[nReverbLoDlyPos];// echodly = delayed signal | ||
217 | ReverbLoFilterDelay[nReverbLoDlyPos] = echo >> 1; | ||
218 | nReverbLoDlyPos++; | ||
219 | nReverbLoDlyPos &= 0x1F; | ||
220 | int n = nReverbLoFltPos; | ||
221 | nReverbLoFltSum -= ReverbLoFilterBuffer[n]; | ||
222 | int tmp = echo / 128; | ||
223 | ReverbLoFilterBuffer[n] = tmp; | ||
224 | nReverbLoFltSum += tmp; | ||
225 | echodly -= nReverbLoFltSum; | ||
226 | nReverbLoFltPos = (n + 1) & 0x3F; | ||
227 | // Reverb | ||
228 | int v = (pin[0]+pin[1]) >> nFilterAttn; | ||
229 | pr[0] += pin[0] + echodly; | ||
230 | pr[1] += pin[1] + echodly; | ||
231 | v += echodly >> 2; | ||
232 | ReverbBuffer3[nReverbBufferPos3] = v; | ||
233 | ReverbBuffer4[nReverbBufferPos4] = v; | ||
234 | v += echodly >> 4; | ||
235 | v >>= 1; | ||
236 | gRvbLPSum -= gRvbLowPass[gRvbLPPos]; | ||
237 | gRvbLPSum += v; | ||
238 | gRvbLowPass[gRvbLPPos] = v; | ||
239 | gRvbLPPos++; | ||
240 | gRvbLPPos &= 7; | ||
241 | int vlp = gRvbLPSum >> 2; | ||
242 | ReverbBuffer[nReverbBufferPos] = vlp; | ||
243 | ReverbBuffer2[nReverbBufferPos2] = vlp; | ||
244 | if (++nReverbBufferPos >= nReverbSize) nReverbBufferPos = 0; | ||
245 | if (++nReverbBufferPos2 >= nReverbSize2) nReverbBufferPos2 = 0; | ||
246 | if (++nReverbBufferPos3 >= nReverbSize3) nReverbBufferPos3 = 0; | ||
247 | if (++nReverbBufferPos4 >= nReverbSize4) nReverbBufferPos4 = 0; | ||
248 | pr += 2; | ||
249 | pin += 2; | ||
250 | } while (--rvbcount); | ||
251 | } | ||
252 | #endif | ||
253 | // Dolby Pro-Logic Surround | ||
254 | if (gdwSoundSetup & SNDMIX_SURROUND) | ||
255 | { | ||
256 | int *pr = MixSoundBuffer, n = nDolbyLoFltPos; | ||
257 | for (int r=count; r; r--) | ||
258 | { | ||
259 | int v = (pr[0]+pr[1]+DOLBYATTNROUNDUP) >> (nDolbyHiFltAttn+1); | ||
260 | #ifndef FASTSOUNDLIB | ||
261 | v *= (int)nDolbyDepth; | ||
262 | #endif | ||
263 | // Low-Pass Filter | ||
264 | nDolbyHiFltSum -= DolbyHiFilterBuffer[nDolbyHiFltPos]; | ||
265 | DolbyHiFilterBuffer[nDolbyHiFltPos] = v; | ||
266 | nDolbyHiFltSum += v; | ||
267 | v = nDolbyHiFltSum; | ||
268 | nDolbyHiFltPos++; | ||
269 | nDolbyHiFltPos &= nDolbyHiFltMask; | ||
270 | // Surround | ||
271 | int secho = SurroundBuffer[nSurroundPos]; | ||
272 | SurroundBuffer[nSurroundPos] = v; | ||
273 | // Delay line and remove low frequencies | ||
274 | v = DolbyLoFilterDelay[nDolbyLoDlyPos]; // v = delayed signal | ||
275 | DolbyLoFilterDelay[nDolbyLoDlyPos] = secho;// secho = signal | ||
276 | nDolbyLoDlyPos++; | ||
277 | nDolbyLoDlyPos &= 0x1F; | ||
278 | nDolbyLoFltSum -= DolbyLoFilterBuffer[n]; | ||
279 | int tmp = secho / 64; | ||
280 | DolbyLoFilterBuffer[n] = tmp; | ||
281 | nDolbyLoFltSum += tmp; | ||
282 | v -= nDolbyLoFltSum; | ||
283 | n++; | ||
284 | n &= 0x3F; | ||
285 | // Add echo | ||
286 | pr[0] += v; | ||
287 | pr[1] -= v; | ||
288 | if (++nSurroundPos >= nSurroundSize) nSurroundPos = 0; | ||
289 | pr += 2; | ||
290 | } | ||
291 | nDolbyLoFltPos = n; | ||
292 | } | ||
293 | // Bass Expansion | ||
294 | if (gdwSoundSetup & SNDMIX_MEGABASS) | ||
295 | { | ||
296 | int *px = MixSoundBuffer; | ||
297 | int xba = m_nXBassDepth+1, xbamask = (1 << xba) - 1; | ||
298 | int n = nXBassBufferPos; | ||
299 | for (int x=count; x; x--) | ||
300 | { | ||
301 | nXBassSum -= XBassBuffer[n]; | ||
302 | int tmp0 = px[0] + px[1]; | ||
303 | int tmp = (tmp0 + ((tmp0 >> 31) & xbamask)) >> xba; | ||
304 | XBassBuffer[n] = tmp; | ||
305 | nXBassSum += tmp; | ||
306 | int v = XBassDelay[nXBassDlyPos]; | ||
307 | XBassDelay[nXBassDlyPos] = px[0]; | ||
308 | px[0] = v + nXBassSum; | ||
309 | v = XBassDelay[nXBassDlyPos+1]; | ||
310 | XBassDelay[nXBassDlyPos+1] = px[1]; | ||
311 | px[1] = v + nXBassSum; | ||
312 | nXBassDlyPos = (nXBassDlyPos + 2) & nXBassMask; | ||
313 | px += 2; | ||
314 | n++; | ||
315 | n &= nXBassMask; | ||
316 | } | ||
317 | nXBassBufferPos = n; | ||
318 | } | ||
319 | // Noise Reduction | ||
320 | if (gdwSoundSetup & SNDMIX_NOISEREDUCTION) | ||
321 | { | ||
322 | int n1 = nLeftNR, n2 = nRightNR; | ||
323 | int *pnr = MixSoundBuffer; | ||
324 | for (int nr=count; nr; nr--) | ||
325 | { | ||
326 | int vnr = pnr[0] >> 1; | ||
327 | pnr[0] = vnr + n1; | ||
328 | n1 = vnr; | ||
329 | vnr = pnr[1] >> 1; | ||
330 | pnr[1] = vnr + n2; | ||
331 | n2 = vnr; | ||
332 | pnr += 2; | ||
333 | } | ||
334 | nLeftNR = n1; | ||
335 | nRightNR = n2; | ||
336 | } | ||
337 | } | ||
338 | |||
339 | |||
340 | void CSoundFile::ProcessMonoDSP(int count) | ||
341 | //---------------------------------------- | ||
342 | { | ||
343 | #ifndef NO_REVERB | ||
344 | // Reverb | ||
345 | if (gdwSoundSetup & SNDMIX_REVERB) | ||
346 | { | ||
347 | int *pr = MixSoundBuffer, rvbcount = count, *pin = MixReverbBuffer; | ||
348 | do | ||
349 | { | ||
350 | int echo = ReverbBuffer[nReverbBufferPos] + ReverbBuffer2[nReverbBufferPos2] | ||
351 | + ReverbBuffer3[nReverbBufferPos3] + ReverbBuffer4[nReverbBufferPos4];// echo = reverb signal | ||
352 | // Delay line and remove Low Frequencies // v = original signal | ||
353 | int echodly = ReverbLoFilterDelay[nReverbLoDlyPos];// echodly = delayed signal | ||
354 | ReverbLoFilterDelay[nReverbLoDlyPos] = echo >> 1; | ||
355 | nReverbLoDlyPos++; | ||
356 | nReverbLoDlyPos &= 0x1F; | ||
357 | int n = nReverbLoFltPos; | ||
358 | nReverbLoFltSum -= ReverbLoFilterBuffer[n]; | ||
359 | int tmp = echo / 128; | ||
360 | ReverbLoFilterBuffer[n] = tmp; | ||
361 | nReverbLoFltSum += tmp; | ||
362 | echodly -= nReverbLoFltSum; | ||
363 | nReverbLoFltPos = (n + 1) & 0x3F; | ||
364 | // Reverb | ||
365 | int v = pin[0] >> (nFilterAttn-1); | ||
366 | *pr++ += pin[0] + echodly; | ||
367 | pin++; | ||
368 | v += echodly >> 2; | ||
369 | ReverbBuffer3[nReverbBufferPos3] = v; | ||
370 | ReverbBuffer4[nReverbBufferPos4] = v; | ||
371 | v += echodly >> 4; | ||
372 | v >>= 1; | ||
373 | gRvbLPSum -= gRvbLowPass[gRvbLPPos]; | ||
374 | gRvbLPSum += v; | ||
375 | gRvbLowPass[gRvbLPPos] = v; | ||
376 | gRvbLPPos++; | ||
377 | gRvbLPPos &= 7; | ||
378 | int vlp = gRvbLPSum >> 2; | ||
379 | ReverbBuffer[nReverbBufferPos] = vlp; | ||
380 | ReverbBuffer2[nReverbBufferPos2] = vlp; | ||
381 | if (++nReverbBufferPos >= nReverbSize) nReverbBufferPos = 0; | ||
382 | if (++nReverbBufferPos2 >= nReverbSize2) nReverbBufferPos2 = 0; | ||
383 | if (++nReverbBufferPos3 >= nReverbSize3) nReverbBufferPos3 = 0; | ||
384 | if (++nReverbBufferPos4 >= nReverbSize4) nReverbBufferPos4 = 0; | ||
385 | } while (--rvbcount); | ||
386 | } | ||
387 | #endif | ||
388 | // Bass Expansion | ||
389 | if (gdwSoundSetup & SNDMIX_MEGABASS) | ||
390 | { | ||
391 | int *px = MixSoundBuffer; | ||
392 | int xba = m_nXBassDepth, xbamask = (1 << xba)-1; | ||
393 | int n = nXBassBufferPos; | ||
394 | for (int x=count; x; x--) | ||
395 | { | ||
396 | nXBassSum -= XBassBuffer[n]; | ||
397 | int tmp0 = *px; | ||
398 | int tmp = (tmp0 + ((tmp0 >> 31) & xbamask)) >> xba; | ||
399 | XBassBuffer[n] = tmp; | ||
400 | nXBassSum += tmp; | ||
401 | int v = XBassDelay[nXBassDlyPos]; | ||
402 | XBassDelay[nXBassDlyPos] = *px; | ||
403 | *px++ = v + nXBassSum; | ||
404 | nXBassDlyPos = (nXBassDlyPos + 2) & nXBassMask; | ||
405 | n++; | ||
406 | n &= nXBassMask; | ||
407 | } | ||
408 | nXBassBufferPos = n; | ||
409 | } | ||
410 | // Noise Reduction | ||
411 | if (gdwSoundSetup & SNDMIX_NOISEREDUCTION) | ||
412 | { | ||
413 | int n = nLeftNR; | ||
414 | int *pnr = MixSoundBuffer; | ||
415 | for (int nr=count; nr; pnr++, nr--) | ||
416 | { | ||
417 | int vnr = *pnr >> 1; | ||
418 | *pnr = vnr + n; | ||
419 | n = vnr; | ||
420 | } | ||
421 | nLeftNR = n; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | |||
426 | ///////////////////////////////////////////////////////////////// | ||
427 | // Clean DSP Effects interface | ||
428 | |||
429 | // [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms] | ||
430 | BOOL CSoundFile::SetReverbParameters(UINT nDepth, UINT nDelay) | ||
431 | //------------------------------------------------------------ | ||
432 | { | ||
433 | if (nDepth > 100) nDepth = 100; | ||
434 | UINT gain = nDepth / 20; | ||
435 | if (gain > 4) gain = 4; | ||
436 | m_nReverbDepth = 4 - gain; | ||
437 | if (nDelay < 40) nDelay = 40; | ||
438 | if (nDelay > 250) nDelay = 250; | ||
439 | m_nReverbDelay = nDelay; | ||
440 | return TRUE; | ||
441 | } | ||
442 | |||
443 | |||
444 | // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 20-100] | ||
445 | BOOL CSoundFile::SetXBassParameters(UINT nDepth, UINT nRange) | ||
446 | //----------------------------------------------------------- | ||
447 | { | ||
448 | if (nDepth > 100) nDepth = 100; | ||
449 | UINT gain = nDepth / 20; | ||
450 | if (gain > 4) gain = 4; | ||
451 | m_nXBassDepth = 8 - gain;// filter attenuation 1/256 .. 1/16 | ||
452 | UINT range = nRange / 5; | ||
453 | if (range > 5) range -= 5; else range = 0; | ||
454 | if (nRange > 16) nRange = 16; | ||
455 | m_nXBassRange = 21 - range;// filter average on 0.5-1.6ms | ||
456 | return TRUE; | ||
457 | } | ||
458 | |||
459 | |||
460 | // [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-50ms] | ||
461 | BOOL CSoundFile::SetSurroundParameters(UINT nDepth, UINT nDelay) | ||
462 | //-------------------------------------------------------------- | ||
463 | { | ||
464 | UINT gain = (nDepth * 16) / 100; | ||
465 | if (gain > 16) gain = 16; | ||
466 | if (gain < 1) gain = 1; | ||
467 | m_nProLogicDepth = gain; | ||
468 | if (nDelay < 4) nDelay = 4; | ||
469 | if (nDelay > 50) nDelay = 50; | ||
470 | m_nProLogicDelay = nDelay; | ||
471 | return TRUE; | ||
472 | } | ||
473 | |||
474 | BOOL CSoundFile::SetWaveConfigEx(BOOL bSurround,BOOL bNoOverSampling,BOOL bReverb,BOOL hqido,BOOL bMegaBass,BOOL bNR,BOOL bEQ) | ||
475 | //---------------------------------------------------------------------------------------------------------------------------- | ||
476 | { | ||
477 | DWORD d = gdwSoundSetup & ~(SNDMIX_SURROUND | SNDMIX_NORESAMPLING | SNDMIX_REVERB | SNDMIX_HQRESAMPLER | SNDMIX_MEGABASS | SNDMIX_NOISEREDUCTION | SNDMIX_EQ); | ||
478 | if (bSurround) d |= SNDMIX_SURROUND; | ||
479 | if (bNoOverSampling) d |= SNDMIX_NORESAMPLING; | ||
480 | if (bReverb) d |= SNDMIX_REVERB; | ||
481 | if (hqido) d |= SNDMIX_HQRESAMPLER; | ||
482 | if (bMegaBass) d |= SNDMIX_MEGABASS; | ||
483 | if (bNR) d |= SNDMIX_NOISEREDUCTION; | ||
484 | if (bEQ) d |= SNDMIX_EQ; | ||
485 | gdwSoundSetup = d; | ||
486 | InitPlayer(FALSE); | ||
487 | return TRUE; | ||
488 | } | ||