1
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
3
#include "Effects_Buffer.h"
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 */
18
#include "blargg_source.h"
20
#ifdef BLARGG_ENABLE_OPTIMIZER
21
#include BLARGG_ENABLE_OPTIMIZER
24
typedef blargg_long fixed_t;
26
#define TO_FIXED( f ) fixed_t ((f) * (1L << 15) + 0.5)
27
#define FMUL( x, y ) (((x) * (y)) >> 15)
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
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
37
Effects_Buffer::config_t::config_t()
45
delay_variance = 18.0f;
46
effects_enabled = false;
49
void Effects_Buffer::set_depth( double d )
55
c.reverb_delay = 880 * 0.1f;
56
c.echo_delay = 610 * 0.1f;
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);
66
Effects_Buffer::Effects_Buffer( bool center_only ) : Multi_Buffer( 2 )
68
buf_count = center_only ? max_buf_count - 4 : max_buf_count;
75
effects_enabled = false;
79
Effects_Buffer::~Effects_Buffer() { }
81
blargg_err_t Effects_Buffer::set_sample_rate( long rate, int msec )
83
if ( !echo_buf.size() )
84
RETURN_ERR( echo_buf.resize( echo_size ) );
86
if ( !reverb_buf.size() )
87
RETURN_ERR( reverb_buf.resize( reverb_size ) );
89
for ( int i = 0; i < buf_count; i++ )
90
RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
95
return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
98
void Effects_Buffer::clock_rate( long rate )
100
for ( int i = 0; i < buf_count; i++ )
101
bufs [i].clock_rate( rate );
104
void Effects_Buffer::bass_freq( int freq )
106
for ( int i = 0; i < buf_count; i++ )
107
bufs [i].bass_freq( freq );
110
void Effects_Buffer::clear()
114
if ( echo_buf.size() )
115
memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
117
if ( reverb_buf.size() )
118
memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
120
for ( int i = 0; i < buf_count; i++ )
124
inline int pin_range( int n, int max, int min = 0 )
133
void Effects_Buffer::config( const config_t& cfg )
137
// clear echo and reverb buffers
138
if ( !config_.effects_enabled && cfg.effects_enabled && echo_buf.size() )
140
memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
141
memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
146
if ( config_.effects_enabled )
148
// convert to internal format
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];
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];
156
chans.reverb_level = TO_FIXED( config_.reverb_level );
157
chans.echo_level = TO_FIXED( config_.echo_level );
159
int delay_offset = int (1.0 / 2000 * config_.delay_variance * sample_rate());
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 );
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),
170
chans.echo_delay_r = pin_range( echo_size - 1 - (echo_sample_delay + delay_offset),
173
chan_types [0].center = &bufs [0];
174
chan_types [0].left = &bufs [3];
175
chan_types [0].right = &bufs [4];
177
chan_types [1].center = &bufs [1];
178
chan_types [1].left = &bufs [3];
179
chan_types [1].right = &bufs [4];
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 );
189
for ( unsigned i = 0; i < chan_types_count; i++ )
191
channel_t& c = chan_types [i];
192
c.center = &bufs [0];
198
if ( buf_count < max_buf_count )
200
for ( int i = 0; i < chan_types_count; i++ )
202
channel_t& c = chan_types [i];
209
Effects_Buffer::channel_t Effects_Buffer::channel( int i, int type )
218
else if ( !(type & noise_type) && (type & type_index_mask) % 3 != 0 )
222
return chan_types [out];
225
void Effects_Buffer::end_frame( blip_time_t clock_count )
228
for ( int i = 0; i < buf_count; i++ )
230
bufs_used |= bufs [i].clear_modified() << i;
231
bufs [i].end_frame( clock_count );
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();
238
if ( effects_enabled || config_.effects_enabled )
239
effect_remain = bufs [0].samples_avail() + bufs [0].output_latency();
241
effects_enabled = config_.effects_enabled;
244
long Effects_Buffer::samples_avail() const
246
return bufs [0].samples_avail() * 2;
249
long Effects_Buffer::read_samples( blip_sample_t* out, long total_samples )
251
require( total_samples % 2 == 0 ); // count must be even
253
long remain = bufs [0].samples_avail();
254
if ( remain > (total_samples >> 1) )
255
remain = (total_samples >> 1);
256
total_samples = remain;
259
int active_bufs = buf_count;
262
// optimizing mixing to skip any channels which had nothing added
265
if ( count > effect_remain )
266
count = effect_remain;
270
mix_enhanced( out, count );
274
mix_mono_enhanced( out, count );
278
else if ( stereo_remain )
280
mix_stereo( out, count );
285
mix_mono( out, count );
292
stereo_remain -= count;
293
if ( stereo_remain < 0 )
296
effect_remain -= count;
297
if ( effect_remain < 0 )
300
for ( int i = 0; i < buf_count; i++ )
302
if ( i < active_bufs )
303
bufs [i].remove_samples( count );
305
bufs [i].remove_silence( count ); // keep time synchronized
309
return total_samples * 2;
312
void Effects_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
314
blip_sample_t* BLIP_RESTRICT out = out_;
315
int const bass = BLIP_READER_BASS( bufs [0] );
316
BLIP_READER_BEGIN( c, bufs [0] );
319
for ( blargg_long n = count >> 1; n; --n )
321
blargg_long cs0 = BLIP_READER_READ( c );
322
BLIP_READER_NEXT( c, bass );
324
blargg_long cs1 = BLIP_READER_READ( c );
325
BLIP_READER_NEXT( c, bass );
327
if ( (BOOST::int16_t) cs0 != cs0 )
328
cs0 = 0x7FFF - (cs0 >> 24);
329
((BOOST::uint32_t*) out) [0] = ((BOOST::uint16_t) cs0) | (cs0 << 16);
331
if ( (BOOST::int16_t) cs1 != cs1 )
332
cs1 = 0x7FFF - (cs1 >> 24);
333
((BOOST::uint32_t*) out) [1] = ((BOOST::uint16_t) cs1) | (cs1 << 16);
339
int s = BLIP_READER_READ( c );
340
BLIP_READER_NEXT( c, bass );
343
if ( (BOOST::int16_t) s != s )
345
s = 0x7FFF - (s >> 24);
351
BLIP_READER_END( c, bufs [0] );
354
void Effects_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
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] );
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 );
371
if ( (BOOST::int16_t) left != left )
372
left = 0x7FFF - (left >> 24);
379
if ( (BOOST::int16_t) right != right )
380
out [-1] = 0x7FFF - (right >> 24);
383
BLIP_READER_END( r, bufs [2] );
384
BLIP_READER_END( l, bufs [1] );
385
BLIP_READER_END( c, bufs [0] );
388
void Effects_Buffer::mix_mono_enhanced( blip_sample_t* out_, blargg_long count )
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] );
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;
403
int sum1_s = BLIP_READER_READ( sq1 );
404
int sum2_s = BLIP_READER_READ( sq2 );
406
BLIP_READER_NEXT( sq1, bass );
407
BLIP_READER_NEXT( sq2, bass );
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];
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];
417
fixed_t reverb_level = chans.reverb_level;
418
reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
419
reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
420
reverb_pos = (reverb_pos + 2) & reverb_mask;
422
int sum3_s = BLIP_READER_READ( center );
423
BLIP_READER_NEXT( center, bass );
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] );
430
echo_buf [echo_pos] = sum3_s;
431
echo_pos = (echo_pos + 1) & echo_mask;
433
if ( (BOOST::int16_t) left != left )
434
left = 0x7FFF - (left >> 24);
441
if ( (BOOST::int16_t) right != right )
442
out [-1] = 0x7FFF - (right >> 24);
444
this->reverb_pos = reverb_pos;
445
this->echo_pos = echo_pos;
447
BLIP_READER_END( sq1, bufs [0] );
448
BLIP_READER_END( sq2, bufs [1] );
449
BLIP_READER_END( center, bufs [2] );
452
void Effects_Buffer::mix_enhanced( blip_sample_t* out_, blargg_long count )
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] );
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;
471
int sum1_s = BLIP_READER_READ( sq1 );
472
int sum2_s = BLIP_READER_READ( sq2 );
474
BLIP_READER_NEXT( sq1, bass );
475
BLIP_READER_NEXT( sq2, bass );
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];
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];
485
BLIP_READER_NEXT( l1, bass );
486
BLIP_READER_NEXT( r1, bass );
488
fixed_t reverb_level = chans.reverb_level;
489
reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
490
reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
491
reverb_pos = (reverb_pos + 2) & reverb_mask;
493
int sum3_s = BLIP_READER_READ( center );
494
BLIP_READER_NEXT( center, bass );
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] );
501
BLIP_READER_NEXT( l2, bass );
502
BLIP_READER_NEXT( r2, bass );
504
echo_buf [echo_pos] = sum3_s;
505
echo_pos = (echo_pos + 1) & echo_mask;
507
if ( (BOOST::int16_t) left != left )
508
left = 0x7FFF - (left >> 24);
515
if ( (BOOST::int16_t) right != right )
516
out [-1] = 0x7FFF - (right >> 24);
518
this->reverb_pos = reverb_pos;
519
this->echo_pos = echo_pos;
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] );