routing: add loopback support to nodes
[profile/ivi/pulseaudio-module-murphy-ivi.git] / murphy / fader.c
1 /*
2  * module-murphy-ivi -- PulseAudio module for providing audio routing support
3  * Copyright (c) 2012, Intel Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU Lesser General Public License,
7  * version 2.1, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.
12  * See the GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
17  * MA 02110-1301 USA.
18  *
19  */
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24
25 #include <pulsecore/pulsecore-config.h>
26
27 #include <pulse/proplist.h>
28 #include <pulsecore/core-util.h>
29 #include <pulsecore/sink.h>
30 #include <pulsecore/sink-input.h>
31
32 #include "fader.h"
33 #include "node.h"
34 #include "discover.h"
35 #include "volume.h"
36 #include "utils.h"
37
38 static void set_stream_volume_limit(struct userdata *, pa_sink_input *, double);
39
40 void pa_fader_apply_volume_limits(struct userdata *u, uint32_t stamp)
41 {
42     pa_core       *core;
43     pa_sink       *sink;
44     pa_sink_input *sinp;
45     mir_node      *node;
46     double         atten;
47     uint32_t       i,j;
48     int            class;
49
50     pa_assert(u);
51     pa_assert_se((core = u->core));
52
53     pa_log_debug("applying volume limits ...");
54
55     PA_IDXSET_FOREACH(sink, core->sinks, i) {
56         if ((node = pa_discover_find_node_by_ptr(u, sink))) {
57             pa_log_debug("   node '%s'", node->amname);
58             
59             PA_IDXSET_FOREACH(sinp, sink->inputs, j) {
60                 class = pa_utils_get_stream_class(sinp->proplist);
61                 atten = mir_volume_apply_limits(u, node, class, stamp);
62                 
63                 pa_log_debug("     stream %u attenuation %.2lf dB", sinp->index, atten);
64
65                 set_stream_volume_limit(u, sinp, atten);
66             }
67         }
68     }
69 }
70
71
72 static void set_stream_volume_limit(struct userdata *u, pa_sink_input *sinp, double limit)
73 {
74     pa_sink *sink;
75     pa_volume_t vol;
76
77     pa_assert(u);
78     pa_assert(sinp);
79     pa_assert_se((sink = sinp->sink));
80
81     vol = pa_sw_volume_from_dB(limit);
82     pa_cvolume_set(&sinp->volume_factor, sinp->volume.channels, vol);
83
84     if (pa_sink_flat_volume_enabled(sink)) {
85         pa_sink_set_volume(sink, NULL, TRUE, FALSE);
86     }
87     else {
88         pa_sw_cvolume_multiply(&sinp->soft_volume, &sinp->real_ratio, &sinp->volume_factor);
89
90         pa_asyncmsgq_send(sink->asyncmsgq, PA_MSGOBJECT(sinp),
91                           PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL);
92     }
93     
94
95 }
96
97
98 /*
99  * Local Variables:
100  * c-basic-offset: 4
101  * indent-tabs-mode: nil
102  * End:
103  *
104  */