comparison src/console/Effects_Buffer.cxx @ 316:fb513e10174e trunk

[svn] - merge libconsole-blargg into mainline libconsole: + obsoletes plugins-ugly:sapplug
author nenolod
date Thu, 30 Nov 2006 19:54:33 -0800
parents
children 986f098da058
comparison
equal deleted inserted replaced
315:2294f3a6f136 316:fb513e10174e
1 // Game_Music_Emu 0.5.1. http://www.slack.net/~ant/
2
3 #include "Effects_Buffer.h"
4
5 #include <string.h>
6
7 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
8 can redistribute it and/or modify it under the terms of the GNU Lesser
9 General Public License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version. This
11 module is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 details. You should have received a copy of the GNU Lesser General Public
15 License along with this module; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
17
18 #include "blargg_source.h"
19
20 #ifdef BLARGG_ENABLE_OPTIMIZER
21 #include BLARGG_ENABLE_OPTIMIZER
22 #endif
23
24 typedef blargg_long fixed_t;
25
26 #define TO_FIXED( f ) fixed_t ((f) * (1L << 15) + 0.5)
27 #define FMUL( x, y ) (((x) * (y)) >> 15)
28
29 const unsigned echo_size = 4096;
30 const unsigned echo_mask = echo_size - 1;
31 BOOST_STATIC_ASSERT( (echo_size & echo_mask) == 0 ); // must be power of 2
32
33 const unsigned reverb_size = 8192 * 2;
34 const unsigned reverb_mask = reverb_size - 1;
35 BOOST_STATIC_ASSERT( (reverb_size & reverb_mask) == 0 ); // must be power of 2
36
37 Effects_Buffer::config_t::config_t()
38 {
39 pan_1 = -0.15f;
40 pan_2 = 0.15f;
41 reverb_delay = 88.0f;
42 reverb_level = 0.12f;
43 echo_delay = 61.0f;
44 echo_level = 0.10f;
45 delay_variance = 18.0f;
46 effects_enabled = false;
47 }
48
49 void Effects_Buffer::set_depth( double d )
50 {
51 float f = (float) d;
52 config_t c;
53 c.pan_1 = -0.6f * f;
54 c.pan_2 = 0.6f * f;
55 c.reverb_delay = 880 * 0.1f;
56 c.echo_delay = 610 * 0.1f;
57 if ( f > 0.5 )
58 f = 0.5; // TODO: more linear reduction of extreme reverb/echo
59 c.reverb_level = 0.5f * f;
60 c.echo_level = 0.30f * f;
61 c.delay_variance = 180 * 0.1f;
62 c.effects_enabled = (d > 0.0f);
63 config( c );
64 }
65
66 Effects_Buffer::Effects_Buffer( bool center_only ) : Multi_Buffer( 2 )
67 {
68 buf_count = center_only ? max_buf_count - 4 : max_buf_count;
69
70 echo_pos = 0;
71 reverb_pos = 0;
72
73 stereo_remain = 0;
74 effect_remain = 0;
75 effects_enabled = false;
76 set_depth( 0 );
77 }
78
79 Effects_Buffer::~Effects_Buffer() { }
80
81 blargg_err_t Effects_Buffer::set_sample_rate( long rate, int msec )
82 {
83 if ( !echo_buf.size() )
84 RETURN_ERR( echo_buf.resize( echo_size ) );
85
86 if ( !reverb_buf.size() )
87 RETURN_ERR( reverb_buf.resize( reverb_size ) );
88
89 for ( int i = 0; i < buf_count; i++ )
90 RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
91
92 config( config_ );
93 clear();
94
95 return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
96 }
97
98 void Effects_Buffer::clock_rate( long rate )
99 {
100 for ( int i = 0; i < buf_count; i++ )
101 bufs [i].clock_rate( rate );
102 }
103
104 void Effects_Buffer::bass_freq( int freq )
105 {
106 for ( int i = 0; i < buf_count; i++ )
107 bufs [i].bass_freq( freq );
108 }
109
110 void Effects_Buffer::clear()
111 {
112 stereo_remain = 0;
113 effect_remain = 0;
114 if ( echo_buf.size() )
115 memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
116
117 if ( reverb_buf.size() )
118 memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
119
120 for ( int i = 0; i < buf_count; i++ )
121 bufs [i].clear();
122 }
123
124 inline int pin_range( int n, int max, int min = 0 )
125 {
126 if ( n < min )
127 return min;
128 if ( n > max )
129 return max;
130 return n;
131 }
132
133 void Effects_Buffer::config( const config_t& cfg )
134 {
135 channels_changed();
136
137 // clear echo and reverb buffers
138 if ( !config_.effects_enabled && cfg.effects_enabled && echo_buf.size() )
139 {
140 memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
141 memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
142 }
143
144 config_ = cfg;
145
146 if ( config_.effects_enabled )
147 {
148 // convert to internal format
149
150 chans.pan_1_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_1 );
151 chans.pan_1_levels [1] = TO_FIXED( 2 ) - chans.pan_1_levels [0];
152
153 chans.pan_2_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_2 );
154 chans.pan_2_levels [1] = TO_FIXED( 2 ) - chans.pan_2_levels [0];
155
156 chans.reverb_level = TO_FIXED( config_.reverb_level );
157 chans.echo_level = TO_FIXED( config_.echo_level );
158
159 int delay_offset = int (1.0 / 2000 * config_.delay_variance * sample_rate());
160
161 int reverb_sample_delay = int (1.0 / 1000 * config_.reverb_delay * sample_rate());
162 chans.reverb_delay_l = pin_range( reverb_size -
163 (reverb_sample_delay - delay_offset) * 2, reverb_size - 2, 0 );
164 chans.reverb_delay_r = pin_range( reverb_size + 1 -
165 (reverb_sample_delay + delay_offset) * 2, reverb_size - 1, 1 );
166
167 int echo_sample_delay = int (1.0 / 1000 * config_.echo_delay * sample_rate());
168 chans.echo_delay_l = pin_range( echo_size - 1 - (echo_sample_delay - delay_offset),
169 echo_size - 1 );
170 chans.echo_delay_r = pin_range( echo_size - 1 - (echo_sample_delay + delay_offset),
171 echo_size - 1 );
172
173 chan_types [0].center = &bufs [0];
174 chan_types [0].left = &bufs [3];
175 chan_types [0].right = &bufs [4];
176
177 chan_types [1].center = &bufs [1];
178 chan_types [1].left = &bufs [3];
179 chan_types [1].right = &bufs [4];
180
181 chan_types [2].center = &bufs [2];
182 chan_types [2].left = &bufs [5];
183 chan_types [2].right = &bufs [6];
184 assert( 2 < chan_types_count );
185 }
186 else
187 {
188 // set up outputs
189 for ( unsigned i = 0; i < chan_types_count; i++ )
190 {
191 channel_t& c = chan_types [i];
192 c.center = &bufs [0];
193 c.left = &bufs [1];
194 c.right = &bufs [2];
195 }
196 }
197
198 if ( buf_count < max_buf_count )
199 {
200 for ( int i = 0; i < chan_types_count; i++ )
201 {
202 channel_t& c = chan_types [i];
203 c.left = c.center;
204 c.right = c.center;
205 }
206 }
207 }
208
209 Effects_Buffer::channel_t Effects_Buffer::channel( int i, int type )
210 {
211 int out = 2;
212 if ( !type )
213 {
214 out = i % 5;
215 if ( out > 2 )
216 out = 2;
217 }
218 else if ( !(type & noise_type) && (type & type_index_mask) % 3 != 0 )
219 {
220 out = type & 1;
221 }
222 return chan_types [out];
223 }
224
225 void Effects_Buffer::end_frame( blip_time_t clock_count )
226 {
227 int bufs_used = 0;
228 for ( int i = 0; i < buf_count; i++ )
229 {
230 bufs_used |= bufs [i].clear_modified() << i;
231 bufs [i].end_frame( clock_count );
232 }
233
234 int stereo_mask = (config_.effects_enabled ? 0x78 : 0x06);
235 if ( (bufs_used & stereo_mask) && buf_count == max_buf_count )
236 stereo_remain = bufs [0].samples_avail() + bufs [0].output_latency();
237
238 if ( effects_enabled || config_.effects_enabled )
239 effect_remain = bufs [0].samples_avail() + bufs [0].output_latency();
240
241 effects_enabled = config_.effects_enabled;
242 }
243
244 long Effects_Buffer::samples_avail() const
245 {
246 return bufs [0].samples_avail() * 2;
247 }
248
249 long Effects_Buffer::read_samples( blip_sample_t* out, long total_samples )
250 {
251 require( total_samples % 2 == 0 ); // count must be even
252
253 long remain = bufs [0].samples_avail();
254 if ( remain > (total_samples >> 1) )
255 remain = (total_samples >> 1);
256 total_samples = remain;
257 while ( remain )
258 {
259 int active_bufs = buf_count;
260 long count = remain;
261
262 // optimizing mixing to skip any channels which had nothing added
263 if ( effect_remain )
264 {
265 if ( count > effect_remain )
266 count = effect_remain;
267
268 if ( stereo_remain )
269 {
270 mix_enhanced( out, count );
271 }
272 else
273 {
274 mix_mono_enhanced( out, count );
275 active_bufs = 3;
276 }
277 }
278 else if ( stereo_remain )
279 {
280 mix_stereo( out, count );
281 active_bufs = 3;
282 }
283 else
284 {
285 mix_mono( out, count );
286 active_bufs = 1;
287 }
288
289 out += count * 2;
290 remain -= count;
291
292 stereo_remain -= count;
293 if ( stereo_remain < 0 )
294 stereo_remain = 0;
295
296 effect_remain -= count;
297 if ( effect_remain < 0 )
298 effect_remain = 0;
299
300 for ( int i = 0; i < buf_count; i++ )
301 {
302 if ( i < active_bufs )
303 bufs [i].remove_samples( count );
304 else
305 bufs [i].remove_silence( count ); // keep time synchronized
306 }
307 }
308
309 return total_samples * 2;
310 }
311
312 void Effects_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
313 {
314 blip_sample_t* BLIP_RESTRICT out = out_;
315 int const bass = BLIP_READER_BASS( bufs [0] );
316 BLIP_READER_BEGIN( c, bufs [0] );
317
318 // unrolled loop
319 for ( blargg_long n = count >> 1; n; --n )
320 {
321 blargg_long cs0 = BLIP_READER_READ( c );
322 BLIP_READER_NEXT( c, bass );
323
324 blargg_long cs1 = BLIP_READER_READ( c );
325 BLIP_READER_NEXT( c, bass );
326
327 if ( (BOOST::int16_t) cs0 != cs0 )
328 cs0 = 0x7FFF - (cs0 >> 24);
329 ((BOOST::uint32_t*) out) [0] = ((BOOST::uint16_t) cs0) | (cs0 << 16);
330
331 if ( (BOOST::int16_t) cs1 != cs1 )
332 cs1 = 0x7FFF - (cs1 >> 24);
333 ((BOOST::uint32_t*) out) [1] = ((BOOST::uint16_t) cs1) | (cs1 << 16);
334 out += 4;
335 }
336
337 if ( count & 1 )
338 {
339 int s = BLIP_READER_READ( c );
340 BLIP_READER_NEXT( c, bass );
341 out [0] = s;
342 out [1] = s;
343 if ( (BOOST::int16_t) s != s )
344 {
345 s = 0x7FFF - (s >> 24);
346 out [0] = s;
347 out [1] = s;
348 }
349 }
350
351 BLIP_READER_END( c, bufs [0] );
352 }
353
354 void Effects_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
355 {
356 blip_sample_t* BLIP_RESTRICT out = out_;
357 int const bass = BLIP_READER_BASS( bufs [0] );
358 BLIP_READER_BEGIN( c, bufs [0] );
359 BLIP_READER_BEGIN( l, bufs [1] );
360 BLIP_READER_BEGIN( r, bufs [2] );
361
362 while ( count-- )
363 {
364 int cs = BLIP_READER_READ( c );
365 BLIP_READER_NEXT( c, bass );
366 int left = cs + BLIP_READER_READ( l );
367 int right = cs + BLIP_READER_READ( r );
368 BLIP_READER_NEXT( l, bass );
369 BLIP_READER_NEXT( r, bass );
370
371 if ( (BOOST::int16_t) left != left )
372 left = 0x7FFF - (left >> 24);
373
374 out [0] = left;
375 out [1] = right;
376
377 out += 2;
378
379 if ( (BOOST::int16_t) right != right )
380 out [-1] = 0x7FFF - (right >> 24);
381 }
382
383 BLIP_READER_END( r, bufs [2] );
384 BLIP_READER_END( l, bufs [1] );
385 BLIP_READER_END( c, bufs [0] );
386 }
387
388 void Effects_Buffer::mix_mono_enhanced( blip_sample_t* out_, blargg_long count )
389 {
390 blip_sample_t* BLIP_RESTRICT out = out_;
391 int const bass = BLIP_READER_BASS( bufs [2] );
392 BLIP_READER_BEGIN( center, bufs [2] );
393 BLIP_READER_BEGIN( sq1, bufs [0] );
394 BLIP_READER_BEGIN( sq2, bufs [1] );
395
396 blip_sample_t* const reverb_buf = this->reverb_buf.begin();
397 blip_sample_t* const echo_buf = this->echo_buf.begin();
398 int echo_pos = this->echo_pos;
399 int reverb_pos = this->reverb_pos;
400
401 while ( count-- )
402 {
403 int sum1_s = BLIP_READER_READ( sq1 );
404 int sum2_s = BLIP_READER_READ( sq2 );
405
406 BLIP_READER_NEXT( sq1, bass );
407 BLIP_READER_NEXT( sq2, bass );
408
409 int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
410 FMUL( sum2_s, chans.pan_2_levels [0] ) +
411 reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
412
413 int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
414 FMUL( sum2_s, chans.pan_2_levels [1] ) +
415 reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
416
417 fixed_t reverb_level = chans.reverb_level;
418 reverb_buf [reverb_pos] = FMUL( new_reverb_l, reverb_level );
419 reverb_buf [reverb_pos + 1] = FMUL( new_reverb_r, reverb_level );
420 reverb_pos = (reverb_pos + 2) & reverb_mask;
421
422 int sum3_s = BLIP_READER_READ( center );
423 BLIP_READER_NEXT( center, bass );
424
425 int left = new_reverb_l + sum3_s + FMUL( chans.echo_level,
426 echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
427 int right = new_reverb_r + sum3_s + FMUL( chans.echo_level,
428 echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
429
430 echo_buf [echo_pos] = sum3_s;
431 echo_pos = (echo_pos + 1) & echo_mask;
432
433 if ( (BOOST::int16_t) left != left )
434 left = 0x7FFF - (left >> 24);
435
436 out [0] = left;
437 out [1] = right;
438
439 out += 2;
440
441 if ( (BOOST::int16_t) right != right )
442 out [-1] = 0x7FFF - (right >> 24);
443 }
444 this->reverb_pos = reverb_pos;
445 this->echo_pos = echo_pos;
446
447 BLIP_READER_END( sq1, bufs [0] );
448 BLIP_READER_END( sq2, bufs [1] );
449 BLIP_READER_END( center, bufs [2] );
450 }
451
452 void Effects_Buffer::mix_enhanced( blip_sample_t* out_, blargg_long count )
453 {
454 blip_sample_t* BLIP_RESTRICT out = out_;
455 int const bass = BLIP_READER_BASS( bufs [2] );
456 BLIP_READER_BEGIN( center, bufs [2] );
457 BLIP_READER_BEGIN( l1, bufs [3] );
458 BLIP_READER_BEGIN( r1, bufs [4] );
459 BLIP_READER_BEGIN( l2, bufs [5] );
460 BLIP_READER_BEGIN( r2, bufs [6] );
461 BLIP_READER_BEGIN( sq1, bufs [0] );
462 BLIP_READER_BEGIN( sq2, bufs [1] );
463
464 blip_sample_t* const reverb_buf = this->reverb_buf.begin();
465 blip_sample_t* const echo_buf = this->echo_buf.begin();
466 int echo_pos = this->echo_pos;
467 int reverb_pos = this->reverb_pos;
468
469 while ( count-- )
470 {
471 int sum1_s = BLIP_READER_READ( sq1 );
472 int sum2_s = BLIP_READER_READ( sq2 );
473
474 BLIP_READER_NEXT( sq1, bass );
475 BLIP_READER_NEXT( sq2, bass );
476
477 int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
478 FMUL( sum2_s, chans.pan_2_levels [0] ) + BLIP_READER_READ( l1 ) +
479 reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
480
481 int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
482 FMUL( sum2_s, chans.pan_2_levels [1] ) + BLIP_READER_READ( r1 ) +
483 reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
484
485 BLIP_READER_NEXT( l1, bass );
486 BLIP_READER_NEXT( r1, bass );
487
488 fixed_t reverb_level = chans.reverb_level;
489 reverb_buf [reverb_pos] = FMUL( new_reverb_l, reverb_level );
490 reverb_buf [reverb_pos + 1] = FMUL( new_reverb_r, reverb_level );
491 reverb_pos = (reverb_pos + 2) & reverb_mask;
492
493 int sum3_s = BLIP_READER_READ( center );
494 BLIP_READER_NEXT( center, bass );
495
496 int left = new_reverb_l + sum3_s + BLIP_READER_READ( l2 ) + FMUL( chans.echo_level,
497 echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
498 int right = new_reverb_r + sum3_s + BLIP_READER_READ( r2 ) + FMUL( chans.echo_level,
499 echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
500
501 BLIP_READER_NEXT( l2, bass );
502 BLIP_READER_NEXT( r2, bass );
503
504 echo_buf [echo_pos] = sum3_s;
505 echo_pos = (echo_pos + 1) & echo_mask;
506
507 if ( (BOOST::int16_t) left != left )
508 left = 0x7FFF - (left >> 24);
509
510 out [0] = left;
511 out [1] = right;
512
513 out += 2;
514
515 if ( (BOOST::int16_t) right != right )
516 out [-1] = 0x7FFF - (right >> 24);
517 }
518 this->reverb_pos = reverb_pos;
519 this->echo_pos = echo_pos;
520
521 BLIP_READER_END( l1, bufs [3] );
522 BLIP_READER_END( r1, bufs [4] );
523 BLIP_READER_END( l2, bufs [5] );
524 BLIP_READER_END( r2, bufs [6] );
525 BLIP_READER_END( sq1, bufs [0] );
526 BLIP_READER_END( sq2, bufs [1] );
527 BLIP_READER_END( center, bufs [2] );
528 }
529