diff --git a/spa/include/spa/param/audio/format-utils.h b/spa/include/spa/param/audio/format-utils.h index 0b5aab5a1..d35f4a621 100644 --- a/spa/include/spa/param/audio/format-utils.h +++ b/spa/include/spa/param/audio/format-utils.h @@ -33,29 +33,41 @@ extern "C" { static inline int spa_format_audio_raw_parse(const struct spa_pod *format, struct spa_audio_info_raw *info) { - return spa_pod_object_parse(format, + struct spa_pod *position = NULL; + int res; + res = spa_pod_object_parse(format, ":", SPA_FORMAT_AUDIO_format, "I", &info->format, - ":", SPA_FORMAT_AUDIO_layout, "I", &info->layout, ":", SPA_FORMAT_AUDIO_rate, "i", &info->rate, ":", SPA_FORMAT_AUDIO_channels, "i", &info->channels, ":", SPA_FORMAT_AUDIO_flags, "?i", &info->flags, - ":", SPA_FORMAT_AUDIO_channelMask, "?l", &info->channel_mask, NULL); + ":", SPA_FORMAT_AUDIO_position, "?P", &position, NULL); + if (position && position->type == SPA_TYPE_Array && + SPA_POD_ARRAY_TYPE(position) == SPA_TYPE_Id) { + uint32_t *values = SPA_POD_ARRAY_VALUES(position); + uint32_t n_values = SPA_MIN(SPA_POD_ARRAY_N_VALUES(position), SPA_AUDIO_MAX_CHANNELS); + memcpy(info->position, values, n_values * sizeof(uint32_t)); + } + return res; } static inline struct spa_pod * spa_format_audio_raw_build(struct spa_pod_builder *builder, uint32_t id, struct spa_audio_info_raw *info) { - return spa_pod_builder_object(builder, - SPA_TYPE_OBJECT_Format, id, + spa_pod_builder_push_object(builder, SPA_TYPE_OBJECT_Format, id); + spa_pod_builder_props(builder, 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_Id(info->format), - SPA_FORMAT_AUDIO_layout, &SPA_POD_Id(info->layout), SPA_FORMAT_AUDIO_rate, &SPA_POD_Int(info->rate), SPA_FORMAT_AUDIO_channels, &SPA_POD_Int(info->channels), 0); + + spa_pod_builder_prop(builder, SPA_FORMAT_AUDIO_position, 0); + spa_pod_builder_array(builder, sizeof(uint32_t), SPA_TYPE_Id, info->channels, info->position); + return spa_pod_builder_pop(builder); } + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/spa/include/spa/param/audio/raw.h b/spa/include/spa/param/audio/raw.h index eebfbf941..edc3eddd4 100644 --- a/spa/include/spa/param/audio/raw.h +++ b/spa/include/spa/param/audio/raw.h @@ -26,9 +26,14 @@ extern "C" { #include +#define SPA_AUDIO_MAX_CHANNELS 64 + enum spa_audio_format { SPA_AUDIO_FORMAT_UNKNOWN, SPA_AUDIO_FORMAT_ENCODED, + + /* interleaved formats */ + SPA_AUDIO_FORMAT_START_Interleaved = 0x100, SPA_AUDIO_FORMAT_S8, SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_S16_LE, @@ -60,6 +65,18 @@ enum spa_audio_format { SPA_AUDIO_FORMAT_F64_LE, SPA_AUDIO_FORMAT_F64_BE, + /* planar formats */ + SPA_AUDIO_FORMAT_START_Planar = 0x200, + SPA_AUDIO_FORMAT_U8P, + SPA_AUDIO_FORMAT_S16P, + SPA_AUDIO_FORMAT_S24_32P, + SPA_AUDIO_FORMAT_S32P, + SPA_AUDIO_FORMAT_S24P, + SPA_AUDIO_FORMAT_F32P, + SPA_AUDIO_FORMAT_F64P, + + SPA_AUDIO_FORMAT_START_Other = 0x300, + #if __BYTE_ORDER == __BIG_ENDIAN SPA_AUDIO_FORMAT_S16 = SPA_AUDIO_FORMAT_S16_BE, SPA_AUDIO_FORMAT_U16 = SPA_AUDIO_FORMAT_U16_BE, @@ -121,26 +138,97 @@ enum spa_audio_format { #endif }; +#define SPA_AUDIO_FORMAT_IS_INTERLEAVED(fmt) ((fmt) > SPA_AUDIO_FORMAT_START_Interleaved && (fmt) < SPA_AUDIO_FORMAT_START_Planar) +#define SPA_AUDIO_FORMAT_IS_PLANAR(fmt) ((fmt) > SPA_AUDIO_FORMAT_START_Planar && (fmt) < SPA_AUDIO_FORMAT_START_Other) + +enum spa_audio_channel { + SPA_AUDIO_CHANNEL_UNKNOWN, /**< unspecified */ + SPA_AUDIO_CHANNEL_NA, /**< N/A, silent */ + SPA_AUDIO_CHANNEL_MONO, /**< mono stream */ + SPA_AUDIO_CHANNEL_FL, /**< front left */ + SPA_AUDIO_CHANNEL_FR, /**< front right */ + SPA_AUDIO_CHANNEL_RL, /**< rear left */ + SPA_AUDIO_CHANNEL_RR, /**< rear right */ + SPA_AUDIO_CHANNEL_FC, /**< front center */ + SPA_AUDIO_CHANNEL_LFE, /**< LFE */ + SPA_AUDIO_CHANNEL_SL, /**< side left */ + SPA_AUDIO_CHANNEL_SR, /**< side right */ + SPA_AUDIO_CHANNEL_RC, /**< rear center */ + SPA_AUDIO_CHANNEL_FLC, /**< front left center */ + SPA_AUDIO_CHANNEL_FRC, /**< front right center */ + SPA_AUDIO_CHANNEL_RLC, /**< rear left center */ + SPA_AUDIO_CHANNEL_RRC, /**< rear right center */ + SPA_AUDIO_CHANNEL_FLW, /**< front left wide */ + SPA_AUDIO_CHANNEL_FRW, /**< front right wide */ + SPA_AUDIO_CHANNEL_FLH, /**< front left high */ + SPA_AUDIO_CHANNEL_FCH, /**< front center high */ + SPA_AUDIO_CHANNEL_FRH, /**< front right high */ + SPA_AUDIO_CHANNEL_TC, /**< top center */ + SPA_AUDIO_CHANNEL_TFL, /**< top front left */ + SPA_AUDIO_CHANNEL_TFR, /**< top front right */ + SPA_AUDIO_CHANNEL_TFC, /**< top front center */ + SPA_AUDIO_CHANNEL_TRL, /**< top rear left */ + SPA_AUDIO_CHANNEL_TRR, /**< top rear right */ + SPA_AUDIO_CHANNEL_TRC, /**< top rear center */ + SPA_AUDIO_CHANNEL_TFLC, /**< top front left center */ + SPA_AUDIO_CHANNEL_TFRC, /**< top front right center */ + SPA_AUDIO_CHANNEL_TSL, /**< top side left */ + SPA_AUDIO_CHANNEL_TSR, /**< top side right */ + SPA_AUDIO_CHANNEL_LLFE, /**< left LFE */ + SPA_AUDIO_CHANNEL_RLFE, /**< right LFE */ + SPA_AUDIO_CHANNEL_BC, /**< bottom center */ + SPA_AUDIO_CHANNEL_BLC, /**< bottom left center */ + SPA_AUDIO_CHANNEL_BRC, /**< bottom right center */ + + SPA_AUDIO_CHANNEL_CUSTOM_START = 0x10000, +}; + +#define SPA_AUDIO_CHANNEL_MASK(ch) (1LL << SPA_AUDIO_CHANNEL_ ## ch) + +enum spa_audio_layout { + SPA_AUDIO_LAYOUT_DEFAULT, /**< default layout for the number of channels */ + SPA_AUDIO_LAYOUT_CUSTOM, /**< custom layout, either the order of the channels is + * non-standard or the channel position array contains + * custom channels. */ + SPA_AUDIO_LAYOUT_MONO, /**< MONO */ + SPA_AUDIO_LAYOUT_STEREO, /**< FL FR */ + SPA_AUDIO_LAYOUT_2_1, /**< FL FR LFE */ + SPA_AUDIO_LAYOUT_2RC, /**< FL FR RC */ + SPA_AUDIO_LAYOUT_2FC, /**< FL FR FC */ + SPA_AUDIO_LAYOUT_3_1, /**< FL FR FC LFE */ + SPA_AUDIO_LAYOUT_4_0, /**< FL FR FC RC */ + SPA_AUDIO_LAYOUT_4_1, /**< FL FR FC RC LFE */ + SPA_AUDIO_LAYOUT_2_2, /**< FL FR SL SR */ + SPA_AUDIO_LAYOUT_QUAD, /**< FL FR RL RR */ + SPA_AUDIO_LAYOUT_5_0, /**< FL FR FC SL SR */ + SPA_AUDIO_LAYOUT_5_1, /**< FL FR FC SL SR LFE */ + SPA_AUDIO_LAYOUT_5_0R, /**< FL FR FC RL RR */ + SPA_AUDIO_LAYOUT_5_1R, /**< FL FR FC RL RR LFE */ + SPA_AUDIO_LAYOUT_6_0, /**< FL FR FC SL SR RC */ + SPA_AUDIO_LAYOUT_6_0F, /**< FL FR SL SR FLC FRC */ + SPA_AUDIO_LAYOUT_HEXAGONAL, /**< FL FR FC RL RR RC */ + SPA_AUDIO_LAYOUT_6_1, /**< FL FR FC SL SR LFE RC */ + SPA_AUDIO_LAYOUT_6_1R, /**< FL FR FC RL RR LFE RC */ + SPA_AUDIO_LAYOUT_6_1F, /**< FL FR SL SR FLC FRC LFE */ + SPA_AUDIO_LAYOUT_7_0, /**< FL FR FC SL SR RL RR */ + SPA_AUDIO_LAYOUT_7_0F, /**< FL FR FC SL SR FLC FRC */ + SPA_AUDIO_LAYOUT_7_1, /**< FL FR FC SL SR LFE RL RR */ + SPA_AUDIO_LAYOUT_7_1W, /**< FL FR FC SL SR LFE FLC FRC */ + SPA_AUDIO_LAYOUT_7_1WR, /**< FL FR FC RL RR LFE FLC FRC */ + SPA_AUDIO_LAYOUT_OCTAGONAL, /**< FL FR FC SL SR RL RC RR */ +}; + /** Extra audio flags */ #define SPA_AUDIO_FLAG_NONE (0) /*< no valid flag */ #define SPA_AUDIO_FLAG_UNPOSITIONED (1 << 0) /*< the position array explicitly * contains unpositioned channels. */ - -/** Layout of the audio samples for the different channels. */ -enum spa_audio_layout { - SPA_AUDIO_LAYOUT_INVALID, - SPA_AUDIO_LAYOUT_INTERLEAVED, /*< interleaved audio */ - SPA_AUDIO_LAYOUT_NON_INTERLEAVED, /*< non-interleaved audio */ -}; - /** Audio information description */ struct spa_audio_info_raw { - enum spa_audio_format format; /*< format, one of enum spa_audio_format */ - uint32_t flags; /*< extra flags */ - enum spa_audio_layout layout; /*< sample layout */ - uint32_t rate; /*< sample rate */ - uint32_t channels; /*< number of channels */ - uint64_t channel_mask; /*< channel mask */ + enum spa_audio_format format; /*< format, one of enum spa_audio_format */ + uint32_t flags; /*< extra flags */ + uint32_t rate; /*< sample rate */ + uint32_t channels; /*< number of channels */ + uint32_t position[SPA_AUDIO_MAX_CHANNELS]; /*< channel position from enum spa_audio_channel */ }; #define SPA_AUDIO_INFO_RAW_INIT(...) (struct spa_audio_info_raw) { __VA_ARGS__ } diff --git a/spa/include/spa/param/audio/type-info.h b/spa/include/spa/param/audio/type-info.h index 6ca641598..905e142a1 100644 --- a/spa/include/spa/param/audio/type-info.h +++ b/spa/include/spa/param/audio/type-info.h @@ -62,6 +62,15 @@ static const struct spa_type_info spa_type_audio_format[] = { { SPA_AUDIO_FORMAT_F32_BE, SPA_TYPE_AUDIO_FORMAT_BASE "F32BE", SPA_TYPE_Int, }, { SPA_AUDIO_FORMAT_F64_LE, SPA_TYPE_AUDIO_FORMAT_BASE "F64LE", SPA_TYPE_Int, }, { SPA_AUDIO_FORMAT_F64_BE, SPA_TYPE_AUDIO_FORMAT_BASE "F64BE", SPA_TYPE_Int, }, + + { SPA_AUDIO_FORMAT_U8P, SPA_TYPE_AUDIO_FORMAT_BASE "U8P", SPA_TYPE_Int, }, + { SPA_AUDIO_FORMAT_S16P, SPA_TYPE_AUDIO_FORMAT_BASE "S16P", SPA_TYPE_Int, }, + { SPA_AUDIO_FORMAT_S24_32P, SPA_TYPE_AUDIO_FORMAT_BASE "S24_32P", SPA_TYPE_Int, }, + { SPA_AUDIO_FORMAT_S32P, SPA_TYPE_AUDIO_FORMAT_BASE "S32P", SPA_TYPE_Int, }, + { SPA_AUDIO_FORMAT_S24P, SPA_TYPE_AUDIO_FORMAT_BASE "S24P", SPA_TYPE_Int, }, + { SPA_AUDIO_FORMAT_F32P, SPA_TYPE_AUDIO_FORMAT_BASE "F32P", SPA_TYPE_Int, }, + { SPA_AUDIO_FORMAT_F64P, SPA_TYPE_AUDIO_FORMAT_BASE "F64P", SPA_TYPE_Int, }, + { 0, NULL, }, }; @@ -74,14 +83,83 @@ static const struct spa_type_info spa_type_audio_flags[] = { { 0, NULL, }, }; +#define SPA_TYPE__AudioChannel SPA_TYPE_ENUM_BASE "AudioChannel" +#define SPA_TYPE_AUDIO_CHANNEL_BASE SPA_TYPE__AudioChannel ":" + +static const struct spa_type_info spa_type_audio_channel[] = { + { SPA_AUDIO_CHANNEL_UNKNOWN, SPA_TYPE_AUDIO_CHANNEL_BASE "UNK", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_NA, SPA_TYPE_AUDIO_CHANNEL_BASE "NA", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_MONO, SPA_TYPE_AUDIO_CHANNEL_BASE "MONO", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_FL, SPA_TYPE_AUDIO_CHANNEL_BASE "FL", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_FR, SPA_TYPE_AUDIO_CHANNEL_BASE "FR", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_RL, SPA_TYPE_AUDIO_CHANNEL_BASE "RL", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_RR, SPA_TYPE_AUDIO_CHANNEL_BASE "RR", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_FC, SPA_TYPE_AUDIO_CHANNEL_BASE "FC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_LFE, SPA_TYPE_AUDIO_CHANNEL_BASE "LFE", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_SL, SPA_TYPE_AUDIO_CHANNEL_BASE "SL", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_SR, SPA_TYPE_AUDIO_CHANNEL_BASE "SR", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_RC, SPA_TYPE_AUDIO_CHANNEL_BASE "RC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_FLC, SPA_TYPE_AUDIO_CHANNEL_BASE "FLC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_FRC, SPA_TYPE_AUDIO_CHANNEL_BASE "FRC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_RLC, SPA_TYPE_AUDIO_CHANNEL_BASE "RLC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_RRC, SPA_TYPE_AUDIO_CHANNEL_BASE "RRC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_FLW, SPA_TYPE_AUDIO_CHANNEL_BASE "FLW", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_FRW, SPA_TYPE_AUDIO_CHANNEL_BASE "FRW", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_FLH, SPA_TYPE_AUDIO_CHANNEL_BASE "FLH", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_FCH, SPA_TYPE_AUDIO_CHANNEL_BASE "FCH", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_FRH, SPA_TYPE_AUDIO_CHANNEL_BASE "FRH", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TC, SPA_TYPE_AUDIO_CHANNEL_BASE "TC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TFL, SPA_TYPE_AUDIO_CHANNEL_BASE "TFL", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TFR, SPA_TYPE_AUDIO_CHANNEL_BASE "TFR", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TFC, SPA_TYPE_AUDIO_CHANNEL_BASE "TFC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TRL, SPA_TYPE_AUDIO_CHANNEL_BASE "TRL", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TRR, SPA_TYPE_AUDIO_CHANNEL_BASE "TRR", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TRC, SPA_TYPE_AUDIO_CHANNEL_BASE "TRC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TFLC, SPA_TYPE_AUDIO_CHANNEL_BASE "TFLC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TFRC, SPA_TYPE_AUDIO_CHANNEL_BASE "TFRC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TSL, SPA_TYPE_AUDIO_CHANNEL_BASE "TSL", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_TSR, SPA_TYPE_AUDIO_CHANNEL_BASE "TSR", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_LLFE, SPA_TYPE_AUDIO_CHANNEL_BASE "LLFR", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_RLFE, SPA_TYPE_AUDIO_CHANNEL_BASE "RLFE", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_BC, SPA_TYPE_AUDIO_CHANNEL_BASE "BC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_BLC, SPA_TYPE_AUDIO_CHANNEL_BASE "BLC", SPA_TYPE_Int, }, + { SPA_AUDIO_CHANNEL_BRC, SPA_TYPE_AUDIO_CHANNEL_BASE "BRC", SPA_TYPE_Int, }, + { 0, NULL, }, +}; + #define SPA_TYPE__AudioLayout SPA_TYPE_ENUM_BASE "AudioLayout" -#define SPA_TYPE_AUDIO_ENUM_BASE SPA_TYPE__AudioLayout ":" +#define SPA_TYPE_AUDIO_LAYOUT_BASE SPA_TYPE__AudioLayout ":" static const struct spa_type_info spa_type_audio_layout[] = { - { SPA_AUDIO_LAYOUT_INVALID, SPA_TYPE_AUDIO_ENUM_BASE "Invalid", SPA_TYPE_Int, }, - { SPA_AUDIO_LAYOUT_INTERLEAVED, SPA_TYPE_AUDIO_ENUM_BASE "Interleaved", SPA_TYPE_Int, }, - { SPA_AUDIO_LAYOUT_NON_INTERLEAVED, SPA_TYPE_AUDIO_ENUM_BASE "Non-Interleaved", SPA_TYPE_Int, }, - { 0, NULL, }, + { SPA_AUDIO_LAYOUT_DEFAULT, SPA_TYPE_AUDIO_LAYOUT_BASE "Default", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_CUSTOM, SPA_TYPE_AUDIO_LAYOUT_BASE "Custom", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_MONO, SPA_TYPE_AUDIO_LAYOUT_BASE "Mono", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_STEREO, SPA_TYPE_AUDIO_LAYOUT_BASE "Stereo", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_2_1, SPA_TYPE_AUDIO_LAYOUT_BASE "2.1", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_2RC, SPA_TYPE_AUDIO_LAYOUT_BASE "2.1 Rear", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_2FC, SPA_TYPE_AUDIO_LAYOUT_BASE "2.1 Front", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_3_1, SPA_TYPE_AUDIO_LAYOUT_BASE "3.1", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_4_0, SPA_TYPE_AUDIO_LAYOUT_BASE "4.0", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_4_1, SPA_TYPE_AUDIO_LAYOUT_BASE "4.1", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_2_2, SPA_TYPE_AUDIO_LAYOUT_BASE "2.2", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_QUAD, SPA_TYPE_AUDIO_LAYOUT_BASE "Quad", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_5_0, SPA_TYPE_AUDIO_LAYOUT_BASE "5.0", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_5_1, SPA_TYPE_AUDIO_LAYOUT_BASE "5.1", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_5_0R, SPA_TYPE_AUDIO_LAYOUT_BASE "5.0 Rear", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_5_1R, SPA_TYPE_AUDIO_LAYOUT_BASE "5.1 Rear", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_6_0, SPA_TYPE_AUDIO_LAYOUT_BASE "6.0", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_6_0F, SPA_TYPE_AUDIO_LAYOUT_BASE "6.0 Front", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_HEXAGONAL, SPA_TYPE_AUDIO_LAYOUT_BASE "Hexagonal", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_6_1, SPA_TYPE_AUDIO_LAYOUT_BASE "6.1", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_6_1R, SPA_TYPE_AUDIO_LAYOUT_BASE "6.1 Rear", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_6_1F, SPA_TYPE_AUDIO_LAYOUT_BASE "6.1 Front", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_7_0, SPA_TYPE_AUDIO_LAYOUT_BASE "7.0", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_7_0F, SPA_TYPE_AUDIO_LAYOUT_BASE "7.0 Front", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_7_1, SPA_TYPE_AUDIO_LAYOUT_BASE "7.1", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_7_1W, SPA_TYPE_AUDIO_LAYOUT_BASE "7.1 Wide", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_7_1WR, SPA_TYPE_AUDIO_LAYOUT_BASE "7.1 Wide Rear", SPA_TYPE_Int, }, + { SPA_AUDIO_LAYOUT_OCTAGONAL, SPA_TYPE_AUDIO_LAYOUT_BASE "Octagonal", SPA_TYPE_Int, }, + { 0, NULL, }, }; #ifdef __cplusplus diff --git a/spa/include/spa/param/format.h b/spa/include/spa/param/format.h index 5b97f4732..0e6a7c28e 100644 --- a/spa/include/spa/param/format.h +++ b/spa/include/spa/param/format.h @@ -88,12 +88,11 @@ enum spa_format { /* Audio format keys */ SPA_FORMAT_START_Audio, - SPA_FORMAT_AUDIO_format, + SPA_FORMAT_AUDIO_format, /**< audio format, one of enum spa_audio_format */ SPA_FORMAT_AUDIO_flags, - SPA_FORMAT_AUDIO_layout, SPA_FORMAT_AUDIO_rate, - SPA_FORMAT_AUDIO_channels, - SPA_FORMAT_AUDIO_channelMask, + SPA_FORMAT_AUDIO_channels, /**< number of audio channels */ + SPA_FORMAT_AUDIO_position, /**< channel positions one of enum spa_audio_position */ /* Video Format keys */ SPA_FORMAT_START_Video = 0x10000, diff --git a/spa/include/spa/param/type-info.h b/spa/include/spa/param/type-info.h index 84ed4040b..67db1f69e 100644 --- a/spa/include/spa/param/type-info.h +++ b/spa/include/spa/param/type-info.h @@ -209,11 +209,9 @@ static const struct spa_type_info spa_type_format[] = { spa_type_audio_format }, { SPA_FORMAT_AUDIO_flags, SPA_TYPE_FORMAT_AUDIO_BASE "flags", SPA_TYPE_Id, spa_type_audio_flags }, - { SPA_FORMAT_AUDIO_layout, SPA_TYPE_FORMAT_AUDIO_BASE "layout", SPA_TYPE_Id, - spa_type_audio_layout }, { SPA_FORMAT_AUDIO_rate, SPA_TYPE_FORMAT_AUDIO_BASE "rate", SPA_TYPE_Int, }, { SPA_FORMAT_AUDIO_channels, SPA_TYPE_FORMAT_AUDIO_BASE "channels", SPA_TYPE_Int, }, - { SPA_FORMAT_AUDIO_channelMask, SPA_TYPE_FORMAT_AUDIO_BASE "channelMask", SPA_TYPE_Int, }, + { SPA_FORMAT_AUDIO_position, SPA_TYPE_FORMAT_AUDIO_BASE "position", SPA_TYPE_Id, spa_type_audio_channel }, { SPA_FORMAT_VIDEO_format, SPA_TYPE_FORMAT_VIDEO_BASE "format", SPA_TYPE_Id, spa_type_video_format, }, diff --git a/spa/include/spa/pod/pod.h b/spa/include/spa/pod/pod.h index 38df6fdbc..48613ca91 100644 --- a/spa/include/spa/pod/pod.h +++ b/spa/include/spa/pod/pod.h @@ -113,6 +113,7 @@ struct spa_pod_bitmap { #define SPA_POD_ARRAY_TYPE(arr) (SPA_POD_TYPE(SPA_POD_ARRAY_CHILD(arr))) #define SPA_POD_ARRAY_SIZE(arr) (SPA_POD_BODY_SIZE(SPA_POD_ARRAY_CHILD(arr))) #define SPA_POD_ARRAY_N_VALUES(arr) ((SPA_POD_BODY_SIZE(arr) - sizeof(struct spa_pod_array_body)) / SPA_POD_ARRAY_SIZE(arr)) +#define SPA_POD_ARRAY_VALUES(arr) SPA_POD_CONTENTS(struct spa_pod_array, arr) struct spa_pod_array_body { struct spa_pod child; diff --git a/spa/plugins/alsa/alsa-utils.c b/spa/plugins/alsa/alsa-utils.c index 069e61f92..20869d216 100644 --- a/spa/plugins/alsa/alsa-utils.c +++ b/spa/plugins/alsa/alsa-utils.c @@ -58,33 +58,34 @@ int spa_alsa_close(struct state *state) struct format_info { uint32_t spa_format; + uint32_t spa_pformat; snd_pcm_format_t format; }; static const struct format_info format_info[] = { - { SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_UNKNOWN}, - { SPA_AUDIO_FORMAT_S8, SND_PCM_FORMAT_S8}, - { SPA_AUDIO_FORMAT_U8, SND_PCM_FORMAT_U8}, - { SPA_AUDIO_FORMAT_S16_LE, SND_PCM_FORMAT_S16_LE}, - { SPA_AUDIO_FORMAT_S16_BE, SND_PCM_FORMAT_S16_BE}, - { SPA_AUDIO_FORMAT_U16_LE, SND_PCM_FORMAT_U16_LE}, - { SPA_AUDIO_FORMAT_U16_BE, SND_PCM_FORMAT_U16_BE}, - { SPA_AUDIO_FORMAT_S24_32_LE, SND_PCM_FORMAT_S24_LE}, - { SPA_AUDIO_FORMAT_S24_32_BE, SND_PCM_FORMAT_S24_BE}, - { SPA_AUDIO_FORMAT_U24_32_LE, SND_PCM_FORMAT_U24_LE}, - { SPA_AUDIO_FORMAT_U24_32_BE, SND_PCM_FORMAT_U24_BE}, - { SPA_AUDIO_FORMAT_S24_LE, SND_PCM_FORMAT_S24_3LE}, - { SPA_AUDIO_FORMAT_S24_BE, SND_PCM_FORMAT_S24_3BE}, - { SPA_AUDIO_FORMAT_U24_LE, SND_PCM_FORMAT_U24_3LE}, - { SPA_AUDIO_FORMAT_U24_BE, SND_PCM_FORMAT_U24_3BE}, - { SPA_AUDIO_FORMAT_S32_LE, SND_PCM_FORMAT_S32_LE}, - { SPA_AUDIO_FORMAT_S32_BE, SND_PCM_FORMAT_S32_BE}, - { SPA_AUDIO_FORMAT_U32_LE, SND_PCM_FORMAT_U32_LE}, - { SPA_AUDIO_FORMAT_U32_BE, SND_PCM_FORMAT_U32_BE}, - { SPA_AUDIO_FORMAT_F32_LE, SND_PCM_FORMAT_FLOAT_LE}, - { SPA_AUDIO_FORMAT_F32_BE, SND_PCM_FORMAT_FLOAT_BE}, - { SPA_AUDIO_FORMAT_F64_LE, SND_PCM_FORMAT_FLOAT64_LE}, - { SPA_AUDIO_FORMAT_F64_BE, SND_PCM_FORMAT_FLOAT64_BE}, + { SPA_AUDIO_FORMAT_UNKNOWN, SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_UNKNOWN}, + { SPA_AUDIO_FORMAT_S8, SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_S8}, + { SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_U8P, SND_PCM_FORMAT_U8}, + { SPA_AUDIO_FORMAT_S16_LE, SPA_AUDIO_FORMAT_S16P, SND_PCM_FORMAT_S16_LE}, + { SPA_AUDIO_FORMAT_S16_BE, SPA_AUDIO_FORMAT_S16P, SND_PCM_FORMAT_S16_BE}, + { SPA_AUDIO_FORMAT_U16_LE, SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_U16_LE}, + { SPA_AUDIO_FORMAT_U16_BE, SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_U16_BE}, + { SPA_AUDIO_FORMAT_S24_32_LE, SPA_AUDIO_FORMAT_S24_32P, SND_PCM_FORMAT_S24_LE}, + { SPA_AUDIO_FORMAT_S24_32_BE, SPA_AUDIO_FORMAT_S24_32P, SND_PCM_FORMAT_S24_BE}, + { SPA_AUDIO_FORMAT_U24_32_LE, SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_U24_LE}, + { SPA_AUDIO_FORMAT_U24_32_BE, SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_U24_BE}, + { SPA_AUDIO_FORMAT_S24_LE, SPA_AUDIO_FORMAT_S24P, SND_PCM_FORMAT_S24_3LE}, + { SPA_AUDIO_FORMAT_S24_BE, SPA_AUDIO_FORMAT_S24P, SND_PCM_FORMAT_S24_3BE}, + { SPA_AUDIO_FORMAT_U24_LE, SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_U24_3LE}, + { SPA_AUDIO_FORMAT_U24_BE, SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_U24_3BE}, + { SPA_AUDIO_FORMAT_S32_LE, SPA_AUDIO_FORMAT_S32P, SND_PCM_FORMAT_S32_LE}, + { SPA_AUDIO_FORMAT_S32_BE, SPA_AUDIO_FORMAT_S32P, SND_PCM_FORMAT_S32_BE}, + { SPA_AUDIO_FORMAT_U32_LE, SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_U32_LE}, + { SPA_AUDIO_FORMAT_U32_BE, SPA_AUDIO_FORMAT_UNKNOWN, SND_PCM_FORMAT_U32_BE}, + { SPA_AUDIO_FORMAT_F32_LE, SPA_AUDIO_FORMAT_F32P, SND_PCM_FORMAT_FLOAT_LE}, + { SPA_AUDIO_FORMAT_F32_BE, SPA_AUDIO_FORMAT_F32P, SND_PCM_FORMAT_FLOAT_BE}, + { SPA_AUDIO_FORMAT_F64_LE, SPA_AUDIO_FORMAT_F64P, SND_PCM_FORMAT_FLOAT64_LE}, + { SPA_AUDIO_FORMAT_F64_BE, SPA_AUDIO_FORMAT_F64P, SND_PCM_FORMAT_FLOAT64_BE}, }; static snd_pcm_format_t spa_format_to_alsa(uint32_t format) @@ -98,48 +99,54 @@ static snd_pcm_format_t spa_format_to_alsa(uint32_t format) return SND_PCM_FORMAT_UNKNOWN; } -static uint64_t map_to_mask(snd_pcm_chmap_t* map) +struct chmap_info { + enum snd_pcm_chmap_position pos; + enum spa_audio_channel channel; +}; + +static const struct chmap_info chmap_info[] = { + [SND_CHMAP_UNKNOWN] = { SND_CHMAP_UNKNOWN, SPA_AUDIO_CHANNEL_UNKNOWN }, + [SND_CHMAP_NA] = { SND_CHMAP_NA, SPA_AUDIO_CHANNEL_NA }, + [SND_CHMAP_MONO] = { SND_CHMAP_MONO, SPA_AUDIO_CHANNEL_MONO }, + [SND_CHMAP_FL] = { SND_CHMAP_FL, SPA_AUDIO_CHANNEL_FL }, + [SND_CHMAP_FR] = { SND_CHMAP_FR, SPA_AUDIO_CHANNEL_FR }, + [SND_CHMAP_RL] = { SND_CHMAP_RL, SPA_AUDIO_CHANNEL_RL }, + [SND_CHMAP_RR] = { SND_CHMAP_RR, SPA_AUDIO_CHANNEL_RR }, + [SND_CHMAP_FC] = { SND_CHMAP_FC, SPA_AUDIO_CHANNEL_FC }, + [SND_CHMAP_LFE] = { SND_CHMAP_LFE, SPA_AUDIO_CHANNEL_LFE }, + [SND_CHMAP_SL] = { SND_CHMAP_SL, SPA_AUDIO_CHANNEL_SL }, + [SND_CHMAP_SR] = { SND_CHMAP_SR, SPA_AUDIO_CHANNEL_SR }, + [SND_CHMAP_RC] = { SND_CHMAP_RC, SPA_AUDIO_CHANNEL_RC }, + [SND_CHMAP_FLC] = { SND_CHMAP_FLC, SPA_AUDIO_CHANNEL_FLC }, + [SND_CHMAP_FRC] = { SND_CHMAP_FRC, SPA_AUDIO_CHANNEL_FRC }, + [SND_CHMAP_RLC] = { SND_CHMAP_RLC, SPA_AUDIO_CHANNEL_RLC }, + [SND_CHMAP_RRC] = { SND_CHMAP_RRC, SPA_AUDIO_CHANNEL_RRC }, + [SND_CHMAP_FLW] = { SND_CHMAP_FLW, SPA_AUDIO_CHANNEL_FLW }, + [SND_CHMAP_FRW] = { SND_CHMAP_FRW, SPA_AUDIO_CHANNEL_FRW }, + [SND_CHMAP_FLH] = { SND_CHMAP_FLH, SPA_AUDIO_CHANNEL_FLH }, + [SND_CHMAP_FCH] = { SND_CHMAP_FCH, SPA_AUDIO_CHANNEL_FCH }, + [SND_CHMAP_FRH] = { SND_CHMAP_FRH, SPA_AUDIO_CHANNEL_FRH }, + [SND_CHMAP_TC] = { SND_CHMAP_TC, SPA_AUDIO_CHANNEL_TC }, + [SND_CHMAP_TFL] = { SND_CHMAP_TFL, SPA_AUDIO_CHANNEL_TFL }, + [SND_CHMAP_TFR] = { SND_CHMAP_TFR, SPA_AUDIO_CHANNEL_TFR }, + [SND_CHMAP_TFC] = { SND_CHMAP_TFC, SPA_AUDIO_CHANNEL_TFC }, + [SND_CHMAP_TRL] = { SND_CHMAP_TRL, SPA_AUDIO_CHANNEL_TRL }, + [SND_CHMAP_TRR] = { SND_CHMAP_TRR, SPA_AUDIO_CHANNEL_TRR }, + [SND_CHMAP_TRC] = { SND_CHMAP_TRC, SPA_AUDIO_CHANNEL_TRC }, + [SND_CHMAP_TFLC] = { SND_CHMAP_TFLC, SPA_AUDIO_CHANNEL_TFLC }, + [SND_CHMAP_TFRC] = { SND_CHMAP_TFRC, SPA_AUDIO_CHANNEL_TFRC }, + [SND_CHMAP_TSL] = { SND_CHMAP_TSL, SPA_AUDIO_CHANNEL_TSL }, + [SND_CHMAP_TSR] = { SND_CHMAP_TSR, SPA_AUDIO_CHANNEL_TSR }, + [SND_CHMAP_LLFE] = { SND_CHMAP_LLFE, SPA_AUDIO_CHANNEL_LLFE }, + [SND_CHMAP_RLFE] = { SND_CHMAP_RLFE, SPA_AUDIO_CHANNEL_RLFE }, + [SND_CHMAP_BC] = { SND_CHMAP_BC, SPA_AUDIO_CHANNEL_BC }, + [SND_CHMAP_BLC] = { SND_CHMAP_BLC, SPA_AUDIO_CHANNEL_BLC }, + [SND_CHMAP_BRC] = { SND_CHMAP_BRC, SPA_AUDIO_CHANNEL_BRC }, +}; + +static enum spa_audio_channel chmap_position_to_channel(enum snd_pcm_chmap_position pos) { - uint64_t result = 0; - int i; - - for (i = 0; i < map->channels; i++) { - switch (map->pos[i]) { - case SND_CHMAP_UNKNOWN: - case SND_CHMAP_NA: /* N/A, silent */ - case SND_CHMAP_MONO: /* mono stream */ - break; - - case SND_CHMAP_FL: /* front left */ - case SND_CHMAP_FR: /* front right */ - case SND_CHMAP_RL: /* rear left */ - case SND_CHMAP_RR: /* rear right */ - case SND_CHMAP_FC: /* front center */ - case SND_CHMAP_LFE: /* LFE */ - case SND_CHMAP_SL: /* side left */ - case SND_CHMAP_SR: /* side right */ - case SND_CHMAP_RC: /* rear center */ - case SND_CHMAP_FLC: /* front left center */ - case SND_CHMAP_FRC: /* front right center */ - case SND_CHMAP_RLC: /* rear left center */ - case SND_CHMAP_RRC: /* rear right center */ - case SND_CHMAP_FLW: /* front left wide */ - case SND_CHMAP_FRW: /* front right wide */ - case SND_CHMAP_FLH: /* front left high */ - case SND_CHMAP_FCH: /* front center high */ - case SND_CHMAP_FRH: /* front right high */ - case SND_CHMAP_TC: /* top center */ - case SND_CHMAP_TFL: /* top front left */ - case SND_CHMAP_TFR: /* top front right */ - case SND_CHMAP_TFC: /* top front center */ - case SND_CHMAP_TRL: /* top rear left */ - case SND_CHMAP_TRR: /* top rear right */ - case SND_CHMAP_TRC: /* top rear center */ - result |= (1LL << (map->pos[i] - 3)); - break; - } - } - return result; + return chmap_info[pos].channel; } int @@ -187,6 +194,9 @@ spa_alsa_enum_format(struct state *state, uint32_t *index, snd_pcm_format_mask_alloca(&fmask); snd_pcm_hw_params_get_format_mask(params, fmask); + snd_pcm_access_mask_alloca(&amask); + snd_pcm_hw_params_get_access_mask(params, amask); + spa_pod_builder_prop(&b, SPA_FORMAT_AUDIO_format, 0); choice = spa_pod_builder_deref(&b, @@ -196,36 +206,23 @@ spa_alsa_enum_format(struct state *state, uint32_t *index, const struct format_info *fi = &format_info[i]; if (snd_pcm_format_mask_test(fmask, fi->format)) { - if (j++ == 0) + if (snd_pcm_access_mask_test(amask, SND_PCM_ACCESS_MMAP_INTERLEAVED)) { + if (j++ == 0) + spa_pod_builder_id(&b, fi->spa_format); spa_pod_builder_id(&b, fi->spa_format); - spa_pod_builder_id(&b, fi->spa_format); + } + if (snd_pcm_access_mask_test(amask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED) && + fi->spa_pformat != SPA_AUDIO_FORMAT_UNKNOWN) { + if (j++ == 0) + spa_pod_builder_id(&b, fi->spa_pformat); + spa_pod_builder_id(&b, fi->spa_pformat); + } } } if (j > 1) choice->body.type = SPA_CHOICE_Enum; spa_pod_builder_pop(&b); - snd_pcm_access_mask_alloca(&amask); - snd_pcm_hw_params_get_access_mask(params, amask); - - spa_pod_builder_prop(&b, SPA_FORMAT_AUDIO_layout, 0); - - choice = spa_pod_builder_deref(&b, - spa_pod_builder_push_choice(&b, SPA_CHOICE_None, 0)); - j = 0; - if (snd_pcm_access_mask_test(amask, SND_PCM_ACCESS_MMAP_INTERLEAVED)) { - if (j++ == 0) - spa_pod_builder_id(&b, SPA_AUDIO_LAYOUT_INTERLEAVED); - spa_pod_builder_id(&b, SPA_AUDIO_LAYOUT_INTERLEAVED); - } - if (snd_pcm_access_mask_test(amask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) { - if (j++ == 0) - spa_pod_builder_id(&b, SPA_AUDIO_LAYOUT_NON_INTERLEAVED); - spa_pod_builder_id(&b, SPA_AUDIO_LAYOUT_NON_INTERLEAVED); - } - if (j > 1) - choice->body.type = SPA_CHOICE_Enum; - spa_pod_builder_pop(&b); CHECK(snd_pcm_hw_params_get_rate_min(params, &min, &dir), "get_rate_min"); CHECK(snd_pcm_hw_params_get_rate_max(params, &max, &dir), "get_rate_max"); @@ -259,12 +256,16 @@ spa_alsa_enum_format(struct state *state, uint32_t *index, spa_pod_builder_pop(&b); if ((maps = snd_pcm_query_chmaps(hndl)) != NULL) { - spa_pod_builder_prop(&b, SPA_FORMAT_AUDIO_channelMask, 0); + uint32_t channel; - spa_pod_builder_push_choice(&b, SPA_CHOICE_None, 0); + spa_pod_builder_prop(&b, SPA_FORMAT_AUDIO_position, 0); + spa_pod_builder_push_array(&b); for (i = 0; maps[i]; i++) { - uint64_t mask = map_to_mask(&maps[i]->map); - spa_pod_builder_long(&b, mask); + snd_pcm_chmap_t* map = &maps[i]->map; + for (j = 0; j < map->channels; j++) { + channel = chmap_position_to_channel(map->pos[j]); + spa_pod_builder_id(&b, channel); + } } spa_pod_builder_pop(&b); diff --git a/spa/plugins/audioconvert/channelmix-ops-sse.c b/spa/plugins/audioconvert/channelmix-ops-sse.c new file mode 100644 index 000000000..37a6b68cb --- /dev/null +++ b/spa/plugins/audioconvert/channelmix-ops-sse.c @@ -0,0 +1,262 @@ +/* Spa + * Copyright (C) 2018 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include + +static void +channelmix_copy_sse(void *data, int n_dst, void *dst[n_dst], + int n_src, const void *src[n_src], void *matrix, int n_bytes) +{ + int i, n, n_samples = n_bytes / sizeof(float), unrolled, remain; + float **d = (float **)dst; + float **s = (float **)src; + float *m = matrix; + float v = m[0]; + __m128 vol = _mm_set1_ps(v); + + if (v <= VOLUME_MIN) { + for (i = 0; i < n_dst; i++) + memset(d[i], 0, n_bytes); + } + else if (v == VOLUME_NORM) { + for (i = 0; i < n_dst; i++) + memcpy(d[i], s[i], n_bytes); + } + else { + unrolled = n_samples / 4; + remain = n_samples & 3; + + for (i = 0; i < n_dst; i++) { + float *di = d[i], *si = s[i]; + for(n = 0; unrolled--; n += 4) + _mm_storeu_ps(&di[n], _mm_mul_ps(_mm_loadu_ps(&si[n]), vol)); + for(; remain--; n++) + _mm_store_ss(&di[n], _mm_mul_ss(_mm_load_ss(&si[n]), vol)); + } + } +} + +static void +channelmix_f32_2_4_sse(void *data, int n_dst, void *dst[n_dst], + int n_src, const void *src[n_src], void *matrix, int n_bytes) +{ + int i, n, n_samples = n_bytes / sizeof(float), unrolled, remain; + float **d = (float **)dst; + float **s = (float **)src; + float *m = matrix; + float v = m[0]; + __m128 vol = _mm_set1_ps(v); + __m128 in; + + if (v <= VOLUME_MIN) { + for (i = 0; i < n_dst; i++) + memset(d[i], 0, n_bytes); + } + else if (v == VOLUME_NORM) { + float *d0 = d[0], *d1 = d[1], *d2 = d[2], *d3 = d[3], *s0 = s[0], *s1 = s[1]; + unrolled = n_samples / 4; + remain = n_samples & 3; + + for(n = 0; unrolled--; n += 4) { + in = _mm_loadu_ps(&s0[n]); + _mm_storeu_ps(&d0[n], in); + _mm_storeu_ps(&d2[n], in); + in = _mm_loadu_ps(&s1[n]); + _mm_storeu_ps(&d1[n], in); + _mm_storeu_ps(&d3[n], in); + } + for(; remain--; n++) { + in = _mm_load_ss(&s0[n]); + _mm_store_ss(&d0[n], in); + _mm_store_ss(&d2[n], in); + in = _mm_load_ss(&s1[n]); + _mm_store_ss(&d1[n], in); + _mm_store_ss(&d3[n], in); + } + } + else { + float *d0 = d[0], *d1 = d[1], *d2 = d[2], *d3 = d[3], *s0 = s[0], *s1 = s[1]; + unrolled = n_samples / 4; + remain = n_samples & 3; + + for(n = 0; unrolled--; n += 4) { + in = _mm_mul_ps(_mm_loadu_ps(&s0[n]), vol); + _mm_storeu_ps(&d0[n], in); + _mm_storeu_ps(&d2[n], in); + in = _mm_mul_ps(_mm_loadu_ps(&s1[n]), vol); + _mm_storeu_ps(&d1[n], in); + _mm_storeu_ps(&d3[n], in); + } + for(; remain--; n++) { + in = _mm_mul_ss(_mm_load_ss(&s0[n]), vol); + _mm_store_ss(&d0[n], in); + _mm_store_ss(&d2[n], in); + in = _mm_mul_ss(_mm_load_ss(&s1[n]), vol); + _mm_store_ss(&d1[n], in); + _mm_store_ss(&d3[n], in); + } + } +} + +/* FL+FR+RL+RR+FC+LFE -> FL+FR */ +static void +channelmix_f32_5p1_2_sse(void *data, int n_dst, void *dst[n_dst], + int n_src, const void *src[n_src], void *matrix, int n_bytes) +{ + int n, n_samples = n_bytes / sizeof(float), unrolled, remain; + float **d = (float **) dst; + float **s = (float **) src; + float *m = matrix; + float v = m[0]; + __m128 clev = _mm_set1_ps(0.7071f); + __m128 slev = _mm_set1_ps(0.7071f); + __m128 vol = _mm_set1_ps(v); + __m128 in, ctr; + + if (v <= VOLUME_MIN) { + memset(d[0], 0, n_bytes); + memset(d[1], 0, n_bytes); + } + else if (v == VOLUME_NORM) { + float *d0 = d[0], *d1 = d[1], *s0 = s[0], *s1 = s[1], *s2 = s[2], *s3 = s[3], *s4 = s[4]; + + unrolled = n_samples / 4; + remain = n_samples & 3; + + for(n = 0; unrolled--; n += 4) { + ctr = _mm_mul_ps(_mm_loadu_ps(&s4[n]), clev); + in = _mm_mul_ps(_mm_loadu_ps(&s2[n]), slev); + in = _mm_add_ps(in, ctr); + in = _mm_add_ps(in, _mm_loadu_ps(&s0[n])); + _mm_storeu_ps(&d0[n], in); + in = _mm_mul_ps(_mm_loadu_ps(&s3[n]), slev); + in = _mm_add_ps(in, ctr); + in = _mm_add_ps(in, _mm_loadu_ps(&s1[n])); + _mm_storeu_ps(&d1[n], in); + } + for(; remain--; n++) { + ctr = _mm_mul_ss(_mm_load_ss(&s4[n]), clev); + in = _mm_mul_ss(_mm_load_ss(&s2[n]), slev); + in = _mm_add_ss(in, ctr); + in = _mm_add_ss(in, _mm_load_ss(&s0[n])); + _mm_store_ss(&d0[n], in); + in = _mm_mul_ss(_mm_load_ss(&s3[n]), slev); + in = _mm_add_ss(in, ctr); + in = _mm_add_ss(in, _mm_load_ss(&s1[n])); + _mm_store_ss(&d1[n], in); + } + } + else { + float *d0 = d[0], *d1 = d[1], *s0 = s[0], *s1 = s[1], *s2 = s[2], *s3 = s[3], *s4 = s[4]; + + unrolled = n_samples / 4; + remain = n_samples & 3; + + for(n = 0; unrolled--; n += 4) { + ctr = _mm_mul_ps(_mm_loadu_ps(&s4[n]), clev); + in = _mm_mul_ps(_mm_loadu_ps(&s2[n]), slev); + in = _mm_add_ps(in, ctr); + in = _mm_add_ps(in, _mm_loadu_ps(&s0[n])); + in = _mm_mul_ps(in, vol); + _mm_storeu_ps(&d0[n], in); + in = _mm_mul_ps(_mm_loadu_ps(&s3[n]), slev); + in = _mm_add_ps(in, ctr); + in = _mm_add_ps(in, _mm_loadu_ps(&s1[n])); + in = _mm_mul_ps(in, vol); + _mm_storeu_ps(&d1[n], in); + } + for(; remain--; n++) { + ctr = _mm_mul_ss(_mm_load_ss(&s4[n]), clev); + in = _mm_mul_ss(_mm_load_ss(&s2[n]), slev); + in = _mm_add_ss(in, ctr); + in = _mm_add_ss(in, _mm_load_ss(&s0[n])); + in = _mm_mul_ss(in, vol); + _mm_store_ss(&d0[n], in); + in = _mm_mul_ss(_mm_load_ss(&s3[n]), slev); + in = _mm_add_ss(in, ctr); + in = _mm_add_ss(in, _mm_load_ss(&s1[n])); + in = _mm_mul_ss(in, vol); + _mm_store_ss(&d1[n], in); + } + } +} + +/* FL+FR+RL+RR+FC+LFE -> FL+FR+RL+RR*/ +static void +channelmix_f32_5p1_4_sse(void *data, int n_dst, void *dst[n_dst], + int n_src, const void *src[n_src], void *matrix, int n_bytes) +{ + int i, n, n_samples = n_bytes / sizeof(float), unrolled, remain; + float **d = (float **) dst; + float **s = (float **) src; + float *m = matrix; + float v = m[0]; + __m128 clev = _mm_set1_ps(0.7071f); + __m128 vol = _mm_set1_ps(v); + __m128 ctr; + + if (v <= VOLUME_MIN) { + for (i = 0; i < n_dst; i++) + memset(d[i], 0, n_bytes); + } + else if (v == VOLUME_NORM) { + float *s0 = s[0], *s1 = s[1], *s2 = s[2], *s3 = s[3], *s4 = d[4]; + float *d0 = d[0], *d1 = d[1], *d2 = d[2], *d3 = d[3]; + + unrolled = n_samples / 4; + remain = n_samples & 3; + + for(n = 0; unrolled--; n += 4) { + ctr = _mm_mul_ps(_mm_loadu_ps(&s4[n]), clev); + _mm_storeu_ps(&d0[n], _mm_add_ps(_mm_loadu_ps(&s0[n]), ctr)); + _mm_storeu_ps(&d1[n], _mm_add_ps(_mm_loadu_ps(&s1[n]), ctr)); + _mm_storeu_ps(&d2[n], _mm_loadu_ps(&s2[n])); + _mm_storeu_ps(&d3[n], _mm_loadu_ps(&s3[n])); + } + for(; remain--; n++) { + ctr = _mm_mul_ss(_mm_load_ss(&s4[n]), clev); + _mm_store_ss(&d0[n], _mm_add_ss(_mm_load_ss(&s0[n]), ctr)); + _mm_store_ss(&d1[n], _mm_add_ss(_mm_load_ss(&s1[n]), ctr)); + _mm_store_ss(&d2[n], _mm_load_ss(&s2[n])); + _mm_store_ss(&d3[n], _mm_load_ss(&s3[n])); + } + } + else { + float *s0 = s[0], *s1 = s[1], *s2 = s[2], *s3 = s[3], *s4 = d[4]; + float *d0 = d[0], *d1 = d[1], *d2 = d[2], *d3 = d[3]; + + unrolled = n_samples / 4; + remain = n_samples & 3; + + for(n = 0; unrolled--; n += 4) { + ctr = _mm_mul_ps(_mm_loadu_ps(&s4[n]), clev); + _mm_storeu_ps(&d0[n], _mm_mul_ps(_mm_add_ps(_mm_loadu_ps(&s0[n]), ctr), vol)); + _mm_storeu_ps(&d1[n], _mm_mul_ps(_mm_add_ps(_mm_loadu_ps(&s1[n]), ctr), vol)); + _mm_storeu_ps(&d2[n], _mm_mul_ps(_mm_loadu_ps(&s2[n]), vol)); + _mm_storeu_ps(&d3[n], _mm_mul_ps(_mm_loadu_ps(&s3[n]), vol)); + } + for(; remain--; n++) { + ctr = _mm_mul_ss(_mm_load_ss(&s4[n]), clev); + _mm_store_ss(&d0[n], _mm_mul_ss(_mm_add_ss(_mm_load_ss(&s0[n]), ctr), vol)); + _mm_store_ss(&d1[n], _mm_mul_ss(_mm_add_ss(_mm_load_ss(&s1[n]), ctr), vol)); + _mm_store_ss(&d2[n], _mm_mul_ss(_mm_load_ss(&s2[n]), vol)); + _mm_store_ss(&d3[n], _mm_mul_ss(_mm_load_ss(&s3[n]), vol)); + } + } +} diff --git a/spa/plugins/audioconvert/channelmix-ops.c b/spa/plugins/audioconvert/channelmix-ops.c index 7ea45b135..15a054a13 100644 --- a/spa/plugins/audioconvert/channelmix-ops.c +++ b/spa/plugins/audioconvert/channelmix-ops.c @@ -25,30 +25,32 @@ #define VOLUME_MIN 0.0f #define VOLUME_NORM 1.0f +#if defined (__SSE__) +#include "channelmix-ops-sse.c" +#endif + static void channelmix_copy(void *data, int n_dst, void *dst[n_dst], int n_src, const void *src[n_src], void *matrix, int n_bytes) { - int i, j; + int i, n, n_samples = n_bytes / sizeof(float); + float **d = (float **)dst; + float **s = (float **)src; float *m = matrix; float v = m[0]; if (v <= VOLUME_MIN) { - for (i = 0; i < n_src; i++) - memset(dst[i], 0, n_bytes); + for (i = 0; i < n_dst; i++) + memset(d[i], 0, n_bytes); } else if (v == VOLUME_NORM) { - for (i = 0; i < n_src; i++) - memcpy(dst[i], src[i], n_bytes); + for (i = 0; i < n_dst; i++) + memcpy(d[i], s[i], n_bytes); } else { - float **d = (float **) dst; - float **s = (float **) src; - int n_samples = n_bytes / sizeof(float); - - for (i = 0; i < n_src; i++) - for (j = 0; j < n_samples; j++) - d[i][j] = s[i][j] * v; + for (i = 0; i < n_dst; i++) + for (n = 0; n < n_samples; n++) + d[i][n] = s[i][n] * v; } } @@ -56,12 +58,11 @@ static void channelmix_f32_n_m(void *data, int n_dst, void *dst[n_dst], int n_src, const void *src[n_src], void *matrix, int n_bytes) { - int i, j, n, n_samples; + int i, j, n, n_samples = n_bytes / sizeof(float); float **d = (float **) dst; float **s = (float **) src; float *m = matrix; - n_samples = n_bytes / sizeof(float); for (n = 0; n < n_samples; n++) { for (i = 0; i < n_dst; i++) { float sum = 0.0f; @@ -78,23 +79,23 @@ static void channelmix_f32_1_2(void *data, int n_dst, void *dst[n_dst], int n_src, const void *src[n_src], void *matrix, int n_bytes) { - int n, n_samples; - float **d = (float **) dst; - const float *s = src[0]; + int n, n_samples = n_bytes / sizeof(float); + float **d = (float **)dst; + float **s = (float **)src; float *m = matrix; float v = m[0]; - n_samples = n_bytes / sizeof(float); if (v <= VOLUME_MIN) { memset(d[0], 0, n_bytes); + memset(d[1], 0, n_bytes); } else if (v == VOLUME_NORM) { for (n = 0; n < n_samples; n++) - d[0][n] = d[1][n] = s[n]; + d[0][n] = d[1][n] = s[0][n]; } else { for (n = 0; n < n_samples; n++) - d[0][n] = d[1][n] = s[n] * v; + d[0][n] = d[1][n] = s[0][n] * v; } } @@ -102,24 +103,209 @@ static void channelmix_f32_2_1(void *data, int n_dst, void *dst[n_dst], int n_src, const void *src[n_src], void *matrix, int n_bytes) { - int n, n_samples; - float *d = dst[0]; + int n, n_samples = n_bytes / sizeof(float); + float **d = (float **)dst; + float **s = (float **)src; + float *m = matrix; + float v = m[0]; + + if (v <= VOLUME_MIN) { + memset(d[0], 0, n_bytes); + } + else { + const float f = v * 0.5f; + for (n = 0; n < n_samples; n++) + d[0][n] = (s[0][n] + s[1][n]) * f; + } +} + +static void +channelmix_f32_2_4(void *data, int n_dst, void *dst[n_dst], + int n_src, const void *src[n_src], void *matrix, int n_bytes) +{ + int i, n, n_samples = n_bytes / sizeof(float); + float **d = (float **)dst; + float **s = (float **)src; + float *m = matrix; + float v = m[0]; + + if (v <= VOLUME_MIN) { + for (i = 0; i < n_dst; i++) + memset(d[i], 0, n_bytes); + } + else if (v == VOLUME_NORM) { + for (n = 0; n < n_samples; n++) { + d[0][n] = d[2][n] = s[0][n]; + d[1][n] = d[3][n] = s[1][n]; + } + } + else { + for (n = 0; n < n_samples; n++) { + d[0][n] = d[2][n] = s[0][n] * v; + d[1][n] = d[3][n] = s[1][n] * v; + } + } +} + +static void +channelmix_f32_2_3p1(void *data, int n_dst, void *dst[n_dst], + int n_src, const void *src[n_src], void *matrix, int n_bytes) +{ + int i, n, n_samples = n_bytes / sizeof(float); + float **d = (float **)dst; + float **s = (float **)src; + float *m = matrix; + float v = m[0]; + + if (v <= VOLUME_MIN) { + for (i = 0; i < n_dst; i++) + memset(d[i], 0, n_bytes); + } + else if (v == VOLUME_NORM) { + for (n = 0; n < n_samples; n++) { + d[0][n] = s[0][n]; + d[1][n] = s[1][n]; + d[2][n] = (s[0][n] + s[1][n]) * 0.5f; + d[3][n] = 0.0f; + } + } + else { + const float f = 0.5f * v; + for (n = 0; n < n_samples; n++) { + d[0][n] = s[0][n] * v; + d[1][n] = s[1][n] * v; + d[2][n] = (s[0][n] + s[1][n]) * f; + d[3][n] = 0.0f; + } + } +} + +static void +channelmix_f32_2_5p1(void *data, int n_dst, void *dst[n_dst], + int n_src, const void *src[n_src], void *matrix, int n_bytes) +{ + int i, n, n_samples = n_bytes / sizeof(float); + float **d = (float **)dst; + float **s = (float **)src; + float *m = matrix; + float v = m[0]; + + if (v <= VOLUME_MIN) { + for (i = 0; i < n_dst; i++) + memset(d[i], 0, n_bytes); + } + else if (v == VOLUME_NORM) { + for (n = 0; n < n_samples; n++) { + d[0][n] = d[2][n] = s[0][n]; + d[1][n] = d[3][n] = s[1][n]; + d[4][n] = (s[0][n] + s[1][n]) * 0.5f; + d[5][n] = 0.0f; + } + } + else { + const float f = 0.5f * v; + for (n = 0; n < n_samples; n++) { + d[0][n] = d[2][n] = s[0][n] * v; + d[1][n] = d[3][n] = s[1][n] * v; + d[4][n] = (s[0][n] + s[1][n]) * f; + d[5][n] = 0.0f; + } + } +} + +/* FL+FR+RL+RR+FC+LFE -> FL+FR */ +static void +channelmix_f32_5p1_2(void *data, int n_dst, void *dst[n_dst], + int n_src, const void *src[n_src], void *matrix, int n_bytes) +{ + int n, n_samples = n_bytes / sizeof(float); + float **d = (float **) dst; + float **s = (float **) src; + float *m = matrix; + float v = m[0]; + const float clev = 0.7071f; + const float slev = 0.7071f; + + if (v <= VOLUME_MIN) { + memset(d[0], 0, n_bytes); + memset(d[1], 0, n_bytes); + } + else if (v == VOLUME_NORM) { + for (n = 0; n < n_samples; n++) { + const float ctr = clev * s[4][n]; + d[0][n] = s[0][n] + ctr + (slev * s[2][n]); + d[1][n] = s[1][n] + ctr + (slev * s[3][n]); + } + } + else { + for (n = 0; n < n_samples; n++) { + const float ctr = clev * s[4][n]; + d[0][n] = (s[0][n] + ctr + (slev * s[2][n])) * v; + d[1][n] = (s[1][n] + ctr + (slev * s[3][n])) * v; + } + } +} + +/* FL+FR+RL+RR+FC+LFE -> FL+FR+FC+LFE*/ +static void +channelmix_f32_5p1_3p1(void *data, int n_dst, void *dst[n_dst], + int n_src, const void *src[n_src], void *matrix, int n_bytes) +{ + int i, n, n_samples; + float **d = (float **) dst; float **s = (float **) src; float *m = matrix; float v = m[0]; n_samples = n_bytes / sizeof(float); if (v <= VOLUME_MIN) { - memset(d, 0, n_bytes); - } - else if (v == VOLUME_NORM) { - for (n = 0; n < n_samples; n++) - d[n] = (s[0][n] + s[1][n]) * 0.5f; + for (i = 0; i < n_dst; i++) + memset(d[i], 0, n_bytes); } else { - v *= 0.5f; - for (n = 0; n < n_samples; n++) - d[n] = (s[0][n] + s[1][n]) * v; + const float f1 = 0.5f * v; + for (n = 0; n < n_samples; n++) { + d[0][n] = (s[0][n] + s[2][n]) * f1; + d[1][n] = (s[1][n] + s[3][n]) * f1; + d[2][n] = s[4][n] * v; + d[3][n] = s[5][n] * v; + } + } +} + +/* FL+FR+RL+RR+FC+LFE -> FL+FR+RL+RR*/ +static void +channelmix_f32_5p1_4(void *data, int n_dst, void *dst[n_dst], + int n_src, const void *src[n_src], void *matrix, int n_bytes) +{ + int i, n, n_samples; + float **d = (float **) dst; + float **s = (float **) src; + float *m = matrix; + float v = m[0]; + + n_samples = n_bytes / sizeof(float); + if (v <= VOLUME_MIN) { + for (i = 0; i < n_dst; i++) + memset(d[i], 0, n_bytes); + } + else if (v == VOLUME_NORM) { + for (n = 0; n < n_samples; n++) { + float ctr = s[4][n] * 0.7071f; + d[0][n] = s[0][n] + ctr; + d[1][n] = s[1][n] + ctr; + d[2][n] = s[2][n]; + d[3][n] = s[3][n]; + } + } + else { + for (n = 0; n < n_samples; n++) { + float ctr = s[4][n] * 0.7071f; + d[0][n] = (s[0][n] + ctr) * v; + d[1][n] = (s[1][n] + ctr) * v; + d[2][n] = s[2][n] * v; + d[3][n] = s[3][n] * v; + } } } @@ -130,30 +316,53 @@ typedef void (*channelmix_func_t) (void *data, int n_dst, void *dst[n_dst], static const struct channelmix_info { uint32_t src_chan; + uint64_t src_mask; uint32_t dst_chan; + uint64_t dst_mask; channelmix_func_t func; - uint32_t flags; +#define FEATURE_SSE (1<<0) + uint32_t features; } channelmix_table[] = { - { -2, -2, channelmix_copy, 0 }, - { 1, 2, channelmix_f32_1_2, 0 }, - { 2, 1, channelmix_f32_2_1, 0 }, - { -1, -1, channelmix_f32_n_m, 0 }, +#if defined (__SSE2__) + { -2, 0, -2, 0, channelmix_copy_sse, 0 }, +#endif + { -2, 0, -2, 0, channelmix_copy, 0 }, + { 1, 0, 2, 0, channelmix_f32_1_2, 0 }, + { 2, 0, 1, 0, channelmix_f32_2_1, 0 }, +#if defined (__SSE2__) + { 2, 0, 4, 0, channelmix_f32_2_4_sse, FEATURE_SSE }, +#endif + { 2, 0, 4, 0, channelmix_f32_2_4, 0 }, + { 2, 0, 4, 0, channelmix_f32_2_3p1, 0 }, + { 2, 0, 6, 0, channelmix_f32_2_5p1, 0 }, +#if defined (__SSE2__) + { 6, 0, 2, 0, channelmix_f32_5p1_2_sse, FEATURE_SSE }, +#endif + { 6, 0, 2, 0, channelmix_f32_5p1_2, 0 }, +#if defined (__SSE2__) + { 6, 0, 4, 0, channelmix_f32_5p1_4_sse, FEATURE_SSE }, +#endif + { 6, 0, 4, 0, channelmix_f32_5p1_4, 0 }, + { 6, 0, 4, 0, channelmix_f32_5p1_3p1, 0 }, + { -1, 0, -1, 0, channelmix_f32_n_m, 0 }, }; #define MATCH_CHAN(a,b) ((a) == -1 || (a) == (b)) -static const struct channelmix_info *find_channelmix_info(uint32_t src_chan, uint32_t dst_chan) +static const struct channelmix_info *find_channelmix_info(uint32_t src_chan, uint64_t src_mask, + uint32_t dst_chan, uint64_t dst_mask, uint32_t features) { int i; - if (src_chan == dst_chan) + if (src_chan == dst_chan && src_mask == dst_mask) return &channelmix_table[0]; for (i = 1; i < SPA_N_ELEMENTS(channelmix_table); i++) { if (MATCH_CHAN(channelmix_table[i].src_chan, src_chan) && - MATCH_CHAN(channelmix_table[i].dst_chan, dst_chan)) + MATCH_CHAN(channelmix_table[i].dst_chan, dst_chan) && + (channelmix_table[i].features == 0 || (channelmix_table[i].features & features) != 0)) return &channelmix_table[i]; } return NULL; diff --git a/spa/plugins/audioconvert/channelmix.c b/spa/plugins/audioconvert/channelmix.c index 159509bb0..d3214ced8 100644 --- a/spa/plugins/audioconvert/channelmix.c +++ b/spa/plugins/audioconvert/channelmix.c @@ -143,23 +143,23 @@ static int setup_convert(struct impl *this, src_chan = src_info->info.raw.channels; dst_chan = dst_info->info.raw.channels; - spa_log_info(this->log, NAME " %p: %d/%d@%d.%d->%d/%d@%d.%d", this, + spa_log_info(this->log, NAME " %p: %d/%d@%d->%d/%d@%d", this, src_info->info.raw.format, src_chan, src_info->info.raw.rate, - src_info->info.raw.layout, dst_info->info.raw.format, dst_chan, - dst_info->info.raw.rate, - dst_info->info.raw.layout); + dst_info->info.raw.rate); if (src_info->info.raw.rate != dst_info->info.raw.rate) return -EINVAL; /* find convert function */ - if ((chanmix_info = find_channelmix_info(src_chan, dst_chan)) == NULL) + if ((chanmix_info = find_channelmix_info(src_chan, 0, dst_chan, 0, FEATURE_SSE)) == NULL) return -ENOTSUP; + spa_log_info(this->log, NAME " %p: got channelmix features %08x", this, chanmix_info->features); + this->convert = chanmix_info->func; /* set up the matrix if needed */ @@ -311,8 +311,7 @@ static int port_enum_formats(struct spa_node *node, 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_Id(SPA_AUDIO_FORMAT_F32), - SPA_FORMAT_AUDIO_layout, &SPA_POD_Id(SPA_AUDIO_LAYOUT_NON_INTERLEAVED), + SPA_FORMAT_AUDIO_format, &SPA_POD_Id(SPA_AUDIO_FORMAT_F32P), SPA_FORMAT_AUDIO_rate, &SPA_POD_Int(other->format.info.raw.rate), SPA_FORMAT_AUDIO_channels, &SPA_POD_CHOICE_RANGE_Int(DEFAULT_CHANNELS, 1, INT32_MAX), 0); @@ -321,8 +320,7 @@ static int port_enum_formats(struct spa_node *node, 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_Id(SPA_AUDIO_FORMAT_F32), - SPA_FORMAT_AUDIO_layout, &SPA_POD_Id(SPA_AUDIO_LAYOUT_NON_INTERLEAVED), + SPA_FORMAT_AUDIO_format, &SPA_POD_Id(SPA_AUDIO_FORMAT_F32P), SPA_FORMAT_AUDIO_rate, &SPA_POD_CHOICE_RANGE_Int(DEFAULT_RATE, 1, INT32_MAX), SPA_FORMAT_AUDIO_channels, &SPA_POD_CHOICE_RANGE_Int(DEFAULT_CHANNELS, 1, INT32_MAX), 0); @@ -516,9 +514,7 @@ static int port_set_format(struct spa_node *node, if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) return -EINVAL; - if (info.info.raw.format != SPA_AUDIO_FORMAT_F32) - return -EINVAL; - if (info.info.raw.layout != SPA_AUDIO_LAYOUT_NON_INTERLEAVED) + if (info.info.raw.format != SPA_AUDIO_FORMAT_F32P) return -EINVAL; port->stride = sizeof(float); diff --git a/spa/plugins/audioconvert/fmt-ops.c b/spa/plugins/audioconvert/fmt-ops.c index 8416e9742..06dce3a75 100644 --- a/spa/plugins/audioconvert/fmt-ops.c +++ b/spa/plugins/audioconvert/fmt-ops.c @@ -675,64 +675,92 @@ static const struct conv_info { #define FEATURE_SSE (1<<0) uint32_t features; - convert_func_t i2i; - convert_func_t i2d; - convert_func_t d2i; + convert_func_t func; } conv_table[] = { /* to f32 */ - { SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_F32, 0, - conv_u8_to_f32, conv_u8_to_f32d, conv_u8d_to_f32 }, + { SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_F32, 0, conv_u8_to_f32 }, + { SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_F32P, 0, conv_u8_to_f32d }, + { SPA_AUDIO_FORMAT_U8P, SPA_AUDIO_FORMAT_F32, 0, conv_u8d_to_f32 }, + + + { SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_F32, 0, conv_s16_to_f32 }, #if defined (__SSE2__) - { SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_F32, FEATURE_SSE, - conv_s16_to_f32, conv_s16_to_f32d_sse, conv_s16d_to_f32 }, + { SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_F32P, FEATURE_SSE, conv_s16_to_f32d_sse }, #endif - { SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_F32, 0, - conv_s16_to_f32, conv_s16_to_f32d, conv_s16d_to_f32 }, - { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_F32, 0, - conv_copy, deinterleave_32, interleave_32 }, - { SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_F32, 0, - conv_s32_to_f32, conv_s32_to_f32d, conv_s32d_to_f32 }, - { SPA_AUDIO_FORMAT_S24, SPA_AUDIO_FORMAT_F32, 0, - conv_s24_to_f32, conv_s24_to_f32d, conv_s24d_to_f32 }, - { SPA_AUDIO_FORMAT_S24_32, SPA_AUDIO_FORMAT_F32, 0, - conv_s24_32_to_f32, conv_s24_32_to_f32d, conv_s24_32d_to_f32 }, + { SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_F32P, 0, conv_s16_to_f32d }, + { SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_F32, 0, conv_s16d_to_f32 }, + + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_F32, 0, conv_copy }, + { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F32P, 0, conv_copy }, + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_F32P, 0, deinterleave_32 }, + { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F32, 0, interleave_32 }, + + { SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_F32, 0, conv_s32_to_f32 }, + { SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_F32P, 0, conv_s32_to_f32d }, + { SPA_AUDIO_FORMAT_S32P, SPA_AUDIO_FORMAT_F32, 0, conv_s32d_to_f32 }, + + { SPA_AUDIO_FORMAT_S24, SPA_AUDIO_FORMAT_F32, 0, conv_s24_to_f32 }, + { SPA_AUDIO_FORMAT_S24, SPA_AUDIO_FORMAT_F32P, 0, conv_s24_to_f32d }, + { SPA_AUDIO_FORMAT_S24P, SPA_AUDIO_FORMAT_F32, 0, conv_s24d_to_f32 }, + + { SPA_AUDIO_FORMAT_S24_32, SPA_AUDIO_FORMAT_F32, 0, conv_s24_32_to_f32 }, + { SPA_AUDIO_FORMAT_S24_32, SPA_AUDIO_FORMAT_F32P, 0, conv_s24_32_to_f32d }, + { SPA_AUDIO_FORMAT_S24_32P, SPA_AUDIO_FORMAT_F32, 0, conv_s24_32d_to_f32 }, /* from f32 */ - { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_U8, 0, - conv_f32_to_u8, conv_f32_to_u8d, conv_f32d_to_u8 }, - { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S16, 0, - conv_f32_to_s16, conv_f32_to_s16d, conv_f32d_to_s16 }, + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_U8, 0, conv_f32_to_u8 }, + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_U8P, 0, conv_f32_to_u8d }, + { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_U8, 0, conv_f32d_to_u8 }, + + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S16, 0, conv_f32_to_s16 }, + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S16P, 0, conv_f32_to_s16d }, + { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_S16, 0, conv_f32d_to_s16 }, + + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S32, 0, conv_f32_to_s32 }, + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S32P, 0, conv_f32_to_s32d }, #if defined (__SSE2__) - { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S32, FEATURE_SSE, - conv_f32_to_s32, conv_f32_to_s32d, conv_f32d_to_s32_sse }, + { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_S32, FEATURE_SSE, conv_f32d_to_s32_sse }, #endif - { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S32, 0, - conv_f32_to_s32, conv_f32_to_s32d, conv_f32d_to_s32 }, - { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S24, 0, - conv_f32_to_s24, conv_f32_to_s24d, conv_f32d_to_s24 }, - { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S24_32, 0, - conv_f32_to_s24_32, conv_f32_to_s24_32d, conv_f32d_to_s24_32 }, + { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_S32, 0, conv_f32d_to_s32 }, + + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S24, 0, conv_f32_to_s24 }, + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S24P, 0, conv_f32_to_s24d }, + { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_S24, 0, conv_f32d_to_s24 }, + + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S24_32, 0, conv_f32_to_s24_32 }, + { SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_S24_32P, 0, conv_f32_to_s24_32d }, + { SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_S24_32, 0, conv_f32d_to_s24_32 }, /* u8 */ - { SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_U8, 0, - conv_copy, deinterleave_8, interleave_8 }, + { SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_U8, 0, conv_copy }, + { SPA_AUDIO_FORMAT_U8P, SPA_AUDIO_FORMAT_U8P, 0, conv_copy }, + { SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_U8P, 0, deinterleave_8 }, + { SPA_AUDIO_FORMAT_U8P, SPA_AUDIO_FORMAT_U8, 0, interleave_8 }, /* s16 */ - { SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S16, 0, - conv_copy, deinterleave_16, interleave_16 }, + { SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S16, 0, conv_copy }, + { SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_S16P, 0, conv_copy }, + { SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S16P, 0, deinterleave_16 }, + { SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_S16, 0, interleave_16 }, /* s32 */ - { SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_S32, 0, - conv_copy, deinterleave_32, interleave_32 }, + { SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_S32, 0, conv_copy }, + { SPA_AUDIO_FORMAT_S32P, SPA_AUDIO_FORMAT_S32P, 0, conv_copy }, + { SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_S32P, 0, deinterleave_32 }, + { SPA_AUDIO_FORMAT_S32P, SPA_AUDIO_FORMAT_S32, 0, interleave_32 }, /* s24 */ - { SPA_AUDIO_FORMAT_S24, SPA_AUDIO_FORMAT_S24, 0, - conv_copy, deinterleave_24, interleave_24 }, + { SPA_AUDIO_FORMAT_S24, SPA_AUDIO_FORMAT_S24, 0, conv_copy }, + { SPA_AUDIO_FORMAT_S24P, SPA_AUDIO_FORMAT_S24P, 0, conv_copy }, + { SPA_AUDIO_FORMAT_S24, SPA_AUDIO_FORMAT_S24P, 0, deinterleave_24 }, + { SPA_AUDIO_FORMAT_S24P, SPA_AUDIO_FORMAT_S24, 0, interleave_24 }, /* s24_32 */ - { SPA_AUDIO_FORMAT_S24_32, SPA_AUDIO_FORMAT_S24_32, 0, - conv_copy, deinterleave_32, interleave_32 }, + { SPA_AUDIO_FORMAT_S24_32, SPA_AUDIO_FORMAT_S24_32, 0, conv_copy }, + { SPA_AUDIO_FORMAT_S24_32P, SPA_AUDIO_FORMAT_S24_32P, 0, conv_copy }, + { SPA_AUDIO_FORMAT_S24_32, SPA_AUDIO_FORMAT_S24_32P, 0, deinterleave_32 }, + { SPA_AUDIO_FORMAT_S24_32P, SPA_AUDIO_FORMAT_S24_32, 0, interleave_32 }, }; static const struct conv_info *find_conv_info(uint32_t src_fmt, uint32_t dst_fmt, uint32_t features) diff --git a/spa/plugins/audioconvert/fmtconvert.c b/spa/plugins/audioconvert/fmtconvert.c index eeb22382a..a334a39f8 100644 --- a/spa/plugins/audioconvert/fmtconvert.c +++ b/spa/plugins/audioconvert/fmtconvert.c @@ -160,15 +160,13 @@ static int setup_convert(struct impl *this) src_fmt = informat.format.info.raw.format; dst_fmt = outformat.format.info.raw.format; - spa_log_info(this->log, NAME " %p: %s/%d@%d.%d->%s/%d@%d.%d", this, + spa_log_info(this->log, NAME " %p: %s/%d@%d->%s/%d@%d", this, spa_debug_type_find_name(spa_type_audio_format, src_fmt), informat.format.info.raw.channels, informat.format.info.raw.rate, - informat.format.info.raw.layout, spa_debug_type_find_name(spa_type_audio_format, dst_fmt), outformat.format.info.raw.channels, - outformat.format.info.raw.rate, - outformat.format.info.raw.layout); + outformat.format.info.raw.rate); if (informat.format.info.raw.channels != outformat.format.info.raw.channels) return -EINVAL; @@ -181,18 +179,8 @@ static int setup_convert(struct impl *this) if (conv != NULL) { spa_log_info(this->log, NAME " %p: got converter features %08x", this, conv->features); - if (informat.format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) { - if (outformat.format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) - this->convert = conv->i2i; - else - this->convert = conv->i2d; - } - else { - if (outformat.format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) - this->convert = conv->d2i; - else - this->convert = conv->i2i; - } + + this->convert = conv->func; return 0; } return -ENOTSUP; @@ -428,11 +416,7 @@ static int port_enum_formats(struct spa_node *node, other->info.raw.format, other->info.raw.format, SPA_AUDIO_FORMAT_F32, - SPA_AUDIO_FORMAT_F32_OE), - SPA_FORMAT_AUDIO_layout, &SPA_POD_CHOICE_ENUM_Id(3, - other->info.raw.layout, - SPA_AUDIO_LAYOUT_INTERLEAVED, - SPA_AUDIO_LAYOUT_NON_INTERLEAVED), + SPA_AUDIO_FORMAT_F32P), SPA_FORMAT_AUDIO_rate, &SPA_POD_Int(other->info.raw.rate), SPA_FORMAT_AUDIO_channels, &SPA_POD_Int(other->info.raw.channels), 0); @@ -441,23 +425,25 @@ static int port_enum_formats(struct spa_node *node, 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(12, + SPA_FORMAT_AUDIO_format, &SPA_POD_CHOICE_ENUM_Id(18, SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_U8P, SPA_AUDIO_FORMAT_U8, + SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S16_OE, + SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_F32_OE, + SPA_AUDIO_FORMAT_S32P, SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_S32_OE, + SPA_AUDIO_FORMAT_S24P, SPA_AUDIO_FORMAT_S24, SPA_AUDIO_FORMAT_S24_OE, + SPA_AUDIO_FORMAT_S24_32P, SPA_AUDIO_FORMAT_S24_32, SPA_AUDIO_FORMAT_S24_32_OE), - SPA_FORMAT_AUDIO_layout, &SPA_POD_CHOICE_ENUM_Id(3, - SPA_AUDIO_LAYOUT_INTERLEAVED, - SPA_AUDIO_LAYOUT_INTERLEAVED, - SPA_AUDIO_LAYOUT_NON_INTERLEAVED), SPA_FORMAT_AUDIO_rate, &SPA_POD_CHOICE_RANGE_Int( DEFAULT_RATE, 1, INT32_MAX), SPA_FORMAT_AUDIO_channels, &SPA_POD_CHOICE_RANGE_Int( @@ -632,7 +618,6 @@ static int clear_buffers(struct impl *this, struct port *port) static int compatible_format(struct spa_audio_info *info, struct spa_audio_info *info2) { if (info->info.raw.format != info2->info.raw.format || - info->info.raw.layout != info2->info.raw.layout || info->info.raw.rate != info2->info.raw.rate) return -EINVAL; return 0; @@ -686,12 +671,12 @@ static int port_set_format(struct spa_node *node, port->stride = calc_width(&info); - if (info.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) { - port->stride *= info.info.raw.channels; - port->blocks = 1; + if (SPA_AUDIO_FORMAT_IS_PLANAR(info.info.raw.format)) { + port->blocks = info.info.raw.channels; } else { - port->blocks = info.info.raw.channels; + port->stride *= info.info.raw.channels; + port->blocks = 1; } if (this->n_formats[SPA_DIRECTION_INPUT] == this->n_ports[SPA_DIRECTION_INPUT] && diff --git a/spa/plugins/audioconvert/merger.c b/spa/plugins/audioconvert/merger.c index 107e26a72..90bc4b8f0 100644 --- a/spa/plugins/audioconvert/merger.c +++ b/spa/plugins/audioconvert/merger.c @@ -319,23 +319,20 @@ static int port_enum_formats(struct spa_node *node, 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(12, + SPA_FORMAT_AUDIO_format, &SPA_POD_CHOICE_ENUM_Id(13, SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_F32, - SPA_AUDIO_FORMAT_F32_OE, + SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_S32, - SPA_AUDIO_FORMAT_S32_OE, + SPA_AUDIO_FORMAT_S32P, SPA_AUDIO_FORMAT_S24_32, - SPA_AUDIO_FORMAT_S24_32_OE, + SPA_AUDIO_FORMAT_S24_32P, SPA_AUDIO_FORMAT_S24, - SPA_AUDIO_FORMAT_S24_OE, + SPA_AUDIO_FORMAT_S24P, SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S16_OE, - SPA_AUDIO_FORMAT_U8), - SPA_FORMAT_AUDIO_layout, &SPA_POD_CHOICE_ENUM_Id(3, - SPA_AUDIO_LAYOUT_INTERLEAVED, - SPA_AUDIO_LAYOUT_INTERLEAVED, - SPA_AUDIO_LAYOUT_NON_INTERLEAVED), + SPA_AUDIO_FORMAT_S16P, + SPA_AUDIO_FORMAT_U8, + SPA_AUDIO_FORMAT_U8P), SPA_FORMAT_AUDIO_rate, rate, SPA_FORMAT_AUDIO_channels, &SPA_POD_Int(this->port_count), 0); @@ -345,8 +342,7 @@ static int port_enum_formats(struct spa_node *node, 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_Id(SPA_AUDIO_FORMAT_F32), - SPA_FORMAT_AUDIO_layout, &SPA_POD_Id(SPA_AUDIO_LAYOUT_NON_INTERLEAVED), + SPA_FORMAT_AUDIO_format, &SPA_POD_Id(SPA_AUDIO_FORMAT_F32P), SPA_FORMAT_AUDIO_rate, rate, SPA_FORMAT_AUDIO_channels, &SPA_POD_Int(1), 0); @@ -512,33 +508,21 @@ static int setup_convert(struct impl *this) src_fmt = inport->format.info.raw.format; dst_fmt = outport->format.info.raw.format; - spa_log_info(this->log, NAME " %p: %s/%d@%d.%dx%d->%s/%d@%d.%d", this, + spa_log_info(this->log, NAME " %p: %s/%d@%dx%d->%s/%d@%d", this, spa_debug_type_find_name(spa_type_audio_format, src_fmt), inport->format.info.raw.channels, inport->format.info.raw.rate, - inport->format.info.raw.layout, this->port_count, spa_debug_type_find_name(spa_type_audio_format, dst_fmt), outport->format.info.raw.channels, - outport->format.info.raw.rate, - outport->format.info.raw.layout); + outport->format.info.raw.rate); conv = find_conv_info(src_fmt, dst_fmt, FEATURE_SSE); if (conv != NULL) { spa_log_info(this->log, NAME " %p: got converter features %08x", this, conv->features); - if (inport->format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) { - if (outport->format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) - this->convert = conv->i2i; - else - this->convert = conv->i2d; - } - else { - if (outport->format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) - this->convert = conv->d2i; - else - this->convert = conv->i2i; - } + + this->convert = conv->func; return 0; } return -ENOTSUP; @@ -602,9 +586,7 @@ static int port_set_format(struct spa_node *node, if (info.info.raw.channels != this->port_count) return -EINVAL; } else { - if (info.info.raw.format != SPA_AUDIO_FORMAT_F32) - return -EINVAL; - if (info.info.raw.layout != SPA_AUDIO_LAYOUT_NON_INTERLEAVED) + if (info.info.raw.format != SPA_AUDIO_FORMAT_F32P) return -EINVAL; if (info.info.raw.channels != 1) return -EINVAL; @@ -612,12 +594,12 @@ static int port_set_format(struct spa_node *node, port->format = info; port->stride = calc_width(&info); - if (info.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) { - port->stride *= info.info.raw.channels; - port->blocks = 1; + if (SPA_AUDIO_FORMAT_IS_PLANAR(info.info.raw.format)) { + port->blocks = info.info.raw.channels; } else { - port->blocks = info.info.raw.channels; + port->stride *= info.info.raw.channels; + port->blocks = 1; } spa_log_debug(this->log, NAME " %p: %d %d %d", this, port_id, port->stride, port->blocks); @@ -958,7 +940,6 @@ impl_init(const struct spa_handle_factory *factory, const char *str; int rate; - spa_return_val_if_fail(factory != NULL, -EINVAL); spa_return_val_if_fail(handle != NULL, -EINVAL); diff --git a/spa/plugins/audioconvert/resample.c b/spa/plugins/audioconvert/resample.c index c8139041e..b01d968b6 100644 --- a/spa/plugins/audioconvert/resample.c +++ b/spa/plugins/audioconvert/resample.c @@ -115,15 +115,13 @@ static int setup_convert(struct impl *this, dst_info = info; } - spa_log_info(this->log, NAME " %p: %d/%d@%d.%d->%d/%d@%d.%d", this, + spa_log_info(this->log, NAME " %p: %d/%d@%d->%d/%d@%d", this, src_info->info.raw.format, src_info->info.raw.channels, src_info->info.raw.rate, - src_info->info.raw.layout, dst_info->info.raw.format, dst_info->info.raw.channels, - dst_info->info.raw.rate, - dst_info->info.raw.layout); + dst_info->info.raw.rate); if (src_info->info.raw.channels != dst_info->info.raw.channels) return -EINVAL; @@ -285,8 +283,7 @@ static int port_enum_formats(struct spa_node *node, 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_Id(SPA_AUDIO_FORMAT_F32), - SPA_FORMAT_AUDIO_layout, &SPA_POD_Id(SPA_AUDIO_LAYOUT_NON_INTERLEAVED), + SPA_FORMAT_AUDIO_format, &SPA_POD_Id(SPA_AUDIO_FORMAT_F32P), SPA_FORMAT_AUDIO_rate, &SPA_POD_CHOICE_RANGE_Int( other->format.info.raw.rate, 1, INT32_MAX), SPA_FORMAT_AUDIO_channels, &SPA_POD_Int(other->format.info.raw.channels), @@ -296,8 +293,7 @@ static int port_enum_formats(struct spa_node *node, 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_Id(SPA_AUDIO_FORMAT_F32), - SPA_FORMAT_AUDIO_layout, &SPA_POD_Id(SPA_AUDIO_LAYOUT_NON_INTERLEAVED), + SPA_FORMAT_AUDIO_format, &SPA_POD_Id(SPA_AUDIO_FORMAT_F32P), SPA_FORMAT_AUDIO_rate, &SPA_POD_CHOICE_RANGE_Int(DEFAULT_RATE, 1, INT32_MAX), SPA_FORMAT_AUDIO_channels, &SPA_POD_CHOICE_RANGE_Int(DEFAULT_CHANNELS, 1, INT32_MAX), 0); @@ -488,9 +484,7 @@ static int port_set_format(struct spa_node *node, if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) return -EINVAL; - if (info.info.raw.format != SPA_AUDIO_FORMAT_F32) - return -EINVAL; - if (info.info.raw.layout != SPA_AUDIO_LAYOUT_NON_INTERLEAVED) + if (info.info.raw.format != SPA_AUDIO_FORMAT_F32P) return -EINVAL; port->stride = sizeof(float); diff --git a/spa/plugins/audioconvert/splitter.c b/spa/plugins/audioconvert/splitter.c index 71205a7d0..703428b70 100644 --- a/spa/plugins/audioconvert/splitter.c +++ b/spa/plugins/audioconvert/splitter.c @@ -317,23 +317,25 @@ static int port_enum_formats(struct spa_node *node, 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(12, + SPA_FORMAT_AUDIO_format, &SPA_POD_CHOICE_ENUM_Id(18, SPA_AUDIO_FORMAT_F32, + SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_F32_OE, + SPA_AUDIO_FORMAT_S32P, SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_S32_OE, + SPA_AUDIO_FORMAT_S24_32P, SPA_AUDIO_FORMAT_S24_32, SPA_AUDIO_FORMAT_S24_32_OE, + SPA_AUDIO_FORMAT_S24P, SPA_AUDIO_FORMAT_S24, SPA_AUDIO_FORMAT_S24_OE, + SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_S16, SPA_AUDIO_FORMAT_S16_OE, + SPA_AUDIO_FORMAT_U8P, SPA_AUDIO_FORMAT_U8), - SPA_FORMAT_AUDIO_layout, &SPA_POD_CHOICE_ENUM_Id(3, - SPA_AUDIO_LAYOUT_INTERLEAVED, - SPA_AUDIO_LAYOUT_INTERLEAVED, - SPA_AUDIO_LAYOUT_NON_INTERLEAVED), SPA_FORMAT_AUDIO_rate, prate, SPA_FORMAT_AUDIO_channels, &SPA_POD_Int(this->port_count), 0); @@ -343,8 +345,7 @@ static int port_enum_formats(struct spa_node *node, 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_Id(SPA_AUDIO_FORMAT_F32), - SPA_FORMAT_AUDIO_layout, &SPA_POD_Id(SPA_AUDIO_LAYOUT_NON_INTERLEAVED), + SPA_FORMAT_AUDIO_format, &SPA_POD_Id(SPA_AUDIO_FORMAT_F32P), SPA_FORMAT_AUDIO_rate, prate, SPA_FORMAT_AUDIO_channels, &SPA_POD_Int(1), 0); @@ -513,33 +514,21 @@ static int setup_convert(struct impl *this) src_fmt = inport->format.info.raw.format; dst_fmt = outport->format.info.raw.format; - spa_log_info(this->log, NAME " %p: %s/%d@%d.%dx%d->%s/%d@%d.%d", this, + spa_log_info(this->log, NAME " %p: %s/%d@%dx%d->%s/%d@%d", this, spa_debug_type_find_name(spa_type_audio_format, src_fmt), inport->format.info.raw.channels, inport->format.info.raw.rate, - inport->format.info.raw.layout, this->port_count, spa_debug_type_find_name(spa_type_audio_format, dst_fmt), outport->format.info.raw.channels, - outport->format.info.raw.rate, - outport->format.info.raw.layout); + outport->format.info.raw.rate); conv = find_conv_info(src_fmt, dst_fmt, FEATURE_SSE); if (conv != NULL) { spa_log_info(this->log, NAME " %p: got converter features %08x", this, conv->features); - if (inport->format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) { - if (outport->format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) - this->convert = conv->i2i; - else - this->convert = conv->i2d; - } - else { - if (outport->format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) - this->convert = conv->d2i; - else - this->convert = conv->i2i; - } + + this->convert = conv->func; return 0; } return -ENOTSUP; @@ -549,10 +538,13 @@ static int calc_width(struct spa_audio_info *info) { switch (info->info.raw.format) { case SPA_AUDIO_FORMAT_U8: + case SPA_AUDIO_FORMAT_U8P: return 1; + case SPA_AUDIO_FORMAT_S16P: case SPA_AUDIO_FORMAT_S16: case SPA_AUDIO_FORMAT_S16_OE: return 2; + case SPA_AUDIO_FORMAT_S24P: case SPA_AUDIO_FORMAT_S24: case SPA_AUDIO_FORMAT_S24_OE: return 3; @@ -603,9 +595,7 @@ static int port_set_format(struct spa_node *node, if (info.info.raw.channels != this->port_count) return -EINVAL; } else { - if (info.info.raw.format != SPA_AUDIO_FORMAT_F32) - return -EINVAL; - if (info.info.raw.layout != SPA_AUDIO_LAYOUT_NON_INTERLEAVED) + if (info.info.raw.format != SPA_AUDIO_FORMAT_F32P) return -EINVAL; if (info.info.raw.channels != 1) return -EINVAL; @@ -613,13 +603,12 @@ static int port_set_format(struct spa_node *node, port->format = info; port->stride = calc_width(&info); - if (info.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) { + if (SPA_AUDIO_FORMAT_IS_PLANAR(info.info.raw.format)) { + port->blocks = info.info.raw.channels; + } else { port->stride *= info.info.raw.channels; port->blocks = 1; } - else { - port->blocks = info.info.raw.channels; - } spa_log_debug(this->log, NAME " %p: %d %d %d", this, port_id, port->stride, port->blocks); this->have_format = true; diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index b8d055a75..9213dfe76 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -541,7 +541,6 @@ port_enum_formats(struct impl *this, SPA_AUDIO_FORMAT_S32, SPA_AUDIO_FORMAT_F32, SPA_AUDIO_FORMAT_F64), - SPA_FORMAT_AUDIO_layout, &SPA_POD_Id(SPA_AUDIO_LAYOUT_INTERLEAVED), SPA_FORMAT_AUDIO_rate, &SPA_POD_CHOICE_RANGE_Int(44100, 1, INT32_MAX), SPA_FORMAT_AUDIO_channels, &SPA_POD_CHOICE_RANGE_Int(2, 1, INT32_MAX), 0); diff --git a/spa/plugins/bluez5/a2dp-sink.c b/spa/plugins/bluez5/a2dp-sink.c index 5c719040a..230c2226e 100644 --- a/spa/plugins/bluez5/a2dp-sink.c +++ b/spa/plugins/bluez5/a2dp-sink.c @@ -975,7 +975,6 @@ impl_node_port_enum_params(struct spa_node *node, 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_Id(SPA_AUDIO_FORMAT_S16), - SPA_FORMAT_AUDIO_layout, &SPA_POD_Id(SPA_AUDIO_LAYOUT_INTERLEAVED), SPA_FORMAT_AUDIO_rate, &SPA_POD_Int(rate), SPA_FORMAT_AUDIO_channels, &SPA_POD_Int(channels), 0); diff --git a/spa/tests/test-control.c b/spa/tests/test-control.c index e780766f9..4eabcfa26 100644 --- a/spa/tests/test-control.c +++ b/spa/tests/test-control.c @@ -377,7 +377,6 @@ static int negotiate_formats(struct data *data) filter = spa_format_audio_raw_build(&b, 0, &SPA_AUDIO_INFO_RAW_INIT( .format = SPA_AUDIO_FORMAT_S16, - .layout = SPA_AUDIO_LAYOUT_INTERLEAVED, .rate = 44100, .channels = 2 )); diff --git a/spa/tests/test-convert.c b/spa/tests/test-convert.c index 66de30e7b..ae27d8484 100644 --- a/spa/tests/test-convert.c +++ b/spa/tests/test-convert.c @@ -210,7 +210,6 @@ static int negotiate_formats(struct data *data) format = spa_format_audio_raw_build(&b, 0, &SPA_AUDIO_INFO_RAW_INIT( .format = SPA_AUDIO_FORMAT_S16, - .layout = SPA_AUDIO_LAYOUT_INTERLEAVED, .rate = 44100, .channels = 2 )); @@ -236,8 +235,7 @@ static int negotiate_formats(struct data *data) spa_pod_builder_init(&b, buffer, sizeof(buffer)); format = spa_format_audio_raw_build(&b, 0, &SPA_AUDIO_INFO_RAW_INIT( - .format = SPA_AUDIO_FORMAT_F32, - .layout = SPA_AUDIO_LAYOUT_NON_INTERLEAVED, + .format = SPA_AUDIO_FORMAT_F32P, .rate = 44100, .channels = 2 )); diff --git a/spa/tests/test-convert2.c b/spa/tests/test-convert2.c index 7af8458cd..a8b4a445e 100644 --- a/spa/tests/test-convert2.c +++ b/spa/tests/test-convert2.c @@ -260,7 +260,6 @@ static int negotiate_formats(struct data *data) format = spa_format_audio_raw_build(&b, 0, &SPA_AUDIO_INFO_RAW_INIT( .format = SPA_AUDIO_FORMAT_S16, - .layout = SPA_AUDIO_LAYOUT_INTERLEAVED, .rate = 44100, .channels = 2 )); @@ -270,8 +269,7 @@ static int negotiate_formats(struct data *data) spa_pod_builder_init(&b, buffer, sizeof(buffer)); format = spa_format_audio_raw_build(&b, 0, &SPA_AUDIO_INFO_RAW_INIT( - .format = SPA_AUDIO_FORMAT_S16, - .layout = SPA_AUDIO_LAYOUT_NON_INTERLEAVED, + .format = SPA_AUDIO_FORMAT_S16P, .rate = 48000, .channels = 1 )); diff --git a/spa/tests/test-graph.c b/spa/tests/test-graph.c index 6487a6729..c0352cfab 100644 --- a/spa/tests/test-graph.c +++ b/spa/tests/test-graph.c @@ -351,7 +351,6 @@ static int negotiate_formats(struct data *data) filter = spa_format_audio_raw_build(&b, 0, &SPA_AUDIO_INFO_RAW_INIT( .format = SPA_AUDIO_FORMAT_S16, - .layout = SPA_AUDIO_LAYOUT_INTERLEAVED, .rate = 44100, .channels = 2 )); diff --git a/spa/tests/test-mixer.c b/spa/tests/test-mixer.c index 1998a10ed..48e65cf95 100644 --- a/spa/tests/test-mixer.c +++ b/spa/tests/test-mixer.c @@ -478,7 +478,6 @@ static int negotiate_formats(struct data *data) filter = spa_format_audio_raw_build(&b, 0, &SPA_AUDIO_INFO_RAW_INIT( .format = SPA_AUDIO_FORMAT_S16, - .layout = SPA_AUDIO_LAYOUT_INTERLEAVED, .rate = 44100, .channels = 2 )); diff --git a/spa/tests/test-ringbuffer.c b/spa/tests/test-ringbuffer.c index 4a67258de..91f5b3577 100644 --- a/spa/tests/test-ringbuffer.c +++ b/spa/tests/test-ringbuffer.c @@ -275,7 +275,6 @@ static int negotiate_formats(struct data *data) filter = spa_format_audio_raw_build(&b, 0, &SPA_AUDIO_INFO_RAW_INIT( .format = SPA_AUDIO_FORMAT_S16, - .layout = SPA_AUDIO_LAYOUT_INTERLEAVED, .rate = 44100, .channels = 2 )); diff --git a/src/examples/audio-src.c b/src/examples/audio-src.c index 741627a00..03af12841 100644 --- a/src/examples/audio-src.c +++ b/src/examples/audio-src.c @@ -115,7 +115,6 @@ int main(int argc, char *argv[]) params[0] = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &SPA_AUDIO_INFO_RAW_INIT( .format = SPA_AUDIO_FORMAT_F32, - .layout = SPA_AUDIO_LAYOUT_INTERLEAVED, .channels = DEFAULT_CHANNELS, .rate = DEFAULT_RATE )); diff --git a/src/examples/export-source.c b/src/examples/export-source.c index 8b5f893d2..f7c9abb98 100644 --- a/src/examples/export-source.c +++ b/src/examples/export-source.c @@ -179,14 +179,12 @@ static int port_enum_formats(struct spa_node *node, 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(3, + SPA_FORMAT_AUDIO_format, &SPA_POD_CHOICE_ENUM_Id(5, SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S16P, SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_F32P, SPA_AUDIO_FORMAT_F32), - SPA_FORMAT_AUDIO_layout, &SPA_POD_CHOICE_ENUM_Id(3, - SPA_AUDIO_LAYOUT_INTERLEAVED, - SPA_AUDIO_LAYOUT_INTERLEAVED, - SPA_AUDIO_LAYOUT_NON_INTERLEAVED), SPA_FORMAT_AUDIO_channels, &SPA_POD_CHOICE_RANGE_Int(2, 1, INT32_MAX), SPA_FORMAT_AUDIO_rate, &SPA_POD_CHOICE_RANGE_Int(44100, 1, INT32_MAX), 0); diff --git a/src/examples/media-session.c b/src/examples/media-session.c index 3c77ea71e..6acdca71d 100644 --- a/src/examples/media-session.c +++ b/src/examples/media-session.c @@ -190,8 +190,8 @@ static void node_proxy_destroy(void *data) if (n->info) pw_node_info_free(n->info); if (n->session) { - n->session = NULL; spa_list_remove(&n->session_link); + n->session = NULL; } } @@ -276,6 +276,11 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id, sess->need_dsp = need_dsp; sess->enabled = true; sess->node = node; + if ((str = spa_dict_lookup(props, "node.plugged")) != NULL) + sess->plugged = pw_properties_parse_uint64(str); + else + sess->plugged = SPA_TIMESPEC_TO_TIME(&impl->now); + spa_list_init(&sess->node_list); spa_list_append(&impl->session_list, &sess->l); @@ -397,8 +402,6 @@ registry_global(void *data,uint32_t id, uint32_t parent_id, { struct impl *impl = data; - clock_gettime(CLOCK_MONOTONIC, &impl->now); - pw_log_debug(NAME " %p: new global '%d'", impl, id); switch (type) { @@ -699,7 +702,6 @@ static void dsp_node_event_info(void *object, struct pw_node_info *info) s->dsp = dsp; spa_hook_remove(&s->listener); - dsp->session = s; dsp->direction = s->direction; dsp->type = NODE_TYPE_DSP; } @@ -727,7 +729,7 @@ static void rescan_session(struct impl *impl, struct session *sess) props = pw_properties_new_dict(node->info->props); pw_properties_setf(props, "audio-dsp.direction", "%d", sess->direction); pw_properties_setf(props, "audio-dsp.channels", "%d", node->format.channels); - pw_properties_setf(props, "audio-dsp.channelmask", "%"PRIu64, node->format.channel_mask); + pw_properties_setf(props, "audio-dsp.channelmask", "%d", 0); pw_properties_setf(props, "audio-dsp.rate", "%d", node->format.rate); pw_properties_setf(props, "audio-dsp.maxbuffer", "%ld", MAX_QUANTUM_SIZE * sizeof(float)); @@ -749,6 +751,8 @@ static void do_rescan(struct impl *impl) struct session *sess; struct node *node; + clock_gettime(CLOCK_MONOTONIC, &impl->now); + spa_list_for_each(sess, &impl->session_list, l) rescan_session(impl, sess); spa_list_for_each(node, &impl->node_list, l) diff --git a/src/gst/gstpipewireformat.c b/src/gst/gstpipewireformat.c index bd5e690ba..465bbfb7e 100644 --- a/src/gst/gstpipewireformat.c +++ b/src/gst/gstpipewireformat.c @@ -454,6 +454,7 @@ handle_audio_fields (ConvertData *d) choice->body.type = SPA_CHOICE_None; } +#if 0 value = gst_structure_get_value (d->cs, "layout"); if (value) { const char *v; @@ -478,6 +479,7 @@ handle_audio_fields (ConvertData *d) if (i <= 1) choice->body.type = SPA_CHOICE_None; } +#endif value = gst_structure_get_value (d->cs, "rate"); if (value) { int v; diff --git a/src/modules/module-client-node/client-stream.c b/src/modules/module-client-node/client-stream.c index 221c17538..c285e9587 100644 --- a/src/modules/module-client-node/client-stream.c +++ b/src/modules/module-client-node/client-stream.c @@ -896,6 +896,9 @@ static void client_node_initialized(void *data) spa_debug_type_find_name(spa_type_media_subtype, media_subtype)); + if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG)) + spa_debug_format(2, NULL, format); + if (!exclusive && media_type == SPA_MEDIA_TYPE_audio && media_subtype == SPA_MEDIA_SUBTYPE_raw) { diff --git a/src/modules/module-media-session.c b/src/modules/module-media-session.c index 9969ad9ab..e5f444551 100644 --- a/src/modules/module-media-session.c +++ b/src/modules/module-media-session.c @@ -646,7 +646,6 @@ static int collect_audio_format(void *data, uint32_t id, if (info.channels > d->channels) { d->channels = info.channels; - d->channelmask = info.channel_mask; d->rate = info.rate; } return 0; diff --git a/src/modules/module-media-session/audio-dsp.c b/src/modules/module-media-session/audio-dsp.c index 8a8f6f9f6..696489603 100644 --- a/src/modules/module-media-session/audio-dsp.c +++ b/src/modules/module-media-session/audio-dsp.c @@ -144,7 +144,8 @@ static const struct pw_port_implementation port_implementation = { static const char *chmap_names[] = { - "FL", + "MONO", /**< mono */ + "FL", /**< front left */ "FR", /**< front right */ "RL", /**< rear left */ "RR", /**< rear right */ @@ -242,6 +243,8 @@ struct pw_node *pw_audio_dsp_new(struct pw_core *core, pw_properties_set(pr, "node.session", str); pw_properties_setf(pr, "node.format.rate", "%d", sample_rate); + pw_properties_setf(pr, "node.format.channels", "%d", channels); + pw_properties_setf(pr, "node.format.channelmask", "%"PRIu64, channelmask); node = pw_spa_node_load(core, NULL, NULL, "audioconvert/libspa-audioconvert", @@ -293,6 +296,7 @@ struct pw_node *pw_audio_dsp_new(struct pw_core *core, alias, direction == PW_DIRECTION_INPUT ? "in" : "out", channel_name); + pw_properties_setf(props, "port.channel", "%s", channel_name); port = pw_port_new(direction, i, diff --git a/src/modules/module-media-session/floatmix.c b/src/modules/module-media-session/floatmix.c index dc8afd06f..aa00f15f3 100644 --- a/src/modules/module-media-session/floatmix.c +++ b/src/modules/module-media-session/floatmix.c @@ -331,8 +331,7 @@ static int port_enum_formats(struct spa_node *node, 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_Id(SPA_AUDIO_FORMAT_F32), - SPA_FORMAT_AUDIO_layout, &SPA_POD_Id(SPA_AUDIO_LAYOUT_NON_INTERLEAVED), + SPA_FORMAT_AUDIO_format, &SPA_POD_Id(SPA_AUDIO_FORMAT_F32P), SPA_FORMAT_AUDIO_rate, &SPA_POD_CHOICE_RANGE_Int(44100, 1, INT32_MAX), SPA_FORMAT_AUDIO_channels, &SPA_POD_Int(1), 0); @@ -550,7 +549,7 @@ static int port_set_format(struct spa_node *node, if (memcmp(&info, &this->format, sizeof(struct spa_audio_info))) return -EINVAL; } else { - if (info.info.raw.format != SPA_AUDIO_FORMAT_F32) + if (info.info.raw.format != SPA_AUDIO_FORMAT_F32P) return -EINVAL; this->stride = sizeof(float); diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index 8889cebfd..55247f36b 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -777,8 +777,8 @@ static void port_marshal_info(void *object, struct pw_port_info *info) spa_pod_builder_add(b, "[", "i", info->id, + "i", info->direction, "l", info->change_mask, - "s", info->name, "i", n_items, NULL); for (i = 0; i < n_items; i++) { @@ -803,8 +803,8 @@ static int port_demarshal_info(void *object, void *data, size_t size) if (spa_pod_parser_get(&prs, "[" "i", &info.id, + "i", &info.direction, "l", &info.change_mask, - "s", &info.name, "i", &props.n_items, NULL) < 0) return -EINVAL; diff --git a/src/pipewire/introspect.c b/src/pipewire/introspect.c index d9aed7fa8..9778ee986 100644 --- a/src/pipewire/introspect.c +++ b/src/pipewire/introspect.c @@ -242,13 +242,9 @@ struct pw_port_info *pw_port_info_update(struct pw_port_info *info, return NULL; } info->id = update->id; + info->direction = update->direction; info->change_mask = update->change_mask; - if (update->change_mask & PW_PORT_CHANGE_MASK_NAME) { - if (info->name) - free((void *) info->name); - info->name = update->name ? strdup(update->name) : NULL; - } if (update->change_mask & PW_PORT_CHANGE_MASK_PROPS) { if (info->props) pw_spa_dict_destroy(info->props); @@ -260,8 +256,6 @@ struct pw_port_info *pw_port_info_update(struct pw_port_info *info, void pw_port_info_free(struct pw_port_info *info) { - if (info->name) - free((void *) info->name); if (info->props) pw_spa_dict_destroy(info->props); free(info); diff --git a/src/pipewire/introspect.h b/src/pipewire/introspect.h index fd51d70e3..b16a8e07f 100644 --- a/src/pipewire/introspect.h +++ b/src/pipewire/introspect.h @@ -167,11 +167,10 @@ pw_node_info_free(struct pw_node_info *info); struct pw_port_info { uint32_t id; /**< id of the global */ -#define PW_PORT_CHANGE_MASK_NAME (1 << 0) -#define PW_PORT_CHANGE_MASK_PROPS (1 << 1) -#define PW_PORT_CHANGE_MASK_ENUM_PARAMS (1 << 2) + enum pw_direction direction; /**< port direction */ +#define PW_PORT_CHANGE_MASK_PROPS (1 << 0) +#define PW_PORT_CHANGE_MASK_ENUM_PARAMS (1 << 1) uint64_t change_mask; /**< bitfield of changed fields since last call */ - const char *name; /**< name the port, suitable for display */ struct spa_dict *props; /**< the properties of the port */ }; diff --git a/src/pipewire/node.c b/src/pipewire/node.c index c112ff21c..0e5aae9f2 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -889,8 +889,8 @@ uint32_t pw_node_get_free_port_id(struct pw_node *node, enum pw_direction direct n_ports = node->info.n_output_ports; portmap = &node->output_port_map; } - pw_log_debug("node %p: direction %d %u %u", - node, direction, n_ports, max_ports); + pw_log_debug("node %p: direction %s n_ports:%u max_ports:%u", + node, pw_direction_as_string(direction), n_ports, max_ports); if (n_ports >= max_ports) goto no_mem; diff --git a/src/pipewire/port.c b/src/pipewire/port.c index ebdfa516d..9fe5ab7a2 100644 --- a/src/pipewire/port.c +++ b/src/pipewire/port.c @@ -214,6 +214,7 @@ struct pw_port *pw_port_new(enum pw_direction direction, if (user_data_size > 0) this->user_data = SPA_MEMBER(impl, sizeof(struct impl), void); + this->info.direction = direction; this->info.props = &this->properties->dict; spa_list_init(&this->links); diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c index b619f1f9f..3f28ebcff 100644 --- a/src/tools/pipewire-cli.c +++ b/src/tools/pipewire-cli.c @@ -555,9 +555,8 @@ static void info_port(struct proxy_data *pd) struct pw_port_info *info = pd->info; info_global(pd); - fprintf(stdout, "%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name); - print_properties(info->props, MARK_CHANGE(1), true); - fprintf(stdout, "%c\tenum_params\n", MARK_CHANGE(2)); + print_properties(info->props, MARK_CHANGE(0), true); + fprintf(stdout, "%c\tenum_params\n", MARK_CHANGE(1)); info->change_mask = 0; } diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c index a64cfd786..8474afaf7 100644 --- a/src/tools/pipewire-monitor.c +++ b/src/tools/pipewire-monitor.c @@ -289,8 +289,8 @@ static void print_port(struct proxy_data *data) printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Port, data->version); if (print_all) { int i; - printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name); - printf("%c\tparams:\n", MARK_CHANGE(2)); + printf(" \tdirection: \"%s\"\n", pw_direction_as_string(info->direction)); + printf("%c\tparams:\n", MARK_CHANGE(1)); for (i = 0; i < data->n_params; i++) { if (spa_pod_is_object_type(data->params[i], SPA_TYPE_OBJECT_Format)) spa_debug_format(12, NULL, data->params[i]);