1
0
Fork 0
forked from len0rd/rockbox

5th part of FS#12176. Further fixed point migration. Only two emulators (ym2413, ym2612) still use floating point.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30281 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Andree Buschmann 2011-08-11 21:06:16 +00:00
parent b127949860
commit 1b9f9fb465
17 changed files with 38 additions and 43 deletions

View file

@ -107,7 +107,7 @@ static void Adpcm_run_until( struct Hes_Apu_Adpcm* this, blip_time_t end_time )
int fadetimer = state->fadetimer; int fadetimer = state->fadetimer;
int fadecount = state->fadecount; int fadecount = state->fadecount;
int last_time = this->last_time; int last_time = this->last_time;
double next_timer = this->next_timer; int next_timer = this->next_timer;
int last_amp = this->last_amp; int last_amp = this->last_amp;
struct Blip_Buffer* output = this->output; // cache often-used values struct Blip_Buffer* output = this->output; // cache often-used values
@ -129,7 +129,7 @@ static void Adpcm_run_until( struct Hes_Apu_Adpcm* this, blip_time_t end_time )
volume = 0xFF - ( 0xFF * fadecount / fadetimer ); volume = 0xFF - ( 0xFF * fadecount / fadetimer );
} }
} }
next_timer += 7159.091; next_timer += 7159; // 7159091/1000;
} }
int amp; int amp;
if ( state->ad_low_nibble ) if ( state->ad_low_nibble )
@ -160,7 +160,7 @@ static void Adpcm_run_until( struct Hes_Apu_Adpcm* this, blip_time_t end_time )
if ( !state->playflag ) if ( !state->playflag )
{ {
while ( next_timer <= end_time ) next_timer += 7159.091; while ( next_timer <= end_time ) next_timer += 7159; // 7159091/1000
last_time = end_time; last_time = end_time;
} }
@ -290,7 +290,7 @@ void Adpcm_end_frame( struct Hes_Apu_Adpcm* this, blip_time_t end_time )
{ {
Adpcm_run_until( this, end_time ); Adpcm_run_until( this, end_time );
this->last_time -= end_time; this->last_time -= end_time;
this->next_timer -= (double)end_time; this->next_timer -= end_time;
check( last_time >= 0 ); check( last_time >= 0 );
if ( this->output ) if ( this->output )
Blip_set_modified( this->output ); Blip_set_modified( this->output );

View file

@ -43,7 +43,7 @@ struct Hes_Apu_Adpcm {
struct Blip_Buffer* output; struct Blip_Buffer* output;
blip_time_t last_time; blip_time_t last_time;
double next_timer; int next_timer;
int last_amp; int last_amp;
}; };

View file

@ -46,7 +46,7 @@ void Apu_init( struct Nes_Apu* this )
void Apu_enable_nonlinear( struct Nes_Apu* this, int v ) void Apu_enable_nonlinear( struct Nes_Apu* this, int v )
{ {
this->dmc.nonlinear = true; this->dmc.nonlinear = true;
Synth_volume( &this->square_synth, (int)((1.3 * 0.25751258 / 0.742467605 * 0.25 * FP_ONE_VOLUME) / amp_range * v) ); Synth_volume( &this->square_synth, (int)((long long)(1.3 * 0.25751258 / 0.742467605 * 0.25 * FP_ONE_VOLUME) / amp_range * v) );
const int tnd = (int)(0.48 / 202 * 0.75 * FP_ONE_VOLUME); const int tnd = (int)(0.48 / 202 * 0.75 * FP_ONE_VOLUME);
Synth_volume( &this->triangle.synth, 3 * tnd ); Synth_volume( &this->triangle.synth, 3 * tnd );

View file

@ -29,7 +29,7 @@ void Vrc7_reset( struct Nes_Vrc7_Apu* this )
OPLL_setMask(&this->opll, this->mask); OPLL_setMask(&this->opll, this->mask);
} }
void Vrc7_set_rate( struct Nes_Vrc7_Apu* this, double r ) void Vrc7_set_rate( struct Nes_Vrc7_Apu* this, int r )
{ {
OPLL_set_quality( &this->opll, r < 44100 ? 0 : 1 ); OPLL_set_quality( &this->opll, r < 44100 ? 0 : 1 );
OPLL_set_rate( &this->opll, (e_uint32)r ); OPLL_set_rate( &this->opll, (e_uint32)r );

View file

@ -27,7 +27,7 @@ struct Nes_Vrc7_Apu {
// See Nes_Apu.h for reference // See Nes_Apu.h for reference
void Vrc7_init( struct Nes_Vrc7_Apu* this ); void Vrc7_init( struct Nes_Vrc7_Apu* this );
void Vrc7_reset( struct Nes_Vrc7_Apu* this ); void Vrc7_reset( struct Nes_Vrc7_Apu* this );
void Vrc7_set_rate( struct Nes_Vrc7_Apu* this, double r ); void Vrc7_set_rate( struct Nes_Vrc7_Apu* this, int r );
void Vrc7_end_frame( struct Nes_Vrc7_Apu* this, blip_time_t ) ICODE_ATTR; void Vrc7_end_frame( struct Nes_Vrc7_Apu* this, blip_time_t ) ICODE_ATTR;
void Vrc7_write_reg( struct Nes_Vrc7_Apu* this, int reg ) ICODE_ATTR; void Vrc7_write_reg( struct Nes_Vrc7_Apu* this, int reg ) ICODE_ATTR;

View file

@ -179,9 +179,9 @@ static bool pal_only( struct header_t* this )
return (this->speed_flags & 3) == 1; return (this->speed_flags & 3) == 1;
} }
static double clock_rate( struct header_t* this ) static long clock_rate( struct header_t* this )
{ {
return pal_only( this ) ? 1662607.125 : 1789772.727272727; return pal_only( this ) ? (long)1662607.125 : (long)1789772.727272727;
} }
static int play_period( struct header_t* this ) static int play_period( struct header_t* this )
@ -206,7 +206,7 @@ static int play_period( struct header_t* this )
// Custom rate // Custom rate
if ( rate != value ) if ( rate != value )
clocks = (int) (rate * clock_rate( this ) * (1.0/1000000.0)); clocks = (int) ((1LL * rate * clock_rate( this )) / 1000000);
return clocks; return clocks;
} }
@ -285,7 +285,7 @@ blargg_err_t Nsf_post_load( struct Nsf_Emu* this )
this->track_count = this->header.track_count; this->track_count = this->header.track_count;
// Change clock rate & setup buffer // Change clock rate & setup buffer
this->clock_rate__ = (long) (clock_rate( &this->header ) + 0.5); this->clock_rate__ = (long) clock_rate( &this->header );
Buffer_clock_rate( &this->stereo_buf, this->clock_rate__ ); Buffer_clock_rate( &this->stereo_buf, this->clock_rate__ );
this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf ); this->buf_changed_count = Buffer_channels_changed_count( &this->stereo_buf );
return 0; return 0;

