]> code.delx.au - pulseaudio/blob - src/pulsecore/sink-input.c
core: Fix macro typo - PA_SINK_IS_LINKED -> PA_SINK_INPUT_IS_LINKED
[pulseaudio] / src / pulsecore / sink-input.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <pulse/utf8.h>
32 #include <pulse/xmalloc.h>
33 #include <pulse/util.h>
34
35 #include <pulsecore/sample-util.h>
36 #include <pulsecore/core-subscribe.h>
37 #include <pulsecore/log.h>
38 #include <pulsecore/play-memblockq.h>
39 #include <pulsecore/namereg.h>
40 #include <pulsecore/core-util.h>
41 #include <pulse/timeval.h>
42
43 #include "sink-input.h"
44
45 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
46 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
47
48 PA_DEFINE_PUBLIC_CLASS(pa_sink_input, pa_msgobject);
49
50 static void sink_input_free(pa_object *o);
51 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
52 static void sink_input_set_ramping_info(pa_sink_input* i, pa_volume_t pre_virtual_volume, pa_volume_t target_virtual_volume, pa_usec_t t);
53 static void sink_input_set_ramping_info_for_mute(pa_sink_input* i, pa_bool_t mute, pa_usec_t t);
54 static void sink_input_volume_ramping(pa_sink_input* i, pa_memchunk* chunk);
55 static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes);
56 static void sink_input_release_envelope(pa_sink_input *i);
57
58 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) {
59 pa_assert(data);
60
61 pa_zero(*data);
62 data->resample_method = PA_RESAMPLER_INVALID;
63 data->proplist = pa_proplist_new();
64
65 return data;
66 }
67
68 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec) {
69 pa_assert(data);
70
71 if ((data->sample_spec_is_set = !!spec))
72 data->sample_spec = *spec;
73 }
74
75 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map) {
76 pa_assert(data);
77
78 if ((data->channel_map_is_set = !!map))
79 data->channel_map = *map;
80 }
81
82 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
83 pa_assert(data);
84
85 if ((data->volume_is_set = !!volume))
86 data->volume = *volume;
87 }
88
89 void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
90 pa_assert(data);
91 pa_assert(volume_factor);
92
93 if (data->volume_factor_is_set)
94 pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor);
95 else {
96 data->volume_factor_is_set = TRUE;
97 data->volume_factor = *volume_factor;
98 }
99 }
100
101 void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
102 pa_assert(data);
103 pa_assert(volume_factor);
104
105 if (data->volume_factor_sink_is_set)
106 pa_sw_cvolume_multiply(&data->volume_factor_sink, &data->volume_factor_sink, volume_factor);
107 else {
108 data->volume_factor_sink_is_set = TRUE;
109 data->volume_factor_sink = *volume_factor;
110 }
111 }
112
113 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
114 pa_assert(data);
115
116 data->muted_is_set = TRUE;
117 data->muted = !!mute;
118 }
119
120 void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
121 pa_assert(data);
122
123 pa_proplist_free(data->proplist);
124 }
125
126 /* Called from main context */
127 static void reset_callbacks(pa_sink_input *i) {
128 pa_assert(i);
129
130 i->pop = NULL;
131 i->process_rewind = NULL;
132 i->update_max_rewind = NULL;
133 i->update_max_request = NULL;
134 i->update_sink_requested_latency = NULL;
135 i->update_sink_latency_range = NULL;
136 i->update_sink_fixed_latency = NULL;
137 i->attach = NULL;
138 i->detach = NULL;
139 i->suspend = NULL;
140 i->suspend_within_thread = NULL;
141 i->moving = NULL;
142 i->kill = NULL;
143 i->get_latency = NULL;
144 i->state_change = NULL;
145 i->may_move_to = NULL;
146 i->send_event = NULL;
147 i->volume_changed = NULL;
148 i->mute_changed = NULL;
149 }
150
151 /* Called from main context */
152 int pa_sink_input_new(
153 pa_sink_input **_i,
154 pa_core *core,
155 pa_sink_input_new_data *data) {
156
157 pa_sink_input *i;
158 pa_resampler *resampler = NULL;
159 char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
160 pa_channel_map original_cm;
161 int r;
162 char *pt;
163
164 pa_assert(_i);
165 pa_assert(core);
166 pa_assert(data);
167 pa_assert_ctl_context();
168
169 if (data->client)
170 pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
171
172 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0)
173 return r;
174
175 pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID);
176
177 if (!data->sink) {
178 data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
179 data->save_sink = FALSE;
180 }
181
182 pa_return_val_if_fail(data->sink, -PA_ERR_NOENTITY);
183 pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)), -PA_ERR_BADSTATE);
184 pa_return_val_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED), -PA_ERR_INVALID);
185
186 if (!data->sample_spec_is_set)
187 data->sample_spec = data->sink->sample_spec;
188
189 pa_return_val_if_fail(pa_sample_spec_valid(&data->sample_spec), -PA_ERR_INVALID);
190
191 if (!data->channel_map_is_set) {
192 if (pa_channel_map_compatible(&data->sink->channel_map, &data->sample_spec))
193 data->channel_map = data->sink->channel_map;
194 else
195 pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
196 }
197
198 pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
199
200 if (!data->volume_is_set) {
201 pa_cvolume_reset(&data->volume, data->sample_spec.channels);
202 data->volume_is_absolute = FALSE;
203 data->save_volume = FALSE;
204 }
205
206 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
207
208 if (!data->volume_factor_is_set)
209 pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
210
211 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
212
213 if (!data->volume_factor_sink_is_set)
214 pa_cvolume_reset(&data->volume_factor_sink, data->sink->sample_spec.channels);
215
216 pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor_sink, &data->sink->sample_spec), -PA_ERR_INVALID);
217
218 if (!data->muted_is_set)
219 data->muted = FALSE;
220
221 if (data->flags & PA_SINK_INPUT_FIX_FORMAT)
222 data->sample_spec.format = data->sink->sample_spec.format;
223
224 if (data->flags & PA_SINK_INPUT_FIX_RATE)
225 data->sample_spec.rate = data->sink->sample_spec.rate;
226
227 original_cm = data->channel_map;
228
229 if (data->flags & PA_SINK_INPUT_FIX_CHANNELS) {
230 data->sample_spec.channels = data->sink->sample_spec.channels;
231 data->channel_map = data->sink->channel_map;
232 }
233
234 pa_assert(pa_sample_spec_valid(&data->sample_spec));
235 pa_assert(pa_channel_map_valid(&data->channel_map));
236
237 /* Due to the fixing of the sample spec the volume might not match anymore */
238 pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
239
240 if (data->resample_method == PA_RESAMPLER_INVALID)
241 data->resample_method = core->resample_method;
242
243 pa_return_val_if_fail(data->resample_method < PA_RESAMPLER_MAX, -PA_ERR_INVALID);
244
245 if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], data)) < 0)
246 return r;
247
248 if ((data->flags & PA_SINK_INPUT_NO_CREATE_ON_SUSPEND) &&
249 pa_sink_get_state(data->sink) == PA_SINK_SUSPENDED) {
250 pa_log_warn("Failed to create sink input: sink is suspended.");
251 return -PA_ERR_BADSTATE;
252 }
253
254 if (pa_idxset_size(data->sink->inputs) >= PA_MAX_INPUTS_PER_SINK) {
255 pa_log_warn("Failed to create sink input: too many inputs per sink.");
256 return -PA_ERR_TOOLARGE;
257 }
258
259 if ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
260 !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) ||
261 !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
262
263 if (!(resampler = pa_resampler_new(
264 core->mempool,
265 &data->sample_spec, &data->channel_map,
266 &data->sink->sample_spec, &data->sink->channel_map,
267 data->resample_method,
268 ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
269 ((data->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
270 (core->disable_remixing || (data->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
271 (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
272 pa_log_warn("Unsupported resampling operation.");
273 return -PA_ERR_NOTSUPPORTED;
274 }
275 }
276
277 i = pa_msgobject_new(pa_sink_input);
278 i->parent.parent.free = sink_input_free;
279 i->parent.process_msg = pa_sink_input_process_msg;
280
281 i->core = core;
282 i->state = PA_SINK_INPUT_INIT;
283 i->flags = data->flags;
284 i->proplist = pa_proplist_copy(data->proplist);
285 i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
286 i->module = data->module;
287 i->sink = data->sink;
288 i->client = data->client;
289
290 i->requested_resample_method = data->resample_method;
291 i->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
292 i->sample_spec = data->sample_spec;
293 i->channel_map = data->channel_map;
294
295 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !data->volume_is_absolute) {
296 pa_cvolume remapped;
297
298 /* When the 'absolute' bool is not set then we'll treat the volume
299 * as relative to the sink volume even in flat volume mode */
300 remapped = data->sink->reference_volume;
301 pa_cvolume_remap(&remapped, &data->sink->channel_map, &data->channel_map);
302 pa_sw_cvolume_multiply(&i->volume, &data->volume, &remapped);
303 } else
304 i->volume = data->volume;
305
306 i->volume_factor = data->volume_factor;
307 i->volume_factor_sink = data->volume_factor_sink;
308 i->real_ratio = i->reference_ratio = data->volume;
309 pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
310 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
311 i->save_volume = data->save_volume;
312 i->save_sink = data->save_sink;
313 i->save_muted = data->save_muted;
314
315 i->muted = data->muted;
316
317 if (data->sync_base) {
318 i->sync_next = data->sync_base->sync_next;
319 i->sync_prev = data->sync_base;
320
321 if (data->sync_base->sync_next)
322 data->sync_base->sync_next->sync_prev = i;
323 data->sync_base->sync_next = i;
324 } else
325 i->sync_next = i->sync_prev = NULL;
326
327 i->direct_outputs = pa_idxset_new(NULL, NULL);
328
329 reset_callbacks(i);
330 i->userdata = NULL;
331
332 /* Set Ramping info */
333 i->thread_info.ramp_info.is_ramping = FALSE;
334 i->thread_info.ramp_info.envelope_dead = TRUE;
335 i->thread_info.ramp_info.envelope = NULL;
336 i->thread_info.ramp_info.item = NULL;
337 i->thread_info.ramp_info.envelope_dying = 0;
338
339 pa_atomic_store(&i->before_ramping_v, 0);
340 pa_atomic_store(&i->before_ramping_m, 0);
341
342 i->thread_info.state = i->state;
343 i->thread_info.attached = FALSE;
344 pa_atomic_store(&i->thread_info.drained, 1);
345 i->thread_info.sample_spec = i->sample_spec;
346 i->thread_info.resampler = resampler;
347 i->thread_info.soft_volume = i->soft_volume;
348 i->thread_info.muted = i->muted;
349 i->thread_info.requested_sink_latency = (pa_usec_t) -1;
350 i->thread_info.rewrite_nbytes = 0;
351 i->thread_info.rewrite_flush = FALSE;
352 i->thread_info.dont_rewind_render = FALSE;
353 i->thread_info.underrun_for = (uint64_t) -1;
354 i->thread_info.playing_for = 0;
355 i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
356
357 i->thread_info.render_memblockq = pa_memblockq_new(
358 0,
359 MEMBLOCKQ_MAXLENGTH,
360 0,
361 pa_frame_size(&i->sink->sample_spec),
362 0,
363 1,
364 0,
365 &i->sink->silence);
366
367 pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
368 pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
369
370 if (i->client)
371 pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
372
373 pt = pa_proplist_to_string_sep(i->proplist, "\n ");
374 pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
375 i->index,
376 pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
377 i->sink->name,
378 pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec),
379 pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
380 pt);
381 pa_xfree(pt);
382
383 /* Don't forget to call pa_sink_input_put! */
384
385 *_i = i;
386 return 0;
387 }
388
389 /* Called from main context */
390 static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {
391 pa_assert(i);
392 pa_assert_ctl_context();
393
394 if (!i->sink)
395 return;
396
397 if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED)
398 pa_assert_se(i->sink->n_corked -- >= 1);
399 else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED)
400 i->sink->n_corked++;
401 }
402
403 /* Called from main context */
404 static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) {
405 pa_sink_input *ssync;
406 pa_assert(i);
407 pa_assert_ctl_context();
408
409 if (state == PA_SINK_INPUT_DRAINED)
410 state = PA_SINK_INPUT_RUNNING;
411
412 if (i->state == state)
413 return;
414
415 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0);
416
417 update_n_corked(i, state);
418 i->state = state;
419
420 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) {
421 update_n_corked(ssync, state);
422 ssync->state = state;
423 }
424 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) {
425 update_n_corked(ssync, state);
426 ssync->state = state;
427 }
428
429 if (state != PA_SINK_INPUT_UNLINKED) {
430 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], i);
431
432 for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev)
433 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
434
435 for (ssync = i->sync_next; ssync; ssync = ssync->sync_next)
436 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
437 }
438
439 pa_sink_update_status(i->sink);
440 }
441
442 /* Called from main context */
443 void pa_sink_input_unlink(pa_sink_input *i) {
444 pa_bool_t linked;
445 pa_source_output *o, *p = NULL;
446
447 pa_assert(i);
448 pa_assert_ctl_context();
449
450 /* See pa_sink_unlink() for a couple of comments how this function
451 * works */
452
453 pa_sink_input_ref(i);
454
455 linked = PA_SINK_INPUT_IS_LINKED(i->state);
456
457 if (linked)
458 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i);
459
460 if (i->sync_prev)
461 i->sync_prev->sync_next = i->sync_next;
462 if (i->sync_next)
463 i->sync_next->sync_prev = i->sync_prev;
464
465 i->sync_prev = i->sync_next = NULL;
466
467 pa_idxset_remove_by_data(i->core->sink_inputs, i, NULL);
468
469 if (i->sink)
470 if (pa_idxset_remove_by_data(i->sink->inputs, i, NULL))
471 pa_sink_input_unref(i);
472
473 if (i->client)
474 pa_idxset_remove_by_data(i->client->sink_inputs, i, NULL);
475
476 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
477 pa_assert(o != p);
478 pa_source_output_kill(o);
479 p = o;
480 }
481
482 update_n_corked(i, PA_SINK_INPUT_UNLINKED);
483 i->state = PA_SINK_INPUT_UNLINKED;
484
485 if (linked && i->sink) {
486 /* We might need to update the sink's volume if we are in flat volume mode. */
487 if (i->sink->flags & PA_SINK_FLAT_VOLUME)
488 pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
489
490 if (i->sink->asyncmsgq)
491 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
492 }
493
494 reset_callbacks(i);
495
496 if (linked) {
497 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index);
498 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i);
499 }
500
501 if (i->sink) {
502 pa_sink_update_status(i->sink);
503 i->sink = NULL;
504 }
505
506 pa_core_maybe_vacuum(i->core);
507
508 pa_sink_input_unref(i);
509 }
510
511 /* Called from main context */
512 static void sink_input_free(pa_object *o) {
513 pa_sink_input* i = PA_SINK_INPUT(o);
514
515 pa_assert(i);
516 pa_assert_ctl_context();
517 pa_assert(pa_sink_input_refcnt(i) == 0);
518
519 if (PA_SINK_INPUT_IS_LINKED(i->state))
520 pa_sink_input_unlink(i);
521
522 pa_log_info("Freeing input %u \"%s\"", i->index, pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)));
523
524 /* Side note: this function must be able to destruct properly any
525 * kind of sink input in any state, even those which are
526 * "half-moved" or are connected to sinks that have no asyncmsgq
527 * and are hence half-destructed themselves! */
528
529 if (i->thread_info.ramp_info.envelope) {
530 pa_log_debug ("Freeing envelope\n");
531 pa_envelope_free(i->thread_info.ramp_info.envelope);
532 i->thread_info.ramp_info.envelope = NULL;
533 }
534
535 if (i->thread_info.render_memblockq)
536 pa_memblockq_free(i->thread_info.render_memblockq);
537
538 if (i->thread_info.resampler)
539 pa_resampler_free(i->thread_info.resampler);
540
541 if (i->proplist)
542 pa_proplist_free(i->proplist);
543
544 if (i->direct_outputs)
545 pa_idxset_free(i->direct_outputs, NULL, NULL);
546
547 if (i->thread_info.direct_outputs)
548 pa_hashmap_free(i->thread_info.direct_outputs, NULL, NULL);
549
550 pa_xfree(i->driver);
551 pa_xfree(i);
552 }
553
554 /* Called from main context */
555 void pa_sink_input_put(pa_sink_input *i) {
556 pa_sink_input_state_t state;
557
558 pa_sink_input_assert_ref(i);
559 pa_assert_ctl_context();
560
561 pa_assert(i->state == PA_SINK_INPUT_INIT);
562
563 /* The following fields must be initialized properly */
564 pa_assert(i->pop);
565 pa_assert(i->process_rewind);
566 pa_assert(i->kill);
567
568 state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING;
569
570 update_n_corked(i, state);
571 i->state = state;
572
573 /* We might need to update the sink's volume if we are in flat volume mode. */
574 if (i->sink->flags & PA_SINK_FLAT_VOLUME)
575 pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
576 else
577 set_real_ratio(i, &i->volume);
578
579 i->thread_info.soft_volume = i->soft_volume;
580 i->thread_info.muted = i->muted;
581
582 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL) == 0);
583
584 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index);
585 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i);
586
587 pa_sink_update_status(i->sink);
588 }
589
590 /* Called from main context */
591 void pa_sink_input_kill(pa_sink_input*i) {
592 pa_sink_input_assert_ref(i);
593 pa_assert_ctl_context();
594 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
595
596 i->kill(i);
597 }
598
599 /* Called from main context */
600 pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
601 pa_usec_t r[2] = { 0, 0 };
602
603 pa_sink_input_assert_ref(i);
604 pa_assert_ctl_context();
605 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
606
607 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, r, 0, NULL) == 0);
608
609 if (i->get_latency)
610 r[0] += i->get_latency(i);
611
612 if (sink_latency)
613 *sink_latency = r[1];
614
615 return r[0];
616 }
617
618 /* Called from thread context */
619 void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) {
620 pa_bool_t do_volume_adj_here, need_volume_factor_sink;
621 pa_bool_t volume_is_norm;
622 pa_bool_t ramping;
623 size_t block_size_max_sink, block_size_max_sink_input;
624 size_t ilength;
625
626 pa_sink_input_assert_ref(i);
627 pa_sink_input_assert_io_context(i);
628 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
629 pa_assert(pa_frame_aligned(slength, &i->sink->sample_spec));
630 pa_assert(chunk);
631 pa_assert(volume);
632
633 /* pa_log_debug("peek"); */
634
635 pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING ||
636 i->thread_info.state == PA_SINK_INPUT_CORKED ||
637 i->thread_info.state == PA_SINK_INPUT_DRAINED);
638
639 block_size_max_sink_input = i->thread_info.resampler ?
640 pa_resampler_max_block_size(i->thread_info.resampler) :
641 pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sample_spec);
642
643 block_size_max_sink = pa_frame_align(pa_mempool_block_size_max(i->core->mempool), &i->sink->sample_spec);
644
645 /* Default buffer size */
646 if (slength <= 0)
647 slength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sink->sample_spec);
648
649 if (slength > block_size_max_sink)
650 slength = block_size_max_sink;
651
652 if (i->thread_info.resampler) {
653 ilength = pa_resampler_request(i->thread_info.resampler, slength);
654
655 if (ilength <= 0)
656 ilength = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sample_spec);
657 } else
658 ilength = slength;
659
660 if (ilength > block_size_max_sink_input)
661 ilength = block_size_max_sink_input;
662
663 /* If the channel maps of the sink and this stream differ, we need
664 * to adjust the volume *before* we resample. Otherwise we can do
665 * it after and leave it for the sink code */
666
667 do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map) || i->thread_info.ramp_info.is_ramping;
668 volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted;
669 need_volume_factor_sink = !pa_cvolume_is_norm(&i->volume_factor_sink);
670
671 while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) {
672 pa_memchunk tchunk;
673
674 /* There's nothing in our render queue. We need to fill it up
675 * with data from the implementor. */
676
677 if (i->thread_info.state == PA_SINK_INPUT_CORKED ||
678 i->pop(i, ilength, &tchunk) < 0) {
679
680 /* OK, we're corked or the implementor didn't give us any
681 * data, so let's just hand out silence */
682 pa_atomic_store(&i->thread_info.drained, 1);
683
684 pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, TRUE);
685 i->thread_info.playing_for = 0;
686 if (i->thread_info.underrun_for != (uint64_t) -1)
687 i->thread_info.underrun_for += ilength;
688 break;
689 }
690
691 pa_atomic_store(&i->thread_info.drained, 0);
692
693 pa_assert(tchunk.length > 0);
694 pa_assert(tchunk.memblock);
695
696 i->thread_info.underrun_for = 0;
697 i->thread_info.playing_for += tchunk.length;
698
699 while (tchunk.length > 0) {
700 pa_memchunk wchunk;
701 pa_bool_t nvfs = need_volume_factor_sink;
702
703 wchunk = tchunk;
704 pa_memblock_ref(wchunk.memblock);
705
706 if (wchunk.length > block_size_max_sink_input)
707 wchunk.length = block_size_max_sink_input;
708
709 /* It might be necessary to adjust the volume here */
710 if (do_volume_adj_here && !volume_is_norm && !i->thread_info.ramp_info.is_ramping) {
711 pa_memchunk_make_writable(&wchunk, 0);
712
713 if (i->thread_info.muted) {
714 pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
715 nvfs = FALSE;
716
717 } else if (!i->thread_info.resampler && nvfs) {
718 pa_cvolume v;
719
720 /* If we don't need a resampler we can merge the
721 * post and the pre volume adjustment into one */
722
723 pa_sw_cvolume_multiply(&v, &i->thread_info.soft_volume, &i->volume_factor_sink);
724 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &v);
725 nvfs = FALSE;
726
727 } else
728 pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &i->thread_info.soft_volume);
729 }
730
731 if (!i->thread_info.resampler) {
732
733 if (nvfs) {
734 pa_memchunk_make_writable(&wchunk, 0);
735 pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
736 }
737
738 pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
739 } else {
740 pa_memchunk rchunk;
741 pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
742
743 /* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
744
745 if (rchunk.memblock) {
746
747 if (nvfs) {
748 pa_memchunk_make_writable(&rchunk, 0);
749 pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
750 }
751
752 pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
753 pa_memblock_unref(rchunk.memblock);
754 }
755 }
756
757 pa_memblock_unref(wchunk.memblock);
758
759 tchunk.index += wchunk.length;
760 tchunk.length -= wchunk.length;
761 }
762
763 pa_memblock_unref(tchunk.memblock);
764 }
765
766 pa_assert_se(pa_memblockq_peek(i->thread_info.render_memblockq, chunk) >= 0);
767
768 pa_assert(chunk->length > 0);
769 pa_assert(chunk->memblock);
770
771 /* pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
772
773 if (chunk->length > block_size_max_sink)
774 chunk->length = block_size_max_sink;
775
776 ramping = i->thread_info.ramp_info.is_ramping;
777 if (ramping)
778 sink_input_volume_ramping(i, chunk);
779
780 if (!i->thread_info.ramp_info.envelope_dead) {
781 i->thread_info.ramp_info.envelope_dying += chunk->length;
782 pa_log_debug("Envelope dying is %d, chunk length is %zu, dead thresholder is %lu\n", i->thread_info.ramp_info.envelope_dying,
783 chunk->length,
784 i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope));
785
786 if (i->thread_info.ramp_info.envelope_dying >= (int32_t) (i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope))) {
787 pa_log_debug("RELEASE Envelop");
788 i->thread_info.ramp_info.envelope_dead = TRUE;
789 sink_input_release_envelope(i);
790 }
791 }
792
793 /* Let's see if we had to apply the volume adjustment ourselves,
794 * or if this can be done by the sink for us */
795
796 if (do_volume_adj_here)
797 /* We had different channel maps, so we already did the adjustment */
798 pa_cvolume_reset(volume, i->sink->sample_spec.channels);
799 else if (i->thread_info.muted)
800 /* We've both the same channel map, so let's have the sink do the adjustment for us*/
801 pa_cvolume_mute(volume, i->sink->sample_spec.channels);
802 else
803 *volume = i->thread_info.soft_volume;
804 }
805
806 /* Called from thread context */
807 void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
808
809 pa_sink_input_assert_ref(i);
810 pa_sink_input_assert_io_context(i);
811 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
812 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
813 pa_assert(nbytes > 0);
814
815 /* pa_log_debug("dropping %lu", (unsigned long) nbytes); */
816
817 pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
818 }
819
820 /* Called from thread context */
821 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
822 size_t lbq;
823 pa_bool_t called = FALSE;
824
825 pa_sink_input_assert_ref(i);
826 pa_sink_input_assert_io_context(i);
827 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
828 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
829
830 /* pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
831
832 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
833
834 if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
835 pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
836 pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
837 sink_input_rewind_ramp_info(i, nbytes);
838 }
839
840 if (i->thread_info.rewrite_nbytes == (size_t) -1) {
841
842 /* We were asked to drop all buffered data, and rerequest new
843 * data from implementor the next time push() is called */
844
845 pa_memblockq_flush_write(i->thread_info.render_memblockq);
846
847 } else if (i->thread_info.rewrite_nbytes > 0) {
848 size_t max_rewrite, amount;
849
850 /* Calculate how much make sense to rewrite at most */
851 max_rewrite = nbytes + lbq;
852
853 /* Transform into local domain */
854 if (i->thread_info.resampler)
855 max_rewrite = pa_resampler_request(i->thread_info.resampler, max_rewrite);
856
857 /* Calculate how much of the rewinded data should actually be rewritten */
858 amount = PA_MIN(i->thread_info.rewrite_nbytes, max_rewrite);
859
860 if (amount > 0) {
861 pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
862
863 /* Tell the implementor */
864 if (i->process_rewind)
865 i->process_rewind(i, amount);
866 called = TRUE;
867
868 /* Convert back to to sink domain */
869 if (i->thread_info.resampler)
870 amount = pa_resampler_result(i->thread_info.resampler, amount);
871
872 if (amount > 0)
873 /* Ok, now update the write pointer */
874 pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE, TRUE);
875
876 if (i->thread_info.rewrite_flush)
877 pa_memblockq_silence(i->thread_info.render_memblockq);
878
879 /* And reset the resampler */
880 if (i->thread_info.resampler)
881 pa_resampler_reset(i->thread_info.resampler);
882 }
883 }
884
885 if (!called)
886 if (i->process_rewind)
887 i->process_rewind(i, 0);
888
889 i->thread_info.rewrite_nbytes = 0;
890 i->thread_info.rewrite_flush = FALSE;
891 i->thread_info.dont_rewind_render = FALSE;
892 }
893
894 /* Called from thread context */
895 size_t pa_sink_input_get_max_rewind(pa_sink_input *i) {
896 pa_sink_input_assert_ref(i);
897 pa_sink_input_assert_io_context(i);
898
899 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_rewind) : i->sink->thread_info.max_rewind;
900 }
901
902 /* Called from thread context */
903 size_t pa_sink_input_get_max_request(pa_sink_input *i) {
904 pa_sink_input_assert_ref(i);
905 pa_sink_input_assert_io_context(i);
906
907 /* We're not verifying the status here, to allow this to be called
908 * in the state change handler between _INIT and _RUNNING */
909
910 return i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, i->sink->thread_info.max_request) : i->sink->thread_info.max_request;
911 }
912
913 /* Called from thread context */
914 void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
915 pa_sink_input_assert_ref(i);
916 pa_sink_input_assert_io_context(i);
917 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
918 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
919
920 pa_memblockq_set_maxrewind(i->thread_info.render_memblockq, nbytes);
921
922 if (i->update_max_rewind)
923 i->update_max_rewind(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
924 }
925
926 /* Called from thread context */
927 void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes /* in the sink's sample spec */) {
928 pa_sink_input_assert_ref(i);
929 pa_sink_input_assert_io_context(i);
930 pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
931 pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
932
933 if (i->update_max_request)
934 i->update_max_request(i, i->thread_info.resampler ? pa_resampler_request(i->thread_info.resampler, nbytes) : nbytes);
935 }
936
937 /* Called from thread context */
938 pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) {
939 pa_sink_input_assert_ref(i);
940 pa_sink_input_assert_io_context(i);
941
942 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
943 usec = i->sink->thread_info.fixed_latency;
944
945 if (usec != (pa_usec_t) -1)
946 usec = PA_CLAMP(usec, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
947
948 i->thread_info.requested_sink_latency = usec;
949 pa_sink_invalidate_requested_latency(i->sink, TRUE);
950
951 return usec;
952 }
953
954 /* Called from main context */
955 pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
956 pa_sink_input_assert_ref(i);
957 pa_assert_ctl_context();
958
959 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
960 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
961 return usec;
962 }
963
964 /* If this sink input is not realized yet or we are being moved,
965 * we have to touch the thread info data directly */
966
967 if (i->sink) {
968 if (!(i->sink->flags & PA_SINK_DYNAMIC_LATENCY))
969 usec = pa_sink_get_fixed_latency(i->sink);
970
971 if (usec != (pa_usec_t) -1) {
972 pa_usec_t min_latency, max_latency;
973 pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
974 usec = PA_CLAMP(usec, min_latency, max_latency);
975 }
976 }
977
978 i->thread_info.requested_sink_latency = usec;
979
980 return usec;
981 }
982
983 /* Called from main context */
984 pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
985 pa_sink_input_assert_ref(i);
986 pa_assert_ctl_context();
987
988 if (PA_SINK_INPUT_IS_LINKED(i->state) && i->sink) {
989 pa_usec_t usec = 0;
990 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
991 return usec;
992 }
993
994 /* If this sink input is not realized yet or we are being moved,
995 * we have to touch the thread info data directly */
996
997 return i->thread_info.requested_sink_latency;
998 }
999
1000 /* Called from main context */
1001 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
1002 pa_sink_input_assert_ref(i);
1003 pa_assert_ctl_context();
1004 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1005 pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
1006
1007 /* This basically calculates:
1008 *
1009 * i->real_ratio := v
1010 * i->soft_volume := i->real_ratio * i->volume_factor */
1011
1012 if (v)
1013 i->real_ratio = *v;
1014 else
1015 pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
1016
1017 pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
1018 /* We don't copy the data to the thread_info data. That's left for someone else to do */
1019 }
1020
1021 /* Called from main context */
1022 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
1023 /* test ramping -> return pa_sink_input_set_volume_with_ramping(i, volume, save, absolute, 2000 * PA_USEC_PER_MSEC); */
1024 return pa_sink_input_set_volume_with_ramping(i, volume, save, absolute, 0);
1025 }
1026
1027 /* Called from main context */
1028 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {
1029 pa_sink_input_assert_ref(i);
1030 pa_assert_ctl_context();
1031 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1032
1033 if (absolute || !(i->sink->flags & PA_SINK_FLAT_VOLUME))
1034 *volume = i->volume;
1035 else
1036 *volume = i->reference_ratio;
1037
1038 return volume;
1039 }
1040
1041 /* Called from main context */
1042 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
1043 /* test ramping -> return pa_sink_input_set_mute_with_ramping(i, mute, save, 2000 * PA_USEC_PER_MSEC); */
1044 return pa_sink_input_set_mute_with_ramping(i, mute, save, 0);
1045 }
1046
1047 /* Called from main context */
1048 pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) {
1049 pa_sink_input_assert_ref(i);
1050 pa_assert_ctl_context();
1051 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1052
1053 return i->muted;
1054 }
1055
1056 /* Called from main thread */
1057 void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {
1058 pa_sink_input_assert_ref(i);
1059 pa_assert_ctl_context();
1060
1061 if (p)
1062 pa_proplist_update(i->proplist, mode, p);
1063
1064 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1065 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1066 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1067 }
1068 }
1069
1070 /* Called from main context */
1071 void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b) {
1072 pa_sink_input_assert_ref(i);
1073 pa_assert_ctl_context();
1074 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1075
1076 sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING);
1077 }
1078
1079 /* Called from main context */
1080 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {
1081 pa_sink_input_assert_ref(i);
1082 pa_assert_ctl_context();
1083 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1084 pa_return_val_if_fail(i->thread_info.resampler, -PA_ERR_BADSTATE);
1085
1086 if (i->sample_spec.rate == rate)
1087 return 0;
1088
1089 i->sample_spec.rate = rate;
1090
1091 pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL);
1092
1093 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1094 return 0;
1095 }
1096
1097 /* Called from main context */
1098 void pa_sink_input_set_name(pa_sink_input *i, const char *name) {
1099 const char *old;
1100 pa_sink_input_assert_ref(i);
1101 pa_assert_ctl_context();
1102
1103 if (!name && !pa_proplist_contains(i->proplist, PA_PROP_MEDIA_NAME))
1104 return;
1105
1106 old = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME);
1107
1108 if (old && name && pa_streq(old, name))
1109 return;
1110
1111 if (name)
1112 pa_proplist_sets(i->proplist, PA_PROP_MEDIA_NAME, name);
1113 else
1114 pa_proplist_unset(i->proplist, PA_PROP_MEDIA_NAME);
1115
1116 if (PA_SINK_INPUT_IS_LINKED(i->state)) {
1117 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
1118 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1119 }
1120 }
1121
1122 /* Called from main context */
1123 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
1124 pa_sink_input_assert_ref(i);
1125 pa_assert_ctl_context();
1126
1127 return i->actual_resample_method;
1128 }
1129
1130 /* Called from main context */
1131 pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {
1132 pa_sink_input_assert_ref(i);
1133 pa_assert_ctl_context();
1134 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1135
1136 if (i->flags & PA_SINK_INPUT_DONT_MOVE)
1137 return FALSE;
1138
1139 if (i->sync_next || i->sync_prev) {
1140 pa_log_warn("Moving synchronised streams not supported.");
1141 return FALSE;
1142 }
1143
1144 return TRUE;
1145 }
1146
1147 /* Called from main context */
1148 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
1149 pa_sink_input_assert_ref(i);
1150 pa_assert_ctl_context();
1151 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1152 pa_sink_assert_ref(dest);
1153
1154 if (dest == i->sink)
1155 return TRUE;
1156
1157 if (!pa_sink_input_may_move(i))
1158 return FALSE;
1159
1160 if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
1161 pa_log_warn("Failed to move sink input: too many inputs per sink.");
1162 return FALSE;
1163 }
1164
1165 if (i->may_move_to)
1166 if (!i->may_move_to(i, dest))
1167 return FALSE;
1168
1169 return TRUE;
1170 }
1171
1172 /* Called from main context */
1173 int pa_sink_input_start_move(pa_sink_input *i) {
1174 pa_source_output *o, *p = NULL;
1175 int r;
1176
1177 pa_sink_input_assert_ref(i);
1178 pa_assert_ctl_context();
1179 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1180 pa_assert(i->sink);
1181
1182 if (!pa_sink_input_may_move(i))
1183 return -PA_ERR_NOTSUPPORTED;
1184
1185 if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
1186 return r;
1187
1188 /* Kill directly connected outputs */
1189 while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
1190 pa_assert(o != p);
1191 pa_source_output_kill(o);
1192 p = o;
1193 }
1194 pa_assert(pa_idxset_isempty(i->direct_outputs));
1195
1196 pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
1197
1198 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1199 pa_assert_se(i->sink->n_corked-- >= 1);
1200
1201 if (i->sink->flags & PA_SINK_FLAT_VOLUME)
1202 /* We might need to update the sink's volume if we are in flat
1203 * volume mode. */
1204 pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
1205
1206 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
1207
1208 pa_sink_update_status(i->sink);
1209 pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
1210 i->sink = NULL;
1211
1212 pa_sink_input_unref(i);
1213
1214 return 0;
1215 }
1216
1217 /* Called from main context */
1218 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1219 pa_resampler *new_resampler;
1220
1221 pa_sink_input_assert_ref(i);
1222 pa_assert_ctl_context();
1223 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1224 pa_assert(!i->sink);
1225 pa_sink_assert_ref(dest);
1226
1227 if (!pa_sink_input_may_move_to(i, dest))
1228 return -PA_ERR_NOTSUPPORTED;
1229
1230 if (i->thread_info.resampler &&
1231 pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
1232 pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
1233
1234 /* Try to reuse the old resampler if possible */
1235 new_resampler = i->thread_info.resampler;
1236
1237 else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
1238 !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) ||
1239 !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) {
1240
1241 /* Okey, we need a new resampler for the new sink */
1242
1243 if (!(new_resampler = pa_resampler_new(
1244 i->core->mempool,
1245 &i->sample_spec, &i->channel_map,
1246 &dest->sample_spec, &dest->channel_map,
1247 i->requested_resample_method,
1248 ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
1249 ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
1250 (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
1251 pa_log_warn("Unsupported resampling operation.");
1252 return -PA_ERR_NOTSUPPORTED;
1253 }
1254 } else
1255 new_resampler = NULL;
1256
1257 if (i->moving)
1258 i->moving(i, dest);
1259
1260 i->sink = dest;
1261 i->save_sink = save;
1262 pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
1263
1264 pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
1265
1266 if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
1267 i->sink->n_corked++;
1268
1269 /* Replace resampler and render queue */
1270 if (new_resampler != i->thread_info.resampler) {
1271
1272 if (i->thread_info.resampler)
1273 pa_resampler_free(i->thread_info.resampler);
1274 i->thread_info.resampler = new_resampler;
1275
1276 pa_memblockq_free(i->thread_info.render_memblockq);
1277
1278 i->thread_info.render_memblockq = pa_memblockq_new(
1279 0,
1280 MEMBLOCKQ_MAXLENGTH,
1281 0,
1282 pa_frame_size(&i->sink->sample_spec),
1283 0,
1284 1,
1285 0,
1286 &i->sink->silence);
1287 }
1288 pa_sink_update_status(dest);
1289
1290 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1291 pa_cvolume remapped;
1292
1293 /* Make relative volumes absolute */
1294 remapped = dest->reference_volume;
1295 pa_cvolume_remap(&remapped, &dest->channel_map, &i->channel_map);
1296 pa_sw_cvolume_multiply(&i->volume, &i->reference_ratio, &remapped);
1297
1298 /* We might need to update the sink's volume if we are in flat volume mode. */
1299 pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
1300 }
1301
1302 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
1303
1304 pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
1305
1306 /* Notify everyone */
1307 pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
1308
1309 if (i->volume_changed)
1310 i->volume_changed(i);
1311
1312 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1313
1314 return 0;
1315 }
1316
1317 /* Called from main context */
1318 void pa_sink_input_fail_move(pa_sink_input *i) {
1319
1320 pa_sink_input_assert_ref(i);
1321 pa_assert_ctl_context();
1322 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1323 pa_assert(!i->sink);
1324
1325 /* Check if someone wants this sink input? */
1326 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], i) == PA_HOOK_STOP)
1327 return;
1328
1329 if (i->moving)
1330 i->moving(i, NULL);
1331
1332 pa_sink_input_kill(i);
1333 }
1334
1335 /* Called from main context */
1336 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
1337 int r;
1338
1339 pa_sink_input_assert_ref(i);
1340 pa_assert_ctl_context();
1341 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1342 pa_assert(i->sink);
1343 pa_sink_assert_ref(dest);
1344
1345 if (dest == i->sink)
1346 return 0;
1347
1348 if (!pa_sink_input_may_move_to(i, dest))
1349 return -PA_ERR_NOTSUPPORTED;
1350
1351 pa_sink_input_ref(i);
1352
1353 if ((r = pa_sink_input_start_move(i)) < 0) {
1354 pa_sink_input_unref(i);
1355 return r;
1356 }
1357
1358 if ((r = pa_sink_input_finish_move(i, dest, save)) < 0) {
1359 pa_sink_input_fail_move(i);
1360 pa_sink_input_unref(i);
1361 return r;
1362 }
1363
1364 pa_sink_input_unref(i);
1365
1366 return 0;
1367 }
1368
1369 /* Called from IO thread context */
1370 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
1371 pa_bool_t corking, uncorking;
1372
1373 pa_sink_input_assert_ref(i);
1374 pa_sink_input_assert_io_context(i);
1375
1376 if (state == i->thread_info.state)
1377 return;
1378
1379 if ((state == PA_SINK_INPUT_DRAINED || state == PA_SINK_INPUT_RUNNING) &&
1380 !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
1381 pa_atomic_store(&i->thread_info.drained, 1);
1382
1383 corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
1384 uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
1385
1386 if (i->state_change)
1387 i->state_change(i, state);
1388
1389 i->thread_info.state = state;
1390
1391 if (corking) {
1392
1393 pa_log_debug("Requesting rewind due to corking");
1394
1395 /* This will tell the implementing sink input driver to rewind
1396 * so that the unplayed already mixed data is not lost */
1397 pa_sink_input_request_rewind(i, 0, TRUE, TRUE, FALSE);
1398
1399 } else if (uncorking) {
1400
1401 i->thread_info.underrun_for = (uint64_t) -1;
1402 i->thread_info.playing_for = 0;
1403
1404 pa_log_debug("Requesting rewind due to uncorking");
1405
1406 /* OK, we're being uncorked. Make sure we're not rewound when
1407 * the hw buffer is remixed and request a remix. */
1408 pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
1409 }
1410 }
1411
1412 /* Called from thread context, except when it is not. */
1413 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1414 pa_sink_input *i = PA_SINK_INPUT(o);
1415 pa_sink_input_assert_ref(i);
1416
1417 switch (code) {
1418
1419 case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
1420 if (pa_atomic_load(&i->before_ramping_v))
1421 i->thread_info.future_soft_volume = i->soft_volume;
1422
1423 if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
1424 if (!pa_atomic_load(&i->before_ramping_v))
1425 i->thread_info.soft_volume = i->soft_volume;
1426 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1427 }
1428 return 0;
1429
1430 case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
1431 if (pa_atomic_load(&i->before_ramping_m))
1432 i->thread_info.future_muted = i->muted;
1433
1434 if (i->thread_info.muted != i->muted) {
1435 if (!pa_atomic_load(&i->before_ramping_m))
1436 i->thread_info.muted = i->muted;
1437 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
1438 }
1439 return 0;
1440
1441 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1442 pa_usec_t *r = userdata;
1443
1444 r[0] += pa_bytes_to_usec(pa_memblockq_get_length(i->thread_info.render_memblockq), &i->sink->sample_spec);
1445 r[1] += pa_sink_get_latency_within_thread(i->sink);
1446
1447 return 0;
1448 }
1449
1450 case PA_SINK_INPUT_MESSAGE_SET_RATE:
1451
1452 i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata);
1453 pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata));
1454
1455 return 0;
1456
1457 case PA_SINK_INPUT_MESSAGE_SET_STATE: {
1458 pa_sink_input *ssync;
1459
1460 pa_sink_input_set_state_within_thread(i, PA_PTR_TO_UINT(userdata));
1461
1462 for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev)
1463 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1464
1465 for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next)
1466 pa_sink_input_set_state_within_thread(ssync, PA_PTR_TO_UINT(userdata));
1467
1468 return 0;
1469 }
1470
1471 case PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: {
1472 pa_usec_t *usec = userdata;
1473
1474 *usec = pa_sink_input_set_requested_latency_within_thread(i, *usec);
1475 return 0;
1476 }
1477
1478 case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: {
1479 pa_usec_t *r = userdata;
1480
1481 *r = i->thread_info.requested_sink_latency;
1482 return 0;
1483 }
1484
1485 case PA_SINK_INPUT_MESSAGE_SET_ENVELOPE: {
1486 if (!i->thread_info.ramp_info.envelope)
1487 i->thread_info.ramp_info.envelope = pa_envelope_new(&i->sink->sample_spec);
1488
1489 if (i->thread_info.ramp_info.envelope && i->thread_info.ramp_info.item) {
1490 pa_envelope_remove(i->thread_info.ramp_info.envelope, i->thread_info.ramp_info.item);
1491 i->thread_info.ramp_info.item = NULL;
1492 }
1493
1494 i->thread_info.ramp_info.item = pa_envelope_add(i->thread_info.ramp_info.envelope, &i->using_def);
1495 i->thread_info.ramp_info.is_ramping = TRUE;
1496 i->thread_info.ramp_info.envelope_dead = FALSE;
1497 i->thread_info.ramp_info.envelope_dying = 0;
1498
1499 if (i->thread_info.ramp_info.envelope)
1500 pa_envelope_restart(i->thread_info.ramp_info.envelope);
1501
1502 return 0;
1503 }
1504 }
1505
1506 return -PA_ERR_NOTIMPLEMENTED;
1507 }
1508
1509 /* Called from main thread */
1510 pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) {
1511 pa_sink_input_assert_ref(i);
1512 pa_assert_ctl_context();
1513
1514 if (i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED)
1515 return pa_atomic_load(&i->thread_info.drained) ? PA_SINK_INPUT_DRAINED : PA_SINK_INPUT_RUNNING;
1516
1517 return i->state;
1518 }
1519
1520 /* Called from IO context */
1521 pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
1522 pa_sink_input_assert_ref(i);
1523 pa_sink_input_assert_io_context(i);
1524
1525 if (PA_SINK_INPUT_IS_LINKED(i->thread_info.state))
1526 return pa_memblockq_is_empty(i->thread_info.render_memblockq);
1527
1528 return TRUE;
1529 }
1530
1531 /* Called from IO context */
1532 void pa_sink_input_request_rewind(
1533 pa_sink_input *i,
1534 size_t nbytes /* in our sample spec */,
1535 pa_bool_t rewrite,
1536 pa_bool_t flush,
1537 pa_bool_t dont_rewind_render) {
1538
1539 size_t lbq;
1540
1541 /* If 'rewrite' is TRUE the sink is rewound as far as requested
1542 * and possible and the exact value of this is passed back the
1543 * implementor via process_rewind(). If 'flush' is also TRUE all
1544 * already rendered data is also dropped.
1545 *
1546 * If 'rewrite' is FALSE the sink is rewound as far as requested
1547 * and possible and the already rendered data is dropped so that
1548 * in the next iteration we read new data from the
1549 * implementor. This implies 'flush' is TRUE. If
1550 * dont_rewind_render is TRUE then the render memblockq is not
1551 * rewound. */
1552
1553 /* nbytes = 0 means maximum rewind request */
1554
1555 pa_sink_input_assert_ref(i);
1556 pa_sink_input_assert_io_context(i);
1557 pa_assert(rewrite || flush);
1558 pa_assert(!dont_rewind_render || !rewrite);
1559
1560 /* We don't take rewind requests while we are corked */
1561 if (i->thread_info.state == PA_SINK_INPUT_CORKED)
1562 return;
1563
1564 nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
1565
1566 /* pa_log_debug("request rewrite %zu", nbytes); */
1567
1568 /* Calculate how much we can rewind locally without having to
1569 * touch the sink */
1570 if (rewrite)
1571 lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
1572 else
1573 lbq = 0;
1574
1575 /* Check if rewinding for the maximum is requested, and if so, fix up */
1576 if (nbytes <= 0) {
1577
1578 /* Calculate maximum number of bytes that could be rewound in theory */
1579 nbytes = i->sink->thread_info.max_rewind + lbq;
1580
1581 /* Transform from sink domain */
1582 if (i->thread_info.resampler)
1583 nbytes = pa_resampler_request(i->thread_info.resampler, nbytes);
1584 }
1585
1586 /* Remember how much we actually want to rewrite */
1587 if (i->thread_info.rewrite_nbytes != (size_t) -1) {
1588 if (rewrite) {
1589 /* Make sure to not overwrite over underruns */
1590 if (nbytes > i->thread_info.playing_for)
1591 nbytes = (size_t) i->thread_info.playing_for;
1592
1593 i->thread_info.rewrite_nbytes = nbytes;
1594 } else
1595 i->thread_info.rewrite_nbytes = (size_t) -1;
1596 }
1597
1598 i->thread_info.rewrite_flush =
1599 i->thread_info.rewrite_flush ||
1600 (flush && i->thread_info.rewrite_nbytes != 0);
1601
1602 i->thread_info.dont_rewind_render =
1603 i->thread_info.dont_rewind_render ||
1604 dont_rewind_render;
1605
1606 if (nbytes != (size_t) -1) {
1607
1608 /* Transform to sink domain */
1609 if (i->thread_info.resampler)
1610 nbytes = pa_resampler_result(i->thread_info.resampler, nbytes);
1611
1612 if (nbytes > lbq)
1613 pa_sink_request_rewind(i->sink, nbytes - lbq);
1614 else
1615 /* This call will make sure process_rewind() is called later */
1616 pa_sink_request_rewind(i->sink, 0);
1617 }
1618 }
1619
1620 /* Called from main context */
1621 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {
1622 pa_sink_input_assert_ref(i);
1623 pa_assert_ctl_context();
1624 pa_assert(ret);
1625
1626 /* FIXME: Shouldn't access resampler object from main context! */
1627
1628 pa_silence_memchunk_get(
1629 &i->core->silence_cache,
1630 i->core->mempool,
1631 ret,
1632 &i->sample_spec,
1633 i->thread_info.resampler ? pa_resampler_max_block_size(i->thread_info.resampler) : 0);
1634
1635 return ret;
1636 }
1637
1638 /* Called from main context */
1639 void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {
1640 pa_proplist *pl = NULL;
1641 pa_sink_input_send_event_hook_data hook_data;
1642
1643 pa_sink_input_assert_ref(i);
1644 pa_assert_ctl_context();
1645 pa_assert(event);
1646
1647 if (!i->send_event)
1648 return;
1649
1650 if (!data)
1651 data = pl = pa_proplist_new();
1652
1653 hook_data.sink_input = i;
1654 hook_data.data = data;
1655 hook_data.event = event;
1656
1657 if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT], &hook_data) < 0)
1658 goto finish;
1659
1660 i->send_event(i, event, data);
1661
1662 finish:
1663 if (pl)
1664 pa_proplist_free(pl);
1665 }
1666
1667 /* Called from IO context */
1668 static void sink_input_volume_ramping(pa_sink_input* i, pa_memchunk* chunk) {
1669 pa_assert(i);
1670 pa_assert(chunk);
1671 pa_assert(chunk->memblock);
1672 pa_assert(i->thread_info.ramp_info.is_ramping);
1673
1674 /* Volume is adjusted with ramping effect here */
1675 pa_envelope_apply(i->thread_info.ramp_info.envelope, chunk);
1676
1677 if (pa_envelope_is_finished(i->thread_info.ramp_info.envelope)) {
1678 i->thread_info.ramp_info.is_ramping = FALSE;
1679 if (pa_atomic_load(&i->before_ramping_v)) {
1680 i->thread_info.soft_volume = i->thread_info.future_soft_volume;
1681 pa_atomic_store(&i->before_ramping_v, 0);
1682 }
1683 else if (pa_atomic_load(&i->before_ramping_m)) {
1684 i->thread_info.muted = i->thread_info.future_muted;
1685 pa_atomic_store(&i->before_ramping_m, 0);
1686 }
1687 }
1688 }
1689
1690 /*
1691 * Called from main context
1692 * This function should be called inside pa_sink_input_set_volume_with_ramping
1693 * should be called after soft_volume of sink_input and sink are all adjusted
1694 */
1695 static void sink_input_set_ramping_info(pa_sink_input* i, pa_volume_t pre_virtual_volume, pa_volume_t target_virtual_volume, pa_usec_t t) {
1696
1697 int32_t target_abs_vol, target_apply_vol, pre_apply_vol;
1698 pa_assert(i);
1699
1700 pa_log_debug("Sink input's soft volume is %d= %f ", pa_cvolume_avg(&i->soft_volume), pa_sw_volume_to_linear(pa_cvolume_avg(&i->soft_volume)));
1701
1702 /* Calculation formula are target_abs_vol := i->soft_volume
1703 * target_apply_vol := lrint(pa_sw_volume_to_linear(target_abs_vol) * 0x10000)
1704 * pre_apply_vol := ( previous_virtual_volume / target_virtual_volume ) * target_apply_vol
1705 *
1706 * Will do volume adjustment inside pa_sink_input_peek
1707 */
1708 target_abs_vol = pa_cvolume_avg(&i->soft_volume);
1709 target_apply_vol = (int32_t) lrint(pa_sw_volume_to_linear(target_abs_vol) * 0x10000);
1710 pre_apply_vol = (int32_t) ((pa_sw_volume_to_linear(pre_virtual_volume) / pa_sw_volume_to_linear(target_virtual_volume)) * target_apply_vol);
1711
1712 i->using_def.n_points = 2;
1713 i->using_def.points_x[0] = 0;
1714 i->using_def.points_x[1] = t;
1715 i->using_def.points_y.i[0] = pre_apply_vol;
1716 i->using_def.points_y.i[1] = target_apply_vol;
1717 i->using_def.points_y.f[0] = ((float) i->using_def.points_y.i[0]) /0x10000;
1718 i->using_def.points_y.f[1] = ((float) i->using_def.points_y.i[1]) /0x10000;
1719
1720 pa_log_debug("Volume Ramping: Point 1 is %d=%f, Point 2 is %d=%f\n", i->using_def.points_y.i[0], i->using_def.points_y.f[0],
1721 i->using_def.points_y.i[1], i->using_def.points_y.f[1]);
1722
1723 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, NULL, 0, NULL) == 0);
1724 }
1725
1726 /* Called from main context */
1727 static void sink_input_set_ramping_info_for_mute(pa_sink_input* i, pa_bool_t mute, pa_usec_t t) {
1728
1729 int32_t cur_vol;
1730 pa_assert(i);
1731
1732 i->using_def.n_points = 2;
1733 i->using_def.points_x[0] = 0;
1734 i->using_def.points_x[1] = t;
1735 cur_vol = (int32_t) lrint( pa_sw_volume_to_linear(pa_cvolume_avg(&i->soft_volume)) * 0x10000);
1736
1737 if (mute) {
1738 i->using_def.points_y.i[0] = cur_vol;
1739 i->using_def.points_y.i[1] = 0;
1740 } else {
1741 i->using_def.points_y.i[0] = 0;
1742 i->using_def.points_y.i[1] = cur_vol;
1743 }
1744
1745 i->using_def.points_y.f[0] = ((float) i->using_def.points_y.i[0]) /0x10000;
1746 i->using_def.points_y.f[1] = ((float) i->using_def.points_y.i[1]) /0x10000;
1747
1748 pa_log_debug("Mute Ramping: Point 1 is %d=%f, Point 2 is %d=%f\n", i->using_def.points_y.i[0], i->using_def.points_y.f[0],
1749 i->using_def.points_y.i[1], i->using_def.points_y.f[1]);
1750
1751 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_ENVELOPE, NULL, 0, NULL) == 0);
1752 }
1753
1754 /* Called from IO context */
1755 static void sink_input_release_envelope(pa_sink_input *i) {
1756 pa_assert(i);
1757 pa_assert(!i->thread_info.ramp_info.is_ramping);
1758 pa_assert(i->thread_info.ramp_info.envelope_dead);
1759
1760 pa_envelope_free(i->thread_info.ramp_info.envelope);
1761 i->thread_info.ramp_info.envelope = NULL;
1762 i->thread_info.ramp_info.item = NULL;
1763 }
1764
1765 /* Called from IO context */
1766 static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes) {
1767 pa_assert(i);
1768
1769 if (!i->thread_info.ramp_info.envelope_dead) {
1770 int32_t envelope_length;
1771
1772 pa_assert(i->thread_info.ramp_info.envelope);
1773
1774 envelope_length = pa_envelope_length(i->thread_info.ramp_info.envelope);
1775
1776 if (i->thread_info.ramp_info.envelope_dying > envelope_length) {
1777 if ((int32_t) (i->thread_info.ramp_info.envelope_dying - nbytes) < envelope_length) {
1778 pa_log_debug("Envelope Become Alive");
1779 pa_envelope_rewind(i->thread_info.ramp_info.envelope, envelope_length - (i->thread_info.ramp_info.envelope_dying - nbytes));
1780 i->thread_info.ramp_info.is_ramping = TRUE;
1781 }
1782 } else if (i->thread_info.ramp_info.envelope_dying < envelope_length) {
1783 if ((i->thread_info.ramp_info.envelope_dying - (ssize_t) nbytes) <= 0) {
1784 pa_log_debug("Envelope Restart");
1785 pa_envelope_restart(i->thread_info.ramp_info.envelope);
1786 }
1787 else {
1788 pa_log_debug("Envelope Simple Rewind");
1789 pa_envelope_rewind(i->thread_info.ramp_info.envelope, nbytes);
1790 }
1791 }
1792
1793 i->thread_info.ramp_info.envelope_dying -= nbytes;
1794 if (i->thread_info.ramp_info.envelope_dying <= 0)
1795 i->thread_info.ramp_info.envelope_dying = 0;
1796 }
1797 }
1798
1799 void pa_sink_input_set_volume_with_ramping(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute, pa_usec_t t){
1800 pa_cvolume v;
1801 pa_volume_t previous_virtual_volume, target_virtual_volume;
1802
1803 pa_sink_input_assert_ref(i);
1804 pa_assert_ctl_context();
1805 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1806 pa_assert(volume);
1807 pa_assert(pa_cvolume_valid(volume));
1808 pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec));
1809
1810 if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
1811 v = i->sink->reference_volume;
1812 pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
1813
1814 if (pa_cvolume_compatible(volume, &i->sample_spec))
1815 volume = pa_sw_cvolume_multiply(&v, &v, volume);
1816 else
1817 volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
1818 } else {
1819
1820 if (!pa_cvolume_compatible(volume, &i->sample_spec)) {
1821 v = i->volume;
1822 volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
1823 }
1824 }
1825
1826 if (pa_cvolume_equal(volume, &i->volume)) {
1827 i->save_volume = i->save_volume || save;
1828 return;
1829 }
1830
1831 previous_virtual_volume = pa_cvolume_avg(&i->volume);
1832 target_virtual_volume = pa_cvolume_avg(volume);
1833
1834 if (t > 0 && target_virtual_volume > 0)
1835 pa_log_debug("SetVolumeWithRamping: Virtual Volume From %u=%f to %u=%f\n", previous_virtual_volume, pa_sw_volume_to_linear(previous_virtual_volume),
1836 target_virtual_volume, pa_sw_volume_to_linear(target_virtual_volume));
1837
1838 i->volume = *volume;
1839 i->save_volume = save;
1840
1841 /* Set this flag before the following code modify i->thread_info.soft_volume */
1842 if (t > 0 && target_virtual_volume > 0)
1843 pa_atomic_store(&i->before_ramping_v, 1);
1844
1845 if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
1846 /* We are in flat volume mode, so let's update all sink input
1847 * volumes and update the flat volume of the sink */
1848
1849 pa_sink_set_volume(i->sink, NULL, TRUE, save);
1850
1851 } else {
1852 /* OK, we are in normal volume mode. The volume only affects
1853 * ourselves */
1854 set_real_ratio(i, volume);
1855
1856 /* Copy the new soft_volume to the thread_info struct */
1857 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
1858 }
1859
1860 if (t > 0 && target_virtual_volume > 0)
1861 sink_input_set_ramping_info(i, previous_virtual_volume, target_virtual_volume, t);
1862
1863 /* The volume changed, let's tell people so */
1864 if (i->volume_changed)
1865 i->volume_changed(i);
1866
1867 /* The virtual volume changed, let's tell people so */
1868 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1869 }
1870
1871 void pa_sink_input_set_mute_with_ramping(pa_sink_input *i, pa_bool_t mute, pa_bool_t save, pa_usec_t t){
1872
1873 pa_sink_input_assert_ref(i);
1874 pa_assert_ctl_context();
1875 pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
1876
1877 if (!i->muted == !mute) {
1878 i->save_muted = i->save_muted || mute;
1879 return;
1880 }
1881
1882 i->muted = mute;
1883 i->save_muted = save;
1884
1885 /* Set this flag before the following code modify i->thread_info.muted, otherwise distortion will be heard */
1886 if (t > 0)
1887 pa_atomic_store(&i->before_ramping_m, 1);
1888
1889 pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
1890
1891 if (t > 0)
1892 sink_input_set_ramping_info_for_mute(i, mute, t);
1893
1894 /* The mute status changed, let's tell people so */
1895 if (i->mute_changed)
1896 i->mute_changed(i);
1897
1898 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
1899 }