2nd part of FS#12176. Tempo setting migrated to fixed point for libgme.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30274 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/codecs/libgme/ay_emu.c b/apps/codecs/libgme/ay_emu.c
index dc775cb..78d4556 100644
--- a/apps/codecs/libgme/ay_emu.c
+++ b/apps/codecs/libgme/ay_emu.c
@@ -54,7 +54,7 @@
 {

 	this->sample_rate  = 0;

 	this->mute_mask_   = 0;

-	this->tempo        = 1.0;

+	this->tempo        = (int)FP_ONE_TEMPO;

 	this->gain         = 1.0;

 	this->track_count  = 0;

 	

@@ -343,11 +343,11 @@
 	}

 }

 

-void Sound_set_tempo( struct Ay_Emu *this, double t )

+void Sound_set_tempo( struct Ay_Emu *this, int t )

 {

 	require( this->sample_rate ); // sample rate must be set first

-	double const min = 0.02;

-	double const max = 4.00;

+	int const min = (int)(FP_ONE_TEMPO*0.02);

+	int const max = (int)(FP_ONE_TEMPO*4.00);

 	if ( t < min ) t = min;

 	if ( t > max ) t = max;

 	this->tempo = t;

@@ -356,7 +356,7 @@
 	if ( this->clock_rate_ != spectrum_clock )

 		p = this->clock_rate_ / 50;

 	

-	this->play_period = (blip_time_t) (p / t);

+	this->play_period = (blip_time_t) ((p * FP_ONE_TEMPO) / t);

 }

 

 void fill_buf( struct Ay_Emu *this ) ICODE_ATTR;;

diff --git a/apps/codecs/libgme/ay_emu.h b/apps/codecs/libgme/ay_emu.h
index 9125216..c41debc 100644
--- a/apps/codecs/libgme/ay_emu.h
+++ b/apps/codecs/libgme/ay_emu.h
@@ -65,7 +65,7 @@
 	int max_initial_silence;
 	int voice_count;
 	int mute_mask_;
-	double tempo;
+	int tempo;
 	double gain;
 	
 	long sample_rate;
@@ -141,7 +141,7 @@
 
 // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
 // Track length as returned by track_info() assumes a tempo of 1.0.
-void Sound_set_tempo( struct Ay_Emu* this, double t );
+void Sound_set_tempo( struct Ay_Emu* this, int t );
 	
 // Mute/unmute voice i, where voice 0 is first voice
 void Sound_mute_voice( struct Ay_Emu* this, int index, bool mute );
diff --git a/apps/codecs/libgme/blargg_common.h b/apps/codecs/libgme/blargg_common.h
index be34379..a9e47b8 100644
--- a/apps/codecs/libgme/blargg_common.h
+++ b/apps/codecs/libgme/blargg_common.h
@@ -20,6 +20,9 @@
 #include "codeclib.h"
 #endif
 
+// common defines
+#define FP_ONE_TEMPO (1LL <<16)
+
 #if 1 /* IRAM configuration is not yet active for all libGME codecs. */
     #undef  ICODE_ATTR
     #define ICODE_ATTR
diff --git a/apps/codecs/libgme/gb_apu.c b/apps/codecs/libgme/gb_apu.c
index a441645..adc3071 100644
--- a/apps/codecs/libgme/gb_apu.c
+++ b/apps/codecs/libgme/gb_apu.c
@@ -152,11 +152,11 @@
 	}
 }
 
-void Apu_set_tempo( struct Gb_Apu* this, double t )
+void Apu_set_tempo( struct Gb_Apu* this, int t )
 {
 	this->frame_period = 4194304 / 512; // 512 Hz
-	if ( t != 1.0 )
-		this->frame_period = t ? (blip_time_t) (this->frame_period / t) : (blip_time_t) (0);
+	if ( t != (int)FP_ONE_TEMPO )
+		this->frame_period = t ? (blip_time_t) ((this->frame_period * FP_ONE_TEMPO) / t) : (blip_time_t) (0);
 }
 
 void Apu_init( struct Gb_Apu* this )
@@ -184,7 +184,7 @@
 	}
 	
 	this->reduce_clicks_ = false;
