43e8283efc5417e9b54f842e19d5e047a2775e60
[AGL/meta-agl.git] / meta-ivi-common / recipes-multimedia / pulseaudio / pulseaudio / 0012-volume-ramp-add-volume-ramping-to-sink.patch
1 --- a/src/pulsecore/sink.c      2016-04-12 18:01:23.403957855 +0200
2 +++ b/src/pulsecore/sink.c      2016-04-12 18:44:49.677953506 +0200
3 @@ -324,6 +324,8 @@
4              &s->sample_spec,
5              0);
6  
7 +    pa_cvolume_ramp_int_init(&s->ramp, PA_VOLUME_NORM, data->sample_spec.channels);
8 +
9      s->thread_info.rtpoll = NULL;
10      s->thread_info.inputs = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL,
11                                                  (pa_free_cb_t) pa_sink_input_unref);
12 @@ -347,6 +349,8 @@
13      s->thread_info.volume_change_extra_delay = core->deferred_volume_extra_delay_usec;
14      s->thread_info.latency_offset = s->latency_offset;
15  
16 +    s->thread_info.ramp = s->ramp;
17 +
18      /* FIXME: This should probably be moved to pa_sink_put() */
19      pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0);
20  
21 @@ -1182,6 +1186,7 @@
22  
23      } else if (n == 1) {
24          pa_cvolume volume;
25 +        pa_cvolume target;
26  
27          *result = info[0].chunk;
28          pa_memblock_ref(result->memblock);
29 @@ -1198,9 +1203,20 @@
30                                      result,
31                                      &s->sample_spec,
32                                      result->length);
33 -        } else if (!pa_cvolume_is_norm(&volume)) {
34 +        } else if (!pa_cvolume_is_norm(&volume) || pa_cvolume_ramp_target_active(&s->thread_info.ramp) || pa_cvolume_ramp_active(&s->thread_info.ramp)) {
35              pa_memchunk_make_writable(result, 0);
36 -            pa_volume_memchunk(result, &s->sample_spec, &volume);
37 +            if (!pa_cvolume_ramp_active(&s->thread_info.ramp)) {
38 +                if (!pa_cvolume_is_norm(&volume))
39 +                    pa_volume_memchunk(result, &s->sample_spec, &volume);
40 +                pa_volume_ramp_memchunk(result, &s->sample_spec, &(s->thread_info.ramp));
41 +            }
42 +            else {
43 +                if (pa_cvolume_ramp_target_active(&s->thread_info.ramp)) {
44 +                    pa_cvolume_ramp_get_targets(&s->thread_info.ramp, &target);
45 +                    pa_sw_cvolume_multiply(&volume, &volume, &target);
46 +                }
47 +                pa_volume_memchunk(result, &s->sample_spec, &volume);
48 +            }
49          }
50      } else {
51          void *ptr;
52 @@ -1290,6 +1306,7 @@
53  
54      } else {
55          void *ptr;
56 +        pa_cvolume target_vol;
57  
58          ptr = pa_memblock_acquire(target->memblock);
59  
60 @@ -1299,6 +1316,15 @@
61                                  &s->thread_info.soft_volume,
62                                  s->thread_info.soft_muted);
63  
64 +        if (pa_cvolume_ramp_target_active(&s->thread_info.ramp) || pa_cvolume_ramp_active(&s->thread_info.ramp)) {
65 +            if (pa_cvolume_ramp_active(&s->thread_info.ramp))
66 +                pa_volume_ramp_memchunk(target, &s->sample_spec, &(s->thread_info.ramp));
67 +            else {
68 +                pa_cvolume_ramp_get_targets(&s->thread_info.ramp, &target_vol);
69 +                pa_volume_memchunk(target, &s->sample_spec, &target_vol);
70 +            }
71 +        }
72 +
73          pa_memblock_release(target->memblock);
74      }
75  
76 @@ -2058,6 +2084,32 @@
77          pa_assert_se(pa_asyncmsgq_send(root_sink->asyncmsgq, PA_MSGOBJECT(root_sink), PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL) == 0);
78  }
79  
80 +/* Called from main thread */
81 +void pa_sink_set_volume_ramp(
82 +        pa_sink *s,
83 +        const pa_cvolume_ramp *ramp,
84 +        bool send_msg,
85 +        bool save) {
86 +
87 +    pa_sink_assert_ref(s);
88 +    pa_assert_ctl_context();
89 +    pa_assert(PA_SINK_IS_LINKED(s->state));
90 +    pa_assert(ramp);
91 +
92 +    /* make sure we don't change the volume when a PASSTHROUGH input is connected ...
93 +     * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */
94 +    if (pa_sink_is_passthrough(s)) {
95 +        pa_log_warn("Cannot do volume ramp, Sink is connected to PASSTHROUGH input");
96 +        return;
97 +    }
98 +
99 +    pa_cvolume_ramp_convert(ramp, &s->ramp, s->sample_spec.rate);
100 +
101 +    /* This tells the sink that volume ramp changed */
102 +    if (send_msg)
103 +        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME_RAMP, NULL, 0, NULL) == 0);
104 +}
105 +
106  /* Called from the io thread if sync volume is used, otherwise from the main thread.
107   * Only to be called by sink implementor */
108  void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {
109 @@ -2713,6 +2765,12 @@
110              sync_input_volumes_within_thread(s);
111              return 0;
112  
113 +        case PA_SINK_MESSAGE_SET_VOLUME_RAMP:
114 +            /* if we have ongoing ramp where we take current start values */
115 +            pa_cvolume_ramp_start_from(&s->thread_info.ramp, &s->ramp);
116 +            s->thread_info.ramp = s->ramp;
117 +            return 0;
118 +
119          case PA_SINK_MESSAGE_GET_VOLUME:
120  
121              if ((s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_volume) {
122 --- a/src/pulsecore/sink.h      2016-04-12 18:01:42.117957824 +0200
123 +++ b/src/pulsecore/sink.h      2016-04-12 18:23:29.394955642 +0200
124 @@ -105,6 +105,9 @@
125      pa_cvolume saved_volume;
126      bool saved_save_volume:1;
127  
128 +    /* for volume ramps */
129 +    pa_cvolume_ramp_int ramp;
130 +
131      pa_asyncmsgq *asyncmsgq;
132  
133      pa_memchunk silence;
134 @@ -300,6 +303,8 @@
135          uint32_t volume_change_safety_margin;
136          /* Usec delay added to all volume change events, may be negative. */
137          int32_t volume_change_extra_delay;
138 +
139 +        pa_cvolume_ramp_int ramp;
140      } thread_info;
141  
142      void *userdata;
143 @@ -333,6 +338,7 @@
144      PA_SINK_MESSAGE_SET_MAX_REQUEST,
145      PA_SINK_MESSAGE_SET_PORT,
146      PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE,
147 +    PA_SINK_MESSAGE_SET_VOLUME_RAMP,
148      PA_SINK_MESSAGE_SET_LATENCY_OFFSET,
149      PA_SINK_MESSAGE_MAX
150  } pa_sink_message_t;
151 @@ -453,6 +459,8 @@
152  void pa_sink_set_mute(pa_sink *sink, bool mute, bool save);
153  bool pa_sink_get_mute(pa_sink *sink, bool force_refresh);
154  
155 +void pa_sink_set_volume_ramp(pa_sink *s, const pa_cvolume_ramp *ramp, bool send_msg, bool save); 
156 +
157  bool pa_sink_update_proplist(pa_sink *s, pa_update_mode_t mode, pa_proplist *p);
158  
159  int pa_sink_set_port(pa_sink *s, const char *name, bool save);