rtoss - Blame information for rev 26

Subversion Repositories:
Rev:
Rev Author Line No. Line
14 roytam 1 #include <windows.h>
2 #include "maplay.h"
3 #include "helper.h"
4 #include "effect.h"
5 #include <math.h>
6  
7 short Clip16(int s)
8 {
9         int nRet = s;
10         if (nRet > 32767)
11                 nRet = 32767;
12         else if (nRet < -32768)
13                 nRet = -32768;
14         return (short)nRet;
15 }
16  
17 unsigned char Clip8(int s)
18 {
19         int nRet = s;
20         if (nRet > 255)
21                 nRet = 255;
22         else if (nRet < 0)
23                 nRet = 0;
24         return (unsigned char)nRet;
25 }
26  
27 #define SURROUND_PREAMP         (-0.035)
28  
29 CSurroundEffect::CSurroundEffect()
30 {
31         m_fEnable = FALSE;
32         m_nRate = 20;
33         m_nPreamp = (int)(pow(10, SURROUND_PREAMP * m_nRate / 20) * 100);
34 }
35  
36 CSurroundEffect::~CSurroundEffect()
37 {
38 }
39  
40 void CSurroundEffect::SetParameter(EFFECT* value)
41 {
42         m_fEnable = value->fEnable;
43         m_nRate = max(min(value->nRate, 100), 0);
44         m_nPreamp = (int)(pow(10, SURROUND_PREAMP * m_nRate / 20) * 100);
45 }
46  
47 void CSurroundEffect::GetParameter(EFFECT* value)
48 {
49         value->fEnable = m_fEnable;
50         value->nRate = m_nRate;
51         value->nDelay = 0;
52 }
53  
54 void CSurroundEffect::Process(int nResolution, void* pBuf, DWORD cbSize)
55 {
56         if (!m_fEnable || !m_nRate)
57                 return;
58  
59         if (nResolution == 8) {
60                 unsigned char* pSample = (unsigned char*)pBuf;
61                 int nSamples = cbSize / (sizeof(unsigned char) * 2);
62                 while (nSamples) {
63                         int l = UINT8_TO_INT16((int)*pSample);
64                         int r = UINT8_TO_INT16((int)*(pSample + 1));
65                         *pSample++ = Clip8(INT16_TO_UINT8((l + (l - r) * m_nRate / 100)) * m_nPreamp / 100);
66                         *pSample++ = Clip8(INT16_TO_UINT8((r + (r - l) * m_nRate / 100)) * m_nPreamp / 100);
67                         nSamples--;
68                 }
69         }
70         else if (nResolution == 16) {
71                 short* pSample = (short*)pBuf;
72                 int nSamples = cbSize / (sizeof(short) * 2);
73                 while (nSamples) {
74                         int l = *pSample;
75                         int r = *(pSample + 1);
76                         *pSample++ = Clip16((l + (l - r) * m_nRate / 100) * m_nPreamp / 100);
77                         *pSample++ = Clip16((r + (r - l) * m_nRate / 100) * m_nPreamp / 100);
78                         nSamples--;
79                 }
80         }      
81 }
82  
83 CDelayEffect::CDelayEffect(BOOL fEcho)
84 {
85         m_nChannels = 0;
86         m_nSamplingRate = 0;
87         m_nReadPos = 0;
88         m_nWritePos = 0;
89         m_cBuf = 0;
90         m_pBuf = NULL;
91  
92         m_fEcho = fEcho;
93         m_fEnable = FALSE;
94         m_nDelay = 100;
95         m_nRate = 20;
96 }
97  
98 CDelayEffect::~CDelayEffect()
99 {
100 }
101  
102 void CDelayEffect::Open(int nChannels, int nSamplingRate)
103 {
104         m_nChannels = nChannels;
105         m_nSamplingRate = nSamplingRate;
106         if (!nChannels || !nSamplingRate)
107                 return;
108  
109         if (!m_fEnable)
110                 return;
111  
112         if (!m_nRate || !m_nDelay)
113                 return;
114  
115         m_cBuf = (m_nDelay * nSamplingRate / 1000) * nChannels;
116         if (m_cBuf & 1)
117                 m_cBuf = (m_cBuf & 0xFFFFFFF0) + 1;
118         m_cBuf += 1;
119  
120         m_pBuf = new int[m_cBuf];
121         memset(m_pBuf, 0, sizeof(int) * m_cBuf);
122         m_nWritePos = 0;
123         m_nReadPos = 1;
124 }
125  
126 void CDelayEffect::Close()
127 {
128         if (!m_pBuf) {
129                 delete [] m_pBuf;
130                 m_pBuf = NULL;
131         }
132 }
133  
134 void CDelayEffect::Process(int nResolution, void* pBuf, DWORD cbSize)
135 {
136         CAutoLock lock(&m_csec);
137         if (!m_fEnable)
138                 return;
139  
140         if (!m_nChannels || !m_nSamplingRate)
141                 return;
142  
143         if (!m_nDelay || !m_nRate)
144                 return;
145  
146         if (!m_pBuf)
147                 return;
148  
149         if (nResolution == 8) {
150                 unsigned char* pSample = (unsigned char*)pBuf;
151                 int nSamples = cbSize / sizeof(unsigned char) / m_nChannels;
152                 while (nSamples--) {
153                         for (int i = 0; i < m_nChannels; i++) {
154                                 *pSample = INT16_TO_UINT8(DelayEffect(UINT8_TO_INT16(*pSample), i));
155                                 pSample++;
156                         }
157                 }
158         }
159         else if (nResolution == 16) {
160                 short* pSample = (short*)pBuf;
161                 int nSamples = cbSize / sizeof(short) / m_nChannels;
162                 while (nSamples--) {
163                         for (int i = 0; i < m_nChannels; i++) {
164                                 *pSample = DelayEffect(*pSample, i);
165                                 pSample++;
166                         }
167                 }
168         }
169 }
170  
171 void CDelayEffect::SetParameter(EFFECT* value)
172 {      
173         CAutoLock lock(&m_csec);
174         int nChannels, nSamplingRate;
175         nChannels = m_nChannels; nSamplingRate = m_nSamplingRate;
176         Close();
177  
178         m_fEnable = value->fEnable;
179         m_nDelay = value->nDelay;
180         m_nRate = value->nRate;
181  
182         Open(m_nChannels, m_nSamplingRate);
183 }
184  
185 void CDelayEffect::GetParameter(EFFECT* value)
186 {      
187         value->fEnable = m_fEnable;
188         value->nDelay = m_nDelay;
189         value->nRate = m_nRate;
190 }
191  
192 short CDelayEffect::DelayEffect(short s, int nChannel)
193 {
194         int* p;
195         int nRet;
196  
197         p = (int*)m_pBuf;
198  
199         if (m_fEcho)
200                 *(p + m_nWritePos++) = s;
201  
202         nRet = s + *(p + m_nReadPos++) * m_nRate / 100;
203  
204         nRet = Clip16(nRet);
205         if (!m_fEcho)
206                 *(p + m_nWritePos++) = nRet;
207  
208         if (m_nReadPos == m_cBuf)
209                 m_nReadPos = 0;
210         if (m_nWritePos == m_cBuf)
211                 m_nWritePos = 0;
212         return (short)nRet;
213 }
214  
215 void CDelayEffect::Reset()
216 {
217         if (!m_pBuf)
218                 return;
219  
220         CAutoLock lock(&m_csec);
221         memset(m_pBuf, 0, sizeof(int) * m_cBuf);
222 }
223  
224 CBassBoost::CBassBoost()
225 {
226         m_nChannels = m_nSampleRate = 0;
227         m_nLevel = 0;
228         m_nPreamp = 100;
229 }
230  
231 CBassBoost::~CBassBoost()
232 {
233 }
234  
235 #define BASSBOOST_PREAMP                (-0.4)
236 #define BASSBOOST_FREQUENCY             145
237 #ifdef FIXED_BASSBOOOST
238 #define FIXED_FIG                               24
239 #define FIXED_BASE                              (1 << FIXED_FIG)
240 #define TO_FIXED_POINT(x)               ((BB_FIXED_T)((x) * FIXED_BASE))
241 #define FROM_FIXED_POINT(x)             ((BB_FIXED_T2)((x) >> FIXED_FIG))
242 #define ADD_PREAMP(x)                   ((x) << 8)
243 #define REMOVE_PREAMP(x)                ((x) >> 8)
244 #else
245 #define TO_FIXED_POINT(x)               ((BB_FIXED_T)(x))
246 #define FROM_FIXED_POINT(x)             ((BB_FIXED_T2)(x))
247 #define ADD_PREAMP(x)                   ((BB_FIXED_T2)((x) << 8))
248 #define REMOVE_PREAMP(x)                ((int)(x) >> 8)
249 #endif
250  
251 void CBassBoost::Open(int nChannels, int nSampleRate)
252 {
253         m_nChannels = nChannels;
254         m_nSampleRate = nSampleRate;
255  
256         if (!m_nLevel || !m_nChannels || !m_nSampleRate)
257                 return;
258  
259         double omega = 2 * 3.141592653589 * BASSBOOST_FREQUENCY / nSampleRate;
260         double sn = sin(omega);
261         double cs = cos(omega);
262         double ax = exp(log(10) * (double)m_nLevel * 0.35 / 40);
263         double shape = 7.0;
264         double beta = sqrt((ax * ax + 1) / shape - (pow((ax - 1), 2)));
265         double b0 = ax * ((ax + 1) - (ax - 1) * cs + beta * sn);
266         double b1 = 2 * ax * ((ax - 1) - (ax + 1) * cs);
267         double b2 = ax * ((ax + 1) - (ax - 1) * cs - beta * sn);
268         double a0 = ((ax + 1) + (ax - 1) * cs + beta * sn);
269         double a1 = -2 * ((ax - 1) + (ax + 1) * cs);
270         double a2 = (ax + 1) + (ax - 1) * cs - beta * sn;
271  
272         b[0] = TO_FIXED_POINT(b0 / a0);
273         b[1] = TO_FIXED_POINT(b1 / a0);
274         b[2] = TO_FIXED_POINT(b2 / a0);
275         a[1] = TO_FIXED_POINT(a1 / a0);
276         a[2] = TO_FIXED_POINT(a2 / a0);
277  
278         memset(xn, 0, sizeof(xn));
279         memset(yn, 0, sizeof(yn));
280         m_nPreamp = (int)(pow(10, BASSBOOST_PREAMP * m_nLevel / 20) * 100);
281 }
282  
283 void CBassBoost::Close()
284 {
285         m_nChannels = m_nSampleRate = 0;
286 }
287  
288 void CBassBoost::Reset()
289 {
290         memset(xn, 0, sizeof(xn));
291         memset(yn, 0, sizeof(yn));
292 }
293  
294 void CBassBoost::Process(int nResolution, void* pBuf, DWORD nSize)
295 {
296         CAutoLock lock(&m_csec);
297         if (!m_nLevel || !m_nChannels || !m_nSampleRate)
298                 return;
299  
300         if (nResolution == 8) {
301                 unsigned char* pSample = (unsigned char*)pBuf;
302                 int nSamples = nSize / sizeof(unsigned char) / m_nChannels;
303  
304                 BB_FIXED_T2 in, out;
305                 for (int i = 0; i < nSamples; i++) {
306                         in = (BB_FIXED_T2)ADD_PREAMP(UINT8_TO_INT16((int)*pSample));
307                         out = FROM_FIXED_POINT((b[0] * in)
308                                                                         + (b[1] * xn[0][0])
309                                                                         + (b[2] * xn[1][0])
310                                                                         - (a[1] * yn[0][0])
311                                                                         - (a[2] * yn[1][0]));
312  
313                         xn[1][0] = xn[0][0];
314                         xn[0][0] = in;
315                         yn[1][0] = yn[0][0];
316                         yn[0][0] = out;
317                         *pSample++ = Clip8(INT16_TO_UINT8(REMOVE_PREAMP(out)* m_nPreamp / 100));
318  
319                         if (m_nChannels == 2) {
320                                 in = (BB_FIXED_T2)ADD_PREAMP(UINT8_TO_INT16((int)*pSample));
321                                 out = FROM_FIXED_POINT((b[0] * in)
322                                                                         + (b[1] * xn[0][0])
323                                                                         + (b[2] * xn[1][0])
324                                                                         - (a[1] * yn[0][0])
325                                                                         - (a[2] * yn[1][0]));
326  
327                                 xn[1][1] = xn[0][0];
328                                 xn[0][1] = in;
329                                 yn[1][1] = yn[0][0];
330                                 yn[0][1] = out;
331                                 *pSample++ = Clip8(INT16_TO_UINT8(REMOVE_PREAMP(out) * m_nPreamp / 100));
332                         }
333                 }
334         }
335         else if (nResolution == 16) {
336                 short* pSample = (short*)pBuf;
337                 int nSamples = nSize / sizeof(short) / m_nChannels;
338  
339                 BB_FIXED_T2 in, out;
340                 for (int i = 0; i < nSamples; i++) {
341                         in = (BB_FIXED_T2)ADD_PREAMP(*pSample);
342                         out = FROM_FIXED_POINT((b[0] * in)
343                                                                         + (b[1] * xn[0][0])
344                                                                         + (b[2] * xn[1][0])
345                                                                         - (a[1] * yn[0][0])
346                                                                         - (a[2] * yn[1][0]));
347  
348                         xn[1][0] = xn[0][0];
349                         xn[0][0] = in;
350                         yn[1][0] = yn[0][0];
351                         yn[0][0] = out;
352                         *pSample++ = Clip16(REMOVE_PREAMP(out) * m_nPreamp / 100);
353  
354                         if (m_nChannels == 2) {
355                                 in = (BB_FIXED_T2)ADD_PREAMP(*pSample);
356                                 out = FROM_FIXED_POINT((b[0] * in)
357                                                                                 + (b[1] * xn[0][0])
358                                                                                 + (b[2] * xn[1][0])
359                                                                                 - (a[1] * yn[0][0])
360                                                                                 - (a[2] * yn[1][0]));
361                                 xn[1][1] = xn[0][0];
362                                 xn[0][1] = in;
363                                 yn[1][1] = yn[0][0];
364                                 yn[0][1] = out;
365                                 *pSample++ = Clip16(REMOVE_PREAMP(out)* m_nPreamp / 100);
366                         }
367                 }
368         }
369 }
370  
371 void CBassBoost::SetLevel(int nLevel)
372 {
373         CAutoLock lock(&m_csec);
374         int nChannels = m_nChannels;
375         int nSampleRate = m_nSampleRate;
376         Close();
377  
378         m_nLevel = min(max(0, nLevel), 20);
379         Open(nChannels, nSampleRate);
380 }
381  
382 #define CHORUS_PREAMP           (-0.035)
383 #define CHORUS_DELAY    6
384 #define CHORUS_DEPTH    3
385 #ifdef _WIN32_WCE
386 #define CHORUS_FIXED_T  int
387 #define CHORUS_BITS             8
388 #define CHORUS_BASE             ((CHORUS_FIXED_T)1 << CHORUS_BITS)
389 #else
390 #define CHORUS_FIXED_T  LONGLONG
391 #define CHORUS_BITS             31
392 #define CHORUS_BASE             ((CHORUS_FIXED_T)1 << CHORUS_BITS)
393 #endif
394  
395 C3DChorus::C3DChorus()
396 {
397         m_fEnable = FALSE;
26 roytam 398         m_nRate = 20;
14 roytam 399  
400         m_nSampleRate = 0;
401         m_pBuf[0] = m_pBuf[1] = NULL;
402  
403         Reset();
404 }
405  
406 C3DChorus::~C3DChorus()
407 {
408         Close();
409 }
410  
411 void C3DChorus::Open(int nSampleRate)
412 {
413         m_pBuf[0] = new int[nSampleRate];
414         m_pBuf[1] = new int[nSampleRate];
415  
416         m_nDelayOffset = nSampleRate * CHORUS_DELAY / 1000;
417         m_nDepth = ((CHORUS_FIXED_T)CHORUS_DEPTH << (CHORUS_BITS + 1)) / 1000;
418         m_nSampleRate = nSampleRate;
419  
420         Reset();
421 }
422  
423 void C3DChorus::Process(int nResolution, LPBYTE pbBuf, DWORD cbSize)
424 {
425         CAutoLock lock(&m_csec);
426         if (!m_pBuf || !m_fEnable || m_nRate == 0)
427                 return;
428  
429         if (nResolution == 16) {
430                 short* pSample = (short*)pbBuf;
431                 int nSamples = cbSize / (sizeof(short) * 2);
432                 while (nSamples) {
433                         *pSample++ = Chorus(*pSample, 0);
434                         *pSample++ = Chorus(*pSample, 1);
435                         nSamples--;
436                 }
437         }
438         else if (nResolution == 8) {
439                 unsigned char* pSample = (unsigned char*)pbBuf;
440                 int nSamples = cbSize / (sizeof(unsigned char) * 2);
441                 while (nSamples) {
442                         *pSample++ = INT16_TO_UINT8(Chorus(UINT8_TO_INT16(*pSample), 0));
443                         *pSample++ = INT16_TO_UINT8(Chorus(UINT8_TO_INT16(*pSample), 1));
444                         nSamples--;
445                 }
446         }
447 }
448  
449 void C3DChorus::Close()
450 {
451         if (m_pBuf[0]) {
452                 delete m_pBuf[0];
453                 m_pBuf[0] = NULL;
454         }
455         if (m_pBuf[1]) {
456                 delete m_pBuf[1];
457                 m_pBuf[1] = NULL;
458         }
459         m_nSampleRate = 0;
460 }
461  
462 void C3DChorus::Reset()
463 {
464         CAutoLock lock(&m_csec);
465         m_nCyclePos[0] = 0;
466         m_nCyclePos[1] = m_nSampleRate / 2;
467         m_nWritePos[0] = m_nWritePos[1] = 0;
468         if (m_pBuf[0])
469                 memset(m_pBuf[0], 0, sizeof(int) * m_nSampleRate);
470         if (m_pBuf[1])
471                 memset(m_pBuf[1], 0, sizeof(int) * m_nSampleRate);
472  
473         m_nPreamp = (int)(pow(10, CHORUS_PREAMP * m_nRate / 20) * 100);
474 }
475  
476 short C3DChorus::Chorus(short s, int nChannel)
477 {
478         CHORUS_FIXED_T s2 = (CHORUS_FIXED_T)s << CHORUS_BITS;
479         CHORUS_FIXED_T offset;
480  
481         offset = ((CHORUS_FIXED_T)m_nWritePos[nChannel] - m_nDelayOffset) << CHORUS_BITS;
482         if (m_nCyclePos[nChannel] < m_nSampleRate / 2)
483                 offset -= (CHORUS_FIXED_T)m_nDepth * m_nCyclePos[nChannel];
484         else
485                 offset -= (CHORUS_FIXED_T)m_nDepth * (m_nSampleRate - m_nCyclePos[nChannel]);
486  
487         if (offset < 0)
488                 offset += (CHORUS_FIXED_T)(m_nSampleRate - 1) << CHORUS_BITS;
489  
490         int offset1 = (int)(offset >> CHORUS_BITS);
491         int offset2 = offset1 + 1;
492         if (offset2 == m_nSampleRate - 1)
493                 offset2 = 0;
494  
495         int mod = (int)(offset % CHORUS_BASE);
496         CHORUS_FIXED_T s3 = (CHORUS_FIXED_T)m_pBuf[nChannel][offset1] * (CHORUS_BASE - mod);
497         s3 += (CHORUS_FIXED_T)m_pBuf[nChannel][offset2] * mod;
498  
499         s2 -= (s3 * m_nRate / 100);
500  
501         m_pBuf[nChannel][m_nWritePos[nChannel]] = s;
502  
503         m_nWritePos[nChannel]++;
504         if (m_nWritePos[nChannel] == m_nSampleRate - 1)
505                 m_nWritePos[nChannel] = 0;
506  
507         m_nCyclePos[nChannel]++;
508         if (m_nCyclePos[nChannel] == m_nSampleRate - 1)
509                 m_nCyclePos[nChannel] = 0;
510  
511         return Clip16((int)((s2 * m_nPreamp / 100) >> CHORUS_BITS));
512 }
513  
514 void C3DChorus::SetParameter(EFFECT* value)
515 {
516         m_fEnable = value->fEnable;
517         m_nRate = value->nRate;
518         Reset();
519 }
520  
521 void C3DChorus::GetParameter(EFFECT* value)
522 {
523         value->fEnable = m_fEnable;
524         value->nRate = m_nRate;
525 }