From fa95439b985552a134ee84274ea343baf4f9ba8e Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 25 Feb 2012 13:55:38 -0600 Subject: [PATCH 1/2] hairtunes: simplify and reorganize some floating point operations The math operations are all equivalent, but are simplified a bit for the benefit of processors with slower floating point performance. * Don't use float casts when we need to eventually convert to double precision anyway. * Use multiplication instead of division when possible. --- hairtunes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hairtunes.c b/hairtunes.c index 181dd031..0d22a6b3 100644 --- a/hairtunes.c +++ b/hairtunes.c @@ -575,7 +575,7 @@ static void biquad_init(biquad_t *bq, double a[], double b[]) { } static void biquad_lpf(biquad_t *bq, double freq, double Q) { - double w0 = 2*M_PI*freq/((float)sampling_rate/(float)frame_size); + double w0 = 2.0 * M_PI * freq * frame_size / (double)sampling_rate; double alpha = sin(w0)/(2.0*Q); double a_0 = 1.0 + alpha; @@ -706,7 +706,7 @@ static int stuff_buffer(double playback_rate, short *inptr, short *outptr) { p_stuff = 1.0 - pow(1.0 - fabs(playback_rate-1.0), frame_size); - if ((float)rand()/((float)RAND_MAX) < p_stuff) { + if (rand() < p_stuff * RAND_MAX) { stuff = playback_rate > 1.0 ? -1 : 1; stuffsamp = rand() % (frame_size - 1); } From db8b1810388bec8bfd48f449f0428af133f90447 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 25 Feb 2012 13:57:46 -0600 Subject: [PATCH 2/2] hairtunes: implement a simple LCG-based RNG for dithering We are calling out to libc's rand() function, which has significant overhead, especially since we are calling it 88200 times per second (2 channels * 44100 samples). Implement a very simple linear congruential generator in our code that is plenty good enough for dithering purposes, and small enough for the compiler to optimize and inline. --- hairtunes.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hairtunes.c b/hairtunes.c index 0d22a6b3..8b815111 100644 --- a/hairtunes.c +++ b/hairtunes.c @@ -548,6 +548,12 @@ static int init_rtp(void) { return port; } +static short lcg_rand(void) { + static unsigned long lcg_prev = 12345; + lcg_prev = lcg_prev * 69069 + 3; + return lcg_prev & 0xffff; +} + static inline short dithered_vol(short sample) { static short rand_a, rand_b; long out; @@ -555,7 +561,7 @@ static inline short dithered_vol(short sample) { out = (long)sample * fix_volume; if (fix_volume < 0x10000) { rand_b = rand_a; - rand_a = rand() & 0xffff; + rand_a = lcg_rand(); out += rand_a; out -= rand_b; }