2 This file is part of PulseAudio.
4 Copyright 2010 Intel Corporation
5 Contributor: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
6 Copyright 2012 Niels Ole Salscheider <niels_ole@salscheider-online.de>
8 PulseAudio is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published
10 by the Free Software Foundation; either version 2.1 of the License,
11 or (at your option) any later version.
13 PulseAudio is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with PulseAudio; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 #include <pulse/gccmacro.h>
29 #include <pulse/xmalloc.h>
31 #include <pulsecore/i18n.h>
32 #include <pulsecore/namereg.h>
33 #include <pulsecore/sink.h>
34 #include <pulsecore/module.h>
35 #include <pulsecore/core-util.h>
36 #include <pulsecore/modargs.h>
37 #include <pulsecore/log.h>
38 #include <pulsecore/rtpoll.h>
39 #include <pulsecore/sample-util.h>
40 #include <pulsecore/ltdl-helper.h>
41 #include <pulsecore/sound-file.h>
42 #include <pulsecore/resampler.h>
46 #include "module-virtual-surround-sink-symdef.h"
48 PA_MODULE_AUTHOR("Niels Ole Salscheider");
49 PA_MODULE_DESCRIPTION(_("Virtual surround sink"));
50 PA_MODULE_VERSION(PACKAGE_VERSION
);
51 PA_MODULE_LOAD_ONCE(false);
53 _("sink_name=<name for the sink> "
54 "sink_properties=<properties for the sink> "
55 "master=<name of sink to filter> "
56 "format=<sample format> "
58 "channels=<number of channels> "
59 "channel_map=<channel map> "
60 "use_volume_sharing=<yes or no> "
61 "force_flat_volume=<yes or no> "
62 "hrir=/path/to/left_hrir.wav "
65 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
70 /* FIXME: Uncomment this and take "autoloaded" as a modarg if this is a filter */
71 /* bool autoloaded; */
74 pa_sink_input
*sink_input
;
76 pa_memblockq
*memblockq
;
80 unsigned hrir_channels
;
84 unsigned *mapping_left
;
85 unsigned *mapping_right
;
87 unsigned hrir_samples
;
91 int input_buffer_offset
;
94 static const char* const valid_modargs
[] = {
102 "use_volume_sharing",
108 /* Called from I/O thread context */
109 static int sink_process_msg_cb(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
110 struct userdata
*u
= PA_SINK(o
)->userdata
;
114 case PA_SINK_MESSAGE_GET_LATENCY
:
116 /* The sink is _put() before the sink input is, so let's
117 * make sure we don't access it in that time. Also, the
118 * sink input is first shut down, the sink second. */
119 if (!PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
) ||
120 !PA_SINK_INPUT_IS_LINKED(u
->sink_input
->thread_info
.state
)) {
121 *((pa_usec_t
*) data
) = 0;
125 *((pa_usec_t
*) data
) =
127 /* Get the latency of the master sink */
128 pa_sink_get_latency_within_thread(u
->sink_input
->sink
) +
130 /* Add the latency internal to our sink input on top */
131 pa_bytes_to_usec(pa_memblockq_get_length(u
->sink_input
->thread_info
.render_memblockq
), &u
->sink_input
->sink
->sample_spec
);
136 return pa_sink_process_msg(o
, code
, data
, offset
, chunk
);
139 /* Called from main context */
140 static int sink_set_state_cb(pa_sink
*s
, pa_sink_state_t state
) {
143 pa_sink_assert_ref(s
);
144 pa_assert_se(u
= s
->userdata
);
146 if (!PA_SINK_IS_LINKED(state
) ||
147 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u
->sink_input
)))
150 pa_sink_input_cork(u
->sink_input
, state
== PA_SINK_SUSPENDED
);
154 /* Called from I/O thread context */
155 static void sink_request_rewind_cb(pa_sink
*s
) {
158 pa_sink_assert_ref(s
);
159 pa_assert_se(u
= s
->userdata
);
161 if (!PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
) ||
162 !PA_SINK_INPUT_IS_LINKED(u
->sink_input
->thread_info
.state
))
165 /* Just hand this one over to the master sink */
166 pa_sink_input_request_rewind(u
->sink_input
,
167 s
->thread_info
.rewind_nbytes
+
168 pa_memblockq_get_length(u
->memblockq
), true, false, false);
171 /* Called from I/O thread context */
172 static void sink_update_requested_latency_cb(pa_sink
*s
) {
175 pa_sink_assert_ref(s
);
176 pa_assert_se(u
= s
->userdata
);
178 if (!PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
) ||
179 !PA_SINK_INPUT_IS_LINKED(u
->sink_input
->thread_info
.state
))
182 /* Just hand this one over to the master sink */
183 pa_sink_input_set_requested_latency_within_thread(
185 pa_sink_get_requested_latency_within_thread(s
));
188 /* Called from main context */
189 static void sink_set_volume_cb(pa_sink
*s
) {
192 pa_sink_assert_ref(s
);
193 pa_assert_se(u
= s
->userdata
);
195 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s
)) ||
196 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u
->sink_input
)))
199 pa_sink_input_set_volume(u
->sink_input
, &s
->real_volume
, s
->save_volume
, true);
202 /* Called from main context */
203 static void sink_set_mute_cb(pa_sink
*s
) {
206 pa_sink_assert_ref(s
);
207 pa_assert_se(u
= s
->userdata
);
209 if (!PA_SINK_IS_LINKED(pa_sink_get_state(s
)) ||
210 !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u
->sink_input
)))
213 pa_sink_input_set_mute(u
->sink_input
, s
->muted
, s
->save_muted
);
216 /* Called from I/O thread context */
217 static int sink_input_pop_cb(pa_sink_input
*i
, size_t nbytes
, pa_memchunk
*chunk
) {
224 float sum_right
, sum_left
;
225 float current_sample
;
227 pa_sink_input_assert_ref(i
);
229 pa_assert_se(u
= i
->userdata
);
231 /* Hmm, process any rewind request that might be queued up */
232 pa_sink_process_rewind(u
->sink
, 0);
234 while (pa_memblockq_peek(u
->memblockq
, &tchunk
) < 0) {
237 pa_sink_render(u
->sink
, nbytes
* u
->sink_fs
/ u
->fs
, &nchunk
);
238 pa_memblockq_push(u
->memblockq
, &nchunk
);
239 pa_memblock_unref(nchunk
.memblock
);
242 tchunk
.length
= PA_MIN(nbytes
* u
->sink_fs
/ u
->fs
, tchunk
.length
);
243 pa_assert(tchunk
.length
> 0);
245 n
= (unsigned) (tchunk
.length
/ u
->sink_fs
);
250 chunk
->length
= n
* u
->fs
;
251 chunk
->memblock
= pa_memblock_new(i
->sink
->core
->mempool
, chunk
->length
);
253 pa_memblockq_drop(u
->memblockq
, n
* u
->sink_fs
);
255 src
= pa_memblock_acquire_chunk(&tchunk
);
256 dst
= pa_memblock_acquire(chunk
->memblock
);
258 for (l
= 0; l
< n
; l
++) {
259 memcpy(((char*) u
->input_buffer
) + u
->input_buffer_offset
* u
->sink_fs
, ((char *) src
) + l
* u
->sink_fs
, u
->sink_fs
);
264 /* fold the input buffer with the impulse response */
265 for (j
= 0; j
< u
->hrir_samples
; j
++) {
266 for (k
= 0; k
< u
->channels
; k
++) {
267 current_sample
= u
->input_buffer
[((u
->input_buffer_offset
+ j
) % u
->hrir_samples
) * u
->channels
+ k
];
269 sum_left
+= current_sample
* u
->hrir_data
[j
* u
->hrir_channels
+ u
->mapping_left
[k
]];
270 sum_right
+= current_sample
* u
->hrir_data
[j
* u
->hrir_channels
+ u
->mapping_right
[k
]];
274 dst
[2 * l
] = PA_CLAMP_UNLIKELY(sum_left
, -1.0f
, 1.0f
);
275 dst
[2 * l
+ 1] = PA_CLAMP_UNLIKELY(sum_right
, -1.0f
, 1.0f
);
277 u
->input_buffer_offset
--;
278 if (u
->input_buffer_offset
< 0)
279 u
->input_buffer_offset
+= u
->hrir_samples
;
282 pa_memblock_release(tchunk
.memblock
);
283 pa_memblock_release(chunk
->memblock
);
285 pa_memblock_unref(tchunk
.memblock
);
290 /* Called from I/O thread context */
291 static void sink_input_process_rewind_cb(pa_sink_input
*i
, size_t nbytes
) {
295 pa_sink_input_assert_ref(i
);
296 pa_assert_se(u
= i
->userdata
);
298 if (u
->sink
->thread_info
.rewind_nbytes
> 0) {
301 max_rewrite
= nbytes
* u
->sink_fs
/ u
->fs
+ pa_memblockq_get_length(u
->memblockq
);
302 amount
= PA_MIN(u
->sink
->thread_info
.rewind_nbytes
* u
->sink_fs
/ u
->fs
, max_rewrite
);
303 u
->sink
->thread_info
.rewind_nbytes
= 0;
306 pa_memblockq_seek(u
->memblockq
, - (int64_t) amount
, PA_SEEK_RELATIVE
, true);
308 /* Reset the input buffer */
309 memset(u
->input_buffer
, 0, u
->hrir_samples
* u
->sink_fs
);
310 u
->input_buffer_offset
= 0;
314 pa_sink_process_rewind(u
->sink
, amount
);
315 pa_memblockq_rewind(u
->memblockq
, nbytes
* u
->sink_fs
/ u
->fs
);
318 /* Called from I/O thread context */
319 static void sink_input_update_max_rewind_cb(pa_sink_input
*i
, size_t nbytes
) {
322 pa_sink_input_assert_ref(i
);
323 pa_assert_se(u
= i
->userdata
);
325 /* FIXME: Too small max_rewind:
326 * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
327 pa_memblockq_set_maxrewind(u
->memblockq
, nbytes
* u
->sink_fs
/ u
->fs
);
328 pa_sink_set_max_rewind_within_thread(u
->sink
, nbytes
* u
->sink_fs
/ u
->fs
);
331 /* Called from I/O thread context */
332 static void sink_input_update_max_request_cb(pa_sink_input
*i
, size_t nbytes
) {
335 pa_sink_input_assert_ref(i
);
336 pa_assert_se(u
= i
->userdata
);
338 pa_sink_set_max_request_within_thread(u
->sink
, nbytes
* u
->sink_fs
/ u
->fs
);
341 /* Called from I/O thread context */
342 static void sink_input_update_sink_latency_range_cb(pa_sink_input
*i
) {
345 pa_sink_input_assert_ref(i
);
346 pa_assert_se(u
= i
->userdata
);
348 pa_sink_set_latency_range_within_thread(u
->sink
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
351 /* Called from I/O thread context */
352 static void sink_input_update_sink_fixed_latency_cb(pa_sink_input
*i
) {
355 pa_sink_input_assert_ref(i
);
356 pa_assert_se(u
= i
->userdata
);
358 pa_sink_set_fixed_latency_within_thread(u
->sink
, i
->sink
->thread_info
.fixed_latency
);
361 /* Called from I/O thread context */
362 static void sink_input_detach_cb(pa_sink_input
*i
) {
365 pa_sink_input_assert_ref(i
);
366 pa_assert_se(u
= i
->userdata
);
368 pa_sink_detach_within_thread(u
->sink
);
370 pa_sink_set_rtpoll(u
->sink
, NULL
);
373 /* Called from I/O thread context */
374 static void sink_input_attach_cb(pa_sink_input
*i
) {
377 pa_sink_input_assert_ref(i
);
378 pa_assert_se(u
= i
->userdata
);
380 pa_sink_set_rtpoll(u
->sink
, i
->sink
->thread_info
.rtpoll
);
381 pa_sink_set_latency_range_within_thread(u
->sink
, i
->sink
->thread_info
.min_latency
, i
->sink
->thread_info
.max_latency
);
383 pa_sink_set_fixed_latency_within_thread(u
->sink
, i
->sink
->thread_info
.fixed_latency
);
385 pa_sink_set_max_request_within_thread(u
->sink
, pa_sink_input_get_max_request(i
) * u
->sink_fs
/ u
->fs
);
387 /* FIXME: Too small max_rewind:
388 * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
389 pa_sink_set_max_rewind_within_thread(u
->sink
, pa_sink_input_get_max_rewind(i
) * u
->sink_fs
/ u
->fs
);
391 pa_sink_attach_within_thread(u
->sink
);
394 /* Called from main context */
395 static void sink_input_kill_cb(pa_sink_input
*i
) {
398 pa_sink_input_assert_ref(i
);
399 pa_assert_se(u
= i
->userdata
);
401 /* The order here matters! We first kill the sink input, followed
402 * by the sink. That means the sink callbacks must be protected
403 * against an unconnected sink input! */
404 pa_sink_input_unlink(u
->sink_input
);
405 pa_sink_unlink(u
->sink
);
407 pa_sink_input_unref(u
->sink_input
);
408 u
->sink_input
= NULL
;
410 pa_sink_unref(u
->sink
);
413 pa_module_unload_request(u
->module
, true);
416 /* Called from IO thread context */
417 static void sink_input_state_change_cb(pa_sink_input
*i
, pa_sink_input_state_t state
) {
420 pa_sink_input_assert_ref(i
);
421 pa_assert_se(u
= i
->userdata
);
423 /* If we are added for the first time, ask for a rewinding so that
424 * we are heard right-away. */
425 if (PA_SINK_INPUT_IS_LINKED(state
) &&
426 i
->thread_info
.state
== PA_SINK_INPUT_INIT
) {
427 pa_log_debug("Requesting rewind due to state change.");
428 pa_sink_input_request_rewind(i
, 0, false, true, true);
432 /* Called from main context */
433 static void sink_input_moving_cb(pa_sink_input
*i
, pa_sink
*dest
) {
436 pa_sink_input_assert_ref(i
);
437 pa_assert_se(u
= i
->userdata
);
440 pa_sink_set_asyncmsgq(u
->sink
, dest
->asyncmsgq
);
441 pa_sink_update_flags(u
->sink
, PA_SINK_LATENCY
|PA_SINK_DYNAMIC_LATENCY
, dest
->flags
);
443 pa_sink_set_asyncmsgq(u
->sink
, NULL
);
445 if (u
->auto_desc
&& dest
) {
449 pl
= pa_proplist_new();
450 z
= pa_proplist_gets(dest
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
451 pa_proplist_setf(pl
, PA_PROP_DEVICE_DESCRIPTION
, "Virtual Surround Sink %s on %s",
452 pa_proplist_gets(u
->sink
->proplist
, "device.vsurroundsink.name"), z
? z
: dest
->name
);
454 pa_sink_update_proplist(u
->sink
, PA_UPDATE_REPLACE
, pl
);
455 pa_proplist_free(pl
);
459 /* Called from main context */
460 static void sink_input_volume_changed_cb(pa_sink_input
*i
) {
463 pa_sink_input_assert_ref(i
);
464 pa_assert_se(u
= i
->userdata
);
466 pa_sink_volume_changed(u
->sink
, &i
->volume
);
469 /* Called from main context */
470 static void sink_input_mute_changed_cb(pa_sink_input
*i
) {
473 pa_sink_input_assert_ref(i
);
474 pa_assert_se(u
= i
->userdata
);
476 pa_sink_mute_changed(u
->sink
, i
->muted
);
479 static pa_channel_position_t
mirror_channel(pa_channel_position_t channel
) {
481 case PA_CHANNEL_POSITION_FRONT_LEFT
:
482 return PA_CHANNEL_POSITION_FRONT_RIGHT
;
484 case PA_CHANNEL_POSITION_FRONT_RIGHT
:
485 return PA_CHANNEL_POSITION_FRONT_LEFT
;
487 case PA_CHANNEL_POSITION_REAR_LEFT
:
488 return PA_CHANNEL_POSITION_REAR_RIGHT
;
490 case PA_CHANNEL_POSITION_REAR_RIGHT
:
491 return PA_CHANNEL_POSITION_REAR_LEFT
;
493 case PA_CHANNEL_POSITION_SIDE_LEFT
:
494 return PA_CHANNEL_POSITION_SIDE_RIGHT
;
496 case PA_CHANNEL_POSITION_SIDE_RIGHT
:
497 return PA_CHANNEL_POSITION_SIDE_LEFT
;
499 case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
:
500 return PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
502 case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
:
503 return PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
;
505 case PA_CHANNEL_POSITION_TOP_FRONT_LEFT
:
506 return PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
;
508 case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
:
509 return PA_CHANNEL_POSITION_TOP_FRONT_LEFT
;
511 case PA_CHANNEL_POSITION_TOP_REAR_LEFT
:
512 return PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
514 case PA_CHANNEL_POSITION_TOP_REAR_RIGHT
:
515 return PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
522 int pa__init(pa_module
*m
) {
524 pa_sample_spec ss
, sink_input_ss
;
525 pa_channel_map map
, sink_input_map
;
527 pa_sink
*master
=NULL
;
528 pa_sink_input_new_data sink_input_data
;
529 pa_sink_new_data sink_data
;
530 bool use_volume_sharing
= true;
531 bool force_flat_volume
= false;
534 const char *hrir_file
;
535 unsigned i
, j
, found_channel_left
, found_channel_right
;
536 float hrir_sum
, hrir_max
;
539 pa_sample_spec hrir_ss
;
540 pa_channel_map hrir_map
;
542 pa_sample_spec hrir_temp_ss
;
543 pa_memchunk hrir_temp_chunk
, hrir_temp_chunk_resampled
;
544 pa_resampler
*resampler
;
546 size_t hrir_copied_length
, hrir_total_length
;
548 hrir_temp_chunk
.memblock
= NULL
;
549 hrir_temp_chunk_resampled
.memblock
= NULL
;
553 if (!(ma
= pa_modargs_new(m
->argument
, valid_modargs
))) {
554 pa_log("Failed to parse module arguments.");
558 if (!(master
= pa_namereg_get(m
->core
, pa_modargs_get_value(ma
, "master", NULL
), PA_NAMEREG_SINK
))) {
559 pa_log("Master sink not found");
565 u
= pa_xnew0(struct userdata
, 1);
569 /* Initialize hrir and input buffer */
570 /* this is the hrir file for the left ear! */
571 if (!(hrir_file
= pa_modargs_get_value(ma
, "hrir", NULL
))) {
572 pa_log("The mandatory 'hrir' module argument is missing.");
576 if (pa_sound_file_load(master
->core
->mempool
, hrir_file
, &hrir_temp_ss
, &hrir_map
, &hrir_temp_chunk
, NULL
) < 0) {
577 pa_log("Cannot load hrir file.");
581 /* sample spec / map of hrir */
582 hrir_ss
.format
= PA_SAMPLE_FLOAT32
;
583 hrir_ss
.rate
= master
->sample_spec
.rate
;
584 hrir_ss
.channels
= hrir_temp_ss
.channels
;
586 /* sample spec of sink */
589 if (pa_modargs_get_sample_spec_and_channel_map(ma
, &ss
, &map
, PA_CHANNEL_MAP_DEFAULT
) < 0) {
590 pa_log("Invalid sample format specification or channel map");
593 ss
.format
= PA_SAMPLE_FLOAT32
;
594 hrir_ss
.rate
= ss
.rate
;
595 u
->channels
= ss
.channels
;
597 if (pa_modargs_get_value_boolean(ma
, "use_volume_sharing", &use_volume_sharing
) < 0) {
598 pa_log("use_volume_sharing= expects a boolean argument");
602 if (pa_modargs_get_value_boolean(ma
, "force_flat_volume", &force_flat_volume
) < 0) {
603 pa_log("force_flat_volume= expects a boolean argument");
607 if (use_volume_sharing
&& force_flat_volume
) {
608 pa_log("Flat volume can't be forced when using volume sharing.");
612 /* sample spec / map of sink input */
613 pa_channel_map_init_stereo(&sink_input_map
);
614 sink_input_ss
.channels
= 2;
615 sink_input_ss
.format
= PA_SAMPLE_FLOAT32
;
616 sink_input_ss
.rate
= ss
.rate
;
618 u
->sink_fs
= pa_frame_size(&ss
);
619 u
->fs
= pa_frame_size(&sink_input_ss
);
622 pa_sink_new_data_init(&sink_data
);
623 sink_data
.driver
= __FILE__
;
624 sink_data
.module
= m
;
625 if (!(sink_data
.name
= pa_xstrdup(pa_modargs_get_value(ma
, "sink_name", NULL
))))
626 sink_data
.name
= pa_sprintf_malloc("%s.vsurroundsink", master
->name
);
627 pa_sink_new_data_set_sample_spec(&sink_data
, &ss
);
628 pa_sink_new_data_set_channel_map(&sink_data
, &map
);
629 pa_proplist_sets(sink_data
.proplist
, PA_PROP_DEVICE_MASTER_DEVICE
, master
->name
);
630 pa_proplist_sets(sink_data
.proplist
, PA_PROP_DEVICE_CLASS
, "filter");
631 pa_proplist_sets(sink_data
.proplist
, "device.vsurroundsink.name", sink_data
.name
);
633 if (pa_modargs_get_proplist(ma
, "sink_properties", sink_data
.proplist
, PA_UPDATE_REPLACE
) < 0) {
634 pa_log("Invalid properties");
635 pa_sink_new_data_done(&sink_data
);
639 if ((u
->auto_desc
= !pa_proplist_contains(sink_data
.proplist
, PA_PROP_DEVICE_DESCRIPTION
))) {
642 z
= pa_proplist_gets(master
->proplist
, PA_PROP_DEVICE_DESCRIPTION
);
643 pa_proplist_setf(sink_data
.proplist
, PA_PROP_DEVICE_DESCRIPTION
, "Virtual Surround Sink %s on %s", sink_data
.name
, z
? z
: master
->name
);
646 u
->sink
= pa_sink_new(m
->core
, &sink_data
, (master
->flags
& (PA_SINK_LATENCY
|PA_SINK_DYNAMIC_LATENCY
))
647 | (use_volume_sharing
? PA_SINK_SHARE_VOLUME_WITH_MASTER
: 0));
648 pa_sink_new_data_done(&sink_data
);
651 pa_log("Failed to create sink.");
655 u
->sink
->parent
.process_msg
= sink_process_msg_cb
;
656 u
->sink
->set_state
= sink_set_state_cb
;
657 u
->sink
->update_requested_latency
= sink_update_requested_latency_cb
;
658 u
->sink
->request_rewind
= sink_request_rewind_cb
;
659 pa_sink_set_set_mute_callback(u
->sink
, sink_set_mute_cb
);
660 if (!use_volume_sharing
) {
661 pa_sink_set_set_volume_callback(u
->sink
, sink_set_volume_cb
);
662 pa_sink_enable_decibel_volume(u
->sink
, true);
664 /* Normally this flag would be enabled automatically be we can force it. */
665 if (force_flat_volume
)
666 u
->sink
->flags
|= PA_SINK_FLAT_VOLUME
;
667 u
->sink
->userdata
= u
;
669 pa_sink_set_asyncmsgq(u
->sink
, master
->asyncmsgq
);
671 /* Create sink input */
672 pa_sink_input_new_data_init(&sink_input_data
);
673 sink_input_data
.driver
= __FILE__
;
674 sink_input_data
.module
= m
;
675 pa_sink_input_new_data_set_sink(&sink_input_data
, master
, false);
676 sink_input_data
.origin_sink
= u
->sink
;
677 pa_proplist_setf(sink_input_data
.proplist
, PA_PROP_MEDIA_NAME
, "Virtual Surround Sink Stream from %s", pa_proplist_gets(u
->sink
->proplist
, PA_PROP_DEVICE_DESCRIPTION
));
678 pa_proplist_sets(sink_input_data
.proplist
, PA_PROP_MEDIA_ROLE
, "filter");
679 pa_sink_input_new_data_set_sample_spec(&sink_input_data
, &sink_input_ss
);
680 pa_sink_input_new_data_set_channel_map(&sink_input_data
, &sink_input_map
);
682 pa_sink_input_new(&u
->sink_input
, m
->core
, &sink_input_data
);
683 pa_sink_input_new_data_done(&sink_input_data
);
688 u
->sink_input
->pop
= sink_input_pop_cb
;
689 u
->sink_input
->process_rewind
= sink_input_process_rewind_cb
;
690 u
->sink_input
->update_max_rewind
= sink_input_update_max_rewind_cb
;
691 u
->sink_input
->update_max_request
= sink_input_update_max_request_cb
;
692 u
->sink_input
->update_sink_latency_range
= sink_input_update_sink_latency_range_cb
;
693 u
->sink_input
->update_sink_fixed_latency
= sink_input_update_sink_fixed_latency_cb
;
694 u
->sink_input
->kill
= sink_input_kill_cb
;
695 u
->sink_input
->attach
= sink_input_attach_cb
;
696 u
->sink_input
->detach
= sink_input_detach_cb
;
697 u
->sink_input
->state_change
= sink_input_state_change_cb
;
698 u
->sink_input
->moving
= sink_input_moving_cb
;
699 u
->sink_input
->volume_changed
= use_volume_sharing
? NULL
: sink_input_volume_changed_cb
;
700 u
->sink_input
->mute_changed
= sink_input_mute_changed_cb
;
701 u
->sink_input
->userdata
= u
;
703 u
->sink
->input_to_master
= u
->sink_input
;
705 pa_sink_input_get_silence(u
->sink_input
, &silence
);
706 u
->memblockq
= pa_memblockq_new("module-virtual-surround-sink memblockq", 0, MEMBLOCKQ_MAXLENGTH
, 0, &sink_input_ss
, 1, 1, 0, &silence
);
707 pa_memblock_unref(silence
.memblock
);
710 resampler
= pa_resampler_new(u
->sink
->core
->mempool
, &hrir_temp_ss
, &hrir_map
, &hrir_ss
, &hrir_map
,
711 PA_RESAMPLER_SRC_SINC_BEST_QUALITY
, PA_RESAMPLER_NO_REMAP
);
713 u
->hrir_samples
= hrir_temp_chunk
.length
/ pa_frame_size(&hrir_temp_ss
) * hrir_ss
.rate
/ hrir_temp_ss
.rate
;
714 if (u
->hrir_samples
> 64) {
715 u
->hrir_samples
= 64;
716 pa_log("The (resampled) hrir contains more than 64 samples. Only the first 64 samples will be used to limit processor usage.");
719 hrir_total_length
= u
->hrir_samples
* pa_frame_size(&hrir_ss
);
720 u
->hrir_channels
= hrir_ss
.channels
;
722 u
->hrir_data
= (float *) pa_xmalloc(hrir_total_length
);
723 hrir_copied_length
= 0;
725 /* add silence to the hrir until we get enough samples out of the resampler */
726 while (hrir_copied_length
< hrir_total_length
) {
727 pa_resampler_run(resampler
, &hrir_temp_chunk
, &hrir_temp_chunk_resampled
);
728 if (hrir_temp_chunk
.memblock
!= hrir_temp_chunk_resampled
.memblock
) {
729 /* Silence input block */
730 pa_silence_memblock(hrir_temp_chunk
.memblock
, &hrir_temp_ss
);
733 if (hrir_temp_chunk_resampled
.memblock
) {
735 hrir_data
= (float *) pa_memblock_acquire(hrir_temp_chunk_resampled
.memblock
);
737 if (hrir_total_length
- hrir_copied_length
>= hrir_temp_chunk_resampled
.length
) {
738 memcpy(u
->hrir_data
+ hrir_copied_length
, hrir_data
, hrir_temp_chunk_resampled
.length
);
739 hrir_copied_length
+= hrir_temp_chunk_resampled
.length
;
741 memcpy(u
->hrir_data
+ hrir_copied_length
, hrir_data
, hrir_total_length
- hrir_copied_length
);
742 hrir_copied_length
= hrir_total_length
;
745 pa_memblock_release(hrir_temp_chunk_resampled
.memblock
);
746 pa_memblock_unref(hrir_temp_chunk_resampled
.memblock
);
747 hrir_temp_chunk_resampled
.memblock
= NULL
;
751 pa_resampler_free(resampler
);
753 pa_memblock_unref(hrir_temp_chunk
.memblock
);
754 hrir_temp_chunk
.memblock
= NULL
;
756 if (hrir_map
.channels
< map
.channels
) {
757 pa_log("hrir file does not have enough channels!");
761 /* normalize hrir to avoid clipping */
763 for (i
= 0; i
< u
->hrir_samples
; i
++) {
765 for (j
= 0; j
< u
->hrir_channels
; j
++)
766 hrir_sum
+= fabs(u
->hrir_data
[i
* u
->hrir_channels
+ j
]);
768 if (hrir_sum
> hrir_max
)
772 for (i
= 0; i
< u
->hrir_samples
; i
++) {
773 for (j
= 0; j
< u
->hrir_channels
; j
++)
774 u
->hrir_data
[i
* u
->hrir_channels
+ j
] /= hrir_max
* 1.2;
778 /* create mapping between hrir and input */
779 u
->mapping_left
= (unsigned *) pa_xnew0(unsigned, u
->channels
);
780 u
->mapping_right
= (unsigned *) pa_xnew0(unsigned, u
->channels
);
781 for (i
= 0; i
< map
.channels
; i
++) {
782 found_channel_left
= 0;
783 found_channel_right
= 0;
785 for (j
= 0; j
< hrir_map
.channels
; j
++) {
786 if (hrir_map
.map
[j
] == map
.map
[i
]) {
787 u
->mapping_left
[i
] = j
;
788 found_channel_left
= 1;
791 if (hrir_map
.map
[j
] == mirror_channel(map
.map
[i
])) {
792 u
->mapping_right
[i
] = j
;
793 found_channel_right
= 1;
797 if (!found_channel_left
) {
798 pa_log("Cannot find mapping for channel %s", pa_channel_position_to_string(map
.map
[i
]));
801 if (!found_channel_right
) {
802 pa_log("Cannot find mapping for channel %s", pa_channel_position_to_string(mirror_channel(map
.map
[i
])));
807 u
->input_buffer
= pa_xmalloc0(u
->hrir_samples
* u
->sink_fs
);
808 u
->input_buffer_offset
= 0;
810 pa_sink_put(u
->sink
);
811 pa_sink_input_put(u
->sink_input
);
817 if (hrir_temp_chunk
.memblock
)
818 pa_memblock_unref(hrir_temp_chunk
.memblock
);
820 if (hrir_temp_chunk_resampled
.memblock
)
821 pa_memblock_unref(hrir_temp_chunk_resampled
.memblock
);
831 int pa__get_n_used(pa_module
*m
) {
835 pa_assert_se(u
= m
->userdata
);
837 return pa_sink_linked_by(u
->sink
);
840 void pa__done(pa_module
*m
) {
845 if (!(u
= m
->userdata
))
848 /* See comments in sink_input_kill_cb() above regarding
849 * destruction order! */
852 pa_sink_input_unlink(u
->sink_input
);
855 pa_sink_unlink(u
->sink
);
858 pa_sink_input_unref(u
->sink_input
);
861 pa_sink_unref(u
->sink
);
864 pa_memblockq_free(u
->memblockq
);
867 pa_xfree(u
->hrir_data
);
870 pa_xfree(u
->input_buffer
);
873 pa_xfree(u
->mapping_left
);
874 if (u
->mapping_right
)
875 pa_xfree(u
->mapping_right
);