mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
alsa: increase precision of delay function
pw->time.delay is delay in number of frames in pw->time.rate domain, however snd_pcm_pipewire_delay function is suppose to return number of frames in io->rate domain. Convert pw->time.delay to io->rate domain to increase precision when the io->rate is not equal to the pw->time.rate snd_pcm_pipewire_delay should return how many frames are queued in pipewire, pw_stream_get_time returns numbers of the queued frames before snd_pcm_pipewire_process is called, however this function inserts (or removes) some frames from pipewire. Therefore newly inserted (removed) frames should be added to pw->time.delay to increase precision. Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
This commit is contained in:
parent
925644fbcc
commit
a7d238ed59
1 changed files with 16 additions and 4 deletions
|
|
@ -234,7 +234,7 @@ static int snd_pcm_pipewire_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delay
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static snd_pcm_uframes_t
|
||||
snd_pcm_pipewire_process(snd_pcm_pipewire_t *pw, struct pw_buffer *b,
|
||||
snd_pcm_uframes_t *hw_avail,snd_pcm_uframes_t want)
|
||||
{
|
||||
|
|
@ -319,6 +319,7 @@ snd_pcm_pipewire_process(snd_pcm_pipewire_t *pw, struct pw_buffer *b,
|
|||
|
||||
snd_pcm_areas_silence(pwareas, xfer, io->channels,
|
||||
frames, io->format);
|
||||
xfer += frames;
|
||||
}
|
||||
if (io->state == SND_PCM_STATE_RUNNING ||
|
||||
io->state == SND_PCM_STATE_DRAINING) {
|
||||
|
|
@ -326,7 +327,7 @@ snd_pcm_pipewire_process(snd_pcm_pipewire_t *pw, struct pw_buffer *b,
|
|||
pw->xrun_detected = true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return xfer;
|
||||
}
|
||||
|
||||
static void on_stream_param_changed(void *data, uint32_t id, const struct spa_pod *param)
|
||||
|
|
@ -387,10 +388,16 @@ static void on_stream_process(void *data)
|
|||
snd_pcm_pipewire_t *pw = data;
|
||||
snd_pcm_ioplug_t *io = &pw->io;
|
||||
struct pw_buffer *b;
|
||||
snd_pcm_uframes_t hw_avail, want;
|
||||
snd_pcm_uframes_t hw_avail, want, xfer;
|
||||
|
||||
pw_stream_get_time(pw->stream, &pw->time);
|
||||
|
||||
if (pw->time.rate.num != 0) {
|
||||
pw->time.delay = pw->time.delay * io->rate * pw->time.rate.num / pw->time.rate.denom;
|
||||
pw->time.rate.denom = io->rate;
|
||||
pw->time.rate.num = 1;
|
||||
}
|
||||
|
||||
hw_avail = snd_pcm_ioplug_hw_avail(io, pw->hw_ptr, io->appl_ptr);
|
||||
|
||||
if (pw->drained) {
|
||||
|
|
@ -405,7 +412,12 @@ static void on_stream_process(void *data)
|
|||
want = pw->rate_match ? pw->rate_match->size : hw_avail;
|
||||
pw_log_trace("%p: avail:%lu want:%lu", pw, hw_avail, want);
|
||||
|
||||
snd_pcm_pipewire_process(pw, b, &hw_avail, want);
|
||||
xfer = snd_pcm_pipewire_process(pw, b, &hw_avail, want);
|
||||
|
||||
if (io->stream == SND_PCM_STREAM_PLAYBACK)
|
||||
pw->time.delay += xfer;
|
||||
else
|
||||
pw->time.delay -= SPA_MIN(pw->time.delay, xfer);
|
||||
|
||||
pw_stream_queue_buffer(pw->stream, b);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue