meta-agl-profile-telematics: recipes-core: systemd: change canbus systemd match regex
[AGL/meta-agl.git] / meta-agl-profile-core / recipes-multimedia / pulseaudio / pulseaudio-12.2 / 0005-sink-input-volume-Add-support-for-volume-ramp-factor.patch
1 From a98e78ccc4f12d6efad2832a09202651e2a8b6cd Mon Sep 17 00:00:00 2001
2 From: Sangchul Lee <sangchul1011@gmail.com>
3 Date: Sat, 27 Aug 2016 21:33:19 +0900
4 Subject: [PATCH 5/6] sink-input, volume: Add support for volume ramp factor
5
6 Previously, using pa_sink_input_set_volume_ramp() is hard to manage
7 if there are several callers. These new volume ramp factor APIs make it
8 easy for caller to use and to set more than one volume ramp factor.
9 New volume ramp factor will be applied by the multiplication of the other
10 ramp factors that have been already set.
11
12 APIs are added as below.
13  - pa_sink_input_add_volume_ramp_factor()
14  - pa_sink_input_remove_volume_ramp_factor()
15  - pa_cvolume_ramp_compatible()
16  - pa_sw_cvolume_ramp_multiply()
17  - pa_cvolume_ramp_valid()
18
19 Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
20 ---
21  src/map-file               |   3 ++
22  src/pulse/volume.c         |  44 ++++++++++++++++++
23  src/pulse/volume.h         |   9 ++++
24  src/pulsecore/sink-input.c | 108 +++++++++++++++++++++++++++++++++++++++++++++
25  src/pulsecore/sink-input.h |   5 +++
26  5 files changed, 169 insertions(+)
27
28 diff --git a/src/map-file b/src/map-file
29 index ef9b57d..7577c14 100644
30 --- a/src/map-file
31 +++ b/src/map-file
32 @@ -142,6 +142,8 @@ pa_cvolume_ramp_equal;
33  pa_cvolume_ramp_init;
34  pa_cvolume_ramp_set;
35  pa_cvolume_ramp_channel_ramp_set;
36 +pa_cvolume_ramp_compatible;
37 +pa_cvolume_ramp_valid;
38  pa_cvolume_remap;
39  pa_cvolume_scale;
40  pa_cvolume_scale_mask;
41 @@ -344,6 +346,7 @@ pa_sw_cvolume_divide_scalar;
42  pa_sw_cvolume_multiply;
43  pa_sw_cvolume_multiply_scalar;
44  pa_sw_cvolume_snprint_dB;
45 +pa_sw_cvolume_ramp_multiply;
46  pa_sw_volume_divide;
47  pa_sw_volume_from_dB;
48  pa_sw_volume_from_linear;
49 diff --git a/src/pulse/volume.c b/src/pulse/volume.c
50 index 85072c1..8d99150 100644
51 --- a/src/pulse/volume.c
52 +++ b/src/pulse/volume.c
53 @@ -1049,3 +1049,47 @@ pa_cvolume_ramp* pa_cvolume_ramp_channel_ramp_set(pa_cvolume_ramp *ramp, unsigne
54  
55      return ramp;
56  }
57 +
58 +int pa_cvolume_ramp_compatible(const pa_cvolume_ramp *ramp, const pa_sample_spec *ss) {
59 +
60 +    pa_assert(ramp);
61 +    pa_assert(ss);
62 +
63 +    pa_return_val_if_fail(pa_cvolume_ramp_valid(ramp), 0);
64 +    pa_return_val_if_fail(pa_sample_spec_valid(ss), 0);
65 +
66 +    return ramp->channels == ss->channels;
67 +}
68 +
69 +pa_cvolume_ramp *pa_sw_cvolume_ramp_multiply(pa_cvolume_ramp *dest, const pa_cvolume_ramp *a, const pa_cvolume_ramp *b) {
70 +    unsigned i;
71 +
72 +    pa_assert(dest);
73 +    pa_assert(a);
74 +    pa_assert(b);
75 +
76 +    pa_return_val_if_fail(pa_cvolume_ramp_valid(a), NULL);
77 +    pa_return_val_if_fail(pa_cvolume_ramp_valid(b), NULL);
78 +
79 +    for (i = 0; i < a->channels && i < b->channels; i++)
80 +        dest->ramps[i].target = pa_sw_volume_multiply(a->ramps[i].target, b->ramps[i].target);
81 +
82 +    dest->channels = (uint8_t) i;
83 +
84 +    return dest;
85 +}
86 +
87 +int pa_cvolume_ramp_valid(const pa_cvolume_ramp *ramp) {
88 +    unsigned c;
89 +
90 +    pa_assert(ramp);
91 +
92 +    if (!pa_channels_valid(ramp->channels))
93 +        return 0;
94 +
95 +    for (c = 0; c < ramp->channels; c++)
96 +        if (!PA_VOLUME_IS_VALID(ramp->ramps[c].target))
97 +            return 0;
98 +
99 +    return 1;
100 +}
101 diff --git a/src/pulse/volume.h b/src/pulse/volume.h
102 index 2ae3451..65fcb08 100644
103 --- a/src/pulse/volume.h
104 +++ b/src/pulse/volume.h
105 @@ -458,12 +458,21 @@ int pa_cvolume_ramp_equal(const pa_cvolume_ramp *a, const pa_cvolume_ramp *b);
106  /** Init volume ramp struct */
107  pa_cvolume_ramp* pa_cvolume_ramp_init(pa_cvolume_ramp *ramp);
108  
109 +/** Set the volume ramp of the first n channels to PA_VOLUME_NORM */
110 +#define pa_cvolume_ramp_reset(a, n, t, l) pa_cvolume_ramp_set((a), (n), (t), (l), PA_VOLUME_NORM)
111 +
112  /** Set first n channels of ramp struct to certain value */
113  pa_cvolume_ramp* pa_cvolume_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol);
114  
115  /** Set individual channel in the channel struct */
116  pa_cvolume_ramp* pa_cvolume_ramp_channel_ramp_set(pa_cvolume_ramp *ramp, unsigned channel, pa_volume_ramp_type_t type, long time, pa_volume_t vol);
117  
118 +int pa_cvolume_ramp_compatible(const pa_cvolume_ramp *ramp, const pa_sample_spec *ss);
119 +
120 +int pa_cvolume_ramp_valid(const pa_cvolume_ramp *ramp);
121 +
122 +pa_cvolume_ramp *pa_sw_cvolume_ramp_multiply(pa_cvolume_ramp *dest, const pa_cvolume_ramp *a, const pa_cvolume_ramp *b);
123 +
124  PA_C_DECL_END
125  
126  #endif
127 diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
128 index e1968e0..6f89aa1 100644
129 --- a/src/pulsecore/sink-input.c
130 +++ b/src/pulsecore/sink-input.c
131 @@ -53,6 +53,11 @@ struct volume_factor_entry {
132      pa_cvolume volume;
133  };
134  
135 +struct volume_ramp_factor_entry {
136 +    char *key;
137 +    pa_cvolume_ramp ramp;
138 +};
139 +
140  static struct volume_factor_entry *volume_factor_entry_new(const char *key, const pa_cvolume *volume) {
141      struct volume_factor_entry *entry;
142  
143 @@ -83,6 +88,37 @@ static void volume_factor_from_hashmap(pa_cvolume *v, pa_hashmap *items, uint8_t
144          pa_sw_cvolume_multiply(v, v, &entry->volume);
145  }
146  
147 +static struct volume_ramp_factor_entry *volume_ramp_factor_entry_new(const char *key, const pa_cvolume_ramp *ramp) {
148 +    struct volume_ramp_factor_entry *entry;
149 +
150 +    pa_assert(key);
151 +    pa_assert(ramp);
152 +
153 +    entry = pa_xnew(struct volume_ramp_factor_entry, 1);
154 +    entry->key = pa_xstrdup(key);
155 +
156 +    entry->ramp = *ramp;
157 +
158 +    return entry;
159 +}
160 +
161 +static void volume_ramp_factor_entry_free(struct volume_ramp_factor_entry *ramp_entry) {
162 +    pa_assert(ramp_entry);
163 +
164 +    pa_xfree(ramp_entry->key);
165 +    pa_xfree(ramp_entry);
166 +}
167 +
168 +static void volume_ramp_factor_from_hashmap(pa_cvolume_ramp *r, pa_hashmap *items, uint8_t channels, pa_volume_ramp_type_t type, long length) {
169 +    struct volume_ramp_factor_entry *entry;
170 +    void *state = NULL;
171 +
172 +    pa_cvolume_ramp_reset(r, channels, type, length);
173 +    PA_HASHMAP_FOREACH(entry, items, state)
174 +        pa_sw_cvolume_ramp_multiply(r, r, &entry->ramp);
175 +
176 +}
177 +
178  static void sink_input_free(pa_object *o);
179  static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
180  
181 @@ -500,6 +536,8 @@ int pa_sink_input_new(
182      i->volume_factor_sink_items = data->volume_factor_sink_items;
183      data->volume_factor_sink_items = NULL;
184      volume_factor_from_hashmap(&i->volume_factor_sink, i->volume_factor_sink_items, i->sink->sample_spec.channels);
185 +    i->ramp_factor_items = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
186 +                                                    (pa_free_cb_t) volume_ramp_factor_entry_free);
187  
188      i->real_ratio = i->reference_ratio = data->volume;
189      pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
190 @@ -764,6 +802,9 @@ static void sink_input_free(pa_object *o) {
191      if (i->volume_factor_sink_items)
192          pa_hashmap_free(i->volume_factor_sink_items);
193  
194 +    if (i->ramp_factor_items)
195 +        pa_hashmap_free(i->ramp_factor_items);
196 +
197      pa_xfree(i->driver);
198      pa_xfree(i);
199  }
200 @@ -1367,6 +1408,73 @@ int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key) {
201      return 0;
202  }
203  
204 +void pa_sink_input_add_volume_ramp_factor(pa_sink_input *i, const char *key, const pa_cvolume_ramp *ramp_factor, bool send_msg) {
205 +    struct volume_ramp_factor_entry *r;
206 +
207 +    pa_sink_input_assert_ref(i);
208 +    pa_assert_ctl_context();
209 +    pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
210 +    pa_assert(ramp_factor);
211 +    pa_assert(key);
212 +    pa_assert(pa_cvolume_ramp_valid(ramp_factor));
213 +    pa_assert(ramp_factor->channels == 1 || pa_cvolume_ramp_compatible(ramp_factor, &i->sample_spec));
214 +
215 +    r = volume_ramp_factor_entry_new(key, ramp_factor);
216 +    if (!pa_cvolume_ramp_compatible(ramp_factor, &i->sample_spec))
217 +        pa_cvolume_ramp_set(&r->ramp, i->sample_spec.channels, ramp_factor->ramps[0].type, ramp_factor->ramps[0].length, ramp_factor->ramps[0].target);
218 +
219 +    pa_assert_se(pa_hashmap_put(i->ramp_factor_items, r->key, r) >= 0);
220 +    if (pa_hashmap_size(i->ramp_factor_items) == 1)
221 +        pa_cvolume_ramp_set(&i->ramp_factor, i->sample_spec.channels, r->ramp.ramps[0].type, r->ramp.ramps[0].length, r->ramp.ramps[0].target);
222 +    else
223 +        pa_sw_cvolume_ramp_multiply(&i->ramp_factor, &i->ramp_factor, &r->ramp);
224 +
225 +    pa_cvolume_ramp_convert(&i->ramp_factor, &i->ramp, i->sample_spec.rate);
226 +
227 +    if (send_msg)
228 +        pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP, NULL, 0, NULL) == 0);
229 +
230 +    return 0;
231 +}
232 +
233 +/* Returns 0 if an entry was removed and -1 if no entry for the given key was
234 + * found. */
235 +int pa_sink_input_remove_volume_ramp_factor(pa_sink_input *i, const char *key, bool send_msg) {
236 +    struct volume_ramp_factor_entry *r;
237 +
238 +    pa_sink_input_assert_ref(i);
239 +    pa_assert(key);
240 +    pa_assert_ctl_context();
241 +    pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
242 +
243 +    r = pa_hashmap_remove(i->ramp_factor_items, key);
244 +    if (!r)
245 +        return -1;
246 +
247 +    switch (pa_hashmap_size(i->ramp_factor_items)) {
248 +        case 0:
249 +            pa_cvolume_ramp_reset(&i->ramp_factor, i->sample_spec.channels, r->ramp.ramps[0].type, r->ramp.ramps[0].length);
250 +            break;
251 +        case 1: {
252 +            struct volume_ramp_factor_entry *rf;
253 +            rf = pa_hashmap_first(i->ramp_factor_items);
254 +            pa_cvolume_ramp_set(&i->ramp_factor, i->sample_spec.channels, r->ramp.ramps[0].type, r->ramp.ramps[0].length, rf->ramp.ramps[0].target);
255 +            break;
256 +        }
257 +        default:
258 +            volume_ramp_factor_from_hashmap(&i->ramp_factor, i->ramp_factor_items, i->ramp_factor.channels, i->ramp_factor.ramps[0].type, i->ramp_factor.ramps[0].length);
259 +    }
260 +
261 +    volume_ramp_factor_entry_free(r);
262 +
263 +    pa_cvolume_ramp_convert(&i->ramp_factor, &i->ramp, i->sample_spec.rate);
264 +
265 +    if (send_msg)
266 +        pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME_RAMP, NULL, 0, NULL) == 0);
267 +
268 +    return 0;
269 +}
270 +
271  /* Called from main thread */
272  void pa_sink_input_set_volume_ramp(
273          pa_sink_input *i,
274 diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
275 index 92f61c3..5430d53 100644
276 --- a/src/pulsecore/sink-input.h
277 +++ b/src/pulsecore/sink-input.h
278 @@ -113,6 +113,9 @@ struct pa_sink_input {
279      pa_cvolume volume_factor_sink; /* A second volume factor in format of the sink this stream is connected to. */
280      pa_hashmap *volume_factor_sink_items;
281  
282 +    pa_cvolume_ramp ramp_factor;
283 +    pa_hashmap *ramp_factor_items;
284 +
285      bool volume_writable:1;
286  
287      bool muted:1;
288 @@ -379,6 +382,8 @@ void pa_sink_input_add_volume_factor(pa_sink_input *i, const char *key, const pa
289  int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key);
290  pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, bool absolute);
291  void pa_sink_input_set_volume_ramp(pa_sink_input *i, const pa_cvolume_ramp *ramp, bool send_msg);
292 +void pa_sink_input_add_volume_ramp_factor(pa_sink_input *i, const char *key, const pa_cvolume_ramp *ramp_factor, bool send_msg);
293 +int pa_sink_input_remove_volume_ramp_factor(pa_sink_input *i, const char *key, bool send_msg);
294  
295  void pa_sink_input_set_mute(pa_sink_input *i, bool mute, bool save);
296  
297 -- 
298 1.9.1
299