Mercurial > audlegacy
comparison Plugins/Input/console/Spc_Dsp.cpp @ 493:c04dff121e1d trunk
[svn] hostile merge, phase 2: reimport based on new plugin code
author | nenolod |
---|---|
date | Tue, 24 Jan 2006 20:19:01 -0800 |
parents | |
children | f12d7e208b43 |
comparison
equal
deleted
inserted
replaced
492:ccb68bad47b2 | 493:c04dff121e1d |
---|---|
1 | |
2 // Game_Music_Emu 0.3.0. http://www.slack.net/~ant/ | |
3 | |
4 // Based on Brad Martin's OpenSPC DSP emulator | |
5 | |
6 #include "Spc_Dsp.h" | |
7 | |
8 #include <string.h> | |
9 | |
10 #include "blargg_endian.h" | |
11 | |
12 /* Copyright (C) 2002 Brad Martin */ | |
13 /* Copyright (C) 2004-2006 Shay Green. This module is free software; you | |
14 can redistribute it and/or modify it under the terms of the GNU Lesser | |
15 General Public License as published by the Free Software Foundation; either | |
16 version 2.1 of the License, or (at your option) any later version. This | |
17 module is distributed in the hope that it will be useful, but WITHOUT ANY | |
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
19 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for | |
20 more details. You should have received a copy of the GNU Lesser General | |
21 Public License along with this module; if not, write to the Free Software | |
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ | |
23 | |
24 #include BLARGG_SOURCE_BEGIN | |
25 | |
26 Spc_Dsp::Spc_Dsp( uint8_t* ram_ ) : ram( ram_ ) | |
27 { | |
28 set_gain( 1.0 ); | |
29 mute_voices( 0 ); | |
30 disable_surround( false ); | |
31 | |
32 BOOST_STATIC_ASSERT( sizeof (g) == register_count && sizeof (voice) == register_count ); | |
33 } | |
34 | |
35 void Spc_Dsp::mute_voices( int mask ) | |
36 { | |
37 for ( int i = 0; i < voice_count; i++ ) | |
38 voice_state [i].enabled = (mask >> i & 1) ? 31 : 7; | |
39 } | |
40 | |
41 void Spc_Dsp::reset() | |
42 { | |
43 keys = 0; | |
44 echo_ptr = 0; | |
45 noise_count = 0; | |
46 noise = 1; | |
47 fir_offset = 0; | |
48 | |
49 g.flags = 0xE0; // reset, mute, echo off | |
50 g.key_ons = 0; | |
51 | |
52 for ( int i = 0; i < voice_count; i++ ) | |
53 { | |
54 voice_t& v = voice_state [i]; | |
55 v.on_cnt = 0; | |
56 v.volume [0] = 0; | |
57 v.volume [1] = 0; | |
58 v.envstate = state_release; | |
59 } | |
60 | |
61 memset( fir_buf, 0, sizeof fir_buf ); | |
62 } | |
63 | |
64 void Spc_Dsp::write( int i, int data ) | |
65 { | |
66 require( (unsigned) i < register_count ); | |
67 | |
68 reg [i] = data; | |
69 int high = i >> 4; | |
70 switch ( i & 0x0f ) | |
71 { | |
72 // voice volume | |
73 case 0: | |
74 case 1: { | |
75 short* volume = voice_state [high].volume; | |
76 int left = (int8_t) reg [i & ~1]; | |
77 int right = (int8_t) reg [i | 1]; | |
78 volume [0] = left; | |
79 volume [1] = right; | |
80 // kill surround only if signs of volumes differ | |
81 if ( left * right < surround_threshold ) | |
82 { | |
83 if ( left < 0 ) | |
84 volume [0] = -left; | |
85 else | |
86 volume [1] = -right; | |
87 } | |
88 break; | |
89 } | |
90 | |
91 // fir coefficients | |
92 case 0x0f: | |
93 fir_coeff [high] = (int8_t) data; // sign-extend | |
94 break; | |
95 } | |
96 } | |
97 | |
98 // This table is for envelope timing. It represents the number of counts | |
99 // that should be subtracted from the counter each sample period (32kHz). | |
100 // The counter starts at 30720 (0x7800). Each count divides exactly into | |
101 // 0x7800 without remainder. | |
102 const int env_rate_init = 0x7800; | |
103 static const short env_rates [0x20] = | |
104 { | |
105 0x0000, 0x000F, 0x0014, 0x0018, 0x001E, 0x0028, 0x0030, 0x003C, | |
106 0x0050, 0x0060, 0x0078, 0x00A0, 0x00C0, 0x00F0, 0x0140, 0x0180, | |
107 0x01E0, 0x0280, 0x0300, 0x03C0, 0x0500, 0x0600, 0x0780, 0x0A00, | |
108 0x0C00, 0x0F00, 0x1400, 0x1800, 0x1E00, 0x2800, 0x3C00, 0x7800 | |
109 }; | |
110 | |
111 const int env_range = 0x800; | |
112 | |
113 inline int Spc_Dsp::clock_envelope( int v ) | |
114 { /* Return value is current | |
115 * ENVX */ | |
116 raw_voice_t& raw_voice = this->voice [v]; | |
117 voice_t& voice = voice_state [v]; | |
118 | |
119 int envx = voice.envx; | |
120 if ( voice.envstate == state_release ) | |
121 { | |
122 /* | |
123 * Docs: "When in the state of "key off". the "click" sound is | |
124 * prevented by the addition of the fixed value 1/256" WTF??? | |
125 * Alright, I'm going to choose to interpret that this way: | |
126 * When a note is keyed off, start the RELEASE state, which | |
127 * subtracts 1/256th each sample period (32kHz). Note there's | |
128 * no need for a count because it always happens every update. | |
129 */ | |
130 envx -= env_range / 256; | |
131 if ( envx <= 0 ) | |
132 { | |
133 envx = 0; | |
134 keys &= ~(1 << v); | |
135 return -1; | |
136 } | |
137 voice.envx = envx; | |
138 raw_voice.envx = envx >> 8; | |
139 return envx; | |
140 } | |
141 | |
142 int cnt = voice.envcnt; | |
143 int adsr1 = raw_voice.adsr [0]; | |
144 if ( adsr1 & 0x80 ) | |
145 { | |
146 switch ( voice.envstate ) | |
147 { | |
148 case state_attack: { | |
149 // increase envelope by 1/64 each step | |
150 int t = adsr1 & 15; | |
151 if ( t == 15 ) | |
152 { | |
153 envx += env_range / 2; | |
154 } | |
155 else | |
156 { | |
157 cnt -= env_rates [t * 2 + 1]; | |
158 if ( cnt > 0 ) | |
159 break; | |
160 envx += env_range / 64; | |
161 cnt = env_rate_init; | |
162 } | |
163 if ( envx >= env_range ) | |
164 { | |
165 envx = env_range - 1; | |
166 voice.envstate = state_decay; | |
167 } | |
168 voice.envx = envx; | |
169 break; | |
170 } | |
171 | |
172 case state_decay: { | |
173 // Docs: "DR... [is multiplied] by the fixed value | |
174 // 1-1/256." Well, at least that makes some sense. | |
175 // Multiplying ENVX by 255/256 every time DECAY is | |
176 // updated. | |
177 cnt -= env_rates [((adsr1 >> 3) & 0xE) + 0x10]; | |
178 if ( cnt <= 0 ) | |
179 { | |
180 cnt = env_rate_init; | |
181 envx -= ((envx - 1) >> 8) + 1; | |
182 voice.envx = envx; | |
183 } | |
184 int sustain_level = raw_voice.adsr [1] >> 5; | |
185 | |
186 if ( envx <= (sustain_level + 1) * 0x100 ) | |
187 voice.envstate = state_sustain; | |
188 break; | |
189 } | |
190 | |
191 case state_sustain: | |
192 // Docs: "SR [is multiplied] by the fixed value 1-1/256." | |
193 // Multiplying ENVX by 255/256 every time SUSTAIN is | |
194 // updated. | |
195 cnt -= env_rates [raw_voice.adsr [1] & 0x1f]; | |
196 if ( cnt <= 0 ) | |
197 { | |
198 cnt = env_rate_init; | |
199 envx -= ((envx - 1) >> 8) + 1; | |
200 voice.envx = envx; | |
201 } | |
202 break; | |
203 | |
204 case state_release: | |
205 // handled above | |
206 break; | |
207 } | |
208 } | |
209 else | |
210 { /* GAIN mode is set */ | |
211 /* | |
212 * Note: if the game switches between ADSR and GAIN modes | |
213 * partway through, should the count be reset, or should it | |
214 * continue from where it was? Does the DSP actually watch for | |
215 * that bit to change, or does it just go along with whatever | |
216 * it sees when it performs the update? I'm going to assume | |
217 * the latter and not update the count, unless I see a game | |
218 * that obviously wants the other behavior. The effect would | |
219 * be pretty subtle, in any case. | |
220 */ | |
221 int t = raw_voice.gain; | |
222 if (t < 0x80) | |
223 { | |
224 envx = voice.envx = t << 4; | |
225 } | |
226 else switch (t >> 5) | |
227 { | |
228 case 4: /* Docs: "Decrease (linear): Subtraction | |
229 * of the fixed value 1/64." */ | |
230 cnt -= env_rates [t & 0x1F]; | |
231 if (cnt > 0) | |
232 break; | |
233 cnt = env_rate_init; | |
234 envx -= env_range / 64; | |
235 if ( envx < 0 ) | |
236 { | |
237 envx = 0; | |
238 if ( voice.envstate == state_attack ) | |
239 voice.envstate = state_decay; | |
240 } | |
241 voice.envx = envx; | |
242 break; | |
243 case 5: /* Docs: "Drecrease <sic> (exponential): | |
244 * Multiplication by the fixed value | |
245 * 1-1/256." */ | |
246 cnt -= env_rates [t & 0x1F]; | |
247 if (cnt > 0) | |
248 break; | |
249 cnt = env_rate_init; | |
250 envx -= ((envx - 1) >> 8) + 1; | |
251 if ( envx < 0 ) | |
252 { | |
253 envx = 0; | |
254 if ( voice.envstate == state_attack ) | |
255 voice.envstate = state_decay; | |
256 } | |
257 voice.envx = envx; | |
258 break; | |
259 case 6: /* Docs: "Increase (linear): Addition of | |
260 * the fixed value 1/64." */ | |
261 cnt -= env_rates [t & 0x1F]; | |
262 if (cnt > 0) | |
263 break; | |
264 cnt = env_rate_init; | |
265 envx += env_range / 64; | |
266 if ( envx >= env_range ) | |
267 envx = env_range - 1; | |
268 voice.envx = envx; | |
269 break; | |
270 case 7: /* Docs: "Increase (bent line): Addition | |
271 * of the constant 1/64 up to .75 of the | |
272 * constaint <sic> 1/256 from .75 to 1." */ | |
273 cnt -= env_rates [t & 0x1F]; | |
274 if (cnt > 0) | |
275 break; | |
276 cnt = env_rate_init; | |
277 if ( envx < env_range * 3 / 4 ) | |
278 envx += env_range / 64; | |
279 else | |
280 envx += env_range / 256; | |
281 if ( envx >= env_range ) | |
282 envx = env_range - 1; | |
283 voice.envx = envx; | |
284 break; | |
285 } | |
286 } | |
287 voice.envcnt = cnt; | |
288 raw_voice.envx = envx >> 4; | |
289 return envx; | |
290 } | |
291 | |
292 // Clamp n into range -32768 <= n <= 32767 | |
293 inline int clamp_16( int n ) | |
294 { | |
295 if ( (BOOST::int16_t) n != n ) | |
296 n = BOOST::int16_t (0x7FFF - (n >> 31)); | |
297 return n; | |
298 } | |
299 | |
300 void Spc_Dsp::run( long count, short* out_buf ) | |
301 { | |
302 // to do: make clock_envelope() inline so that this becomes a leaf function? | |
303 | |
304 // Should we just fill the buffer with silence? Flags won't be cleared | |
305 // during this run so it seems it should keep resetting every sample. | |
306 if ( g.flags & 0x80 ) | |
307 reset(); | |
308 | |
309 struct src_dir { | |
310 char start [2]; | |
311 char loop [2]; | |
312 }; | |
313 | |
314 const src_dir* const sd = (src_dir*) &ram [g.wave_page * 0x100]; | |
315 | |
316 int left_volume = g.left_volume; | |
317 int right_volume = g.right_volume; | |
318 if ( left_volume * right_volume < surround_threshold ) | |
319 right_volume = -right_volume; // kill global surround | |
320 left_volume *= emu_gain; | |
321 right_volume *= emu_gain; | |
322 | |
323 while ( --count >= 0 ) | |
324 { | |
325 // Here we check for keys on/off. Docs say that successive writes | |
326 // to KON/KOF must be separated by at least 2 Ts periods or risk | |
327 // being neglected. Therefore DSP only looks at these during an | |
328 // update, and not at the time of the write. Only need to do this | |
329 // once however, since the regs haven't changed over the whole | |
330 // period we need to catch up with. | |
331 | |
332 g.wave_ended &= ~g.key_ons; // Keying on a voice resets that bit in ENDX. | |
333 | |
334 if ( g.noise_enables ) | |
335 { | |
336 noise_count -= env_rates [g.flags & 0x1F]; | |
337 if ( noise_count <= 0 ) | |
338 { | |
339 noise_count = env_rate_init; | |
340 | |
341 noise_amp = BOOST::int16_t (noise * 2); | |
342 | |
343 int feedback = (noise << 13) ^ (noise << 14); | |
344 noise = (feedback & 0x4000) | (noise >> 1); | |
345 } | |
346 } | |
347 | |
348 // What is the expected behavior when pitch modulation is enabled on | |
349 // voice 0? Jurassic Park 2 does this. Assume 0 for now. | |
350 long prev_outx = 0; | |
351 | |
352 int echol = 0; | |
353 int echor = 0; | |
354 int left = 0; | |
355 int right = 0; | |
356 for ( int vidx = 0; vidx < voice_count; vidx++ ) | |
357 { | |
358 const int vbit = 1 << vidx; | |
359 raw_voice_t& raw_voice = voice [vidx]; | |
360 voice_t& voice = voice_state [vidx]; | |
361 | |
362 if ( voice.on_cnt && !--voice.on_cnt ) | |
363 { | |
364 // key on | |
365 keys |= vbit; | |
366 voice.addr = GET_LE16( sd [raw_voice.waveform].start ); | |
367 voice.block_remain = 1; | |
368 voice.envx = 0; | |
369 voice.block_header = 0; | |
370 voice.fraction = 0x3fff; // decode three samples immediately | |
371 voice.interp0 = 0; // BRR decoder filter uses previous two samples | |
372 voice.interp1 = 0; | |
373 | |
374 // NOTE: Real SNES does *not* appear to initialize the | |
375 // envelope counter to anything in particular. The first | |
376 // cycle always seems to come at a random time sooner than | |
377 // expected; as yet, I have been unable to find any | |
378 // pattern. I doubt it will matter though, so we'll go | |
379 // ahead and do the full time for now. | |
380 voice.envcnt = env_rate_init; | |
381 voice.envstate = state_attack; | |
382 } | |
383 | |
384 if ( g.key_ons & vbit & ~g.key_offs ) | |
385 { | |
386 // voice doesn't come on if key off is set | |
387 g.key_ons &= ~vbit; | |
388 voice.on_cnt = 8; | |
389 } | |
390 | |
391 if ( keys & g.key_offs & vbit ) | |
392 { | |
393 // key off | |
394 voice.envstate = state_release; | |
395 voice.on_cnt = 0; | |
396 } | |
397 | |
398 int envx; | |
399 if ( !(keys & vbit) || (envx = clock_envelope( vidx )) < 0 ) | |
400 { | |
401 raw_voice.envx = 0; | |
402 raw_voice.outx = 0; | |
403 prev_outx = 0; | |
404 continue; | |
405 } | |
406 | |
407 // Decode samples when fraction >= 1.0 (0x1000) | |
408 for ( int n = voice.fraction >> 12; --n >= 0; ) | |
409 { | |
410 if ( !--voice.block_remain ) | |
411 { | |
412 if ( voice.block_header & 1 ) | |
413 { | |
414 g.wave_ended |= vbit; | |
415 | |
416 if ( voice.block_header & 2 ) | |
417 { | |
418 // verified (played endless looping sample and ENDX was set) | |
419 voice.addr = GET_LE16( sd [raw_voice.waveform].loop ); | |
420 } | |
421 else | |
422 { | |
423 // first block was end block; don't play anything (verified) | |
424 goto sample_ended; // to do: find alternative to goto | |
425 } | |
426 } | |
427 | |
428 voice.block_header = ram [voice.addr++]; | |
429 voice.block_remain = 16; // nybbles | |
430 } | |
431 | |
432 // if next block has end flag set, *this* block ends *early* (verified) | |
433 if ( voice.block_remain == 9 && (ram [voice.addr + 5] & 3) == 1 && | |
434 (voice.block_header & 3) != 3 ) | |
435 { | |
436 sample_ended: | |
437 g.wave_ended |= vbit; | |
438 keys &= ~vbit; | |
439 raw_voice.envx = 0; | |
440 voice.envx = 0; | |
441 // add silence samples to interpolation buffer | |
442 do | |
443 { | |
444 voice.interp3 = voice.interp2; | |
445 voice.interp2 = voice.interp1; | |
446 voice.interp1 = voice.interp0; | |
447 voice.interp0 = 0; | |
448 } | |
449 while ( --n >= 0 ); | |
450 break; | |
451 } | |
452 | |
453 int delta = ram [voice.addr]; | |
454 if ( voice.block_remain & 1 ) | |
455 { | |
456 delta <<= 4; // use lower nybble | |
457 voice.addr++; | |
458 } | |
459 | |
460 // Use sign-extended upper nybble | |
461 delta = int8_t (delta) >> 4; | |
462 | |
463 // For invalid ranges (D,E,F): if the nybble is negative, | |
464 // the result is F000. If positive, 0000. Nothing else | |
465 // like previous range, etc seems to have any effect. If | |
466 // range is valid, do the shift normally. Note these are | |
467 // both shifted right once to do the filters properly, but | |
468 // the output will be shifted back again at the end. | |
469 int shift = voice.block_header >> 4; | |
470 delta = (delta << shift) >> 1; | |
471 if ( shift > 0x0C ) | |
472 delta = (delta >> 14) & ~0x7FF; | |
473 | |
474 // One, two and three point IIR filters | |
475 int smp1 = voice.interp0; | |
476 int smp2 = voice.interp1; | |
477 switch ( (voice.block_header >> 2) & 3 ) | |
478 { | |
479 case 0: | |
480 break; | |
481 | |
482 case 1: | |
483 delta += smp1 >> 1; | |
484 delta += (-smp1) >> 5; | |
485 break; | |
486 | |
487 case 2: | |
488 delta += smp1; | |
489 delta += (-(smp1 + (smp1 >> 1))) >> 5; | |
490 delta -= smp2 >> 1; | |
491 delta += smp2 >> 5; | |
492 break; | |
493 | |
494 case 3: | |
495 delta += smp1; | |
496 delta += (-(smp1 + (smp1 << 2) + (smp1 << 3))) >> 7; | |
497 delta -= smp2 >> 1; | |
498 delta += (smp2 + (smp2 >> 1)) >> 4; | |
499 break; | |
500 } | |
501 | |
502 voice.interp3 = voice.interp2; | |
503 voice.interp2 = smp2; | |
504 voice.interp1 = smp1; | |
505 voice.interp0 = BOOST::int16_t (clamp_16( delta ) * 2); // sign-extend | |
506 } | |
507 | |
508 // rate (with possible modulation) | |
509 int rate = GET_LE16( raw_voice.rate ) & 0x3FFF; | |
510 if ( g.pitch_mods & vbit ) | |
511 rate = (rate * (prev_outx + 32768)) >> 15; | |
512 | |
513 // Gaussian interpolation using most recent 4 samples | |
514 int index = voice.fraction >> 2 & 0x3FC; | |
515 voice.fraction = (voice.fraction & 0x0FFF) + rate; | |
516 const BOOST::int16_t* table = (BOOST::int16_t*) ((char*) gauss + index); | |
517 const BOOST::int16_t* table2 = (BOOST::int16_t*) ((char*) gauss + (255*4 - index)); | |
518 int s = ((table [0] * voice.interp3) >> 12) + | |
519 ((table [1] * voice.interp2) >> 12); | |
520 s += ((table2 [1] * voice.interp1) >> 12) + | |
521 // to do: should clamp here | |
522 ((table2 [0] * voice.interp0) >> 12); | |
523 int output = noise_amp; // noise is rarely used | |
524 if ( !(g.noise_enables & vbit) ) | |
525 output = clamp_16( s * 2 ); | |
526 | |
527 // scale output and set outx values | |
528 output = (output * envx) >> 11 & ~1; | |
529 | |
530 // output and apply muting (by setting voice.enabled to 31) | |
531 // if voice is externally disabled (not a SNES feature) | |
532 int l = (voice.volume [0] * output) >> voice.enabled; | |
533 int r = (voice.volume [1] * output) >> voice.enabled; | |
534 prev_outx = output; | |
535 raw_voice.outx = output >> 8; | |
536 if ( g.echo_ons & vbit ) | |
537 { | |
538 echol += l; | |
539 echor += r; | |
540 } | |
541 left += l; | |
542 right += r; | |
543 } | |
544 // end of channel loop | |
545 | |
546 // main volume control | |
547 left = (left * left_volume ) >> (7 + emu_gain_bits); | |
548 right = (right * right_volume) >> (7 + emu_gain_bits); | |
549 | |
550 // Echo FIR filter | |
551 | |
552 // read feedback from echo buffer | |
553 int echo_ptr = this->echo_ptr; | |
554 uint8_t* echo_buf = &ram [(g.echo_page * 0x100 + echo_ptr) & 0xFFFF]; | |
555 echo_ptr += 4; | |
556 if ( echo_ptr >= (g.echo_delay & 15) * 0x800 ) | |
557 echo_ptr = 0; | |
558 int fb_left = (BOOST::int16_t) GET_LE16( echo_buf ); // sign-extend | |
559 int fb_right = (BOOST::int16_t) GET_LE16( echo_buf + 2 ); // sign-extend | |
560 this->echo_ptr = echo_ptr; | |
561 | |
562 // put samples in history ring buffer | |
563 const int fir_offset = this->fir_offset; | |
564 short (*fir_pos) [2] = &fir_buf [fir_offset]; | |
565 this->fir_offset = (fir_offset + 7) & 7; // move backwards one step | |
566 fir_pos [0] [0] = fb_left; | |
567 fir_pos [0] [1] = fb_right; | |
568 fir_pos [8] [0] = fb_left; // duplicate at +8 eliminates wrap checking below | |
569 fir_pos [8] [1] = fb_right; | |
570 | |
571 // FIR | |
572 fb_left = fb_left * fir_coeff [7] + | |
573 fir_pos [1] [0] * fir_coeff [6] + | |
574 fir_pos [2] [0] * fir_coeff [5] + | |
575 fir_pos [3] [0] * fir_coeff [4] + | |
576 fir_pos [4] [0] * fir_coeff [3] + | |
577 fir_pos [5] [0] * fir_coeff [2] + | |
578 fir_pos [6] [0] * fir_coeff [1] + | |
579 fir_pos [7] [0] * fir_coeff [0]; | |
580 | |
581 fb_right = fb_right * fir_coeff [7] + | |
582 fir_pos [1] [1] * fir_coeff [6] + | |
583 fir_pos [2] [1] * fir_coeff [5] + | |
584 fir_pos [3] [1] * fir_coeff [4] + | |
585 fir_pos [4] [1] * fir_coeff [3] + | |
586 fir_pos [5] [1] * fir_coeff [2] + | |
587 fir_pos [6] [1] * fir_coeff [1] + | |
588 fir_pos [7] [1] * fir_coeff [0]; | |
589 | |
590 left += (fb_left * g.left_echo_volume ) >> 14; | |
591 right += (fb_right * g.right_echo_volume) >> 14; | |
592 | |
593 // echo buffer feedback | |
594 if ( !(g.flags & 0x20) ) | |
595 { | |
596 echol += (fb_left * g.echo_feedback) >> 14; | |
597 echor += (fb_right * g.echo_feedback) >> 14; | |
598 SET_LE16( echo_buf , clamp_16( echol ) ); | |
599 SET_LE16( echo_buf + 2, clamp_16( echor ) ); | |
600 } | |
601 | |
602 if ( out_buf ) | |
603 { | |
604 // write final samples | |
605 | |
606 left = clamp_16( left ); | |
607 right = clamp_16( right ); | |
608 | |
609 int mute = g.flags & 0x40; | |
610 | |
611 out_buf [0] = left; | |
612 out_buf [1] = right; | |
613 out_buf += 2; | |
614 | |
615 // muting | |
616 if ( mute ) | |
617 { | |
618 out_buf [-2] = 0; | |
619 out_buf [-1] = 0; | |
620 } | |
621 } | |
622 } | |
623 } | |
624 | |
625 // Base normal_gauss table is almost exactly (with an error of 0 or -1 for each entry): | |
626 // int normal_gauss [512]; | |
627 // normal_gauss [i] = exp((i-511)*(i-511)*-9.975e-6)*pow(sin(0.00307096*i),1.7358)*1304.45 | |
628 | |
629 // Interleved gauss table (to improve cache coherency). | |
630 // gauss [i * 2 + j] = normal_gauss [(1 - j) * 256 + i] | |
631 const BOOST::int16_t Spc_Dsp::gauss [512] = | |
632 { | |
633 370,1305, 366,1305, 362,1304, 358,1304, 354,1304, 351,1304, 347,1304, 343,1303, | |
634 339,1303, 336,1303, 332,1302, 328,1302, 325,1301, 321,1300, 318,1300, 314,1299, | |
635 311,1298, 307,1297, 304,1297, 300,1296, 297,1295, 293,1294, 290,1293, 286,1292, | |
636 283,1291, 280,1290, 276,1288, 273,1287, 270,1286, 267,1284, 263,1283, 260,1282, | |
637 257,1280, 254,1279, 251,1277, 248,1275, 245,1274, 242,1272, 239,1270, 236,1269, | |
638 233,1267, 230,1265, 227,1263, 224,1261, 221,1259, 218,1257, 215,1255, 212,1253, | |
639 210,1251, 207,1248, 204,1246, 201,1244, 199,1241, 196,1239, 193,1237, 191,1234, | |
640 188,1232, 186,1229, 183,1227, 180,1224, 178,1221, 175,1219, 173,1216, 171,1213, | |
641 168,1210, 166,1207, 163,1205, 161,1202, 159,1199, 156,1196, 154,1193, 152,1190, | |
642 150,1186, 147,1183, 145,1180, 143,1177, 141,1174, 139,1170, 137,1167, 134,1164, | |
643 132,1160, 130,1157, 128,1153, 126,1150, 124,1146, 122,1143, 120,1139, 118,1136, | |
644 117,1132, 115,1128, 113,1125, 111,1121, 109,1117, 107,1113, 106,1109, 104,1106, | |
645 102,1102, 100,1098, 99,1094, 97,1090, 95,1086, 94,1082, 92,1078, 90,1074, | |
646 89,1070, 87,1066, 86,1061, 84,1057, 83,1053, 81,1049, 80,1045, 78,1040, | |
647 77,1036, 76,1032, 74,1027, 73,1023, 71,1019, 70,1014, 69,1010, 67,1005, | |
648 66,1001, 65, 997, 64, 992, 62, 988, 61, 983, 60, 978, 59, 974, 58, 969, | |
649 56, 965, 55, 960, 54, 955, 53, 951, 52, 946, 51, 941, 50, 937, 49, 932, | |
650 48, 927, 47, 923, 46, 918, 45, 913, 44, 908, 43, 904, 42, 899, 41, 894, | |
651 40, 889, 39, 884, 38, 880, 37, 875, 36, 870, 36, 865, 35, 860, 34, 855, | |
652 33, 851, 32, 846, 32, 841, 31, 836, 30, 831, 29, 826, 29, 821, 28, 816, | |
653 27, 811, 27, 806, 26, 802, 25, 797, 24, 792, 24, 787, 23, 782, 23, 777, | |
654 22, 772, 21, 767, 21, 762, 20, 757, 20, 752, 19, 747, 19, 742, 18, 737, | |
655 17, 732, 17, 728, 16, 723, 16, 718, 15, 713, 15, 708, 15, 703, 14, 698, | |
656 14, 693, 13, 688, 13, 683, 12, 678, 12, 674, 11, 669, 11, 664, 11, 659, | |
657 10, 654, 10, 649, 10, 644, 9, 640, 9, 635, 9, 630, 8, 625, 8, 620, | |
658 8, 615, 7, 611, 7, 606, 7, 601, 6, 596, 6, 592, 6, 587, 6, 582, | |
659 5, 577, 5, 573, 5, 568, 5, 563, 4, 559, 4, 554, 4, 550, 4, 545, | |
660 4, 540, 3, 536, 3, 531, 3, 527, 3, 522, 3, 517, 2, 513, 2, 508, | |
661 2, 504, 2, 499, 2, 495, 2, 491, 2, 486, 1, 482, 1, 477, 1, 473, | |
662 1, 469, 1, 464, 1, 460, 1, 456, 1, 451, 1, 447, 1, 443, 1, 439, | |
663 0, 434, 0, 430, 0, 426, 0, 422, 0, 418, 0, 414, 0, 410, 0, 405, | |
664 0, 401, 0, 397, 0, 393, 0, 389, 0, 385, 0, 381, 0, 378, 0, 374, | |
665 }; | |
666 |