Age | Commit message (Collapse) | Author | Files | Lines |
|
Perform detection of supported sample format and rates just after device is
opened, before `snd_pcm_hw_params()` is called for the first time. This fixes a
problem where device restricts available sample rates after HW params are set
preventing sample rate detection (seen with UAC2 devices and kernel 6.1.9)
Bug: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/1414
Bug: https://github.com/alsa-project/alsa-lib/issues/119
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/782>
|
|
After previous patches, we should be generating no combination ports, so
we don't need to store multiple devices per port. Simplify the code
based on this.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
|
|
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/55>
|
|
We check if mapping is NULL but if so we never set mdev, set it to NULL as well.
Fixes: 79cb1369fc4d22966cb65253e9da2ccda2f25b45
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/615>
|
|
Recently we found an issue of output volume on speaker and headphone,
they should have their own volume but in practice they share one
output volume.
This issue happens on the laptops which use the ucm2 sof-hda-dsp,
originally the speaker has output volume A while the headphone has the
output volume B, suppose the speaker is the active port at the moment
and the output volume is A, users plug a headphone to the jack and the
headphone becomes the active port, in this process, ucm_set_port()
calls _disdev/_enadev which triggers the io_mixer_callback(), in the
meanwhile, the module_device_restore will restore the headphone's
volume to B, it will call set_volume_cb() to set the volume to B, but
this value is not written to hw immediately, during the time of
waiting for the B to be written to the hw, the io_mixer_callback()
calls get_volume_cb(), it reads hw volume and gets the volume A, then
it overrides the output volume to A, this results in the headphone
gets the volume A instead of B.
If a machine doesn't use the ucm, this issue will not happen since the
set_port_cb() will not trigger the io_mixer_callback(). If the ports
don't belong to the same sink/source, this issue also doesn't happen.
BugLink: http://bugs.launchpad.net/bugs/1930188
Signed-off-by: Hui Wang <hui.wang@canonical.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/577>
|
|
Fix Debian bullseye bug where adding this line makes pulseaudio crash on startup
`load-module module-alsa-sink device=hw:1,0 control=Wave`
See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=989103
Fixes: dacfcbb09 ("alsa-ucm: use the proper mixer name for ucm pcm sink/source")
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/576>
|
|
Since commit cb91d7a1 the watermark is increased when there is nothing to rewind.
This is also done in the case when there was actually no rewind requested at all,
so the watermark is increased needlessly.
This patch fixes the issue by skipping the rewind if none is requested.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/530>
|
|
If we do not manage to rewind at all because there is nothing to rewind
any more, it means the latency is too small, and we let audio escape our
control. We should thus increase the watermark to fix this.
Fixes #871
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/287>
|
|
modules/alsa/alsa-sink.c: In function ‘pa_alsa_sink_new’:
modules/alsa/alsa-sink.c:2603:15: warning: declaration of ‘state’ shadows a previous local [-Wshadow]
void *state;
^~~~~
modules/alsa/alsa-sink.c:2270:11: note: shadowed declaration is here
void *state = NULL;
^~~~~
CC modules/alsa/module_alsa_sink_la-module-alsa-sink.lo
modules/alsa/alsa-source.c: In function ‘pa_alsa_source_new’:
modules/alsa/alsa-source.c:2289:15: warning: declaration of ‘state’ shadows a previous local [-Wshadow]
void *state;
^~~~~
modules/alsa/alsa-source.c:1975:11: note: shadowed declaration is here
void *state = NULL;
^~~~~
modules/alsa/module-alsa-card.c: In function ‘prune_singleton_availability_groups’:
modules/alsa/module-alsa-card.c:691:71: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
pa_hashmap_put(group_counts, p->availability_group, count + 1);
^
|
|
On the machines with the ucm used, the different input/output devices
often have different pcm stream, so they often belong to different
sources and sinks, this is greatly different from the design of all
devices connected to a codec (without ucm).
For example, on a machine with ucm2 used:
the internal dmic is on source#0
the external mic is on the source#1
the internal spk is on sink#0
the external headphone is on sink#1
Users expect that after plugging the external device, it will become
the active device automatically. The switch-on-port-available could
make it to be the active_port on its own source/sink, but can't make
source/sink to be default_source/sink since the sources/sinks belong
to the same profile (HiFi usually).
If we adjust the source/sink priority according to ucm ports priority,
the device_port.c could handle the default_source/sink changing then.
Usually we set higher priority for external device than internal
device in the ucm.
In order to bring the lowest side effect on the source/sink priority,
I change the ucm priority to units digit first, then add it to the
original priority.
Signed-off-by: Hui Wang <hui.wang@canonical.com>
|
|
We met a weird situation on a couple of Lenovo machines and at least
on one Dell machine. First we open the gnome-sound-setting, then
suspend and resume the system, after the system resume back, the audio
devices change to dummy, the audio doesn't work anymore. And pacmd
list-cards shows no available sound card.
Through debugging I found after resume, the alsa receives POLLERR
events and it will call unsuspend to recover the pcm, but at that
moment, the device nodes in /dev/snd/ is not accessible, so the
snd_pcm_open() fails and the pulseaudio unload the module-alsa-card.
Here I add retry and pa_msleep if snd_pcm_open fails, I tested it on
all machines which have this problem, pa_msleep(25) is ok for most of
them, there is only one machine which needs to call pa_msleep(25)
twice, so for safety reason, I set the max retry times to 4.
Signed-off-by: Hui Wang <hui.wang@canonical.com>
|
|
Previously avoid_resampling was always false unless the sink or source
implementation explicitly configured the variable. The null sink doesn't
explicitly configure it, so it didn't switch the sample rate as
expected when avoid_resampling was enabled.
This change means that also sinks that don't support rate switching can
have avoid_resampling set to true, but I think that's fine, because
pa_sink_reconfigure() doesn't try to do anything if the reconfigure()
callback isn't set.
Fixes: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/923
|
|
- remove duplicate mixer initialization in sink
- use the similar mixer initialization for source like for sink
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
|
The UCM device must be activated using the pa_alsa_ucm_set_port()
call on boot (the sink creation time). In case when the
mixer controls are not defined for the application in the
UCM configuration, the mixer_handle is NULL.
Call the pa_alsa_ucm_set_port() before the mixer_handle check.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
|
It is possible that UCM doesn't specify hardware volume controls.
Fall back to software controls instead of aborting.
|
|
The unused mixer instances are created without this code.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
|
The ALSA mixer can be opened multiple times (especially for UCM
in the probe). This adds a simple mixer cache to prevent
multiple open calls.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
|
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
|
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
|
- sync mixer logic added
- mixer path creation, empty set in mapping creation, paths added in path creation
- path creation moved inside new port creation as it might be called twice otherwise
- some comments added
|
|
This allows us to support the PlaybackVolume and CaptureVolume commands
in UCM, specifying a mixer control to use for hardware volume control.
This only works with ports corresponding to single devices at the
moment, and doesn't support stacking controls for combination ports.
The configuration is intended to provide a control (like Headphone
Playback Volume), but we try to resolve to a simple mixer control
(Headphone) to reuse existing volume paths.
On the UCM side, this also requires that when disabling the device for
the port, the volume should be reset to some default.
When enabling/disabling combination devices, things are a bit iffy since
we have no way to reset the volume before switching to a combination
device. It would be nice to have a combination-transition-sequence
command in UCM to handle this and other similar cases.
PlaybackSwitch and CaptureSwitch are yet to be implemented.
|
|
Consumers are expected to use <alsa/asoundlib.h> instead of
<asoundlib.h>.
This is in preparation of an change to pkgconfig(alsa) to
not pollute CFLAGS with -I/usr/include/alsa anymore.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
|
Currently, when a system is waking up from suspend, the resume process of the
ALSA sink and source is unstable. Sometimes the device needs to be restarted
multiple times and when the system was suspended between snd_pcm_mmap_begin()
and snd_pcm_mmap_commit(), pulseaudio crashes on resume.
Additionally, variables are not reset after the resume, so that sink/source
report wrong latencies.
This patch fixes the issues by closing and re-opening the PCM if recovery
from an error condition is not possible. Additionally, the variables are
reset, so that latencies are reported correctly.
|
|
|
|
avoid-resampling/passthrough
Sample format(e.g. 16 bit, 24 bit) was not considered even if the
avoid-resampling option is set or the passthrough mode is used.
This patch checks both sample format and rate of a stream to
determine whether to avoid resampling in case of the option is set.
In other word, it is possble to use the stream's original sample
format and rate without resampling as long as these are supported
by the device.
pa_sink_input_update_rate() and pa_source_output_update_rate() are
renamed to pa_sink_input_update_resampler() and pa_source_output
_update_resampler() respectively.
functions are added as below.
pa_sink_set_sample_format(), pa_sink_set_sample_rate(),
pa_source_set_sample_format(), pa_source_set_sample_rate()
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
|
|
It is changed from 'rates' to 'supported_rates'.
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
|
|
There has been a function to get supported sample rates from alsa and
an array for it in userdata of each module-alsa-sink/source. Similarly,
this patch adds a function to get supported sample formats(bit depth)
from alsa and an array for it to each userdata of the modules.
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
|
|
pa_sink_get_state() and pa_source_get_state() just return the state
variable. We can as well access the state variable directly.
There are no behaviour changes, except that module-virtual-source
accessed the main thread's sink state variable from its push() callback.
I fixed the module so that it uses the thread_info.state variable
instead. Also, the compiler started to complain about comparing a sink
state variable to a source state enum value in protocol-esound.c. The
underlying bug was that a source pointer was assigned to a variable
whose type was a sink pointer (somehow using the pa_source_get_state()
macro confused the compiler enough so that it didn't complain before).
I fixed the variable type.
|
|
Previously, the "avoid-resampling" option of daemon.conf is to make the
daemon try to use the stream sample rate if possible for all sinks or
sources.
This patch applies this option to module-udev-detect and module-alsa-card
as a module argument in order to override the default value of daemon.conf.
As a result, user can use this argument for more fine-grained control.
e.g.) set it false in daemon.conf and set it true for module-udev-detect
or a particular module-alsa-card in default.pa.(or vice versa)
To set it, use "avoid_resampling=true or false" as the module argument.
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
|
|
This should make it easier for clients to elevate their audio threads to
real time priority without having to dig through much through specific
system internals.
|
|
Source and sink are passed in arguments to set_state_in_io_thread()
callbacks. There is optimal to access them directly.
|
|
Reconfiguration callback should also be set in case of avoiding resampling
option. This patch set the callback for every case because the callback
has already conditions to leave if it is not needed.
Also unnecessary codes of setting alternate sample rate to 0 are removed.
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
|
|
The alsa sink calls pa_sink_suspend() from the set_port() callback.
pa_sink_suspend() can only be called from the main thread, but the
set_port() callback was often called from the IO thread. That caused an
assertion to be hit in pa_sink_suspend() when switching ports.
Another issue was that pa_sink_suspend() called the set_port() callback,
and if the callback calls pa_sink_suspend() again recursively, nothing
good can be expected from that, so the thread mismatch was not the only
problem.
This patch moves the mixer syncing logic out of pa_sink/source_suspend()
to be handled internally by the alsa sink/source. This removes the
recursive pa_sink_suspend() call. This also removes the need to have the
mixer_dirty flag in pa_sink/source, so the flag and the
pa_sink/source_set_mixer_dirty() functions can be removed.
This patch also changes the threading rules of set_port(). Previously it
was called sometimes from the main thread and sometimes from the IO
thread. Now it's always called from the main thread. When deferred
volumes are used, the alsa sink and source still have to update the
mixer from the IO thread when switching ports, but the thread
synchronization is now handled internally by the alsa sink and source.
The SET_PORT messages are not needed any more and can be removed.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=104761
|
|
The suspend cause isn't yet used by any of the callbacks. The alsa sink
and source will use it to sync the mixer when the SESSION suspend cause
is removed. Currently the syncing is done in pa_sink/source_suspend(),
and I want to change that, because pa_sink/source_suspend() shouldn't
have any alsa specific code.
|
|
There are no behaviour changes, the code from almost all the SET_STATE
handlers is moved with minimal changes to the newly introduced
set_state_in_io_thread() callback. The only exception is module-tunnel,
which has to call pa_sink_render() after pa_sink.thread_info.state has
been updated. The set_state_in_io_thread() callback is called before
updating that variable, so moving the SET_STATE handler code to the
callback isn't possible.
The purpose of this change is to make it easier to get state change
handling right in modules. Hooking to the SET_STATE messages in modules
required care in calling pa_sink/source_process_msg() at the right time
(or not calling it at all, as was the case on resume failures), and
there were a few bugs (fixed before this patch). Now the core takes care
of ordering things correctly.
Another motivation for this change is that there was some talk about
adding a suspend_cause variable to pa_sink/source.thread_info. The
variable would be updated in the core SET_STATE handler, but that would
not work with the old design, because in case of resume failures modules
didn't call the core message handler.
|
|
There will be a new callback named set_state_in_io_thread(). It seems
like a good idea to have a similar name for the main thread variant.
|
|
build_pollfd() isn't likely to fail, but if it does, pa_sink/source_put()
will crash on an assertion failure. I haven't seen such crash happening,
this is just something that I noticed while studying the state change
code.
|
|
Suspending never fails.
|
|
The suspend cause isn't yet used by any of the callbacks. The alsa sink
and source will use it to sync the mixer when the SESSION suspend cause
is removed. Currently the syncing is done in pa_sink/source_suspend(),
and I want to change that, because pa_sink/source_suspend() shouldn't
have any alsa specific code.
|
|
This removes the need to hardcode the PCM device index in the HDMI jack
names. The hardcoded values don't work with the Intel HDMI LPE driver.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488
|
|
The Intel HDMI LPE driver works in a peculiar way when the HDMI cable is
not plugged in: any written audio is immediately discarded and underrun
is reported. That resulted in an infinite loop, because PulseAudio tried
to keep the buffer filled, which was futile since the written audio was
immediately consumed/discarded.
This patch adds special handling for the LPE driver: if the active port
of the sink is unavailable, the sink suspends itself. A new suspend
cause is added: PA_SUSPEND_UNAVAILABLE.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488
|
|
Previously max_rewind was always set to the full hw buffer size, but
the actual maximum rewind amount is limited to the part of the hw buffer
that is in use.
The rewind request that was done when lowering the sink latency had to
be moved to happen before updating max_rewind.
The practical benefit of this change: When using a filter source on a
monitor source, the filter source latency is increased by max_rewind.
Without this change the max_rewind of an alsa sink is often
unnecessarily high, which leads to unnecessarily high latency with
filter sources.
Monitor sources themselves don't suffer from the latency issue, because
they use the current sink latency instead of max_rewind for the extra
buffer that they keep to deal with rewinds.
|
|
This rejigs the update_rate() logic to encompass changes to the sample
spec as a whole, as well as passthrough status. As a result,
sinks/sources provide a reconfigure() method which allows
reconfiguration as required.
The behaviour itself is currently unchanged -- alsa-sink/-source do not
actually implement anything other than rate updates for now (nor are
they ever requested to). This can be modified in the future, to allow,
for example 24-bit output when incoming media supports it, as well as
channel count changes for passthrough sinks.
Another related change is that passthrough status is now part of
sink/source reconfiguration, and we can stop doing a suspend/unsuspend
when entering/leaving passthrough state. So that part is now divided
in two -- pa_sink_reconfigure() sets the sink in passthrough mode if
required, and pa_sink_enter_passthrough() sets up everything else
(this currently means only volumes, but could disable other processing)
for passthrough mode.
|
|
negative values
The reported latency of source or sink is based on measured initial conditions.
If the conditions contain an error, the estimated latency values may become negative.
This does not indicate that the latency is indeed negative but can be considered
merely an offset error. The current get_latency_in_thread() calls and the
implementations of the PA_{SINK,SOURCE}_MESSAGE_GET_LATENCY messages truncate negative
latencies because they do not make sense from a physical point of view. In fact,
the values are truncated twice, once in the message handler and a second time in
the pa_{source,sink}_get_latency_within_thread() call itself.
This leads to two problems for the latency controller within module-loopback:
- Truncating leads to discontinuities in the latency reports which then trigger
unwanted end to end latency corrections.
- If a large negative port latency offsets is set, the reported latency is always 0,
making it impossible to control the end to end latency at all.
This patch is a pre-condition for solving these problems.
It adds a new flag to pa_{sink,source}_get_latency_within_thread() to allow
negative return values. Truncating is also removed in all implementations of the
PA_{SINK,SOURCE}_MESSAGE_GET_LATENCY message handlers. The allow_negative flag
is set to false for all calls of pa_{sink,source}_get_latency_within_thread()
except when used within PA_{SINK,SOURCE}_MESSAGE_GET_LATENCY. This means that the
original behavior is not altered in most cases. Only if a positive latency offset
is set and the message returns a negative value, the reported latency is smaller
because the values are not truncated twice.
Additionally let PA_SOURCE_MESSAGE_GET_LATENCY return -pa_sink_get_latency_within_thread()
for monitor sources because the source gets the data before it is played.
|
|
If the ALSA device supports granular pointer reporting, we end up in a
situation where we write out a bunch of data, iterate, and then find a
small amount of data available in the buffer (consumed while we were
writing data into the available buffer space). We do this 10 times
before quitting the write loop.
This is inefficient in itself, but can also have wider consequences. For
example, with module-combine-sink, this will end up pushing the same
small chunks to all other devices too.
Given both of these, it just makes sense to not try to write out data
unless a minimum threshold is available. This could potentially be a
fragment, but it's likely most robust to just work with a fraction of
the total available buffer size.
|
|
Bug 96741 shows a case where an assertion is hit, because
pa_asyncq_new() failed due to running out of file descriptors.
pa_asyncq_new() is used in only one place (not counting the call in
asyncq-test): pa_asyncmsgq_new(). Now pa_asyncmsgq_new() can fail too,
which requires error handling in many places. One of those places is
pa_thread_mq_init(), which can now fail too, and that needs additional
error handling in many more places. Luckily there weren't any places
where adding better error handling wouldn't have been easy, so there are
many changes in this patch, but they are not complicated.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=96741
|
|
If a card has been hot-plugged after pulseaudio start, alsa-lib still has
old configuration in memory, which doesn't have PCM definitions for the
new card. Thus, this error appears, and the device doesn't work:
I: [pulseaudio] (alsa-lib)confmisc.c: Unable to find definition 'cards.USB-Audio.pcm.front.0:CARD=0'
I: [pulseaudio] (alsa-lib)conf.c: function snd_func_refer returned error: No such file or directory
I: [pulseaudio] (alsa-lib)conf.c: Evaluate error: No such file or directory
I: [pulseaudio] (alsa-lib)pcm.c: Unknown PCM front:0
I: [pulseaudio] alsa-util.c: Error opening PCM device front:0: No such file or directory
The snd_config_update_free_global() function makes alsa-lib forget any
cached configuration and reparse all PCM definitions from scratch next
time it is told to open anything.
The trick has been copied from Phonon.
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=54029
Signed-off-by: Alexander E. Patrakov <patrakov@gmail.com>
|
|
It doesn't work currently (fails and falls back to PCM), due to channel
count mismatch between the sink sample spec and the sample spec required
by IEC61937.
To be reverted when someone implements changing channel count without
switching profiles. This would also be required for HBR passthrough over
HDMI.
Reported-by: Xamindar <junkxamindar@gmail.com>
Signed-off-by: Alexander E. Patrakov <patrakov@gmail.com>
|
|
|
|
This fixes rare condition when pulseaudio client tries to rewind,
but a device previously reached underrun and was changed to XRUN state.
|