--- src/pulsecore/sink.c | 31 +++++++++++++++++++++++++++++++ src/pulsecore/sink.h | 6 ++++++ src/pulsecore/source.c | 31 +++++++++++++++++++++++++++++++ src/pulsecore/source.h | 6 ++++++ 4 files changed, 74 insertions(+) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 15237c5..2299502 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -83,6 +83,9 @@ pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data) { pa_zero(*data); data->proplist = pa_proplist_new(); data->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + pa_node_new_data_init(&data->node_data); + pa_node_new_data_set_type(&data->node_data, PA_NODE_TYPE_SINK); + pa_node_new_data_set_direction(&data->node_data, PA_DIRECTION_OUTPUT); return data; } @@ -136,9 +139,16 @@ void pa_sink_new_data_set_port(pa_sink_new_data *data, const char *port) { data->active_port = pa_xstrdup(port); } +void pa_sink_new_data_set_create_node(pa_sink_new_data *data, bool create) { + pa_assert(data); + + data->create_node = create; +} + void pa_sink_new_data_done(pa_sink_new_data *data) { pa_assert(data); + pa_node_new_data_done(&data->node_data); pa_proplist_free(data->proplist); if (data->ports) @@ -367,6 +377,18 @@ pa_sink* pa_sink_new( pa_source_set_fixed_latency(s->monitor_source, s->thread_info.fixed_latency); pa_source_set_max_rewind(s->monitor_source, s->thread_info.max_rewind); + if (data->create_node) { + if (!data->node_data.description) + pa_node_new_data_set_description(&data->node_data, pa_sink_get_description(s)); + + if (!(s->node = pa_node_new(s->core, &data->node_data))) { + pa_log("Failed to create a node for sink %s.", s->name); + goto fail; + } + + s->node->owner = s; + } + pt = pa_proplist_to_string_sep(s->proplist, "\n "); pa_log_info("Created sink %u \"%s\" with sample spec %s and channel map %s\n %s", s->index, @@ -647,6 +669,9 @@ void pa_sink_put(pa_sink* s) { pa_source_put(s->monitor_source); + if (s->node) + pa_node_put(s->node); + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PUT], s); } @@ -672,6 +697,9 @@ void pa_sink_unlink(pa_sink* s) { if (linked) pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s); + if (s->node) + pa_node_unlink(s->node); + if (s->state != PA_SINK_UNLINKED && s->name) pa_namereg_unregister(s->core, s->name); @@ -716,6 +744,9 @@ static void sink_free(pa_object *o) { if (s->state != PA_SINK_INIT) pa_log_info("Freeing sink %u \"%s\"", s->index, s->name); + if (s->node) + pa_node_free(s->node); + if (s->monitor_source) { pa_source_unref(s->monitor_source); s->monitor_source = NULL; diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 8a14bc0..3eba2f1 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -37,6 +37,7 @@ typedef struct pa_sink_volume_change pa_sink_volume_change; #include <pulsecore/core.h> #include <pulsecore/idxset.h> #include <pulsecore/memchunk.h> +#include <pulsecore/node.h> #include <pulsecore/source.h> #include <pulsecore/module.h> #include <pulsecore/asyncmsgq.h> @@ -84,6 +85,7 @@ struct pa_sink { unsigned n_corked; pa_source *monitor_source; pa_sink_input *input_to_master; /* non-NULL only for filter sinks */ + pa_node *node; pa_volume_t base_volume; /* shall be constant */ unsigned n_volume_steps; /* shall be constant */ @@ -357,6 +359,9 @@ typedef struct pa_sink_new_data { pa_bool_t save_port:1; pa_bool_t save_volume:1; pa_bool_t save_muted:1; + + bool create_node; + pa_node_new_data node_data; } pa_sink_new_data; pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data); @@ -367,6 +372,7 @@ void pa_sink_new_data_set_alternate_sample_rate(pa_sink_new_data *data, const ui void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume); void pa_sink_new_data_set_muted(pa_sink_new_data *data, pa_bool_t mute); void pa_sink_new_data_set_port(pa_sink_new_data *data, const char *port); +void pa_sink_new_data_set_create_node(pa_sink_new_data *data, bool create); void pa_sink_new_data_done(pa_sink_new_data *data); /*** To be called exclusively by the sink driver, from main context */ diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index d49b4a4..1102813 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -74,6 +74,9 @@ pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data) { pa_zero(*data); data->proplist = pa_proplist_new(); data->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + pa_node_new_data_init(&data->node_data); + pa_node_new_data_set_type(&data->node_data, PA_NODE_TYPE_SOURCE); + pa_node_new_data_set_direction(&data->node_data, PA_DIRECTION_INPUT); return data; } @@ -127,9 +130,16 @@ void pa_source_new_data_set_port(pa_source_new_data *data, const char *port) { data->active_port = pa_xstrdup(port); } +void pa_source_new_data_set_create_node(pa_source_new_data *data, bool create) { + pa_assert(data); + + data->create_node = create; +} + void pa_source_new_data_done(pa_source_new_data *data) { pa_assert(data); + pa_node_new_data_done(&data->node_data); pa_proplist_free(data->proplist); if (data->ports) @@ -322,6 +332,18 @@ pa_source* pa_source_new( if (s->card) pa_assert_se(pa_idxset_put(s->card->sources, s, NULL) >= 0); + if (data->create_node) { + if (!data->node_data.description) + pa_node_new_data_set_description(&data->node_data, pa_source_get_description(s)); + + if (!(s->node = pa_node_new(s->core, &data->node_data))) { + pa_log("Failed to create a node for source %s.", s->name); + goto fail; + } + + s->node->owner = s; + } + pt = pa_proplist_to_string_sep(s->proplist, "\n "); pa_log_info("Created source %u \"%s\" with sample spec %s and channel map %s\n %s", s->index, @@ -591,6 +613,9 @@ void pa_source_put(pa_source *s) { else pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0); + if (s->node) + pa_node_put(s->node); + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PUT], s); } @@ -611,6 +636,9 @@ void pa_source_unlink(pa_source *s) { if (linked) pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s); + if (s->node) + pa_node_unlink(s->node); + if (s->state != PA_SOURCE_UNLINKED && s->name) pa_namereg_unregister(s->core, s->name); @@ -652,6 +680,9 @@ static void source_free(pa_object *o) { if (s->state != PA_SOURCE_INIT) pa_log_info("Freeing source %u \"%s\"", s->index, s->name); + if (s->node) + pa_node_free(s->node); + if (s->outputs) pa_idxset_free(s->outputs, NULL); diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index a8f7864..54be876 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -37,6 +37,7 @@ typedef struct pa_source_volume_change pa_source_volume_change; #include <pulsecore/core.h> #include <pulsecore/idxset.h> #include <pulsecore/memchunk.h> +#include <pulsecore/node.h> #include <pulsecore/sink.h> #include <pulsecore/module.h> #include <pulsecore/asyncmsgq.h> @@ -84,6 +85,7 @@ struct pa_source { unsigned n_corked; pa_sink *monitor_of; /* may be NULL */ pa_source_output *output_from_master; /* non-NULL only for filter sources */ + pa_node *node; pa_volume_t base_volume; /* shall be constant */ unsigned n_volume_steps; /* shall be constant */ @@ -294,6 +296,9 @@ typedef struct pa_source_new_data { pa_bool_t save_port:1; pa_bool_t save_volume:1; pa_bool_t save_muted:1; + + bool create_node; + pa_node_new_data node_data; } pa_source_new_data; pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data); @@ -304,6 +309,7 @@ void pa_source_new_data_set_alternate_sample_rate(pa_source_new_data *data, cons void pa_source_new_data_set_volume(pa_source_new_data *data, const pa_cvolume *volume); void pa_source_new_data_set_muted(pa_source_new_data *data, pa_bool_t mute); void pa_source_new_data_set_port(pa_source_new_data *data, const char *port); +void pa_source_new_data_set_create_node(pa_source_new_data *data, bool create); void pa_source_new_data_done(pa_source_new_data *data); /*** To be called exclusively by the source driver, from main context */ -- 1.8.1.2