1 /***
2   This file is part of PulseAudio.
3 
4   This module is based off Lennart Poettering's LADSPA sink and swaps out
5   LADSPA functionality for a dbus-aware STFT OLA based digital equalizer.
6   All new work is published under PulseAudio's original license.
7 
8   Copyright 2009 Jason Newton <nevion@gmail.com>
9 
10   Original Author:
11   Copyright 2004-2008 Lennart Poettering
12 
13   PulseAudio is free software; you can redistribute it and/or modify
14   it under the terms of the GNU Lesser General Public License as
15   published by the Free Software Foundation; either version 2.1 of the
16   License, or (at your option) any later version.
17 
18   PulseAudio is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21   General Public License for more details.
22 
23   You should have received a copy of the GNU Lesser General Public
24   License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
25 ***/
26 
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <float.h>
34 #include <math.h>
35 #include <string.h>
36 #include <stdint.h>
37 
38 //#undef __SSE2__
39 #ifdef __SSE2__
40 #include <xmmintrin.h>
41 #include <emmintrin.h>
42 #endif
43 
44 #include <fftw3.h>
45 
46 #include <pulse/xmalloc.h>
47 #include <pulse/timeval.h>
48 
49 #include <pulsecore/core-rtclock.h>
50 #include <pulsecore/i18n.h>
51 #include <pulsecore/aupdate.h>
52 #include <pulsecore/namereg.h>
53 #include <pulsecore/sink.h>
54 #include <pulsecore/module.h>
55 #include <pulsecore/core-util.h>
56 #include <pulsecore/modargs.h>
57 #include <pulsecore/log.h>
58 #include <pulsecore/rtpoll.h>
59 #include <pulsecore/sample-util.h>
60 #include <pulsecore/shared.h>
61 #include <pulsecore/idxset.h>
62 #include <pulsecore/strlist.h>
63 #include <pulsecore/database.h>
64 #include <pulsecore/protocol-dbus.h>
65 #include <pulsecore/dbus-util.h>
66 
67 PA_MODULE_AUTHOR("Jason Newton");
68 PA_MODULE_DESCRIPTION(_("General Purpose Equalizer"));
69 PA_MODULE_VERSION(PACKAGE_VERSION);
70 PA_MODULE_LOAD_ONCE(false);
71 PA_MODULE_USAGE(
72         _("sink_name=<name of the sink> "
73           "sink_properties=<properties for the sink> "
74           "sink_master=<sink to connect to> "
75           "format=<sample format> "
76           "rate=<sample rate> "
77           "channels=<number of channels> "
78           "channel_map=<channel map> "
79           "autoloaded=<set if this module is being loaded automatically> "
80           "use_volume_sharing=<yes or no> "
81          ));
82 
83 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
84 #define DEFAULT_AUTOLOADED false
85 
86 struct userdata {
87     pa_module *module;
88     pa_sink *sink;
89     pa_sink_input *sink_input;
90     bool autoloaded;
91 
92     size_t channels;
93     size_t fft_size;//length (res) of fft
94     size_t window_size;/*
95                         *sliding window size
96                         *effectively chooses R
97                         */
98     size_t R;/* the hop size between overlapping windows
99               * the latency of the filter, calculated from window_size
100               * based on constraints of COLA and window function
101               */
102     //for twiddling with pulseaudio
103     size_t overlap_size;//window_size-R
104     size_t samples_gathered;
105     size_t input_buffer_max;
106     //message
107     float *W;//windowing function (time domain)
108     float *work_buffer, **input, **overlap_accum;
109     fftwf_complex *output_window;
110     fftwf_plan forward_plan, inverse_plan;
111     //size_t samplings;
112 
113     float **Xs;
114     float ***Hs;//thread updatable copies of the freq response filters (magnitude based)
115     pa_aupdate **a_H;
116     pa_memblockq *input_q;
117     char *output_buffer;
118     size_t output_buffer_length;
119     size_t output_buffer_max_length;
120     pa_memblockq *output_q;
121     bool first_iteration;
122 
123     pa_dbus_protocol *dbus_protocol;
124     char *dbus_path;
125 
126     pa_database *database;
127     char **base_profiles;
128 
129     bool automatic_description;
130 };
131 
132 static const char* const valid_modargs[] = {
133     "sink_name",
134     "sink_properties",
135     "sink_master",
136     "format",
137     "rate",
138     "channels",
139     "channel_map",
140     "autoloaded",
141     "use_volume_sharing",
142     NULL
143 };
144 
145 #define v_size 4
146 #define SINKLIST "equalized_sinklist"
147 #define EQDB "equalizer_db"
148 #define EQ_STATE_DB "equalizer-state"
149 #define FILTER_SIZE(u) ((u)->fft_size / 2 + 1)
150 #define CHANNEL_PROFILE_SIZE(u) (FILTER_SIZE(u) + 1)
151 #define FILTER_STATE_SIZE(u) (CHANNEL_PROFILE_SIZE(u) * (u)->channels)
152 
153 static void dbus_init(struct userdata *u);
154 static void dbus_done(struct userdata *u);
155 
hanning_window(float *W, size_t window_size)156 static void hanning_window(float *W, size_t window_size) {
157     /* h=.5*(1-cos(2*pi*j/(window_size+1)), COLA for R=(M+1)/2 */
158     for (size_t i = 0; i < window_size; ++i)
159         W[i] = (float).5 * (1 - cos(2*M_PI*i / (window_size+1)));
160 }
161 
fix_filter(float *H, size_t fft_size)162 static void fix_filter(float *H, size_t fft_size) {
163     /* divide out the fft gain */
164     for (size_t i = 0; i < fft_size / 2 + 1; ++i)
165         H[i] /= fft_size;
166 }
167 
interpolate(float *samples, size_t length, uint32_t *xs, float *ys, size_t n_points)168 static void interpolate(float *samples, size_t length, uint32_t *xs, float *ys, size_t n_points) {
169     /* Note that xs must be monotonically increasing! */
170     float x_range_lower, x_range_upper, c0;
171 
172     pa_assert(n_points >= 2);
173     pa_assert(xs[0] == 0);
174     pa_assert(xs[n_points - 1] == length - 1);
175 
176     for (size_t x = 0, x_range_lower_i = 0; x < length-1; ++x) {
177         pa_assert(x_range_lower_i < n_points-1);
178 
179         x_range_lower = (float) xs[x_range_lower_i];
180         x_range_upper = (float) xs[x_range_lower_i+1];
181 
182         pa_assert_se(x_range_lower < x_range_upper);
183         pa_assert_se(x >= x_range_lower);
184         pa_assert_se(x <= x_range_upper);
185 
186         /* bilinear-interpolation of coefficients specified */
187         c0 = (x-x_range_lower) / (x_range_upper-x_range_lower);
188         pa_assert(c0 >= 0 && c0 <= 1.0);
189 
190         samples[x] = ((1.0f - c0) * ys[x_range_lower_i] + c0 * ys[x_range_lower_i + 1]);
191         while(x >= xs[x_range_lower_i + 1])
192             x_range_lower_i++;
193     }
194 
195     samples[length-1] = ys[n_points-1];
196 }
197 
is_monotonic(const uint32_t *xs, size_t length)198 static bool is_monotonic(const uint32_t *xs, size_t length) {
199     pa_assert(xs);
200 
201     if (length < 2)
202         return true;
203 
204     for(size_t i = 1; i < length; ++i)
205         if (xs[i] <= xs[i-1])
206             return false;
207 
208     return true;
209 }
210 
211 /* ensures memory allocated is a multiple of v_size and aligned */
alloc(size_t x, size_t s)212 static void * alloc(size_t x, size_t s) {
213     size_t f;
214     float *t;
215 
216     f = PA_ROUND_UP(x*s, sizeof(float)*v_size);
217     pa_assert_se(t = fftwf_malloc(f));
218     pa_memzero(t, f);
219 
220     return t;
221 }
222 
alloc_input_buffers(struct userdata *u, size_t min_buffer_length)223 static void alloc_input_buffers(struct userdata *u, size_t min_buffer_length) {
224     if (min_buffer_length <= u->input_buffer_max)
225         return;
226 
227     pa_assert(min_buffer_length >= u->window_size);
228     for (size_t c = 0; c < u->channels; ++c) {
229         float *tmp = alloc(min_buffer_length, sizeof(float));
230         if (u->input[c]) {
231             if (!u->first_iteration)
232                 memcpy(tmp, u->input[c], u->overlap_size * sizeof(float));
233             fftwf_free(u->input[c]);
234         }
235         u->input[c] = tmp;
236     }
237     u->input_buffer_max = min_buffer_length;
238 }
239 
240 /* Called from I/O thread context */
sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk)241 static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
242     struct userdata *u = PA_SINK(o)->userdata;
243 
244     switch (code) {
245 
246         case PA_SINK_MESSAGE_GET_LATENCY: {
247             //size_t fs=pa_frame_size(&u->sink->sample_spec);
248 
249             /* The sink is _put() before the sink input is, so let's
250              * make sure we don't access it in that time. Also, the
251              * sink input is first shut down, the sink second. */
252             if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
253                 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) {
254                 *((int64_t*) data) = 0;
255                 return 0;
256             }
257 
258             *((int64_t*) data) =
259                 /* Get the latency of the master sink */
260                 pa_sink_get_latency_within_thread(u->sink_input->sink, true) +
261 
262                 /* Add the latency internal to our sink input on top */
263                 pa_bytes_to_usec(pa_memblockq_get_length(u->output_q) +
264                                  pa_memblockq_get_length(u->input_q), &u->sink_input->sink->sample_spec) +
265                 pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec);
266             //    pa_bytes_to_usec(u->samples_gathered * fs, &u->sink->sample_spec);
267             //+ pa_bytes_to_usec(u->latency * fs, ss)
268 
269             /* Add resampler latency */
270             *((int64_t*) data) += pa_resampler_get_delay_usec(u->sink_input->thread_info.resampler);
271             return 0;
272         }
273     }
274 
275     return pa_sink_process_msg(o, code, data, offset, chunk);
276 }
277 
278 /* Called from main context */
sink_set_state_in_main_thread_cb(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause)279 static int sink_set_state_in_main_thread_cb(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
280     struct userdata *u;
281 
282     pa_sink_assert_ref(s);
283     pa_assert_se(u = s->userdata);
284 
285     if (!PA_SINK_IS_LINKED(state) ||
286         !PA_SINK_INPUT_IS_LINKED(u->sink_input->state))
287         return 0;
288 
289     pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED);
290     return 0;
291 }
292 
293 /* Called from the IO thread. */
sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state, pa_suspend_cause_t new_suspend_cause)294 static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
295     struct userdata *u;
296 
297     pa_assert(s);
298     pa_assert_se(u = s->userdata);
299 
300     /* When set to running or idle for the first time, request a rewind
301      * of the master sink to make sure we are heard immediately */
302     if (PA_SINK_IS_OPENED(new_state) && s->thread_info.state == PA_SINK_INIT) {
303         pa_log_debug("Requesting rewind due to state change.");
304         pa_sink_input_request_rewind(u->sink_input, 0, false, true, true);
305     }
306 
307     return 0;
308 }
309 
310 /* Called from I/O thread context */
sink_request_rewind_cb(pa_sink *s)311 static void sink_request_rewind_cb(pa_sink *s) {
312     struct userdata *u;
313 
314     pa_sink_assert_ref(s);
315     pa_assert_se(u = s->userdata);
316 
317     if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
318         !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
319         return;
320 
321     /* Just hand this one over to the master sink */
322     pa_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes+pa_memblockq_get_length(u->input_q), true, false, false);
323 }
324 
325 /* Called from I/O thread context */
sink_update_requested_latency_cb(pa_sink *s)326 static void sink_update_requested_latency_cb(pa_sink *s) {
327     struct userdata *u;
328 
329     pa_sink_assert_ref(s);
330     pa_assert_se(u = s->userdata);
331 
332     if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
333         !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
334         return;
335 
336     /* Just hand this one over to the master sink */
337     pa_sink_input_set_requested_latency_within_thread(
338             u->sink_input,
339             pa_sink_get_requested_latency_within_thread(s));
340 }
341 
342 /* Called from main context */
sink_set_volume_cb(pa_sink *s)343 static void sink_set_volume_cb(pa_sink *s) {
344     struct userdata *u;
345 
346     pa_sink_assert_ref(s);
347     pa_assert_se(u = s->userdata);
348 
349     if (!PA_SINK_IS_LINKED(s->state) ||
350         !PA_SINK_INPUT_IS_LINKED(u->sink_input->state))
351         return;
352 
353     pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, true);
354 }
355 
356 /* Called from main context */
sink_set_mute_cb(pa_sink *s)357 static void sink_set_mute_cb(pa_sink *s) {
358     struct userdata *u;
359 
360     pa_sink_assert_ref(s);
361     pa_assert_se(u = s->userdata);
362 
363     if (!PA_SINK_IS_LINKED(s->state) ||
364         !PA_SINK_INPUT_IS_LINKED(u->sink_input->state))
365         return;
366 
367     pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
368 }
369 
370 #if 1
371 //reference implementation
dsp_logic( float * restrict dst, float * restrict src, float * restrict overlap, const float X, const float * restrict H, const float * restrict W, fftwf_complex * restrict output_window, struct userdata *u)372 static void dsp_logic(
373     float * restrict dst,//used as a temp array too, needs to be fft_length!
374     float * restrict src,/*input data w/ overlap at start,
375                                *automatically cycled in routine
376                                */
377     float * restrict overlap,
378     const float X,//multiplier
379     const float * restrict H,//The freq. magnitude scalers filter
380     const float * restrict W,//The windowing function
381     fftwf_complex * restrict output_window,//The transformed windowed src
382     struct userdata *u) {
383 
384     //use a linear-phase sliding STFT and overlap-add method (for each channel)
385     //window the data
386     for(size_t j = 0; j < u->window_size; ++j) {
387         dst[j] = X * W[j] * src[j];
388     }
389     //zero pad the remaining fft window
390     memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
391     //Processing is done here!
392     //do fft
393     fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
394     //perform filtering
395     for(size_t j = 0; j < FILTER_SIZE(u); ++j) {
396         u->output_window[j][0] *= H[j];
397         u->output_window[j][1] *= H[j];
398     }
399     //inverse fft
400     fftwf_execute_dft_c2r(u->inverse_plan, output_window, dst);
401     ////debug: tests overlapping add
402     ////and negates ALL PREVIOUS processing
403     ////yields a perfect reconstruction if COLA is held
404     //for(size_t j = 0; j < u->window_size; ++j) {
405     //    u->work_buffer[j] = u->W[j] * u->input[c][j];
406     //}
407 
408     //overlap add and preserve overlap component from this window (linear phase)
409     for(size_t j = 0; j < u->overlap_size; ++j) {
410         u->work_buffer[j] += overlap[j];
411         overlap[j] = dst[u->R + j];
412     }
413     ////debug: tests if basic buffering works
414     ////shouldn't modify the signal AT ALL (beyond roundoff)
415     //for(size_t j = 0; j < u->window_size;++j) {
416     //    u->work_buffer[j] = u->input[c][j];
417     //}
418 
419     //preserve the needed input for the next window's overlap
420     memmove(src, src + u->R,
421         (u->samples_gathered - u->R) * sizeof(float)
422     );
423 }
424 #else
425 typedef float v4sf __attribute__ ((__aligned__(v_size * sizeof(float))));
426 typedef union float_vector {
427     float f[v_size];
428     v4sf v;
429     __m128 m;
430 } float_vector_t;
431 
432 //regardless of sse enabled, the loops in here assume
433 //16 byte aligned addresses and memory allocations divisible by v_size
dsp_logic( float * restrict dst, float * restrict src, float * restrict overlap, const float X, const float * restrict H, const float * restrict W, fftwf_complex * restrict output_window, struct userdata *u)434 static void dsp_logic(
435     float * restrict dst,//used as a temp array too, needs to be fft_length!
436     float * restrict src,/*input data w/ overlap at start,
437                                *automatically cycled in routine
438                                */
439     float * restrict overlap,//The size of the overlap
440     const float X,//multiplier
441     const float * restrict H,//The freq. magnitude scalers filter
442     const float * restrict W,//The windowing function
443     fftwf_complex * restrict output_window,//The transformed windowed src
444     struct userdata *u) {//Collection of constants
445     const size_t overlap_size = PA_ROUND_UP(u->overlap_size, v_size);
446     float_vector_t x;
447     x.f[0] = x.f[1] = x.f[2] = x.f[3] = X;
448 
449     //assert(u->samples_gathered >= u->R);
450     //use a linear-phase sliding STFT and overlap-add method
451     for(size_t j = 0; j < u->window_size; j += v_size) {
452         //dst[j] = W[j] * src[j];
453         float_vector_t *d = (float_vector_t*) (dst + j);
454         float_vector_t *w = (float_vector_t*) (W + j);
455         float_vector_t *s = (float_vector_t*) (src + j);
456 //#if __SSE2__
457         d->m = _mm_mul_ps(x.m, _mm_mul_ps(w->m, s->m));
458 //        d->v = x->v * w->v * s->v;
459 //#endif
460     }
461     //zero pad the remaining fft window
462     memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
463 
464     //Processing is done here!
465     //do fft
466     fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
467     //perform filtering - purely magnitude based
468     for(size_t j = 0; j < FILTER_SIZE; j += v_size / 2) {
469         //output_window[j][0]*=H[j];
470         //output_window[j][1]*=H[j];
471         float_vector_t *d = (float_vector_t*)( ((float *) output_window) + 2 * j);
472         float_vector_t h;
473         h.f[0] = h.f[1] = H[j];
474         h.f[2] = h.f[3] = H[j + 1];
475 //#if __SSE2__
476         d->m = _mm_mul_ps(d->m, h.m);
477 //#else
478 //        d->v = d->v * h.v;
479 //#endif
480     }
481 
482     //inverse fft
483     fftwf_execute_dft_c2r(u->inverse_plan, output_window, dst);
484 
485     ////debug: tests overlapping add
486     ////and negates ALL PREVIOUS processing
487     ////yields a perfect reconstruction if COLA is held
488     //for(size_t j = 0; j < u->window_size; ++j) {
489     //    dst[j] = W[j] * src[j];
490     //}
491 
492     //overlap add and preserve overlap component from this window (linear phase)
493     for(size_t j = 0; j < overlap_size; j += v_size) {
494         //dst[j]+=overlap[j];
495         //overlap[j]+=dst[j+R];
496         float_vector_t *d = (float_vector_t*)(dst + j);
497         float_vector_t *o = (float_vector_t*)(overlap + j);
498 //#if __SSE2__
499         d->m = _mm_add_ps(d->m, o->m);
500         o->m = ((float_vector_t*)(dst + u->R + j))->m;
501 //#else
502 //        d->v = d->v + o->v;
503 //        o->v = ((float_vector_t*)(dst + u->R + j))->v;
504 //#endif
505     }
506     //memcpy(overlap, dst+u->R, u->overlap_size * sizeof(float)); //overlap preserve (debug)
507     //zero out the bit beyond the real overlap so we don't add garbage next iteration
508     memset(overlap + u->overlap_size, 0, overlap_size - u->overlap_size);
509 
510     ////debug: tests if basic buffering works
511     ////shouldn't modify the signal AT ALL (beyond roundoff)
512     //for(size_t j = 0; j < u->window_size; ++j) {
513     //    dst[j] = src[j];
514     //}
515 
516     //preserve the needed input for the next window's overlap
517     memmove(src, src + u->R,
518         (u->samples_gathered - u->R) * sizeof(float)
519     );
520 }
521 #endif
522 
flatten_to_memblockq(struct userdata *u)523 static void flatten_to_memblockq(struct userdata *u) {
524     size_t mbs = pa_mempool_block_size_max(u->sink->core->mempool);
525     pa_memchunk tchunk;
526     char *dst;
527     size_t i = 0;
528     while(i < u->output_buffer_length) {
529         tchunk.index = 0;
530         tchunk.length = PA_MIN((u->output_buffer_length - i), mbs);
531         tchunk.memblock = pa_memblock_new(u->sink->core->mempool, tchunk.length);
532         //pa_log_debug("pushing %ld into the q", tchunk.length);
533         dst = pa_memblock_acquire(tchunk.memblock);
534         memcpy(dst, u->output_buffer + i, tchunk.length);
535         pa_memblock_release(tchunk.memblock);
536         pa_memblockq_push(u->output_q, &tchunk);
537         pa_memblock_unref(tchunk.memblock);
538         i += tchunk.length;
539     }
540 }
541 
process_samples(struct userdata *u)542 static void process_samples(struct userdata *u) {
543     size_t fs = pa_frame_size(&(u->sink->sample_spec));
544     unsigned a_i;
545     float *H, X;
546     size_t iterations, offset;
547     pa_assert(u->samples_gathered >= u->window_size);
548     iterations = (u->samples_gathered - u->overlap_size) / u->R;
549     //make sure there is enough buffer memory allocated
550     if (iterations * u->R * fs > u->output_buffer_max_length) {
551         u->output_buffer_max_length = iterations * u->R * fs;
552         pa_xfree(u->output_buffer);
553         u->output_buffer = pa_xmalloc(u->output_buffer_max_length);
554     }
555     u->output_buffer_length = iterations * u->R * fs;
556 
557     for(size_t iter = 0; iter < iterations; ++iter) {
558         offset = iter * u->R * fs;
559         for(size_t c = 0;c < u->channels; c++) {
560             a_i = pa_aupdate_read_begin(u->a_H[c]);
561             X = u->Xs[c][a_i];
562             H = u->Hs[c][a_i];
563             dsp_logic(
564                 u->work_buffer,
565                 u->input[c],
566                 u->overlap_accum[c],
567                 X,
568                 H,
569                 u->W,
570                 u->output_window,
571                 u
572             );
573             pa_aupdate_read_end(u->a_H[c]);
574             if (u->first_iteration) {
575                 /* The windowing function will make the audio ramped in, as a cheap fix we can
576                  * undo the windowing (for non-zero window values)
577                  */
578                 for(size_t i = 0; i < u->overlap_size; ++i) {
579                     u->work_buffer[i] = u->W[i] <= FLT_EPSILON ? u->work_buffer[i] : u->work_buffer[i] / u->W[i];
580                 }
581             }
582             pa_sample_clamp(PA_SAMPLE_FLOAT32NE, (uint8_t *) (((float *)u->output_buffer) + c) + offset, fs, u->work_buffer, sizeof(float), u->R);
583         }
584         if (u->first_iteration) {
585             u->first_iteration = false;
586         }
587         u->samples_gathered -= u->R;
588     }
589     flatten_to_memblockq(u);
590 }
591 
input_buffer(struct userdata *u, pa_memchunk *in)592 static void input_buffer(struct userdata *u, pa_memchunk *in) {
593     size_t fs = pa_frame_size(&(u->sink->sample_spec));
594     size_t samples = in->length/fs;
595     float *src = pa_memblock_acquire_chunk(in);
596     pa_assert(u->samples_gathered + samples <= u->input_buffer_max);
597     for(size_t c = 0; c < u->channels; c++) {
598         //buffer with an offset after the overlap from previous
599         //iterations
600         pa_assert_se(
601             u->input[c] + u->samples_gathered + samples <= u->input[c] + u->input_buffer_max
602         );
603         pa_sample_clamp(PA_SAMPLE_FLOAT32NE, u->input[c] + u->samples_gathered, sizeof(float), src + c, fs, samples);
604     }
605     u->samples_gathered += samples;
606     pa_memblock_release(in->memblock);
607 }
608 
609 /* Called from I/O thread context */
sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk)610 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
611     struct userdata *u;
612     size_t fs, target_samples;
613     size_t mbs;
614     //struct timeval start, end;
615     pa_memchunk tchunk;
616 
617     pa_sink_input_assert_ref(i);
618     pa_assert_se(u = i->userdata);
619     pa_assert(chunk);
620     pa_assert(u->sink);
621 
622     if (!PA_SINK_IS_LINKED(u->sink->thread_info.state))
623         return -1;
624 
625     /* FIXME: Please clean this up. I see more commented code lines
626      * than uncommented code lines. I am sorry, but I am too dumb to
627      * understand this. */
628 
629     fs = pa_frame_size(&(u->sink->sample_spec));
630     mbs = pa_mempool_block_size_max(u->sink->core->mempool);
631     if (pa_memblockq_get_length(u->output_q) > 0) {
632         //pa_log_debug("qsize is %ld", pa_memblockq_get_length(u->output_q));
633         goto END;
634     }
635     //nbytes = PA_MIN(nbytes, pa_mempool_block_size_max(u->sink->core->mempool));
636     target_samples = PA_ROUND_UP(nbytes / fs, u->R);
637     ////pa_log_debug("vanilla mbs = %ld",mbs);
638     //mbs = PA_ROUND_DOWN(mbs / fs, u->R);
639     //mbs = PA_MAX(mbs, u->R);
640     //target_samples = PA_MAX(target_samples, mbs);
641     //pa_log_debug("target samples: %ld", target_samples);
642     if (u->first_iteration) {
643         //allocate request_size
644         target_samples = PA_MAX(target_samples, u->window_size);
645     }else{
646         //allocate request_size + overlap
647         target_samples += u->overlap_size;
648     }
649     alloc_input_buffers(u, target_samples);
650     //pa_log_debug("post target samples: %ld", target_samples);
651     chunk->memblock = NULL;
652 
653     /* Hmm, process any rewind request that might be queued up */
654     pa_sink_process_rewind(u->sink, 0);
655 
656     //pa_log_debug("start output-buffered %ld, input-buffered %ld, requested %ld",buffered_samples,u->samples_gathered,samples_requested);
657     //pa_rtclock_get(&start);
658     do{
659         size_t input_remaining = target_samples - u->samples_gathered;
660        // pa_log_debug("input remaining %ld samples", input_remaining);
661         pa_assert(input_remaining > 0);
662         while (pa_memblockq_peek(u->input_q, &tchunk) < 0) {
663             //pa_sink_render(u->sink, input_remaining * fs, &tchunk);
664             pa_sink_render_full(u->sink, PA_MIN(input_remaining * fs, mbs), &tchunk);
665             pa_memblockq_push(u->input_q, &tchunk);
666             pa_memblock_unref(tchunk.memblock);
667         }
668         pa_assert(tchunk.memblock);
669 
670         tchunk.length = PA_MIN(input_remaining * fs, tchunk.length);
671 
672         pa_memblockq_drop(u->input_q, tchunk.length);
673         //pa_log_debug("asked for %ld input samples, got %ld samples",input_remaining,buffer->length/fs);
674         /* copy new input */
675         //pa_rtclock_get(start);
676        // pa_log_debug("buffering %ld bytes", tchunk.length);
677         input_buffer(u, &tchunk);
678         //pa_rtclock_get(&end);
679         //pa_log_debug("Took %0.5f seconds to setup", pa_timeval_diff(end, start) / (double) PA_USEC_PER_SEC);
680         pa_memblock_unref(tchunk.memblock);
681     } while(u->samples_gathered < target_samples);
682 
683     //pa_rtclock_get(&end);
684     //pa_log_debug("Took %0.6f seconds to get data", (double) pa_timeval_diff(&end, &start) / PA_USEC_PER_SEC);
685 
686     pa_assert(u->fft_size >= u->window_size);
687     pa_assert(u->R < u->window_size);
688     //pa_rtclock_get(&start);
689     /* process a block */
690     process_samples(u);
691     //pa_rtclock_get(&end);
692     //pa_log_debug("Took %0.6f seconds to process", (double) pa_timeval_diff(&end, &start) / PA_USEC_PER_SEC);
693 END:
694     pa_assert_se(pa_memblockq_peek(u->output_q, chunk) >= 0);
695     pa_assert(chunk->memblock);
696     pa_memblockq_drop(u->output_q, chunk->length);
697 
698     //pa_log_debug("gave %ld", chunk->length/fs);
699     //pa_log_debug("end pop");
700     return 0;
701 }
702 
703 /* Called from main context */
sink_input_volume_changed_cb(pa_sink_input *i)704 static void sink_input_volume_changed_cb(pa_sink_input *i) {
705     struct userdata *u;
706 
707     pa_sink_input_assert_ref(i);
708     pa_assert_se(u = i->userdata);
709 
710     pa_sink_volume_changed(u->sink, &i->volume);
711 }
712 
713 /* Called from main context */
sink_input_mute_changed_cb(pa_sink_input *i)714 static void sink_input_mute_changed_cb(pa_sink_input *i) {
715     struct userdata *u;
716 
717     pa_sink_input_assert_ref(i);
718     pa_assert_se(u = i->userdata);
719 
720     pa_sink_mute_changed(u->sink, i->muted);
721 }
722 
723 #if 0
724 static void reset_filter(struct userdata *u) {
725     size_t fs = pa_frame_size(&u->sink->sample_spec);
726     size_t max_request;
727 
728     u->samples_gathered = 0;
729 
730     for(size_t i = 0; i < u->channels; ++i)
731         pa_memzero(u->overlap_accum[i], u->overlap_size * sizeof(float));
732 
733     u->first_iteration = true;
734     //set buffer size to max request, no overlap copy
735     max_request = PA_ROUND_UP(pa_sink_input_get_max_request(u->sink_input) / fs , u->R);
736     max_request = PA_MAX(max_request, u->window_size);
737     pa_sink_set_max_request_within_thread(u->sink, max_request * fs);
738 }
739 #endif
740 
741 /* Called from I/O thread context */
sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes)742 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
743     struct userdata *u;
744     size_t amount = 0;
745 
746     pa_log_debug("Rewind callback!");
747     pa_sink_input_assert_ref(i);
748     pa_assert_se(u = i->userdata);
749 
750     /* If the sink is not yet linked, there is nothing to rewind */
751     if (!PA_SINK_IS_LINKED(u->sink->thread_info.state))
752         return;
753 
754     if (u->sink->thread_info.rewind_nbytes > 0) {
755         size_t max_rewrite;
756 
757         //max_rewrite = nbytes;
758         max_rewrite = nbytes + pa_memblockq_get_length(u->input_q);
759         //PA_MIN(pa_memblockq_get_length(u->input_q), nbytes);
760         amount = PA_MIN(u->sink->thread_info.rewind_nbytes, max_rewrite);
761         u->sink->thread_info.rewind_nbytes = 0;
762 
763         if (amount > 0) {
764             //invalidate the output q
765             pa_memblockq_seek(u->input_q, - (int64_t) amount, PA_SEEK_RELATIVE, true);
766             pa_log("Resetting filter");
767             //reset_filter(u); //this is the "proper" thing to do...
768         }
769     }
770 
771     pa_sink_process_rewind(u->sink, amount);
772     pa_memblockq_rewind(u->input_q, nbytes);
773 }
774 
775 /* Called from I/O thread context */
sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes)776 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
777     struct userdata *u;
778 
779     pa_sink_input_assert_ref(i);
780     pa_assert_se(u = i->userdata);
781 
782     /* FIXME: Too small max_rewind:
783      * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
784     pa_memblockq_set_maxrewind(u->input_q, nbytes);
785     pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
786 }
787 
788 /* Called from I/O thread context */
sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes)789 static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
790     struct userdata *u;
791     size_t fs;
792 
793     pa_sink_input_assert_ref(i);
794     pa_assert_se(u = i->userdata);
795 
796     fs = pa_frame_size(&u->sink_input->sample_spec);
797     pa_sink_set_max_request_within_thread(u->sink, PA_ROUND_UP(nbytes / fs, u->R) * fs);
798 }
799 
800 /* Called from I/O thread context */
sink_input_update_sink_latency_range_cb(pa_sink_input *i)801 static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) {
802     struct userdata *u;
803 
804     pa_sink_input_assert_ref(i);
805     pa_assert_se(u = i->userdata);
806 
807     pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
808 }
809 
810 /* Called from I/O thread context */
sink_input_update_sink_fixed_latency_cb(pa_sink_input *i)811 static void sink_input_update_sink_fixed_latency_cb(pa_sink_input *i) {
812     struct userdata *u;
813 
814     pa_sink_input_assert_ref(i);
815     pa_assert_se(u = i->userdata);
816 
817     pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
818 }
819 
820 /* Called from I/O thread context */
sink_input_detach_cb(pa_sink_input *i)821 static void sink_input_detach_cb(pa_sink_input *i) {
822     struct userdata *u;
823 
824     pa_sink_input_assert_ref(i);
825     pa_assert_se(u = i->userdata);
826 
827     if (PA_SINK_IS_LINKED(u->sink->thread_info.state))
828         pa_sink_detach_within_thread(u->sink);
829 
830     pa_sink_set_rtpoll(u->sink, NULL);
831 }
832 
833 /* Called from I/O thread context */
sink_input_attach_cb(pa_sink_input *i)834 static void sink_input_attach_cb(pa_sink_input *i) {
835     struct userdata *u;
836     size_t fs, max_request;
837 
838     pa_sink_input_assert_ref(i);
839     pa_assert_se(u = i->userdata);
840 
841     pa_sink_set_rtpoll(u->sink, i->sink->thread_info.rtpoll);
842     pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
843     pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
844 
845     fs = pa_frame_size(&u->sink_input->sample_spec);
846     /* set buffer size to max request, no overlap copy */
847     max_request = PA_ROUND_UP(pa_sink_input_get_max_request(u->sink_input) / fs, u->R);
848     max_request = PA_MAX(max_request, u->window_size);
849 
850     pa_sink_set_max_request_within_thread(u->sink, max_request * fs);
851 
852     /* FIXME: Too small max_rewind:
853      * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
854     pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
855 
856     if (PA_SINK_IS_LINKED(u->sink->thread_info.state))
857         pa_sink_attach_within_thread(u->sink);
858 }
859 
860 /* Called from main context */
sink_input_kill_cb(pa_sink_input *i)861 static void sink_input_kill_cb(pa_sink_input *i) {
862     struct userdata *u;
863 
864     pa_sink_input_assert_ref(i);
865     pa_assert_se(u = i->userdata);
866 
867     /* The order here matters! We first kill the sink so that streams
868      * can properly be moved away while the sink input is still connected
869      * to the master. */
870     pa_sink_input_cork(u->sink_input, true);
871     pa_sink_unlink(u->sink);
872     pa_sink_input_unlink(u->sink_input);
873 
874     pa_sink_input_unref(u->sink_input);
875     u->sink_input = NULL;
876 
877     /* Leave u->sink alone for now, it will be cleaned up on module
878      * unload (and it is needed during unload as well). */
879 
880     pa_module_unload_request(u->module, true);
881 }
882 
pack(char **strs, size_t len, char **packed, size_t *length)883 static void pack(char **strs, size_t len, char **packed, size_t *length) {
884     size_t t_len = 0;
885     size_t headers = (1+len) * sizeof(uint16_t);
886     char *p;
887     for(size_t i = 0; i < len; ++i) {
888         t_len += strlen(strs[i]);
889     }
890     *length = headers + t_len;
891     p = *packed = pa_xmalloc0(*length);
892     *((uint16_t *) p) = (uint16_t) len;
893     p += sizeof(uint16_t);
894     for(size_t i = 0; i < len; ++i) {
895         uint16_t l = strlen(strs[i]);
896         *((uint16_t *) p) = (uint16_t) l;
897         p += sizeof(uint16_t);
898         memcpy(p, strs[i], l);
899         p += l;
900     }
901 }
unpack(char *str, size_t length, char ***strs, size_t *len)902 static void unpack(char *str, size_t length, char ***strs, size_t *len) {
903     char *p = str;
904     *len = *((uint16_t *) p);
905     p += sizeof(uint16_t);
906     *strs = pa_xnew(char *, *len);
907 
908     for(size_t i = 0; i < *len; ++i) {
909         size_t l = *((uint16_t *) p);
910         p += sizeof(uint16_t);
911         (*strs)[i] = pa_xnew(char, l + 1);
912         memcpy((*strs)[i], p, l);
913         (*strs)[i][l] = '\0';
914         p += l;
915     }
916 }
save_profile(struct userdata *u, size_t channel, char *name)917 static void save_profile(struct userdata *u, size_t channel, char *name) {
918     unsigned a_i;
919     const size_t profile_size = CHANNEL_PROFILE_SIZE(u) * sizeof(float);
920     float *H_n, *profile;
921     const float *H;
922     pa_datum key, data;
923     profile = pa_xnew0(float, profile_size);
924     a_i = pa_aupdate_read_begin(u->a_H[channel]);
925     profile[0] = u->Xs[a_i][channel];
926     H = u->Hs[channel][a_i];
927     H_n = profile + 1;
928     for(size_t i = 0 ; i < FILTER_SIZE(u); ++i) {
929         H_n[i] = H[i] * u->fft_size;
930         //H_n[i] = H[i];
931     }
932     pa_aupdate_read_end(u->a_H[channel]);
933     key.data=name;
934     key.size = strlen(key.data);
935     data.data = profile;
936     data.size = profile_size;
937     pa_database_set(u->database, &key, &data, true);
938     pa_database_sync(u->database);
939     if (u->base_profiles[channel]) {
940         pa_xfree(u->base_profiles[channel]);
941     }
942     u->base_profiles[channel] = pa_xstrdup(name);
943 }
944 
save_state(struct userdata *u)945 static void save_state(struct userdata *u) {
946     unsigned a_i;
947     const size_t filter_state_size = FILTER_STATE_SIZE(u) * sizeof(float);
948     float *H_n, *state;
949     float *H;
950     pa_datum key, data;
951     pa_database *database;
952     char *state_path;
953     char *packed;
954     size_t packed_length;
955 
956     pack(u->base_profiles, u->channels, &packed, &packed_length);
957     state = (float *) pa_xmalloc0(filter_state_size + packed_length);
958     memcpy(state + FILTER_STATE_SIZE(u), packed, packed_length);
959     pa_xfree(packed);
960 
961     for(size_t c = 0; c < u->channels; ++c) {
962         a_i = pa_aupdate_read_begin(u->a_H[c]);
963         state[c * CHANNEL_PROFILE_SIZE(u)] = u->Xs[c][a_i];
964         H = u->Hs[c][a_i];
965         H_n = &state[c * CHANNEL_PROFILE_SIZE(u) + 1];
966         memcpy(H_n, H, FILTER_SIZE(u) * sizeof(float));
967         pa_aupdate_read_end(u->a_H[c]);
968     }
969 
970     key.data = u->sink->name;
971     key.size = strlen(key.data);
972     data.data = state;
973     data.size = filter_state_size + packed_length;
974     //thread safety for 0.9.17?
975     pa_assert_se(state_path = pa_state_path(NULL, false));
976     pa_assert_se(database = pa_database_open(state_path, EQ_STATE_DB, false, true));
977     pa_xfree(state_path);
978 
979     pa_database_set(database, &key, &data, true);
980     pa_database_sync(database);
981     pa_database_close(database);
982     pa_xfree(state);
983 }
984 
remove_profile(pa_core *c, char *name)985 static void remove_profile(pa_core *c, char *name) {
986     pa_datum key;
987     pa_database *database;
988     key.data = name;
989     key.size = strlen(key.data);
990     pa_assert_se(database = pa_shared_get(c, EQDB));
991     pa_database_unset(database, &key);
992     pa_database_sync(database);
993 }
994 
load_profile(struct userdata *u, size_t channel, char *name)995 static const char* load_profile(struct userdata *u, size_t channel, char *name) {
996     unsigned a_i;
997     pa_datum key, value;
998     const size_t profile_size = CHANNEL_PROFILE_SIZE(u) * sizeof(float);
999     key.data = name;
1000     key.size = strlen(key.data);
1001     if (pa_database_get(u->database, &key, &value) != NULL) {
1002         if (value.size == profile_size) {
1003             float *profile = (float *) value.data;
1004             a_i = pa_aupdate_write_begin(u->a_H[channel]);
1005             u->Xs[channel][a_i] = profile[0];
1006             memcpy(u->Hs[channel][a_i], profile + 1, FILTER_SIZE(u) * sizeof(float));
1007             fix_filter(u->Hs[channel][a_i], u->fft_size);
1008             pa_aupdate_write_end(u->a_H[channel]);
1009             pa_xfree(u->base_profiles[channel]);
1010             u->base_profiles[channel] = pa_xstrdup(name);
1011         }else{
1012             return "incompatible size";
1013         }
1014         pa_datum_free(&value);
1015     }else{
1016         return "profile doesn't exist";
1017     }
1018     return NULL;
1019 }
1020 
load_state(struct userdata *u)1021 static void load_state(struct userdata *u) {
1022     unsigned a_i;
1023     float *H;
1024     pa_datum key, value;
1025     pa_database *database;
1026     char *state_path;
1027     pa_assert_se(state_path = pa_state_path(NULL, false));
1028     database = pa_database_open(state_path, EQ_STATE_DB, false, false);
1029     pa_xfree(state_path);
1030     if (!database) {
1031         pa_log("No resume state");
1032         return;
1033     }
1034 
1035     key.data = u->sink->name;
1036     key.size = strlen(key.data);
1037 
1038     if (pa_database_get(database, &key, &value) != NULL) {
1039         if (value.size > FILTER_STATE_SIZE(u) * sizeof(float) + sizeof(uint16_t)) {
1040             float *state = (float *) value.data;
1041             size_t n_profs;
1042             char **names;
1043             for(size_t c = 0; c < u->channels; ++c) {
1044                 a_i = pa_aupdate_write_begin(u->a_H[c]);
1045                 H = state + c * CHANNEL_PROFILE_SIZE(u) + 1;
1046                 u->Xs[c][a_i] = state[c * CHANNEL_PROFILE_SIZE(u)];
1047                 memcpy(u->Hs[c][a_i], H, FILTER_SIZE(u) * sizeof(float));
1048                 pa_aupdate_write_end(u->a_H[c]);
1049             }
1050             unpack(((char *)value.data) + FILTER_STATE_SIZE(u) * sizeof(float), value.size - FILTER_STATE_SIZE(u) * sizeof(float), &names, &n_profs);
1051             n_profs = PA_MIN(n_profs, u->channels);
1052             for(size_t c = 0; c < n_profs; ++c) {
1053                 pa_xfree(u->base_profiles[c]);
1054                 u->base_profiles[c] = names[c];
1055             }
1056             pa_xfree(names);
1057         }
1058         pa_datum_free(&value);
1059     }else{
1060         pa_log("resume state exists but is wrong size!");
1061     }
1062     pa_database_close(database);
1063 }
1064 
1065 /* Called from main context */
sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest)1066 static bool sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
1067     struct userdata *u;
1068 
1069     pa_sink_input_assert_ref(i);
1070     pa_assert_se(u = i->userdata);
1071 
1072     return u->sink != dest;
1073 }
1074 
1075 /* Called from main context */
sink_input_moving_cb(pa_sink_input *i, pa_sink *dest)1076 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
1077     struct userdata *u;
1078 
1079     pa_sink_input_assert_ref(i);
1080     pa_assert_se(u = i->userdata);
1081 
1082     if (u->autoloaded) {
1083         /* We were autoloaded, and don't support moving. Let's unload ourselves. */
1084         pa_log_debug("Can't move autoloaded stream, unloading");
1085         pa_module_unload_request(u->module, true);
1086     }
1087 
1088     if (dest) {
1089         pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
1090         pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
1091 
1092         if (u->automatic_description) {
1093             const char *master_description;
1094             char *new_description;
1095 
1096             master_description = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
1097             new_description = pa_sprintf_malloc(_("FFT based equalizer on %s"),
1098                                                 master_description ? master_description : dest->name);
1099             pa_sink_set_description(u->sink, new_description);
1100             pa_xfree(new_description);
1101         }
1102     } else
1103         pa_sink_set_asyncmsgq(u->sink, NULL);
1104 }
1105 
pa__init(pa_module*m)1106 int pa__init(pa_module*m) {
1107     struct userdata *u;
1108     pa_sample_spec ss;
1109     pa_channel_map map;
1110     pa_modargs *ma;
1111     pa_sink *master;
1112     pa_sink_input_new_data sink_input_data;
1113     pa_sink_new_data sink_data;
1114     size_t i;
1115     unsigned c;
1116     float *H;
1117     unsigned a_i;
1118     bool use_volume_sharing = true;
1119 
1120     pa_assert(m);
1121 
1122     pa_log_warn("module-equalizer-sink is currently unsupported, and can sometimes cause "
1123                 "PulseAudio crashes, increased latency or audible artifacts.");
1124     pa_log_warn("If you're facing audio problems, try unloading this module as a potential workaround.");
1125 
1126     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
1127         pa_log("Failed to parse module arguments.");
1128         goto fail;
1129     }
1130 
1131     if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "sink_master", NULL), PA_NAMEREG_SINK))) {
1132         pa_log("Master sink not found");
1133         goto fail;
1134     }
1135 
1136     ss = master->sample_spec;
1137     ss.format = PA_SAMPLE_FLOAT32;
1138     map = master->channel_map;
1139     if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
1140         pa_log("Invalid sample format specification or channel map");
1141         goto fail;
1142     }
1143 
1144     //fs = pa_frame_size(&ss);
1145 
1146     if (pa_modargs_get_value_boolean(ma, "use_volume_sharing", &use_volume_sharing) < 0) {
1147         pa_log("use_volume_sharing= expects a boolean argument");
1148         goto fail;
1149     }
1150 
1151     u = pa_xnew0(struct userdata, 1);
1152     u->module = m;
1153     m->userdata = u;
1154 
1155     u->channels = ss.channels;
1156     u->fft_size = pow(2, ceil(log(ss.rate) / log(2)));//probably unstable near corner cases of powers of 2
1157     pa_log_debug("fft size: %zd", u->fft_size);
1158     u->window_size = 15999;
1159     if (u->window_size % 2 == 0)
1160         u->window_size--;
1161     u->R = (u->window_size + 1) / 2;
1162     u->overlap_size = u->window_size - u->R;
1163     u->samples_gathered = 0;
1164     u->input_buffer_max = 0;
1165 
1166     u->a_H = pa_xnew0(pa_aupdate *, u->channels);
1167     u->Xs = pa_xnew0(float *, u->channels);
1168     u->Hs = pa_xnew0(float **, u->channels);
1169 
1170     for (c = 0; c < u->channels; ++c) {
1171         u->Xs[c] = pa_xnew0(float, 2);
1172         u->Hs[c] = pa_xnew0(float *, 2);
1173         for (i = 0; i < 2; ++i)
1174             u->Hs[c][i] = alloc(FILTER_SIZE(u), sizeof(float));
1175     }
1176 
1177     u->W = alloc(u->window_size, sizeof(float));
1178     u->work_buffer = alloc(u->fft_size, sizeof(float));
1179     u->input = pa_xnew0(float *, u->channels);
1180     u->overlap_accum = pa_xnew0(float *, u->channels);
1181     for (c = 0; c < u->channels; ++c) {
1182         u->a_H[c] = pa_aupdate_new();
1183         u->input[c] = NULL;
1184         u->overlap_accum[c] = alloc(u->overlap_size, sizeof(float));
1185     }
1186     u->output_window = alloc(FILTER_SIZE(u), sizeof(fftwf_complex));
1187     u->forward_plan = fftwf_plan_dft_r2c_1d(u->fft_size, u->work_buffer, u->output_window, FFTW_ESTIMATE);
1188     u->inverse_plan = fftwf_plan_dft_c2r_1d(u->fft_size, u->output_window, u->work_buffer, FFTW_ESTIMATE);
1189 
1190     hanning_window(u->W, u->window_size);
1191     u->first_iteration = true;
1192 
1193     u->base_profiles = pa_xnew0(char *, u->channels);
1194     for (c = 0; c < u->channels; ++c)
1195         u->base_profiles[c] = pa_xstrdup("default");
1196 
1197     /* Create sink */
1198     pa_sink_new_data_init(&sink_data);
1199     sink_data.driver = __FILE__;
1200     sink_data.module = m;
1201     if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
1202         sink_data.name = pa_sprintf_malloc("%s.equalizer", master->name);
1203     pa_sink_new_data_set_sample_spec(&sink_data, &ss);
1204     pa_sink_new_data_set_channel_map(&sink_data, &map);
1205 
1206     pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
1207     pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
1208 
1209     if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
1210         pa_log("Invalid properties");
1211         pa_sink_new_data_done(&sink_data);
1212         goto fail;
1213     }
1214 
1215     if (!pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION)) {
1216         const char *master_description;
1217 
1218         master_description = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
1219         pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION,
1220                          _("FFT based equalizer on %s"), master_description ? master_description : master->name);
1221         u->automatic_description = true;
1222     }
1223 
1224     u->autoloaded = DEFAULT_AUTOLOADED;
1225     if (pa_modargs_get_value_boolean(ma, "autoloaded", &u->autoloaded) < 0) {
1226         pa_log("Failed to parse autoloaded value");
1227         goto fail;
1228     }
1229 
1230     u->sink = pa_sink_new(m->core, &sink_data, (master->flags & (PA_SINK_LATENCY | PA_SINK_DYNAMIC_LATENCY))
1231                                                | (use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0));
1232     pa_sink_new_data_done(&sink_data);
1233 
1234     if (!u->sink) {
1235         pa_log("Failed to create sink.");
1236         goto fail;
1237     }
1238 
1239     u->sink->parent.process_msg = sink_process_msg_cb;
1240     u->sink->set_state_in_main_thread = sink_set_state_in_main_thread_cb;
1241     u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
1242     u->sink->update_requested_latency = sink_update_requested_latency_cb;
1243     u->sink->request_rewind = sink_request_rewind_cb;
1244     pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
1245     if (!use_volume_sharing) {
1246         pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
1247         pa_sink_enable_decibel_volume(u->sink, true);
1248     }
1249     u->sink->userdata = u;
1250 
1251     u->input_q = pa_memblockq_new("module-equalizer-sink input_q", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, &u->sink->silence);
1252     u->output_q = pa_memblockq_new("module-equalizer-sink output_q", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, NULL);
1253     u->output_buffer = NULL;
1254     u->output_buffer_length = 0;
1255     u->output_buffer_max_length = 0;
1256 
1257     pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
1258     //pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->R*fs, &ss));
1259 
1260     /* Create sink input */
1261     pa_sink_input_new_data_init(&sink_input_data);
1262     sink_input_data.driver = __FILE__;
1263     sink_input_data.module = m;
1264     pa_sink_input_new_data_set_sink(&sink_input_data, master, false, true);
1265     sink_input_data.origin_sink = u->sink;
1266     pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Equalized Stream");
1267     pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
1268     pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
1269     pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
1270     sink_input_data.flags |= PA_SINK_INPUT_START_CORKED;
1271 
1272     pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
1273     pa_sink_input_new_data_done(&sink_input_data);
1274 
1275     if (!u->sink_input)
1276         goto fail;
1277 
1278     u->sink_input->pop = sink_input_pop_cb;
1279     u->sink_input->process_rewind = sink_input_process_rewind_cb;
1280     u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
1281     u->sink_input->update_max_request = sink_input_update_max_request_cb;
1282     u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
1283     u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
1284     u->sink_input->kill = sink_input_kill_cb;
1285     u->sink_input->attach = sink_input_attach_cb;
1286     u->sink_input->detach = sink_input_detach_cb;
1287     u->sink_input->may_move_to = sink_input_may_move_to_cb;
1288     u->sink_input->moving = sink_input_moving_cb;
1289     if (!use_volume_sharing)
1290         u->sink_input->volume_changed = sink_input_volume_changed_cb;
1291     u->sink_input->mute_changed = sink_input_mute_changed_cb;
1292     u->sink_input->userdata = u;
1293 
1294     u->sink->input_to_master = u->sink_input;
1295 
1296     dbus_init(u);
1297 
1298     /* default filter to these */
1299     for (c = 0; c< u->channels; ++c) {
1300         a_i = pa_aupdate_write_begin(u->a_H[c]);
1301         H = u->Hs[c][a_i];
1302         u->Xs[c][a_i] = 1.0f;
1303 
1304         for(i = 0; i < FILTER_SIZE(u); ++i)
1305             H[i] = 1.0 / sqrtf(2.0f);
1306 
1307         fix_filter(H, u->fft_size);
1308         pa_aupdate_write_end(u->a_H[c]);
1309     }
1310 
1311     /* load old parameters */
1312     load_state(u);
1313 
1314     /* The order here is important. The input must be put first,
1315      * otherwise streams might attach to the sink before the sink
1316      * input is attached to the master. */
1317     pa_sink_input_put(u->sink_input);
1318     pa_sink_put(u->sink);
1319     pa_sink_input_cork(u->sink_input, false);
1320 
1321     pa_modargs_free(ma);
1322 
1323     return 0;
1324 
1325 fail:
1326     if (ma)
1327         pa_modargs_free(ma);
1328 
1329     pa__done(m);
1330 
1331     return -1;
1332 }
1333 
pa__get_n_used(pa_module *m)1334 int pa__get_n_used(pa_module *m) {
1335     struct userdata *u;
1336 
1337     pa_assert(m);
1338     pa_assert_se(u = m->userdata);
1339 
1340     return pa_sink_linked_by(u->sink);
1341 }
1342 
pa__done(pa_module*m)1343 void pa__done(pa_module*m) {
1344     struct userdata *u;
1345     unsigned c;
1346 
1347     pa_assert(m);
1348 
1349     if (!(u = m->userdata))
1350         return;
1351 
1352     save_state(u);
1353 
1354     dbus_done(u);
1355 
1356     for(c = 0; c < u->channels; ++c)
1357         pa_xfree(u->base_profiles[c]);
1358     pa_xfree(u->base_profiles);
1359 
1360     /* See comments in sink_input_kill_cb() above regarding
1361      * destruction order! */
1362 
1363     if (u->sink_input)
1364         pa_sink_input_cork(u->sink_input, true);
1365 
1366     if (u->sink)
1367         pa_sink_unlink(u->sink);
1368 
1369     if (u->sink_input) {
1370         pa_sink_input_unlink(u->sink_input);
1371         pa_sink_input_unref(u->sink_input);
1372 }
1373 
1374     if (u->sink)
1375         pa_sink_unref(u->sink);
1376 
1377     pa_xfree(u->output_buffer);
1378     pa_memblockq_free(u->output_q);
1379     pa_memblockq_free(u->input_q);
1380 
1381     fftwf_destroy_plan(u->inverse_plan);
1382     fftwf_destroy_plan(u->forward_plan);
1383     fftwf_free(u->output_window);
1384     for (c = 0; c < u->channels; ++c) {
1385         pa_aupdate_free(u->a_H[c]);
1386         fftwf_free(u->overlap_accum[c]);
1387         fftwf_free(u->input[c]);
1388     }
1389     pa_xfree(u->a_H);
1390     pa_xfree(u->overlap_accum);
1391     pa_xfree(u->input);
1392     fftwf_free(u->work_buffer);
1393     fftwf_free(u->W);
1394     for (c = 0; c < u->channels; ++c) {
1395         pa_xfree(u->Xs[c]);
1396         for (size_t i = 0; i < 2; ++i)
1397             fftwf_free(u->Hs[c][i]);
1398         fftwf_free(u->Hs[c]);
1399     }
1400     pa_xfree(u->Xs);
1401     pa_xfree(u->Hs);
1402 
1403     pa_xfree(u);
1404 }
1405 
1406 /*
1407  * DBus Routines and Callbacks
1408  */
1409 #define EXTNAME "org.PulseAudio.Ext.Equalizing1"
1410 #define MANAGER_PATH "/org/pulseaudio/equalizing1"
1411 #define MANAGER_IFACE EXTNAME ".Manager"
1412 #define EQUALIZER_IFACE EXTNAME ".Equalizer"
1413 static void manager_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u);
1414 static void manager_get_sinks(DBusConnection *conn, DBusMessage *msg, void *_u);
1415 static void manager_get_profiles(DBusConnection *conn, DBusMessage *msg, void *_u);
1416 static void manager_get_all(DBusConnection *conn, DBusMessage *msg, void *_u);
1417 static void manager_handle_remove_profile(DBusConnection *conn, DBusMessage *msg, void *_u);
1418 static void equalizer_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u);
1419 static void equalizer_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *_u);
1420 static void equalizer_get_filter_rate(DBusConnection *conn, DBusMessage *msg, void *_u);
1421 static void equalizer_get_n_coefs(DBusConnection *conn, DBusMessage *msg, void *_u);
1422 static void equalizer_get_n_channels(DBusConnection *conn, DBusMessage *msg, void *_u);
1423 static void equalizer_get_all(DBusConnection *conn, DBusMessage *msg, void *_u);
1424 static void equalizer_handle_seed_filter(DBusConnection *conn, DBusMessage *msg, void *_u);
1425 static void equalizer_handle_get_filter_points(DBusConnection *conn, DBusMessage *msg, void *_u);
1426 static void equalizer_handle_get_filter(DBusConnection *conn, DBusMessage *msg, void *_u);
1427 static void equalizer_handle_set_filter(DBusConnection *conn, DBusMessage *msg, void *_u);
1428 static void equalizer_handle_save_profile(DBusConnection *conn, DBusMessage *msg, void *_u);
1429 static void equalizer_handle_load_profile(DBusConnection *conn, DBusMessage *msg, void *_u);
1430 static void equalizer_handle_save_state(DBusConnection *conn, DBusMessage *msg, void *_u);
1431 static void equalizer_handle_get_profile_name(DBusConnection *conn, DBusMessage *msg, void *_u);
1432 enum manager_method_index {
1433     MANAGER_METHOD_REMOVE_PROFILE,
1434     MANAGER_METHOD_MAX
1435 };
1436 
1437 pa_dbus_arg_info remove_profile_args[]={
1438     {"name", "s","in"},
1439 };
1440 
1441 static pa_dbus_method_handler manager_methods[MANAGER_METHOD_MAX]={
1442     [MANAGER_METHOD_REMOVE_PROFILE]={
1443         .method_name="RemoveProfile",
1444         .arguments=remove_profile_args,
1445         .n_arguments=sizeof(remove_profile_args)/sizeof(pa_dbus_arg_info),
1446         .receive_cb=manager_handle_remove_profile}
1447 };
1448 
1449 enum manager_handler_index {
1450     MANAGER_HANDLER_REVISION,
1451     MANAGER_HANDLER_EQUALIZED_SINKS,
1452     MANAGER_HANDLER_PROFILES,
1453     MANAGER_HANDLER_MAX
1454 };
1455 
1456 static pa_dbus_property_handler manager_handlers[MANAGER_HANDLER_MAX]={
1457     [MANAGER_HANDLER_REVISION]={.property_name="InterfaceRevision",.type="u",.get_cb=manager_get_revision,.set_cb=NULL},
1458     [MANAGER_HANDLER_EQUALIZED_SINKS]={.property_name="EqualizedSinks",.type="ao",.get_cb=manager_get_sinks,.set_cb=NULL},
1459     [MANAGER_HANDLER_PROFILES]={.property_name="Profiles",.type="as",.get_cb=manager_get_profiles,.set_cb=NULL}
1460 };
1461 
1462 pa_dbus_arg_info sink_args[]={
1463     {"sink", "o", NULL}
1464 };
1465 
1466 enum manager_signal_index{
1467     MANAGER_SIGNAL_SINK_ADDED,
1468     MANAGER_SIGNAL_SINK_REMOVED,
1469     MANAGER_SIGNAL_PROFILES_CHANGED,
1470     MANAGER_SIGNAL_MAX
1471 };
1472 
1473 static pa_dbus_signal_info manager_signals[MANAGER_SIGNAL_MAX]={
1474     [MANAGER_SIGNAL_SINK_ADDED]={.name="SinkAdded", .arguments=sink_args, .n_arguments=sizeof(sink_args)/sizeof(pa_dbus_arg_info)},
1475     [MANAGER_SIGNAL_SINK_REMOVED]={.name="SinkRemoved", .arguments=sink_args, .n_arguments=sizeof(sink_args)/sizeof(pa_dbus_arg_info)},
1476     [MANAGER_SIGNAL_PROFILES_CHANGED]={.name="ProfilesChanged", .arguments=NULL, .n_arguments=0}
1477 };
1478 
1479 static pa_dbus_interface_info manager_info={
1480     .name=MANAGER_IFACE,
1481     .method_handlers=manager_methods,
1482     .n_method_handlers=MANAGER_METHOD_MAX,
1483     .property_handlers=manager_handlers,
1484     .n_property_handlers=MANAGER_HANDLER_MAX,
1485     .get_all_properties_cb=manager_get_all,
1486     .signals=manager_signals,
1487     .n_signals=MANAGER_SIGNAL_MAX
1488 };
1489 
1490 enum equalizer_method_index {
1491     EQUALIZER_METHOD_FILTER_POINTS,
1492     EQUALIZER_METHOD_SEED_FILTER,
1493     EQUALIZER_METHOD_SAVE_PROFILE,
1494     EQUALIZER_METHOD_LOAD_PROFILE,
1495     EQUALIZER_METHOD_SET_FILTER,
1496     EQUALIZER_METHOD_GET_FILTER,
1497     EQUALIZER_METHOD_SAVE_STATE,
1498     EQUALIZER_METHOD_GET_PROFILE_NAME,
1499     EQUALIZER_METHOD_MAX
1500 };
1501 
1502 enum equalizer_handler_index {
1503     EQUALIZER_HANDLER_REVISION,
1504     EQUALIZER_HANDLER_SAMPLERATE,
1505     EQUALIZER_HANDLER_FILTERSAMPLERATE,
1506     EQUALIZER_HANDLER_N_COEFS,
1507     EQUALIZER_HANDLER_N_CHANNELS,
1508     EQUALIZER_HANDLER_MAX
1509 };
1510 
1511 pa_dbus_arg_info filter_points_args[]={
1512     {"channel", "u","in"},
1513     {"xs", "au","in"},
1514     {"ys", "ad","out"},
1515     {"preamp", "d","out"}
1516 };
1517 pa_dbus_arg_info seed_filter_args[]={
1518     {"channel", "u","in"},
1519     {"xs", "au","in"},
1520     {"ys", "ad","in"},
1521     {"preamp", "d","in"}
1522 };
1523 
1524 pa_dbus_arg_info set_filter_args[]={
1525     {"channel", "u","in"},
1526     {"ys", "ad","in"},
1527     {"preamp", "d","in"}
1528 };
1529 pa_dbus_arg_info get_filter_args[]={
1530     {"channel", "u","in"},
1531     {"ys", "ad","out"},
1532     {"preamp", "d","out"}
1533 };
1534 
1535 pa_dbus_arg_info save_profile_args[]={
1536     {"channel", "u","in"},
1537     {"name", "s","in"}
1538 };
1539 pa_dbus_arg_info load_profile_args[]={
1540     {"channel", "u","in"},
1541     {"name", "s","in"}
1542 };
1543 pa_dbus_arg_info base_profile_name_args[]={
1544     {"channel", "u","in"},
1545     {"name", "s","out"}
1546 };
1547 
1548 static pa_dbus_method_handler equalizer_methods[EQUALIZER_METHOD_MAX]={
1549     [EQUALIZER_METHOD_SEED_FILTER]={
1550         .method_name="SeedFilter",
1551         .arguments=seed_filter_args,
1552         .n_arguments=sizeof(seed_filter_args)/sizeof(pa_dbus_arg_info),
1553         .receive_cb=equalizer_handle_seed_filter},
1554     [EQUALIZER_METHOD_FILTER_POINTS]={
1555         .method_name="FilterAtPoints",
1556         .arguments=filter_points_args,
1557         .n_arguments=sizeof(filter_points_args)/sizeof(pa_dbus_arg_info),
1558         .receive_cb=equalizer_handle_get_filter_points},
1559     [EQUALIZER_METHOD_SET_FILTER]={
1560         .method_name="SetFilter",
1561         .arguments=set_filter_args,
1562         .n_arguments=sizeof(set_filter_args)/sizeof(pa_dbus_arg_info),
1563         .receive_cb=equalizer_handle_set_filter},
1564     [EQUALIZER_METHOD_GET_FILTER]={
1565         .method_name="GetFilter",
1566         .arguments=get_filter_args,
1567         .n_arguments=sizeof(get_filter_args)/sizeof(pa_dbus_arg_info),
1568         .receive_cb=equalizer_handle_get_filter},
1569     [EQUALIZER_METHOD_SAVE_PROFILE]={
1570         .method_name="SaveProfile",
1571         .arguments=save_profile_args,
1572         .n_arguments=sizeof(save_profile_args)/sizeof(pa_dbus_arg_info),
1573         .receive_cb=equalizer_handle_save_profile},
1574     [EQUALIZER_METHOD_LOAD_PROFILE]={
1575         .method_name="LoadProfile",
1576         .arguments=load_profile_args,
1577         .n_arguments=sizeof(load_profile_args)/sizeof(pa_dbus_arg_info),
1578         .receive_cb=equalizer_handle_load_profile},
1579     [EQUALIZER_METHOD_SAVE_STATE]={
1580         .method_name="SaveState",
1581         .arguments=NULL,
1582         .n_arguments=0,
1583         .receive_cb=equalizer_handle_save_state},
1584     [EQUALIZER_METHOD_GET_PROFILE_NAME]={
1585         .method_name="BaseProfile",
1586         .arguments=base_profile_name_args,
1587         .n_arguments=sizeof(base_profile_name_args)/sizeof(pa_dbus_arg_info),
1588         .receive_cb=equalizer_handle_get_profile_name}
1589 };
1590 
1591 static pa_dbus_property_handler equalizer_handlers[EQUALIZER_HANDLER_MAX]={
1592     [EQUALIZER_HANDLER_REVISION]={.property_name="InterfaceRevision",.type="u",.get_cb=equalizer_get_revision,.set_cb=NULL},
1593     [EQUALIZER_HANDLER_SAMPLERATE]={.property_name="SampleRate",.type="u",.get_cb=equalizer_get_sample_rate,.set_cb=NULL},
1594     [EQUALIZER_HANDLER_FILTERSAMPLERATE]={.property_name="FilterSampleRate",.type="u",.get_cb=equalizer_get_filter_rate,.set_cb=NULL},
1595     [EQUALIZER_HANDLER_N_COEFS]={.property_name="NFilterCoefficients",.type="u",.get_cb=equalizer_get_n_coefs,.set_cb=NULL},
1596     [EQUALIZER_HANDLER_N_CHANNELS]={.property_name="NChannels",.type="u",.get_cb=equalizer_get_n_channels,.set_cb=NULL},
1597 };
1598 
1599 enum equalizer_signal_index{
1600     EQUALIZER_SIGNAL_FILTER_CHANGED,
1601     EQUALIZER_SIGNAL_SINK_RECONFIGURED,
1602     EQUALIZER_SIGNAL_MAX
1603 };
1604 
1605 static pa_dbus_signal_info equalizer_signals[EQUALIZER_SIGNAL_MAX]={
1606     [EQUALIZER_SIGNAL_FILTER_CHANGED]={.name="FilterChanged", .arguments=NULL, .n_arguments=0},
1607     [EQUALIZER_SIGNAL_SINK_RECONFIGURED]={.name="SinkReconfigured", .arguments=NULL, .n_arguments=0},
1608 };
1609 
1610 static pa_dbus_interface_info equalizer_info={
1611     .name=EQUALIZER_IFACE,
1612     .method_handlers=equalizer_methods,
1613     .n_method_handlers=EQUALIZER_METHOD_MAX,
1614     .property_handlers=equalizer_handlers,
1615     .n_property_handlers=EQUALIZER_HANDLER_MAX,
1616     .get_all_properties_cb=equalizer_get_all,
1617     .signals=equalizer_signals,
1618     .n_signals=EQUALIZER_SIGNAL_MAX
1619 };
1620 
dbus_init(struct userdata *u)1621 void dbus_init(struct userdata *u) {
1622     uint32_t dummy;
1623     DBusMessage *message = NULL;
1624     pa_idxset *sink_list = NULL;
1625     u->dbus_protocol=pa_dbus_protocol_get(u->sink->core);
1626     u->dbus_path=pa_sprintf_malloc("/org/pulseaudio/core1/sink%d", u->sink->index);
1627 
1628     pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, u->dbus_path, &equalizer_info, u) >= 0);
1629     sink_list = pa_shared_get(u->sink->core, SINKLIST);
1630     u->database = pa_shared_get(u->sink->core, EQDB);
1631     if (sink_list == NULL) {
1632         char *state_path;
1633         sink_list=pa_idxset_new(&pa_idxset_trivial_hash_func, &pa_idxset_trivial_compare_func);
1634         pa_shared_set(u->sink->core, SINKLIST, sink_list);
1635         pa_assert_se(state_path = pa_state_path(NULL, false));
1636         pa_assert_se(u->database = pa_database_open(state_path, "equalizer-presets", false, true));
1637         pa_xfree(state_path);
1638         pa_shared_set(u->sink->core, EQDB, u->database);
1639         pa_dbus_protocol_add_interface(u->dbus_protocol, MANAGER_PATH, &manager_info, u->sink->core);
1640         pa_dbus_protocol_register_extension(u->dbus_protocol, EXTNAME);
1641     }
1642     pa_idxset_put(sink_list, u, &dummy);
1643 
1644     pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_SINK_ADDED].name)));
1645     dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &u->dbus_path, DBUS_TYPE_INVALID);
1646     pa_dbus_protocol_send_signal(u->dbus_protocol, message);
1647     dbus_message_unref(message);
1648 }
1649 
dbus_done(struct userdata *u)1650 void dbus_done(struct userdata *u) {
1651     pa_idxset *sink_list;
1652     uint32_t dummy;
1653 
1654     DBusMessage *message = NULL;
1655     pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_SINK_REMOVED].name)));
1656     dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &u->dbus_path, DBUS_TYPE_INVALID);
1657     pa_dbus_protocol_send_signal(u->dbus_protocol, message);
1658     dbus_message_unref(message);
1659 
1660     pa_assert_se(sink_list=pa_shared_get(u->sink->core,SINKLIST));
1661     pa_idxset_remove_by_data(sink_list,u,&dummy);
1662     if (pa_idxset_size(sink_list) == 0) {
1663         pa_dbus_protocol_unregister_extension(u->dbus_protocol, EXTNAME);
1664         pa_dbus_protocol_remove_interface(u->dbus_protocol, MANAGER_PATH, manager_info.name);
1665         pa_shared_remove(u->sink->core, EQDB);
1666         pa_database_close(u->database);
1667         pa_shared_remove(u->sink->core, SINKLIST);
1668         pa_xfree(sink_list);
1669     }
1670     pa_dbus_protocol_remove_interface(u->dbus_protocol, u->dbus_path, equalizer_info.name);
1671     pa_xfree(u->dbus_path);
1672     pa_dbus_protocol_unref(u->dbus_protocol);
1673 }
1674 
manager_handle_remove_profile(DBusConnection *conn, DBusMessage *msg, void *_u)1675 void manager_handle_remove_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
1676     DBusError error;
1677     pa_core *c = (pa_core *)_u;
1678     DBusMessage *message = NULL;
1679     pa_dbus_protocol *dbus_protocol;
1680     char *name;
1681     pa_assert(conn);
1682     pa_assert(msg);
1683     pa_assert(c);
1684     dbus_error_init(&error);
1685     if (!dbus_message_get_args(msg, &error,
1686                  DBUS_TYPE_STRING, &name,
1687                 DBUS_TYPE_INVALID)) {
1688         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
1689         dbus_error_free(&error);
1690         return;
1691     }
1692     remove_profile(c,name);
1693     pa_dbus_send_empty_reply(conn, msg);
1694 
1695     pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_PROFILES_CHANGED].name)));
1696     dbus_protocol = pa_dbus_protocol_get(c);
1697     pa_dbus_protocol_send_signal(dbus_protocol, message);
1698     pa_dbus_protocol_unref(dbus_protocol);
1699     dbus_message_unref(message);
1700 }
1701 
manager_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u)1702 void manager_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u) {
1703     uint32_t rev=1;
1704     pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &rev);
1705 }
1706 
get_sinks(pa_core *u, char ***names, unsigned *n_sinks)1707 static void get_sinks(pa_core *u, char ***names, unsigned *n_sinks) {
1708     void *iter = NULL;
1709     struct userdata *sink_u = NULL;
1710     uint32_t dummy;
1711     pa_idxset *sink_list;
1712     pa_assert(u);
1713     pa_assert(names);
1714     pa_assert(n_sinks);
1715 
1716     pa_assert_se(sink_list = pa_shared_get(u, SINKLIST));
1717     *n_sinks = (unsigned) pa_idxset_size(sink_list);
1718     *names = *n_sinks > 0 ? pa_xnew0(char *,*n_sinks) : NULL;
1719     for(uint32_t i = 0; i < *n_sinks; ++i) {
1720         sink_u = (struct userdata *) pa_idxset_iterate(sink_list, &iter, &dummy);
1721         (*names)[i] = pa_xstrdup(sink_u->dbus_path);
1722     }
1723 }
1724 
manager_get_sinks(DBusConnection *conn, DBusMessage *msg, void *_u)1725 void manager_get_sinks(DBusConnection *conn, DBusMessage *msg, void *_u) {
1726     unsigned n;
1727     char **names = NULL;
1728     pa_assert(conn);
1729     pa_assert(msg);
1730     pa_assert(_u);
1731 
1732     get_sinks((pa_core *) _u, &names, &n);
1733     pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, names, n);
1734     for(unsigned i = 0; i < n; ++i) {
1735         pa_xfree(names[i]);
1736     }
1737     pa_xfree(names);
1738 }
1739 
get_profiles(pa_core *c, char ***names, unsigned *n)1740 static void get_profiles(pa_core *c, char ***names, unsigned *n) {
1741     char *name;
1742     pa_database *database;
1743     pa_datum key, next_key;
1744     pa_strlist *head=NULL, *iter;
1745     bool done;
1746     pa_assert_se(database = pa_shared_get(c, EQDB));
1747 
1748     pa_assert(c);
1749     pa_assert(names);
1750     pa_assert(n);
1751     done = !pa_database_first(database, &key, NULL);
1752     *n = 0;
1753     while(!done) {
1754         done = !pa_database_next(database, &key, &next_key, NULL);
1755         name=pa_xmalloc(key.size + 1);
1756         memcpy(name, key.data, key.size);
1757         name[key.size] = '\0';
1758         pa_datum_free(&key);
1759         head = pa_strlist_prepend(head, name);
1760         pa_xfree(name);
1761         key = next_key;
1762         (*n)++;
1763     }
1764     (*names) = *n > 0 ? pa_xnew0(char *, *n) : NULL;
1765     iter=head;
1766     for(unsigned i = 0; i < *n; ++i) {
1767         (*names)[*n - 1 - i] = pa_xstrdup(pa_strlist_data(iter));
1768         iter = pa_strlist_next(iter);
1769     }
1770     pa_strlist_free(head);
1771 }
1772 
manager_get_profiles(DBusConnection *conn, DBusMessage *msg, void *_u)1773 void manager_get_profiles(DBusConnection *conn, DBusMessage *msg, void *_u) {
1774     char **names;
1775     unsigned n;
1776     pa_assert(conn);
1777     pa_assert(msg);
1778     pa_assert(_u);
1779 
1780     get_profiles((pa_core *)_u, &names, &n);
1781     pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_STRING, names, n);
1782     for(unsigned i = 0; i < n; ++i) {
1783         pa_xfree(names[i]);
1784     }
1785     pa_xfree(names);
1786 }
1787 
manager_get_all(DBusConnection *conn, DBusMessage *msg, void *_u)1788 void manager_get_all(DBusConnection *conn, DBusMessage *msg, void *_u) {
1789     pa_core *c;
1790     char **names = NULL;
1791     unsigned n;
1792     DBusMessage *reply = NULL;
1793     DBusMessageIter msg_iter, dict_iter;
1794     uint32_t rev;
1795     pa_assert(conn);
1796     pa_assert(msg);
1797     pa_assert_se(c = _u);
1798 
1799     pa_assert_se((reply = dbus_message_new_method_return(msg)));
1800     dbus_message_iter_init_append(reply, &msg_iter);
1801     pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
1802 
1803     rev = 1;
1804     pa_dbus_append_basic_variant_dict_entry(&dict_iter, manager_handlers[MANAGER_HANDLER_REVISION].property_name, DBUS_TYPE_UINT32, &rev);
1805 
1806     get_sinks(c, &names, &n);
1807     pa_dbus_append_basic_array_variant_dict_entry(&dict_iter,manager_handlers[MANAGER_HANDLER_EQUALIZED_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, names, n);
1808     for(unsigned i = 0; i < n; ++i) {
1809         pa_xfree(names[i]);
1810     }
1811     pa_xfree(names);
1812 
1813     get_profiles(c, &names, &n);
1814     pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, manager_handlers[MANAGER_HANDLER_PROFILES].property_name, DBUS_TYPE_STRING, names, n);
1815     for(unsigned i = 0; i < n; ++i) {
1816         pa_xfree(names[i]);
1817     }
1818     pa_xfree(names);
1819     pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
1820     pa_assert_se(dbus_connection_send(conn, reply, NULL));
1821     dbus_message_unref(reply);
1822 }
1823 
equalizer_handle_seed_filter(DBusConnection *conn, DBusMessage *msg, void *_u)1824 void equalizer_handle_seed_filter(DBusConnection *conn, DBusMessage *msg, void *_u) {
1825     struct userdata *u = _u;
1826     DBusError error;
1827     DBusMessage *message = NULL;
1828     float *ys;
1829     uint32_t *xs, channel, r_channel;
1830     double *_ys, preamp;
1831     unsigned x_npoints, y_npoints, a_i;
1832     float *H;
1833     bool points_good = true;
1834 
1835     pa_assert(conn);
1836     pa_assert(msg);
1837     pa_assert(u);
1838 
1839     dbus_error_init(&error);
1840 
1841     if (!dbus_message_get_args(msg, &error,
1842                 DBUS_TYPE_UINT32, &channel,
1843                 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &xs, &x_npoints,
1844                 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &_ys, &y_npoints,
1845                 DBUS_TYPE_DOUBLE, &preamp,
1846                 DBUS_TYPE_INVALID)) {
1847         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
1848         dbus_error_free(&error);
1849         return;
1850     }
1851     if (channel > u->channels) {
1852         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
1853         dbus_error_free(&error);
1854         return;
1855     }
1856     for(size_t i = 0; i < x_npoints; ++i) {
1857         if (xs[i] >= FILTER_SIZE(u)) {
1858             points_good = false;
1859             break;
1860         }
1861     }
1862     if (!is_monotonic(xs, x_npoints) || !points_good) {
1863         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs must be monotonic and 0<=x<=%zd", u->fft_size / 2);
1864         dbus_error_free(&error);
1865         return;
1866     }else if (x_npoints != y_npoints || x_npoints < 2 || x_npoints > FILTER_SIZE(u)) {
1867         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs and ys must be the same length and 2<=l<=%zd!", FILTER_SIZE(u));
1868         dbus_error_free(&error);
1869         return;
1870     }else if (xs[0] != 0 || xs[x_npoints - 1] != u->fft_size / 2) {
1871         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs[0] must be 0 and xs[-1]=fft_size/2");
1872         dbus_error_free(&error);
1873         return;
1874     }
1875 
1876     ys = pa_xmalloc(x_npoints * sizeof(float));
1877     for(uint32_t i = 0; i < x_npoints; ++i) {
1878         ys[i] = (float) _ys[i];
1879     }
1880     r_channel = channel == u->channels ? 0 : channel;
1881     a_i = pa_aupdate_write_begin(u->a_H[r_channel]);
1882     H = u->Hs[r_channel][a_i];
1883     u->Xs[r_channel][a_i] = preamp;
1884     interpolate(H, FILTER_SIZE(u), xs, ys, x_npoints);
1885     fix_filter(H, u->fft_size);
1886     if (channel == u->channels) {
1887         for(size_t c = 1; c < u->channels; ++c) {
1888             unsigned b_i = pa_aupdate_write_begin(u->a_H[c]);
1889             float *H_p = u->Hs[c][b_i];
1890             u->Xs[c][b_i] = preamp;
1891             memcpy(H_p, H, FILTER_SIZE(u) * sizeof(float));
1892             pa_aupdate_write_end(u->a_H[c]);
1893         }
1894     }
1895     pa_aupdate_write_end(u->a_H[r_channel]);
1896     pa_xfree(ys);
1897 
1898     pa_dbus_send_empty_reply(conn, msg);
1899 
1900     pa_assert_se((message = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
1901     pa_dbus_protocol_send_signal(u->dbus_protocol, message);
1902     dbus_message_unref(message);
1903 }
1904 
equalizer_handle_get_filter_points(DBusConnection *conn, DBusMessage *msg, void *_u)1905 void equalizer_handle_get_filter_points(DBusConnection *conn, DBusMessage *msg, void *_u) {
1906     struct userdata *u = (struct userdata *) _u;
1907     uint32_t *xs, channel, r_channel;
1908     double *ys, preamp;
1909     unsigned x_npoints, a_i;
1910     float *H;
1911     bool points_good=true;
1912     DBusMessage *reply = NULL;
1913     DBusMessageIter msg_iter;
1914     DBusError error;
1915 
1916     pa_assert(conn);
1917     pa_assert(msg);
1918     pa_assert(u);
1919 
1920     dbus_error_init(&error);
1921     if (!dbus_message_get_args(msg, &error,
1922                 DBUS_TYPE_UINT32, &channel,
1923                 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &xs, &x_npoints,
1924                 DBUS_TYPE_INVALID)) {
1925         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
1926         dbus_error_free(&error);
1927         return;
1928     }
1929     if (channel > u->channels) {
1930         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
1931         dbus_error_free(&error);
1932         return;
1933     }
1934 
1935     for(size_t i = 0; i < x_npoints; ++i) {
1936         if (xs[i] >= FILTER_SIZE(u)) {
1937             points_good=false;
1938             break;
1939         }
1940     }
1941 
1942     if (x_npoints > FILTER_SIZE(u) || !points_good) {
1943         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs indices/length must be <= %zd!", FILTER_SIZE(u));
1944         dbus_error_free(&error);
1945         return;
1946     }
1947 
1948     r_channel = channel == u->channels ? 0 : channel;
1949     ys = pa_xmalloc(x_npoints * sizeof(double));
1950     a_i = pa_aupdate_read_begin(u->a_H[r_channel]);
1951     H = u->Hs[r_channel][a_i];
1952     preamp = u->Xs[r_channel][a_i];
1953     for(uint32_t i = 0; i < x_npoints; ++i) {
1954         ys[i] = H[xs[i]] * u->fft_size;
1955     }
1956     pa_aupdate_read_end(u->a_H[r_channel]);
1957 
1958     pa_assert_se((reply = dbus_message_new_method_return(msg)));
1959     dbus_message_iter_init_append(reply, &msg_iter);
1960 
1961     pa_dbus_append_basic_array(&msg_iter, DBUS_TYPE_DOUBLE, ys, x_npoints);
1962     pa_dbus_append_basic_variant(&msg_iter, DBUS_TYPE_DOUBLE, &preamp);
1963 
1964     pa_assert_se(dbus_connection_send(conn, reply, NULL));
1965     dbus_message_unref(reply);
1966     pa_xfree(ys);
1967 }
1968 
get_filter(struct userdata *u, size_t channel, double **H_, double *preamp)1969 static void get_filter(struct userdata *u, size_t channel, double **H_, double *preamp) {
1970     float *H;
1971     unsigned a_i;
1972     size_t r_channel = channel == u->channels ? 0 : channel;
1973     *H_ = pa_xnew0(double, FILTER_SIZE(u));
1974     a_i = pa_aupdate_read_begin(u->a_H[r_channel]);
1975     H = u->Hs[r_channel][a_i];
1976     for(size_t i = 0;i < FILTER_SIZE(u); ++i) {
1977         (*H_)[i] = H[i] * u->fft_size;
1978     }
1979     *preamp = u->Xs[r_channel][a_i];
1980 
1981     pa_aupdate_read_end(u->a_H[r_channel]);
1982 }
1983 
equalizer_handle_get_filter(DBusConnection *conn, DBusMessage *msg, void *_u)1984 void equalizer_handle_get_filter(DBusConnection *conn, DBusMessage *msg, void *_u) {
1985     struct userdata *u;
1986     unsigned n_coefs;
1987     uint32_t channel;
1988     double *H_, preamp;
1989     DBusMessage *reply = NULL;
1990     DBusMessageIter msg_iter;
1991     DBusError error;
1992     pa_assert_se(u = (struct userdata *) _u);
1993     pa_assert(conn);
1994     pa_assert(msg);
1995 
1996     dbus_error_init(&error);
1997     if (!dbus_message_get_args(msg, &error,
1998                 DBUS_TYPE_UINT32, &channel,
1999                 DBUS_TYPE_INVALID)) {
2000         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
2001         dbus_error_free(&error);
2002         return;
2003     }
2004     if (channel > u->channels) {
2005         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
2006         dbus_error_free(&error);
2007         return;
2008     }
2009 
2010     n_coefs = CHANNEL_PROFILE_SIZE(u);
2011     pa_assert(conn);
2012     pa_assert(msg);
2013     get_filter(u, channel, &H_, &preamp);
2014     pa_assert_se((reply = dbus_message_new_method_return(msg)));
2015     dbus_message_iter_init_append(reply, &msg_iter);
2016 
2017     pa_dbus_append_basic_array(&msg_iter, DBUS_TYPE_DOUBLE, H_, n_coefs);
2018     pa_dbus_append_basic_variant(&msg_iter, DBUS_TYPE_DOUBLE, &preamp);
2019 
2020     pa_assert_se(dbus_connection_send(conn, reply, NULL));
2021     dbus_message_unref(reply);
2022     pa_xfree(H_);
2023 }
2024 
set_filter(struct userdata *u, size_t channel, double *H_, double preamp)2025 static void set_filter(struct userdata *u, size_t channel, double *H_, double preamp) {
2026     unsigned a_i;
2027     size_t r_channel = channel == u->channels ? 0 : channel;
2028     float *H;
2029     //all channels
2030     a_i = pa_aupdate_write_begin(u->a_H[r_channel]);
2031     u->Xs[r_channel][a_i] = (float) preamp;
2032     H = u->Hs[r_channel][a_i];
2033     for(size_t i = 0; i < FILTER_SIZE(u); ++i) {
2034         H[i] = (float) H_[i];
2035     }
2036     fix_filter(H, u->fft_size);
2037     if (channel == u->channels) {
2038         for(size_t c = 1; c < u->channels; ++c) {
2039             unsigned b_i = pa_aupdate_write_begin(u->a_H[c]);
2040             u->Xs[c][b_i] = u->Xs[r_channel][a_i];
2041             memcpy(u->Hs[c][b_i], u->Hs[r_channel][a_i], FILTER_SIZE(u) * sizeof(float));
2042             pa_aupdate_write_end(u->a_H[c]);
2043         }
2044     }
2045     pa_aupdate_write_end(u->a_H[r_channel]);
2046 }
2047 
equalizer_handle_set_filter(DBusConnection *conn, DBusMessage *msg, void *_u)2048 void equalizer_handle_set_filter(DBusConnection *conn, DBusMessage *msg, void *_u) {
2049     struct userdata *u;
2050     double *H, preamp;
2051     uint32_t channel;
2052     unsigned _n_coefs;
2053     DBusMessage *message = NULL;
2054     DBusError error;
2055     pa_assert_se(u = (struct userdata *) _u);
2056     pa_assert(conn);
2057     pa_assert(msg);
2058 
2059     dbus_error_init(&error);
2060     if (!dbus_message_get_args(msg, &error,
2061                 DBUS_TYPE_UINT32, &channel,
2062                 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &H, &_n_coefs,
2063                 DBUS_TYPE_DOUBLE, &preamp,
2064                 DBUS_TYPE_INVALID)) {
2065         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
2066         dbus_error_free(&error);
2067         return;
2068     }
2069     if (channel > u->channels) {
2070         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
2071         dbus_error_free(&error);
2072         return;
2073     }
2074     if (_n_coefs != FILTER_SIZE(u)) {
2075         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "This filter takes exactly %zd coefficients, you gave %d", FILTER_SIZE(u), _n_coefs);
2076         return;
2077     }
2078     set_filter(u, channel, H, preamp);
2079 
2080     pa_dbus_send_empty_reply(conn, msg);
2081 
2082     pa_assert_se((message = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
2083     pa_dbus_protocol_send_signal(u->dbus_protocol, message);
2084     dbus_message_unref(message);
2085 }
2086 
equalizer_handle_save_profile(DBusConnection *conn, DBusMessage *msg, void *_u)2087 void equalizer_handle_save_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
2088     struct userdata *u = (struct userdata *) _u;
2089     char *name;
2090     uint32_t channel, r_channel;
2091     DBusMessage *message = NULL;
2092     DBusError error;
2093     pa_assert(conn);
2094     pa_assert(msg);
2095     pa_assert(u);
2096     dbus_error_init(&error);
2097 
2098     if (!dbus_message_get_args(msg, &error,
2099                 DBUS_TYPE_UINT32, &channel,
2100                 DBUS_TYPE_STRING, &name,
2101                 DBUS_TYPE_INVALID)) {
2102         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
2103         dbus_error_free(&error);
2104         return;
2105     }
2106     if (channel > u->channels) {
2107         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
2108         dbus_error_free(&error);
2109         return;
2110     }
2111     r_channel = channel == u->channels ? 0 : channel;
2112     save_profile(u, r_channel, name);
2113     pa_dbus_send_empty_reply(conn, msg);
2114 
2115     pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_PROFILES_CHANGED].name)));
2116     pa_dbus_protocol_send_signal(u->dbus_protocol, message);
2117     dbus_message_unref(message);
2118 }
2119 
equalizer_handle_load_profile(DBusConnection *conn, DBusMessage *msg, void *_u)2120 void equalizer_handle_load_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
2121     struct userdata *u = (struct userdata *) _u;
2122     char *name;
2123     DBusError error;
2124     uint32_t channel, r_channel;
2125     const char *err_msg = NULL;
2126     DBusMessage *message = NULL;
2127 
2128     pa_assert(conn);
2129     pa_assert(msg);
2130     pa_assert(u);
2131     dbus_error_init(&error);
2132 
2133     if (!dbus_message_get_args(msg, &error,
2134                 DBUS_TYPE_UINT32, &channel,
2135                 DBUS_TYPE_STRING, &name,
2136                 DBUS_TYPE_INVALID)) {
2137         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
2138         dbus_error_free(&error);
2139         return;
2140     }
2141     if (channel > u->channels) {
2142         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
2143         dbus_error_free(&error);
2144         return;
2145     }
2146     r_channel = channel == u->channels ? 0 : channel;
2147 
2148     err_msg = load_profile(u, r_channel, name);
2149     if (err_msg != NULL) {
2150         pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "error loading profile %s: %s", name, err_msg);
2151         dbus_error_free(&error);
2152         return;
2153     }
2154     if (channel == u->channels) {
2155         for(uint32_t c = 1; c < u->channels; ++c) {
2156             load_profile(u, c, name);
2157         }
2158     }
2159     pa_dbus_send_empty_reply(conn, msg);
2160 
2161     pa_assert_se((message = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
2162     pa_dbus_protocol_send_signal(u->dbus_protocol, message);
2163     dbus_message_unref(message);
2164 }
2165 
equalizer_handle_save_state(DBusConnection *conn, DBusMessage *msg, void *_u)2166 void equalizer_handle_save_state(DBusConnection *conn, DBusMessage *msg, void *_u) {
2167     struct userdata *u = (struct userdata *) _u;
2168     pa_assert(conn);
2169     pa_assert(msg);
2170     pa_assert(u);
2171 
2172     save_state(u);
2173     pa_dbus_send_empty_reply(conn, msg);
2174 }
2175 
equalizer_handle_get_profile_name(DBusConnection *conn, DBusMessage *msg, void *_u)2176 void equalizer_handle_get_profile_name(DBusConnection *conn, DBusMessage *msg, void *_u) {
2177     struct userdata *u = (struct userdata *) _u;
2178     DBusError error;
2179     uint32_t channel, r_channel;
2180 
2181     pa_assert(conn);
2182     pa_assert(msg);
2183     pa_assert(u);
2184     dbus_error_init(&error);
2185 
2186     if (!dbus_message_get_args(msg, &error,
2187                 DBUS_TYPE_UINT32, &channel,
2188                 DBUS_TYPE_INVALID)) {
2189         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
2190         dbus_error_free(&error);
2191         return;
2192     }
2193     if (channel > u->channels) {
2194         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
2195         dbus_error_free(&error);
2196         return;
2197     }
2198     r_channel = channel == u->channels ? 0 : channel;
2199     pa_assert(u->base_profiles[r_channel]);
2200     pa_dbus_send_basic_value_reply(conn,msg, DBUS_TYPE_STRING, &u->base_profiles[r_channel]);
2201 }
2202 
equalizer_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u)2203 void equalizer_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u) {
2204     uint32_t rev=1;
2205     pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &rev);
2206 }
2207 
equalizer_get_n_channels(DBusConnection *conn, DBusMessage *msg, void *_u)2208 void equalizer_get_n_channels(DBusConnection *conn, DBusMessage *msg, void *_u) {
2209     struct userdata *u;
2210     uint32_t channels;
2211     pa_assert_se(u = (struct userdata *) _u);
2212     pa_assert(conn);
2213     pa_assert(msg);
2214 
2215     channels = (uint32_t) u->channels;
2216     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &channels);
2217 }
2218 
equalizer_get_n_coefs(DBusConnection *conn, DBusMessage *msg, void *_u)2219 void equalizer_get_n_coefs(DBusConnection *conn, DBusMessage *msg, void *_u) {
2220     struct userdata *u;
2221     uint32_t n_coefs;
2222     pa_assert_se(u = (struct userdata *) _u);
2223     pa_assert(conn);
2224     pa_assert(msg);
2225 
2226     n_coefs = (uint32_t) CHANNEL_PROFILE_SIZE(u);
2227     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &n_coefs);
2228 }
2229 
equalizer_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *_u)2230 void equalizer_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *_u) {
2231     struct userdata *u;
2232     uint32_t rate;
2233     pa_assert_se(u = (struct userdata *) _u);
2234     pa_assert(conn);
2235     pa_assert(msg);
2236 
2237     rate = (uint32_t) u->sink->sample_spec.rate;
2238     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &rate);
2239 }
2240 
equalizer_get_filter_rate(DBusConnection *conn, DBusMessage *msg, void *_u)2241 void equalizer_get_filter_rate(DBusConnection *conn, DBusMessage *msg, void *_u) {
2242     struct userdata *u;
2243     uint32_t fft_size;
2244     pa_assert_se(u = (struct userdata *) _u);
2245     pa_assert(conn);
2246     pa_assert(msg);
2247 
2248     fft_size = (uint32_t) u->fft_size;
2249     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &fft_size);
2250 }
2251 
equalizer_get_all(DBusConnection *conn, DBusMessage *msg, void *_u)2252 void equalizer_get_all(DBusConnection *conn, DBusMessage *msg, void *_u) {
2253     struct userdata *u;
2254     DBusMessage *reply = NULL;
2255     DBusMessageIter msg_iter, dict_iter;
2256     uint32_t rev, n_coefs, rate, fft_size, channels;
2257 
2258     pa_assert_se(u = _u);
2259     pa_assert(msg);
2260 
2261     rev = 1;
2262     n_coefs = (uint32_t) CHANNEL_PROFILE_SIZE(u);
2263     rate = (uint32_t) u->sink->sample_spec.rate;
2264     fft_size = (uint32_t) u->fft_size;
2265     channels = (uint32_t) u->channels;
2266 
2267     pa_assert_se((reply = dbus_message_new_method_return(msg)));
2268     dbus_message_iter_init_append(reply, &msg_iter);
2269     pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
2270 
2271     pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_REVISION].property_name, DBUS_TYPE_UINT32, &rev);
2272     pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_SAMPLERATE].property_name, DBUS_TYPE_UINT32, &rate);
2273     pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_FILTERSAMPLERATE].property_name, DBUS_TYPE_UINT32, &fft_size);
2274     pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_N_COEFS].property_name, DBUS_TYPE_UINT32, &n_coefs);
2275     pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_N_CHANNELS].property_name, DBUS_TYPE_UINT32, &channels);
2276 
2277     pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
2278     pa_assert_se(dbus_connection_send(conn, reply, NULL));
2279     dbus_message_unref(reply);
2280 }
2281