From bc1f9d304f68ac88e388c0fc0f2ad27c49215676 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Wed, 5 May 2021 08:56:59 +0300 Subject: [PATCH] audioconvert: handle S8/S8P raw audio formats --- spa/include/spa/param/audio/raw.h | 1 + spa/include/spa/param/audio/type-info.h | 1 + spa/plugins/audioconvert/fmt-ops-c.c | 113 ++++++++++++++++++++++++ spa/plugins/audioconvert/fmt-ops.c | 15 ++++ spa/plugins/audioconvert/fmt-ops.h | 15 ++++ spa/plugins/audioconvert/fmtconvert.c | 6 +- spa/plugins/audioconvert/merger.c | 5 +- spa/plugins/audioconvert/splitter.c | 6 +- 8 files changed, 159 insertions(+), 3 deletions(-) diff --git a/spa/include/spa/param/audio/raw.h b/spa/include/spa/param/audio/raw.h index 7254c70a7..7689811ae 100644 --- a/spa/include/spa/param/audio/raw.h +++ b/spa/include/spa/param/audio/raw.h @@ -83,6 +83,7 @@ enum spa_audio_format { SPA_AUDIO_FORMAT_S24P, SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F64P, + SPA_AUDIO_FORMAT_S8P, /* other formats start here */ SPA_AUDIO_FORMAT_START_Other = 0x400, diff --git a/spa/include/spa/param/audio/type-info.h b/spa/include/spa/param/audio/type-info.h index f25b7269c..7d1987f45 100644 --- a/spa/include/spa/param/audio/type-info.h +++ b/spa/include/spa/param/audio/type-info.h @@ -75,6 +75,7 @@ static const struct spa_type_info spa_type_audio_format[] = { { SPA_AUDIO_FORMAT_S24P, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_FORMAT_BASE "S24P", NULL }, { SPA_AUDIO_FORMAT_F32P, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_FORMAT_BASE "F32P", NULL }, { SPA_AUDIO_FORMAT_F64P, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_FORMAT_BASE "F64P", NULL }, + { SPA_AUDIO_FORMAT_S8P, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_FORMAT_BASE "S8P", NULL }, #if __BYTE_ORDER == __BIG_ENDIAN { SPA_AUDIO_FORMAT_S16_OE, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_FORMAT_BASE "S16OE", NULL }, diff --git a/spa/plugins/audioconvert/fmt-ops-c.c b/spa/plugins/audioconvert/fmt-ops-c.c index 8000fed54..a39066b76 100644 --- a/spa/plugins/audioconvert/fmt-ops-c.c +++ b/spa/plugins/audioconvert/fmt-ops-c.c @@ -154,6 +154,62 @@ conv_u8d_to_f32_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * } } +void +conv_s8d_to_f32d_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], + uint32_t n_samples) +{ + uint32_t i, j, n_channels = conv->n_channels; + + for (i = 0; i < n_channels; i++) { + const int8_t *s = src[i]; + float *d = dst[i]; + for (j = 0; j < n_samples; j++) + d[j] = S8_TO_F32(s[j]); + } +} + +void +conv_s8_to_f32_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], + uint32_t n_samples) +{ + uint32_t i, n_channels = conv->n_channels; + const int8_t *s = src[0]; + float *d = dst[0]; + + n_samples *= n_channels; + + for (i = 0; i < n_samples; i++) + d[i] = S8_TO_F32(s[i]); +} + +void +conv_s8_to_f32d_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], + uint32_t n_samples) +{ + const int8_t *s = src[0]; + float **d = (float **) dst; + uint32_t i, j, n_channels = conv->n_channels; + + for (j = 0; j < n_samples; j++) { + for (i = 0; i < n_channels; i++) + d[i][j] = S8_TO_F32(*s++); + } +} + +void +conv_s8d_to_f32_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], + uint32_t n_samples) +{ + const int8_t **s = (const int8_t **) src; + float *d = dst[0]; + uint32_t i, j, n_channels = conv->n_channels; + + for (j = 0; j < n_samples; j++) { + for (i = 0; i < n_channels; i++) + *d++ = S8_TO_F32(s[i][j]); + } +} + void conv_s16d_to_f32d_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) @@ -461,6 +517,63 @@ conv_f32d_to_u8_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * } } +void +conv_f32d_to_s8d_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], + uint32_t n_samples) +{ + uint32_t i, j, n_channels = conv->n_channels; + + for (i = 0; i < n_channels; i++) { + const float *s = src[i]; + int8_t *d = dst[i]; + + for (j = 0; j < n_samples; j++) + d[j] = F32_TO_S8(s[j]); + } +} + +void +conv_f32_to_s8_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], + uint32_t n_samples) +{ + uint32_t i, n_channels = conv->n_channels; + const float *s = src[0]; + int8_t *d = dst[0]; + + n_samples *= n_channels; + + for (i = 0; i < n_samples; i++) + d[i] = F32_TO_S8(s[i]); +} + +void +conv_f32_to_s8d_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], + uint32_t n_samples) +{ + const float *s = src[0]; + int8_t **d = (int8_t **) dst; + uint32_t i, j, n_channels = conv->n_channels; + + for (j = 0; j < n_samples; j++) { + for (i = 0; i < n_channels; i++) + d[i][j] = F32_TO_S8(*s++); + } +} + +void +conv_f32d_to_s8_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], + uint32_t n_samples) +{ + const float **s = (const float **) src; + int8_t *d = dst[0]; + uint32_t i, j, n_channels = conv->n_channels; + + for (j = 0; j < n_samples; j++) { + for (i = 0; i < n_channels; i++) + *d++ = F32_TO_S8(s[i][j]); + } +} + void conv_f32d_to_s16d_c(struct convert *conv, void * SPA_RESTRICT dst[], const void * SPA_RESTRICT src[], uint32_t n_samples) diff --git a/spa/plugins/audioconvert/fmt-ops.c b/spa/plugins/audioconvert/fmt-ops.c index f0d9e0538..ea6ffe662 100644 --- a/spa/plugins/audioconvert/fmt-ops.c +++ b/spa/plugins/audioconvert/fmt-ops.c @@ -52,6 +52,10 @@ static struct conv_info conv_table[] = { SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_F32P, 0, 0, conv_u8_to_f32d_c }, { SPA_AUDIO_FORMAT_U8P, SPA_AUDIO_FORMAT_F32, 0, 0, conv_u8d_to_f32_c }, + { SPA_AUDIO_FORMAT_S8, SPA_AUDIO_FORMAT_F32, 0, 0, conv_s8_to_f32_c }, + { SPA_AUDIO_FORMAT_S8P, SPA_AUDIO_FORMAT_F32P, 0, 0, conv_s8d_to_f32d_c }, + { SPA_AUDIO_FORMAT_S8, SPA_AUDIO_FORMAT_F32P, 0, 0, conv_s8_to_f32d_c }, + { SPA_AUDIO_FORMAT_S8P, SPA_AUDIO_FORMAT_F32, 0, 0, conv_s8d_to_f32_c }, { SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_F32, 0, 0, conv_s16_to_f32_c }, { SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_F32P, 0, 0, conv_s16d_to_f32d_c }, @@ -115,6 +119,11 @@ static struct conv_info conv_table[] = { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_U8P, 0, 0, conv_f32_to_u8d_c }, { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_U8, 0, 0, conv_f32d_to_u8_c }, + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S8, 0, 0, conv_f32_to_s8_c }, + { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_S8P, 0, 0, conv_f32d_to_s8d_c }, + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S8P, 0, 0, conv_f32_to_s8d_c }, + { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_S8, 0, 0, conv_f32d_to_s8_c }, + #if defined (HAVE_SSE2) { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S16, 0, SPA_CPU_FLAG_SSE2, conv_f32_to_s16_sse2 }, #endif @@ -170,6 +179,12 @@ static struct conv_info conv_table[] = { SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_U8P, 0, 0, conv_deinterleave_8_c }, { SPA_AUDIO_FORMAT_U8P, SPA_AUDIO_FORMAT_U8, 0, 0, conv_interleave_8_c }, + /* s8 */ + { SPA_AUDIO_FORMAT_S8, SPA_AUDIO_FORMAT_S8, 0, 0, conv_copy8_c }, + { SPA_AUDIO_FORMAT_S8P, SPA_AUDIO_FORMAT_S8P, 0, 0, conv_copy8d_c }, + { SPA_AUDIO_FORMAT_S8, SPA_AUDIO_FORMAT_S8P, 0, 0, conv_deinterleave_8_c }, + { SPA_AUDIO_FORMAT_S8P, SPA_AUDIO_FORMAT_S8, 0, 0, conv_interleave_8_c }, + /* s16 */ { SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S16, 0, 0, conv_copy16_c }, { SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_S16P, 0, 0, conv_copy16d_c }, diff --git a/spa/plugins/audioconvert/fmt-ops.h b/spa/plugins/audioconvert/fmt-ops.h index cfc694967..2dc4809d2 100644 --- a/spa/plugins/audioconvert/fmt-ops.h +++ b/spa/plugins/audioconvert/fmt-ops.h @@ -33,6 +33,13 @@ #define U8_TO_F32(v) ((((uint8_t)(v)) * (1.0f / U8_OFFS)) - 1.0) #define F32_TO_U8(v) (uint8_t)((SPA_CLAMP(v, -1.0f, 1.0f) * U8_SCALE) + U8_OFFS) +#define S8_MIN -127 +#define S8_MAX 127 +#define S8_MAX_F 127.0f +#define S8_SCALE 127.0f +#define S8_TO_F32(v) (((int8_t)(v)) * (1.0f / S8_SCALE)) +#define F32_TO_S8(v) (int8_t)(SPA_CLAMP(v, -1.0f, 1.0f) * S8_SCALE) + #define S16_MIN -32767 #define S16_MAX 32767 #define S16_MAX_F 32767.0f @@ -140,6 +147,10 @@ DEFINE_FUNCTION(u8d_to_f32d, c); DEFINE_FUNCTION(u8_to_f32, c); DEFINE_FUNCTION(u8_to_f32d, c); DEFINE_FUNCTION(u8d_to_f32, c); +DEFINE_FUNCTION(s8d_to_f32d, c); +DEFINE_FUNCTION(s8_to_f32, c); +DEFINE_FUNCTION(s8_to_f32d, c); +DEFINE_FUNCTION(s8d_to_f32, c); DEFINE_FUNCTION(s16d_to_f32d, c); DEFINE_FUNCTION(s16_to_f32, c); DEFINE_FUNCTION(s16_to_f32d, c); @@ -161,6 +172,10 @@ DEFINE_FUNCTION(f32d_to_u8d, c); DEFINE_FUNCTION(f32_to_u8, c); DEFINE_FUNCTION(f32_to_u8d, c); DEFINE_FUNCTION(f32d_to_u8, c); +DEFINE_FUNCTION(f32d_to_s8d, c); +DEFINE_FUNCTION(f32_to_s8, c); +DEFINE_FUNCTION(f32_to_s8d, c); +DEFINE_FUNCTION(f32d_to_s8, c); DEFINE_FUNCTION(f32d_to_s16d, c); DEFINE_FUNCTION(f32_to_s16, c); DEFINE_FUNCTION(f32_to_s16d, c); diff --git a/spa/plugins/audioconvert/fmtconvert.c b/spa/plugins/audioconvert/fmtconvert.c index d99578e57..34eb06b45 100644 --- a/spa/plugins/audioconvert/fmtconvert.c +++ b/spa/plugins/audioconvert/fmtconvert.c @@ -384,7 +384,7 @@ static int port_enum_formats(void *object, info.info.raw.format == SPA_AUDIO_FORMAT_F32P || info.info.raw.format == SPA_AUDIO_FORMAT_F32) { spa_pod_builder_add(builder, - SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(14, + SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(16, info.info.raw.format, SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F32, @@ -397,6 +397,8 @@ static int port_enum_formats(void *object, SPA_AUDIO_FORMAT_S24_OE, SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S8P, + SPA_AUDIO_FORMAT_S8, SPA_AUDIO_FORMAT_U8P, SPA_AUDIO_FORMAT_U8), 0); @@ -567,6 +569,8 @@ static int calc_width(struct spa_audio_info *info) switch (info->info.raw.format) { case SPA_AUDIO_FORMAT_U8P: case SPA_AUDIO_FORMAT_U8: + case SPA_AUDIO_FORMAT_S8P: + case SPA_AUDIO_FORMAT_S8: return 1; case SPA_AUDIO_FORMAT_S16P: case SPA_AUDIO_FORMAT_S16: diff --git a/spa/plugins/audioconvert/merger.c b/spa/plugins/audioconvert/merger.c index 42f5a12b0..e5caa86ad 100644 --- a/spa/plugins/audioconvert/merger.c +++ b/spa/plugins/audioconvert/merger.c @@ -674,7 +674,7 @@ static int port_enum_formats(void *object, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), - SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(14, + SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(16, SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F32, @@ -687,6 +687,8 @@ static int port_enum_formats(void *object, SPA_AUDIO_FORMAT_S24_OE, SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S8P, + SPA_AUDIO_FORMAT_S8, SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_U8P), SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int( @@ -877,6 +879,7 @@ static int calc_width(struct spa_audio_info *info) { switch (info->info.raw.format) { case SPA_AUDIO_FORMAT_U8: + case SPA_AUDIO_FORMAT_S8: return 1; case SPA_AUDIO_FORMAT_S16: case SPA_AUDIO_FORMAT_S16_OE: diff --git a/spa/plugins/audioconvert/splitter.c b/spa/plugins/audioconvert/splitter.c index 9e3cef180..d199dbfcd 100644 --- a/spa/plugins/audioconvert/splitter.c +++ b/spa/plugins/audioconvert/splitter.c @@ -433,7 +433,7 @@ static int port_enum_formats(void *object, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), - SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(14, + SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(16, SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F32, @@ -446,6 +446,8 @@ static int port_enum_formats(void *object, SPA_AUDIO_FORMAT_S24_OE, SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S8P, + SPA_AUDIO_FORMAT_S8, SPA_AUDIO_FORMAT_U8P, SPA_AUDIO_FORMAT_U8), SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int( @@ -638,6 +640,8 @@ static int calc_width(struct spa_audio_info *info) switch (info->info.raw.format) { case SPA_AUDIO_FORMAT_U8: case SPA_AUDIO_FORMAT_U8P: + case SPA_AUDIO_FORMAT_S8: + case SPA_AUDIO_FORMAT_S8P: return 1; case SPA_AUDIO_FORMAT_S16P: case SPA_AUDIO_FORMAT_S16: