When checking that a card has all of its PCM devices available, ignore
any specific device with the ACP_IGNORE udev environment variable. This
mirrors how we ignore whole cards, but specifically allows non-PipeWire
software to own specific PCM devices.
Note that this does not actually stop PipeWire from using those
subdevices right now, we assume UCM configs take care of that. This
should probably be implemented later to ensure PipeWire always stays
away from them, but for now this fixes the issue where it refuses to
probe the entire card.
Fixes: #3570
Signed-off-by: Hector Martin <marcan@marcan.st>
All linked PCMs prepare together. If we prepare the secondaries, that
action clobbers the write pointer of every PCM every time, which then
causes playback to fail to start due to lack of data.
Signed-off-by: Hector Martin <marcan@marcan.st>
When the PCM is stopped, don't check for early wakeup because if we
are early, we will never be on time in the next iteration either because the
PCM is stopped and doesn't advance.
Also don't try to align when stopped.
See #3565
Only schedule nodes together when there is just 1 capture and 1 playback
device. Devices might be mutually exclusive or require special setup
that would break otherwise.
See #3556
Add an option to automatically use snd_pcm_link when the follower clock
is matching the driver. Only set this to true in pro-audio and when
nodes are scheduled together.
See #3556
We only start the ALSA pcm after we get our first buffer.
We still need to do the sync through (and get the number of prefilled
samples) to make sure we set our new timeout and don't keep on waking
up quickly while the graph fetches the first buffer.
Rename some variables to make it clear that we are dealing with the rate
and duration of the driver.
Set the driver rate in the clock instead of the target_rate, which we
might have rejected.
When we are using the same clock (!matching) try to link the two PCM
devices together. This starts and stops the devices at the same time and
gives better latency.
Keep track or the follower state and do the sync from the driver
wakeup.
This improves sync between devices because the sync no longer
depends on when the node was woken up in the graph and scheduled. We
would have been able to handle this difference by using the htimestamp
but that doesn't seen to work reliably on some hardware.
This is also essential for the interrupt based scheduling.
Split the spa_alsa_start() in a prepare and start function. Prepare
will then also reset state and prefill the playback buffer with silence.
This makes it possible to reuse the prepare function in recover().
The threshold depends on the samplerate and even when the graph rate or
quantum didn't change, the driver could be opened in a different
samplerate, which would cause the timeouts to be wrong and cause xruns.
As part of this, in alsa-udev.c, certain structures and variables referred
to as "device" are renamed to "card". Otherwise, there is ambiguity, since
"device" can mean a udev device, an SPA device, a compress-offload device,
a PCM device etc.
Also, replace "card id" with "card number" to emphasize that these integers
are not actually SPA object IDs.