diff --git a/drivers/alsa/memops.c b/drivers/alsa/memops.c index b654345..8bb8425 100644 --- a/drivers/alsa/memops.c +++ b/drivers/alsa/memops.c @@ -71,9 +71,13 @@ #define SAMPLE_24BIT_MAX 8388607 #define SAMPLE_24BIT_MIN -8388607 +#define SAMPLE_24BIT_MAX_F 8388607.0f +#define SAMPLE_24BIT_MIN_F -8388607.0f #define SAMPLE_16BIT_MAX 32767 #define SAMPLE_16BIT_MIN -32767 +#define SAMPLE_16BIT_MAX_F 32767.0f +#define SAMPLE_16BIT_MIN_F -32767.0f /* these mark the outer edges of the range considered "within" range for a floating point sample value. values outside (and on the boundaries) @@ -91,6 +95,49 @@ #define f_round(f) lrintf(f) +#define float_16(s, d)\ + if ((s) <= NORMALIZED_FLOAT_MIN) {\ + (d) = SAMPLE_16BIT_MIN;\ + } else if ((s) >= NORMALIZED_FLOAT_MAX) {\ + (d) = SAMPLE_16BIT_MAX;\ + } else {\ + (d) = f_round ((s) * SAMPLE_16BIT_SCALING);\ + } + +/* call this when "s" has already been scaled (e.g. when dithering) + */ + +#define float_16_scaled(s, d)\ + if ((s) <= SAMPLE_16BIT_MIN_F) {\ + (d) = SAMPLE_16BIT_MIN_F;\ + } else if ((s) >= SAMPLE_16BIT_MAX_F) { \ + (d) = SAMPLE_16BIT_MAX;\ + } else {\ + (d) = f_round ((s));\ + } + +#define float_24(s, d) \ + if ((s) <= NORMALIZED_FLOAT_MIN) {\ + (d) = SAMPLE_24BIT_MIN;\ + } else if ((s) >= NORMALIZED_FLOAT_MAX) {\ + (d) = SAMPLE_24BIT_MAX;\ + } else {\ + (d) = f_round ((s) * SAMPLE_24BIT_SCALING) << 8;\ + } + +/* call this when "s" has already been scaled (e.g. when dithering) + */ + +#define float_24_scaled(s, d)\ + if ((s) <= SAMPLE_24BIT_MIN_F) {\ + (d) = SAMPLE_24BIT_MIN;\ + } else if ((s) >= SAMPLE_24BIT_MAX_F) { \ + (d) = SAMPLE_24BIT_MAX; \ + } else {\ + (d) = f_round ((s)) << 8; \ + } + + /* Linear Congruential noise generator. From the music-dsp list * less random than rand(), but good enough and 10x faster */ @@ -151,13 +198,10 @@ void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsign int32_t z; while (nsamples--) { - if (*src <= NORMALIZED_FLOAT_MIN) { - z = SAMPLE_24BIT_MIN; - } else if (*src >= NORMALIZED_FLOAT_MAX) { - z = SAMPLE_24BIT_MAX; - } else { - z = f_round (*src * SAMPLE_24BIT_SCALING) << 8; - } + + float_24 (*src, z); + + #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(z>>24); dst[1]=(char)(z>>16); @@ -177,13 +221,7 @@ void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsign void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { while (nsamples--) { - if (*src <= NORMALIZED_FLOAT_MIN) { - *((int32_t*) dst) = SAMPLE_24BIT_MIN; - } else if (*src >= NORMALIZED_FLOAT_MAX) { - *((int32_t*) dst) = SAMPLE_24BIT_MAX; - } else { - *((int32_t*) dst) = f_round (*src * SAMPLE_24BIT_SCALING) << 8; - } + float_24 (*src, *((int32_t*) dst)); dst += dst_skip; src++; } @@ -234,14 +272,7 @@ void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned int32_t z; while (nsamples--) { - if (*src <= NORMALIZED_FLOAT_MIN) { - z = SAMPLE_24BIT_MIN; - } else if (*src >= NORMALIZED_FLOAT_MAX) { - z = SAMPLE_24BIT_MAX; - } else { - z = (int32_t)f_round (*src * SAMPLE_24BIT_SCALING); - } - + float_24 (*src, z); #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(z>>16); dst[1]=(char)(z>>8); @@ -261,14 +292,7 @@ void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned l int32_t z; while (nsamples--) { - if (*src <= NORMALIZED_FLOAT_MIN) { - z = SAMPLE_24BIT_MIN; - } else if (*src >= NORMALIZED_FLOAT_MAX) { - z = SAMPLE_24BIT_MAX; - } else { - z = (int32_t) f_round (*src * SAMPLE_24BIT_SCALING); - } - + float_24 (*src, z); #if __BYTE_ORDER == __LITTLE_ENDIAN memcpy (dst, &z, 3); #elif __BYTE_ORDER == __BIG_ENDIAN @@ -335,9 +359,9 @@ void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned { int16_t tmp; - /* ALERT: signed sign-extension portability !!! */ - while (nsamples--) { + // float_16 (*src, tmp); + if (*src <= NORMALIZED_FLOAT_MIN) { tmp = SAMPLE_16BIT_MIN; } else if (*src >= NORMALIZED_FLOAT_MAX) { @@ -345,6 +369,7 @@ void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned } else { tmp = (int16_t) f_round (*src * SAMPLE_16BIT_SCALING); } + #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(tmp>>8); dst[1]=(char)(tmp); @@ -359,16 +384,8 @@ void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { - /* ALERT: signed sign-extension portability !!! */ - while (nsamples--) { - if (*src <= NORMALIZED_FLOAT_MIN) { - *((int16_t*) dst) = SAMPLE_16BIT_MIN; - } else if (*src >= NORMALIZED_FLOAT_MAX) { - *((int16_t*) dst) = SAMPLE_16BIT_MAX; - } else { - *((int16_t*) dst) = (int16_t) f_round (*src * SAMPLE_16BIT_SCALING); - } + float_16 (*src, *((int16_t*) dst)); dst += dst_skip; src++; } @@ -380,14 +397,8 @@ void sample_move_dither_rect_d16_sSs (char *dst, jack_default_audio_sample_t *s int16_t tmp; while (nsamples--) { - val = *src - (fast_rand()/((float)INT_MAX-1.0f)); - if (val <= NORMALIZED_FLOAT_MIN) { - tmp = SAMPLE_16BIT_MIN; - } else if (val >= NORMALIZED_FLOAT_MAX) { - tmp = SAMPLE_16BIT_MAX; - } else { - tmp = (int16_t) f_round(*src * SAMPLE_16BIT_SCALING); - } + val = (*src * SAMPLE_16BIT_SCALING) + fast_rand() / (float) INT_MAX - 1.0f; + float_16_scaled (val, tmp); #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(tmp>>8); dst[1]=(char)(tmp); @@ -405,14 +416,8 @@ void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *sr jack_default_audio_sample_t val; while (nsamples--) { - val = *src - (fast_rand()/((float)INT_MAX - 1.0f)); - if (val <= NORMALIZED_FLOAT_MIN) { - *((int16_t*) dst) = SAMPLE_16BIT_MIN; - } else if (val >= NORMALIZED_FLOAT_MAX) { - *((int16_t*) dst) = SAMPLE_16BIT_MAX; - } else { - *((int16_t*) dst) = (int16_t) f_round(*src * SAMPLE_16BIT_SCALING); - } + val = (*src * SAMPLE_16BIT_SCALING) + fast_rand() / (float)INT_MAX - 1.0f; + float_16_scaled (val, *((int16_t*) dst)); dst += dst_skip; src++; } @@ -420,24 +425,17 @@ void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *sr void sample_move_dither_tri_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { - jack_default_audio_sample_t x; + jack_default_audio_sample_t val; float r; float rm1 = state->rm1; int16_t y; while (nsamples--) { - x = *src * SAMPLE_16BIT_SCALING; - r = 2.0f * (float)fast_rand() / (float)INT_MAX - 1.0f; - x += r - rm1; + r = 2.0f * (fast_rand() / (float)INT_MAX - 1.0f); + val = (*src * SAMPLE_16BIT_SCALING) + (r - rm1); rm1 = r; - - if (x <= NORMALIZED_FLOAT_MIN) { - y = SAMPLE_16BIT_MIN; - } else if (x >= NORMALIZED_FLOAT_MAX) { - y = SAMPLE_16BIT_MAX; - } else { - y = f_round(x); - } + + float_16_scaled (*src, y); #if __BYTE_ORDER == __LITTLE_ENDIAN dst[0]=(char)(y>>8); @@ -454,23 +452,17 @@ void sample_move_dither_tri_d16_sSs (char *dst, jack_default_audio_sample_t *sr void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) { - jack_default_audio_sample_t x; + jack_default_audio_sample_t val; float r; float rm1 = state->rm1; while (nsamples--) { - x = *src * SAMPLE_16BIT_SCALING; + r = 2.0f * (float)fast_rand() / (float)INT_MAX - 1.0f; - x += r - rm1; + val = (*src * SAMPLE_16BIT_SCALING) + (r - rm1); rm1 = r; - if (x <= NORMALIZED_FLOAT_MIN) { - *((int16_t*)dst) = SAMPLE_16BIT_MIN; - } else if (x >= NORMALIZED_FLOAT_MAX) { - *((int16_t*)dst) = SAMPLE_16BIT_MAX; - } else { - *((int16_t*)dst) = (int16_t) f_round (x * SAMPLE_16BIT_SCALING); - } + float_16_scaled (val, *((int16_t*) dst)); dst += dst_skip; src++; @@ -502,13 +494,7 @@ void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t xp = xe + r - rm1; rm1 = r; - if (xp <= NORMALIZED_FLOAT_MIN) { - tmp = SAMPLE_16BIT_MIN; - } else if (xp >= NORMALIZED_FLOAT_MAX) { - tmp = SAMPLE_16BIT_MAX; - } else { - tmp = (int16_t) f_round (xp * SAMPLE_16BIT_SCALING); - } + float_16_scaled (xp, tmp); /* Intrinsic z^-1 delay */ idx = (idx + 1) & DITHER_BUF_MASK; @@ -551,13 +537,7 @@ void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t * xp = xe + r - rm1; rm1 = r; - if (xp <= NORMALIZED_FLOAT_MIN) { - *((int16_t*) dst) = SAMPLE_16BIT_MIN; - } else if (xp >= NORMALIZED_FLOAT_MIN) { - *((int16_t*) dst) = SAMPLE_16BIT_MAX; - } else { - *((int16_t*) dst) = (int16_t) f_round (*src * SAMPLE_16BIT_SCALING); - } + float_16_scaled (xp, *((int16_t*) dst)); /* Intrinsic z^-1 delay */ idx = (idx + 1) & DITHER_BUF_MASK;