Exemplo n.º 1
0
blargg_err_t Vgm_Emu::setup_fm()
{
	long ym2612_rate = get_le32( header().ym2612_rate );
	long ym2413_rate = get_le32( header().ym2413_rate );
	if ( ym2413_rate && get_le32( header().version ) < 0x110 )
		update_fm_rates( &ym2413_rate, &ym2612_rate );
	
	uses_fm = false;
	
	fm_rate = blip_buf.sample_rate() * oversample_factor;
	
	if ( ym2612_rate )
	{
		uses_fm = true;
		if ( disable_oversampling_ )
			fm_rate = ym2612_rate / 144.0;
		Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, fm_gain * gain() );
		RETURN_ERR( ym2612.set_rate( fm_rate, ym2612_rate ) );
		ym2612.enable( true );
		set_voice_count( 8 );
	}
	
	if ( !uses_fm && ym2413_rate )
	{
		uses_fm = true;
		if ( disable_oversampling_ )
			fm_rate = ym2413_rate / 72.0;
		Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, fm_gain * gain() );
		int result = ym2413.set_rate( fm_rate, ym2413_rate );
		if ( result == 2 )
			return "YM2413 FM sound isn't supported";
		CHECK_ALLOC( !result );
		ym2413.enable( true );
		set_voice_count( 8 );
	}
	
	if ( uses_fm )
	{
		RETURN_ERR( Dual_Resampler::reset( blip_buf.length() * blip_buf.sample_rate() / 1000 ) );
		psg.volume( 0.135 * fm_gain * gain() );
	}
	else
	{
		ym2612.enable( false );
		ym2413.enable( false );
		psg.volume( gain() );
	}
	
	return 0;
}
Exemplo n.º 2
0
blargg_err_t Sap_Emu::load_mem_( byte const in [], int size )
{
	file_end = in + size;
	
	info_.warning    = NULL;
	info_.type       = 'B';
	info_.stereo     = false;
	info_.init_addr  = -1;
	info_.play_addr  = -1;
	info_.music_addr = -1;
	info_.fastplay   = 312;
	RETURN_ERR( parse_info( in, size, &info_ ) );
	
	set_warning( info_.warning );
	set_track_count( info_.track_count );
	set_voice_count( Sap_Apu::osc_count << info_.stereo );
	core.apu_impl().volume( gain() );
	
	static const char* const names [Sap_Apu::osc_count * 2] = {
		"Wave 1", "Wave 2", "Wave 3", "Wave 4",
		"Wave 5", "Wave 6", "Wave 7", "Wave 8",
	};
	set_voice_names( names );
	
	static int const types [Sap_Apu::osc_count * 2] = {
		wave_type+1, wave_type+2, wave_type+3, wave_type+0,
		wave_type+5, wave_type+6, wave_type+7, wave_type+4,
	};
	set_voice_types( types );
	
	return setup_buffer( 1773447 );
}
Exemplo n.º 3
0
blargg_err_t Ay_Emu::load_mem_( byte const in [], int size )
{
    assert( offsetof (header_t,track_info [2]) == header_t::size );

    RETURN_ERR( parse_header( in, size, &file ) );
    set_track_count( file.header->max_track + 1 );

    if ( file.header->vers > 2 )
        set_warning( "Unknown file version" );

    int const osc_count = Ay_Apu::osc_count + 1; // +1 for beeper

    set_voice_count( osc_count );
    core.apu().volume( gain() );

    static const char* const names [osc_count] = {
        "Wave 1", "Wave 2", "Wave 3", "Beeper"
    };
    set_voice_names( names );

    static int const types [osc_count] = {
        wave_type+0, wave_type+1, wave_type+2, mixed_type+1
    };
    set_voice_types( types );

    return setup_buffer( spectrum_clock );
}
Exemplo n.º 4
0
blargg_err_t Vgm_Emu::load_mem_( byte const data [], int size )
{
	RETURN_ERR( core.load_mem( data, size ) );

	set_voice_count( core.psg[0].osc_count );
	
	double fm_rate = 0.0;
	if ( !disable_oversampling_ )
		fm_rate = sample_rate() * oversample_factor;
	RETURN_ERR( core.init_chips( &fm_rate ) );

	double psg_gain = ( ( core.header().psg_rate[3] & 0xC0 ) == 0x40 ) ? 0.5 : 1.0;
	
	if ( core.uses_fm() )
	{
		set_voice_count( 8 );
		RETURN_ERR( resampler.setup( fm_rate / sample_rate(), rolloff, gain() ) );
		RETURN_ERR( resampler.reset( core.stereo_buf[0].length() * sample_rate() / 1000 ) );
		core.psg[0].volume( 0.135 * fm_gain * psg_gain * gain() );
		core.psg[1].volume( 0.135 * fm_gain * psg_gain * gain() );
		core.ay[0].volume( 0.135 * fm_gain * gain() );
		core.ay[1].volume( 0.135 * fm_gain * gain() );
        core.huc6280[0].volume( 0.135 * fm_gain * gain() );
        core.huc6280[1].volume( 0.135 * fm_gain * gain() );
	}
	else
	{
		core.psg[0].volume( psg_gain * gain() );
		core.psg[1].volume( psg_gain * gain() );
	}
	
	static const char* const fm_names [] = {
		"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
	};
	static const char* const psg_names [] = { "Square 1", "Square 2", "Square 3", "Noise" };
	set_voice_names( core.uses_fm() ? fm_names : psg_names );
	
	static int const types [8] = {
		wave_type+1, wave_type+2, wave_type+3, noise_type+1,
		0, 0, 0, 0
	};
	set_voice_types( types );
	
	return Classic_Emu::setup_buffer( core.stereo_buf[0].center()->clock_rate() );
}
Exemplo n.º 5
0
bool SamplePlayer::_set(const StringName& p_name, const Variant& p_value) {

	String name=p_name;

	if (name=="play/play") {
		if (library.is_valid()) {

			String what=p_value;
			if (what=="")
				stop_all();
			else
				play(what);

			played_back=what;
		}
	} else if (name=="config/samples")
		set_sample_library(p_value);
	else if (name=="config/voices")
		set_voice_count(p_value);
	else if (name.begins_with("default/")) {

		String what=name.right(8);

		if (what=="volume_db")
			set_default_volume_db(p_value);
		else if (what=="pitch_scale")
			set_default_pitch_scale(p_value);
		else if (what=="pan")
			_default.pan=p_value;
		else if (what=="depth")
			_default.depth=p_value;
		else if (what=="height")
			_default.height=p_value;
		else if (what=="filter/type")
			_default.filter_type=FilterType(p_value.operator int());
		else if (what=="filter/cutoff")
			_default.filter_cutoff=p_value;
		else if (what=="filter/resonance")
			_default.filter_resonance=p_value;
		else if (what=="filter/gain")
			_default.filter_gain=p_value;
		else if (what=="reverb_room")
			_default.reverb_room=ReverbRoomType(p_value.operator int());
		else if (what=="reverb_send")
			_default.reverb_send=p_value;
		else if (what=="chorus_send")
			_default.chorus_send=p_value;
		else
			return false;


	} else
		return false;

	return true;
}
Exemplo n.º 6
0
blargg_err_t Spc_Emu::load_mem_( byte const* in, long size )
{
	assert( offsetof (header_t,unused2 [46]) == header_size );
	file_data = in;
	file_size = size;
	set_voice_count( Snes_Spc::voice_count );
	if ( size < Snes_Spc::spc_min_file_size )
		return gme_wrong_file_type;
	return check_spc_header( in );
}
Exemplo n.º 7
0
blargg_err_t Sfm_Emu::load_mem_( byte const in [], int size )
{
    set_voice_count( Spc_Dsp::voice_count );
    if ( size < Sfm_Emu::sfm_min_file_size )
        return blargg_err_file_type;
    
    static const char* const names [Spc_Dsp::voice_count] = {
        "DSP 1", "DSP 2", "DSP 3", "DSP 4", "DSP 5", "DSP 6", "DSP 7", "DSP 8"
    };
    set_voice_names( names );
    
    return check_sfm_header( in );
}
Exemplo n.º 8
0
blargg_err_t Hes_Emu::load_( Data_Reader& in )
{
	assert( offsetof (header_t,unused [4]) == header_size );
	RETURN_ERR( rom.load( in, header_size, &header_, unmapped ) );
	
	RETURN_ERR( check_hes_header( header_.tag ) );
	
	if ( header_.vers != 0 )
		set_warning( "Unknown file version" );
	
	if ( memcmp( header_.data_tag, "DATA", 4 ) )
		set_warning( "Data header missing" );
	
	if ( memcmp( header_.unused, "\0\0\0\0", 4 ) )
		set_warning( "Unknown header data" );
	
	// File spec supports multiple blocks, but I haven't found any, and
	// many files have bad sizes in the only block, so it's simpler to
	// just try to load the damn data as best as possible.
	
	long addr = get_le32( header_.addr );
	long size = get_le32( header_.size );
	long const rom_max = 0x100000;
	if ( addr & ~(rom_max - 1) )
	{
		set_warning( "Invalid address" );
		addr &= rom_max - 1;
	}
	if ( (unsigned long) (addr + size) > (unsigned long) rom_max )
		set_warning( "Invalid size" );
	
	if ( size != rom.file_size() )
	{
		if ( size <= rom.file_size() - 4 && !memcmp( rom.begin() + size, "DATA", 4 ) )
			set_warning( "Multiple DATA not supported" );
		else if ( size < rom.file_size() )
			set_warning( "Extra file data" );
		else
			set_warning( "Missing file data" );
	}
	
	rom.set_addr( addr );
	
	set_voice_count( apu.osc_count );
	
	apu.volume( gain() );
	
	return setup_buffer( 7159091 );
}
Exemplo n.º 9
0
blargg_err_t Ay_Emu::load_mem_( byte const* in, long size )
{
	assert( offsetof (header_t,track_info [2]) == header_size );
	
	RETURN_ERR( parse_header( in, size, &file ) );
	set_track_count( file.header->max_track + 1 );
	
	if ( file.header->vers > 2 )
		set_warning( "Unknown file version" );
	
	set_voice_count( osc_count );
	apu.volume( gain() );
	
	return setup_buffer( spectrum_clock );
}
Exemplo n.º 10
0
blargg_err_t Gbs_Emu::load_( Data_Reader& in )
{
	RETURN_ERR( core_.load( in ) );
	set_warning( core_.warning() );
	set_track_count( header().track_count );
	set_voice_count( Gb_Apu::osc_count );
	core_.apu().volume( gain() );
	
	static const char* const names [Gb_Apu::osc_count] = {
		"Square 1", "Square 2", "Wave", "Noise"
	};
	set_voice_names( names );
	
	static int const types [Gb_Apu::osc_count] = {
		wave_type+1, wave_type+2, wave_type+3, mixed_type+1
	};
	set_voice_types( types );
	
	return setup_buffer( 4194304 );
}
Exemplo n.º 11
0
blargg_err_t Sap_Emu::load_mem_( byte const* in, long size )
{
	file_end = in + size;
	
	info.warning    = 0;
	info.type       = 'B';
	info.stereo     = false;
	info.init_addr  = -1;
	info.play_addr  = -1;
	info.music_addr = -1;
	info.fastplay   = 312;
	RETURN_ERR( parse_info( in, size, &info ) );
	
	set_warning( info.warning );
	set_track_count( info.track_count );
	set_voice_count( Sap_Apu::osc_count << info.stereo );
	apu_impl.volume( gain() );
	
	return setup_buffer( 1773447 );
}
Exemplo n.º 12
0
blargg_err_t Hes_Emu::load_( Data_Reader& in )
{
	RETURN_ERR( core.load( in ) );
	
	static const char* const names [Hes_Apu::osc_count + Hes_Apu_Adpcm::osc_count] = {
		"Wave 1", "Wave 2", "Wave 3", "Wave 4", "Multi 1", "Multi 2", "ADPCM"
	};
	set_voice_names( names );
	
	static int const types [Hes_Apu::osc_count + Hes_Apu_Adpcm::osc_count] = {
		wave_type+0, wave_type+1, wave_type+2, wave_type+3, mixed_type+0, mixed_type+1, mixed_type+2
	};
	set_voice_types( types );
	
	set_voice_count( core.apu().osc_count + core.adpcm().osc_count );
	core.apu().volume( gain() );
	core.adpcm().volume( gain() );
	
    return setup_buffer( 7159091 );
}
Exemplo n.º 13
0
blargg_err_t Vgm_Emu::load_mem_( byte const* new_data, long new_size )
{
	assert( offsetof (header_t,unused2 [8]) == header_size );
	
	if ( new_size <= header_size )
		return gme_wrong_file_type;
	
	header_t const& h = *(header_t const*) new_data;
	
	RETURN_ERR( check_vgm_header( h ) );
	
	check( get_le32( h.version ) <= 0x150 );
	
	// psg rate
	psg_rate = get_le32( h.psg_rate );
	if ( !psg_rate )
		psg_rate = 3579545;
	blip_buf.clock_rate( psg_rate );
	
	data     = new_data;
	data_end = new_data + new_size;
	
	// get loop
	loop_begin = data_end;
	if ( get_le32( h.loop_offset ) )
		loop_begin = &data [get_le32( h.loop_offset ) + offsetof (header_t,loop_offset)];
	
	set_voice_count( psg.osc_count );
	
	RETURN_ERR( setup_fm() );
	
	static const char* const fm_names [] = {
		"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
	};
	static const char* const psg_names [] = { "Square 1", "Square 2", "Square 3", "Noise" };
	set_voice_names( uses_fm ? fm_names : psg_names );
	
	// do after FM in case output buffer is changed
	return Classic_Emu::setup_buffer( psg_rate );
}
Exemplo n.º 14
0
blargg_err_t Gym_Emu::load_mem_( byte const in [], int size )
{
	assert( offsetof (header_t,packed [4]) == header_t::size );
	log_offset = 0;
	RETURN_ERR( check_header( in, size, &log_offset ) );
	
	loop_begin = NULL;
	
	static const char* const names [] = {
		"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
	};
	set_voice_names( names );
	
	set_voice_count( 8 );
	
	if ( log_offset )
		header_ = *(header_t const*) in;
	else
		memset( &header_, 0, sizeof header_ );
	
	return blargg_ok;
}
Exemplo n.º 15
0
blargg_err_t Nsf_Emu::init_sound()
{
	if ( header_.chip_flags & ~(namco_flag | vrc6_flag | fme7_flag) )
		set_warning( "Uses unsupported audio expansion hardware" );
	
	{
		#define APU_NAMES "Square 1", "Square 2", "Triangle", "Noise", "DMC"
		
		int const count = Nes_Apu::osc_count;
		static const char* const apu_names [count] = { APU_NAMES };
		set_voice_count( count );
		set_voice_names( apu_names );
		
	}
	
	static int const types [] = {
		wave_type  | 1, wave_type  | 2, wave_type | 0,
		noise_type | 0, mixed_type | 1,
		wave_type  | 3, wave_type  | 4, wave_type | 5,
		wave_type  | 6, wave_type  | 7, wave_type | 8, wave_type | 9,
		wave_type  |10, wave_type  |11, wave_type |12, wave_type |13
	};
	set_voice_types( types ); // common to all sound chip configurations
	
	double adjusted_gain = gain();
	
	#if NSF_EMU_APU_ONLY
	{
		if ( header_.chip_flags )
			set_warning( "Uses unsupported audio expansion hardware" );
	}
	#else
	{
		if ( header_.chip_flags & (namco_flag | vrc6_flag | fme7_flag) )
			set_voice_count( Nes_Apu::osc_count + 3 );
		
		if ( header_.chip_flags & namco_flag )
		{
			namco = BLARGG_NEW Nes_Namco_Apu;
			CHECK_ALLOC( namco );
			adjusted_gain *= 0.75;
			
			int const count = Nes_Apu::osc_count + Nes_Namco_Apu::osc_count;
			static const char* const names [count] = {
				APU_NAMES,
				"Wave 1", "Wave 2", "Wave 3", "Wave 4",
				"Wave 5", "Wave 6", "Wave 7", "Wave 8"
			};
			set_voice_count( count );
			set_voice_names( names );
		}
		
		if ( header_.chip_flags & vrc6_flag )
		{
			vrc6 = BLARGG_NEW Nes_Vrc6_Apu;
			CHECK_ALLOC( vrc6 );
			adjusted_gain *= 0.75;
			
			{
				int const count = Nes_Apu::osc_count + Nes_Vrc6_Apu::osc_count;
				static const char* const names [count] = {
					APU_NAMES,
					"Saw Wave", "Square 3", "Square 4"
				};
				set_voice_count( count );
				set_voice_names( names );
			}
			
			if ( header_.chip_flags & namco_flag )
			{
				int const count = Nes_Apu::osc_count + Nes_Vrc6_Apu::osc_count +
						Nes_Namco_Apu::osc_count;
				static const char* const names [count] = {
					APU_NAMES,
					"Saw Wave", "Square 3", "Square 4",
					"Wave 1", "Wave 2", "Wave 3", "Wave 4",
					"Wave 5", "Wave 6", "Wave 7", "Wave 8"
				};
				set_voice_count( count );
				set_voice_names( names );
			}
		}
		
		if ( header_.chip_flags & fme7_flag )
		{
			fme7 = BLARGG_NEW Nes_Fme7_Apu;
			CHECK_ALLOC( fme7 );
			adjusted_gain *= 0.75;
			
			int const count = Nes_Apu::osc_count + Nes_Fme7_Apu::osc_count;
			static const char* const names [count] = {
				APU_NAMES,
				"Square 3", "Square 4", "Square 5"
			};
			set_voice_count( count );
			set_voice_names( names );
		}
		
		if ( namco ) namco->volume( adjusted_gain );
		if ( vrc6  ) vrc6 ->volume( adjusted_gain );
		if ( fme7  ) fme7 ->volume( adjusted_gain );
	}
	#endif
	
	apu.volume( adjusted_gain );
	
	return 0;
}
Exemplo n.º 16
0
blargg_err_t Kss_Emu::load_( Data_Reader& in )
{
	RETURN_ERR( core.load( in ) );
	set_warning( core.warning() );

	set_track_count( get_le16( header().last_track ) + 1 );

	core.scc_enabled = false;
	if ( header().device_flags & 0x02 ) // Sega Master System
	{
		int const osc_count = Sms_Apu::osc_count + Opl_Apu::osc_count;
		static const char* const names [osc_count] = {
			"Square 1", "Square 2", "Square 3", "Noise", "FM"
		};
		set_voice_names( names );

		static int const types [osc_count] = {
			wave_type+1, wave_type+3, wave_type+2, mixed_type+1, wave_type+0
		};
		set_voice_types( types );

		// sms.psg
		set_voice_count( Sms_Apu::osc_count );
		check( !core.sms.psg );
		CHECK_ALLOC( core.sms.psg = BLARGG_NEW Sms_Apu );

		// sms.fm
		if ( header().device_flags & 0x01 )
		{
			set_voice_count( osc_count );
			RETURN_ERR( new_opl_apu( Opl_Apu::type_smsfmunit, &core.sms.fm ) );
		}

	}
	else // MSX
	{
		int const osc_count = Ay_Apu::osc_count + Opl_Apu::osc_count;
		static const char* const names [osc_count] = {
			"Square 1", "Square 2", "Square 3", "FM"
		};
		set_voice_names( names );

		static int const types [osc_count] = {
			wave_type+1, wave_type+3, wave_type+2, wave_type+0
		};
		set_voice_types( types );

		// msx.psg
		set_voice_count( Ay_Apu::osc_count );
		check( !core.msx.psg );
		CHECK_ALLOC( core.msx.psg = BLARGG_NEW Ay_Apu );

		if ( header().device_flags & 0x10 )
			set_warning( "MSX stereo not supported" );

		// msx.music
		if ( header().device_flags & 0x01 )
		{
			set_voice_count( osc_count );
			RETURN_ERR( new_opl_apu( Opl_Apu::type_msxmusic, &core.msx.music ) );
		}

		// msx.audio
		if ( header().device_flags & 0x08 )
		{
			set_voice_count( osc_count );
			RETURN_ERR( new_opl_apu( Opl_Apu::type_msxaudio, &core.msx.audio ) );
		}

		if ( !(header().device_flags & 0x80) )
		{
			if ( !(header().device_flags & 0x84) )
				core.scc_enabled = core.scc_enabled_true;

			// msx.scc
			check( !core.msx.scc );
			CHECK_ALLOC( core.msx.scc = BLARGG_NEW Scc_Apu );

			int const osc_count = Ay_Apu::osc_count + Scc_Apu::osc_count;
			static const char* const names [osc_count] = {
				"Square 1", "Square 2", "Square 3",
				"Wave 1", "Wave 2", "Wave 3", "Wave 4", "Wave 5"
			};
			set_voice_names( names );

			static int const types [osc_count] = {
				wave_type+1, wave_type+3, wave_type+2,
				wave_type+0, wave_type+4, wave_type+5, wave_type+6, wave_type+7,
			};
			set_voice_types( types );

			set_voice_count( osc_count );
		}
	}

	set_silence_lookahead( 6 );
	if ( core.sms.fm || core.msx.music || core.msx.audio )
	{
		if ( !Opl_Apu::supported() )
			set_warning( "FM sound not supported" );
		else
			set_silence_lookahead( 3 ); // Opl_Apu is really slow
	}

	return setup_buffer( ::clock_rate );
}