audio-session: detect sample rate

This commit is contained in:
Wim Taymans 2018-05-11 10:01:13 +02:00
parent bd3b7e8ee4
commit 2c6ff2dad2
3 changed files with 36 additions and 19 deletions

View file

@ -289,10 +289,13 @@ static int on_peer_port(void *data, struct pw_port *port)
static void reconfigure_session(struct session *sess) static void reconfigure_session(struct session *sess)
{ {
struct node_info *ni; struct node_info *ni;
uint32_t buffer_size = 1024; struct impl *impl = sess->impl;
uint32_t buffer_size = MAX_BUFFER_SIZE;
spa_list_for_each(ni, &sess->node_list, l) spa_list_for_each(ni, &sess->node_list, l) {
if (ni->buffer_size > 0)
buffer_size = SPA_MIN(buffer_size, ni->buffer_size); buffer_size = SPA_MIN(buffer_size, ni->buffer_size);
}
sess->buffer_size = buffer_size; sess->buffer_size = buffer_size;
} }
@ -402,8 +405,7 @@ static void handle_autoconnect(struct impl *impl, struct pw_node *node,
struct node_info *info; struct node_info *info;
uint32_t sample_rate, buffer_size; uint32_t sample_rate, buffer_size;
sample_rate = 44100; sample_rate = DEFAULT_SAMPLE_RATE;
buffer_size = 1024;
if ((media = pw_properties_get(props, PW_NODE_PROP_MEDIA)) == NULL) if ((media = pw_properties_get(props, PW_NODE_PROP_MEDIA)) == NULL)
media = "Audio"; media = "Audio";
@ -421,7 +423,14 @@ static void handle_autoconnect(struct impl *impl, struct pw_node *node,
else else
exclusive = false; exclusive = false;
pw_log_debug("module %p: '%s' '%s' '%s' %d", impl, media, category, role, exclusive); if ((str = pw_properties_get(props, "node.latency")) != NULL)
buffer_size = atoi(str) * sizeof(float);
else
buffer_size = MAX_BUFFER_SIZE;
pw_log_info("module %p: '%s' '%s' '%s' exclusive:%d quantum:%d/%d", impl,
media, category, role, exclusive,
sample_rate, buffer_size);
if (strcmp(category, "Playback") == 0) if (strcmp(category, "Playback") == 0)
find.media_class = "Audio/Sink"; find.media_class = "Audio/Sink";
@ -471,8 +480,6 @@ static void handle_autoconnect(struct impl *impl, struct pw_node *node,
return; return;
} }
peer = session->dsp; peer = session->dsp;
sample_rate = session->sample_rate;
buffer_size = session->buffer_size;
} }
pw_log_debug("module %p: linking to session '%d'", impl, session->id); pw_log_debug("module %p: linking to session '%d'", impl, session->id);
@ -490,6 +497,8 @@ static void handle_autoconnect(struct impl *impl, struct pw_node *node,
pw_node_add_listener(node, &info->node_listener, &node_info_events, info); pw_node_add_listener(node, &info->node_listener, &node_info_events, info);
pw_node_for_each_port(peer, direction, on_peer_port, info); pw_node_for_each_port(peer, direction, on_peer_port, info);
reconfigure_session(session);
} }
static void node_destroy(void *data) static void node_destroy(void *data)
@ -536,6 +545,7 @@ static const struct pw_node_events dsp_events = {
struct channel_data { struct channel_data {
struct impl *impl; struct impl *impl;
uint32_t channels; uint32_t channels;
uint32_t rate;
}; };
static int collect_channel(void *data, uint32_t id, uint32_t index, uint32_t next, struct spa_pod *param) static int collect_channel(void *data, uint32_t id, uint32_t index, uint32_t next, struct spa_pod *param)
@ -559,17 +569,19 @@ static int collect_channel(void *data, uint32_t id, uint32_t index, uint32_t nex
if (spa_format_audio_raw_parse(param, &info, &impl->type.format_audio) < 0) if (spa_format_audio_raw_parse(param, &info, &impl->type.format_audio) < 0)
return 0; return 0;
if (info.channels > d->channels) if (info.channels > d->channels) {
d->channels = info.channels; d->channels = info.channels;
d->rate = info.rate;
}
return 0; return 0;
} }
static uint32_t find_port_channels(struct impl *impl, struct pw_port *port) static int find_port_channels(struct impl *impl, struct pw_port *port,
uint32_t *channels, uint32_t *rate)
{ {
struct pw_type *t = impl->t; struct pw_type *t = impl->t;
struct channel_data data = { impl, 0, }; struct channel_data data = { impl, 0, 0 };
pw_port_for_each_param(port, pw_port_for_each_param(port,
t->param.idEnumFormat, t->param.idEnumFormat,
@ -577,7 +589,10 @@ static uint32_t find_port_channels(struct impl *impl, struct pw_port *port)
collect_channel, &data); collect_channel, &data);
pw_log_debug("port channels %d", data.channels); pw_log_debug("port channels %d", data.channels);
return data.channels; *channels = data.channels;
*rate = data.rate;
return channels > 0 ? 0 : -1;
} }
static int on_global(void *data, struct pw_global *global) static int on_global(void *data, struct pw_global *global)
@ -589,7 +604,7 @@ static int on_global(void *data, struct pw_global *global)
const char *str; const char *str;
enum pw_direction direction; enum pw_direction direction;
struct pw_port *node_port, *dsp_port; struct pw_port *node_port, *dsp_port;
uint32_t id, channels; uint32_t id, channels, rate;
if (pw_global_get_type(global) != impl->t->node) if (pw_global_get_type(global) != impl->t->node)
return 0; return 0;
@ -619,14 +634,14 @@ static int on_global(void *data, struct pw_global *global)
if ((node_port = pw_node_get_free_port(node, pw_direction_reverse(direction))) == NULL) if ((node_port = pw_node_get_free_port(node, pw_direction_reverse(direction))) == NULL)
return 0; return 0;
channels = find_port_channels(impl, node_port); if (find_port_channels(impl, node_port, &channels, &rate) < 0)
if (channels == 0)
return 0; return 0;
dsp = pw_audio_dsp_new(impl->core, dsp = pw_audio_dsp_new(impl->core,
properties, properties,
direction, direction,
channels, channels,
rate,
MAX_BUFFER_SIZE, MAX_BUFFER_SIZE,
sizeof(struct session)); sizeof(struct session));
if (dsp == NULL) if (dsp == NULL)
@ -643,6 +658,8 @@ static int on_global(void *data, struct pw_global *global)
sess->node_port = node_port; sess->node_port = node_port;
sess->dsp = dsp; sess->dsp = dsp;
sess->dsp_port = dsp_port; sess->dsp_port = dsp_port;
sess->sample_rate = rate;
sess->buffer_size = MAX_BUFFER_SIZE;
spa_list_init(&sess->node_list); spa_list_init(&sess->node_list);
spa_list_append(&impl->session_list, &sess->l); spa_list_append(&impl->session_list, &sess->l);

