summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Wischer <twischer@de.adit-jv.com>2018-11-16 11:42:18 +0100
committerFilipe Coelho <falktx@falktx.com>2019-01-17 00:56:39 +0100
commite75325431353919b1917d96a047a2a195ce01c00 (patch)
treee3cda95650c3f9230edd2beed1077fd52930fc8d
parent831163e51640aad2fbda7710c44bc406f167df85 (diff)
downloadjack2-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.c33
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;
}