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