-	Apu_set_tempo( this, 1.0 );
+	Apu_set_tempo( this, (int)FP_ONE_TEMPO );
 	this->volume_ = 1.0;
 	Apu_reset( this, mode_cgb, false );
 }
diff --git a/apps/codecs/libgme/gb_apu.h b/apps/codecs/libgme/gb_apu.h
index f1457a2..028be29 100644
--- a/apps/codecs/libgme/gb_apu.h
+++ b/apps/codecs/libgme/gb_apu.h
@@ -77,7 +77,7 @@
 	
 // Sets frame sequencer rate, where 1.0 is normal. Meant for adjusting the
 // tempo in a music player.
-void Apu_set_tempo( struct Gb_Apu* this, double t );
+void Apu_set_tempo( struct Gb_Apu* this, int t );
 
 
 void write_osc( struct Gb_Apu* this, int reg, int old_data, int data ) ICODE_ATTR;
diff --git a/apps/codecs/libgme/gbs_emu.c b/apps/codecs/libgme/gbs_emu.c
index f5e214e..05c9be2 100644
--- a/apps/codecs/libgme/gbs_emu.c
+++ b/apps/codecs/libgme/gbs_emu.c
@@ -46,7 +46,7 @@
 {	
 	this->sample_rate_ = 0;
 	this->mute_mask_   = 0;
-	this->tempo_       = 1.0;
+	this->tempo_       = (int)(FP_ONE_TEMPO);
 	
 	// Unload
 	this->header.timer_mode = 0;
@@ -304,16 +304,16 @@
 	}
 }
 
-void Sound_set_tempo( struct Gbs_Emu* this, double t )
+void Sound_set_tempo( struct Gbs_Emu* this, int t )
 {
 	require( this->sample_rate_ ); // sample rate must be set first
-	double const min = 0.02;
-	double const max = 4.00;
+	int const min = (int)(FP_ONE_TEMPO*0.02);
+	int const max = (int)(FP_ONE_TEMPO*4.00);
 	if ( t < min ) t = min;
 	if ( t > max ) t = max;
 	this->tempo_ = t;
 		
-	this->tempo = (int) (tempo_unit / t + 0.5 );
+	this->tempo = (int) ((tempo_unit * FP_ONE_TEMPO) / t);
 	Apu_set_tempo( &this->apu, t );
 	Update_timer( this );
 }
diff --git a/apps/codecs/libgme/gbs_emu.h b/apps/codecs/libgme/gbs_emu.h
index c107264..dcbc5b0 100644
--- a/apps/codecs/libgme/gbs_emu.h
+++ b/apps/codecs/libgme/gbs_emu.h
@@ -64,7 +64,7 @@
 	unsigned buf_changed_count;
 	int voice_count_;
 	double gain_;
-	double tempo_;
+	int tempo_;
 	
 	// track-specific
 	byte track_count;
@@ -158,7 +158,7 @@
 // Sound customization
 // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
 // Track length as returned by track_info() assumes a tempo of 1.0.
-void Sound_set_tempo( struct Gbs_Emu* this, double );
+void Sound_set_tempo( struct Gbs_Emu* this, int );
 
 // Mute/unmute voice i, where voice 0 is first voice
 void Sound_mute_voice( struct Gbs_Emu* this, int index, bool mute );
diff --git a/apps/codecs/libgme/hes_emu.c b/apps/codecs/libgme/hes_emu.c
index 3240278..112cd75 100644
--- a/apps/codecs/libgme/hes_emu.c
+++ b/apps/codecs/libgme/hes_emu.c
@@ -49,7 +49,7 @@
 {
 	this->sample_rate_ = 0;
 	this->mute_mask_   = 0;
-	this->tempo_       = 1.0;
+	this->tempo_       = (int)(FP_ONE_TEMPO);
 
 	// defaults
 	this->max_initial_silence = 2;
@@ -544,15 +544,15 @@
 	}
 }
 
