Skip to content

Commit 07b6d8e

Browse files
claudiocabralClaudio Cabral
authored andcommitted
Add 32 bit support for ALSA driver (#811)
* apply changes without whitespace * remove neon intrinsics and fix indentation * update float_32 macro and fix misspellings * check msbits to determine number of bits in alsa driver * add better error messages and support for SND_PCM_FORMAT_S32_BE * log when sample format is not equal to bits Co-authored-by: Claudio Cabral <clca@bang-olufsen.dk> Co-authored-by: Claudio Cabral <cl@udio.co>
1 parent a03c985 commit 07b6d8e

2 files changed

Lines changed: 101 additions & 4 deletions

File tree

common/memops.c

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
So, for now (October 2008) we use 2^(N-1)-1 as the scaling factor.
7474
*/
7575

76+
#define SAMPLE_32BIT_SCALING 2147483647.0
7677
#define SAMPLE_24BIT_SCALING 8388607.0f
7778
#define SAMPLE_16BIT_SCALING 32767.0f
7879

@@ -81,6 +82,11 @@
8182
advice from Fons Adriaensen: make the limits symmetrical
8283
*/
8384

85+
#define SAMPLE_32BIT_MAX 2147483647
86+
#define SAMPLE_32BIT_MIN -2147483647
87+
#define SAMPLE_32BIT_MAX_D 2147483647.0
88+
#define SAMPLE_32BIT_MIN_D -2147483647.0
89+
8490
#define SAMPLE_24BIT_MAX 8388607
8591
#define SAMPLE_24BIT_MIN -8388607
8692
#define SAMPLE_24BIT_MAX_F 8388607.0f
@@ -106,6 +112,7 @@
106112
*/
107113

108114
#define f_round(f) lrintf(f)
115+
#define d_round(f) lrint(f)
109116

110117
#define float_16(s, d)\
111118
if ((s) <= NORMALIZED_FLOAT_MIN) {\
@@ -146,6 +153,15 @@
146153
(d) = f_round ((s) * SAMPLE_24BIT_SCALING); \
147154
}
148155

156+
#define float_32(s, d) \
157+
do { \
158+
double clipped = fmin(NORMALIZED_FLOAT_MAX, \
159+
fmax((double)(s), NORMALIZED_FLOAT_MIN)); \
160+
double scaled = clipped * SAMPLE_32BIT_MAX_D; \
161+
(d) = d_round(scaled); \
162+
} \
163+
while (0)
164+
149165
/* call this when "s" has already been scaled (e.g. when dithering)
150166
*/
151167

@@ -195,6 +211,11 @@ static inline __m128 clip(__m128 s, __m128 min, __m128 max)
195211
return _mm_min_ps(max, _mm_max_ps(s, min));
196212
}
197213

