summaryrefslogtreecommitdiff
path: root/plugins/gme/game-music-emu-svn/gme/Effects_Buffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gme/game-music-emu-svn/gme/Effects_Buffer.cpp')
-rw-r--r--plugins/gme/game-music-emu-svn/gme/Effects_Buffer.cpp529
1 files changed, 0 insertions, 529 deletions
diff --git a/plugins/gme/game-music-emu-svn/gme/Effects_Buffer.cpp b/plugins/gme/game-music-emu-svn/gme/Effects_Buffer.cpp
deleted file mode 100644
index 181b11e9..00000000
--- a/plugins/gme/game-music-emu-svn/gme/Effects_Buffer.cpp
+++ /dev/null
@@ -1,529 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Effects_Buffer.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-typedef blargg_long fixed_t;
-
-#define TO_FIXED( f ) fixed_t ((f) * (1L << 15) + 0.5)
-#define FMUL( x, y ) (((x) * (y)) >> 15)
-
-const unsigned echo_size = 4096;
-const unsigned echo_mask = echo_size - 1;
-BOOST_STATIC_ASSERT( (echo_size & echo_mask) == 0 ); // must be power of 2
-
-const unsigned reverb_size = 8192 * 2;
-const unsigned reverb_mask = reverb_size - 1;
-BOOST_STATIC_ASSERT( (reverb_size & reverb_mask) == 0 ); // must be power of 2
-
-Effects_Buffer::config_t::config_t()
-{
- pan_1 = -0.15f;
- pan_2 = 0.15f;
- reverb_delay = 88.0f;
- reverb_level = 0.12f;
- echo_delay = 61.0f;
- echo_level = 0.10f;
- delay_variance = 18.0f;
- effects_enabled = false;
-}
-
-void Effects_Buffer::set_depth( double d )
-{
- float f = (float) d;
- config_t c;
- c.pan_1 = -0.6f * f;
- c.pan_2 = 0.6f * f;
- c.reverb_delay = 880 * 0.1f;
- c.echo_delay = 610 * 0.1f;
- if ( f > 0.5 )
- f = 0.5; // TODO: more linear reduction of extreme reverb/echo
- c.reverb_level = 0.5f * f;
- c.echo_level = 0.30f * f;
- c.delay_variance = 180 * 0.1f;
- c.effects_enabled = (d > 0.0f);
- config( c );
-}
-
-Effects_Buffer::Effects_Buffer( bool center_only ) : Multi_Buffer( 2 )
-{
- buf_count = center_only ? max_buf_count - 4 : max_buf_count;
-
- echo_pos = 0;
- reverb_pos = 0;
-
- stereo_remain = 0;
- effect_remain = 0;
- effects_enabled = false;
- set_depth( 0 );
-}
-
-Effects_Buffer::~Effects_Buffer() { }
-
-blargg_err_t Effects_Buffer::set_sample_rate( long rate, int msec )
-{
- if ( !echo_buf.size() )
- RETURN_ERR( echo_buf.resize( echo_size ) );
-
- if ( !reverb_buf.size() )
- RETURN_ERR( reverb_buf.resize( reverb_size ) );
-
- for ( int i = 0; i < buf_count; i++ )
- RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
-
- config( config_ );
- clear();
-
- return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
-}
-
-void Effects_Buffer::clock_rate( long rate )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clock_rate( rate );
-}
-
-void Effects_Buffer::bass_freq( int freq )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].bass_freq( freq );
-}
-
-void Effects_Buffer::clear()
-{
- stereo_remain = 0;
- effect_remain = 0;
- if ( echo_buf.size() )
- memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
-
- if ( reverb_buf.size() )
- memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
-
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clear();
-}
-
-inline int pin_range( int n, int max, int min = 0 )
-{
- if ( n < min )
- return min;
- if ( n > max )
- return max;
- return n;
-}
-
-void Effects_Buffer::config( const config_t& cfg )
-{
- channels_changed();
-
- // clear echo and reverb buffers
- if ( !config_.effects_enabled && cfg.effects_enabled && echo_buf.size() )
- {
- memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
- memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
- }
-
- config_ = cfg;
-
- if ( config_.effects_enabled )
- {
- // convert to internal format
-
- chans.pan_1_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_1 );
- chans.pan_1_levels [1] = TO_FIXED( 2 ) - chans.pan_1_levels [0];
-
- chans.pan_2_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_2 );
- chans.pan_2_levels [1] = TO_FIXED( 2 ) - chans.pan_2_levels [0];
-
- chans.reverb_level = TO_FIXED( config_.reverb_level );
- chans.echo_level = TO_FIXED( config_.echo_level );
-
- int delay_offset = int (1.0 / 2000 * config_.delay_variance * sample_rate());
-
- int reverb_sample_delay = int (1.0 / 1000 * config_.reverb_delay * sample_rate());
- chans.reverb_delay_l = pin_range( reverb_size -
- (reverb_sample_delay - delay_offset) * 2, reverb_size - 2, 0 );
- chans.reverb_delay_r = pin_range( reverb_size + 1 -
- (reverb_sample_delay + delay_offset) * 2, reverb_size - 1, 1 );
-
- int echo_sample_delay = int (1.0 / 1000 * config_.echo_delay * sample_rate());
- chans.echo_delay_l = pin_range( echo_size - 1 - (echo_sample_delay - delay_offset),
- echo_size - 1 );
- chans.echo_delay_r = pin_range( echo_size - 1 - (echo_sample_delay + delay_offset),
- echo_size - 1 );
-
- chan_types [0].center = &bufs [0];
- chan_types [0].left = &bufs [3];
- chan_types [0].right = &bufs [4];
-
- chan_types [1].center = &bufs [1];
- chan_types [1].left = &bufs [3];
- chan_types [1].right = &bufs [4];
-
- chan_types [2].center = &bufs [2];
- chan_types [2].left = &bufs [5];
- chan_types [2].right = &bufs [6];
- assert( 2 < chan_types_count );
- }
- else
- {
- // set up outputs
- for ( unsigned i = 0; i < chan_types_count; i++ )
- {
- channel_t& c = chan_types [i];
- c.center = &bufs [0];
- c.left = &bufs [1];
- c.right = &bufs [2];
- }
- }
-
- if ( buf_count < max_buf_count )
- {
- for ( int i = 0; i < chan_types_count; i++ )
- {
- channel_t& c = chan_types [i];
- c.left = c.center;
- c.right = c.center;
- }
- }
-}
-
-Effects_Buffer::channel_t Effects_Buffer::channel( int i, int type )
-{
- int out = 2;
- if ( !type )
- {
- out = i % 5;
- if ( out > 2 )
- out = 2;
- }
- else if ( !(type & noise_type) && (type & type_index_mask) % 3 != 0 )
- {
- out = type & 1;
- }
- return chan_types [out];
-}
-
-void Effects_Buffer::end_frame( blip_time_t clock_count )
-{
- int bufs_used = 0;
- for ( int i = 0; i < buf_count; i++ )
- {
- bufs_used |= bufs [i].clear_modified() << i;
- bufs [i].end_frame( clock_count );
- }
-
- int stereo_mask = (config_.effects_enabled ? 0x78 : 0x06);
- if ( (bufs_used & stereo_mask) && buf_count == max_buf_count )
- stereo_remain = bufs [0].samples_avail() + bufs [0].output_latency();
-
- if ( effects_enabled || config_.effects_enabled )
- effect_remain = bufs [0].samples_avail() + bufs [0].output_latency();
-
- effects_enabled = config_.effects_enabled;
-}
-
-long Effects_Buffer::samples_avail() const
-{
- return bufs [0].samples_avail() * 2;
-}
-
-long Effects_Buffer::read_samples( blip_sample_t* out, long total_samples )
-{
- require( total_samples % 2 == 0 ); // count must be even
-
- long remain = bufs [0].samples_avail();
- if ( remain > (total_samples >> 1) )
- remain = (total_samples >> 1);
- total_samples = remain;
- while ( remain )
- {
- int active_bufs = buf_count;
- long count = remain;
-
- // optimizing mixing to skip any channels which had nothing added
- if ( effect_remain )
- {
- if ( count > effect_remain )
- count = effect_remain;
-
- if ( stereo_remain )
- {
- mix_enhanced( out, count );
- }
- else
- {
- mix_mono_enhanced( out, count );
- active_bufs = 3;
- }
- }
- else if ( stereo_remain )
- {
- mix_stereo( out, count );
- active_bufs = 3;
- }
- else
- {
- mix_mono( out, count );
- active_bufs = 1;
- }
-
- out += count * 2;
- remain -= count;
-
- stereo_remain -= count;
- if ( stereo_remain < 0 )
- stereo_remain = 0;
-
- effect_remain -= count;
- if ( effect_remain < 0 )
- effect_remain = 0;
-
- for ( int i = 0; i < buf_count; i++ )
- {
- if ( i < active_bufs )
- bufs [i].remove_samples( count );
- else
- bufs [i].remove_silence( count ); // keep time synchronized
- }
- }
-
- return total_samples * 2;
-}
-
-void Effects_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( c, bufs [0] );
-
- // unrolled loop
- for ( blargg_long n = count >> 1; n; --n )
- {
- blargg_long cs0 = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
-
- blargg_long cs1 = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
-
- if ( (BOOST::int16_t) cs0 != cs0 )
- cs0 = 0x7FFF - (cs0 >> 24);
- ((BOOST::uint32_t*) out) [0] = ((BOOST::uint16_t) cs0) | (cs0 << 16);
-
- if ( (BOOST::int16_t) cs1 != cs1 )
- cs1 = 0x7FFF - (cs1 >> 24);
- ((BOOST::uint32_t*) out) [1] = ((BOOST::uint16_t) cs1) | (cs1 << 16);
- out += 4;
- }
-
- if ( count & 1 )
- {
- int s = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
- out [0] = s;
- out [1] = s;
- if ( (BOOST::int16_t) s != s )
- {
- s = 0x7FFF - (s >> 24);
- out [0] = s;
- out [1] = s;
- }
- }
-
- BLIP_READER_END( c, bufs [0] );
-}
-
-void Effects_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( c, bufs [0] );
- BLIP_READER_BEGIN( l, bufs [1] );
- BLIP_READER_BEGIN( r, bufs [2] );
-
- while ( count-- )
- {
- int cs = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
- int left = cs + BLIP_READER_READ( l );
- int right = cs + BLIP_READER_READ( r );
- BLIP_READER_NEXT( l, bass );
- BLIP_READER_NEXT( r, bass );
-
- if ( (BOOST::int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (BOOST::int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
-
- BLIP_READER_END( r, bufs [2] );
- BLIP_READER_END( l, bufs [1] );
- BLIP_READER_END( c, bufs [0] );
-}
-
-void Effects_Buffer::mix_mono_enhanced( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [2] );
- BLIP_READER_BEGIN( center, bufs [2] );
- BLIP_READER_BEGIN( sq1, bufs [0] );
- BLIP_READER_BEGIN( sq2, bufs [1] );
-
- blip_sample_t* const reverb_buf = this->reverb_buf.begin();
- blip_sample_t* const echo_buf = this->echo_buf.begin();
- int echo_pos = this->echo_pos;
- int reverb_pos = this->reverb_pos;
-
- while ( count-- )
- {
- int sum1_s = BLIP_READER_READ( sq1 );
- int sum2_s = BLIP_READER_READ( sq2 );
-
- BLIP_READER_NEXT( sq1, bass );
- BLIP_READER_NEXT( sq2, bass );
-
- int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
- FMUL( sum2_s, chans.pan_2_levels [0] ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
-
- int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
- FMUL( sum2_s, chans.pan_2_levels [1] ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
-
- fixed_t reverb_level = chans.reverb_level;
- reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
- reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
- reverb_pos = (reverb_pos + 2) & reverb_mask;
-
- int sum3_s = BLIP_READER_READ( center );
- BLIP_READER_NEXT( center, bass );
-
- int left = new_reverb_l + sum3_s + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
- int right = new_reverb_r + sum3_s + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
-
- echo_buf [echo_pos] = sum3_s;
- echo_pos = (echo_pos + 1) & echo_mask;
-
- if ( (BOOST::int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (BOOST::int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
- this->reverb_pos = reverb_pos;
- this->echo_pos = echo_pos;
-
- BLIP_READER_END( sq1, bufs [0] );
- BLIP_READER_END( sq2, bufs [1] );
- BLIP_READER_END( center, bufs [2] );
-}
-
-void Effects_Buffer::mix_enhanced( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [2] );
- BLIP_READER_BEGIN( center, bufs [2] );
- BLIP_READER_BEGIN( l1, bufs [3] );
- BLIP_READER_BEGIN( r1, bufs [4] );
- BLIP_READER_BEGIN( l2, bufs [5] );
- BLIP_READER_BEGIN( r2, bufs [6] );
- BLIP_READER_BEGIN( sq1, bufs [0] );
- BLIP_READER_BEGIN( sq2, bufs [1] );
-
- blip_sample_t* const reverb_buf = this->reverb_buf.begin();
- blip_sample_t* const echo_buf = this->echo_buf.begin();
- int echo_pos = this->echo_pos;
- int reverb_pos = this->reverb_pos;
-
- while ( count-- )
- {
- int sum1_s = BLIP_READER_READ( sq1 );
- int sum2_s = BLIP_READER_READ( sq2 );
-
- BLIP_READER_NEXT( sq1, bass );
- BLIP_READER_NEXT( sq2, bass );
-
- int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
- FMUL( sum2_s, chans.pan_2_levels [0] ) + BLIP_READER_READ( l1 ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
-
- int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
- FMUL( sum2_s, chans.pan_2_levels [1] ) + BLIP_READER_READ( r1 ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
-
- BLIP_READER_NEXT( l1, bass );
- BLIP_READER_NEXT( r1, bass );
-
- fixed_t reverb_level = chans.reverb_level;
- reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
- reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
- reverb_pos = (reverb_pos + 2) & reverb_mask;
-
- int sum3_s = BLIP_READER_READ( center );
- BLIP_READER_NEXT( center, bass );
-
- int left = new_reverb_l + sum3_s + BLIP_READER_READ( l2 ) + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
- int right = new_reverb_r + sum3_s + BLIP_READER_READ( r2 ) + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
-
- BLIP_READER_NEXT( l2, bass );
- BLIP_READER_NEXT( r2, bass );
-
- echo_buf [echo_pos] = sum3_s;
- echo_pos = (echo_pos + 1) & echo_mask;
-
- if ( (BOOST::int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (BOOST::int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
- this->reverb_pos = reverb_pos;
- this->echo_pos = echo_pos;
-
- BLIP_READER_END( l1, bufs [3] );
- BLIP_READER_END( r1, bufs [4] );
- BLIP_READER_END( l2, bufs [5] );
- BLIP_READER_END( r2, bufs [6] );
- BLIP_READER_END( sq1, bufs [0] );
- BLIP_READER_END( sq2, bufs [1] );
- BLIP_READER_END( center, bufs [2] );
-}
-