diff options
Diffstat (limited to 'src/modules/module-virtual-sink.c')
-rw-r--r-- | src/modules/module-virtual-sink.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/src/modules/module-virtual-sink.c b/src/modules/module-virtual-sink.c index fac204d4..cc134900 100644 --- a/src/modules/module-virtual-sink.c +++ b/src/modules/module-virtual-sink.c @@ -57,6 +57,8 @@ PA_MODULE_USAGE( "rate=<sample rate> " "channels=<number of channels> " "channel_map=<channel map> " + "use_volume_sharing=<yes or no> " + "force_flat_volume=<yes or no> " )); #define MEMBLOCKQ_MAXLENGTH (16*1024*1024) @@ -81,6 +83,8 @@ static const char* const valid_modargs[] = { "rate", "channels", "channel_map", + "use_volume_sharing", + "force_flat_volume", NULL }; @@ -477,7 +481,9 @@ int pa__init(pa_module*m) { pa_sink *master=NULL; pa_sink_input_new_data sink_input_data; pa_sink_new_data sink_data; - pa_bool_t *use_default = NULL; + pa_bool_t use_volume_sharing = FALSE; + pa_bool_t force_flat_volume = FALSE; + pa_memchunk silence; pa_assert(m); @@ -501,6 +507,21 @@ int pa__init(pa_module*m) { goto fail; } + if (pa_modargs_get_value_boolean(ma, "use_volume_sharing", &use_volume_sharing) < 0) { + pa_log("use_volume_sharing= expects a boolean argument"); + goto fail; + } + + if (pa_modargs_get_value_boolean(ma, "force_flat_volume", &force_flat_volume) < 0) { + pa_log("force_flat_volume= expects a boolean argument"); + goto fail; + } + + if (use_volume_sharing && force_flat_volume) { + pa_log("Flat volume can't be forced when using volume sharing."); + goto fail; + } + u = pa_xnew0(struct userdata, 1); u->module = m; m->userdata = u; @@ -531,9 +552,9 @@ int pa__init(pa_module*m) { pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Virtual Sink %s on %s", sink_data.name, z ? z : master->name); } - u->sink = pa_sink_new(m->core, &sink_data, - PA_SINK_HW_MUTE_CTRL|PA_SINK_HW_VOLUME_CTRL|PA_SINK_DECIBEL_VOLUME| - (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY))); + u->sink = pa_sink_new(m->core, &sink_data, (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY)) + | (use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0) + | (force_flat_volume ? PA_SINK_FLAT_VOLUME : 0)); pa_sink_new_data_done(&sink_data); if (!u->sink) { @@ -545,7 +566,7 @@ int pa__init(pa_module*m) { u->sink->set_state = sink_set_state_cb; u->sink->update_requested_latency = sink_update_requested_latency_cb; u->sink->request_rewind = sink_request_rewind_cb; - u->sink->set_volume = sink_set_volume_cb; + u->sink->set_volume = use_volume_sharing ? NULL : sink_set_volume_cb; u->sink->set_mute = sink_set_mute_cb; u->sink->userdata = u; @@ -556,7 +577,8 @@ int pa__init(pa_module*m) { sink_input_data.driver = __FILE__; sink_input_data.module = m; sink_input_data.sink = master; - pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Sink Stream"); + sink_input_data.origin_sink = u->sink; + pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Sink Stream from %s", pa_proplist_gets(u->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)); pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter"); pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss); pa_sink_input_new_data_set_channel_map(&sink_input_data, &map); @@ -579,32 +601,29 @@ int pa__init(pa_module*m) { u->sink_input->state_change = sink_input_state_change_cb; u->sink_input->may_move_to = sink_input_may_move_to_cb; u->sink_input->moving = sink_input_moving_cb; - u->sink_input->volume_changed = sink_input_volume_changed_cb; + u->sink_input->volume_changed = use_volume_sharing ? NULL : sink_input_volume_changed_cb; u->sink_input->mute_changed = sink_input_mute_changed_cb; u->sink_input->userdata = u; - /* (9) IF YOU REQUIRE A FIXED BLOCK SIZE MAKE SURE TO PASS A - * SILENCE MEMBLOCK AS LAST PARAMETER - * HERE. pa_sink_input_get_silence() IS USEFUL HERE. */ - u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL); + u->sink->input_to_master = u->sink_input; - /* (10) INITIALIZE ANYTHING ELSE YOU NEED HERE */ + pa_sink_input_get_silence(u->sink_input, &silence); + u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, &silence); + pa_memblock_unref(silence.memblock); + + /* (9) INITIALIZE ANYTHING ELSE YOU NEED HERE */ pa_sink_put(u->sink); pa_sink_input_put(u->sink_input); pa_modargs_free(ma); - pa_xfree(use_default); - return 0; - fail: +fail: if (ma) pa_modargs_free(ma); - pa_xfree(use_default); - pa__done(m); return -1; |