summaryrefslogtreecommitdiff
path: root/plugins/gme/game-music-emu-0.6.0/gme/Gym_Emu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gme/game-music-emu-0.6.0/gme/Gym_Emu.cpp')
-rw-r--r--plugins/gme/game-music-emu-0.6.0/gme/Gym_Emu.cpp380
1 files changed, 0 insertions, 380 deletions
diff --git a/plugins/gme/game-music-emu-0.6.0/gme/Gym_Emu.cpp b/plugins/gme/game-music-emu-0.6.0/gme/Gym_Emu.cpp
deleted file mode 100644
index c286dea9..00000000
--- a/plugins/gme/game-music-emu-0.6.0/gme/Gym_Emu.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Gym_Emu.h"
-
-#include "blargg_endian.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"
-
-double const min_tempo = 0.25;
-double const oversample_factor = 5 / 3.0;
-double const fm_gain = 3.0;
-
-const long base_clock = 53700300;
-const long clock_rate = base_clock / 15;
-
-Gym_Emu::Gym_Emu()
-{
- data = 0;
- pos = 0;
- set_type( gme_gym_type );
-
- static const char* const names [] = {
- "FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
- };
- set_voice_names( names );
- set_silence_lookahead( 1 ); // tracks should already be trimmed
-}
-
-Gym_Emu::~Gym_Emu() { }
-
-// Track info
-
-static void get_gym_info( Gym_Emu::header_t const& h, long length, track_info_t* out )
-{
- if ( !memcmp( h.tag, "GYMX", 4 ) )
- {
- length = length * 50 / 3; // 1000 / 60
- long loop = get_le32( h.loop_start );
- if ( loop )
- {
- out->intro_length = loop * 50 / 3;
- out->loop_length = length - out->intro_length;
- }
- else
- {
- out->length = length;
- out->intro_length = length; // make it clear that track is no longer than length
- out->loop_length = 0;
- }
-
- // more stupidity where the field should have been left
- if ( strcmp( h.song, "Unknown Song" ) )
- GME_COPY_FIELD( h, out, song );
-
- if ( strcmp( h.game, "Unknown Game" ) )
- GME_COPY_FIELD( h, out, game );
-
- if ( strcmp( h.copyright, "Unknown Publisher" ) )
- GME_COPY_FIELD( h, out, copyright );
-
- if ( strcmp( h.dumper, "Unknown Person" ) )
- GME_COPY_FIELD( h, out, dumper );
-
- if ( strcmp( h.comment, "Header added by YMAMP" ) )
- GME_COPY_FIELD( h, out, comment );
- }
-}
-
-blargg_err_t Gym_Emu::track_info_( track_info_t* out, int ) const
-{
- get_gym_info( header_, track_length(), out );
- return 0;
-}
-
-static long gym_track_length( byte const* p, byte const* end )
-{
- long time = 0;
- while ( p < end )
- {
- switch ( *p++ )
- {
- case 0:
- time++;
- break;
-
- case 1:
- case 2:
- p += 2;
- break;
-
- case 3:
- p += 1;
- break;
- }
- }
- return time;
-}
-
-long Gym_Emu::track_length() const { return gym_track_length( data, data_end ); }
-
-static blargg_err_t check_header( byte const* in, long size, int* data_offset = 0 )
-{
- if ( size < 4 )
- return gme_wrong_file_type;
-
- if ( memcmp( in, "GYMX", 4 ) == 0 )
- {
- if ( size < Gym_Emu::header_size + 1 )
- return gme_wrong_file_type;
-
- if ( memcmp( ((Gym_Emu::header_t const*) in)->packed, "\0\0\0\0", 4 ) != 0 )
- return "Packed GYM file not supported";
-
- if ( data_offset )
- *data_offset = Gym_Emu::header_size;
- }
- else if ( *in > 3 )
- {
- return gme_wrong_file_type;
- }
-
- return 0;
-}
-
-struct Gym_File : Gme_Info_
-{
- byte const* file_begin;
- byte const* file_end;
- int data_offset;
-
- Gym_File() { set_type( gme_gym_type ); }
-
- blargg_err_t load_mem_( byte const* in, long size )
- {
- file_begin = in;
- file_end = in + size;
- data_offset = 0;
- return check_header( in, size, &data_offset );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- long length = gym_track_length( &file_begin [data_offset], file_end );
- get_gym_info( *(Gym_Emu::header_t const*) file_begin, length, out );
- return 0;
- }
-};
-
-static Music_Emu* new_gym_emu () { return BLARGG_NEW Gym_Emu ; }
-static Music_Emu* new_gym_file() { return BLARGG_NEW Gym_File; }
-
-static gme_type_t_ const gme_gym_type_ = { "Sega Genesis", 1, &new_gym_emu, &new_gym_file, "GYM", 0 };
-gme_type_t const gme_gym_type = &gme_gym_type_;
-
-// Setup
-
-blargg_err_t Gym_Emu::set_sample_rate_( long sample_rate )
-{
- blip_eq_t eq( -32, 8000, sample_rate );
- apu.treble_eq( eq );
- dac_synth.treble_eq( eq );
- apu.volume( 0.135 * fm_gain * gain() );
- dac_synth.volume( 0.125 / 256 * fm_gain * gain() );
- double factor = Dual_Resampler::setup( oversample_factor, 0.990, fm_gain * gain() );
- fm_sample_rate = sample_rate * factor;
-
- RETURN_ERR( blip_buf.set_sample_rate( sample_rate, int (1000 / 60.0 / min_tempo) ) );
- blip_buf.clock_rate( clock_rate );
-
- RETURN_ERR( fm.set_rate( fm_sample_rate, base_clock / 7.0 ) );
- RETURN_ERR( Dual_Resampler::reset( long (1.0 / 60 / min_tempo * sample_rate) ) );
-
- return 0;
-}
-
-void Gym_Emu::set_tempo_( double t )
-{
- if ( t < min_tempo )
- {
- set_tempo( min_tempo );
- return;
- }
-
- if ( blip_buf.sample_rate() )
- {
- clocks_per_frame = long (clock_rate / 60 / tempo());
- Dual_Resampler::resize( long (sample_rate() / (60.0 * tempo())) );
- }
-}
-
-void Gym_Emu::mute_voices_( int mask )
-{
- Music_Emu::mute_voices_( mask );
- fm.mute_voices( mask );
- dac_muted = (mask & 0x40) != 0;
- apu.output( (mask & 0x80) ? 0 : &blip_buf );
-}
-
-blargg_err_t Gym_Emu::load_mem_( byte const* in, long size )
-{
- assert( offsetof (header_t,packed [4]) == header_size );
- int offset = 0;
- RETURN_ERR( check_header( in, size, &offset ) );
- set_voice_count( 8 );
-
- data = in + offset;
- data_end = in + size;
- loop_begin = 0;
-
- if ( offset )
- header_ = *(header_t const*) in;
- else
- memset( &header_, 0, sizeof header_ );
-
- return 0;
-}
-
-// Emulation
-
-blargg_err_t Gym_Emu::start_track_( int track )
-{
- RETURN_ERR( Music_Emu::start_track_( track ) );
-
- pos = data;
- loop_remain = get_le32( header_.loop_start );
-
- prev_dac_count = 0;
- dac_enabled = false;
- dac_amp = -1;
-
- fm.reset();
- apu.reset();
- blip_buf.clear();
- Dual_Resampler::clear();
- return 0;
-}
-
-void Gym_Emu::run_dac( int dac_count )
-{
- // Guess beginning and end of sample and adjust rate and buffer position accordingly.
-
- // count dac samples in next frame
- int next_dac_count = 0;
- const byte* p = this->pos;
- int cmd;
- while ( (cmd = *p++) != 0 )
- {
- int data = *p++;
- if ( cmd <= 2 )
- ++p;
- if ( cmd == 1 && data == 0x2A )
- next_dac_count++;
- }
-
- // detect beginning and end of sample
- int rate_count = dac_count;
- int start = 0;
- if ( !prev_dac_count && next_dac_count && dac_count < next_dac_count )
- {
- rate_count = next_dac_count;
- start = next_dac_count - dac_count;
- }
- else if ( prev_dac_count && !next_dac_count && dac_count < prev_dac_count )
- {
- rate_count = prev_dac_count;
- }
-
- // Evenly space samples within buffer section being used
- blip_resampled_time_t period = blip_buf.resampled_duration( clocks_per_frame ) / rate_count;
-
- blip_resampled_time_t time = blip_buf.resampled_time( 0 ) +
- period * start + (period >> 1);
-
- int dac_amp = this->dac_amp;
- if ( dac_amp < 0 )
- dac_amp = dac_buf [0];
-
- for ( int i = 0; i < dac_count; i++ )
- {
- int delta = dac_buf [i] - dac_amp;
- dac_amp += delta;
- dac_synth.offset_resampled( time, delta, &blip_buf );
- time += period;
- }
- this->dac_amp = dac_amp;
-}
-
-void Gym_Emu::parse_frame()
-{
- int dac_count = 0;
- const byte* pos = this->pos;
-
- if ( loop_remain && !--loop_remain )
- loop_begin = pos; // find loop on first time through sequence
-
- int cmd;
- while ( (cmd = *pos++) != 0 )
- {
- int data = *pos++;
- if ( cmd == 1 )
- {
- int data2 = *pos++;
- if ( data != 0x2A )
- {
- if ( data == 0x2B )
- dac_enabled = (data2 & 0x80) != 0;
-
- fm.write0( data, data2 );
- }
- else if ( dac_count < (int) sizeof dac_buf )
- {
- dac_buf [dac_count] = data2;
- dac_count += dac_enabled;
- }
- }
- else if ( cmd == 2 )
- {
- fm.write1( data, *pos++ );
- }
- else if ( cmd == 3 )
- {
- apu.write_data( 0, data );
- }
- else
- {
- // to do: many GYM streams are full of errors, and error count should
- // reflect cases where music is really having problems
- //log_error();
- --pos; // put data back
- }
- }
-
- // loop
- if ( pos >= data_end )
- {
- check( pos == data_end );
-
- if ( loop_begin )
- pos = loop_begin;
- else
- set_track_ended();
- }
- this->pos = pos;
-
- // dac
- if ( dac_count && !dac_muted )
- run_dac( dac_count );
- prev_dac_count = dac_count;
-}
-
-int Gym_Emu::play_frame( blip_time_t blip_time, int sample_count, sample_t* buf )
-{
- if ( !track_ended() )
- parse_frame();
-
- apu.end_frame( blip_time );
-
- memset( buf, 0, sample_count * sizeof *buf );
- fm.run( sample_count >> 1, buf );
-
- return sample_count;
-}
-
-blargg_err_t Gym_Emu::play_( long count, sample_t* out )
-{
- Dual_Resampler::dual_play( count, out, blip_buf );
- return 0;
-}