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

CQTexperiment
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 )
{
/*apu.set_tempo( (int) (t * Snes_Spc::tempo_unit) );*/
smp.set_tempo( t );
}
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 )
{
/*apu.set_tempo( (int) (t * Snes_Spc::tempo_unit) );*/
smp.set_tempo( t );
}
// (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)];
@ -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( "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 );

View File

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

View File

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

View File

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

View File

@ -15,6 +15,7 @@ struct SMP : Processor::SPC700 {
uint8_t iplrom[64];
uint8_t apuram[64 * 1024];
int64_t dsp_clock_step;
SuperFamicom::DSP dsp;
inline void step(unsigned clocks);
@ -27,6 +28,8 @@ struct SMP : Processor::SPC700 {
void power();
void reset();
void set_tempo(double);
void render(int16_t * buffer, unsigned count);
void skip(unsigned count);
@ -115,6 +118,8 @@ public:
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 const uint8_t* SMP::get_sfm_queue() const { return sfm_queue; }