Browse Source

macro-ize the core conversions and fix mistakes in dithering cases

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@3050 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.115.6
paul 17 years ago
parent
commit
bf5acc20a2
1 changed files with 73 additions and 93 deletions
  1. +73
    -93
      drivers/alsa/memops.c

+ 73
- 93
drivers/alsa/memops.c View File

@@ -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;


Loading…
Cancel
Save