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