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