Make a function that can initialize raw audio info from a dict and fill
in the defaults. We can use this in many of the modules when the audio
format is parsed.
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.
Improve the Latency reporting, we always report Input and Output latency
pairs.
Keep ProcessLatency on the capture and playback streams. The capture
stream process latency is reported as input latency and the playback
process latency as output latency.
Setting ProcessLatency on the capture stream (Sink), for example, will
propagate the added latency upstream. This would then instruct players
to send the audio earlier to compensate for the delay.
See #4270
Convert capture and playback streams to any global channel position that
has been set. This can then be used to implement an upmix sink and add
such an example config.
When we don't set a rate, assume both input and output streams are
following the graph rate and so disable the resampler.
This mostly works around an issue where the input and output could
negotiate to different rates in some cases. With the resampler disabled
this would still result in the same amount of samples going in as
comming out instead of a stuttering mismatch.
See #2969
When one side of the loopback suspends, do a EnumFormat params to force
renegotiation on the other side as well.
Suppose this:
1. sink/filter/pw-play plays at 48000Hz
2. pw-play goes away, sink and filter-sink suspend, filter-playback
idles
3. pw-play starts with 44100Hz
4. sink/filter-sink renegotiate to 44100Hz, filter-playback is still
at 48000Hz and pitch shifted.
We might want to manually suspend the IDLE nodes instead but for now
this is a good workaround.
Fixes#2969
Because the capture triggers the playback stream, the playback stream
might not be actually triggered when the stream is not running.
This can cause a buffer to be queued in the capture side that is never
dequeued from the playback side. If 2 buffers are queued (and 2 buffers
are available on the stream), the capture source has no more buffers and
starts to drop/stutter.
Fix this problem by always dequeueing/queuing all the queued buffers so
that we always use the last one.
See #3276
When one side of the loopback suspends, do a EnumFormat params to force
renegotiation on the other side as well.
Suppose this:
1. sink/filter/pw-play plays at 48000Hz
2. pw-play goes away, sink and filter-sink suspend, filter-playback
idles
3. pw-play starts with 44100Hz
4. sink/filter-sink renegotiate to 44100Hz, filter-playback is still
at 48000Hz and pitch shifted.
We might want to manually suspend the IDLE nodes instead but for now
this is a good workaround.
Fixes#2969
Connect the playback stream before the capture stream since the capture
stream can otherwise trigger playback_process() before the playback node
has been activated.
Modules echo-cancel, filter-chain and loopback may print errors if no
applicable target nodes exist when they start up. For our products this
is not considered error/warning worthy, since the issue will resolve
itself once the target nodes exist.
Add a target.delay.sec property to module-loopback that uses a
ringbuffer to further delay the signal to the requested value. This
also takes into account the graph delay to get an end-to-end delay.
Add a -d property to pw-loopback to control this.
Implement latency_msec on the pulse module with this new property so
that it behaves similar to pulseaudio.
First go over all the input and collect pointers and the size that we
need to copy. Then go over all destinations and copy the source or
clear the buffer memory.
This fixes the problem where extra planes in the destination would get
a 0 size, which would make the converter produce 0 output. It also
ensure that the output size is consistent.
It's possible that the stream is sent an error when the session manager
can't link the node (because, for example, the sink/source is not
available yet). We should not stop but just log this error.
When the session manager actively kills the stream (when it is
reconnected while the DONT_RECONNECT flag is true) we will end up in the
UNCONNECTED state and that's when we can unload the module.