From 0257ec3971882de5fe9fe18521f863f0b3a024e5 Mon Sep 17 00:00:00 2001 From: ratchov Date: Thu, 28 Jan 2021 11:06:07 +0000 Subject: [PATCH] Make slot_{attach,detach}() the opposite of each other No bahavior change. Now, slot_attach() moves slot's clock forward and puts the slot on device list; slot_detach() does the opposite: remove from device list and move clock backwards. This will allow to detach a client and attach it later in exactly the same state. --- usr.bin/sndiod/dev.c | 72 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/usr.bin/sndiod/dev.c b/usr.bin/sndiod/dev.c index 299a9595a49..2f425dac7d7 100644 --- a/usr.bin/sndiod/dev.c +++ b/usr.bin/sndiod/dev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.c,v 1.78 2021/01/28 11:02:28 ratchov Exp $ */ +/* $OpenBSD: dev.c,v 1.79 2021/01/28 11:06:07 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -1575,6 +1575,7 @@ dev_sync_attach(struct dev *d) if (!s->ops || !s->opt->mmc) continue; slot_attach(s); + s->pstate = SLOT_RUN; } d->tstate = MMC_RUN; dev_midi_full(d); @@ -2000,34 +2001,34 @@ slot_attach(struct slot *s) { struct dev *d = s->dev; long long pos; - int startpos; /* * start the device if not started */ dev_wakeup(d); - /* - * get the current position, the origin is when the first sample - * played and/or recorded - */ - startpos = dev_getpos(d) * (int)s->round / (int)d->round; - /* * adjust initial clock */ - pos = (long long)d->delta * s->round; - s->delta = startpos + pos / (int)d->round; + pos = s->delta_rem + + (long long)s->delta * d->round + + (long long)d->delta * s->round; + s->delta = pos / (int)d->round; s->delta_rem = pos % d->round; + if (s->delta_rem < 0) { + s->delta_rem += d->round; + s->delta--; + } - s->pstate = SLOT_RUN; #ifdef DEBUG if (log_level >= 2) { slot_log(s); log_puts(": attached at "); - log_puti(startpos); - log_puts(", delta = "); - log_puti(d->delta); + log_puti(s->delta); + log_puts(" + "); + log_puti(s->delta_rem); + log_puts("/"); + log_puti(s->round); log_puts("\n"); } #endif @@ -2065,9 +2066,10 @@ slot_ready(struct slot *s) */ if (s->dev->pstate == DEV_CFG) return; - if (!s->opt->mmc) + if (!s->opt->mmc) { slot_attach(s); - else + s->pstate = SLOT_RUN; + } else dev_sync_attach(s->dev); } @@ -2115,6 +2117,13 @@ slot_start(struct slot *s) } s->skip = 0; + /* + * get the current position, the origin is when the first sample + * played and/or recorded + */ + s->delta = dev_getpos(s->dev) * (int)s->round / (int)s->dev->round; + s->delta_rem = 0; + if (s->mode & MODE_PLAY) { s->pstate = SLOT_START; } else { @@ -2130,6 +2139,8 @@ void slot_detach(struct slot *s) { struct slot **ps; + struct dev *d; + long long pos; #ifdef DEBUG if (log_level >= 3) { @@ -2147,6 +2158,35 @@ slot_detach(struct slot *s) #endif } *ps = s->next; + + d = s->dev; + + /* + * adjust clock, go back d->delta ticks so that slot_attach() + * could be called with the resulting state + */ + pos = s->delta_rem + + (long long)s->delta * d->round - + (long long)d->delta * s->round; + s->delta = pos / (int)d->round; + s->delta_rem = pos % d->round; + if (s->delta_rem < 0) { + s->delta_rem += d->round; + s->delta--; + } + +#ifdef DEBUG + if (log_level >= 2) { + slot_log(s); + log_puts(": detached at "); + log_puti(s->delta); + log_puts(" + "); + log_puti(s->delta_rem); + log_puts("/"); + log_puti(d->round); + log_puts("\n"); + } +#endif if (s->mode & MODE_PLAY) dev_mix_adjvol(s->dev); } -- 2.20.1