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.
This adds a port, card and profile to RAOP sinks to make it
possible to change the latency at runtime (and have it persist)
using pavucontrol or pactl set-port-latency-offset.
Also move the IP:port part of the sink name to the port name.
Use predefined values depending on the server, and make it configurable.
AirPlay is supposed to have 2s of latency. With my hardware, this is
more 2.352 seconds after numerous tests.
Switch from pausing/resuming the smoother to resetting it because the
smoother got stuck returning the same value after an idle/running cycle,
making latency calculation wrong.
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.
Regression introduced in commit 8c6407f:
raop: Merge TCP and UDP code paths + refactoring
Anyway, we need to determine if initial volume has to be setup before
sending RECORD or after:
- Setting it up *before* shouldn't be a problem: sink.c waits for
CONNECT state, set the volume and client.c triggers RECORD only once
he's got the SET_PARAMETER reply from server.
- Setting it up *after* seems to be more difficult if we try not to
send any audio before receiving the SET_PARAMETER reply form server. A
solution may be to send SET_PARAMETER just after the RECORD server
response is received and hope that it get processed by server during the
2sec latency/buffering time...
Attached patch implement that last solution. Works for me, but I cannot
guaranty it will with your hardware...
This patch switch the packet-buffer to use core memory pool instead of
manually allocating the room required for storing TCP/UDP packets. Packets
are now stored using pa_memchunk instead of internal struct. Quite a few
malloc saved compare to previous design.
TCP and UDP implementation are following two diffrent code path while code
logic is quite the same. This patch merges both code path into a unique one
and, thus, leads to a big refactoring. Major changes include:
- moving sink implementation to a separate file (raop-sink.c)
- move raop-sink.c protocol specific code to raop-client.c
- modernise RTSP session handling in TCP mode
- reduce code duplications between TCP and UDP modes
- introduce authentication support
- TCP mode does not constantly send silent audio anymore
About authentication: OPTIONS is now issued when the sink is preliminary
loaded. Client authentication appends at that time and credential is kept
for the whole sink lifetime. Later RTSP connection will thus look like this:
ANNOUNCE > 200 OK > SETUP > 200 OK > RECORD > 200 OK (no more OPTIONS). This
behaviour is similar to iTunes one.
Also this patch includes file name changes to match Pulseaudio naming
rules, as most of pulseaudio source code files seem to be using '-'
instead of '_' as a word separator.