-void Sound_set_tempo( struct Hes_Emu* this, double t )
+void Sound_set_tempo( struct Hes_Emu* this, int t )
 {
 	require( this->sample_rate_ ); // sample rate must be set first
-	double const min = 0.02;
-	double const max = 4.00;
+	int const min = (int)(FP_ONE_TEMPO*0.02);
+	int const max = (int)(FP_ONE_TEMPO*4.00);
 	if ( t < min ) t = min;
 	if ( t > max ) t = max;
-	this->play_period = (hes_time_t) (period_60hz / t);
-	this->timer_base = (int) (1024 / t);
+	this->play_period = (hes_time_t) ((period_60hz*FP_ONE_TEMPO) / t);
+	this->timer_base = (int) ((1024*FP_ONE_TEMPO) / t);
 	recalc_timer_load( this );
 	this->tempo_ = t;
 }
diff --git a/apps/codecs/libgme/hes_emu.h b/apps/codecs/libgme/hes_emu.h
index 18dbe0d..d16ba64 100644
--- a/apps/codecs/libgme/hes_emu.h
+++ b/apps/codecs/libgme/hes_emu.h
@@ -69,7 +69,7 @@
 	long sample_rate_;
 	unsigned buf_changed_count;
 	int voice_count_;
-	double tempo_;
+	int tempo_;
 	double gain_;
 	
 	// track-specific
@@ -168,7 +168,7 @@
 // Sound customization
 // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
 // Track length as returned by track_info() assumes a tempo of 1.0.
-void Sound_set_tempo( struct Hes_Emu* this, double );
+void Sound_set_tempo( struct Hes_Emu* this, int );
 
 // Mute/unmute voice i, where voice 0 is first voice
 void Sound_mute_voice( struct Hes_Emu* this, int index, bool mute );
diff --git a/apps/codecs/libgme/kss_emu.c b/apps/codecs/libgme/kss_emu.c
index b010342..e1576ad 100644
--- a/apps/codecs/libgme/kss_emu.c
+++ b/apps/codecs/libgme/kss_emu.c
@@ -53,7 +53,7 @@
 {
 	this->sample_rate   = 0;
 	this->mute_mask_    = 0;
-	this->tempo       = 1.0;
+	this->tempo       = (int)(FP_ONE_TEMPO);
 	this->gain        = 1.0;
 	this->chip_flags = 0;
 	
@@ -509,18 +509,18 @@
 	}
 }
 
-void Sound_set_tempo( struct Kss_Emu* this, double t )
+void Sound_set_tempo( struct Kss_Emu* this, int t )
 {
 	require( this->sample_rate ); // sample rate must be set first
-	double const min = 0.02;
-	double const max = 4.00;
+	int const min = (int)(FP_ONE_TEMPO*0.02);
+	int const max = (int)(FP_ONE_TEMPO*4.00);
 	if ( t < min ) t = min;
 	if ( t > max ) t = max;
 	this->tempo = t;
 	
 	blip_time_t period =
 		(this->header.device_flags & 0x40 ? clock_rate / 50 : clock_rate / 60);
-	this->play_period = (blip_time_t) (period / t);
+	this->play_period = (blip_time_t) ((period * FP_ONE_TEMPO) / t);
 }
 
 void fill_buf( struct Kss_Emu* this );
diff --git a/apps/codecs/libgme/kss_emu.h b/apps/codecs/libgme/kss_emu.h
index 81db2ae..d0a3de3 100644
--- a/apps/codecs/libgme/kss_emu.h
+++ b/apps/codecs/libgme/kss_emu.h
@@ -97,7 +97,7 @@
 	int max_initial_silence;
 	int voice_count;
 	int mute_mask_;
-	double tempo;
+	int tempo;
 	double gain;
 	
 	long sample_rate;
@@ -192,7 +192,7 @@
 
 // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
 // Track length as returned by track_info() assumes a tempo of 1.0.
-void Sound_set_tempo( struct Kss_Emu* this, double t );
+void Sound_set_tempo( struct Kss_Emu* this, int t );
 
 // Mute/unmute voice i, where voice 0 is first voice
 void Sound_mute_voice( struct Kss_Emu* this, int index, bool mute );
