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