Implemented SPC/SFM tempo control, which the GME plugin doesn't use anyway

This commit is contained in:
Chris Moeller 2013-10-26 11:12:50 -07:00
parent c07a38e59c
commit 4be3186b4c
6 changed files with 13 additions and 12 deletions

View file

@ -354,7 +354,7 @@ blargg_err_t Spc_Emu::load_mem_( byte const in [], int size )
void Spc_Emu::set_tempo_( double t ) void Spc_Emu::set_tempo_( double t )
{ {
/*apu.set_tempo( (int) (t * Snes_Spc::tempo_unit) );*/ smp.set_tempo( t );
} }
blargg_err_t Spc_Emu::start_track_( int track ) blargg_err_t Spc_Emu::start_track_( int track )

View file

@ -138,7 +138,7 @@ blargg_err_t Sfm_Emu::load_mem_( byte const in [], int size )
void Sfm_Emu::set_tempo_( double t ) void Sfm_Emu::set_tempo_( double t )
{ {
/*apu.set_tempo( (int) (t * Snes_Spc::tempo_unit) );*/ smp.set_tempo( t );
} }
// (n ? n : 256) // (n ? n : 256)
@ -255,7 +255,7 @@ blargg_err_t Sfm_Emu::start_track_( int track )
} }
} }
smp.dsp.clock = META_ENUM_INT("dsp:clock", 0); smp.dsp.clock = META_ENUM_INT("dsp:clock", 0) * 4096;
smp.dsp.spc_dsp.m.echo_hist_pos = &smp.dsp.spc_dsp.m.echo_hist[META_ENUM_INT("dsp:echohistaddr", 0)]; smp.dsp.spc_dsp.m.echo_hist_pos = &smp.dsp.spc_dsp.m.echo_hist[META_ENUM_INT("dsp:echohistaddr", 0)];
@ -405,7 +405,7 @@ blargg_err_t Sfm_Emu::save( gme_writer_t writer, void* your_data ) const
metadata.setValue( name + "line", t.current_line ); metadata.setValue( name + "line", t.current_line );
} }
metadata.setValue( "dsp:clock", smp.dsp.clock ); metadata.setValue( "dsp:clock", smp.dsp.clock / 4096 );
metadata.setValue( "dsp:echohistaddr", smp.dsp.spc_dsp.m.echo_hist_pos - smp.dsp.spc_dsp.m.echo_hist ); metadata.setValue( "dsp:echohistaddr", smp.dsp.spc_dsp.m.echo_hist_pos - smp.dsp.spc_dsp.m.echo_hist );

View file

@ -7,13 +7,9 @@ void DSP::step(unsigned clocks) {
clock += clocks; clock += clocks;
} }
void DSP::synchronize_smp() {
while(clock >= 0) smp.enter();
}
void DSP::enter() { void DSP::enter() {
spc_dsp.run(1); spc_dsp.run(1);
step(24); step(24 * 4096);
signed count = spc_dsp.sample_count(); signed count = spc_dsp.sample_count();
if(count > 0) { if(count > 0) {

View file

@ -8,10 +8,9 @@
namespace SuperFamicom { namespace SuperFamicom {
struct DSP { struct DSP {
long clock; int64_t clock;
inline void step(unsigned clocks); inline void step(unsigned clocks);
inline void synchronize_smp();
bool mute(); bool mute();
uint8_t read(uint8_t addr); uint8_t read(uint8_t addr);

View file

@ -10,7 +10,7 @@ namespace SuperFamicom {
void SMP::step(unsigned clocks) { void SMP::step(unsigned clocks) {
clock += clocks; clock += clocks;
dsp.clock -= clocks; dsp.clock -= clocks * dsp_clock_step;
} }
void SMP::synchronize_dsp() { void SMP::synchronize_dsp() {
@ -133,6 +133,7 @@ void SMP::reset() {
SMP::SMP() : dsp( *this ), timer0( *this ), timer1( *this ), timer2( *this ), clock( 0 ) { SMP::SMP() : dsp( *this ), timer0( *this ), timer1( *this ), timer2( *this ), clock( 0 ) {
for(auto& byte : iplrom) byte = 0; for(auto& byte : iplrom) byte = 0;
set_sfm_queue(0, 0); set_sfm_queue(0, 0);
set_tempo(1.0);
} }
SMP::~SMP() { SMP::~SMP() {

View file

@ -15,6 +15,7 @@ struct SMP : Processor::SPC700 {
uint8_t iplrom[64]; uint8_t iplrom[64];
uint8_t apuram[64 * 1024]; uint8_t apuram[64 * 1024];
int64_t dsp_clock_step;
SuperFamicom::DSP dsp; SuperFamicom::DSP dsp;
inline void step(unsigned clocks); inline void step(unsigned clocks);
@ -27,6 +28,8 @@ struct SMP : Processor::SPC700 {
void power(); void power();
void reset(); void reset();
void set_tempo(double);
void render(int16_t * buffer, unsigned count); void render(int16_t * buffer, unsigned count);
void skip(unsigned count); void skip(unsigned count);
@ -115,6 +118,8 @@ public:
inline void cycle_edge(); inline void cycle_edge();
}; };
inline void SMP::set_tempo(double speed) { dsp_clock_step = (int64_t)(4096.0 / speed); }
inline void SMP::set_sfm_queue(const uint8_t *queue, const uint8_t *queue_end) { sfm_queue = queue; sfm_queue_end = queue_end; sfm_last[0] = 0; sfm_last[1] = 0; sfm_last[2] = 0; sfm_last[3] = 0; } inline void SMP::set_sfm_queue(const uint8_t *queue, const uint8_t *queue_end) { sfm_queue = queue; sfm_queue_end = queue_end; sfm_last[0] = 0; sfm_last[1] = 0; sfm_last[2] = 0; sfm_last[3] = 0; }
inline const uint8_t* SMP::get_sfm_queue() const { return sfm_queue; } inline const uint8_t* SMP::get_sfm_queue() const { return sfm_queue; }