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