diff --git a/apps/codecs/libgme/nes_apu.c b/apps/codecs/libgme/nes_apu.c
index 8f1f376..826c768 100644
--- a/apps/codecs/libgme/nes_apu.c
+++ b/apps/codecs/libgme/nes_apu.c
@@ -19,7 +19,7 @@
 
 void Apu_init( struct Nes_Apu* this )
 {
-	this->tempo_ = 1.0;
+	this->tempo_ = (int)(FP_ONE_TEMPO);
 	this->dmc.apu = this;
 	this->dmc.prg_reader = NULL;
 	this->irq_notifier_ = NULL;
@@ -77,12 +77,12 @@
 		Apu_osc_output( this, i, buffer );
 }
 
-void Apu_set_tempo( struct Nes_Apu* this, double t )
+void Apu_set_tempo( struct Nes_Apu* this, int t )
 {
 	this->tempo_ = t;
 	this->frame_period = (this->dmc.pal_mode ? 8314 : 7458);
-	if ( t != 1.0 )
-		this->frame_period = (int) (this->frame_period / t) & ~1; // must be even
+	if ( t != (int)FP_ONE_TEMPO )
+		this->frame_period = (int) ((this->frame_period * FP_ONE_TEMPO) / t) & ~1; // must be even
 }
 
 void Apu_reset( struct Nes_Apu* this, bool pal_mode, int initial_dmc_dac )
diff --git a/apps/codecs/libgme/nes_apu.h b/apps/codecs/libgme/nes_apu.h
index 6a2c280..8653afc 100644
--- a/apps/codecs/libgme/nes_apu.h
+++ b/apps/codecs/libgme/nes_apu.h
@@ -28,7 +28,7 @@
 	struct Nes_Triangle        triangle;
 	struct Nes_Dmc             dmc;
 	
-	double tempo_;
+	int tempo_;
 	nes_time_t last_time; // has been run until this time in current frame
 	nes_time_t earliest_irq_;
 	nes_time_t next_irq;
@@ -74,7 +74,7 @@
 void Apu_reset( struct Nes_Apu* this, bool pal_mode, int initial_dmc_dac );
 	
 // Adjust frame period
-void Apu_set_tempo( struct Nes_Apu* this, double );
+void Apu_set_tempo( struct Nes_Apu* this, int );
 	
 // Set overall volume (default is 1.0)
 void Apu_volume( struct Nes_Apu* this, double );
diff --git a/apps/codecs/libgme/nes_fds_apu.c b/apps/codecs/libgme/nes_fds_apu.c
index 5142141..f78e962 100644
--- a/apps/codecs/libgme/nes_fds_apu.c
+++ b/apps/codecs/libgme/nes_fds_apu.c
@@ -108,12 +108,12 @@
 	}
 }
 
-void Fds_set_tempo( struct Nes_Fds_Apu* this, double t )
+void Fds_set_tempo( struct Nes_Fds_Apu* this, int t )
 {
 	this->lfo_tempo = lfo_base_tempo;
-	if ( t != 1.0 )
+	if ( t != (int)FP_ONE_TEMPO )
 	{
-		this->lfo_tempo = (int) ((double) lfo_base_tempo / t + 0.5);
+		this->lfo_tempo = (int) ((lfo_base_tempo * FP_ONE_TEMPO) / t);
 		if ( this->lfo_tempo <= 0 )
 			this->lfo_tempo = 1;
 	}
diff --git a/apps/codecs/libgme/nes_fds_apu.h b/apps/codecs/libgme/nes_fds_apu.h
index 1360e44..47b17eb 100644
--- a/apps/codecs/libgme/nes_fds_apu.h
+++ b/apps/codecs/libgme/nes_fds_apu.h
@@ -48,7 +48,7 @@
 // init
 void Fds_init( struct Nes_Fds_Apu* this );
 // setup
-void Fds_set_tempo( struct Nes_Fds_Apu* this, double t );
+void Fds_set_tempo( struct Nes_Fds_Apu* this, int t );
 	
 // emulation
 void Fds_reset( struct Nes_Fds_Apu* this );
diff --git a/apps/codecs/libgme/nsf_emu.c b/apps/codecs/libgme/nsf_emu.c
index c805780..7b9ff1a 100644
--- a/apps/codecs/libgme/nsf_emu.c
+++ b/apps/codecs/libgme/nsf_emu.c
@@ -54,7 +54,7 @@
 {
 	this->sample_rate = 0;
 	this->mute_mask_   = 0;
-	this->tempo        = 1.0;
+	this->tempo        = (int)(FP_ONE_TEMPO);
 	this->gain         = 1.0;
 	
 	// defaults
@@ -474,16 +474,16 @@
 	}
 }
 
