mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-10-29 05:40:27 -04:00 
			
		
		
		
	json: add helper function to parse channel positions
Use the helper instead of duplicating the same code. Also add some helpers to parse a json array of uint32_t Move some functions to convert between type name and id.
This commit is contained in:
		
							parent
							
								
									911a601b95
								
							
						
					
					
						commit
						e2991f6398
					
				
					 34 changed files with 256 additions and 791 deletions
				
			
		|  | @ -772,7 +772,7 @@ static int snd_pcm_pipewire_hw_params(snd_pcm_ioplug_t * io, | ||||||
| 		pw->requested.info.raw.channels = io->channels; | 		pw->requested.info.raw.channels = io->channels; | ||||||
| 		pw->requested.info.raw.rate = io->rate; | 		pw->requested.info.raw.rate = io->rate; | ||||||
| 		set_default_channels(io->channels, pw->requested.info.raw.position); | 		set_default_channels(io->channels, pw->requested.info.raw.position); | ||||||
| 		fmt_str = spa_debug_type_find_name(spa_type_audio_format, pw->requested.info.raw.format); | 		fmt_str = spa_type_audio_format_to_short_name(pw->requested.info.raw.format); | ||||||
| 		pw->format = pw->requested; | 		pw->format = pw->requested; | ||||||
| 		break; | 		break; | ||||||
| 	case SPA_MEDIA_SUBTYPE_dsd: | 	case SPA_MEDIA_SUBTYPE_dsd: | ||||||
|  |  | ||||||
|  | @ -33,6 +33,14 @@ static const struct spa_type_info spa_type_audio_iec958_codec[] = { | ||||||
| 	{ 0, 0, NULL, NULL }, | 	{ 0, 0, NULL, NULL }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | static inline uint32_t spa_type_audio_iec958_codec_from_short_name(const char *name) | ||||||
|  | { | ||||||
|  | 	return spa_type_from_short_name(name, spa_type_audio_iec958_codec, SPA_AUDIO_IEC958_CODEC_UNKNOWN); | ||||||
|  | } | ||||||
|  | static inline const char * spa_type_audio_iec958_codec_to_short_name(uint32_t type) | ||||||
|  | { | ||||||
|  | 	return spa_type_to_short_name(type, spa_type_audio_iec958_codec, "UNKNOWN"); | ||||||
|  | } | ||||||
| /**
 | /**
 | ||||||
|  * \} |  * \} | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
							
								
								
									
										47
									
								
								spa/include/spa/param/audio/raw-json.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								spa/include/spa/param/audio/raw-json.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | ||||||
|  | /* Simple Plugin API */ | ||||||
|  | /* SPDX-FileCopyrightText: Copyright © 2024 Wim Taymans */ | ||||||
|  | /* SPDX-License-Identifier: MIT */ | ||||||
|  | 
 | ||||||
|  | #ifndef SPA_AUDIO_RAW_JSON_H | ||||||
|  | #define SPA_AUDIO_RAW_JSON_H | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \addtogroup spa_param | ||||||
|  |  * \{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <spa/utils/json.h> | ||||||
|  | #include <spa/param/audio/raw-types.h> | ||||||
|  | 
 | ||||||
|  | static inline int | ||||||
|  | spa_audio_parse_position(const char *str, size_t len, | ||||||
|  | 		uint32_t *position, uint32_t *n_channels) | ||||||
|  | { | ||||||
|  | 	struct spa_json iter; | ||||||
|  |         char v[256]; | ||||||
|  | 	uint32_t channels = 0; | ||||||
|  | 
 | ||||||
|  |         if (spa_json_begin_array_relax(&iter, str, len) <= 0) | ||||||
|  |                 return 0; | ||||||
|  | 
 | ||||||
|  |         while (spa_json_get_string(&iter, v, sizeof(v)) > 0 && | ||||||
|  | 		channels < SPA_AUDIO_MAX_CHANNELS) { | ||||||
|  |                 position[channels++] = spa_type_audio_channel_from_short_name(v); | ||||||
|  |         } | ||||||
|  | 	*n_channels = channels; | ||||||
|  | 	return channels; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \} | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }  /* extern "C" */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* SPA_AUDIO_RAW_JSON_H */ | ||||||
|  | @ -129,6 +129,15 @@ static const struct spa_type_info spa_type_audio_format[] = { | ||||||
| 	{ 0, 0, NULL, NULL }, | 	{ 0, 0, NULL, NULL }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | static inline uint32_t spa_type_audio_format_from_short_name(const char *name) | ||||||
|  | { | ||||||
|  | 	return spa_type_from_short_name(name, spa_type_audio_format, SPA_AUDIO_FORMAT_UNKNOWN); | ||||||
|  | } | ||||||
|  | static inline const char * spa_type_audio_format_to_short_name(uint32_t type) | ||||||
|  | { | ||||||
|  | 	return spa_type_to_short_name(type, spa_type_audio_format, "UNKNOWN"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #define SPA_TYPE_INFO_AudioFlags	SPA_TYPE_INFO_FLAGS_BASE "AudioFlags" | #define SPA_TYPE_INFO_AudioFlags	SPA_TYPE_INFO_FLAGS_BASE "AudioFlags" | ||||||
| #define SPA_TYPE_INFO_AUDIO_FLAGS_BASE	SPA_TYPE_INFO_AudioFlags ":" | #define SPA_TYPE_INFO_AUDIO_FLAGS_BASE	SPA_TYPE_INFO_AudioFlags ":" | ||||||
| 
 | 
 | ||||||
|  | @ -250,12 +259,11 @@ static const struct spa_type_info spa_type_audio_channel[] = { | ||||||
| 
 | 
 | ||||||
| static inline uint32_t spa_type_audio_channel_from_short_name(const char *name) | static inline uint32_t spa_type_audio_channel_from_short_name(const char *name) | ||||||
| { | { | ||||||
| 	int i; | 	return spa_type_from_short_name(name, spa_type_audio_channel, SPA_AUDIO_CHANNEL_UNKNOWN); | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { | } | ||||||
| 		if (spa_streq(name, spa_type_short_name(spa_type_audio_channel[i].name))) | static inline const char * spa_type_audio_channel_to_short_name(uint32_t type) | ||||||
| 			return spa_type_audio_channel[i].type; | { | ||||||
| 	} | 	return spa_type_to_short_name(type, spa_type_audio_channel, "UNK"); | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,7 +20,8 @@ extern "C" { | ||||||
| #define SPA_TYPE_INFO_VIDEO_FORMAT_BASE		SPA_TYPE_INFO_VideoFormat ":" | #define SPA_TYPE_INFO_VIDEO_FORMAT_BASE		SPA_TYPE_INFO_VideoFormat ":" | ||||||
| 
 | 
 | ||||||
| static const struct spa_type_info spa_type_video_format[] = { | static const struct spa_type_info spa_type_video_format[] = { | ||||||
| 	{ SPA_VIDEO_FORMAT_ENCODED,	SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "encoded", NULL }, | 	{ SPA_VIDEO_FORMAT_UNKNOWN,	SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "UNKNOWN", NULL }, | ||||||
|  | 	{ SPA_VIDEO_FORMAT_ENCODED,	SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "ENCODED", NULL }, | ||||||
| 	{ SPA_VIDEO_FORMAT_I420,	SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "I420", NULL }, | 	{ SPA_VIDEO_FORMAT_I420,	SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "I420", NULL }, | ||||||
| 	{ SPA_VIDEO_FORMAT_YV12,	SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "YV12", NULL }, | 	{ SPA_VIDEO_FORMAT_YV12,	SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "YV12", NULL }, | ||||||
| 	{ SPA_VIDEO_FORMAT_YUY2,	SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "YUY2", NULL }, | 	{ SPA_VIDEO_FORMAT_YUY2,	SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "YUY2", NULL }, | ||||||
|  | @ -110,6 +111,15 @@ static const struct spa_type_info spa_type_video_format[] = { | ||||||
| 	{ 0, 0, NULL, NULL }, | 	{ 0, 0, NULL, NULL }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | static inline uint32_t spa_type_video_format_from_short_name(const char *name) | ||||||
|  | { | ||||||
|  | 	return spa_type_from_short_name(name, spa_type_video_format, SPA_VIDEO_FORMAT_UNKNOWN); | ||||||
|  | } | ||||||
|  | static inline const char * spa_type_video_format_to_short_name(uint32_t type) | ||||||
|  | { | ||||||
|  | 	return spa_type_to_short_name(type, spa_type_video_format, "UNKNOWN"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #define SPA_TYPE_INFO_VideoFlags	SPA_TYPE_INFO_FLAGS_BASE "VideoFlags" | #define SPA_TYPE_INFO_VideoFlags	SPA_TYPE_INFO_FLAGS_BASE "VideoFlags" | ||||||
| #define SPA_TYPE_INFO_VIDEO_FLAGS_BASE	SPA_TYPE_INFO_VideoFlags ":" | #define SPA_TYPE_INFO_VIDEO_FLAGS_BASE	SPA_TYPE_INFO_VideoFlags ":" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -185,6 +185,24 @@ static inline int spa_json_begin_array(struct spa_json * iter, const char *data, | ||||||
| 	return spa_json_begin_container(iter, data, size, '[', false); | 	return spa_json_begin_container(iter, data, size, '[', false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #define spa_json_make_str_array_unpack(maxlen,type,conv)			\ | ||||||
|  | {										\ | ||||||
|  | 	struct spa_json iter;							\ | ||||||
|  | 	char v[maxlen];								\ | ||||||
|  | 	uint32_t count = 0;							\ | ||||||
|  |         if (spa_json_begin_array_relax(&iter, arr, arr_len) <= 0)		\ | ||||||
|  | 		return -EINVAL;							\ | ||||||
|  | 	while (spa_json_get_string(&iter, v, sizeof(v)) > 0 && count < max)	\ | ||||||
|  | 		values[count++] = conv(v);					\ | ||||||
|  | 	return count;								\ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int spa_json_str_array_uint32(const char *arr, size_t arr_len, | ||||||
|  | 		uint32_t *values, size_t max) | ||||||
|  | { | ||||||
|  | 	spa_json_make_str_array_unpack(32,uint32_t, atoi); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \} |  * \} | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #include <spa/utils/defs.h> | #include <spa/utils/defs.h> | ||||||
|  | #include <spa/utils/string.h> | ||||||
| 
 | 
 | ||||||
| /** \defgroup spa_types Types
 | /** \defgroup spa_types Types
 | ||||||
|  * Data type information enumerations |  * Data type information enumerations | ||||||
|  | @ -136,6 +137,34 @@ static inline const char *spa_type_short_name(const char *name) | ||||||
| 	return name; | 	return name; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static inline uint32_t spa_type_from_short_name(const char *name, | ||||||
|  | 		const struct spa_type_info *info, uint32_t unknown) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	for (i = 0; info[i].name; i++) { | ||||||
|  | 		if (spa_streq(name, spa_type_short_name(info[i].name))) | ||||||
|  | 			return info[i].type; | ||||||
|  | 	} | ||||||
|  | 	return unknown; | ||||||
|  | } | ||||||
|  | static inline const char * spa_type_to_name(uint32_t type, | ||||||
|  | 		const struct spa_type_info *info, const char *unknown) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	for (i = 0; info[i].name; i++) { | ||||||
|  | 		if (info[i].type == type) | ||||||
|  | 			return info[i].name; | ||||||
|  | 	} | ||||||
|  | 	return unknown; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline const char * spa_type_to_short_name(uint32_t type, | ||||||
|  | 		const struct spa_type_info *info, const char *unknown) | ||||||
|  | { | ||||||
|  | 	const char *n = spa_type_to_name(type, info, unknown); | ||||||
|  | 	return n ? spa_type_short_name(n) : NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \} |  * \} | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | @ -159,7 +159,7 @@ static int alsa_set_param(struct state *state, const char *k, const char *s) | ||||||
| 		state->default_rate = atoi(s); | 		state->default_rate = atoi(s); | ||||||
| 		fmt_change++; | 		fmt_change++; | ||||||
| 	} else if (spa_streq(k, SPA_KEY_AUDIO_FORMAT)) { | 	} else if (spa_streq(k, SPA_KEY_AUDIO_FORMAT)) { | ||||||
| 		state->default_format = spa_alsa_format_from_name(s, strlen(s)); | 		state->default_format = spa_type_audio_format_from_short_name(s); | ||||||
| 		fmt_change++; | 		fmt_change++; | ||||||
| 	} else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { | 	} else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { | ||||||
| 		spa_alsa_parse_position(&state->default_pos, s, strlen(s)); | 		spa_alsa_parse_position(&state->default_pos, s, strlen(s)); | ||||||
|  | @ -2041,7 +2041,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_ | ||||||
| 		unsigned aes3; | 		unsigned aes3; | ||||||
| 
 | 
 | ||||||
| 		spa_log_info(state->log, "using IEC958 Codec:%s rate:%d", | 		spa_log_info(state->log, "using IEC958 Codec:%s rate:%d", | ||||||
| 				spa_debug_type_find_short_name(spa_type_audio_iec958_codec, f->codec), | 				spa_type_audio_iec958_codec_to_short_name(f->codec), | ||||||
| 				f->rate); | 				f->rate); | ||||||
| 
 | 
 | ||||||
| 		rformat = SND_PCM_FORMAT_S16_LE; | 		rformat = SND_PCM_FORMAT_S16_LE; | ||||||
|  |  | ||||||
|  | @ -30,6 +30,7 @@ extern "C" { | ||||||
| #include <spa/param/param.h> | #include <spa/param/param.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/param/tag-utils.h> | #include <spa/param/tag-utils.h> | ||||||
| 
 | 
 | ||||||
| #include "alsa.h" | #include "alsa.h" | ||||||
|  | @ -303,64 +304,19 @@ void spa_alsa_recycle_buffer(struct state *state, uint32_t buffer_id); | ||||||
| void spa_alsa_emit_node_info(struct state *state, bool full); | void spa_alsa_emit_node_info(struct state *state, bool full); | ||||||
| void spa_alsa_emit_port_info(struct state *state, bool full); | void spa_alsa_emit_port_info(struct state *state, bool full); | ||||||
| 
 | 
 | ||||||
| static inline uint32_t spa_alsa_format_from_name(const char *name, size_t len) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (strncmp(name, spa_debug_type_short_name(spa_type_audio_format[i].name), len) == 0) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline uint32_t spa_alsa_channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (strcmp(name, spa_debug_type_short_name(spa_type_audio_channel[i].name)) == 0) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline void spa_alsa_parse_position(struct channel_map *map, const char *val, size_t len) | static inline void spa_alsa_parse_position(struct channel_map *map, const char *val, size_t len) | ||||||
| { | { | ||||||
| 	struct spa_json it[1]; | 	spa_audio_parse_position(val, len, map->pos, &map->channels); | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	map->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    map->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		map->pos[map->channels++] = spa_alsa_channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline uint32_t spa_alsa_parse_rates(uint32_t *rates, uint32_t max, const char *val, size_t len) | static inline uint32_t spa_alsa_parse_rates(uint32_t *rates, uint32_t max, const char *val, size_t len) | ||||||
| { | { | ||||||
| 	struct spa_json it[1]; | 	return spa_json_str_array_uint32(val, len, rates, max); | ||||||
| 	char v[256]; |  | ||||||
| 	uint32_t count; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return 0; |  | ||||||
| 
 |  | ||||||
| 	count = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && count < max) |  | ||||||
| 		rates[count++] = atoi(v); |  | ||||||
| 	return count; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline uint32_t spa_alsa_iec958_codec_from_name(const char *name) | static inline uint32_t spa_alsa_iec958_codec_from_name(const char *name) | ||||||
| { | { | ||||||
| 	int i; | 	return spa_type_audio_iec958_codec_from_short_name(name); | ||||||
| 	for (i = 0; spa_type_audio_iec958_codec[i].name; i++) { |  | ||||||
| 		if (strcmp(name, spa_debug_type_short_name(spa_type_audio_iec958_codec[i].name)) == 0) |  | ||||||
| 			return spa_type_audio_iec958_codec[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_IEC958_CODEC_UNKNOWN; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void spa_alsa_parse_iec958_codecs(uint64_t *codecs, const char *val, size_t len) | static inline void spa_alsa_parse_iec958_codecs(uint64_t *codecs, const char *val, size_t len) | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ | ||||||
| #include <spa/node/utils.h> | #include <spa/node/utils.h> | ||||||
| #include <spa/node/keys.h> | #include <spa/node/keys.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/param/param.h> | #include <spa/param/param.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/tag-utils.h> | #include <spa/param/tag-utils.h> | ||||||
|  | @ -3413,33 +3414,6 @@ impl_get_size(const struct spa_handle_factory *factory, | ||||||
| 	return sizeof(struct impl); | 	return sizeof(struct impl); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline uint32_t parse_position(uint32_t *pos, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 	uint32_t i = 0; |  | ||||||
| 
 |  | ||||||
| 	if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return 0; |  | ||||||
| 
 |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 			i < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		pos[i++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| 	return i; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static int | static int | ||||||
| impl_init(const struct spa_handle_factory *factory, | impl_init(const struct spa_handle_factory *factory, | ||||||
| 	  struct spa_handle *handle, | 	  struct spa_handle *handle, | ||||||
|  | @ -3492,7 +3466,8 @@ impl_init(const struct spa_handle_factory *factory, | ||||||
| 				RESAMPLE_OPTION_PREFILL, spa_atob(s)); | 				RESAMPLE_OPTION_PREFILL, spa_atob(s)); | ||||||
| 		else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { | 		else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { | ||||||
| 			if (s != NULL) | 			if (s != NULL) | ||||||
| 	                        this->props.n_channels = parse_position(this->props.channel_map, s, strlen(s)); | 				spa_audio_parse_position(s, strlen(s), this->props.channel_map, | ||||||
|  | 						&this->props.n_channels); | ||||||
| 		} | 		} | ||||||
| 		else if (spa_streq(k, SPA_KEY_PORT_IGNORE_LATENCY)) | 		else if (spa_streq(k, SPA_KEY_PORT_IGNORE_LATENCY)) | ||||||
| 			this->port_ignore_latency = spa_atob(s); | 			this->port_ignore_latency = spa_atob(s); | ||||||
|  |  | ||||||
|  | @ -37,10 +37,11 @@ static int avb_set_param(struct state *state, const char *k, const char *s) | ||||||
| 		state->default_rate = atoi(s); | 		state->default_rate = atoi(s); | ||||||
| 		fmt_change++; | 		fmt_change++; | ||||||
| 	} else if (spa_streq(k, SPA_KEY_AUDIO_FORMAT)) { | 	} else if (spa_streq(k, SPA_KEY_AUDIO_FORMAT)) { | ||||||
| 		state->default_format = spa_avb_format_from_name(s, strlen(s)); | 		state->default_format = spa_type_audio_format_from_short_name(s); | ||||||
| 		fmt_change++; | 		fmt_change++; | ||||||
| 	} else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { | 	} else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { | ||||||
| 		spa_avb_parse_position(&state->default_pos, s, strlen(s)); | 		spa_audio_parse_position(s, strlen(s), state->default_pos.pos, | ||||||
|  | 				&state->default_pos.channels); | ||||||
| 		fmt_change++; | 		fmt_change++; | ||||||
| 	} else if (spa_streq(k, SPA_KEY_AUDIO_ALLOWED_RATES)) { | 	} else if (spa_streq(k, SPA_KEY_AUDIO_ALLOWED_RATES)) { | ||||||
| 		state->n_allowed_rates = spa_avb_parse_rates(state->allowed_rates, | 		state->n_allowed_rates = spa_avb_parse_rates(state->allowed_rates, | ||||||
|  |  | ||||||
|  | @ -33,6 +33,7 @@ extern "C" { | ||||||
| #include <spa/param/param.h> | #include <spa/param/param.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| 
 | 
 | ||||||
| #include "avb.h" | #include "avb.h" | ||||||
| 
 | 
 | ||||||
|  | @ -264,41 +265,6 @@ int spa_avb_skip(struct state *state); | ||||||
| 
 | 
 | ||||||
| void spa_avb_recycle_buffer(struct state *state, struct port *port, uint32_t buffer_id); | void spa_avb_recycle_buffer(struct state *state, struct port *port, uint32_t buffer_id); | ||||||
| 
 | 
 | ||||||
| static inline uint32_t spa_avb_format_from_name(const char *name, size_t len) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (strncmp(name, spa_debug_type_short_name(spa_type_audio_format[i].name), len) == 0) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline uint32_t spa_avb_channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (strcmp(name, spa_debug_type_short_name(spa_type_audio_channel[i].name)) == 0) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline void spa_avb_parse_position(struct channel_map *map, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	map->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    map->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		map->pos[map->channels++] = spa_avb_channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline uint32_t spa_avb_parse_rates(uint32_t *rates, uint32_t max, const char *val, size_t len) | static inline uint32_t spa_avb_parse_rates(uint32_t *rates, uint32_t max, const char *val, size_t len) | ||||||
| { | { | ||||||
| 	struct spa_json it[1]; | 	struct spa_json it[1]; | ||||||
|  |  | ||||||
|  | @ -502,12 +502,7 @@ static void get_channels(struct spa_bt_transport *t, bool a2dp_duplex, uint32_t | ||||||
| 
 | 
 | ||||||
| static const char *get_channel_name(uint32_t channel) | static const char *get_channel_name(uint32_t channel) | ||||||
| { | { | ||||||
|         int i; | 	return spa_type_to_short_name(channel, spa_type_audio_channel, NULL); | ||||||
|         for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_type_audio_channel[i].type == channel) |  | ||||||
| 			return spa_debug_type_short_name(spa_type_audio_channel[i].name); |  | ||||||
|         } |  | ||||||
|         return NULL; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int channel_position_cmp(const void *pa, const void *pb) | static int channel_position_cmp(const void *pa, const void *pb) | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ | ||||||
| #include <spa/node/io.h> | #include <spa/node/io.h> | ||||||
| #include <spa/node/keys.h> | #include <spa/node/keys.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/debug/types.h> | #include <spa/debug/types.h> | ||||||
| #include <spa/debug/mem.h> | #include <spa/debug/mem.h> | ||||||
| #include <spa/param/audio/type-info.h> | #include <spa/param/audio/type-info.h> | ||||||
|  | @ -859,41 +860,6 @@ impl_get_size(const struct spa_handle_factory *factory, | ||||||
| 	return sizeof(struct impl); | 	return sizeof(struct impl); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint32_t format_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_format[i].name))) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline void parse_position(struct impl *this, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	this->props.channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    this->props.channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		this->props.pos[this->props.channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int | static int | ||||||
| impl_init(const struct spa_handle_factory *factory, | impl_init(const struct spa_handle_factory *factory, | ||||||
| 	  struct spa_handle *handle, | 	  struct spa_handle *handle, | ||||||
|  | @ -975,7 +941,7 @@ impl_init(const struct spa_handle_factory *factory, | ||||||
| 		if (spa_streq(k, "clock.quantum-limit")) { | 		if (spa_streq(k, "clock.quantum-limit")) { | ||||||
| 			spa_atou32(s, &this->quantum_limit, 0); | 			spa_atou32(s, &this->quantum_limit, 0); | ||||||
| 		} else if (spa_streq(k, SPA_KEY_AUDIO_FORMAT)) { | 		} else if (spa_streq(k, SPA_KEY_AUDIO_FORMAT)) { | ||||||
| 			this->props.format = format_from_name(s); | 			this->props.format = spa_type_audio_format_from_short_name(s); | ||||||
| 		} else if (spa_streq(k, SPA_KEY_AUDIO_CHANNELS)) { | 		} else if (spa_streq(k, SPA_KEY_AUDIO_CHANNELS)) { | ||||||
| 			this->props.channels = atoi(s); | 			this->props.channels = atoi(s); | ||||||
| 		} else if (spa_streq(k, SPA_KEY_AUDIO_RATE)) { | 		} else if (spa_streq(k, SPA_KEY_AUDIO_RATE)) { | ||||||
|  | @ -983,7 +949,7 @@ impl_init(const struct spa_handle_factory *factory, | ||||||
| 		} else if (spa_streq(k, SPA_KEY_NODE_DRIVER)) { | 		} else if (spa_streq(k, SPA_KEY_NODE_DRIVER)) { | ||||||
| 			this->props.driver = spa_atob(s); | 			this->props.driver = spa_atob(s); | ||||||
| 		} else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { | 		} else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { | ||||||
| 			parse_position(this, s, strlen(s)); | 			spa_audio_parse_position(s, strlen(s), this->props.pos, &this->props.channels); | ||||||
| 		} else if (spa_streq(k, "clock.name")) { | 		} else if (spa_streq(k, "clock.name")) { | ||||||
| 			spa_scnprintf(this->props.clock_name, | 			spa_scnprintf(this->props.clock_name, | ||||||
| 					sizeof(this->props.clock_name), | 					sizeof(this->props.clock_name), | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ | ||||||
| #include <spa/pod/builder.h> | #include <spa/pod/builder.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/tag-utils.h> | #include <spa/param/tag-utils.h> | ||||||
| 
 | 
 | ||||||
|  | @ -324,31 +325,6 @@ struct stream { | ||||||
| 	unsigned int have_latency:1; | 	unsigned int have_latency:1; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -358,9 +334,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, 0); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, 0); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void ringbuffer_init(struct ringbuffer *r, void *buf, uint32_t size) | static void ringbuffer_init(struct ringbuffer *r, void *buf, uint32_t size) | ||||||
|  | @ -854,13 +831,13 @@ static int create_stream(struct stream_info *info) | ||||||
| 
 | 
 | ||||||
| 	s->info = impl->info; | 	s->info = impl->info; | ||||||
| 	if ((str = pw_properties_get(info->stream_props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(info->stream_props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(&s->info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), s->info.position, &s->info.channels); | ||||||
| 	if (s->info.channels == 0) | 	if (s->info.channels == 0) | ||||||
| 		s->info = impl->info; | 		s->info = impl->info; | ||||||
| 
 | 
 | ||||||
| 	spa_zero(remap_info); | 	spa_zero(remap_info); | ||||||
| 	if ((str = pw_properties_get(info->stream_props, "combine.audio.position")) != NULL) | 	if ((str = pw_properties_get(info->stream_props, "combine.audio.position")) != NULL) | ||||||
| 		parse_position(&remap_info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), remap_info.position, &remap_info.channels); | ||||||
| 	if (remap_info.channels == 0) | 	if (remap_info.channels == 0) | ||||||
| 		remap_info = s->info; | 		remap_info = s->info; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| #include <spa/debug/types.h> | #include <spa/debug/types.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/pod/builder.h> | #include <spa/pod/builder.h> | ||||||
| #include <spa/pod/dynamic.h> | #include <spa/pod/dynamic.h> | ||||||
|  | @ -1191,31 +1192,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -1229,9 +1205,10 @@ static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_ | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | ||||||
|  | @ -1389,17 +1366,21 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if ((str = pw_properties_get(impl->capture_props, SPA_KEY_AUDIO_POSITION)) != NULL) { | 	if ((str = pw_properties_get(impl->capture_props, SPA_KEY_AUDIO_POSITION)) != NULL) { | ||||||
| 		parse_position(&impl->capture_info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), | ||||||
|  | 				impl->capture_info.position, &impl->capture_info.channels); | ||||||
| 	} | 	} | ||||||
| 	if ((str = pw_properties_get(impl->source_props, SPA_KEY_AUDIO_POSITION)) != NULL) { | 	if ((str = pw_properties_get(impl->source_props, SPA_KEY_AUDIO_POSITION)) != NULL) { | ||||||
| 		parse_position(&impl->source_info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), | ||||||
|  | 				impl->source_info.position, &impl->source_info.channels); | ||||||
| 	} | 	} | ||||||
| 	if ((str = pw_properties_get(impl->sink_props, SPA_KEY_AUDIO_POSITION)) != NULL) { | 	if ((str = pw_properties_get(impl->sink_props, SPA_KEY_AUDIO_POSITION)) != NULL) { | ||||||
| 		parse_position(&impl->sink_info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), | ||||||
|  | 				impl->sink_info.position, &impl->sink_info.channels); | ||||||
| 		impl->playback_info = impl->sink_info; | 		impl->playback_info = impl->sink_info; | ||||||
| 	} | 	} | ||||||
| 	if ((str = pw_properties_get(impl->playback_props, SPA_KEY_AUDIO_POSITION)) != NULL) { | 	if ((str = pw_properties_get(impl->playback_props, SPA_KEY_AUDIO_POSITION)) != NULL) { | ||||||
| 		parse_position(&impl->playback_info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), | ||||||
|  | 				impl->playback_info.position, &impl->playback_info.channels); | ||||||
| 		if (impl->playback_info.channels != impl->sink_info.channels) | 		if (impl->playback_info.channels != impl->sink_info.channels) | ||||||
| 			impl->playback_info = impl->sink_info; | 			impl->playback_info = impl->sink_info; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ | ||||||
| #include <spa/utils/json.h> | #include <spa/utils/json.h> | ||||||
| #include <spa/utils/ringbuffer.h> | #include <spa/utils/ringbuffer.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/debug/types.h> | #include <spa/debug/types.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
|  | @ -447,31 +448,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -482,7 +458,7 @@ static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_ | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, 0); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, 0); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ | ||||||
| #include <spa/pod/builder.h> | #include <spa/pod/builder.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
| #include <pipewire/i18n.h> | #include <pipewire/i18n.h> | ||||||
|  | @ -272,41 +273,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static inline uint32_t format_from_name(const char *name, size_t len) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (strncmp(name, spa_debug_type_short_name(spa_type_audio_format[i].name), len) == 0) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -314,7 +280,7 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	spa_zero(*info); | 	spa_zero(*info); | ||||||
| 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | ||||||
| 		str = DEFAULT_FORMAT; | 		str = DEFAULT_FORMAT; | ||||||
| 	info->format = format_from_name(str, strlen(str)); | 	info->format = spa_type_audio_format_from_short_name(str); | ||||||
| 
 | 
 | ||||||
| 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | ||||||
| 	if (info->rate == 0) | 	if (info->rate == 0) | ||||||
|  | @ -323,9 +289,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int calc_frame_size(const struct spa_audio_info_raw *info) | static int calc_frame_size(const struct spa_audio_info_raw *info) | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ | ||||||
| #include <spa/pod/builder.h> | #include <spa/pod/builder.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
| #include <pipewire/i18n.h> | #include <pipewire/i18n.h> | ||||||
|  | @ -278,41 +279,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static inline uint32_t format_from_name(const char *name, size_t len) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (strncmp(name, spa_debug_type_short_name(spa_type_audio_format[i].name), len) == 0) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -320,7 +286,7 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	spa_zero(*info); | 	spa_zero(*info); | ||||||
| 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | ||||||
| 		str = DEFAULT_FORMAT; | 		str = DEFAULT_FORMAT; | ||||||
| 	info->format = format_from_name(str, strlen(str)); | 	info->format = spa_type_audio_format_from_short_name(str); | ||||||
| 
 | 
 | ||||||
| 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | ||||||
| 	if (info->rate == 0) | 	if (info->rate == 0) | ||||||
|  | @ -329,9 +295,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int calc_frame_size(const struct spa_audio_info_raw *info) | static int calc_frame_size(const struct spa_audio_info_raw *info) | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/control/ump-utils.h> | #include <spa/control/ump-utils.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
|  | @ -1406,16 +1407,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_devices(struct impl *impl, const char *val, size_t len) | static void parse_devices(struct impl *impl, const char *val, size_t len) | ||||||
| { | { | ||||||
| 	struct spa_json it[1]; | 	struct spa_json it[1]; | ||||||
|  | @ -1431,21 +1422,6 @@ static void parse_devices(struct impl *impl, const char *val, size_t len) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[2]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -1456,9 +1432,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| #include <spa/support/cpu.h> | #include <spa/support/cpu.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/tag-utils.h> | #include <spa/param/tag-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/pod/dynamic.h> | #include <spa/pod/dynamic.h> | ||||||
| #include <spa/debug/types.h> | #include <spa/debug/types.h> | ||||||
| #include <spa/debug/log.h> | #include <spa/debug/log.h> | ||||||
|  | @ -2904,31 +2905,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -2939,7 +2915,7 @@ static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_ | ||||||
| 	info->channels = pw_properties_get_int32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_int32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/control/ump-utils.h> | #include <spa/control/ump-utils.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
|  | @ -991,31 +992,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -1026,9 +1002,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ | ||||||
| #include <spa/utils/json.h> | #include <spa/utils/json.h> | ||||||
| #include <spa/utils/ringbuffer.h> | #include <spa/utils/ringbuffer.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/debug/types.h> | #include <spa/debug/types.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
|  | @ -769,31 +770,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -804,7 +780,7 @@ static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_ | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, 0); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, 0); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ | ||||||
| #include <spa/debug/types.h> | #include <spa/debug/types.h> | ||||||
| #include <spa/pod/builder.h> | #include <spa/pod/builder.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
| 
 | 
 | ||||||
|  | @ -1146,31 +1147,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -1181,9 +1157,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | ||||||
|  |  | ||||||
|  | @ -29,6 +29,7 @@ | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
| #include <pipewire/i18n.h> | #include <pipewire/i18n.h> | ||||||
|  | @ -1172,31 +1173,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -1207,9 +1183,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | static void copy_props(struct impl *impl, struct pw_properties *props, const char *key) | ||||||
|  |  | ||||||
|  | @ -28,6 +28,7 @@ | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
| #include <pipewire/i18n.h> | #include <pipewire/i18n.h> | ||||||
|  | @ -754,41 +755,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline uint32_t format_from_name(const char *name, size_t len) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (strncmp(name, spa_debug_type_short_name(spa_type_audio_format[i].name), len) == 0) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -796,7 +762,7 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	spa_zero(*info); | 	spa_zero(*info); | ||||||
| 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | ||||||
| 		str = DEFAULT_FORMAT; | 		str = DEFAULT_FORMAT; | ||||||
| 	info->format = format_from_name(str, strlen(str)); | 	info->format = spa_type_audio_format_from_short_name(str); | ||||||
| 
 | 
 | ||||||
| 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | ||||||
| 	if (info->rate == 0) | 	if (info->rate == 0) | ||||||
|  | @ -805,9 +771,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int calc_frame_size(const struct spa_audio_info_raw *info) | static int calc_frame_size(const struct spa_audio_info_raw *info) | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| #include <spa/param/audio/format.h> | #include <spa/param/audio/format.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/utils/json.h> | #include <spa/utils/json.h> | ||||||
| 
 | 
 | ||||||
| #include "format.h" | #include "format.h" | ||||||
|  | @ -130,22 +131,12 @@ uint32_t format_pa2id(enum sample_format format) | ||||||
| 
 | 
 | ||||||
| const char *format_id2name(uint32_t format) | const char *format_id2name(uint32_t format) | ||||||
| { | { | ||||||
| 	int i; | 	return spa_type_audio_format_to_short_name(format); | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (spa_type_audio_format[i].type == format) |  | ||||||
| 			return spa_debug_type_short_name(spa_type_audio_format[i].name); |  | ||||||
| 	} |  | ||||||
| 	return "UNKNOWN"; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t format_name2id(const char *name) | uint32_t format_name2id(const char *name) | ||||||
| { | { | ||||||
| 	int i; | 	return spa_type_audio_format_from_short_name(name); | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_format[i].name))) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t format_paname2id(const char *name, size_t size) | uint32_t format_paname2id(const char *name, size_t size) | ||||||
|  | @ -289,22 +280,12 @@ uint32_t channel_pa2id(enum channel_position channel) | ||||||
| 
 | 
 | ||||||
| const char *channel_id2name(uint32_t channel) | const char *channel_id2name(uint32_t channel) | ||||||
| { | { | ||||||
| 	int i; | 	return spa_type_audio_channel_to_short_name(channel); | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_type_audio_channel[i].type == channel) |  | ||||||
| 			return spa_debug_type_short_name(spa_type_audio_channel[i].name); |  | ||||||
| 	} |  | ||||||
| 	return "UNK"; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t channel_name2id(const char *name) | uint32_t channel_name2id(const char *name) | ||||||
| { | { | ||||||
| 	int i; | 	return spa_type_audio_channel_from_short_name(name); | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (strcmp(name, spa_debug_type_short_name(spa_type_audio_channel[i].name)) == 0) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| enum channel_position channel_id2pa(uint32_t id, uint32_t *aux) | enum channel_position channel_id2pa(uint32_t id, uint32_t *aux) | ||||||
|  | @ -354,6 +335,13 @@ void channel_map_to_positions(const struct channel_map *map, uint32_t *pos) | ||||||
| 		pos[i] = map->map[i]; | 		pos[i] = map->map[i]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void positions_to_channel_map(const uint32_t *pos, uint32_t channels, struct channel_map *map) | ||||||
|  | { | ||||||
|  | 	uint32_t i; | ||||||
|  | 	for (i = 0; i < channels; i++) | ||||||
|  | 		map->map[i] = pos[i]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void channel_map_parse(const char *str, struct channel_map *map) | void channel_map_parse(const char *str, struct channel_map *map) | ||||||
| { | { | ||||||
| 	const char *p = str; | 	const char *p = str; | ||||||
|  | @ -440,17 +428,9 @@ void channel_map_parse(const char *str, struct channel_map *map) | ||||||
| 
 | 
 | ||||||
| void channel_map_parse_position(const char *str, struct channel_map *map) | void channel_map_parse_position(const char *str, struct channel_map *map) | ||||||
| { | { | ||||||
| 	struct spa_json it[1]; | 	uint32_t channels = 0, position[SPA_AUDIO_MAX_CHANNELS]; | ||||||
| 	char v[256]; | 	spa_audio_parse_position(str, strlen(str), position, &channels); | ||||||
| 
 | 	positions_to_channel_map(position, channels, map); | ||||||
| 	if (spa_json_begin_array_relax(&it[0], str, strlen(str)) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	map->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    map->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		map->map[map->channels++] = channel_name2id(v); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool channel_map_valid(const struct channel_map *map) | bool channel_map_valid(const struct channel_map *map) | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ | ||||||
| #include <spa/debug/types.h> | #include <spa/debug/types.h> | ||||||
| #include <spa/param/audio/type-info.h> | #include <spa/param/audio/type-info.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
| 
 | 
 | ||||||
|  | @ -785,41 +786,6 @@ static void impl_free(struct impl *impl) | ||||||
| 	free(impl); | 	free(impl); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline uint32_t format_from_name(const char *name, size_t len) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (strncmp(name, spa_debug_type_short_name(spa_type_audio_format[i].name), len) == 0) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int calc_frame_size(struct spa_audio_info_raw *info) | static int calc_frame_size(struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	int res = info->channels; | 	int res = info->channels; | ||||||
|  | @ -861,7 +827,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ | ||||||
| 	spa_zero(*info); | 	spa_zero(*info); | ||||||
| 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | ||||||
| 		str = DEFAULT_FORMAT; | 		str = DEFAULT_FORMAT; | ||||||
| 	info->format = format_from_name(str, strlen(str)); | 	info->format = spa_type_audio_format_from_short_name(str); | ||||||
| 
 | 
 | ||||||
| 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | ||||||
| 	if (info->rate == 0) | 	if (info->rate == 0) | ||||||
|  | @ -870,9 +836,10 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| 
 | 
 | ||||||
| 	return calc_frame_size(info); | 	return calc_frame_size(info); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
| #include <spa/param/latency-utils.h> | #include <spa/param/latency-utils.h> | ||||||
| #include <spa/param/audio/raw.h> | #include <spa/param/audio/raw.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
| #include <pipewire/i18n.h> | #include <pipewire/i18n.h> | ||||||
|  | @ -1064,41 +1065,6 @@ static const struct pw_impl_module_events module_events = { | ||||||
| 	.destroy = module_destroy, | 	.destroy = module_destroy, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline uint32_t format_from_name(const char *name, size_t len) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (strncmp(name, spa_debug_type_short_name(spa_type_audio_format[i].name), len) == 0) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -1106,7 +1072,7 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	spa_zero(*info); | 	spa_zero(*info); | ||||||
| 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | ||||||
| 		str = DEFAULT_FORMAT; | 		str = DEFAULT_FORMAT; | ||||||
| 	info->format = format_from_name(str, strlen(str)); | 	info->format = spa_type_audio_format_from_short_name(str); | ||||||
| 
 | 
 | ||||||
| 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | ||||||
| 	if (info->rate == 0) | 	if (info->rate == 0) | ||||||
|  | @ -1115,9 +1081,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int calc_frame_size(struct spa_audio_info_raw *info) | static int calc_frame_size(struct spa_audio_info_raw *info) | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ | ||||||
| #include <spa/utils/ringbuffer.h> | #include <spa/utils/ringbuffer.h> | ||||||
| #include <spa/utils/dll.h> | #include <spa/utils/dll.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/control/control.h> | #include <spa/control/control.h> | ||||||
| #include <spa/control/ump-utils.h> | #include <spa/control/ump-utils.h> | ||||||
| #include <spa/debug/types.h> | #include <spa/debug/types.h> | ||||||
|  | @ -269,41 +270,6 @@ static const struct format_info *find_audio_format_info(const struct spa_audio_i | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline uint32_t format_from_name(const char *name, size_t len) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (strncmp(name, spa_debug_type_short_name(spa_type_audio_format[i].name), len) == 0) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -311,7 +277,7 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	spa_zero(*info); | 	spa_zero(*info); | ||||||
| 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | ||||||
| 		str = DEFAULT_FORMAT; | 		str = DEFAULT_FORMAT; | ||||||
| 	info->format = format_from_name(str, strlen(str)); | 	info->format = spa_type_audio_format_from_short_name(str); | ||||||
| 
 | 
 | ||||||
| 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | ||||||
| 	if (info->rate == 0) | 	if (info->rate == 0) | ||||||
|  | @ -320,9 +286,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint32_t msec_to_samples(struct impl *impl, float msec) | static uint32_t msec_to_samples(struct impl *impl, float msec) | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ | ||||||
| #include <spa/utils/string.h> | #include <spa/utils/string.h> | ||||||
| #include <spa/utils/json.h> | #include <spa/utils/json.h> | ||||||
| #include <spa/param/audio/format.h> | #include <spa/param/audio/format.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/debug/types.h> | #include <spa/debug/types.h> | ||||||
| 
 | 
 | ||||||
| #include <pipewire/impl.h> | #include <pipewire/impl.h> | ||||||
|  | @ -502,41 +503,6 @@ static int add_snapcast_stream(struct impl *impl, struct tunnel *t, | ||||||
| 	return -ENOENT; | 	return -ENOENT; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline uint32_t format_from_name(const char *name, size_t len) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (strncmp(name, spa_debug_type_short_name(spa_type_audio_format[i].name), len) == 0) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -544,10 +510,10 @@ static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_ | ||||||
| 	spa_zero(*info); | 	spa_zero(*info); | ||||||
| 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | ||||||
| 		str = DEFAULT_FORMAT; | 		str = DEFAULT_FORMAT; | ||||||
| 	info->format = format_from_name(str, strlen(str)); | 	info->format = spa_type_audio_format_from_short_name(str); | ||||||
| 	if (info->format == 0) { | 	if (info->format == 0) { | ||||||
| 		str = DEFAULT_FORMAT; | 		str = DEFAULT_FORMAT; | ||||||
| 		info->format = format_from_name(str, strlen(str)); | 		info->format = spa_type_audio_format_from_short_name(str); | ||||||
| 	} | 	} | ||||||
| 	pw_properties_set(props, PW_KEY_AUDIO_FORMAT, str); | 	pw_properties_set(props, PW_KEY_AUDIO_FORMAT, str); | ||||||
| 
 | 
 | ||||||
|  | @ -559,9 +525,10 @@ static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_ | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| 	pw_properties_setf(props, PW_KEY_AUDIO_CHANNELS, "%d", info->channels); | 	pw_properties_setf(props, PW_KEY_AUDIO_CHANNELS, "%d", info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ | ||||||
| #include <spa/utils/ringbuffer.h> | #include <spa/utils/ringbuffer.h> | ||||||
| #include <spa/utils/dll.h> | #include <spa/utils/dll.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/control/control.h> | #include <spa/control/control.h> | ||||||
| #include <spa/control/ump-utils.h> | #include <spa/control/ump-utils.h> | ||||||
| #include <spa/debug/types.h> | #include <spa/debug/types.h> | ||||||
|  | @ -187,41 +188,6 @@ static const struct format_info *find_audio_format_info(const struct spa_audio_i | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline uint32_t format_from_name(const char *name, size_t len) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_format[i].name; i++) { |  | ||||||
| 		if (strncmp(name, spa_debug_type_short_name(spa_type_audio_format[i].name), len) == 0) |  | ||||||
| 			return spa_type_audio_format[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_FORMAT_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static uint32_t channel_from_name(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_position(struct spa_audio_info_raw *info, const char *val, size_t len) |  | ||||||
| { |  | ||||||
| 	struct spa_json it[1]; |  | ||||||
| 	char v[256]; |  | ||||||
| 
 |  | ||||||
|         if (spa_json_begin_array_relax(&it[0], val, len) <= 0) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	info->channels = 0; |  | ||||||
| 	while (spa_json_get_string(&it[0], v, sizeof(v)) > 0 && |  | ||||||
| 	    info->channels < SPA_AUDIO_MAX_CHANNELS) { |  | ||||||
| 		info->position[info->channels++] = channel_from_name(v); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) | ||||||
| { | { | ||||||
| 	const char *str; | 	const char *str; | ||||||
|  | @ -229,7 +195,7 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	spa_zero(*info); | 	spa_zero(*info); | ||||||
| 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | 	if ((str = pw_properties_get(props, PW_KEY_AUDIO_FORMAT)) == NULL) | ||||||
| 		str = DEFAULT_FORMAT; | 		str = DEFAULT_FORMAT; | ||||||
| 	info->format = format_from_name(str, strlen(str)); | 	info->format = spa_type_audio_format_from_short_name(str); | ||||||
| 
 | 
 | ||||||
| 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | 	info->rate = pw_properties_get_uint32(props, PW_KEY_AUDIO_RATE, info->rate); | ||||||
| 	if (info->rate == 0) | 	if (info->rate == 0) | ||||||
|  | @ -238,9 +204,10 @@ static void parse_audio_info(const struct pw_properties *props, struct spa_audio | ||||||
| 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | 	info->channels = pw_properties_get_uint32(props, PW_KEY_AUDIO_CHANNELS, info->channels); | ||||||
| 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | 	info->channels = SPA_MIN(info->channels, SPA_AUDIO_MAX_CHANNELS); | ||||||
| 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | 	if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) | ||||||
| 		parse_position(info, str, strlen(str)); | 		spa_audio_parse_position(str, strlen(str), info->position, &info->channels); | ||||||
| 	if (info->channels == 0) | 	if (info->channels == 0) | ||||||
| 		parse_position(info, DEFAULT_POSITION, strlen(DEFAULT_POSITION)); | 		spa_audio_parse_position(DEFAULT_POSITION, strlen(DEFAULT_POSITION), | ||||||
|  | 				info->position, &info->channels); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint32_t msec_to_samples(struct impl *impl, uint32_t msec) | static uint32_t msec_to_samples(struct impl *impl, uint32_t msec) | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <spa/param/audio/layout.h> | #include <spa/param/audio/layout.h> | ||||||
| #include <spa/param/audio/format-utils.h> | #include <spa/param/audio/format-utils.h> | ||||||
|  | #include <spa/param/audio/raw-json.h> | ||||||
| #include <spa/utils/type-info.h> | #include <spa/utils/type-info.h> | ||||||
| #include <spa/param/tag-utils.h> | #include <spa/param/tag-utils.h> | ||||||
| #include <spa/param/props.h> | #include <spa/param/props.h> | ||||||
|  | @ -79,8 +80,8 @@ struct data; | ||||||
| typedef int (*fill_fn)(struct data *d, void *dest, unsigned int n_frames, bool *null_frame); | typedef int (*fill_fn)(struct data *d, void *dest, unsigned int n_frames, bool *null_frame); | ||||||
| 
 | 
 | ||||||
| struct channelmap { | struct channelmap { | ||||||
| 	int n_channels; | 	uint32_t n_channels; | ||||||
| 	int channels[SPA_AUDIO_MAX_CHANNELS]; | 	uint32_t channels[SPA_AUDIO_MAX_CHANNELS]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct data { | struct data { | ||||||
|  | @ -119,7 +120,7 @@ struct data { | ||||||
| 
 | 
 | ||||||
| 	unsigned int bitrate; | 	unsigned int bitrate; | ||||||
| 	unsigned int rate; | 	unsigned int rate; | ||||||
| 	int channels; | 	uint32_t channels; | ||||||
| 	struct channelmap channelmap; | 	struct channelmap channelmap; | ||||||
| 	unsigned int stride; | 	unsigned int stride; | ||||||
| 	enum unit latency_unit; | 	enum unit latency_unit; | ||||||
|  | @ -566,10 +567,10 @@ static int channelmap_from_sf(struct channelmap *map) | ||||||
| 		[SF_CHANNEL_MAP_TOP_REAR_RIGHT] =        SPA_AUDIO_CHANNEL_TRR, | 		[SF_CHANNEL_MAP_TOP_REAR_RIGHT] =        SPA_AUDIO_CHANNEL_TRR, | ||||||
| 		[SF_CHANNEL_MAP_TOP_REAR_CENTER] =       SPA_AUDIO_CHANNEL_TRC | 		[SF_CHANNEL_MAP_TOP_REAR_CENTER] =       SPA_AUDIO_CHANNEL_TRC | ||||||
| 	}; | 	}; | ||||||
| 	int i; | 	uint32_t i; | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < map->n_channels; i++) { | 	for (i = 0; i < map->n_channels; i++) { | ||||||
| 		if (map->channels[i] >= 0 && map->channels[i] < (int) SPA_N_ELEMENTS(table)) | 		if (map->channels[i] < SPA_N_ELEMENTS(table)) | ||||||
| 			map->channels[i] = table[map->channels[i]]; | 			map->channels[i] = table[map->channels[i]]; | ||||||
| 		else | 		else | ||||||
| 			map->channels[i] = SPA_AUDIO_CHANNEL_UNKNOWN; | 			map->channels[i] = SPA_AUDIO_CHANNEL_UNKNOWN; | ||||||
|  | @ -578,8 +579,8 @@ static int channelmap_from_sf(struct channelmap *map) | ||||||
| } | } | ||||||
| struct mapping { | struct mapping { | ||||||
| 	const char *name; | 	const char *name; | ||||||
| 	unsigned int channels; | 	uint32_t channels; | ||||||
| 	unsigned int values[32]; | 	uint32_t values[32]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const struct mapping maps[] = | static const struct mapping maps[] = | ||||||
|  | @ -599,21 +600,8 @@ static const struct mapping maps[] = | ||||||
| 	{ "surround-71",  SPA_AUDIO_LAYOUT_7_1 }, | 	{ "surround-71",  SPA_AUDIO_LAYOUT_7_1 }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static unsigned int find_channel(const char *name) |  | ||||||
| { |  | ||||||
| 	int i; |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; spa_type_audio_channel[i].name; i++) { |  | ||||||
| 		if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channel[i].name))) |  | ||||||
| 			return spa_type_audio_channel[i].type; |  | ||||||
| 	} |  | ||||||
| 	return SPA_AUDIO_CHANNEL_UNKNOWN; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int parse_channelmap(const char *channel_map, struct channelmap *map) | static int parse_channelmap(const char *channel_map, struct channelmap *map) | ||||||
| { | { | ||||||
| 	int i, nch; |  | ||||||
| 
 |  | ||||||
| 	SPA_FOR_EACH_ELEMENT_VAR(maps, m) { | 	SPA_FOR_EACH_ELEMENT_VAR(maps, m) { | ||||||
| 		if (spa_streq(m->name, channel_map)) { | 		if (spa_streq(m->name, channel_map)) { | ||||||
| 			map->n_channels = m->channels; | 			map->n_channels = m->channels; | ||||||
|  | @ -623,16 +611,7 @@ static int parse_channelmap(const char *channel_map, struct channelmap *map) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	spa_auto(pw_strv) ch = pw_split_strv(channel_map, ",", SPA_AUDIO_MAX_CHANNELS, &nch); | 	spa_audio_parse_position(channel_map, strlen(channel_map), map->channels, &map->n_channels); | ||||||
| 	if (ch == NULL) |  | ||||||
| 		return -1; |  | ||||||
| 
 |  | ||||||
| 	map->n_channels = nch; |  | ||||||
| 	for (i = 0; i < map->n_channels; i++) { |  | ||||||
| 		int c = find_channel(ch[i]); |  | ||||||
| 		map->channels[i] = c; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -673,13 +652,11 @@ static int channelmap_default(struct channelmap *map, int n_channels) | ||||||
| 
 | 
 | ||||||
| static void channelmap_print(struct channelmap *map) | static void channelmap_print(struct channelmap *map) | ||||||
| { | { | ||||||
| 	int i; | 	uint32_t i; | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < map->n_channels; i++) { | 	for (i = 0; i < map->n_channels; i++) { | ||||||
| 		const char *name = spa_debug_type_find_name(spa_type_audio_channel, map->channels[i]); | 		const char *name = spa_type_audio_channel_to_short_name(map->channels[i]); | ||||||
| 		if (name == NULL) | 		fprintf(stderr, "%s%s", name, i + 1 < map->n_channels ? "," : ""); | ||||||
| 			name = ":UNK"; |  | ||||||
| 		fprintf(stderr, "%s%s", spa_debug_type_short_name(name), i + 1 < map->n_channels ? "," : ""); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1499,7 +1476,7 @@ static int setup_sndfile(struct data *data) | ||||||
| 	if (data->verbose) | 	if (data->verbose) | ||||||
| 		fprintf(stderr, "sndfile: opened file \"%s\" format %08x channels:%d rate:%d\n", | 		fprintf(stderr, "sndfile: opened file \"%s\" format %08x channels:%d rate:%d\n", | ||||||
| 				data->filename, info.format, info.channels, info.samplerate); | 				data->filename, info.format, info.channels, info.samplerate); | ||||||
| 	if (data->channels > 0 && info.channels != data->channels) { | 	if (data->channels > 0 && info.channels != (int)data->channels) { | ||||||
| 		fprintf(stderr, "sndfile: given channels (%u) don't match file channels (%d)\n", | 		fprintf(stderr, "sndfile: given channels (%u) don't match file channels (%d)\n", | ||||||
| 				data->channels, info.channels); | 				data->channels, info.channels); | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
|  |  | ||||||
|  | @ -233,8 +233,7 @@ static void node_param(void *data, int seq, | ||||||
| 				struct spa_audio_info_raw info = { 0 }; | 				struct spa_audio_info_raw info = { 0 }; | ||||||
| 				if (spa_format_audio_raw_parse(param, &info) >= 0) { | 				if (spa_format_audio_raw_parse(param, &info) >= 0) { | ||||||
| 					snprintf(n->format, sizeof(n->format), "%6.6s %d %d", | 					snprintf(n->format, sizeof(n->format), "%6.6s %d %d", | ||||||
| 						spa_debug_type_find_short_name( | 						spa_type_audio_format_to_short_name(info.format), | ||||||
| 							spa_type_audio_format, info.format), |  | ||||||
| 						info.channels, info.rate); | 						info.channels, info.rate); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
|  | @ -272,7 +271,7 @@ static void node_param(void *data, int seq, | ||||||
| 				struct spa_video_info_raw info = { 0 }; | 				struct spa_video_info_raw info = { 0 }; | ||||||
| 				if (spa_format_video_raw_parse(param, &info) >= 0) { | 				if (spa_format_video_raw_parse(param, &info) >= 0) { | ||||||
| 					snprintf(n->format, sizeof(n->format), "%6.6s %dx%d", | 					snprintf(n->format, sizeof(n->format), "%6.6s %dx%d", | ||||||
| 						spa_debug_type_find_short_name(spa_type_video_format, info.format), | 						spa_type_video_format_to_short_name(info.format), | ||||||
| 						info.size.width, info.size.height); | 						info.size.width, info.size.height); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Wim Taymans
						Wim Taymans