]> code.delx.au - pulseaudio/blob - src/modules/module-equalizer-sink.c
Merge branch 'master' of git://0pointer.de/pulseaudio
[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 #ifndef __SSE2__
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 //window the data
355 for(size_t j = 0; j < u->window_size; ++j){
356 dst[j] = X * W[j] * src[j];
357 }
358 //zero padd the the remaining fft window
359 memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
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 #else
394 typedef float v4sf __attribute__ ((__aligned__(v_size * sizeof(float))));
395 typedef union float_vector {
396 float f[v_size];
397 v4sf v;
398 __m128 m;
399 } float_vector_t;
400
401 //regardless of sse enabled, the loops in here assume
402 //16 byte aligned addresses and memory allocations divisible by v_size
403 static void dsp_logic(
404 float * restrict dst,//used as a temp array too, needs to be fft_length!
405 float * restrict src,/*input data w/ overlap at start,
406 *automatically cycled in routine
407 */
408 float * restrict overlap,//The size of the overlap
409 const float X,//multipliar
410 const float * restrict H,//The freq. magnitude scalers filter
411 const float * restrict W,//The windowing function
412 fftwf_complex * restrict output_window,//The transformed window'd src
413 struct userdata *u){//Collection of constants
414 const size_t overlap_size = PA_ROUND_UP(u->overlap_size, v_size);
415 float_vector_t x;
416 x.f[0] = x.f[1] = x.f[2] = x.f[3] = X;
417
418 //assert(u->samples_gathered >= u->R);
419 //use a linear-phase sliding STFT and overlap-add method
420 for(size_t j = 0; j < u->window_size; j += v_size){
421 //dst[j] = W[j] * src[j];
422 float_vector_t *d = (float_vector_t*) (dst + j);
423 float_vector_t *w = (float_vector_t*) (W + j);
424 float_vector_t *s = (float_vector_t*) (src + j);
425 //#if __SSE2__
426 d->m = _mm_mul_ps(x.m, _mm_mul_ps(w->m, s->m));
427 // d->v = x->v * w->v * s->v;
428 //#endif
429 }
430 //zero padd the the remaining fft window
431 memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
432
433 //Processing is done here!
434 //do fft
435 fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
436 //perform filtering - purely magnitude based
437 for(size_t j = 0; j < FILTER_SIZE; j += v_size / 2){
438 //output_window[j][0]*=H[j];
439 //output_window[j][1]*=H[j];
440 float_vector_t *d = (float_vector_t*)( ((float *) output_window) + 2 * j);
441 float_vector_t h;
442 h.f[0] = h.f[1] = H[j];
443 h.f[2] = h.f[3] = H[j + 1];
444 //#if __SSE2__
445 d->m = _mm_mul_ps(d->m, h.m);
446 //#else
447 // d->v = d->v * h.v;
448 //#endif
449 }
450
451 //inverse fft
452 fftwf_execute_dft_c2r(u->inverse_plan, output_window, dst);
453
454 ////debug: tests overlaping add
455 ////and negates ALL PREVIOUS processing
456 ////yields a perfect reconstruction if COLA is held
457 //for(size_t j = 0; j < u->window_size; ++j){
458 // dst[j] = W[j] * src[j];
459 //}
460
461 //overlap add and preserve overlap component from this window (linear phase)
462 for(size_t j = 0; j < overlap_size; j += v_size){
463 //dst[j]+=overlap[j];
464 //overlap[j]+=dst[j+R];
465 float_vector_t *d = (float_vector_t*)(dst + j);
466 float_vector_t *o = (float_vector_t*)(overlap + j);
467 //#if __SSE2__
468 d->m = _mm_add_ps(d->m, o->m);
469 o->m = ((float_vector_t*)(dst + u->R + j))->m;
470 //#else
471 // d->v = d->v + o->v;
472 // o->v = ((float_vector_t*)(dst + u->R + j))->v;
473 //#endif
474 }
475 //memcpy(overlap, dst+u->R, u->overlap_size * sizeof(float)); //overlap preserve (debug)
476 //zero out the bit beyond the real overlap so we don't add garbage next iteration
477 memset(overlap + u->overlap_size, 0, overlap_size - u->overlap_size);
478
479 ////debug: tests if basic buffering works
480 ////shouldn't modify the signal AT ALL (beyond roundoff)
481 //for(size_t j = 0; j < u->window_size; ++j){
482 // dst[j] = src[j];
483 //}
484
485 //preseve the needed input for the next window's overlap
486 memmove(src, src + u->R,
487 (u->samples_gathered - u->R) * sizeof(float)
488 );
489 }
490 #endif
491
492 static void process_samples(struct userdata *u, pa_memchunk *tchunk){
493 size_t fs = pa_frame_size(&(u->sink->sample_spec));
494 float *dst;
495 unsigned a_i;
496 float *H, X;
497 size_t iterations, offset;
498 pa_assert(u->samples_gathered >= u->window_size);
499 iterations = (u->samples_gathered - u->overlap_size) / u->R;
500 tchunk->index = 0;
501 tchunk->length = iterations * u->R * fs;
502 tchunk->memblock = pa_memblock_new(u->sink->core->mempool, tchunk->length);
503 dst = ((float*) pa_memblock_acquire(tchunk->memblock));
504 for(size_t iter = 0; iter < iterations; ++iter){
505 offset = iter * u->R * fs;
506 for(size_t c = 0;c < u->channels; c++) {
507 a_i = pa_aupdate_read_begin(u->a_H[c]);
508 X = u->Xs[c][a_i];
509 H = u->Hs[c][a_i];
510 dsp_logic(
511 u->work_buffer,
512 u->input[c],
513 u->overlap_accum[c],
514 X,
515 H,
516 u->W,
517 u->output_window,
518 u
519 );
520 pa_aupdate_read_end(u->a_H[c]);
521 if(u->first_iteration){
522 /* The windowing function will make the audio ramped in, as a cheap fix we can
523 * undo the windowing (for non-zero window values)
524 */
525 for(size_t i = 0; i < u->overlap_size; ++i){
526 u->work_buffer[i] = u->W[i] <= FLT_EPSILON ? u->work_buffer[i] : u->work_buffer[i] / u->W[i];
527 }
528 }
529 pa_sample_clamp(PA_SAMPLE_FLOAT32NE, (uint8_t *) (dst + c) + offset, fs, u->work_buffer, sizeof(float), u->R);
530 }
531 if(u->first_iteration){
532 u->first_iteration = FALSE;
533 }
534 u->samples_gathered -= u->R;
535 }
536 pa_memblock_release(tchunk->memblock);
537 }
538
539 static void input_buffer(struct userdata *u, pa_memchunk *in){
540 size_t fs = pa_frame_size(&(u->sink->sample_spec));
541 size_t samples = in->length/fs;
542 float *src = (float*) ((uint8_t*) pa_memblock_acquire(in->memblock) + in->index);
543 pa_assert(u->samples_gathered + samples <= u->input_buffer_max);
544 for(size_t c = 0; c < u->channels; c++) {
545 //buffer with an offset after the overlap from previous
546 //iterations
547 pa_assert_se(
548 u->input[c] + u->samples_gathered + samples <= u->input[c] + u->input_buffer_max
549 );
550 pa_sample_clamp(PA_SAMPLE_FLOAT32NE, u->input[c] + u->samples_gathered, sizeof(float), src + c, fs, samples);
551 }
552 u->samples_gathered += samples;
553 pa_memblock_release(in->memblock);
554 }
555
556 /* Called from I/O thread context */
557 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
558 struct userdata *u;
559 size_t fs, target_samples, mbs;
560 //struct timeval start, end;
561 pa_memchunk tchunk;
562 pa_sink_input_assert_ref(i);
563 pa_assert_se(u = i->userdata);
564 pa_assert(chunk);
565 pa_assert(u->sink);
566 fs = pa_frame_size(&(u->sink->sample_spec));
567 nbytes = PA_MIN(nbytes, pa_mempool_block_size_max(u->sink->core->mempool));
568 target_samples = PA_ROUND_UP(nbytes / fs, u->R);
569 mbs = pa_mempool_block_size_max(u->sink->core->mempool);
570 //pa_log_debug("vanilla mbs = %ld",mbs);
571 mbs = PA_ROUND_DOWN(mbs / fs, u->R);
572 mbs = PA_MAX(mbs, u->R);
573 target_samples = PA_MAX(target_samples, mbs);
574 //pa_log_debug("target samples: %ld", target_samples);
575 if(u->first_iteration){
576 //allocate request_size
577 target_samples = PA_MAX(target_samples, u->window_size);
578 }else{
579 //allocate request_size + overlap
580 target_samples += u->overlap_size;
581 }
582 alloc_input_buffers(u, target_samples);
583 //pa_log_debug("post target samples: %ld", target_samples);
584 chunk->memblock = NULL;
585
586 /* Hmm, process any rewind request that might be queued up */
587 pa_sink_process_rewind(u->sink, 0);
588
589 //pa_log_debug("start output-buffered %ld, input-buffered %ld, requested %ld",buffered_samples,u->samples_gathered,samples_requested);
590 //pa_rtclock_get(&start);
591 do{
592 size_t input_remaining = target_samples - u->samples_gathered;
593 // pa_log_debug("input remaining %ld samples", input_remaining);
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 // pa_log_debug("buffering %ld bytes", tchunk.length);
609 input_buffer(u, &tchunk);
610 //pa_rtclock_get(&end);
611 //pa_log_debug("Took %0.5f seconds to setup", pa_timeval_diff(end, start) / (double) PA_USEC_PER_SEC);
612 pa_memblock_unref(tchunk.memblock);
613 }while(u->samples_gathered < target_samples);
614
615 //pa_rtclock_get(&end);
616 //pa_log_debug("Took %0.6f seconds to get data", (double) pa_timeval_diff(&end, &start) / PA_USEC_PER_SEC);
617
618 pa_assert(u->fft_size >= u->window_size);
619 pa_assert(u->R < u->window_size);
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); //this is the "proper" thing to do...
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 char *p;
818 for(size_t i = 0; i < len; ++i){
819 t_len += strlen(strs[i]);
820 }
821 *length = headers + t_len;
822 p = *packed = pa_xmalloc0(*length);
823 *((uint16_t *) p) = (uint16_t) len;
824 p += sizeof(uint16_t);
825 for(size_t i = 0; i < len; ++i){
826 uint16_t l = strlen(strs[i]);
827 *((uint16_t *) p) = (uint16_t) l;
828 p += sizeof(uint16_t);
829 memcpy(p, strs[i], l);
830 p += l;
831 }
832 }
833 static void unpack(char *str, size_t length, char ***strs, size_t *len){
834 char *p = str;
835 *len = *((uint16_t *) p);
836 p += sizeof(uint16_t);
837 *strs = pa_xnew(char *, *len);
838
839 for(size_t i = 0; i < *len; ++i){
840 size_t l = *((uint16_t *) p);
841 p += sizeof(uint16_t);
842 (*strs)[i] = pa_xnew(char, l + 1);
843 memcpy((*strs)[i], p, l);
844 (*strs)[i][l] = '\0';
845 p += l;
846 }
847 }
848 static void save_profile(struct userdata *u, size_t channel, char *name){
849 unsigned a_i;
850 const size_t profile_size = CHANNEL_PROFILE_SIZE * sizeof(float);
851 float *H_n, *profile;
852 const float *H;
853 pa_datum key, data;
854 profile = pa_xnew0(float, profile_size);
855 a_i = pa_aupdate_read_begin(u->a_H[channel]);
856 profile[0] = u->Xs[a_i][channel];
857 H = u->Hs[channel][a_i];
858 H_n = profile + 1;
859 for(size_t i = 0 ; i <= FILTER_SIZE; ++i){
860 H_n[i] = H[i] * u->fft_size;
861 //H_n[i] = H[i];
862 }
863 pa_aupdate_read_end(u->a_H[channel]);
864 key.data=name;
865 key.size = strlen(key.data);
866 data.data = profile;
867 data.size = profile_size;
868 pa_database_set(u->database, &key, &data, TRUE);
869 pa_database_sync(u->database);
870 if(u->base_profiles[channel]){
871 pa_xfree(u->base_profiles[channel]);
872 }
873 u->base_profiles[channel] = pa_xstrdup(name);
874 }
875
876 static void save_state(struct userdata *u){
877 unsigned a_i;
878 const size_t filter_state_size = FILTER_STATE_SIZE * sizeof(float);
879 float *H_n, *state;
880 float *H;
881 pa_datum key, data;
882 pa_database *database;
883 char *dbname;
884 char *state_name = u->name;
885 char *packed;
886 size_t packed_length;
887
888 pack(u->base_profiles, u->channels, &packed, &packed_length);
889 state = (float *) pa_xmalloc0(filter_state_size + packed_length);
890 memcpy(state + FILTER_STATE_SIZE, packed, packed_length);
891 pa_xfree(packed);
892
893 for(size_t c = 0; c < u->channels; ++c){
894 a_i = pa_aupdate_read_begin(u->a_H[c]);
895 state[c * CHANNEL_PROFILE_SIZE] = u->Xs[c][a_i];
896 H = u->Hs[c][a_i];
897 H_n = &state[c * CHANNEL_PROFILE_SIZE + 1];
898 memcpy(H_n, H, FILTER_SIZE * sizeof(float));
899 pa_aupdate_read_end(u->a_H[c]);
900 }
901
902 key.data = state_name;
903 key.size = strlen(key.data);
904 data.data = state;
905 data.size = filter_state_size + packed_length;
906 //thread safety for 0.9.17?
907 pa_assert_se(dbname = pa_state_path(EQ_STATE_DB, FALSE));
908 pa_assert_se(database = pa_database_open(dbname, TRUE));
909 pa_xfree(dbname);
910
911 pa_database_set(database, &key, &data, TRUE);
912 pa_database_sync(database);
913 pa_database_close(database);
914 pa_xfree(state);
915 }
916
917 static void remove_profile(pa_core *c, char *name){
918 pa_datum key;
919 pa_database *database;
920 key.data = name;
921 key.size = strlen(key.data);
922 pa_assert_se(database = pa_shared_get(c, EQDB));
923 pa_database_unset(database, &key);
924 pa_database_sync(database);
925 }
926
927 static const char* load_profile(struct userdata *u, size_t channel, char *name){
928 unsigned a_i;
929 pa_datum key, value;
930 const size_t profile_size = CHANNEL_PROFILE_SIZE * sizeof(float);
931 key.data = name;
932 key.size = strlen(key.data);
933 if(pa_database_get(u->database, &key, &value) != NULL){
934 if(value.size == profile_size){
935 float *profile = (float *) value.data;
936 a_i = pa_aupdate_write_begin(u->a_H[channel]);
937 u->Xs[channel][a_i] = profile[0];
938 memcpy(u->Hs[channel][a_i], profile + 1, FILTER_SIZE * sizeof(float));
939 fix_filter(u->Hs[channel][a_i], u->fft_size);
940 pa_aupdate_write_end(u->a_H[channel]);
941 pa_xfree(u->base_profiles[channel]);
942 u->base_profiles[channel] = pa_xstrdup(name);
943 }else{
944 return "incompatible size";
945 }
946 pa_datum_free(&value);
947 }else{
948 return "profile doesn't exist";
949 }
950 return NULL;
951 }
952
953 static void load_state(struct userdata *u){
954 unsigned a_i;
955 float *H;
956 pa_datum key, value;
957 pa_database *database;
958 char *dbname;
959 char *state_name = u->name;
960 pa_assert_se(dbname = pa_state_path(EQ_STATE_DB, FALSE));
961 database = pa_database_open(dbname, FALSE);
962 pa_xfree(dbname);
963 if(!database){
964 pa_log("No resume state");
965 return;
966 }
967
968 key.data = state_name;
969 key.size = strlen(key.data);
970
971 if(pa_database_get(database, &key, &value) != NULL){
972 if(value.size > FILTER_STATE_SIZE * sizeof(float) + sizeof(uint16_t)){
973 float *state = (float *) value.data;
974 size_t n_profs;
975 char **names;
976 for(size_t c = 0; c < u->channels; ++c){
977 a_i = pa_aupdate_write_begin(u->a_H[c]);
978 H = state + c * CHANNEL_PROFILE_SIZE + 1;
979 u->Xs[c][a_i] = state[c * CHANNEL_PROFILE_SIZE];
980 memcpy(u->Hs[c][a_i], H, FILTER_SIZE * sizeof(float));
981 pa_aupdate_write_end(u->a_H[c]);
982 }
983 unpack(((char *)value.data) + FILTER_STATE_SIZE * sizeof(float), value.size - FILTER_STATE_SIZE * sizeof(float), &names, &n_profs);
984 n_profs = PA_MIN(n_profs, u->channels);
985 for(size_t c = 0; c < n_profs; ++c){
986 pa_xfree(u->base_profiles[c]);
987 u->base_profiles[c] = names[c];
988 }
989 pa_xfree(names);
990 }
991 pa_datum_free(&value);
992 }else{
993 pa_log("resume state exists but is wrong size!");
994 }
995 pa_database_close(database);
996 }
997
998 /* Called from main context */
999 static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
1000 struct userdata *u;
1001
1002 pa_sink_input_assert_ref(i);
1003 pa_assert_se(u = i->userdata);
1004
1005 return u->sink != dest;
1006 }
1007
1008 /* Called from main context */
1009 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
1010 struct userdata *u;
1011
1012 pa_sink_input_assert_ref(i);
1013 pa_assert_se(u = i->userdata);
1014 if (dest) {
1015 pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
1016 pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
1017 } else
1018 pa_sink_set_asyncmsgq(u->sink, NULL);
1019 }
1020
1021 int pa__init(pa_module*m) {
1022 struct userdata *u;
1023 pa_sample_spec ss;
1024 pa_channel_map map;
1025 pa_modargs *ma;
1026 const char *z;
1027 pa_sink *master;
1028 pa_sink_input_new_data sink_input_data;
1029 pa_sink_new_data sink_data;
1030 size_t fs;
1031 float *H;
1032 unsigned a_i;
1033
1034 pa_assert(m);
1035
1036 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
1037 pa_log("Failed to parse module arguments.");
1038 goto fail;
1039 }
1040
1041 if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK))) {
1042 pa_log("Master sink not found, trying default");
1043 master = pa_namereg_get_default_sink(m->core);
1044 if(!master){
1045 pa_log("no default sink found!");
1046 goto fail;
1047 }
1048 }
1049
1050 ss = master->sample_spec;
1051 ss.format = PA_SAMPLE_FLOAT32;
1052 map = master->channel_map;
1053 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
1054 pa_log("Invalid sample format specification or channel map");
1055 goto fail;
1056 }
1057 fs = pa_frame_size(&ss);
1058
1059 u = pa_xnew0(struct userdata, 1);
1060 u->module = m;
1061 m->userdata = u;
1062
1063 u->set_default = TRUE;
1064 pa_modargs_get_value_boolean(ma, "set_default", &u->set_default);
1065
1066 u->channels = ss.channels;
1067 u->fft_size = pow(2, ceil(log(ss.rate) / log(2)));//probably unstable near corner cases of powers of 2
1068 pa_log_debug("fft size: %ld", u->fft_size);
1069 u->window_size = 15999;
1070 if(u->window_size % 2 == 0){
1071 u->window_size--;
1072 }
1073 u->R = (u->window_size + 1) / 2;
1074 u->overlap_size = u->window_size - u->R;
1075 u->samples_gathered = 0;
1076 u->input_buffer_max = 0;
1077 u->a_H = pa_xnew0(pa_aupdate *, u->channels);
1078 u->Xs = pa_xnew0(float *, u->channels);
1079 u->Hs = pa_xnew0(float **, u->channels);
1080 for(size_t c = 0; c < u->channels; ++c){
1081 u->Xs[c] = pa_xnew0(float, 2);
1082 u->Hs[c] = pa_xnew0(float *, 2);
1083 for(size_t i = 0; i < 2; ++i){
1084 u->Hs[c][i] = alloc(FILTER_SIZE, sizeof(float));
1085 }
1086 }
1087 u->W = alloc(u->window_size, sizeof(float));
1088 u->work_buffer = alloc(u->fft_size, sizeof(float));
1089 memset(u->work_buffer, 0, u->fft_size*sizeof(float));
1090 u->input = pa_xnew0(float *, u->channels);
1091 u->overlap_accum = pa_xnew0(float *, u->channels);
1092 for(size_t c = 0; c < u->channels; ++c){
1093 u->a_H[c] = pa_aupdate_new();
1094 u->input[c] = NULL;
1095 u->overlap_accum[c] = alloc(u->overlap_size, sizeof(float));
1096 }
1097 u->output_window = alloc((FILTER_SIZE), sizeof(fftwf_complex));
1098 u->forward_plan = fftwf_plan_dft_r2c_1d(u->fft_size, u->work_buffer, u->output_window, FFTW_ESTIMATE);
1099 u->inverse_plan = fftwf_plan_dft_c2r_1d(u->fft_size, u->output_window, u->work_buffer, FFTW_ESTIMATE);
1100
1101 hanning_window(u->W, u->window_size);
1102 u->first_iteration = TRUE;
1103
1104 u->base_profiles = pa_xnew0(char *, u->channels);
1105 for(size_t c = 0; c < u->channels; ++c){
1106 u->base_profiles[c] = pa_xstrdup("default");
1107 }
1108
1109 /* Create sink */
1110 pa_sink_new_data_init(&sink_data);
1111 sink_data.driver = __FILE__;
1112 sink_data.module = m;
1113 if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
1114 sink_data.name = pa_sprintf_malloc("%s.equalizer", master->name);
1115 pa_sink_new_data_set_sample_spec(&sink_data, &ss);
1116 pa_sink_new_data_set_channel_map(&sink_data, &map);
1117 z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
1118 pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "FFT based equalizer on %s",z? z: master->name);
1119 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
1120 pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
1121
1122 if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
1123 pa_log("Invalid properties");
1124 pa_sink_new_data_done(&sink_data);
1125 goto fail;
1126 }
1127
1128 u->sink = pa_sink_new(m->core, &sink_data,
1129 PA_SINK_HW_MUTE_CTRL|PA_SINK_HW_VOLUME_CTRL|PA_SINK_DECIBEL_VOLUME|
1130 (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY)));
1131 pa_sink_new_data_done(&sink_data);
1132
1133 if (!u->sink) {
1134 pa_log("Failed to create sink.");
1135 goto fail;
1136 }
1137 u->name=pa_xstrdup(u->sink->name);
1138 u->sink->parent.process_msg = sink_process_msg_cb;
1139 u->sink->set_state = sink_set_state_cb;
1140 u->sink->update_requested_latency = sink_update_requested_latency_cb;
1141 u->sink->request_rewind = sink_request_rewind_cb;
1142 u->sink->set_volume = sink_set_volume_cb;
1143 u->sink->set_mute = sink_set_mute_cb;
1144 u->sink->userdata = u;
1145 u->input_q = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, fs, 1, 1, 0, &u->sink->silence);
1146
1147 pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
1148 //pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->R*fs, &ss));
1149
1150 /* Create sink input */
1151 pa_sink_input_new_data_init(&sink_input_data);
1152 sink_input_data.driver = __FILE__;
1153 sink_input_data.module = m;
1154 sink_input_data.sink = master;
1155 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Equalized Stream");
1156 pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
1157 pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
1158 pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
1159
1160 pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
1161 pa_sink_input_new_data_done(&sink_input_data);
1162
1163 if (!u->sink_input)
1164 goto fail;
1165
1166 u->sink_input->pop = sink_input_pop_cb;
1167 u->sink_input->process_rewind = sink_input_process_rewind_cb;
1168 u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
1169 u->sink_input->update_max_request = sink_input_update_max_request_cb;
1170 u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
1171 u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
1172 u->sink_input->kill = sink_input_kill_cb;
1173 u->sink_input->attach = sink_input_attach_cb;
1174 u->sink_input->detach = sink_input_detach_cb;
1175 u->sink_input->state_change = sink_input_state_change_cb;
1176 u->sink_input->may_move_to = sink_input_may_move_to_cb;
1177 u->sink_input->moving = sink_input_moving_cb;
1178 u->sink_input->volume_changed = sink_input_volume_changed_cb;
1179 u->sink_input->mute_changed = sink_input_mute_changed_cb;
1180
1181 u->sink_input->userdata = u;
1182
1183 pa_sink_put(u->sink);
1184 pa_sink_input_put(u->sink_input);
1185
1186 pa_modargs_free(ma);
1187
1188
1189 dbus_init(u);
1190
1191 //default filter to these
1192 for(size_t c = 0; c< u->channels; ++c){
1193 a_i = pa_aupdate_write_begin(u->a_H[c]);
1194 H = u->Hs[c][a_i];
1195 u->Xs[c][a_i] = 1.0f;
1196 for(size_t i = 0; i < FILTER_SIZE; ++i){
1197 H[i] = 1.0 / sqrtf(2.0f);
1198 }
1199 fix_filter(H, u->fft_size);
1200 pa_aupdate_write_end(u->a_H[c]);
1201 }
1202 //load old parameters
1203 load_state(u);
1204
1205 return 0;
1206
1207 fail:
1208 if (ma)
1209 pa_modargs_free(ma);
1210
1211
1212 pa__done(m);
1213
1214 return -1;
1215 }
1216
1217 int pa__get_n_used(pa_module *m) {
1218 struct userdata *u;
1219
1220 pa_assert(m);
1221 pa_assert_se(u = m->userdata);
1222
1223 return pa_sink_linked_by(u->sink);
1224 }
1225
1226 void pa__done(pa_module*m) {
1227 struct userdata *u;
1228
1229 pa_assert(m);
1230
1231 if (!(u = m->userdata))
1232 return;
1233
1234 save_state(u);
1235
1236 dbus_done(u);
1237
1238 for(size_t c = 0; c < u->channels; ++c){
1239 pa_xfree(u->base_profiles[c]);
1240 }
1241 pa_xfree(u->base_profiles);
1242
1243 /* See comments in sink_input_kill_cb() above regarding
1244 * destruction order! */
1245
1246 if (u->sink_input)
1247 pa_sink_input_unlink(u->sink_input);
1248
1249 if (u->sink)
1250 pa_sink_unlink(u->sink);
1251
1252 if (u->sink_input)
1253 pa_sink_input_unref(u->sink_input);
1254
1255 if (u->sink)
1256 pa_sink_unref(u->sink);
1257
1258 pa_memblockq_free(u->input_q);
1259
1260 fftwf_destroy_plan(u->inverse_plan);
1261 fftwf_destroy_plan(u->forward_plan);
1262 pa_xfree(u->output_window);
1263 for(size_t c=0; c < u->channels; ++c){
1264 pa_aupdate_free(u->a_H[c]);
1265 pa_xfree(u->overlap_accum[c]);
1266 pa_xfree(u->input[c]);
1267 }
1268 pa_xfree(u->a_H);
1269 pa_xfree(u->overlap_accum);
1270 pa_xfree(u->input);
1271 pa_xfree(u->work_buffer);
1272 pa_xfree(u->W);
1273 for(size_t c = 0; c < u->channels; ++c){
1274 pa_xfree(u->Xs[c]);
1275 for(size_t i = 0; i < 2; ++i){
1276 pa_xfree(u->Hs[c][i]);
1277 }
1278 pa_xfree(u->Hs[c]);
1279 }
1280 pa_xfree(u->Xs);
1281 pa_xfree(u->Hs);
1282
1283 pa_xfree(u->name);
1284
1285 pa_xfree(u);
1286 }
1287
1288 /*
1289 * DBus Routines and Callbacks
1290 */
1291 #define EXTNAME "org.PulseAudio.Ext.Equalizing1"
1292 #define MANAGER_PATH "/org/pulseaudio/equalizing1"
1293 #define MANAGER_IFACE EXTNAME ".Manager"
1294 #define EQUALIZER_IFACE EXTNAME ".Equalizer"
1295 static void manager_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u);
1296 static void manager_get_sinks(DBusConnection *conn, DBusMessage *msg, void *_u);
1297 static void manager_get_profiles(DBusConnection *conn, DBusMessage *msg, void *_u);
1298 static void manager_get_all(DBusConnection *conn, DBusMessage *msg, void *_u);
1299 static void manager_handle_remove_profile(DBusConnection *conn, DBusMessage *msg, void *_u);
1300 static void equalizer_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u);
1301 static void equalizer_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *_u);
1302 static void equalizer_get_filter_rate(DBusConnection *conn, DBusMessage *msg, void *_u);
1303 static void equalizer_get_n_coefs(DBusConnection *conn, DBusMessage *msg, void *_u);
1304 static void equalizer_get_n_channels(DBusConnection *conn, DBusMessage *msg, void *_u);
1305 static void equalizer_get_all(DBusConnection *conn, DBusMessage *msg, void *_u);
1306 static void equalizer_handle_seed_filter(DBusConnection *conn, DBusMessage *msg, void *_u);
1307 static void equalizer_handle_get_filter_points(DBusConnection *conn, DBusMessage *msg, void *_u);
1308 static void equalizer_handle_get_filter(DBusConnection *conn, DBusMessage *msg, void *_u);
1309 static void equalizer_handle_set_filter(DBusConnection *conn, DBusMessage *msg, void *_u);
1310 static void equalizer_handle_save_profile(DBusConnection *conn, DBusMessage *msg, void *_u);
1311 static void equalizer_handle_load_profile(DBusConnection *conn, DBusMessage *msg, void *_u);
1312 static void equalizer_handle_save_state(DBusConnection *conn, DBusMessage *msg, void *_u);
1313 static void equalizer_handle_get_profile_name(DBusConnection *conn, DBusMessage *msg, void *_u);
1314 enum manager_method_index {
1315 MANAGER_METHOD_REMOVE_PROFILE,
1316 MANAGER_METHOD_MAX
1317 };
1318
1319 pa_dbus_arg_info remove_profile_args[]={
1320 {"name", "s","in"},
1321 };
1322
1323 static pa_dbus_method_handler manager_methods[MANAGER_METHOD_MAX]={
1324 [MANAGER_METHOD_REMOVE_PROFILE]{
1325 .method_name="RemoveProfile",
1326 .arguments=remove_profile_args,
1327 .n_arguments=sizeof(remove_profile_args)/sizeof(pa_dbus_arg_info),
1328 .receive_cb=manager_handle_remove_profile}
1329 };
1330
1331 enum manager_handler_index {
1332 MANAGER_HANDLER_REVISION,
1333 MANAGER_HANDLER_EQUALIZED_SINKS,
1334 MANAGER_HANDLER_PROFILES,
1335 MANAGER_HANDLER_MAX
1336 };
1337
1338 static pa_dbus_property_handler manager_handlers[MANAGER_HANDLER_MAX]={
1339 [MANAGER_HANDLER_REVISION]={.property_name="InterfaceRevision",.type="u",.get_cb=manager_get_revision,.set_cb=NULL},
1340 [MANAGER_HANDLER_EQUALIZED_SINKS]={.property_name="EqualizedSinks",.type="ao",.get_cb=manager_get_sinks,.set_cb=NULL},
1341 [MANAGER_HANDLER_PROFILES]={.property_name="Profiles",.type="as",.get_cb=manager_get_profiles,.set_cb=NULL}
1342 };
1343
1344 pa_dbus_arg_info sink_args[]={
1345 {"sink", "o", NULL}
1346 };
1347
1348 enum manager_signal_index{
1349 MANAGER_SIGNAL_SINK_ADDED,
1350 MANAGER_SIGNAL_SINK_REMOVED,
1351 MANAGER_SIGNAL_PROFILES_CHANGED,
1352 MANAGER_SIGNAL_MAX
1353 };
1354
1355 static pa_dbus_signal_info manager_signals[MANAGER_SIGNAL_MAX]={
1356 [MANAGER_SIGNAL_SINK_ADDED]={.name="SinkAdded", .arguments=sink_args, .n_arguments=sizeof(sink_args)/sizeof(pa_dbus_arg_info)},
1357 [MANAGER_SIGNAL_SINK_REMOVED]={.name="SinkRemoved", .arguments=sink_args, .n_arguments=sizeof(sink_args)/sizeof(pa_dbus_arg_info)},
1358 [MANAGER_SIGNAL_PROFILES_CHANGED]={.name="ProfilesChanged", .arguments=NULL, .n_arguments=0}
1359 };
1360
1361 static pa_dbus_interface_info manager_info={
1362 .name=MANAGER_IFACE,
1363 .method_handlers=manager_methods,
1364 .n_method_handlers=MANAGER_METHOD_MAX,
1365 .property_handlers=manager_handlers,
1366 .n_property_handlers=MANAGER_HANDLER_MAX,
1367 .get_all_properties_cb=manager_get_all,
1368 .signals=manager_signals,
1369 .n_signals=MANAGER_SIGNAL_MAX
1370 };
1371
1372 enum equalizer_method_index {
1373 EQUALIZER_METHOD_FILTER_POINTS,
1374 EQUALIZER_METHOD_SEED_FILTER,
1375 EQUALIZER_METHOD_SAVE_PROFILE,
1376 EQUALIZER_METHOD_LOAD_PROFILE,
1377 EQUALIZER_METHOD_SET_FILTER,
1378 EQUALIZER_METHOD_GET_FILTER,
1379 EQUALIZER_METHOD_SAVE_STATE,
1380 EQUALIZER_METHOD_GET_PROFILE_NAME,
1381 EQUALIZER_METHOD_MAX
1382 };
1383
1384 enum equalizer_handler_index {
1385 EQUALIZER_HANDLER_REVISION,
1386 EQUALIZER_HANDLER_SAMPLERATE,
1387 EQUALIZER_HANDLER_FILTERSAMPLERATE,
1388 EQUALIZER_HANDLER_N_COEFS,
1389 EQUALIZER_HANDLER_N_CHANNELS,
1390 EQUALIZER_HANDLER_MAX
1391 };
1392
1393 pa_dbus_arg_info filter_points_args[]={
1394 {"channel", "u","in"},
1395 {"xs", "au","in"},
1396 {"ys", "ad","out"},
1397 {"preamp", "d","out"}
1398 };
1399 pa_dbus_arg_info seed_filter_args[]={
1400 {"channel", "u","in"},
1401 {"xs", "au","in"},
1402 {"ys", "ad","in"},
1403 {"preamp", "d","in"}
1404 };
1405
1406 pa_dbus_arg_info set_filter_args[]={
1407 {"channel", "u","in"},
1408 {"ys", "ad","in"},
1409 {"preamp", "d","in"}
1410 };
1411 pa_dbus_arg_info get_filter_args[]={
1412 {"channel", "u","in"},
1413 {"ys", "ad","out"},
1414 {"preamp", "d","out"}
1415 };
1416
1417 pa_dbus_arg_info save_profile_args[]={
1418 {"channel", "u","in"},
1419 {"name", "s","in"}
1420 };
1421 pa_dbus_arg_info load_profile_args[]={
1422 {"channel", "u","in"},
1423 {"name", "s","in"}
1424 };
1425 pa_dbus_arg_info base_profile_name_args[]={
1426 {"channel", "u","in"},
1427 {"name", "s","out"}
1428 };
1429
1430 static pa_dbus_method_handler equalizer_methods[EQUALIZER_METHOD_MAX]={
1431 [EQUALIZER_METHOD_SEED_FILTER]{
1432 .method_name="SeedFilter",
1433 .arguments=seed_filter_args,
1434 .n_arguments=sizeof(seed_filter_args)/sizeof(pa_dbus_arg_info),
1435 .receive_cb=equalizer_handle_seed_filter},
1436 [EQUALIZER_METHOD_FILTER_POINTS]{
1437 .method_name="FilterAtPoints",
1438 .arguments=filter_points_args,
1439 .n_arguments=sizeof(filter_points_args)/sizeof(pa_dbus_arg_info),
1440 .receive_cb=equalizer_handle_get_filter_points},
1441 [EQUALIZER_METHOD_SET_FILTER]{
1442 .method_name="SetFilter",
1443 .arguments=set_filter_args,
1444 .n_arguments=sizeof(set_filter_args)/sizeof(pa_dbus_arg_info),
1445 .receive_cb=equalizer_handle_set_filter},
1446 [EQUALIZER_METHOD_GET_FILTER]{
1447 .method_name="GetFilter",
1448 .arguments=get_filter_args,
1449 .n_arguments=sizeof(get_filter_args)/sizeof(pa_dbus_arg_info),
1450 .receive_cb=equalizer_handle_get_filter},
1451 [EQUALIZER_METHOD_SAVE_PROFILE]{
1452 .method_name="SaveProfile",
1453 .arguments=save_profile_args,
1454 .n_arguments=sizeof(save_profile_args)/sizeof(pa_dbus_arg_info),
1455 .receive_cb=equalizer_handle_save_profile},
1456 [EQUALIZER_METHOD_LOAD_PROFILE]{
1457 .method_name="LoadProfile",
1458 .arguments=load_profile_args,
1459 .n_arguments=sizeof(load_profile_args)/sizeof(pa_dbus_arg_info),
1460 .receive_cb=equalizer_handle_load_profile},
1461 [EQUALIZER_METHOD_SAVE_STATE]{
1462 .method_name="SaveState",
1463 .arguments=NULL,
1464 .n_arguments=0,
1465 .receive_cb=equalizer_handle_save_state},
1466 [EQUALIZER_METHOD_GET_PROFILE_NAME]{
1467 .method_name="BaseProfile",
1468 .arguments=base_profile_name_args,
1469 .n_arguments=sizeof(base_profile_name_args)/sizeof(pa_dbus_arg_info),
1470 .receive_cb=equalizer_handle_get_profile_name}
1471 };
1472
1473 static pa_dbus_property_handler equalizer_handlers[EQUALIZER_HANDLER_MAX]={
1474 [EQUALIZER_HANDLER_REVISION]={.property_name="InterfaceRevision",.type="u",.get_cb=equalizer_get_revision,.set_cb=NULL},
1475 [EQUALIZER_HANDLER_SAMPLERATE]{.property_name="SampleRate",.type="u",.get_cb=equalizer_get_sample_rate,.set_cb=NULL},
1476 [EQUALIZER_HANDLER_FILTERSAMPLERATE]{.property_name="FilterSampleRate",.type="u",.get_cb=equalizer_get_filter_rate,.set_cb=NULL},
1477 [EQUALIZER_HANDLER_N_COEFS]{.property_name="NFilterCoefficients",.type="u",.get_cb=equalizer_get_n_coefs,.set_cb=NULL},
1478 [EQUALIZER_HANDLER_N_CHANNELS]{.property_name="NChannels",.type="u",.get_cb=equalizer_get_n_channels,.set_cb=NULL},
1479 };
1480
1481 enum equalizer_signal_index{
1482 EQUALIZER_SIGNAL_FILTER_CHANGED,
1483 EQUALIZER_SIGNAL_SINK_RECONFIGURED,
1484 EQUALIZER_SIGNAL_MAX
1485 };
1486
1487 static pa_dbus_signal_info equalizer_signals[EQUALIZER_SIGNAL_MAX]={
1488 [EQUALIZER_SIGNAL_FILTER_CHANGED]={.name="FilterChanged", .arguments=NULL, .n_arguments=0},
1489 [EQUALIZER_SIGNAL_SINK_RECONFIGURED]={.name="SinkReconfigured", .arguments=NULL, .n_arguments=0},
1490 };
1491
1492 static pa_dbus_interface_info equalizer_info={
1493 .name=EQUALIZER_IFACE,
1494 .method_handlers=equalizer_methods,
1495 .n_method_handlers=EQUALIZER_METHOD_MAX,
1496 .property_handlers=equalizer_handlers,
1497 .n_property_handlers=EQUALIZER_HANDLER_MAX,
1498 .get_all_properties_cb=equalizer_get_all,
1499 .signals=equalizer_signals,
1500 .n_signals=EQUALIZER_SIGNAL_MAX
1501 };
1502
1503 void dbus_init(struct userdata *u){
1504 uint32_t dummy;
1505 DBusMessage *signal = NULL;
1506 pa_idxset *sink_list = NULL;
1507 u->dbus_protocol=pa_dbus_protocol_get(u->sink->core);
1508 u->dbus_path=pa_sprintf_malloc("/org/pulseaudio/core1/sink%d", u->sink->index);
1509
1510 pa_dbus_protocol_add_interface(u->dbus_protocol, u->dbus_path, &equalizer_info, u);
1511 sink_list = pa_shared_get(u->sink->core, SINKLIST);
1512 u->database = pa_shared_get(u->sink->core, EQDB);
1513 if(sink_list == NULL){
1514 char *dbname;
1515 sink_list=pa_idxset_new(&pa_idxset_trivial_hash_func, &pa_idxset_trivial_compare_func);
1516 pa_shared_set(u->sink->core, SINKLIST, sink_list);
1517 pa_assert_se(dbname = pa_state_path("equalizer-presets", FALSE));
1518 pa_assert_se(u->database = pa_database_open(dbname, TRUE));
1519 pa_xfree(dbname);
1520 pa_shared_set(u->sink->core, EQDB, u->database);
1521 pa_dbus_protocol_add_interface(u->dbus_protocol, MANAGER_PATH, &manager_info, u->sink->core);
1522 pa_dbus_protocol_register_extension(u->dbus_protocol, EXTNAME);
1523 }
1524 pa_idxset_put(sink_list, u, &dummy);
1525
1526 pa_assert_se((signal = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_SINK_ADDED].name)));
1527 dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &u->dbus_path, DBUS_TYPE_INVALID);
1528 pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
1529 dbus_message_unref(signal);
1530 }
1531
1532 void dbus_done(struct userdata *u){
1533 pa_idxset *sink_list;
1534 uint32_t dummy;
1535
1536 DBusMessage *signal = NULL;
1537 pa_assert_se((signal = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_SINK_REMOVED].name)));
1538 dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &u->dbus_path, DBUS_TYPE_INVALID);
1539 pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
1540 dbus_message_unref(signal);
1541
1542 pa_assert_se(sink_list=pa_shared_get(u->sink->core,SINKLIST));
1543 pa_idxset_remove_by_data(sink_list,u,&dummy);
1544 if(pa_idxset_size(sink_list)==0){
1545 pa_dbus_protocol_unregister_extension(u->dbus_protocol, EXTNAME);
1546 pa_dbus_protocol_remove_interface(u->dbus_protocol, MANAGER_PATH, manager_info.name);
1547 pa_shared_remove(u->sink->core, EQDB);
1548 pa_database_close(u->database);
1549 pa_shared_remove(u->sink->core, SINKLIST);
1550 pa_xfree(sink_list);
1551 }
1552 pa_dbus_protocol_remove_interface(u->dbus_protocol, u->dbus_path, equalizer_info.name);
1553 pa_xfree(u->dbus_path);
1554 pa_dbus_protocol_unref(u->dbus_protocol);
1555 }
1556
1557 void manager_handle_remove_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
1558 DBusError error;
1559 pa_core *c = (pa_core *)_u;
1560 DBusMessage *signal = NULL;
1561 pa_dbus_protocol *dbus_protocol;
1562 char *name;
1563 pa_assert(conn);
1564 pa_assert(msg);
1565 pa_assert(c);
1566 dbus_error_init(&error);
1567 if(!dbus_message_get_args(msg, &error,
1568 DBUS_TYPE_STRING, &name,
1569 DBUS_TYPE_INVALID)){
1570 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
1571 dbus_error_free(&error);
1572 return;
1573 }
1574 remove_profile(c,name);
1575 pa_dbus_send_empty_reply(conn, msg);
1576
1577 pa_assert_se((signal = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_PROFILES_CHANGED].name)));
1578 dbus_protocol = pa_dbus_protocol_get(c);
1579 pa_dbus_protocol_send_signal(dbus_protocol, signal);
1580 pa_dbus_protocol_unref(dbus_protocol);
1581 dbus_message_unref(signal);
1582 }
1583
1584 void manager_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u){
1585 uint32_t rev=1;
1586 pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &rev);
1587 }
1588
1589 static void get_sinks(pa_core *u, char ***names, unsigned *n_sinks){
1590 void *iter = NULL;
1591 struct userdata *sink_u = NULL;
1592 uint32_t dummy;
1593 pa_idxset *sink_list;
1594 pa_assert(u);
1595 pa_assert(names);
1596 pa_assert(n_sinks);
1597
1598 pa_assert_se(sink_list = pa_shared_get(u, SINKLIST));
1599 *n_sinks = (unsigned) pa_idxset_size(sink_list);
1600 *names = *n_sinks > 0 ? pa_xnew0(char *,*n_sinks) : NULL;
1601 for(uint32_t i = 0; i < *n_sinks; ++i){
1602 sink_u = (struct userdata *) pa_idxset_iterate(sink_list, &iter, &dummy);
1603 (*names)[i] = pa_xstrdup(sink_u->dbus_path);
1604 }
1605 }
1606
1607 void manager_get_sinks(DBusConnection *conn, DBusMessage *msg, void *_u){
1608 unsigned n;
1609 char **names = NULL;
1610 pa_assert(conn);
1611 pa_assert(msg);
1612 pa_assert(_u);
1613
1614 get_sinks((pa_core *) _u, &names, &n);
1615 pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, names, n);
1616 for(unsigned i = 0; i < n; ++i){
1617 pa_xfree(names[i]);
1618 }
1619 pa_xfree(names);
1620 }
1621
1622 static void get_profiles(pa_core *c, char ***names, unsigned *n){
1623 char *name;
1624 pa_database *database;
1625 pa_datum key, next_key;
1626 pa_strlist *head=NULL, *iter;
1627 pa_bool_t done;
1628 pa_assert_se(database = pa_shared_get(c, EQDB));
1629
1630 pa_assert(c);
1631 pa_assert(names);
1632 pa_assert(n);
1633 done = !pa_database_first(database, &key, NULL);
1634 *n = 0;
1635 while(!done){
1636 done = !pa_database_next(database, &key, &next_key, NULL);
1637 name=pa_xmalloc(key.size + 1);
1638 memcpy(name, key.data, key.size);
1639 name[key.size] = '\0';
1640 pa_datum_free(&key);
1641 head = pa_strlist_prepend(head, name);
1642 pa_xfree(name);
1643 key = next_key;
1644 (*n)++;
1645 }
1646 (*names) = *n > 0 ? pa_xnew0(char *, *n) : NULL;
1647 iter=head;
1648 for(unsigned i = 0; i < *n; ++i){
1649 (*names)[*n - 1 - i] = pa_xstrdup(pa_strlist_data(iter));
1650 iter = pa_strlist_next(iter);
1651 }
1652 pa_strlist_free(head);
1653 }
1654
1655 void manager_get_profiles(DBusConnection *conn, DBusMessage *msg, void *_u){
1656 char **names;
1657 unsigned n;
1658 pa_assert(conn);
1659 pa_assert(msg);
1660 pa_assert(_u);
1661
1662 get_profiles((pa_core *)_u, &names, &n);
1663 pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_STRING, names, n);
1664 for(unsigned i = 0; i < n; ++i){
1665 pa_xfree(names[i]);
1666 }
1667 pa_xfree(names);
1668 }
1669
1670 void manager_get_all(DBusConnection *conn, DBusMessage *msg, void *_u){
1671 pa_core *c;
1672 char **names = NULL;
1673 unsigned n;
1674 DBusMessage *reply = NULL;
1675 DBusMessageIter msg_iter, dict_iter;
1676 uint32_t rev;
1677 pa_assert(conn);
1678 pa_assert(msg);
1679 pa_assert_se(c = _u);
1680
1681 pa_assert_se((reply = dbus_message_new_method_return(msg)));
1682 dbus_message_iter_init_append(reply, &msg_iter);
1683 pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
1684
1685 rev = 1;
1686 pa_dbus_append_basic_variant_dict_entry(&dict_iter, manager_handlers[MANAGER_HANDLER_REVISION].property_name, DBUS_TYPE_UINT32, &rev);
1687
1688 get_sinks(c, &names, &n);
1689 pa_dbus_append_basic_array_variant_dict_entry(&dict_iter,manager_handlers[MANAGER_HANDLER_EQUALIZED_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, names, n);
1690 for(unsigned i = 0; i < n; ++i){
1691 pa_xfree(names[i]);
1692 }
1693 pa_xfree(names);
1694
1695 get_profiles(c, &names, &n);
1696 pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, manager_handlers[MANAGER_HANDLER_PROFILES].property_name, DBUS_TYPE_STRING, names, n);
1697 for(unsigned i = 0; i < n; ++i){
1698 pa_xfree(names[i]);
1699 }
1700 pa_xfree(names);
1701 pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
1702 pa_assert_se(dbus_connection_send(conn, reply, NULL));
1703 dbus_message_unref(reply);
1704 }
1705
1706 void equalizer_handle_seed_filter(DBusConnection *conn, DBusMessage *msg, void *_u) {
1707 struct userdata *u=(struct userdata *) _u;
1708 DBusError error;
1709 DBusMessage *signal = NULL;
1710 float *ys;
1711 uint32_t *xs, channel, r_channel;
1712 double *_ys, preamp;
1713 unsigned x_npoints, y_npoints, a_i;
1714 float *H;
1715 pa_bool_t points_good = TRUE;
1716 pa_assert(conn);
1717 pa_assert(msg);
1718 pa_assert(u);
1719
1720 dbus_error_init(&error);
1721
1722 if(!dbus_message_get_args(msg, &error,
1723 DBUS_TYPE_UINT32, &channel,
1724 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &xs, &x_npoints,
1725 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &_ys, &y_npoints,
1726 DBUS_TYPE_DOUBLE, &preamp,
1727 DBUS_TYPE_INVALID)){
1728 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
1729 dbus_error_free(&error);
1730 return;
1731 }
1732 if(channel > u->channels){
1733 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
1734 dbus_error_free(&error);
1735 return;
1736 }
1737 for(size_t i = 0; i < x_npoints; ++i){
1738 if(xs[i] >= FILTER_SIZE){
1739 points_good = FALSE;
1740 break;
1741 }
1742 }
1743 if(!is_monotonic(xs, x_npoints) || !points_good){
1744 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs must be monotonic and 0<=x<=%ld", u->fft_size / 2);
1745 dbus_error_free(&error);
1746 return;
1747 }else if(x_npoints != y_npoints || x_npoints < 2 || x_npoints > FILTER_SIZE ){
1748 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs and ys must be the same length and 2<=l<=%ld!", FILTER_SIZE);
1749 dbus_error_free(&error);
1750 return;
1751 }else if(xs[0] != 0 || xs[x_npoints - 1] != u->fft_size / 2){
1752 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs[0] must be 0 and xs[-1]=fft_size/2");
1753 dbus_error_free(&error);
1754 return;
1755 }
1756
1757 ys = pa_xmalloc(x_npoints * sizeof(float));
1758 for(uint32_t i = 0; i < x_npoints; ++i){
1759 ys[i] = (float) _ys[i];
1760 }
1761 r_channel = channel == u->channels ? 0 : channel;
1762 a_i = pa_aupdate_write_begin(u->a_H[r_channel]);
1763 H = u->Hs[r_channel][a_i];
1764 u->Xs[r_channel][a_i] = preamp;
1765 interpolate(H, FILTER_SIZE, xs, ys, x_npoints);
1766 fix_filter(H, u->fft_size);
1767 if(channel == u->channels){
1768 for(size_t c = 1; c < u->channels; ++c){
1769 unsigned b_i = pa_aupdate_write_begin(u->a_H[c]);
1770 float *H_p = u->Hs[c][b_i];
1771 u->Xs[c][b_i] = preamp;
1772 memcpy(H_p, H, FILTER_SIZE * sizeof(float));
1773 pa_aupdate_write_end(u->a_H[c]);
1774 }
1775 }
1776 pa_aupdate_write_end(u->a_H[r_channel]);
1777 pa_xfree(ys);
1778
1779
1780 pa_dbus_send_empty_reply(conn, msg);
1781
1782 pa_assert_se((signal = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
1783 pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
1784 dbus_message_unref(signal);
1785 }
1786
1787 void equalizer_handle_get_filter_points(DBusConnection *conn, DBusMessage *msg, void *_u) {
1788 struct userdata *u = (struct userdata *) _u;
1789 uint32_t *xs, channel, r_channel;
1790 double *ys, preamp;
1791 unsigned x_npoints, a_i;
1792 float *H;
1793 pa_bool_t points_good=TRUE;
1794 DBusMessage *reply = NULL;
1795 DBusMessageIter msg_iter;
1796 DBusError error;
1797
1798 pa_assert(conn);
1799 pa_assert(msg);
1800 pa_assert(u);
1801
1802 dbus_error_init(&error);
1803 if(!dbus_message_get_args(msg, &error,
1804 DBUS_TYPE_UINT32, &channel,
1805 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &xs, &x_npoints,
1806 DBUS_TYPE_INVALID)){
1807 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
1808 dbus_error_free(&error);
1809 return;
1810 }
1811 if(channel > u->channels){
1812 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
1813 dbus_error_free(&error);
1814 return;
1815 }
1816
1817 for(size_t i = 0; i < x_npoints; ++i){
1818 if(xs[i] >= FILTER_SIZE){
1819 points_good=FALSE;
1820 break;
1821 }
1822 }
1823
1824 if(x_npoints > FILTER_SIZE || !points_good){
1825 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs indices/length must be <= %ld!", FILTER_SIZE);
1826 dbus_error_free(&error);
1827 return;
1828 }
1829
1830 r_channel = channel == u->channels ? 0 : channel;
1831 ys = pa_xmalloc(x_npoints * sizeof(double));
1832 a_i = pa_aupdate_read_begin(u->a_H[r_channel]);
1833 H = u->Hs[r_channel][a_i];
1834 preamp = u->Xs[r_channel][a_i];
1835 for(uint32_t i = 0; i < x_npoints; ++i){
1836 ys[i] = H[xs[i]] * u->fft_size;
1837 }
1838 pa_aupdate_read_end(u->a_H[r_channel]);
1839
1840 pa_assert_se((reply = dbus_message_new_method_return(msg)));
1841 dbus_message_iter_init_append(reply, &msg_iter);
1842
1843 pa_dbus_append_basic_array(&msg_iter, DBUS_TYPE_DOUBLE, ys, x_npoints);
1844 pa_dbus_append_basic_variant(&msg_iter, DBUS_TYPE_DOUBLE, &preamp);
1845
1846 pa_assert_se(dbus_connection_send(conn, reply, NULL));
1847 dbus_message_unref(reply);
1848 pa_xfree(ys);
1849 }
1850
1851 static void get_filter(struct userdata *u, size_t channel, double **H_, double *preamp){
1852 float *H;
1853 unsigned a_i;
1854 size_t r_channel = channel == u->channels ? 0 : channel;
1855 *H_ = pa_xnew0(double, FILTER_SIZE);
1856 a_i = pa_aupdate_read_begin(u->a_H[r_channel]);
1857 H = u->Hs[r_channel][a_i];
1858 for(size_t i = 0;i < FILTER_SIZE; ++i){
1859 (*H_)[i] = H[i] * u->fft_size;
1860 }
1861 *preamp = u->Xs[r_channel][a_i];
1862
1863 pa_aupdate_read_end(u->a_H[r_channel]);
1864 }
1865
1866 void equalizer_handle_get_filter(DBusConnection *conn, DBusMessage *msg, void *_u){
1867 struct userdata *u;
1868 unsigned n_coefs;
1869 uint32_t channel;
1870 double *H_, preamp;
1871 DBusMessage *reply = NULL;
1872 DBusMessageIter msg_iter;
1873 DBusError error;
1874 pa_assert_se(u = (struct userdata *) _u);
1875 pa_assert(conn);
1876 pa_assert(msg);
1877
1878 dbus_error_init(&error);
1879 if(!dbus_message_get_args(msg, &error,
1880 DBUS_TYPE_UINT32, &channel,
1881 DBUS_TYPE_INVALID)){
1882 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
1883 dbus_error_free(&error);
1884 return;
1885 }
1886 if(channel > u->channels){
1887 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
1888 dbus_error_free(&error);
1889 return;
1890 }
1891
1892 n_coefs = CHANNEL_PROFILE_SIZE;
1893 pa_assert(conn);
1894 pa_assert(msg);
1895 get_filter(u, channel, &H_, &preamp);
1896 pa_assert_se((reply = dbus_message_new_method_return(msg)));
1897 dbus_message_iter_init_append(reply, &msg_iter);
1898
1899 pa_dbus_append_basic_array(&msg_iter, DBUS_TYPE_DOUBLE, H_, n_coefs);
1900 pa_dbus_append_basic_variant(&msg_iter, DBUS_TYPE_DOUBLE, &preamp);
1901
1902 pa_assert_se(dbus_connection_send(conn, reply, NULL));
1903 dbus_message_unref(reply);
1904 pa_xfree(H_);
1905 }
1906
1907 static void set_filter(struct userdata *u, size_t channel, double *H_, double preamp){
1908 unsigned a_i;
1909 size_t r_channel = channel == u->channels ? 0 : channel;
1910 float *H;
1911 //all channels
1912 a_i = pa_aupdate_write_begin(u->a_H[r_channel]);
1913 u->Xs[r_channel][a_i] = (float) preamp;
1914 H = u->Hs[r_channel][a_i];
1915 for(size_t i = 0; i < FILTER_SIZE; ++i){
1916 H[i] = (float) H_[i];
1917 }
1918 fix_filter(H, u->fft_size);
1919 if(channel == u->channels){
1920 for(size_t c = 1; c < u->channels; ++c){
1921 unsigned b_i = pa_aupdate_write_begin(u->a_H[c]);
1922 u->Xs[c][b_i] = u->Xs[r_channel][a_i];
1923 memcpy(u->Hs[c][b_i], u->Hs[r_channel][a_i], FILTER_SIZE * sizeof(float));
1924 pa_aupdate_write_end(u->a_H[c]);
1925 }
1926 }
1927 pa_aupdate_write_end(u->a_H[r_channel]);
1928 }
1929
1930 void equalizer_handle_set_filter(DBusConnection *conn, DBusMessage *msg, void *_u){
1931 struct userdata *u;
1932 double *H, preamp;
1933 uint32_t channel;
1934 unsigned _n_coefs;
1935 DBusMessage *signal = NULL;
1936 DBusError error;
1937 pa_assert_se(u = (struct userdata *) _u);
1938 pa_assert(conn);
1939 pa_assert(msg);
1940
1941 dbus_error_init(&error);
1942 if(!dbus_message_get_args(msg, &error,
1943 DBUS_TYPE_UINT32, &channel,
1944 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &H, &_n_coefs,
1945 DBUS_TYPE_DOUBLE, &preamp,
1946 DBUS_TYPE_INVALID)){
1947 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
1948 dbus_error_free(&error);
1949 return;
1950 }
1951 if(channel > u->channels){
1952 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
1953 dbus_error_free(&error);
1954 return;
1955 }
1956 if(_n_coefs != FILTER_SIZE){
1957 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "This filter takes exactly %ld coefficients, you gave %d", FILTER_SIZE, _n_coefs);
1958 return;
1959 }
1960 set_filter(u, channel, H, preamp);
1961
1962 pa_dbus_send_empty_reply(conn, msg);
1963
1964 pa_assert_se((signal = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
1965 pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
1966 dbus_message_unref(signal);
1967 }
1968
1969 void equalizer_handle_save_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
1970 struct userdata *u = (struct userdata *) _u;
1971 char *name;
1972 uint32_t channel, r_channel;
1973 DBusMessage *signal = NULL;
1974 DBusError error;
1975 pa_assert(conn);
1976 pa_assert(msg);
1977 pa_assert(u);
1978 dbus_error_init(&error);
1979
1980 if(!dbus_message_get_args(msg, &error,
1981 DBUS_TYPE_UINT32, &channel,
1982 DBUS_TYPE_STRING, &name,
1983 DBUS_TYPE_INVALID)){
1984 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
1985 dbus_error_free(&error);
1986 return;
1987 }
1988 if(channel > u->channels){
1989 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
1990 dbus_error_free(&error);
1991 return;
1992 }
1993 r_channel = channel == u->channels ? 0 : channel;
1994 save_profile(u, r_channel, name);
1995 pa_dbus_send_empty_reply(conn, msg);
1996
1997 pa_assert_se((signal = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_PROFILES_CHANGED].name)));
1998 pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
1999 dbus_message_unref(signal);
2000 }
2001
2002 void equalizer_handle_load_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
2003 struct userdata *u = (struct userdata *) _u;
2004 char *name;
2005 DBusError error;
2006 uint32_t channel, r_channel;
2007 const char *err_msg = NULL;
2008 DBusMessage *signal = NULL;
2009
2010 pa_assert(conn);
2011 pa_assert(msg);
2012 pa_assert(u);
2013 dbus_error_init(&error);
2014
2015 if(!dbus_message_get_args(msg, &error,
2016 DBUS_TYPE_UINT32, &channel,
2017 DBUS_TYPE_STRING, &name,
2018 DBUS_TYPE_INVALID)){
2019 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
2020 dbus_error_free(&error);
2021 return;
2022 }
2023 if(channel > u->channels){
2024 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
2025 dbus_error_free(&error);
2026 return;
2027 }
2028 r_channel = channel == u->channels ? 0 : channel;
2029
2030 err_msg = load_profile(u, r_channel, name);
2031 if(err_msg != NULL){
2032 pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "error loading profile %s: %s", name, err_msg);
2033 dbus_error_free(&error);
2034 return;
2035 }
2036 if(channel == u->channels){
2037 for(uint32_t c = 1; c < u->channels; ++c){
2038 load_profile(u, c, name);
2039 }
2040 }
2041 pa_dbus_send_empty_reply(conn, msg);
2042
2043 pa_assert_se((signal = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
2044 pa_dbus_protocol_send_signal(u->dbus_protocol, signal);
2045 dbus_message_unref(signal);
2046 }
2047
2048 void equalizer_handle_save_state(DBusConnection *conn, DBusMessage *msg, void *_u) {
2049 struct userdata *u = (struct userdata *) _u;
2050 pa_assert(conn);
2051 pa_assert(msg);
2052 pa_assert(u);
2053
2054 save_state(u);
2055 pa_dbus_send_empty_reply(conn, msg);
2056 }
2057
2058 void equalizer_handle_get_profile_name(DBusConnection *conn, DBusMessage *msg, void *_u){
2059 struct userdata *u = (struct userdata *) _u;
2060 DBusError error;
2061 uint32_t channel, r_channel;
2062
2063 pa_assert(conn);
2064 pa_assert(msg);
2065 pa_assert(u);
2066 dbus_error_init(&error);
2067
2068 if(!dbus_message_get_args(msg, &error,
2069 DBUS_TYPE_UINT32, &channel,
2070 DBUS_TYPE_INVALID)){
2071 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
2072 dbus_error_free(&error);
2073 return;
2074 }
2075 if(channel > u->channels){
2076 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
2077 dbus_error_free(&error);
2078 return;
2079 }
2080 r_channel = channel == u->channels ? 0 : channel;
2081 pa_assert(u->base_profiles[r_channel]);
2082 pa_dbus_send_basic_value_reply(conn,msg, DBUS_TYPE_STRING, &u->base_profiles[r_channel]);
2083 }
2084
2085 void equalizer_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u){
2086 uint32_t rev=1;
2087 pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &rev);
2088 }
2089
2090 void equalizer_get_n_channels(DBusConnection *conn, DBusMessage *msg, void *_u){
2091 struct userdata *u;
2092 uint32_t channels;
2093 pa_assert_se(u = (struct userdata *) _u);
2094 pa_assert(conn);
2095 pa_assert(msg);
2096
2097 channels = (uint32_t) u->channels;
2098 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &channels);
2099 }
2100
2101 void equalizer_get_n_coefs(DBusConnection *conn, DBusMessage *msg, void *_u){
2102 struct userdata *u;
2103 uint32_t n_coefs;
2104 pa_assert_se(u = (struct userdata *) _u);
2105 pa_assert(conn);
2106 pa_assert(msg);
2107
2108 n_coefs = (uint32_t) CHANNEL_PROFILE_SIZE;
2109 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &n_coefs);
2110 }
2111
2112 void equalizer_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *_u){
2113 struct userdata *u;
2114 uint32_t rate;
2115 pa_assert_se(u = (struct userdata *) _u);
2116 pa_assert(conn);
2117 pa_assert(msg);
2118
2119 rate = (uint32_t) u->sink->sample_spec.rate;
2120 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &rate);
2121 }
2122
2123 void equalizer_get_filter_rate(DBusConnection *conn, DBusMessage *msg, void *_u){
2124 struct userdata *u;
2125 uint32_t fft_size;
2126 pa_assert_se(u = (struct userdata *) _u);
2127 pa_assert(conn);
2128 pa_assert(msg);
2129
2130 fft_size = (uint32_t) u->fft_size;
2131 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &fft_size);
2132 }
2133
2134 void equalizer_get_all(DBusConnection *conn, DBusMessage *msg, void *_u){
2135 struct userdata *u;
2136 DBusMessage *reply = NULL;
2137 DBusMessageIter msg_iter, dict_iter;
2138 uint32_t rev, n_coefs, rate, fft_size, channels;
2139 pa_assert_se(u = (struct userdata *) _u);
2140 pa_assert(msg);
2141
2142 rev = 1;
2143 n_coefs = (uint32_t) CHANNEL_PROFILE_SIZE;
2144 rate = (uint32_t) u->sink->sample_spec.rate;
2145 fft_size = (uint32_t) u->fft_size;
2146 channels = (uint32_t) u->channels;
2147
2148 pa_assert_se((reply = dbus_message_new_method_return(msg)));
2149 dbus_message_iter_init_append(reply, &msg_iter);
2150 pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
2151
2152 pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_REVISION].property_name, DBUS_TYPE_UINT32, &rev);
2153 pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_SAMPLERATE].property_name, DBUS_TYPE_UINT32, &rate);
2154 pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_FILTERSAMPLERATE].property_name, DBUS_TYPE_UINT32, &fft_size);
2155 pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_N_COEFS].property_name, DBUS_TYPE_UINT32, &n_coefs);
2156 pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_N_CHANNELS].property_name, DBUS_TYPE_UINT32, &channels);
2157
2158 pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
2159 pa_assert_se(dbus_connection_send(conn, reply, NULL));
2160 dbus_message_unref(reply);
2161 }