-void Sound_set_tempo( struct Nsf_Emu* this, double t )
+void Sound_set_tempo( struct Nsf_Emu* this, int t )
 {
 	require( this->sample_rate ); // sample rate must be set first
-	double const min = 0.02;
-	double const max = 4.00;
+	int const min = (int)(FP_ONE_TEMPO*0.02);
+	int const max = (int)(FP_ONE_TEMPO*4.00);
 	if ( t < min ) t = min;
 	if ( t > max ) t = max;
 	this->tempo = t;
 	
-	set_play_period( this, (int) (play_period( &this->header ) / t) );
+	set_play_period( this, (int) ((play_period( &this->header ) * FP_ONE_TEMPO) / t) );
 
 	Apu_set_tempo( &this->apu, t );
 	
diff --git a/apps/codecs/libgme/nsf_emu.h b/apps/codecs/libgme/nsf_emu.h
index 421425e..808ef44 100644
--- a/apps/codecs/libgme/nsf_emu.h
+++ b/apps/codecs/libgme/nsf_emu.h
@@ -89,7 +89,7 @@
 	int max_initial_silence;
 	int voice_count;
 	int mute_mask_;
-	double tempo;
+	int tempo;
 	double gain;
 	
 	long sample_rate;
@@ -189,7 +189,7 @@
 
 // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
 // Track length as returned by track_info() assumes a tempo of 1.0.
-void Sound_set_tempo( struct Nsf_Emu* this, double t );
+void Sound_set_tempo( struct Nsf_Emu* this, int t );
 
 // Mute/unmute voice i, where voice 0 is first voice
 void Sound_mute_voice( struct Nsf_Emu* this, int index, bool mute );
diff --git a/apps/codecs/libgme/sgc_emu.c b/apps/codecs/libgme/sgc_emu.c
index 9abfc00..3cd5dc6 100644
--- a/apps/codecs/libgme/sgc_emu.c
+++ b/apps/codecs/libgme/sgc_emu.c
@@ -46,7 +46,7 @@
 	

 	this->sample_rate = 0;

 	this->mute_mask_  = 0;

-	this->tempo       = 1.0;

+	this->tempo       = (int)FP_ONE_TEMPO;

 	this->gain        = 1.0;

 	this->voice_count = 0;

 	

@@ -294,16 +294,16 @@
 	}

 }

 

-void Sound_set_tempo( struct Sgc_Emu* this, double t )

+void Sound_set_tempo( struct Sgc_Emu* this, int t )

 {

 	require( this->sample_rate ); // sample rate must be set first

-	double const min = 0.02;

-	double const max = 4.00;

+	int const min = (int)(FP_ONE_TEMPO*0.02);

+	int const max = (int)(FP_ONE_TEMPO*4.00);

 	if ( t < min ) t = min;

 	if ( t > max ) t = max;

 	this->tempo = t;

 

-	this->play_period = (int) (clock_rate( this ) / (this->header.rate ? 50 : 60) / t);

+	this->play_period = (int) ((clock_rate( this ) * FP_ONE_TEMPO) / (this->header.rate ? 50 : 60) / t);

 }

 

 void fill_buf( struct Sgc_Emu* this ) ICODE_ATTR;

diff --git a/apps/codecs/libgme/sgc_emu.h b/apps/codecs/libgme/sgc_emu.h
index 957e743..89b56f4 100644
--- a/apps/codecs/libgme/sgc_emu.h
+++ b/apps/codecs/libgme/sgc_emu.h
@@ -66,7 +66,7 @@
 	// general

 	int voice_count;

 	int mute_mask_;

-	double tempo;

+	int tempo;

 	double gain;

 	

 	long sample_rate;

