summaryrefslogtreecommitdiffstats
path: root/polyp/sink.c
diff options
context:
space:
mode:
Diffstat (limited to 'polyp/sink.c')
-rw-r--r--polyp/sink.c85
1 files changed, 67 insertions, 18 deletions
diff --git a/polyp/sink.c b/polyp/sink.c
index 481e5cf7..3b074721 100644
--- a/polyp/sink.c
+++ b/polyp/sink.c
@@ -39,12 +39,23 @@
#define MAX_MIX_CHANNELS 32
-struct pa_sink* pa_sink_new(struct pa_core *core, pa_typeid_t typeid, const char *name, int fail, const struct pa_sample_spec *spec) {
+struct pa_sink* pa_sink_new(
+ struct pa_core *core,
+ const char *name,
+ const char *driver,
+ int fail,
+ const struct pa_sample_spec *spec,
+ const struct pa_channel_map *map) {
+
struct pa_sink *s;
char *n = NULL;
char st[256];
int r;
- assert(core && name && *name && spec);
+
+ assert(core);
+ assert(name);
+ assert(*name);
+ assert(spec);
s = pa_xmalloc(sizeof(struct pa_sink));
@@ -53,31 +64,41 @@ struct pa_sink* pa_sink_new(struct pa_core *core, pa_typeid_t typeid, const char
return NULL;
}
- s->name = pa_xstrdup(name);
- s->description = NULL;
- s->typeid = typeid;
-
s->ref = 1;
+ s->core = core;
+
s->state = PA_SINK_RUNNING;
-
+ s->name = pa_xstrdup(name);
+ s->description = NULL;
+ s->driver = pa_xstrdup(driver);
s->owner = NULL;
- s->core = core;
+
s->sample_spec = *spec;
+ if (map)
+ s->channel_map = *map;
+ else
+ pa_channel_map_init_auto(&s->channel_map, spec->channels);
+
s->inputs = pa_idxset_new(NULL, NULL);
n = pa_sprintf_malloc("%s_monitor", name);
- s->monitor_source = pa_source_new(core, typeid, n, 0, spec);
+ s->monitor_source = pa_source_new(core, n, driver, 0, spec, map);
assert(s->monitor_source);
pa_xfree(n);
s->monitor_source->monitor_of = s;
s->monitor_source->description = pa_sprintf_malloc("Monitor source of sink '%s'", s->name);
-
- s->volume = PA_VOLUME_NORM;
+
+ pa_cvolume_reset(&s->sw_volume);
+ pa_cvolume_reset(&s->hw_volume);
s->notify = NULL;
s->get_latency = NULL;
+ s->set_volume = NULL;
+ s->get_volume = NULL;
s->userdata = NULL;
+ s->flags = 0;
+
r = pa_idxset_put(core->sinks, s, &s->index);
assert(s->index != PA_IDXSET_INVALID && r >= 0);
@@ -127,6 +148,7 @@ static void sink_free(struct pa_sink *s) {
pa_xfree(s->name);
pa_xfree(s->description);
+ pa_xfree(s->driver);
pa_xfree(s);
}
@@ -360,11 +382,38 @@ void pa_sink_set_owner(struct pa_sink *s, struct pa_module *m) {
pa_source_set_owner(s->monitor_source, m);
}
-void pa_sink_set_volume(struct pa_sink *s, pa_volume_t volume) {
- assert(s && s->ref >= 1);
-
- if (s->volume != volume) {
- s->volume = volume;
- pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
- }
+void pa_sink_set_volume(struct pa_sink *s, pa_mixer_t m, const struct pa_cvolume *volume) {
+ struct pa_cvolume *v;
+ assert(s);
+ assert(s->ref >= 1);
+ assert(volume);
+
+ if ((m == PA_MIXER_HARDWARE || m == PA_MIXER_AUTO) && s->set_volume)
+ v = &s->hw_volume;
+ else
+ v = &s->sw_volume;
+
+ if (pa_cvolume_equal(v, volume))
+ return;
+
+ *v = volume;
+ pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+
+ if (v == &s->hw_volume)
+ s->set_volume(s);
+}
+
+const struct pa_cvolume *pa_sink_get_volume(struct pa_sink *sink, pa_mixer_t m) {
+ struct pa_cvolume *v;
+ assert(s);
+ assert(s->ref >= 1);
+
+ if ((m == PA_MIXER_HARDWARE || m == PA_MIXER_AUTO) && s->set_volume) {
+
+ if (s->get_volume)
+ s->get_volume(s);
+
+ return &s->hw_volume;
+ } else
+ return &s->sw_volume;
}