diff options
Diffstat (limited to 'plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.cpp')
-rw-r--r-- | plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.cpp | 410 |
1 files changed, 0 insertions, 410 deletions
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.cpp deleted file mode 100644 index 31c7233c..00000000 --- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.cpp +++ /dev/null @@ -1,410 +0,0 @@ -// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ - -#include "Music_Emu.h" - -#include "Multi_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" - -int const stereo = 2; // number of channels for stereo -int const silence_max = 6; // seconds -int const silence_threshold = 0x10; -long const fade_block_size = 512; -int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift) - -Music_Emu::equalizer_t const Music_Emu::tv_eq = { -8.0, 180 }; - -void Music_Emu::clear_track_vars() -{ - current_track_ = -1; - out_time = 0; - emu_time = 0; - emu_track_ended_ = true; - track_ended_ = true; - fade_start = LONG_MAX / 2 + 1; - fade_step = 1; - silence_time = 0; - silence_count = 0; - buf_remain = 0; - warning(); // clear warning -} - -void Music_Emu::unload() -{ - voice_count_ = 0; - clear_track_vars(); - Gme_File::unload(); -} - -Music_Emu::Music_Emu() -{ - effects_buffer = 0; - - sample_rate_ = 0; - mute_mask_ = 0; - tempo_ = 1.0; - gain_ = 1.0; - - // defaults - max_initial_silence = 2; - silence_lookahead = 3; - ignore_silence_ = false; - equalizer_.treble = -1.0; - equalizer_.bass = 60; - - static const char* const names [] = { - "Voice 1", "Voice 2", "Voice 3", "Voice 4", - "Voice 5", "Voice 6", "Voice 7", "Voice 8" - }; - set_voice_names( names ); - Music_Emu::unload(); // non-virtual -} - -Music_Emu::~Music_Emu() { delete effects_buffer; } - -blargg_err_t Music_Emu::set_sample_rate( long rate ) -{ - require( !sample_rate() ); // sample rate can't be changed once set - RETURN_ERR( set_sample_rate_( rate ) ); - RETURN_ERR( buf.resize( buf_size ) ); - sample_rate_ = rate; - return 0; -} - -void Music_Emu::pre_load() -{ - require( sample_rate() ); // set_sample_rate() must be called before loading a file - Gme_File::pre_load(); -} - -void Music_Emu::set_equalizer( equalizer_t const& eq ) -{ - equalizer_ = eq; - set_equalizer_( eq ); -} - -void Music_Emu::mute_voice( int index, bool mute ) -{ - require( (unsigned) index < (unsigned) voice_count() ); - int bit = 1 << index; - int mask = mute_mask_ | bit; - if ( !mute ) - mask ^= bit; - mute_voices( mask ); -} - -void Music_Emu::mute_voices( int mask ) -{ - require( sample_rate() ); // sample rate must be set first - mute_mask_ = mask; - mute_voices_( mask ); -} - -void Music_Emu::set_tempo( double t ) -{ - require( sample_rate() ); // sample rate must be set first - double const min = 0.02; - double const max = 4.00; - if ( t < min ) t = min; - if ( t > max ) t = max; - tempo_ = t; - set_tempo_( t ); -} - -void Music_Emu::post_load_() -{ - set_tempo( tempo_ ); - remute_voices(); -} - -blargg_err_t Music_Emu::start_track( int track ) -{ - clear_track_vars(); - - int remapped = track; - RETURN_ERR( remap_track_( &remapped ) ); - current_track_ = track; - RETURN_ERR( start_track_( remapped ) ); - - emu_track_ended_ = false; - track_ended_ = false; - - if ( !ignore_silence_ ) - { - // play until non-silence or end of track - for ( long end = max_initial_silence * stereo * sample_rate(); emu_time < end; ) - { - fill_buf(); - if ( buf_remain | (int) emu_track_ended_ ) - break; - } - - emu_time = buf_remain; - out_time = 0; - silence_time = 0; - silence_count = 0; - } - return track_ended() ? warning() : 0; -} - -void Music_Emu::end_track_if_error( blargg_err_t err ) -{ - if ( err ) - { - emu_track_ended_ = true; - set_warning( err ); - } -} - -// Tell/Seek - -blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const -{ - blargg_long sec = msec / 1000; - msec -= sec * 1000; - return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo; -} - -long Music_Emu::tell() const -{ - blargg_long rate = sample_rate() * stereo; - blargg_long sec = out_time / rate; - return sec * 1000 + (out_time - sec * rate) * 1000 / rate; -} - -blargg_err_t Music_Emu::seek( long msec ) -{ - blargg_long time = msec_to_samples( msec ); - if ( time < out_time ) - RETURN_ERR( start_track( current_track_ ) ); - return skip( time - out_time ); -} - -blargg_err_t Music_Emu::skip( long count ) -{ - require( current_track() >= 0 ); // start_track() must have been called already - out_time += count; - - // remove from silence and buf first - { - long n = min( count, silence_count ); - silence_count -= n; - count -= n; - - n = min( count, buf_remain ); - buf_remain -= n; - count -= n; - } - - if ( count && !emu_track_ended_ ) - { - emu_time += count; - end_track_if_error( skip_( count ) ); - } - - if ( !(silence_count | buf_remain) ) // caught up to emulator, so update track ended - track_ended_ |= emu_track_ended_; - - return 0; -} - -blargg_err_t Music_Emu::skip_( long count ) -{ - // for long skip, mute sound - const long threshold = 30000; - if ( count > threshold ) - { - int saved_mute = mute_mask_; - mute_voices( ~0 ); - - while ( count > threshold / 2 && !emu_track_ended_ ) - { - RETURN_ERR( play_( buf_size, buf.begin() ) ); - count -= buf_size; - } - - mute_voices( saved_mute ); - } - - while ( count && !emu_track_ended_ ) - { - long n = buf_size; - if ( n > count ) - n = count; - count -= n; - RETURN_ERR( play_( n, buf.begin() ) ); - } - return 0; -} - -// Fading - -void Music_Emu::set_fade( long start_msec, long length_msec ) -{ - fade_step = sample_rate() * length_msec / (fade_block_size * fade_shift * 1000 / stereo); - fade_start = msec_to_samples( start_msec ); -} - -// unit / pow( 2.0, (double) x / step ) -static int int_log( blargg_long x, int step, int unit ) -{ - int shift = x / step; - int fraction = (x - shift * step) * unit / step; - return ((unit - fraction) + (fraction >> 1)) >> shift; -} - -void Music_Emu::handle_fade( long out_count, sample_t* out ) -{ - for ( int i = 0; i < out_count; i += fade_block_size ) - { - int const shift = 14; - int const unit = 1 << shift; - int gain = int_log( (out_time + i - fade_start) / fade_block_size, - fade_step, unit ); - if ( gain < (unit >> fade_shift) ) - track_ended_ = emu_track_ended_ = true; - - sample_t* io = &out [i]; - for ( int count = min( fade_block_size, out_count - i ); count; --count ) - { - *io = sample_t ((*io * gain) >> shift); - ++io; - } - } -} - -// Silence detection - -void Music_Emu::emu_play( long count, sample_t* out ) -{ - check( current_track_ >= 0 ); - emu_time += count; - if ( current_track_ >= 0 && !emu_track_ended_ ) - end_track_if_error( play_( count, out ) ); - else - memset( out, 0, count * sizeof *out ); -} - -// number of consecutive silent samples at end -static long count_silence( Music_Emu::sample_t* begin, long size ) -{ - Music_Emu::sample_t first = *begin; - *begin = silence_threshold; // sentinel - Music_Emu::sample_t* p = begin + size; - while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { } - *begin = first; - return size - (p - begin); -} - -// fill internal buffer and check it for silence -void Music_Emu::fill_buf() -{ - assert( !buf_remain ); - if ( !emu_track_ended_ ) - { - emu_play( buf_size, buf.begin() ); - long silence = count_silence( buf.begin(), buf_size ); - if ( silence < buf_size ) - { - silence_time = emu_time - silence; - buf_remain = buf_size; - return; - } - } - silence_count += buf_size; -} - -blargg_err_t Music_Emu::play( long out_count, sample_t* out ) -{ - if ( track_ended_ ) - { - memset( out, 0, out_count * sizeof *out ); - } - else - { - require( current_track() >= 0 ); - require( out_count % stereo == 0 ); - - assert( emu_time >= out_time ); - - // prints nifty graph of how far ahead we are when searching for silence - //dprintf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" ); - - long pos = 0; - if ( silence_count ) - { - // during a run of silence, run emulator at >=2x speed so it gets ahead - long ahead_time = silence_lookahead * (out_time + out_count - silence_time) + silence_time; - while ( emu_time < ahead_time && !(buf_remain | emu_track_ended_) ) - fill_buf(); - - // fill with silence - pos = min( silence_count, out_count ); - memset( out, 0, pos * sizeof *out ); - silence_count -= pos; - - if ( emu_time - silence_time > silence_max * stereo * sample_rate() ) - { - track_ended_ = emu_track_ended_ = true; - silence_count = 0; - buf_remain = 0; - } - } - - if ( buf_remain ) - { - // empty silence buf - long n = min( buf_remain, out_count - pos ); - memcpy( &out [pos], buf.begin() + (buf_size - buf_remain), n * sizeof *out ); - buf_remain -= n; - pos += n; - } - - // generate remaining samples normally - long remain = out_count - pos; - if ( remain ) - { - emu_play( remain, out + pos ); - track_ended_ |= emu_track_ended_; - - if ( !ignore_silence_ || out_time > fade_start ) - { - // check end for a new run of silence - long silence = count_silence( out + pos, remain ); - if ( silence < remain ) - silence_time = emu_time - silence; - - if ( emu_time - silence_time >= buf_size ) - fill_buf(); // cause silence detection on next play() - } - } - - if ( out_time > fade_start ) - handle_fade( out_count, out ); - } - out_time += out_count; - return 0; -} - -// Gme_Info_ - -blargg_err_t Gme_Info_::set_sample_rate_( long ) { return 0; } -void Gme_Info_::pre_load() { Gme_File::pre_load(); } // skip Music_Emu -void Gme_Info_::post_load_() { Gme_File::post_load_(); } // skip Music_Emu -void Gme_Info_::set_equalizer_( equalizer_t const& ){ check( false ); } -void Gme_Info_::mute_voices_( int ) { check( false ); } -void Gme_Info_::set_tempo_( double ) { } -blargg_err_t Gme_Info_::start_track_( int ) { return "Use full emulator for playback"; } -blargg_err_t Gme_Info_::play_( long, sample_t* ) { return "Use full emulator for playback"; } |