sink, source: Assign to s->muted from only one place
Forcing all mute changes to go through set_mute() makes it easier to
check where the muted field is changed, and it also allows us to have
only one place where notifications for changed mute are sent.
This refactoring reduces duplication, as mute_changed() used to do the
same things as set_mute(). Other benefits are improved logging
(set_mute() logs the mute change, mute_changed() used to not do that)
and the soft mute state is kept up to date, because set_mute() sends
the SET_MUTE message to the IO thread.
The set_mute_in_progress flag is an extra precaution for preventing
recursion in case a sink/source implementation's set_mute() callback
causes mute_changed() to be called. Currently there are no such
implementations, but I think that would be a valid thing to do, so
some day there might be such implementation.
The callback just called pa_source_output_get_mute(), which doesn't
have any side effects, and the return value wasn't used either, so
the callback was essentially a no-op.
sink, source: Allow calling set_mute() during initialization
Currently the alsa sink and source write directly to s->muted during
initialization, but I think it's better to avoid direct writes, and
use the set_mute() function instead, because that makes it easier to
figure out where s->muted is modified. This patch prevents the
set_mute() call from crashing in the state assertion.
sink-input, source-output: Assign to volume from only one place
Forcing all volume changes to go through set_volume_direct() makes
it easier to check where the stream volume is changed, and it also
allows us to have only one place where notifications for changed
volume are sent.
sink, source: Assign to reference_volume from only one place
Forcing all reference volume changes to go through
set_reference_volume_direct() makes it easier to check where the
reference volume is changed, and it also allows us to have only one
place where notifications for changed reference volume are sent.
Peter Meerwald [Wed, 16 Apr 2014 13:07:25 +0000 (15:07 +0200)]
remap: Add special remapping case which just re-arranges channels
Input channels may just be copied to output channels, no mixing; this
avoids the generic (slow) matrix remapping code in cases where channels
are dropped or reordered.
This makes use of the remap struct state introduced earlier.
on Intel Core i7-870 @ 2.93 GHz (GCC 4.6, 64-bit):
Checking special remap (s16, stereo rearrange)
func: 126117 usec (avg: 1261.17, min = 1150, max = 2111, stddev = 117.332).
orig: 190509 usec (avg: 1905.09, min = 1807, max = 2402, stddev = 100.984).
Checking special remap (float, stereo rearrange)
func: 194329 usec (avg: 1943.29, min = 1876, max = 2127, stddev = 64.3486).
orig: 205263 usec (avg: 2052.63, min = 2005, max = 2452, stddev = 70.177).
Checking special remap (s16, 4-channel rearrange)
func: 278754 usec (avg: 2787.54, min = 2719, max = 3093, stddev = 78.22).
orig: 383885 usec (avg: 3838.85, min = 3634, max = 4121, stddev = 128.522).
Checking special remap (float, 4-channel rearrange)
func: 312429 usec (avg: 3124.29, min = 3017, max = 3498, stddev = 120.127).
orig: 388198 usec (avg: 3881.98, min = 3768, max = 4655, stddev = 138.441).
on ARM Cortex-A8 (TI OMAP3 DM3730 @ 1GHz) (Linaro GCC 4.6):
Checking special remap (s16, stereo rearrange)
func: 1204647 usec (avg: 12046.5, min = 10406, max = 25451, stddev = 2491.9).
orig: 1660311 usec (avg: 16603.1, min = 14740, max = 20416, stddev = 1708.07).
Checking special remap (float, stereo rearrange)
func: 1391392 usec (avg: 13913.9, min = 12207, max = 28260, stddev = 2238.12).
orig: 9246707 usec (avg: 92467.1, min = 87525, max = 125611, stddev = 5494.64).
Checking special remap (s16, 4-channel rearrange)
func: 2540225 usec (avg: 25402.2, min = 16937, max = 68268, stddev = 10786.7).
orig: 3319852 usec (avg: 33198.5, min = 29571, max = 36957, stddev = 1250.39).
Checking special remap (float, 4-channel rearrange)
func: 3024414 usec (avg: 30244.1, min = 26153, max = 58105, stddev = 4506.01).
orig: 12643624 usec (avg: 126436, min = 120575, max = 159088, stddev = 5519.28).
benchmark code will be posted as follow-up patches
Peter Meerwald [Wed, 16 Apr 2014 13:00:45 +0000 (15:00 +0200)]
remap: Add (optional) state to remap struct
State can be used by remap function implementations to
speed up the remapping, e.g. by precomputing things or
even by generating specialized code for a specific channel
remapping task
Peter Meerwald [Wed, 16 Apr 2014 09:25:58 +0000 (11:25 +0200)]
remap: Make resampler's remap structure more self-contained
Initialization of the remap structure now happens in one place
Rename calc_map_table() to setup_remap(), copy sample format and
channel specs; the remap structure is initialized when we know the
work sample format of the resampler
"i->save_muted = i->save_muted || mute" makes no sense. The intention
was most likely to use "save" instead of "mute" in the assignment.
This line originates from reverting the volume ramping code, commit 8401572fd534f10e07ed6a418e1399b1294d5596.
The idea of "i->save_muted |= save" is that even if the mute state
doesn't change, save_muted should still be updated, but only if the
transition is from "don't save" to "save".
Changing "!i->muted == !mute" to "mute == i->muted" is cosmetic only.
The rationale behind the old form was probably that when we still had
pa_bool_t, booleans could in theory be defined as int, so comparing
the values without the ! operator was not entirely safe. That's
unnecessary now that we use the standard bool type, which can only
have values 0 or 1.
A value of 0 for adjust_time should disable rate adjustment.
Fix a bug where a 0 value causes rate adjustment to be called
continuously instead after an unsuspend event.
Alexander E. Patrakov [Sun, 20 Apr 2014 15:58:19 +0000 (21:58 +0600)]
core-util: Remove redundant check of directory permissions
Initially (in commit ef422fa4ae626e9638ca70d1c56f27e701dd69c2),
pa_make_secure_dir followed a simple principle: "make a directory, or,
if it exists, check that it is suitable". Later this evolved into "make
a directory, or, if it exists, ensure that it is suitable". But the
check remained.
The check is now neither sufficient nor necessary. On POSIX-compliant
systems, the fstat results being checked are actually post-conditions of
fchmod and fchown. And on systems implementing POSIX ACLs, fstat only
reflects a part of the information relevant to the security of the
directory permissions, so PulseAudio could accept an existing insecure
directory anyway.
Also, the check still fires on non-POSIX-compliant filesystems like CIFS.
As a user cannot do anything to fix it, just accept insecure permissions
in this case.
Juho Hämäläinen [Tue, 15 Apr 2014 13:11:48 +0000 (16:11 +0300)]
dbus: Use correct initialization for source ports hashmap.
Source ports hashmap is created without value freeing function, which
results in (hashmap values) device ports not being freed when source
ports are removed or module is unloaded. This results in memory leak
during normal operation and during daemon shutdown dbus_protocol shared
object isn't unreferenced correctly, leaving dbus_protocol object in
core->shared, which causes assert when shared hashmap is checked for
isempty() before freeing.
This generates a list of deprecated things, which is accessible from
the table of contents frame. The list, however, isn't the important
thing here. The important thing is that this also prevents doxygen
from stripping all documentation for the deprecated things.
virtual-surround-sink: Move normalization heuristic to its own function
This patch also adds a description how the heuristic works and mentions that
there is a scaling factor that can be adjusted if there is audible clipping.
Peter Meerwald [Sat, 29 Mar 2014 17:03:05 +0000 (18:03 +0100)]
pactl: Clean up checking for VOL_RELATIVE flag
VOL_RELATIVE if a bit flag (1 << 4), hence we can simply do
if (vol_flags & VOL_RELATIVE) ...
instead of
if ((vol_flags & VOL_RELATIVE) == VOL_RELATIVE) ...
Parin Porecha [Thu, 19 Dec 2013 11:58:15 +0000 (17:28 +0530)]
pactl: Allow to set volume of each channel independently (Bug #39190)
Example: pactl set-sink-volume "sink_name" 32000 40000
If the number of volumes provided is different than the number of channels
(excluding the case where a single volume is provided), an error message
is displayed explaining why the volumes could not be set.
patch proposed by Parin Porecha
code refactoring and commit message slightly edited by Peter Meerwald
see getopt(3):
""By default, getopt() permutes the contents of argv as it scans, so that
eventually all the nonoptions are at the end. Two other modes are also
implemented. If the first character of optstring is '+' or the envi‐
ronment variable POSIXLY_CORRECT is set, then option processing stops
as soon as a nonoption argument is encountered. If the first character
of optstring is '-', then each nonoption argv-element is handled as if
it were the argument of an option with character code 1. (This is used
by programs that were written to expect options and other argv-elements
in any order and that care about the ordering of the two.) The special
argument "--" forces an end of option-scanning regardless of the scan‐
ning mode.""
prepend optstring with '+' to use POSIXLY_CORRECT mode
Alexander E. Patrakov [Thu, 10 Apr 2014 15:13:43 +0000 (21:13 +0600)]
Name HDMI outputs uniquely
On Haswell hardware, there are multiple HDMI outputs capable of
digital sound output. As they were identically named, KDE's control
center was unable to distinguish them, restored the wrong profile and
thus routed sound to the wrong HDMI monitor.
Also, having identically-named menu items in other mixer applications
looks like a bug.
Tanu Kaskinen [Wed, 19 Mar 2014 07:50:39 +0000 (09:50 +0200)]
zeroconf-publish: Don't assume any particular defer event ordering
Also, initialize userdata with zeros to avoid invalid pointers in
client_free().
This fixes a crash when client_free() is called before
create_client(). The whole issue could be avoided by using some other
mechanism than defer events for running the two functions, but I'll
do that change later (I have also other cleanups planned for
zeroconf-publish).
Tanu Kaskinen [Wed, 19 Mar 2014 10:19:08 +0000 (12:19 +0200)]
client-conf: Don't create multiple cookie files
The old code loaded cookies at the time of loading the client
configuration, which could lead to creation of multiple cookie files.
For example, when pa_client_conf_load() was called, the default cookie
file was created, and then if PULSE_COOKIE was set,
pa_client_conf_env() would create another cookie file.
This patch moves the loading of the cookie to a separate function,
which pa_context calls just before needing the cookie, so the cookie
won't be loaded from the default file if PULSE_COOKIE is set. This
patch also splits the single cookie and cookie_file fields in
pa_client_conf into multiple fields, one for each possible cookie
source. That change allows falling back to another cookie source if
the primary source doesn't work.
Tanu Kaskinen [Wed, 19 Mar 2014 07:18:06 +0000 (09:18 +0200)]
pactl: Fix crash with older servers
Servers older than 0.9.15 don't know anything about cards, and card
operations will return a NULL pa_operation object when connected to
that old server. We must check the pa_operation pointer before passing
it to pa_operation_unref(), otherwise a NULL operation will result in
a crash.
David Henningsson [Fri, 21 Mar 2014 09:19:19 +0000 (10:19 +0100)]
sink/source: Initialize port before fixate hook (fixes volume/mute not saved)
In case a port has not yet been saved, which is e g often the case
if a sink/source has only one port, reading volume/mute will be done
without port, whereas writing volume/mute will be done with port.
Work around this by setting a default port before the fixate hook,
so module-device-restore can read volume/mute for the correct port.
Peter Ujfalusi [Fri, 21 Mar 2014 07:18:40 +0000 (09:18 +0200)]
alsa-util: Reset hwparams_copy before the second try of buffer setup
hwparams_copy needs to be reset (as it is also reset for the third and
fourth try) before the second try.
If the reset is not done and the first try fails:
D: [lt-pulseaudio] alsa-util.c: Maximum hw buffer size is 743 ms
I: [lt-pulseaudio] alsa-util.c: snd_pcm_hw_params_set_buffer_size_near() failed: Invalid argument
I: [lt-pulseaudio] alsa-util.c: snd_pcm_hw_params_set_period_size_near() failed: Invalid argument
I: [lt-pulseaudio] alsa-util.c: snd_pcm_hw_params_set_buffer_size_near() failed: Invalid argument
D: [lt-pulseaudio] alsa-util.c: Set only period size (to 1102 samples).
We have three failures and finally the fourth (only period size) succeed.
With this patch:
D: [lt-pulseaudio] alsa-util.c: Maximum hw buffer size is 743 ms
I: [lt-pulseaudio] alsa-util.c: snd_pcm_hw_params_set_buffer_size_near() failed: Invalid argument
D: [lt-pulseaudio] alsa-util.c: Set period size first (to 1102 samples), buffer size second (to 4408 samples).
We only fail with the first try, the second (period followed by buffer) is
fine.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Tanu Kaskinen [Sat, 15 Mar 2014 07:37:06 +0000 (09:37 +0200)]
zeroconf-publish: Don't react to messages while shutting down
This fixes a case where pa__done() is called while
AVAHI_MESSAGE_PUBLISH_ALL is waiting for processing. The
pa_asyncmsgq_wait_for(AVAHI_MESSAGE_SHUTDOWN_COMPLETE) call will
process all pending messages, and processing AVAHI_MESSAGE_PUBLISH_ALL
causes publish_all_services(), and that in turn accesses u->services,
which has been already freed at this point. If we are shutting down,
we shouldn't react to any of the messages that the Avahi thread is
sending to the main thread.
Pete Beardmore [Thu, 13 Mar 2014 10:14:40 +0000 (10:14 +0000)]
alsa: Use card description in default sink/source prefix when available
When given an explicit device.description in card_properties, prefer
this information over other default prefixes (e.g. 'Built-in Audio')
when constructing sink/source descriptions.
For example, if I manually configure the card description to be
"FooBar", I then expect that the sinks and created by the card also
have "FooBar" in their description instead of generic "Built-in
Audio".
David Henningsson [Tue, 11 Mar 2014 04:50:10 +0000 (05:50 +0100)]
alsa-mixer: Fix Analog Input showing up on USB Headset
In some cases, "Analog Input" could show up as well as
"Headset Mic" (or "Headphone Mic"), because I forgot to add the
relevant "required-absent" lines when I added the headset mic path.
As a result, both "Analog Input" and "Headset Mic" showed up on the
Logitech USB 530 Headset.
Reported-by: Steve Magoun <steve.magoun@canonical.com> Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Peter Meerwald [Thu, 6 Mar 2014 12:15:12 +0000 (13:15 +0100)]
tunnel-source-new: Fix shadow compiler warning
CC modules/module_tunnel_sink_la-module-tunnel.lo
modules/module-tunnel-source-new.c: In function 'read_new_samples':
modules/module-tunnel-source-new.c:145:16: warning: declaration of 'read' shadows a global declaration [-Wshadow]
Tanu Kaskinen [Wed, 29 Jan 2014 18:59:00 +0000 (20:59 +0200)]
alsa: Remove a redundant check
If mixer_handle is not NULL, then hctl_handle won't be NULL either.
The redundant check was confusing, because it looked like we would
leak the mixer_handle if mixer_handle is non-NULL and hctl_handle is
NULL.
James Bunton [Sun, 26 Jan 2014 14:14:39 +0000 (01:14 +1100)]
bluetooth: Fix timing to count based on decoded data
Currently the latency information is being updated based on the encoded
SBC data instead of the decoded PCM data. Fixing this required moving
the timing update to be after the packet has been decoded.
James Bunton [Sun, 26 Jan 2014 14:14:38 +0000 (01:14 +1100)]
bluetooth: Don't abort on SBC decoding error
The Nokia E7 running Symbian Belle Refresh seems to generate invalid SBC
packets every few minutes. This causes pulseaudio to disconnect the
stream and log "SBC decoding error (-3)".
If a single packet is bad, pulseaudio should keep playing the stream.
Some people want module-rtp-send to send silence when the sink that is
monitored goes idle, and some people want module-rtp-send to pause the
RTP stream to avoid unnecessary bandwidth consumption.
Steps to reproduce:
1) Leave LFE remixing disabled (the default)
2) Start playback of stereo material on e g 5.1 surround, notice nothing in LFE
3) Now change profile to e g 4.0 surround and then back to 5.1 surround
4) Notice that LFE channel is now remixed
Signed-off-by: David Henningsson <david.henningsson@canonical.com>