diff options
author | Timo Wischer <twischer@de.adit-jv.com> | 2018-11-16 11:42:18 +0100 |
---|---|---|
committer | Filipe Coelho <falktx@falktx.com> | 2019-01-17 00:56:39 +0100 |
commit | e75325431353919b1917d96a047a2a195ce01c00 (patch) | |
tree | e3cda95650c3f9230edd2beed1077fd52930fc8d | |
parent | 831163e51640aad2fbda7710c44bc406f167df85 (diff) | |
download | jack2-e75325431353919b1917d96a047a2a195ce01c00.tar.gz |
memops: Use right-aligned S24LE to float conversion
ALSA expects right-aligned samples (0x00******) as mentioned in the
source code for SND_PCM_FORMAT_S24_LE:
Signed 24 bit Little Endian using low three bytes in 32-bit word
See http://git.alsa-project.org/?p=alsa-
lib.git;a=blob;f=include/pcm.h;h=5b0782315585de1d5ab82c9f2036b62c168f5a48;hb=HEAD#l140
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
-rw-r--r-- | common/memops.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/common/memops.c b/common/memops.c index cd9eda1b..a8215a8e 100644 --- a/common/memops.c +++ b/common/memops.c @@ -73,8 +73,8 @@ So, for now (October 2008) we use 2^(N-1)-1 as the scaling factor. */ -#define SAMPLE_24BIT_SCALING 8388607.0f -#define SAMPLE_16BIT_SCALING 32767.0f +#define SAMPLE_24BIT_SCALING 8388607 +#define SAMPLE_16BIT_SCALING 32767 /* these are just values to use if the floating point value was out of range @@ -414,8 +414,10 @@ void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigne void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { + const jack_default_audio_sample_t scaling = 1.0 / (SAMPLE_24BIT_SCALING << 8); + #if defined (__ARM_NEON__) || defined (__ARM_NEON) - float32x4_t factor = vdupq_n_f32(1.0 / SAMPLE_24BIT_SCALING); + float32x4_t factor = vdupq_n_f32(scaling); unsigned long unrolled = nsamples / 4; while (unrolled--) { int32x4_t src128; @@ -435,7 +437,8 @@ void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsign break; } src128 = vreinterpretq_s32_u8(vrev32q_u8(vreinterpretq_u8_s32(src128))); - int32x4_t shifted = vshrq_n_s32(src128, 8); + /* sign extension - left shift will be reverted by scaling */ + int32x4_t shifted = vshlq_n_s32(src128, 8); float32x4_t as_float = vcvtq_f32_s32(shifted); float32x4_t divided = vmulq_f32(as_float, factor); vst1q_f32(dst, divided); @@ -448,8 +451,6 @@ void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsign /* ALERT: signed sign-extension portability !!! */ - const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING; - while (nsamples--) { int x; #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -469,7 +470,8 @@ void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsign x <<= 8; x |= (unsigned char)(src[0]); #endif - *dst = (x >> 8) * scaling; + /* sign extension - left shift will be reverted by scaling */ + *dst = (x << 8) * scaling; dst++; src += src_skip; } @@ -477,10 +479,11 @@ void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsign void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { + const jack_default_audio_sample_t scaling = 1.0 / (SAMPLE_24BIT_SCALING << 8); + #if defined (__SSE2__) && !defined (__sun__) unsigned long unrolled = nsamples / 4; - static float inv_sample_max_24bit = 1.0 / SAMPLE_24BIT_SCALING; - __m128 factor = _mm_set1_ps(inv_sample_max_24bit); + __m128 factor = _mm_set1_ps(scaling); while (unrolled--) { int i1 = *((int *) src); @@ -493,7 +496,8 @@ void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigne src+= src_skip; __m128i src = _mm_set_epi32(i4, i3, i2, i1); - __m128i shifted = _mm_srai_epi32(src, 8); + /* sign extension - left shift will be reverted by scaling */ + __m128i shifted = _mm_slli_epi32(src, 8); __m128 as_float = _mm_cvtepi32_ps(shifted); __m128 divided = _mm_mul_ps(as_float, factor); @@ -505,7 +509,7 @@ void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigne nsamples = nsamples & 3; #elif defined (__ARM_NEON__) || defined (__ARM_NEON) unsigned long unrolled = nsamples / 4; - float32x4_t factor = vdupq_n_f32(1.0 / SAMPLE_24BIT_SCALING); + float32x4_t factor = vdupq_n_f32(scaling); while (unrolled--) { int32x4_t src128; switch(src_skip) { @@ -522,7 +526,8 @@ void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigne src128 = vld1q_lane_s32((int32_t*)(src+3*src_skip), src128, 3); break; } - int32x4_t shifted = vshrq_n_s32(src128, 8); + /* sign extension - left shift will be reverted by scaling */ + int32x4_t shifted = vshlq_n_s32(src128, 8); float32x4_t as_float = vcvtq_f32_s32(shifted); float32x4_t divided = vmulq_f32(as_float, factor); vst1q_f32(dst, divided); @@ -535,9 +540,9 @@ void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigne /* ALERT: signed sign-extension portability !!! */ - const jack_default_audio_sample_t scaling = 1.0/SAMPLE_24BIT_SCALING; while (nsamples--) { - *dst = (*((int *) src) >> 8) * scaling; + /* sign extension - left shift will be reverted by scaling */ + *dst = (*((int *) src) << 8) * scaling; dst++; src += src_skip; } |