Example #1
0
blargg_err_t SNES_SPC::skip( int count )
{
	#if SPC_LESS_ACCURATE
	if ( count > 2 * sample_rate * 2 )
	{
		set_output( 0, 0 );
		
		// Skip a multiple of 4 samples
		time_t end = count;
		count = (count & 3) + 1 * sample_rate * 2;
		end = (end - count) * (clocks_per_sample / 2);
		
		m.skipped_kon  = 0;
		m.skipped_koff = 0;
		
		// Preserve DSP and timer synchronization
		// TODO: verify that this really preserves it
		int old_dsp_time = m.dsp_time + m.spc_time;
		m.dsp_time = end - m.spc_time + skipping_time;
		end_frame( end );
		m.dsp_time = m.dsp_time - skipping_time + old_dsp_time;
		
		dsp.write( SPC_DSP::r_koff, m.skipped_koff & ~m.skipped_kon );
		dsp.write( SPC_DSP::r_kon , m.skipped_kon );
		clear_echo();
	}
	#endif
	
	return play( count, 0 );
}
Example #2
0
int SPC_load_spc( THIS, const void* data, long size )
{
    struct spc_file_t const* spc = (struct spc_file_t const*) data;
    struct cpu_regs_t regs;
    
    if ( size < SPC_FILE_SIZE )
        return -1;
    
    if ( ci->memcmp( spc->signature, "SNES-SPC700 Sound File Data", 27 ) != 0 )
        return -1;
    
    regs.pc     = spc->pc [1] * 0x100 + spc->pc [0];
    regs.a      = spc->a;
    regs.x      = spc->x;
    regs.y      = spc->y;
    regs.status = spc->status;
    regs.sp     = spc->sp;
    
    if ( (unsigned long) size >= sizeof *spc )
        ci->memcpy( this->boot_rom, spc->ipl_rom, sizeof this->boot_rom );
    
    SPC_load_state( this, &regs, spc->ram, spc->dsp );
    
    clear_echo(this);
    
    return 0;
}
void Effects_Buffer::clear()
{
    echo_pos       = 0;
    s.low_pass [0] = 0;
    s.low_pass [1] = 0;
    mixer.samples_read = 0;

    for ( int i = bufs_size; --i >= 0; )
        bufs [i].clear();
    clear_echo();
}
void Effects_Buffer::apply_config()
{
    int i;

    if ( !bufs_size )
        return;

    s.treble = TO_FIXED( config_.treble );

    bool echo_dirty = false;

    fixed_t old_feedback = s.feedback;
    s.feedback = TO_FIXED( config_.feedback );
    if ( !old_feedback && s.feedback )
        echo_dirty = true;

    // delays
    for ( i = stereo; --i >= 0; )
    {
        long delay = config_.delay [i] * sample_rate() / 1000 * stereo;
        delay = max( delay, long (max_read * stereo) );
        delay = min( delay, long (echo_size - max_read * stereo) );
        if ( s.delay [i] != delay )
        {
            s.delay [i] = delay;
            echo_dirty = true;
        }
    }

    // side channels
    for ( i = 2; --i >= 0; )
    {
        chans [i+2].cfg.vol = chans [i].cfg.vol = config_.side_chans [i].vol * 0.5f;
        chans [i+2].cfg.pan = chans [i].cfg.pan = config_.side_chans [i].pan;
    }

    // convert volumes
    for ( i = chans.size(); --i >= 0; )
    {
        chan_t& ch = chans [i];
        ch.vol [0] = TO_FIXED( ch.cfg.vol - ch.cfg.vol * ch.cfg.pan );
        ch.vol [1] = TO_FIXED( ch.cfg.vol + ch.cfg.vol * ch.cfg.pan );
        if ( ch.cfg.surround )
            ch.vol [0] = -ch.vol [0];
    }

    assign_buffers();

    // set side channels
    for ( i = chans.size(); --i >= 0; )
    {
        chan_t& ch = chans [i];
        ch.channel.left  = chans [ch.cfg.echo*2  ].channel.center;
        ch.channel.right = chans [ch.cfg.echo*2+1].channel.center;
    }

    bool old_echo = !no_echo && !no_effects;

    // determine whether effects and echo are needed at all
    no_effects = true;
    no_echo    = true;
    for ( i = chans.size(); --i >= extra_chans; )
    {
        chan_t& ch = chans [i];
        if ( ch.cfg.echo && s.feedback )
            no_echo = false;

        if ( ch.vol [0] != TO_FIXED( 1 ) || ch.vol [1] != TO_FIXED( 1 ) )
            no_effects = false;
    }
    if ( !no_echo )
        no_effects = false;

    if (    chans [0].vol [0] != TO_FIXED( 1 ) ||
            chans [0].vol [1] != TO_FIXED( 0 ) ||
            chans [1].vol [0] != TO_FIXED( 0 ) ||
            chans [1].vol [1] != TO_FIXED( 1 ) )
        no_effects = false;

    if ( !config_.enabled )
        no_effects = true;

    if ( no_effects )
    {
        for ( i = chans.size(); --i >= 0; )
        {
            chan_t& ch = chans [i];
            ch.channel.center = &bufs [2];
            ch.channel.left   = &bufs [0];
            ch.channel.right  = &bufs [1];
        }
    }

    mixer.bufs [0] = &bufs [0];
    mixer.bufs [1] = &bufs [1];
    mixer.bufs [2] = &bufs [2];

    if ( echo_dirty || (!old_echo && (!no_echo && !no_effects)) )
        clear_echo();

    channels_changed();
}