Browse Source

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>
tags/v1.9.13
Timo Wischer Filipe Coelho <falktx@falktx.com> 7 years ago
parent
commit
e753254313
1 changed files with 19 additions and 14 deletions
  1. +19
    -14
      common/memops.c

+ 19
- 14
common/memops.c View File

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


Loading…
Cancel
Save