Add a new followerClock block in the profiler info. This is only set
when the follower could be a driver and it contains the clock info used
for following the driver, mostly the rate difference and delay.
Dump this info in pw-profiler -J
Make sure we always set the info in the clock, especially also when we
are following.
Keep a running average and variance of the error. Use this to
periodically update the DLL bandwidth. When the variance gets smaller,
we update the DLL more slowly to stay closer to the ideal rate.
This seems to improve the rate stability.
The properties of the card might overwrite those of the PCM.
For example, the cards's `alsa.id` will be set on the PCM too
since 37a51533e0 ("acp: add more properties for the card").
To avoid that, call `pa_alsa_init_proplist_card()` first
in `pa_alsa_init_proplist_pcm_info()` instead of last.
See #4135
Don't use the api.alsa.soft-mixer option to disable the path selection
but make a new api.alsa.disable-mixer-path.
Disabling the path selection might leave cards unusable after suspend,
so a separate option is a better idea.
See #4311
Use the helper instead of duplicating the same code.
Also add some helpers to parse a json array of uint32_t
Move some functions to convert between type name and id.
Add spa_json_begin_array/object to replace
spa_json_init+spa_json_begin_array/object
This function is better because it does not waste a useless spa_json
structure as an iterator. The relaxed versions also error out when the
container is mismatched because parsing a mismatched container is not
going to give any results anyway.
We have to unlink pcms when they are linked to a driver from
a different pcm.
When a playback and a capture pcm is linked and we start
the playback pcm and the capture pcm later this can leads
to a 'EPIPE' error on the capture device.
...
spa.alsa: hw:3,0c: snd_pcm_start: Broken pipe
...
The port.name should be something fairly unique and stable per node that
is also human readable.
Make sure we include the ALSA client name and port name in the
port.name but try to avoid double client names when the client name
is already in the port name.
There is also a api.alsa.disable-longname that is now set to true by
default. Setting this to false will include the unique client and port
id to the port.name.
This should make the midi port names much more presentable and more in
line with JACK1.
While the spec allows for 1ppm changes, our rate matching logic applies
these changes quite often, which can be spammy on USB. I haven't seen
hosts mind this, but it seems like it might be a problem at some point.
Additionally, if we also have bind ctls enabled, every pitch update is
also a wakeup for ourselves (whether or not we're listening for the
pitch ctls, since the mixer fd does not distinguish between ctls, those
are filtered after we wake up).
The 10ppm threshold is empirically tested as being not "too noisy" (i.e.
when updates happen, I can see them scroll by with `amixer events`).
If necessary, we can make this configurable in the future.
Use the new UMP alsa sequencer API to make it produce UMP packets.
Set the alsa sequencer to MIDI2.0, which will make it convert all
messages to MIDI-2.0 UMP automatically. We can copy this straight into
the control buffers.
This also solves some problems with large sysex messages that are now
nicely split into chunks with UMP.
ACP allows multiple %f in device strings (cf pa_alsa_open_by_template),
but we replace only one of them when emitting the nodes. The a52
profiles in default.conf use multiple %f and probably don't work.
Fix to replace also multiple %f when emitting ACP device nodes.
`:` is a reserved character on Windows filesystems.
As far as I can tell from looking through both PulseAudio and PipeWire
commit history the files under `alsa/mixer/samples` are not used or
installed by anything.
See #2474.
Can be used to group ports together. Mostly because they are all from
the same stream and split into multiple ports by audioconvert/adapter.
Also useful for the alsa sequence to group client ports together.
Also interesting when pw-filter would be able to handle streams in the
future to find out what ports belong to what streams.
When bound_ctl info cannot be read this array elem info
is set to NULL in 'fetch_bind_ctl'. So when we iterate
the bound_ctl array we always have to check this.
In ACP mode, we might be accessing front:0 as the PCM, and using that
string to generate the ctl device name does not make sense. In
PulseAudio, we used the card index to generate a hw:X string, and we
replicate that here.
Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4028
The default kernel pool size on the input is 200 cells. A cell is
about 28 bytes long so the maximum message that can be received in one
go is about 5600 bytes. This causes problems when using amidi to upload
larger sysex messages because they simply can't be received by the
sequencer.
It if however possible to increase this limit with the set_client_pool()
function. Increase the pool size to at least the quantum_limit * 2.
This ensures we can receive and send at least 2 quantums of raw data,
which should be a fairly long sysex message.
Make a min and max value for the pool size. There is an upper limit of
2000 in the kernel but make this configurable and clamp the final
pool size to the min/max.
Make the MAX_EVENT_SIZE 256, because this is how the sequencer seems to
splits the input data as well and it results in less wasted space in the
output buffer.
See #4005
snd_midi_event_encode() will reset the encoder when it returns an
encoded event. It is possible that the function returns with an encoded
event when the internal buffer is full, in that case we need to push the
event and continue encoding without reseting the encoder.
0 is not a snd_midi_event_encode() error, so don't handle it like
one.
The messages, mostly sysex, can be split over multiple control message.
This happens when we read large messages from the sequencer, the
snd_seq_event_input function returns split messages that we transfer to
control messages directly.
When we send those messages out, however, the encoder wants the complete
message before it will return a valid event that we can send out. Keep
on calling the encoder with the control events until we get a complete
message that we can send out.
Fixes#4005
This fixes an issue introduced in 771f71f622
where the quantum is forced and may break applications the specify their
own quantum.
Signed-off-by: Lukas Rusak <lorusak@gmail.com>
This patch fixes use case, when disable_tsched is set and
api.alsa.period-size is set to value different from default quantum size.
In a such configuration, threshold needs to be set to a final value
before snd_pcm_sw_params_set_avail_min is called to get IRQs with
right timing.
Avail minimum is calculated from a threshold set in the check_position_config.
The method returned different value for threshold right before playback
started and after the playback started. Therefore threshold used in
the snd_pcm_sw_params_set_avail_min was incorrect.
Force the check_position_config to use configured values when called
from spa_alsa_prepare as this method is called when starting new playback
and the state->period_frames and the state->rate are already known.
Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
Without this change, playback_ready or capture_ready was called
immediately after spa_alsa_start even tho start-delay was set.
Ready function was called with not precise "nsec" value, as "nsec"
plus latency should return time when the next buffer should be played
which wasn't true as start-delay was not included.
Now the playback is started immediately when the start_delay is set.
The alsa_do_wakeup_work is still called immediately but two things can
happened. Either start-delay is smaller then max_error and *_ready
function is called immediately, or start-delay is bigger then max_error
and state->next_time will be updated to correct value.
Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
Alsa needs to call handler soon enough to have headroom plus threshold
frames in the buffer and not only threshold left.
Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
Headroom are extra samples available in alsa buffer on top of a threshold.
Its use to prefill alsa buffer with silence before the playback starts
and later its use to calculate target number of a frames in the alsa buffer
when get_status is called. Target is calculated as headroom plus
threshold, which should be smaller then buffer size to make sense.
Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
Signed-off-by: Carlos Rafael Giani <crg7475@mailbox.org>