Always use the DSP rate on DSP ports for format conversion, not the
previous used rate.
This avoids some resampler reconfiguration as it negotiates a non-passthrough
rate conversion and then switches to passthrough when the rate correction is
done to match the graph rate.
See #2614
libcamera commit 1c4d4801850559d6f919eef5c2ffbaf7675dbc46
changed the return type of libcamera::ControlList::get()
to be std::optional<T>. Adapt the code to this change.
Fixes#2575
By: Kevin Yin
R->A calculation removed: it wasn't valid anyway. No behavior change.
Placed existing A in there directly.
cosh window -> strangely tweaked exp window: remove the discontinuity
at the border, which is wrong for a window function. If A changes in the
future, this window will be better. With the current A, you will not be
able to tell the difference on any graph. (Of course, it's not a cosh
window anymore.)
Fixes#2574
Support Opus as A2DP vendor codec.
The specification for vendor A2DP codec is our Pipewire-specific one, so
it is compatible only with devices running Pipewire.
The device is not know at SelectConfiguration time, so the settings
argument in select_config is currently unused. Pass on a global settings
dict instead, so that codec parameters can be configured.
Also add settings argument to caps_preference_cmp.
Bump codec API version.
Add a flag A2DP_CODEC_FLAG_SINK to incidate a sink endpoint.
Also enum_config and caps_preference_cmp may need to know whether the
codec is being configured for SRC or SNK. Also add the flags argument to
init_props.
Bump codec API version.
a2dp-sink writing duplex data to the BT socket breaks a2dp-source source
polling, also in A2DP source role. Hence, use the timer-based polling
workaround always in duplex mode.
As currently implemented, input format convert channel remap is no-op.
This is because although the out_datas array is permuted, the original
pointer array is not referred to later on, so the only effect is that
the temporary data array is stored in permuted order.
Fix the permutation by permuting the pointers only for the conversion
step.
Make a new noise method called PATTERN and use it to add a slow (every
1024 samples) repeating pattern of -1, 0.
Only use this method when we don't already use triangular dither.
See #2540
Also clamp the amount of input samples we push when flushing. do several
rounds of zero pushing until we have flushed enough.
Handle the cases where no input is needed or no output is generated.
Fixes crashes when downsampling from 96000 to 1000 Hz or so.
The order of attribute changes is random, so it's possible that controlCX is
accessible before the other devices, which marks the device as available but it
actually fails to open. Only consider the device accessible if both control and
PCM devices can be accessed.
This requires reacting to ATTRIB changes of pcm devices as well now.
Fixes#2534
We need to check the last offset against the size of the buffer, not the
remaining size in the buffer.
When the writing is split, this could cause the buffer to be reused
wrongly.
See #2536
Add avx mixer to test and benchmark
Rework and unroll the avx mixer some more.
The SSE one is 10 times faster than the C one, The AVX is 20 times
faster. The SSE2 function is 5 times faster than the C one.
User changing volume via headset buttons should be treated on the same
level as changing from desktop UI. Also initial headset volume should
be considered saved (even though session managers currently ignore the
initial route values on route restore).
Mark route as saved on volume events.
When emitting node, get initial volumes from transport hardware volume,
if available.
The session manager usually overrides these immediately with saved
values, but it's better to show the HW volume when the node first
appears.
The A2DP and HFP profiles may have different volume curves, so trying to
convert volumes between the two can produce undesirable volume spikes.
For example, when one of them is using hardware volume and the other
software.
Fix by separating HFP and A2DP routes.
Let the mixer functions accumulate the intermediate results into a
larger size variable and then clamp to the final precission. This avoids
distortions because of intermediate clamping.
Although the access pattern of the reads are no longer sequential, the
writes are sequential and we don't need to read intermediate values.
Together with the avoided clamping this is probably faster overall.
Add a unit test for the various cases.
When the audioconverter needs more data, let it return NEED_DATA. This
can happen before the ports actually have consumed all the input data.
For example, then the next cycle would require 1024 samples but there
are currently only 16 samples queued, the next cycle will consume the
16 samples and then need another buffer to produce output.
For rt streams, this is not a problem because a new buffer will be
fetched in the next cycle synchronously.
When the stream is async, we can use this NEED_DATA to prefetch a
new buffer so that we have one in the next cycle.
This fixes hickups with async streams that provide random sized
buffers.
Move the setup of the output buffers first.
Then figure out how many samples we need to produce and consume.
Make sure we use the resampler to only convert the input samples that
are needed to produce the output samples.
Fixes some muddled sound with mpv when upmixing.
Remove the redundant remap array.
First set up the array with remapped output pointers in case we
can do passthrough output. Make sure stages write to the remapped
array in passthrough.
Remap the input array after unpack/convert.
This avoid an input and output memcpy in the common case of
remapping.
When we are actively driving the stream and the converter needs more
data, call the stream process function again to get it so that we
don't underrun.
Fixes#2494
a2dp-source as driver does not produce regularly spaced graph cycles,
because A2DP is not isochronous. This causes e.g. crackling for alsa
etc. that expect regular timings. It also does not rate match.
Change a2dp-source to trigger graph on regular intervals. Change recv to
only accumulate data to a buffer, and put data to buffers in process().
Rate match with DLL, keeping average buffer level constant. Keep track
of jitter to determine a safe target value.
Tweak the conversion constants a bit so that they handle the
extreme ranges a bit better.
Align the C and vector instructions.
Reactivate the unit test asserts when a conversion fails.
Do the channel remapping to the cannonical format when we
deinterleave/interleave instead. Otherwise we would completely skip
the remapping when we have interleaved input.
Fixes#2502, #2490
When we get something else that a drain status as input, bring us back
to the non-drained state.
When we are draining, don't remove the drained flag on the input
io status. This needs to be cleared by the host when the draining is
finished.
Fixes speaker-test
Ensure that our temporary buffers can hold at least quantum_limit
samples. When no output or input is connected, we can generate up
to a quantum_limit of silence, which requires all the buffers to
be scaled correctly.
Fixes a segfault in mpv.
Make a new uint42_t and int24_t type and use that to handle 24 bits
samples. This makes it easier because we can iterate and copy the
structs like other types.
Make dither noise as a value between -0.5 and 0.5 and add this
to the scaled samples.
For this, we first need to do the scaling and then the CLAMP to
the target depth. This optimizes to the same code but allows us
to avoid under and overflows when we add the dither noise.
Add more dithering methods.
Expose a dither.method property on audioconvert. Disable dither when
the target depth > 16.
We need to do dithering and noise when converting f32 to the
target format. This is more natural because we can work in 32 bits
integers instead of floats.
This will also make it possible to actually calculate the error between
source and target values and implement some sort of feedback and
noise shaping later.
Move the noise setting in the dither struct so that it can be
handled separately.
Setup dither separately.
Set used cpu_flags in structures after setup.
The quantize is the amount of bits we want to keep from the original
signal, subtract the amount of bits for noise. Clamp this to 0 (all
noise).
Calculate the scale factor better with powf() and avoid overflows.
Fixes#2479
Rename empty.noise -> dither.noise and always add this amount of noise
when > 0. This also adds the noise to silent sounds, not only when
nothing is connected because that would also be a problem when an amp
needs to be kept alive with an non-0 signal.
Rename noise -> dither because we can use this also for dithering later.
See #705
PipeWire v0.3.7 or later hits assertion at alsa-lib mixer API due to
wrong handling of removal event for mixer element.
wireplumber: mixer.c:149: hctl_elem_event_handler: Assertion `bag_empty(bag)' failed.
The removal event is defined as '~0U', thus it's not distinguished from
the other type of event just by bitwise operator.
At the removal event, class implementator for mixer API should detach
mixer element from hcontrol element in callback handler since alsa-lib
has assertion to check the list of mixer elements for a hcontrol element
is empty or not after calling all of handlers. In detail, please refer to
MR to alsa-lib:
* https://github.com/alsa-project/alsa-lib/pull/244
This commit fixes the above two issues. The issue can be regenerated by
`samples/ctl` Python 3 script of alsa-gobject.
* https://github.com/alsa-project/alsa-gobject/
It adds some user-defined elements into sound card 0. When terminated by
SIGINT signal, it removes the elements. Then PulseAudio dies due to the
assertion.
Fixes: 1612f5e4d2 ("alsa-acp: Add libacp based card device")
Using `int` results in UndefinedBehaviorSanitizer errors
when `noise::intensity` is 31 as that would shift the 1 into
the sign bit of a signed integer type.
It is valid for V4L2 devices to not implement any controls. QUERYCTRL
returns ENOTTY in these cases. Enumerating the controls must not fail in
these cases but return no controls.
Add an empty.noise option that specifies the number of bits to
use for noise when the input signal is pure silence.
Some amplifiers can go into suspend mode pretty easily when they
get pure silence. With empty.noise = 1, audioconvert will now generate
a bitpattern that can keep those amplifiers alive, together with
disabling suspend in the session manager.
Fixes#705
Add an EMPTY chunk flag to mark a piece of memory as 'empty'. For audio
this means silence.
Use the empty flag to avoid mixing 0 samples.
Set the empty flag in output buffers on audioconvert.
this->monitor enabled adds an additional port in reconfigure_mode. If
there was already the maximum 64, this will crash.
Make maximum number of ports one larger than max channels to avoid
problems.
Use the NEAREST flag when setting a format. This only works for raw
formats and will update the format with the nearest accepted rate
or channels. We can then query the real configured format and use that
for the converter.
This makes things work when a driver tells us it can do 44100Hz but then
refuses and changes the rate to 48000.
See #2197, #2457, #2455, rhbz#2096193
When there is no input, mix up to a quantum of data. Otherwise we might
send too much data to the next node and cause a delay if it does not
handle this.
Pass MIDI events as they are.
JACK requires NoteOn 0-velocity midi events to be patched to NoteOff
events for compatibility with LV2 plugins. Let's do this patchup in
the JACK layer then and add an option to disable it.
It's best to pass the midi messages unmodified and then patch them up
wherever they need patching up.
Only advance the in_offset with the number of samples that were consumed
by the resampler. In case when the resampler is filling up an old
buffer, this can be less than n_samples.
Fixes a2dp source and possibly others.
Use the offset to skip entries in the sequence array.
Use one loop to handle intermediate and trailing samples.
Fixes an issue where the last chunk of a sequence would be ignored.
Use a wildcard rate for DSP ports.
Handle wildcards for rate and channels.
Calculate required in/out samples using quantum
Limit monitor and output number of samples.
Assume that capture and playback nodes from a device have different
clocks. This enables the adative resampler to match them. A lot of devices
actually have slightly different rates and would work out of the box
with this fix.
Make an exception when the card is configured in the pro audio profile.
Then we force the same clock on all device nodes and avoid resampling
and rate matching. This can still be changed with a session manager
override.