@@ -166,7 +166,7 @@
 

 // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.

 // Track length as returned by track_info() assumes a tempo of 1.0.

-void Sound_set_tempo( struct Sgc_Emu* this, double t );

+void Sound_set_tempo( struct Sgc_Emu* this, int t );

 

 // Mute/unmute voice i, where voice 0 is first voice

 void Sound_mute_voice( struct Sgc_Emu* this, int index, bool mute );

diff --git a/apps/codecs/libgme/vgm_emu.c b/apps/codecs/libgme/vgm_emu.c
index 7fed4ef..de5bd29 100644
--- a/apps/codecs/libgme/vgm_emu.c
+++ b/apps/codecs/libgme/vgm_emu.c
@@ -76,7 +76,7 @@
 {
 	this->sample_rate = 0;
 	this->mute_mask_ = 0;
-	this->tempo = 1.0;
+	this->tempo = (int)(FP_ONE_TEMPO);
 	
 	// defaults
 	this->max_initial_silence = 2;
@@ -288,7 +288,7 @@
 	Ym2612_enable( &this->ym2612, false );
 	Ym2413_enable( &this->ym2413, false );
 	
-	Sound_set_tempo( this, 1 );
+	Sound_set_tempo( this, (int)(FP_ONE_TEMPO) );
 	
 	this->voice_count = sms_osc_count;
 	
@@ -733,27 +733,26 @@
 	}
 }
 
-void Sound_set_tempo( struct Vgm_Emu* this, double t )
+void Sound_set_tempo( struct Vgm_Emu* this, int t )
 {
 	require( this->sample_rate ); // sample rate must be set first
-	double const min = 0.02;
-	double const max = 4.00;
+	int const min = (int)(FP_ONE_TEMPO*0.02);
+	int const max = (int)(FP_ONE_TEMPO*4.00);
 	if ( t < min ) t = min;
 	if ( t > max ) t = max;
 	this->tempo = t;
 	
 	if ( this->file_begin )
 	{
-		this->vgm_rate = (long) (44100 * t + 0.5);
-		this->blip_time_factor = (int) ((double)
-				(1 << blip_time_bits) / this->vgm_rate * Blip_clock_rate( &this->stereo_buf.bufs [0] ) + 0.5);
+		this->vgm_rate = (long) ((44100LL * t) / FP_ONE_TEMPO);
+		this->blip_time_factor = (int) (((1LL << blip_time_bits) * Blip_clock_rate( &this->stereo_buf.bufs [0] )) / this->vgm_rate);
 		//debug_printf( "blip_time_factor: %ld\n", blip_time_factor );
 		//debug_printf( "vgm_rate: %ld\n", vgm_rate );
 		// TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only)
 		//blip_time_factor = (long) floor( double (1L << blip_time_bits) * psg_rate / 44100 / t + 0.5 );
 		//vgm_rate = (long) floor( double (1L << blip_time_bits) * psg_rate / blip_time_factor + 0.5 );
 		
-		this->fm_time_factor = 2 + (int) (this->fm_rate * (1 << fm_time_bits) / this->vgm_rate + 0.5);
+		this->fm_time_factor = 2 + (int) ((this->fm_rate * (1LL << fm_time_bits)) / this->vgm_rate);
 	}
 }
 
diff --git a/apps/codecs/libgme/vgm_emu.h b/apps/codecs/libgme/vgm_emu.h
index deb64bc..ee57d5c 100644
--- a/apps/codecs/libgme/vgm_emu.h
+++ b/apps/codecs/libgme/vgm_emu.h
@@ -93,7 +93,7 @@
 	int max_initial_silence;
 	int voice_count;
 	int mute_mask_;
-	double tempo;
+	int tempo;
 	double gain;
 	
 	long sample_rate;
@@ -190,7 +190,7 @@
 	
 // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
 // Track length as returned by track_info() assumes a tempo of 1.0.
-void Sound_set_tempo( struct Vgm_Emu* this, double t );
+void Sound_set_tempo( struct Vgm_Emu* this, int t );
 	
 // Mute/unmute voice i, where voice 0 is first voice
 void Sound_mute_voice( struct Vgm_Emu* this, int index, bool mute );