View file

@ -44,8 +44,6 @@
#define MAX_PORTS 256 #define MAX_PORTS 256
#define MAX_BUFFERS 8 #define MAX_BUFFERS 8
#define DEFAULT_SAMPLE_RATE 44100
struct type { struct type {
struct spa_type_media_type media_type; struct spa_type_media_type media_type;
struct spa_type_media_subtype media_subtype; struct spa_type_media_subtype media_subtype;
@ -865,6 +863,7 @@ struct pw_node *pw_audio_dsp_new(struct pw_core *core,
const struct pw_properties *props, const struct pw_properties *props,
enum pw_direction direction, enum pw_direction direction,
uint32_t channels, uint32_t channels,
uint32_t sample_rate,
uint32_t max_buffer_size, uint32_t max_buffer_size,
size_t user_data_size) size_t user_data_size)
{ {
@ -915,7 +914,7 @@ struct pw_node *pw_audio_dsp_new(struct pw_core *core,
n->node_impl.process = node_process_split; n->node_impl.process = node_process_split;
n->channels = channels; n->channels = channels;
n->sample_rate = DEFAULT_SAMPLE_RATE; n->sample_rate = sample_rate;
n->max_buffer_size = max_buffer_size; n->max_buffer_size = max_buffer_size;
pw_node_set_implementation(node, &n->node_impl); pw_node_set_implementation(node, &n->node_impl);

View file

@ -32,6 +32,7 @@ pw_audio_dsp_new(struct pw_core *core,
const struct pw_properties *properties, const struct pw_properties *properties,
enum pw_direction direction, enum pw_direction direction,
uint32_t channels, uint32_t channels,
uint32_t sample_rate,
uint32_t max_buffer_size, uint32_t max_buffer_size,
size_t user_data_size); size_t user_data_size);