optimization from dancinninjac

This commit is contained in:
dborth 2009-11-16 23:28:25 +00:00
parent 44d7390b15
commit 2249894872

View File

@ -27,17 +27,10 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
int const silent_buf_size = 1; // size used for Silent_Blip_Buffer int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
Blip_Buffer::Blip_Buffer() Blip_Buffer::Blip_Buffer():
factor_(LONG_MAX), buffer_(0), buffer_size_(0), bass_shift_(0),
sample_rate_(0), clock_rate_(0), bass_freq_(16),length_(0)
{ {
factor_ = LONG_MAX;
buffer_ = 0;
buffer_size_ = 0;
sample_rate_ = 0;
bass_shift_ = 0;
clock_rate_ = 0;
bass_freq_ = 16;
length_ = 0;
// assumptions code makes about implementation-defined features // assumptions code makes about implementation-defined features
#ifndef NDEBUG #ifndef NDEBUG
// right shift of negative value preserves sign // right shift of negative value preserves sign
@ -126,7 +119,7 @@ Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec
blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
{ {
double ratio = (double) sample_rate_ / rate; double ratio = (double)(sample_rate_) / double(rate);
blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 ); blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
return (blip_resampled_time_t) factor; return (blip_resampled_time_t) factor;
@ -203,14 +196,13 @@ void Blip_Synth_Fast_::volume_unit( double new_unit )
Blip_Synth_::Blip_Synth_( short* p, int w ) : Blip_Synth_::Blip_Synth_( short* p, int w ) :
impulses( p ), impulses( p ),
width( w ) width( w ),
{ volume_unit_(0.0),
volume_unit_ = 0.0; kernel_unit(0),
kernel_unit = 0; buf(0),
buf = 0; last_amp(0),
last_amp = 0; delta_factor(0)
delta_factor = 0; {}
}
#undef PI #undef PI
#define PI 3.1415926535897932384626433832795029 #define PI 3.1415926535897932384626433832795029
@ -226,15 +218,17 @@ static void gen_sinc( float* out, int count, double oversample, double treble, d
treble = 5.0; treble = 5.0;
double const maxh = 4096.0; double const maxh = 4096.0;
double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) ); double const rolloff = pow( 10.0, treble / (maxh * 20.0 * (1.0 - cutoff)) );
double const pow_a_n = pow( rolloff, maxh - maxh * cutoff ); double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
double const to_angle = PI / 2 / maxh / oversample; double const to_angle = PI / (2.0 * maxh * oversample);
for ( int i = 0; i < count; i++ ) for ( int i = 0; i < count; i++ )
{ {
double angle = ((i - count) * 2 + 1) * to_angle; double angle = double(((i - count)<<1) + 1) * to_angle;
double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle ); double maxhAngle = maxh * angle;
double cos_nc_angle = cos( maxh * cutoff * angle ); double c = rolloff * cos( maxhAngle - angle ) - cos( maxhAngle );
double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle ); double cos_nc_angle = cos( maxhAngle * cutoff );
double cos_nc1_angle = cos( maxhAngle * cutoff - angle );
double cos_angle = cos( angle ); double cos_angle = cos( angle );
c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle; c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
@ -250,7 +244,7 @@ void blip_eq_t::generate( float* out, int count ) const
{ {
// lower cutoff freq for narrow kernels with their wider transition band // lower cutoff freq for narrow kernels with their wider transition band
// (8 points->1.49, 16 points->1.15) // (8 points->1.49, 16 points->1.15)
double oversample = blip_res * 2.25 / count + 0.85; double oversample = blip_res * 2.25 / double(count) + 0.85;
double half_rate = sample_rate * 0.5; double half_rate = sample_rate * 0.5;
if ( cutoff_freq ) if ( cutoff_freq )
oversample = half_rate / cutoff_freq; oversample = half_rate / cutoff_freq;
@ -268,7 +262,9 @@ void Blip_Synth_::adjust_impulse()
{ {
// sum pairs for each phase and add error correction to end of first half // sum pairs for each phase and add error correction to end of first half
int const size = impulses_size(); int const size = impulses_size();
for ( int p = blip_res; p-- >= blip_res / 2; )
int blipRes2 = blip_res >> 1;
for ( int p = blip_res; p-- >= blipRes2; )
{ {
int p2 = blip_res - 2 - p; int p2 = blip_res - 2 - p;
long error = kernel_unit; long error = kernel_unit;
@ -290,9 +286,11 @@ void Blip_Synth_::adjust_impulse()
void Blip_Synth_::treble_eq( blip_eq_t const& eq ) void Blip_Synth_::treble_eq( blip_eq_t const& eq )
{ {
float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2]; int blipRes2 = blip_res >> 1;
int const half_size = blip_res / 2 * (width - 1); float fimpulse [blipRes2 * (blip_widest_impulse_ - 1) + blip_res * 2];
int const half_size = blipRes2 * (width - 1);
eq.generate( &fimpulse [blip_res], half_size ); eq.generate( &fimpulse [blip_res], half_size );
int i; int i;
@ -302,25 +300,25 @@ void Blip_Synth_::treble_eq( blip_eq_t const& eq )
fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i]; fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
// starts at 0 // starts at 0
for ( i = 0; i < blip_res; i++ ) for ( i = 0; i < blip_res; ++i )
fimpulse [i] = 0.0f; fimpulse [i] = 0.0f;
// find rescale factor // find rescale factor
double total = 0.0; double total = 0.0;
for ( i = 0; i < half_size; i++ ) for ( i = 0; i < half_size; ++i )
total += fimpulse [blip_res + i]; total += fimpulse [blip_res + i];
//double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB //double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
//double const base_unit = 37888.0; // allows treble to +5 dB //double const base_unit = 37888.0; // allows treble to +5 dB
double const base_unit = 32768.0; // necessary for blip_unscaled to work double const base_unit = 32768.0; // necessary for blip_unscaled to work
double rescale = base_unit / 2 / total; double rescale = base_unit / (2 * total);
kernel_unit = (long) base_unit; kernel_unit = (long) base_unit;
// integrate, first difference, rescale, convert to int // integrate, first difference, rescale, convert to int
double sum = 0.0; double sum = 0.0;
double next = 0.0; double next = 0.0;
int const size = this->impulses_size(); int const size = this->impulses_size();
for ( i = 0; i < size; i++ ) for ( i = 0; i < size; ++i )
{ {
impulses [i] = (short) (int) floor( (next - sum) * rescale + 0.5 ); impulses [i] = (short) (int) floor( (next - sum) * rescale + 0.5 );
sum += fimpulse [i]; sum += fimpulse [i];
@ -355,7 +353,7 @@ void Blip_Synth_::volume_unit( double new_unit )
// if unit is really small, might need to attenuate kernel // if unit is really small, might need to attenuate kernel
while ( factor < 2.0 ) while ( factor < 2.0 )
{ {
shift++; ++shift;
factor *= 2.0; factor *= 2.0;
} }
@ -411,7 +409,7 @@ long Blip_Buffer::read_samples( blip_sample_t* out_, long max_samples, int stere
blip_long s = BLIP_READER_READ( reader ); blip_long s = BLIP_READER_READ( reader );
BLIP_READER_NEXT_IDX_( reader, bass, offset ); BLIP_READER_NEXT_IDX_( reader, bass, offset );
BLIP_CLAMP( s, s ); BLIP_CLAMP( s, s );
out [offset * 2] = (blip_sample_t) s; out [offset << 1] = (blip_sample_t) s;
} }
while ( ++offset ); while ( ++offset );
} }