-/* $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 <alex@caoua.org>
*
if (!s->ops || !s->opt->mmc)
continue;
slot_attach(s);
+ s->pstate = SLOT_RUN;
}
d->tstate = MMC_RUN;
dev_midi_full(d);
{
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
*/
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);
}
}
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 {
slot_detach(struct slot *s)
{
struct slot **ps;
+ struct dev *d;
+ long long pos;
#ifdef DEBUG
if (log_level >= 3) {
#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);
}