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