Peter Meerwald [Wed, 13 Feb 2013 16:26:57 +0000 (17:26 +0100)]
resampler: Resample first followed by remapping if have more out channels than in channels
The patch intends to reduce computational load when resampling AND remapping. The PA
resampler performs the following steps:
sample format conversion -> remapping -> resampling -> sample format conversion
In case the number of output channels is higher than the number of input channels, the
resampler has to be run more often than necessary. E.g. in case of mono to 4-channel remapping,
the resampler runs on 4 channels separately.
To ímprove this, the PA resampler pipeline is made adaptive:
if out-channels <= in-channels:
sample format conversion -> remapping -> resampling -> sample format conversion
if out-channels > in-channels:
sample format conversion -> resampling -> remapping -> sample format conversion
Signed-off-by: Peter Meerwald <p.meerwald@bct-electronic.com>
Tanu Kaskinen [Fri, 15 Feb 2013 19:24:36 +0000 (21:24 +0200)]
echo-cancel: Fix uninitialized variable dotp_xf_xf of AEC struct
Initialize the variable to zero by using pa_xnew0() instead of
pa_xnew(). This also allows us to remove a bunch of other zero
initialization statements.
Reported-by: Peter Meerwald <p.meerwald@bct-electronic.com>
Peter Meerwald [Wed, 13 Feb 2013 16:26:49 +0000 (17:26 +0100)]
build-sys: Properly check for HAVE_DBUS in module-ladspa-sink
prevents
CC module_ladspa_sink_la-module-ladspa-sink.lo
modules/module-ladspa-sink.c:1332:5: warning: "HAVE_DBUS" is not defined
modules/module-ladspa-sink.c:1370:5: warning: "HAVE_DBUS" is not defined
in case HAVE_DBUS is not available
alsa/use-case.h in needed
require at least version 1.0.24 in configure.ac
prevents the following error at compile time:
CC libalsa_util_la-alsa-util.lo
In file included from modules/alsa/alsa-mixer.h:51,
from modules/alsa/alsa-util.h:36,
from modules/alsa/alsa-util.c:46:
modules/alsa/alsa-ucm.h:27:22: error: use-case.h: No such file or directory
In file included from modules/alsa/alsa-mixer.h:51,
from modules/alsa/alsa-util.h:36,
from modules/alsa/alsa-util.c:46:
modules/alsa/alsa-ucm.h:89: error: expected ‘)’ before ‘*’ token
modules/alsa/alsa-ucm.h:169: error: expected specifier-qualifier-list before ‘snd_use_case_mgr_t’
make[3]: *** [libalsa_util_la-alsa-util.lo] Error 1
Stefan Huber [Thu, 7 Feb 2013 13:03:17 +0000 (14:03 +0100)]
resampler: Generate normalized rows in calc_map_table()
Remixing one channel map to another is (except for special cases) done
via a linear mapping between channels, whose corresponding matrix is
computed by calc_map_table(). The k-th row in this matrix corresponds to
the coefficients of the linear combination of the input channels that
result in the k-th output channel. In order to avoid clipping of samples
we require that the sum of these coefficients is (at most) 1. This
commit ensures this.
Prior to this commit tests/remix-test.c gives 52 of 132 matrices that
violate this property. For example:
'front-left,front-right,front-center,lfe' -> 'front-left,front-right'
prior this commit after this commit
I00 I01 I02 I03 I00 I01 I02 I03
+------------------------ +------------------------
O00 | 0.750 0.000 0.375 0.375 O00 | 0.533 0.000 0.267 0.200
O01 | 0.000 0.750 0.375 0.375 O01 | 0.000 0.533 0.267 0.200
Building the matrix is done in several steps. However, only insufficient
measures are taken in order to preserve a row-sum of 1.0 (or leaves it
at 0.0) after each step. The current patch adds a post-processing step
in order check for each row whether the sum exceeds 1.0 and, if
necessary, normalizes this row. This allows for further simplifactions:
- The insufficient normalizations after some steps are removed. Gains
are adapted to (partially) resemble the old matrices.
- Handling unconnected input channls becomes a lot simpler.
Stefan Huber [Thu, 7 Feb 2013 13:03:16 +0000 (14:03 +0100)]
resampler: Refactor calc_map_table()
- Separate the cases with PA_RESAMPLER_NO_REMAP or PA_RESAMPLER_NO_REMIX
set and remove redundant if-conditions.
- Fix C90 compiler warning due to mixing code and variable declaration.
- Do not repeatedly count number of left, right and center channels in
the input channel map.
daemon: Don't rely on prctl(PR_SET_KEEPCAPS, 0) for dropping caps.
Capability dropping when changing the user in the system
mode was previously implemented by calling
prctl(PR_SET_KEEPCAPS, 0), but that doesn't necessarily
work. It's possible that the KEEPCAPS flag is locked to 1,
in which case the prctl() call fails with EPERM (this
happens at least on Harmattan). This patch implements
explicit capability dropping after changing the user.
Jarkko Suontausta [Thu, 24 May 2012 07:38:22 +0000 (10:38 +0300)]
core: Assert on memchunk divisibility by sample spec in pa_memblockq_push().
Earlier, -1 was returned if the memchunk size was not a multiple of the frame
size. Now, it is verified unconditionally through an assertion. Error code -1
is still returned when the memblock queue is full.
In those few cases where the return value of pa_memblockq_push() is checked,
an overflow is assumed to be the reason in case an error code is returned.
Tanu Kaskinen [Wed, 7 Nov 2012 14:52:40 +0000 (16:52 +0200)]
pacat: Handle holes in recording streams.
pa_silence_memory() pulls sample-util as a dependency, so it had to
be moved from libpulsecore to libpulsecommon. sample-util in turn
pulls some more stuff.
Peter Meerwald [Mon, 4 Feb 2013 00:30:19 +0000 (01:30 +0100)]
sconv: Change/fix conversion to/from float32
use (1<<15) instead of 0x7fff as a factor when converting from s16 to float32
use (1<<31) instead of 0x7fffffff as a factor when converting from s32 to float32
the change is motivated by the following desireable properties:
* s16_from_f32(f32_from_s16(x)) == x for all possible s16 values
* x / (1.0f << 15) == x * (1.0f / (1 << 15)) for all x in s16
above changes enable easier optimization while guaranteeing bit-exact results
further, other audio sample conversion code (libavresample) does it the same way
v3 (comments Tanu):
* fix saturation in pa_sconv_s16le_from_f32ne_neon(), use vqrshrn
v2 (comments Tanu):
* fix comments in ARM NEON code
* use llrintf() in pa_sconv_s32le_from_float32ne()
Signed-off-by: Peter Meerwald <p.meerwald@bct-electronic.com> Cc: Tanu Kaskinen <tanuk@iki.fi>
David Henningsson [Tue, 29 Jan 2013 16:27:11 +0000 (17:27 +0100)]
pactl: Document @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@
I went to implement the possibility to use the default sink/source
but found that it was already working. So I figured I'd update
the help text instead.
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Peter Meerwald [Wed, 30 Jan 2013 10:04:05 +0000 (11:04 +0100)]
resampler: Improve s16<-->s32 conversion, use s16 work format if input or output is s16
Problem: s16 to s32 conversion is performed as s16->float->s32 (via work
format float) for resamplers TRIVIAL, COPY, PEAKS.
Precision and efficiency suffers: e.g. 0x9fff results in 0x9ffe4001 (instead
of 0x9fff0000) and there are two sample format conversions instead of one
conversion.
Solution: If input or output format is s16, then choose the work format
to be s16 as well.
If remapping is to be performed, we could stick to work format float32ne for
precision reseans. This is debateable.
Signed-off-by: Peter Meerwald <p.meerwald@bct-electronic.com>
Peter Meerwald [Wed, 30 Jan 2013 10:04:00 +0000 (11:04 +0100)]
tests: Add remap test code to cpu-test
v2 (comments by Paul Menzel):
* generate test samples from -1..1, -0x8000..0x7fff
* check all output samples (not just half of them)
the idea is to compare the output of the C (reference) implementation
against the output of the optimized code path; currently, there are MMX
and SSE implementation for the mono-to-stereo remapper for s16 and float
sample formats
Signed-off-by: Peter Meerwald <p.meerwald@bct-electronic.com> Cc: Paul Menzel <paulepanter@users.sourceforge.net>
Mikel Astiz [Wed, 30 Jan 2013 08:30:31 +0000 (09:30 +0100)]
reserve: Fix leaking NameLost signals after release+acquire
The use of the pseudo-blocking D-Bus calls leads to the problem that
NameLost signals are received after the reply to ReleaseName().
The problem with this is that a later acquisition of the same audio
device can potentially receive the NameLost signal corresponding to
the previous instance, due to the fact that the signal hasn't been
popped from the D-Bus message queue.
The simplest approach to solve this problem is to poll the actual name
owner from the D-Bus daemon, in order to make sure that we did really
lose the name.
The proposal uses a blocking call to GetNameOwner to avoid incosistent
states in the internal APIs: it would otherwise be possible to have a
"busy" device before the reservation has been lost, in the unlikely
case if some other process acquires the name before we got the
confirmation that the NameLost was actually true.
Mikel Astiz [Wed, 30 Jan 2013 08:30:30 +0000 (09:30 +0100)]
reserve: Move get_name_owner() to the public rd_device API
The function is interesting for both rd_device and rd_monitor so make
it part of the rd_device public API to avoid duplicated code.
The decision to move the function to reserve.c is motivated by the fact
that other projects (i.e. jack) use reserve.c only. Therefore, adding a
reserve->reserve-monitor dependency should be avoided.
Mikel Astiz [Mon, 28 Jan 2013 17:25:21 +0000 (18:25 +0100)]
bluetooth: Fix potential assertion failure due to unaligned packet size
While reading from the SCO socket, there is no guarantee regarding the
resulting packet size. In some rare cases, it might not even match the
alignment expected in pa_source_post(), resulting in an assertion
failure inside pa_volume_memchunk():
I: [alsa-sink] module-loopback.c: Could not peek into queue
I: [alsa-sink] module-loopback.c: Could not peek into queue
I: [alsa-sink] module-loopback.c: Could not peek into queue
E: [bluetooth] sample-util.c: Assertion 'pa_frame_aligned(c->length, spec)' failed at pulsecore/sample-util.c:725, function pa_volume_memchunk(). Aborting.
Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffda98f700 (LWP 8058)]
0x00007ffff6177935 in raise () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install alsa-lib-1.0.26-1.fc17.x86_64 dbus-libs-1.4.10-7.fc17.x86_64 flac-1.2.1-9.fc17.x86_64 glibc-2.15-58.fc17.x86_64 gsm-1.0.13-6.fc17.x86_64 json-c-0.10-2.fc17.x86_64 libICE-1.0.8-1.fc17.x86_64 libSM-1.2.1-1.fc17.x86_64 libX11-1.5.0-2.fc17.x86_64 libXau-1.0.6-3.fc17.x86_64 libXext-1.3.1-1.fc17.x86_64 libXi-1.6.1-1.fc17.x86_64 libXtst-1.2.0-3.fc17.x86_64 libogg-1.3.0-1.fc17.x86_64 libsndfile-1.0.25-2.fc17.x86_64 libtool-ltdl-2.4.2-3.1.fc17.x86_64 libudev-182-3.fc17.x86_64 libuuid-2.21.2-3.fc17.x86_64 libvorbis-1.3.3-1.fc17.x86_64 libxcb-1.9-1.fc17.x86_64 speex-1.2-0.14.rc1.fc17.x86_64
Mikel Astiz [Thu, 24 Jan 2013 09:16:57 +0000 (10:16 +0100)]
bluetooth: Fix sending D-Bus reply before internal callback
Make sure the reply to SetConfiguration() is sent before the internal
hook is fired. This is important because the hook could have side
effects including D-Bus interfactions (i.e. transport Acquire() being
called during module startup).
Mikel Astiz [Thu, 24 Jan 2013 09:16:56 +0000 (10:16 +0100)]
bluetooth: Fix potential assertion failure if MTU changes
The assertion in hsp_process_render() assumes that, if a memory block is
already set by the time the function is reached, its size matches
write_block_size.
This can however fail if a transport has been released and acquired
back, in the unlikely case where the MTU has changed in the meantime,
assuming the memory block wasn't released.
Tanu Kaskinen [Tue, 22 Jan 2013 06:42:27 +0000 (08:42 +0200)]
jack: Don't fail module-jackdbus-detect loading if the channels argument is not given.
The u->channels <= 0 check failed if the channels argument was not
given at all, making the whole module loading fail. I don't think the
check is necessary at all - negative values are not possible, and if
someone gives 0 as the argument, it's probably ok if we act as if
there was no channels argument at all.
Tanu Kaskinen [Wed, 16 Jan 2013 01:36:03 +0000 (03:36 +0200)]
Call change_cb() only when there's an actual change.
Calling change_cb() whenever anything happens in the ownership of the
bus name caused trouble in PulseAudio in this scenario:
1. PulseAudio is using a device and owns the corresponding service
name.
2. Another application requests device release.
3. PulseAudio releases the device.
4. Change in the bus name ownership: PulseAudio gives up the
ownership, and nobody owns the name.
5. reserve-monitor notices that, and notifies PulseAudio.
6. Since reserve-monitor reports the device as "not busy", PulseAudio
decides to reserve the bus name immediately back to itself and
opens the device again.
The other application will forcibly take the bus name to itself, as
it should according to the protocol, but the other application may
have trouble opening the device if it tries to do that before
PulseAudio has had time to react to the NameLost signal.
This can be solved by not calling change_cb() if there are no changes
in the device busy status. In this scenario the device is considered
"not busy" while PulseAudio is owning the bus name, so PulseAudio gets
no notification when the ownership changes from PulseAudio to nobody.
Paul Meng [Mon, 7 Jan 2013 13:41:26 +0000 (21:41 +0800)]
pulse: Add pa_operation_set_state_callback() API
[The original commit message didn't have any explanation why this
change is made, so I'll add that information here myself.
--Tanu Kaskinen]
This change is from the developers of a Haskell binding[1]. According
to them, this change isn't strictly necessary, but their code gets
significantly cleaner if they can register an operation callback that
is called when the operation is cancelled due to the context getting
disconnected.
Mikel Astiz [Fri, 11 Jan 2013 10:07:49 +0000 (11:07 +0100)]
bluetooth: Simplify redundant error check
As pointed out by Tanu, checking both error conditions is redundant and
raises the question whether it's possible that one of the conditions is
true while the other is false.
Therefore, simplify the condition by just checking one part of the
disjunction.
Mikel Astiz [Fri, 11 Jan 2013 10:07:48 +0000 (11:07 +0100)]
bluetooth: Remove device_is_audio_ready()
The function was used to check whether the basic properties of the
Bluetooth device have been received. This can be simplified by just
checking d->device_info_valid, since the state of the audio interface
is only relevant inside pa_bluetooth_device_any_audio_connected(), which
is used to trigger the discovery callback.
While checking device_info_valid, special care must be taken with all
three possible values: when set to -1, it means some error was triggered
while getting the device properties. Therefore, these devices can also
be ignored outside bluetooth-util.
Besides that, the patch slightly modifies the behavior of the internal
API affecting pa_bluetooth_discovery_get_by_address() and
pa_bluetooth_discovery_get_by_path(), since they will return the device
no matter the state of the audio interface. This however makes sense and
should have no influence in the current codebase given that the modules
make use of devices only after the discovery hook has been triggered.
Mikel Astiz [Fri, 11 Jan 2013 10:07:47 +0000 (11:07 +0100)]
bluetooth: Do not check profile states is device_audio_is_ready()
The function is used to make sure some basic information has already
been gathered before the device is being used. At this point profile
states can be ignored, since their initial value will be
PA_BT_AUDIO_STATE_INVALID and thus effectively similar to
PA_BT_AUDIO_STATE_DISCONNECTED due to audio_state_to_transport_state().
The change should make no difference given that the behavior of
pa_bluetooth_device_any_audio_connected() doesn't change: by the time
TRUE is returned, a transport needs to exist. This means a profile
will exist in CONNECTING or CONNECTED state and thus the old
implementation of device_audio_is_ready() would also have returned TRUE.
Mikel Astiz [Fri, 11 Jan 2013 10:07:44 +0000 (11:07 +0100)]
bluetooth: Fix minor style issues
Trivially fix some style issues affecting line wrap (128 chars max with
the exception of multi-line comments, which are limited to 80),
indentation and unnecessary parentheses.