mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-16 08:56:45 -05:00
spa: add audio.position support in null sink
This commit is contained in:
parent
4c486c7ae3
commit
57886c1198
2 changed files with 42 additions and 11 deletions
|
|
@ -223,6 +223,8 @@ struct spa_audio_info_raw {
|
||||||
* Ex. "FL" */
|
* Ex. "FL" */
|
||||||
#define SPA_KEY_AUDIO_CHANNELS "audio.channels" /**< an audio channel count as int */
|
#define SPA_KEY_AUDIO_CHANNELS "audio.channels" /**< an audio channel count as int */
|
||||||
#define SPA_KEY_AUDIO_RATE "audio.rate" /**< an audio sample rate as int */
|
#define SPA_KEY_AUDIO_RATE "audio.rate" /**< an audio sample rate as int */
|
||||||
|
#define SPA_KEY_AUDIO_POSITION "audio.position" /**< channel positions as comma separated list
|
||||||
|
* of channels ex. "FL,FR" */
|
||||||
|
|
||||||
struct spa_audio_info_dsp {
|
struct spa_audio_info_dsp {
|
||||||
enum spa_audio_format format; /*< format, one of the DSP formats in enum spa_audio_format_dsp */
|
enum spa_audio_format format; /*< format, one of the DSP formats in enum spa_audio_format_dsp */
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@
|
||||||
#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/debug/types.h>
|
||||||
|
#include <spa/param/audio/type-info.h>
|
||||||
#include <spa/param/param.h>
|
#include <spa/param/param.h>
|
||||||
#include <spa/pod/filter.h>
|
#include <spa/pod/filter.h>
|
||||||
#include <spa/control/control.h>
|
#include <spa/control/control.h>
|
||||||
|
|
@ -47,10 +49,16 @@
|
||||||
|
|
||||||
struct props {
|
struct props {
|
||||||
uint32_t channels;
|
uint32_t channels;
|
||||||
|
uint32_t rate;
|
||||||
|
uint32_t n_pos;
|
||||||
|
uint32_t pos[SPA_AUDIO_MAX_CHANNELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void reset_props(struct props *props)
|
static void reset_props(struct props *props)
|
||||||
{
|
{
|
||||||
|
props->channels = 0;
|
||||||
|
props->rate = 0;
|
||||||
|
props->n_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFAULT_CHANNELS 2
|
#define DEFAULT_CHANNELS 2
|
||||||
|
|
@ -92,8 +100,6 @@ struct impl {
|
||||||
struct spa_loop *data_loop;
|
struct spa_loop *data_loop;
|
||||||
struct spa_system *data_system;
|
struct spa_system *data_system;
|
||||||
|
|
||||||
uint32_t default_rate;
|
|
||||||
uint32_t default_channels;
|
|
||||||
struct props props;
|
struct props props;
|
||||||
|
|
||||||
uint64_t info_all;
|
uint64_t info_all;
|
||||||
|
|
@ -365,24 +371,29 @@ port_enum_formats(struct impl *this,
|
||||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32),
|
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (this->default_rate != 0) {
|
if (this->props.rate != 0) {
|
||||||
spa_pod_builder_add(builder,
|
spa_pod_builder_add(builder,
|
||||||
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(this->default_rate),
|
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(this->props.rate),
|
||||||
0);
|
0);
|
||||||
} else {
|
} else {
|
||||||
spa_pod_builder_add(builder,
|
spa_pod_builder_add(builder,
|
||||||
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(DEFAULT_RATE, 1, INT32_MAX),
|
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(DEFAULT_RATE, 1, INT32_MAX),
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
if (this->default_channels != 0) {
|
if (this->props.channels != 0) {
|
||||||
spa_pod_builder_add(builder,
|
spa_pod_builder_add(builder,
|
||||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(this->default_channels),
|
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(this->props.channels),
|
||||||
0);
|
0);
|
||||||
} else {
|
} else {
|
||||||
spa_pod_builder_add(builder,
|
spa_pod_builder_add(builder,
|
||||||
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(DEFAULT_CHANNELS, 1, INT32_MAX),
|
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(DEFAULT_CHANNELS, 1, INT32_MAX),
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
if (this->props.n_pos != 0) {
|
||||||
|
spa_pod_builder_prop(builder, SPA_FORMAT_AUDIO_position, 0);
|
||||||
|
spa_pod_builder_array(builder, sizeof(uint32_t), SPA_TYPE_Id,
|
||||||
|
this->props.n_pos, this->props.pos);
|
||||||
|
}
|
||||||
*param = spa_pod_builder_pop(builder, &f[0]);
|
*param = spa_pod_builder_pop(builder, &f[0]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -704,6 +715,16 @@ 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, size_t len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; spa_type_audio_channel[i].name; i++) {
|
||||||
|
if (strncmp(name, spa_debug_type_short_name(spa_type_audio_channel[i].name), len) == 0)
|
||||||
|
return spa_type_audio_channel[i].type;
|
||||||
|
}
|
||||||
|
return SPA_AUDIO_CHANNEL_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|
@ -779,16 +800,24 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
|
|
||||||
spa_loop_add_source(this->data_loop, &this->timer_source);
|
spa_loop_add_source(this->data_loop, &this->timer_source);
|
||||||
|
|
||||||
this->default_channels = 0;
|
|
||||||
this->default_rate = 0;
|
|
||||||
|
|
||||||
for (i = 0; info && i < info->n_items; i++) {
|
for (i = 0; info && i < info->n_items; i++) {
|
||||||
if (!strcmp(info->items[i].key, SPA_KEY_AUDIO_CHANNELS)) {
|
if (!strcmp(info->items[i].key, SPA_KEY_AUDIO_CHANNELS)) {
|
||||||
this->default_channels = atoi(info->items[i].value);
|
this->props.channels = atoi(info->items[i].value);
|
||||||
} else if (!strcmp(info->items[i].key, SPA_KEY_AUDIO_RATE)) {
|
} else if (!strcmp(info->items[i].key, SPA_KEY_AUDIO_RATE)) {
|
||||||
this->default_rate = atoi(info->items[i].value);
|
this->props.rate = atoi(info->items[i].value);
|
||||||
|
} else if (!strcmp(info->items[i].key, SPA_KEY_AUDIO_POSITION)) {
|
||||||
|
size_t len;
|
||||||
|
const char *p = info->items[i].value;
|
||||||
|
while (*p && this->props.n_pos < SPA_AUDIO_MAX_CHANNELS) {
|
||||||
|
if ((len = strcspn(p, ",")) == 0)
|
||||||
|
break;
|
||||||
|
this->props.pos[this->props.n_pos++] = channel_from_name(p, len);
|
||||||
|
p += len + strspn(p+len, ",");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this->props.n_pos > 0)
|
||||||
|
this->props.channels = this->props.n_pos;
|
||||||
|
|
||||||
spa_log_info(this->log, NAME " %p: initialized", this);
|
spa_log_info(this->log, NAME " %p: initialized", this);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue