From 0310ad45e93024cf4a72c1620e0f7eb8e251ac46 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Wed, 18 Sep 2019 09:16:58 +0200 Subject: [PATCH] Revert "Allow switching between devices without disconnecting clients." This change was not right: First, upon SIGHUP, next device should be opened before the old one is closed. Second the migration code doesn't reinitialize the conversion layer which breaks audio when switching between devices with different channel counts. This reverts commit 5bc17e6cea0865a32c65a767e3abb6fa774fcc47. --- sndiod/dev.c | 93 ++---------------------------------------------- sndiod/dev.h | 3 +- sndiod/midi.c | 28 ++------------- sndiod/midi.h | 3 +- sndiod/miofile.c | 28 ++------------- sndiod/siofile.c | 43 +++++----------------- sndiod/sndiod.8 | 29 +-------------- sndiod/sndiod.c | 50 +++++--------------------- sndiod/utils.c | 27 -------------- sndiod/utils.h | 8 ----- 10 files changed, 26 insertions(+), 286 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 6e7b00f..ed88446 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -969,8 +969,7 @@ dev_new(char *path, struct aparams *par, return NULL; } d = xmalloc(sizeof(struct dev)); - d->path_list = NULL; - namelist_add(&d->path_list, path); + d->path = xstrdup(path); d->num = dev_sndnum++; d->opt_list = NULL; @@ -1175,94 +1174,6 @@ dev_close(struct dev *d) dev_close_do(d); } -/* - * Close the device, but attempt to migrate everything to a new sndio - * device. - */ -void -dev_reopen(struct dev *d) -{ - struct slot *s; - long long pos; - unsigned int mode, round, bufsz, rate, pstate; - int delta; - - /* not opened */ - if (d->pstate == DEV_CFG) - return; - - if (log_level >= 1) { - dev_log(d); - log_puts(": reopening device\n"); - } - - /* save state */ - mode = d->mode; - round = d->round; - bufsz = d->bufsz; - rate = d->rate; - delta = d->delta; - pstate = d->pstate; - - /* close device */ - dev_close_do(d); - - /* open device */ - if (!dev_open_do(d)) { - if (log_level >= 1) { - dev_log(d); - log_puts(": found no working alternate device\n"); - } - dev_exitall(d); - return; - } - - /* check if new parameters are compatible with old ones */ - if (d->mode != mode || - d->round != round || - d->bufsz != bufsz || - d->rate != rate) { - if (log_level >= 1) { - dev_log(d); - log_puts(": alternate device not compatible\n"); - } - dev_close(d); - return; - } - - /* - * adjust time positions, make anything go back delta ticks, so - * that the new device can start at zero - */ - for (s = d->slot_list; s != NULL; s = s->next) { - pos = (long long)(d->round - delta) * s->round + s->delta_rem; - s->delta_rem = pos % d->round; - s->delta += pos / (int)d->round; - s->delta -= s->round; - if (log_level >= 2) { - slot_log(s); - log_puts(": adjusted: delta -> "); - log_puti(s->delta); - log_puts(", delta_rem -> "); - log_puti(s->delta_rem); - log_puts("\n"); - } - } - if (d->tstate == MMC_RUN) { - d->mtc.delta -= delta * MTC_SEC; - if (log_level >= 2) { - dev_log(d); - log_puts(": adjusted mtc: delta ->"); - log_puti(d->mtc.delta); - log_puts("\n"); - } - } - - /* start the device if needed */ - if (pstate == DEV_RUN) - dev_wakeup(d); -} - int dev_ref(struct dev *d) { @@ -1369,7 +1280,7 @@ dev_del(struct dev *d) } midi_del(d->midi); *p = d->next; - namelist_clear(&d->path_list); + xfree(d->path); xfree(d); } diff --git a/sndiod/dev.h b/sndiod/dev.h index 0fff249..3719d87 100644 --- a/sndiod/dev.h +++ b/sndiod/dev.h @@ -159,7 +159,7 @@ struct dev { #define DEV_INIT 1 /* stopped */ #define DEV_RUN 2 /* playin & recording */ unsigned int pstate; /* one of above */ - struct name *path_list; + char *path; /* sio path */ /* * actual parameters and runtime state (i.e. once opened) @@ -201,7 +201,6 @@ extern struct dev *dev_list; void dev_log(struct dev *); void dev_close(struct dev *); -void dev_reopen(struct dev *); struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); struct dev *dev_bynum(int); diff --git a/sndiod/midi.c b/sndiod/midi.c index 00f941c..971794e 100644 --- a/sndiod/midi.c +++ b/sndiod/midi.c @@ -439,8 +439,7 @@ port_new(char *path, unsigned int mode, int hold) struct port *c; c = xmalloc(sizeof(struct port)); - c->path_list = NULL; - namelist_add(&c->path_list, path); + c->path = xstrdup(path); c->state = PORT_CFG; c->hold = hold; c->midi = midi_new(&port_midiops, c, mode); @@ -470,7 +469,7 @@ port_del(struct port *c) #endif } *p = c->next; - namelist_clear(&c->path_list); + xfree(c->path); xfree(c); } @@ -595,26 +594,3 @@ port_done(struct port *c) if (c->state == PORT_INIT) port_drain(c); } - -void -port_reopen(struct port *p) -{ - if (p->state == PORT_CFG) - return; - - if (log_level >= 1) { - port_log(p); - log_puts(": reopening port\n"); - } - - port_mio_close(p); - - if (!port_mio_open(p)) { - if (log_level >= 1) { - port_log(p); - log_puts(": found no working alternate port\n"); - } - p->state = PORT_CFG; - port_exitall(p); - } -} diff --git a/sndiod/midi.h b/sndiod/midi.h index 26f6e86..67a3563 100644 --- a/sndiod/midi.h +++ b/sndiod/midi.h @@ -88,7 +88,7 @@ struct port { #define PORT_DRAIN 2 unsigned int state; unsigned int num; /* port serial number */ - struct name *path_list; + char *path; int hold; /* hold the port open ? */ struct midi *midi; }; @@ -121,6 +121,5 @@ int port_init(struct port *); void port_done(struct port *); void port_drain(struct port *); int port_close(struct port *); -void port_reopen(struct port *); #endif /* !defined(MIDI_H) */ diff --git a/sndiod/miofile.c b/sndiod/miofile.c index 7669468..5b037f0 100644 --- a/sndiod/miofile.c +++ b/sndiod/miofile.c @@ -44,35 +44,13 @@ struct fileops port_mio_ops = { port_mio_hup }; -/* - * open the port using one of the provided paths - */ -static char * -port_mio_openlist(struct port *c, unsigned int mode) -{ - struct name *n; - - n = c->path_list; - while (1) { - if (n == NULL) - break; - c->mio.hdl = mio_open(n->str, mode, 1); - if (c->mio.hdl != NULL) - return n->str; - n = n->next; - } - return NULL; -} - int port_mio_open(struct port *p) { - char *path; - - path = port_mio_openlist(p, p->midi->mode); + p->mio.hdl = mio_open(p->path, p->midi->mode, 1); if (p->mio.hdl == NULL) return 0; - p->mio.file = file_new(&port_mio_ops, p, path, mio_nfds(p->mio.hdl)); + p->mio.file = file_new(&port_mio_ops, p, p->path, mio_nfds(p->mio.hdl)); return 1; } @@ -150,5 +128,5 @@ port_mio_hup(void *arg) { struct port *p = arg; - port_reopen(p); + port_close(p); } diff --git a/sndiod/siofile.c b/sndiod/siofile.c index 5757623..9f36f8a 100644 --- a/sndiod/siofile.c +++ b/sndiod/siofile.c @@ -83,26 +83,6 @@ dev_sio_timeout(void *arg) dev_close(d); } -/* - * open the device using one of the provided paths - */ -static char * -dev_sio_openlist(struct dev *d, unsigned int mode) -{ - struct name *n; - - n = d->path_list; - while (1) { - if (n == NULL) - break; - d->sio.hdl = sio_open(n->str, mode, 1); - if (d->sio.hdl != NULL) - return n->str; - n = n->next; - } - return NULL; -} - /* * open the device. */ @@ -111,18 +91,17 @@ dev_sio_open(struct dev *d) { struct sio_par par; unsigned int mode = d->mode & (MODE_PLAY | MODE_REC); - char *path; - path = dev_sio_openlist(d, mode); - if (path == NULL) { + d->sio.hdl = sio_open(d->path, mode, 1); + if (d->sio.hdl == NULL) { if (mode != (SIO_PLAY | SIO_REC)) return 0; - path = dev_sio_openlist(d, SIO_PLAY); - if (path != NULL) + d->sio.hdl = sio_open(d->path, SIO_PLAY, 1); + if (d->sio.hdl != NULL) mode = SIO_PLAY; else { - path = dev_sio_openlist(d, SIO_REC); - if (path != NULL) + d->sio.hdl = sio_open(d->path, SIO_REC, 1); + if (d->sio.hdl != NULL) mode = SIO_REC; else return 0; @@ -232,14 +211,8 @@ dev_sio_open(struct dev *d) if (!(mode & MODE_REC)) d->mode &= ~MODE_REC; sio_onmove(d->sio.hdl, dev_sio_onmove, d); - d->sio.file = file_new(&dev_sio_ops, d, path, sio_nfds(d->sio.hdl)); + d->sio.file = file_new(&dev_sio_ops, d, d->path, sio_nfds(d->sio.hdl)); timo_set(&d->sio.watchdog, dev_sio_timeout, d); - if (log_level >= 1) { - dev_log(d); - log_puts(": using "); - log_puts(path); - log_puts("\n"); - } return 1; bad_close: sio_close(d->sio.hdl); @@ -520,5 +493,5 @@ dev_sio_hup(void *arg) log_puts(": disconnected\n"); } #endif - dev_reopen(d); + dev_close(d); } diff --git a/sndiod/sndiod.8 b/sndiod/sndiod.8 index 58b29bf..7c26b0b 100644 --- a/sndiod/sndiod.8 +++ b/sndiod/sndiod.8 @@ -29,12 +29,10 @@ .Op Fl C Ar min : Ns Ar max .Op Fl c Ar min : Ns Ar max .Op Fl e Ar enc -.Op Fl F Ar device .Op Fl f Ar device .Op Fl j Ar flag .Op Fl L Ar addr .Op Fl m Ar mode -.Op Fl Q Ar port .Op Fl q Ar port .Op Fl r Ar rate .Op Fl s Ar name @@ -184,18 +182,6 @@ or Only the signedness and the precision are mandatory. Examples: .Va u8 , s16le , s24le3 , s24le4lsb . -.It Fl F Ar device -Specify an alternate device to use. -If doesn't work, the one given with the last -.Fl f -or -.Fl F -options will be used. -For instance, specifying a USB device following a -PCI device allows -.Nm -to use the USB one preferably when it's connected -and to fall back to the PCI one when it's disconnected. .It Fl f Ar device Add this .Xr sndio 7 @@ -259,15 +245,6 @@ but the same sub-device cannot be used for both recording and monitoring. The default is .Ar play , Ns Ar rec (i.e. full-duplex). -.It Fl Q Ar port -Specify an alternate MIDI port to use. -If doesn't work, the one given with the last -.Fl Q -or -.Fl q -options will be used. -For instance, this allows to replace a USB MIDI controller without -the need to restart programs using it. .It Fl q Ar port Expose the given MIDI port. This allows multiple programs to share the port. @@ -399,15 +376,11 @@ is If .Nm is sent +.Dv SIGHUP , .Dv SIGINT or .Dv SIGTERM , it terminates. -If -.Nm -is sent -.Dv SIGHUP , -it reopens all audio devices and MIDI ports. .Pp By default, when the program cannot accept recorded data fast enough or cannot provide data to play fast enough, diff --git a/sndiod/sndiod.c b/sndiod/sndiod.c index 56cde52..5d3bd73 100644 --- a/sndiod/sndiod.c +++ b/sndiod/sndiod.c @@ -68,7 +68,7 @@ * block size if neither ``-z'' nor ``-b'' is used */ #ifndef DEFAULT_ROUND -#define DEFAULT_ROUND 480 +#define DEFAULT_ROUND 960 #endif /* @@ -86,7 +86,6 @@ #endif void sigint(int); -void sighup(int); void opt_ch(int *, int *); void opt_enc(struct aparams *); int opt_mmc(void); @@ -103,13 +102,12 @@ struct opt *mkopt(char *, struct dev *, int, int, int, int, int, int, int, int); unsigned int log_level = 0; -volatile sig_atomic_t quit_flag = 0, reopen_flag = 0; +volatile sig_atomic_t quit_flag = 0; char usagestr[] = "usage: sndiod [-d] [-a flag] [-b nframes] " - "[-C min:max] [-c min:max]\n\t" - "[-e enc] [-F device] [-f device] [-j flag] [-L addr] [-m mode]\n\t" - "[-Q port] [-q port] [-r rate] [-s name] [-t mode] [-U unit]\n\t" - "[-v volume] [-w flag] [-z nframes]\n"; + "[-C min:max] [-c min:max] [-e enc]\n\t" + "[-f device] [-j flag] [-L addr] [-m mode] [-q port] [-r rate]\n\t" + "[-s name] [-t mode] [-U unit] [-v volume] [-w flag] [-z nframes]\n"; /* * SIGINT handler, it raises the quit flag. If the flag is already set, @@ -124,16 +122,6 @@ sigint(int s) quit_flag = 1; } -/* - * SIGHUP handler, it raises the reopen flag, which requests devices - * to be reopened. - */ -void -sighup(int s) -{ - reopen_flag = 1; -} - void opt_ch(int *rcmin, int *rcmax) { @@ -236,7 +224,6 @@ setsig(void) struct sigaction sa; quit_flag = 0; - reopen_flag = 0; sigfillset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = sigint; @@ -244,7 +231,6 @@ setsig(void) err(1, "sigaction(int) failed"); if (sigaction(SIGTERM, &sa, NULL) == -1) err(1, "sigaction(term) failed"); - sa.sa_handler = sighup; if (sigaction(SIGHUP, &sa, NULL) == -1) err(1, "sigaction(hup) failed"); } @@ -301,8 +287,7 @@ mkdev(char *path, struct aparams *par, struct dev *d; for (d = dev_list; d != NULL; d = d->next) { - if (d->path_list->next == NULL && - strcmp(d->path_list->str, path) == 0) + if (strcmp(d->path, path) == 0) return d; } if (!bufsz && !round) { @@ -324,8 +309,7 @@ mkport(char *path, int hold) struct port *c; for (c = port_list; c != NULL; c = c->next) { - if (c->path_list->next == NULL && - strcmp(c->path_list->str, path) == 0) + if (strcmp(c->path, path) == 0) return c; } c = port_new(path, MODE_MIDIMASK, hold); @@ -391,8 +375,7 @@ main(int argc, char **argv) mode = MODE_PLAY | MODE_REC; tcpaddr_list = NULL; - while ((c = getopt(argc, argv, - "a:b:c:C:de:F:f:j:L:m:Q:q:r:s:t:U:v:w:x:z:")) != -1) { + while ((c = getopt(argc, argv, "a:b:c:C:de:f:j:L:m:q:r:s:t:U:v:w:x:z:")) != -1) { switch (c) { case 'd': log_level++; @@ -449,11 +432,6 @@ main(int argc, char **argv) case 'q': mkport(optarg, hold); break; - case 'Q': - if (port_list == NULL) - errx(1, "-Q %s: no ports defined", optarg); - namelist_add(&port_list->path_list, optarg); - break; case 'a': hold = opt_onoff(); break; @@ -474,11 +452,6 @@ main(int argc, char **argv) mkdev(optarg, &par, 0, bufsz, round, rate, hold, autovol); break; - case 'F': - if (dev_list == NULL) - errx(1, "-F %s: no devices defined", optarg); - namelist_add(&dev_list->path_list, optarg); - break; default: fputs(usagestr, stderr); return 1; @@ -546,13 +519,6 @@ main(int argc, char **argv) for (;;) { if (quit_flag) break; - if (reopen_flag) { - reopen_flag = 0; - for (d = dev_list; d != NULL; d = d->next) - dev_reopen(d); - for (p = port_list; p != NULL; p = p->next) - port_reopen(p); - } if (!file_poll()) break; } diff --git a/sndiod/utils.c b/sndiod/utils.c index bea290b..ebb9fb5 100644 --- a/sndiod/utils.c +++ b/sndiod/utils.c @@ -188,30 +188,3 @@ xstrdup(char *s) memcpy(p, s, size); return p; } - -/* - * copy and append the given string to the name list - */ -void -namelist_add(struct name **list, char *str) -{ - struct name *n; - size_t size; - - size = strlen(str) + 1; - n = xmalloc(sizeof(struct name) + size); - memcpy(n->str, str, size); - n->next = *list; - *list = n; -} - -void -namelist_clear(struct name **list) -{ - struct name *n; - - while ((n = *list) != NULL) { - *list = n->next; - xfree(n); - } -} diff --git a/sndiod/utils.h b/sndiod/utils.h index ca3e089..f11b675 100644 --- a/sndiod/utils.h +++ b/sndiod/utils.h @@ -20,11 +20,6 @@ #include -struct name { - struct name *next; - char str[]; -}; - void log_puts(char *); void log_putx(unsigned long); void log_putu(unsigned long); @@ -36,9 +31,6 @@ void *xmalloc(size_t); char *xstrdup(char *); void xfree(void *); -void namelist_add(struct name **, char *); -void namelist_clear(struct name **); - /* * Log levels: *