214+
static inline __m128d clip_double(__m128d s, __m128d min, __m128d max)
215+
{
216+
return _mm_min_pd(max, _mm_max_pd(s, min));
217+
}
218+
198219
static inline __m128i float_24_sse(__m128 s)
199220
{
200221
const __m128 upper_bound = gen_one(); /* NORMALIZED_FLOAT_MAX */
@@ -274,13 +295,14 @@ void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsign
274295
275296
S - sample is a jack_default_audio_sample_t, currently (October 2008) a 32 bit floating point value
276297
Ss - like S but reverse endian from the host CPU
277-
32u24 - sample is an signed 32 bit integer value, but data is in upper 24 bits only
298+
32 - sample is a signed 32 bit integer value
299+
32u24 - sample is a signed 32 bit integer value, but data is in upper 24 bits only
278300
32u24s - like 32u24 but reverse endian from the host CPU
279-
32l24 - sample is an signed 32 bit integer value, but data is in lower 24 bits only
301+
32l24 - sample is a signed 32 bit integer value, but data is in lower 24 bits only
280302
32l24s - like 32l24 but reverse endian from the host CPU
281-
24 - sample is an signed 24 bit integer value
303+
24 - sample is a signed 24 bit integer value
282304
24s - like 24 but reverse endian from the host CPU
283-
16 - sample is an signed 16 bit integer value
305+
16 - sample is a signed 16 bit integer value
284306
16s - like 16 but reverse endian from the host CPU
285307
286308
For obvious reasons, the reverse endian versions only show as source types.
@@ -290,6 +312,36 @@ void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsign
290312

291313
/* functions for native integer sample data */
292314

315+
void sample_move_d32_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
316+
{
317+
while (nsamples--) {
318+
int32_t z;
319+
float_32(*src, z);
320+
#if __BYTE_ORDER == __LITTLE_ENDIAN
321+
dst[0]=(char)(z>>24);
322+
dst[1]=(char)(z>>16);
323+
dst[2]=(char)(z>>8);
324+
dst[3]=(char)(z);
325+
#elif __BYTE_ORDER == __BIG_ENDIAN
326+
dst[0]=(char)(z);
327+
dst[1]=(char)(z>>8);
328+
dst[2]=(char)(z>>16);
329+
dst[3]=(char)(z>>24);
330+
#endif
331+
dst += dst_skip;
332+
src++;
333+
}
334+
}
335+
336+
void sample_move_d32_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
337+
{
338+
while (nsamples--) {
339+
float_32(*src, *(int32_t *)dst);
340+
dst += dst_skip;
341+
src++;
342+
}
343+
}
344+
293345
void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
294346
{
295347
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
@@ -689,6 +741,35 @@ void sample_move_d32l24_sS (char *dst, jack_default_audio_sample_t *src, unsigne
689741
#endif
690742
}
691743

744+
void sample_move_dS_s32s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
745+
{
746+
const jack_default_audio_sample_t scaling = 1.0/SAMPLE_32BIT_SCALING;
747+
while (nsamples--) {
748+
int32_t x;
749+
#if __BYTE_ORDER == __LITTLE_ENDIAN
750+
x = (unsigned char)(src[0]);
751+
x <<= 8;
752+
x |= (unsigned char)(src[1]);
753+
x <<= 8;
754+
x |= (unsigned char)(src[2]);
755+
x <<= 8;
756+
x |= (unsigned char)(src[3]);
757+
#elif __BYTE_ORDER == __BIG_ENDIAN
758+
x = (unsigned char)(src[3]);
759+
x <<= 8;
760+
x |= (unsigned char)(src[2]);
761+
x <<= 8;
762+
x |= (unsigned char)(src[1]);
763+
x <<= 8;
764+
x |= (unsigned char)(src[0]);
765+
#endif
766+
double extended = x * scaling;
767+
*dst = (float)extended;
768+
dst++;
769+
src += src_skip;
770+
}
771+
}
772+
692773
void sample_move_dS_s32l24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
693774
{
694775
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
@@ -753,6 +834,18 @@ void sample_move_dS_s32l24s (jack_default_audio_sample_t *dst, char *src, unsign
753834
}
754835
}
755836

837+
void sample_move_dS_s32 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
838+
{
839+
const double scaling = 1.0 / SAMPLE_32BIT_SCALING;
840+
while (nsamples--) {
841+
int32_t val=(*((int32_t*)src));
842+
double extended = val * scaling;
843+
*dst = (float)extended;
844+
dst++;
845+
src += src_skip;
846+
}
847+
}
848+
756849
void sample_move_dS_s32l24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
757850
{
758851
#if defined (__SSE2__) && !defined (__sun__)

common/memops.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsig
5353
void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
5454

5555
/* integer functions */
56+
void sample_move_d32_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
57+
void sample_move_d32_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
5658
void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
5759
void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
5860
void sample_move_d32l24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
@@ -81,6 +83,8 @@ void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_
8183
void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
8284
void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
8385

86+
void sample_move_dS_s32s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
87+
void sample_move_dS_s32 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
8488
void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
8589
void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
8690
void sample_move_dS_s32l24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);

0 commit comments

Comments
 (0)