View file

@ -112,7 +112,6 @@ struct Nsf_Emu {
long silence_count; // number of samples of silence to play before using buf long silence_count; // number of samples of silence to play before using buf
long buf_remain; // number of samples left in silence buffer long buf_remain; // number of samples left in silence buffer
double clock_rate_;
long clock_rate__; long clock_rate__;
unsigned buf_changed_count; unsigned buf_changed_count;

View file

@ -24,15 +24,13 @@ unsigned const resampler_extra = 34;
enum { shift = 14 }; enum { shift = 14 };
int const unit = 1 << shift; int const unit = 1 << shift;
blargg_err_t Resampler_setup( struct Resampler* this, double oversample, double rolloff, double gain ) blargg_err_t Resampler_setup( struct Resampler* this, int fm_rate, int fm_gain, int rate, int gain )
{ {
(void) rolloff; this->gain_ = (int)( ((1LL << gain_bits) * fm_gain * gain) / FP_ONE_GAIN );
this->step = (int)( ((1LL << shift) * fm_rate) / rate + 1);
this->gain_ = (int)((1 << gain_bits) * gain); this->rate_ = this->step;
this->step = (int) ( oversample * unit + 0.5); return 0;
this->rate_ = 1.0 / unit * this->step; }
return 0;
}
blargg_err_t Resampler_reset( struct Resampler* this, int pairs ) blargg_err_t Resampler_reset( struct Resampler* this, int pairs )
{ {
@ -52,7 +50,7 @@ void Resampler_resize( struct Resampler* this, int pairs )
if ( this->sample_buf_size != new_sample_buf_size ) if ( this->sample_buf_size != new_sample_buf_size )
{ {
this->sample_buf_size = new_sample_buf_size; this->sample_buf_size = new_sample_buf_size;
this->oversamples_per_frame = (int) (pairs * this->rate_) * 2 + 2; this->oversamples_per_frame = (int) ((pairs * this->rate_ * 2LL) / unit) + 2;
Resampler_clear( this ); Resampler_clear( this );
} }
} }

View file

@ -31,7 +31,7 @@ struct Resampler {
int buffer_size; int buffer_size;
int write_pos; int write_pos;
double rate_; int rate_;
int pos; int pos;
int step; int step;
@ -55,7 +55,7 @@ static inline void Resampler_set_callback(struct Resampler* this, int (*func)( v
this->callback_data = user_data; this->callback_data = user_data;
} }
blargg_err_t Resampler_setup( struct Resampler* this, double oversample, double rolloff, double gain ); blargg_err_t Resampler_setup( struct Resampler* this, int fm_rate, int fm_gain, int rate, int gain );
static inline void Resampler_clear( struct Resampler* this ) static inline void Resampler_clear( struct Resampler* this )
{ {

View file

@ -8,9 +8,9 @@ void Fm_apu_create( struct Sms_Fm_Apu* this )
Ym2413_init( &this->apu ); Ym2413_init( &this->apu );
} }
blargg_err_t Fm_apu_init( struct Sms_Fm_Apu* this, double clock_rate, double sample_rate ) blargg_err_t Fm_apu_init( struct Sms_Fm_Apu* this, int clock_rate, int sample_rate )
{ {
this->period_ = (blip_time_t) (clock_rate / sample_rate + 0.5); this->period_ = (blip_time_t) (clock_rate / sample_rate);
CHECK_ALLOC( !Ym2413_set_rate( &this->apu, sample_rate, clock_rate ) ); CHECK_ALLOC( !Ym2413_set_rate( &this->apu, sample_rate, clock_rate ) );
Fm_apu_set_output( this, 0 ); Fm_apu_set_output( this, 0 );

View file

@ -24,7 +24,7 @@ struct Sms_Fm_Apu {
void Fm_apu_create( struct Sms_Fm_Apu* this ); void Fm_apu_create( struct Sms_Fm_Apu* this );
static inline bool Fm_apu_supported( void ) { return Ym2413_supported(); } static inline bool Fm_apu_supported( void ) { return Ym2413_supported(); }
blargg_err_t Fm_apu_init( struct Sms_Fm_Apu* this, double clock_rate, double sample_rate ); blargg_err_t Fm_apu_init( struct Sms_Fm_Apu* this, int clock_rate, int sample_rate );
static inline void Fm_apu_set_output( struct Sms_Fm_Apu* this, struct Blip_Buffer* b ) static inline void Fm_apu_set_output( struct Sms_Fm_Apu* this, struct Blip_Buffer* b )
{ {

View file

@ -22,8 +22,6 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
const char* const gme_wrong_file_type = "Wrong file type for this emulator"; const char* const gme_wrong_file_type = "Wrong file type for this emulator";
int const fm_gain = 3; // FM emulators are internally quieter to avoid 16-bit overflow int const fm_gain = 3; // FM emulators are internally quieter to avoid 16-bit overflow
double const rolloff = 0.990;
double const oversample_factor = 1.5;
int const silence_max = 6; // seconds int const silence_max = 6; // seconds
int const silence_threshold = 0x10; int const silence_threshold = 0x10;
@ -310,7 +308,7 @@ blargg_err_t Vgm_load_mem( struct Vgm_Emu* this, byte const* new_data, long new_
} }
void update_fm_rates( struct Vgm_Emu* this, int* ym2413_rate, int* ym2612_rate ); void update_fm_rates( struct Vgm_Emu* this, int* ym2413_rate, int* ym2612_rate );
static blargg_err_t init_fm( struct Vgm_Emu* this, double* rate ) static blargg_err_t init_fm( struct Vgm_Emu* this, int* rate )
{ {
int ym2612_rate = get_le32( header( this )->ym2612_rate ); int ym2612_rate = get_le32( header( this )->ym2612_rate );
int ym2413_rate = get_le32( header( this )->ym2413_rate ); int ym2413_rate = get_le32( header( this )->ym2413_rate );
@ -320,14 +318,14 @@ static blargg_err_t init_fm( struct Vgm_Emu* this, double* rate )
if ( ym2612_rate ) if ( ym2612_rate )
{ {
if ( !*rate ) if ( !*rate )
*rate = ym2612_rate / 144.0; *rate = ym2612_rate / 144;
RETURN_ERR( Ym2612_set_rate( &this->ym2612, *rate, ym2612_rate ) ); RETURN_ERR( Ym2612_set_rate( &this->ym2612, *rate, ym2612_rate ) );
Ym2612_enable( &this->ym2612, true ); Ym2612_enable( &this->ym2612, true );
} }
else if ( ym2413_rate ) else if ( ym2413_rate )
{ {
if ( !*rate ) if ( !*rate )
*rate = ym2413_rate / 72.0; *rate = ym2413_rate / 72;
int result = Ym2413_set_rate( &this->ym2413, *rate, ym2413_rate ); int result = Ym2413_set_rate( &this->ym2413, *rate, ym2413_rate );
if ( result == 2 ) if ( result == 2 )
return "YM2413 FM sound not supported"; return "YM2413 FM sound not supported";
@ -342,15 +340,15 @@ static blargg_err_t init_fm( struct Vgm_Emu* this, double* rate )
blargg_err_t setup_fm( struct Vgm_Emu* this ) blargg_err_t setup_fm( struct Vgm_Emu* this )
{ {
double fm_rate = 0.0; int fm_rate = 0;
if ( !this->disable_oversampling ) if ( !this->disable_oversampling )
this->fm_rate = this->sample_rate * oversample_factor; this->fm_rate = (this->sample_rate * 3) / 2; // oversample factor = 1.5
RETURN_ERR( init_fm( this, &fm_rate ) ); RETURN_ERR( init_fm( this, &fm_rate ) );
if ( uses_fm( this ) ) if ( uses_fm( this ) )
{ {
this->voice_count = 8; this->voice_count = 8;
RETURN_ERR( Resampler_setup( &this->resampler, fm_rate / this->sample_rate, rolloff, fm_gain * (double)(this->gain)/FP_ONE_GAIN ) ); RETURN_ERR( Resampler_setup( &this->resampler, fm_rate, fm_gain, this->sample_rate, this->gain ) );
RETURN_ERR( Resampler_reset( &this->resampler, Buffer_length( &this->stereo_buf ) * this->sample_rate / 1000 ) ); RETURN_ERR( Resampler_reset( &this->resampler, Buffer_length( &this->stereo_buf ) * this->sample_rate / 1000 ) );
Sms_apu_volume( &this->psg, ((this->gain/5)-(this->gain*5)/1000) * fm_gain ); Sms_apu_volume( &this->psg, ((this->gain/5)-(this->gain*5)/1000) * fm_gain );
} }

View file

@ -63,7 +63,7 @@ struct track_info_t
// aliasing on high notes. Currently YM2413 support requires that you supply a // aliasing on high notes. Currently YM2413 support requires that you supply a
// YM2413 sound chip emulator. I can provide one I've modified to work with the library. // YM2413 sound chip emulator. I can provide one I've modified to work with the library.
struct Vgm_Emu { struct Vgm_Emu {
double fm_rate; int fm_rate;
long psg_rate; long psg_rate;
long vgm_rate; long vgm_rate;
bool disable_oversampling; bool disable_oversampling;

View file

@ -7,7 +7,7 @@ void Ym2413_init( struct Ym2413_Emu* this )
this->last_time = disabled_time; this->out = 0; this->last_time = disabled_time; this->out = 0;
} }
int Ym2413_set_rate( struct Ym2413_Emu* this, double sample_rate, double clock_rate ) int Ym2413_set_rate( struct Ym2413_Emu* this, int sample_rate, int clock_rate )
{ {
OPLL_new ( &this->opll, clock_rate, sample_rate ); OPLL_new ( &this->opll, clock_rate, sample_rate );
OPLL_reset_patch( &this->opll, OPLL_2413_TONE ); OPLL_reset_patch( &this->opll, OPLL_2413_TONE );

View file

@ -25,7 +25,7 @@ static inline bool Ym2413_supported( void ) { return true; }
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero // Sets output sample rate and chip clock rates, in Hz. Returns non-zero
// if error. // if error.
int Ym2413_set_rate( struct Ym2413_Emu* this, double sample_rate, double clock_rate ); int Ym2413_set_rate( struct Ym2413_Emu* this, int sample_rate, int clock_rate );
// Resets to power-up state // Resets to power-up state
void Ym2413_reset( struct Ym2413_Emu* this ); void Ym2413_reset( struct Ym2413_Emu* this );

View file

@ -682,15 +682,15 @@ static void impl_set_rate( struct Ym2612_Impl* impl, double sample_rate, double
impl_reset( impl ); impl_reset( impl );
} }
const char* Ym2612_set_rate( struct Ym2612_Emu* this, double sample_rate, double clock_rate ) const char* Ym2612_set_rate( struct Ym2612_Emu* this, int sample_rate, int clock_rate )
{ {
// Only set rates if necessary // Only set rates if necessary
#if defined(ROCKBOX) #if defined(ROCKBOX)
static double last_sample_rate = 0.0, last_clock_rate = 0.0; static int last_sample_rate = 0, last_clock_rate = 0;
if (last_sample_rate == sample_rate && last_clock_rate == clock_rate) return 0; if (last_sample_rate == sample_rate && last_clock_rate == clock_rate) return 0;
#endif #endif
memset( &this->impl.YM2612, 0, sizeof this->impl.YM2612 ); memset( &this->impl.YM2612, 0, sizeof this->impl.YM2612 );
impl_set_rate( &this->impl, sample_rate, clock_rate ); impl_set_rate( &this->impl, (double)sample_rate, (double)clock_rate );
return 0; return 0;
} }

View file

@ -199,7 +199,7 @@ static inline void Ym2612_init( struct Ym2612_Emu* this_ )
// Sets sample rate and chip clock rate, in Hz. Returns non-zero // Sets sample rate and chip clock rate, in Hz. Returns non-zero
// if error. If clock_rate=0, uses sample_rate*144 // if error. If clock_rate=0, uses sample_rate*144
const char* Ym2612_set_rate( struct Ym2612_Emu* this_, double sample_rate, double clock_rate ); const char* Ym2612_set_rate( struct Ym2612_Emu* this_, int sample_rate, int clock_rate );
// Resets to power-up state // Resets to power-up state
void Ym2612_reset( struct Ym2612_Emu* this_ ); void Ym2612_reset( struct Ym2612_Emu* this_ );