From eb847f40b4ba7d506b4d19e47f9a0c8fd70314cd Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Sat, 9 Jun 2018 08:05:52 +0200 Subject: [PATCH 01/20] examples: add -n option to rec --- examples/rec.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/examples/rec.c b/examples/rec.c index 326f7f5..0343e44 100644 --- a/examples/rec.c +++ b/examples/rec.c @@ -33,7 +33,8 @@ void usage(void) { fprintf(stderr, - "usage: rec [-b size] [-c nchan] [-e enc] [-r rate]\n"); + "usage: rec [-b size] [-c nchan] [-e enc] [-n nbytes] " + "[-r rate] [-x xrun]\n"); } int @@ -42,7 +43,7 @@ main(int argc, char **argv) int ch; struct sio_hdl *hdl; size_t bufsz; - ssize_t n; + ssize_t n, nbytes; /* * defaults parameters @@ -52,18 +53,19 @@ main(int argc, char **argv) par.bits = 16; par.rchan = 2; par.rate = 48000; + nbytes = -1; - while ((ch = getopt(argc, argv, "r:c:e:b:x:")) != -1) { - switch(ch) { - case 'r': - if (sscanf(optarg, "%u", &par.rate) != 1) { - fprintf(stderr, "%s: bad rate\n", optarg); + while ((ch = getopt(argc, argv, "b:c:e:n:r:x:")) != -1) { + switch (ch) { + case 'b': + if (sscanf(optarg, "%u", &par.appbufsz) != 1) { + fprintf(stderr, "%s: bad buf size\n", optarg); exit(1); } break; case 'c': if (sscanf(optarg, "%u", &par.rchan) != 1) { - fprintf(stderr, "%s: channels number\n", optarg); + fprintf(stderr, "%s: bad channels number\n", optarg); exit(1); } break; @@ -73,9 +75,15 @@ main(int argc, char **argv) exit(1); } break; - case 'b': - if (sscanf(optarg, "%u", &par.appbufsz) != 1) { - fprintf(stderr, "%s: bad buf size\n", optarg); + case 'n': + if (sscanf(optarg, "%zu", &nbytes) != 1) { + fprintf(stderr, "%s: bad bytes count\n", optarg); + exit(1); + } + break; + case 'r': + if (sscanf(optarg, "%u", &par.rate) != 1) { + fprintf(stderr, "%s: bad rate\n", optarg); exit(1); } break; @@ -123,12 +131,16 @@ main(int argc, char **argv) fprintf(stderr, "sio_start() failed\n"); exit(1); } - for (;;) { - n = sio_read(hdl, buf, bufsz); + while (nbytes != 0) { + n = bufsz; + if (nbytes >= 0 && n > nbytes) + n = nbytes; + n = sio_read(hdl, buf, n); if (n == 0) { fprintf(stderr, "sio_write: failed\n"); exit(1); } + nbytes -= n; readpos += n; if (tick) { fprintf(stderr, From 414e011cf6e894ec7b87da60ae287fba44e388b0 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Sat, 9 Jun 2018 08:33:24 +0200 Subject: [PATCH 02/20] sndiod: remove handling of unreachable state in slot_stop() --- sndiod/dev.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index d13ba28..5bdcfdf 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -1867,11 +1867,13 @@ slot_stop(struct slot *s) } #endif if (s->pstate == SLOT_START) { - if (s->mode & MODE_PLAY) { - s->pstate = SLOT_READY; - slot_ready(s); - } else - s->pstate = SLOT_INIT; + /* + * If in rec-only mode, we're already in the READY or + * RUN states. We're here because the play buffer was + * not full enough, try to start so it's drained. + */ + s->pstate = SLOT_READY; + slot_ready(s); } if (s->mode & MODE_RECMASK) abuf_done(&s->sub.buf); From 88e75c3d10ca79b1dcaea29bb7ce82631b8d08ee Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Sat, 9 Jun 2018 09:23:40 +0200 Subject: [PATCH 03/20] sndiod: factor common code of slot_stop() --- sndiod/dev.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 5bdcfdf..269a24f 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -1875,31 +1875,35 @@ slot_stop(struct slot *s) s->pstate = SLOT_READY; slot_ready(s); } + + if (s->tstate != MMC_OFF) + s->tstate = MMC_STOP; + if (s->mode & MODE_RECMASK) abuf_done(&s->sub.buf); - if (s->pstate == SLOT_READY) { + + if (s->pstate == SLOT_RUN) { + if (s->mode & MODE_PLAY) { + /* + * Don't detach, dev_cycle() will do it for us + * when the buffer is drained. + */ + s->pstate = SLOT_STOP; + return; + } + slot_detach(s); + } else { #ifdef DEBUG if (log_level >= 3) { slot_log(s); log_puts(": not drained (blocked by mmc)\n"); } #endif - if (s->mode & MODE_PLAY) - abuf_done(&s->mix.buf); - s->ops->eof(s->arg); - s->pstate = SLOT_INIT; - } else { - /* s->pstate == SLOT_RUN */ - if (s->mode & MODE_PLAY) - s->pstate = SLOT_STOP; - else { - slot_detach(s); - s->pstate = SLOT_INIT; - s->ops->eof(s->arg); - } } - if (s->tstate != MMC_OFF) - s->tstate = MMC_STOP; + if (s->mode & MODE_PLAY) + abuf_done(&s->mix.buf); + s->pstate = SLOT_INIT; + s->ops->eof(s->arg); } void From ddf5e0dfa7cb30c9c6358ba0f18e1185c07d78b8 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Sat, 9 Jun 2018 09:27:27 +0200 Subject: [PATCH 04/20] sndiod: move slot buffer allocations in their own routines --- sndiod/dev.c | 277 ++++++++++++++++++++++++++++----------------------- 1 file changed, 150 insertions(+), 127 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 269a24f..236ac1f 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -78,6 +78,8 @@ void slot_del(struct slot *); void slot_setvol(struct slot *, unsigned int); void slot_attach(struct slot *); void slot_ready(struct slot *); +void slot_allocbufs(struct slot *); +void slot_freebufs(struct slot *); void slot_start(struct slot *); void slot_detach(struct slot *); void slot_stop(struct slot *); @@ -826,15 +828,17 @@ dev_cycle(struct dev *d) * layer, so s->mix.buf.used == 0 and we can * destroy the buffer */ - s->pstate = SLOT_INIT; - abuf_done(&s->mix.buf); - if (s->mix.decbuf) - xfree(s->mix.decbuf); - if (s->mix.resampbuf) - xfree(s->mix.resampbuf); - s->ops->eof(s->arg); *ps = s->next; + s->pstate = SLOT_INIT; + s->ops->eof(s->arg); + slot_freebufs(s); dev_mix_adjvol(d); +#ifdef DEBUG + if (log_level >= 3) { + slot_log(s); + log_puts(": drained\n"); + } +#endif continue; } @@ -1403,6 +1407,138 @@ dev_mmcloc(struct dev *d, unsigned int origin) dev_mmcstart(d); } + +/* + * allocate buffers & conversion chain + */ +void +slot_allocbufs(struct slot *s) +{ + unsigned int slot_nch, dev_nch; + struct dev *d = s->dev; + + if (s->mode & MODE_PLAY) { + s->mix.bpf = s->par.bps * + (s->mix.slot_cmax - s->mix.slot_cmin + 1); + abuf_init(&s->mix.buf, s->appbufsz * s->mix.bpf); + + slot_nch = s->mix.slot_cmax - s->mix.slot_cmin + 1; + dev_nch = s->mix.dev_cmax - s->mix.dev_cmin + 1; + s->mix.decbuf = NULL; + s->mix.resampbuf = NULL; + s->mix.join = 1; + s->mix.expand = 1; + if (s->dup) { + if (dev_nch > slot_nch) + s->mix.expand = dev_nch / slot_nch; + else if (dev_nch < slot_nch) + s->mix.join = slot_nch / dev_nch; + } + cmap_init(&s->mix.cmap, + s->mix.slot_cmin, s->mix.slot_cmax, + s->mix.slot_cmin, s->mix.slot_cmax, + 0, d->pchan - 1, + s->mix.dev_cmin, s->mix.dev_cmax); + if (!aparams_native(&s->par)) { + dec_init(&s->mix.dec, &s->par, slot_nch); + s->mix.decbuf = + xmalloc(s->round * slot_nch * sizeof(adata_t)); + } + if (s->rate != d->rate) { + resamp_init(&s->mix.resamp, s->round, d->round, + slot_nch); + s->mix.resampbuf = + xmalloc(d->round * slot_nch * sizeof(adata_t)); + } + } + + if (s->mode & MODE_RECMASK) { + s->sub.bpf = s->par.bps * + (s->sub.slot_cmax - s->sub.slot_cmin + 1); + abuf_init(&s->sub.buf, s->appbufsz * s->sub.bpf); + + slot_nch = s->sub.slot_cmax - s->sub.slot_cmin + 1; + dev_nch = s->sub.dev_cmax - s->sub.dev_cmin + 1; + s->sub.encbuf = NULL; + s->sub.resampbuf = NULL; + s->sub.join = 1; + s->sub.expand = 1; + if (s->dup) { + if (dev_nch > slot_nch) + s->sub.join = dev_nch / slot_nch; + else if (dev_nch < slot_nch) + s->sub.expand = slot_nch / dev_nch; + } + cmap_init(&s->sub.cmap, + 0, ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1, + s->sub.dev_cmin, s->sub.dev_cmax, + s->sub.slot_cmin, s->sub.slot_cmax, + s->sub.slot_cmin, s->sub.slot_cmax); + if (s->rate != d->rate) { + resamp_init(&s->sub.resamp, d->round, s->round, + slot_nch); + s->sub.resampbuf = + xmalloc(d->round * slot_nch * sizeof(adata_t)); + } + if (!aparams_native(&s->par)) { + enc_init(&s->sub.enc, &s->par, slot_nch); + s->sub.encbuf = + xmalloc(s->round * slot_nch * sizeof(adata_t)); + } + + /* + * cmap_copy() doesn't write samples in all channels, + * for instance when mono->stereo conversion is + * disabled. So we have to prefill cmap_copy() output + * with silence. + */ + if (s->sub.resampbuf) { + memset(s->sub.resampbuf, 0, + d->round * slot_nch * sizeof(adata_t)); + } else if (s->sub.encbuf) { + memset(s->sub.encbuf, 0, + s->round * slot_nch * sizeof(adata_t)); + } else { + memset(s->sub.buf.data, 0, + s->appbufsz * slot_nch * sizeof(adata_t)); + } + } + +#ifdef DEBUG + if (log_level >= 3) { + slot_log(s); + log_puts(": allocated "); + log_putu(s->appbufsz); + log_puts("/"); + log_putu(SLOT_BUFSZ(s)); + log_puts(" fr buffers\n"); + } +#endif +} + +/* + * free buffers & conversion chain + */ +void +slot_freebufs(struct slot *s) +{ + if (s->mode & MODE_RECMASK) { + abuf_done(&s->sub.buf); + if (s->sub.encbuf) + xfree(s->sub.encbuf); + if (s->sub.resampbuf) + xfree(s->sub.resampbuf); + } + + if (s->mode & MODE_PLAY) { + abuf_done(&s->mix.buf); + if (s->mix.decbuf) + xfree(s->mix.decbuf); + if (s->mix.resampbuf) + xfree(s->mix.resampbuf); + } +} + /* * allocate a new slot and register the given call-backs */ @@ -1590,7 +1726,6 @@ void slot_attach(struct slot *s) { struct dev *d = s->dev; - unsigned int slot_nch, dev_nch; long long pos; int startpos; @@ -1640,84 +1775,10 @@ slot_attach(struct slot *s) d->slot_list = s; s->skip = 0; if (s->mode & MODE_PLAY) { - slot_nch = s->mix.slot_cmax - s->mix.slot_cmin + 1; - dev_nch = s->mix.dev_cmax - s->mix.dev_cmin + 1; - s->mix.decbuf = NULL; - s->mix.resampbuf = NULL; - s->mix.join = 1; - s->mix.expand = 1; - if (s->dup) { - if (dev_nch > slot_nch) - s->mix.expand = dev_nch / slot_nch; - else if (dev_nch < slot_nch) - s->mix.join = slot_nch / dev_nch; - } - cmap_init(&s->mix.cmap, - s->mix.slot_cmin, s->mix.slot_cmax, - s->mix.slot_cmin, s->mix.slot_cmax, - 0, d->pchan - 1, - s->mix.dev_cmin, s->mix.dev_cmax); - if (!aparams_native(&s->par)) { - dec_init(&s->mix.dec, &s->par, slot_nch); - s->mix.decbuf = - xmalloc(s->round * slot_nch * sizeof(adata_t)); - } - if (s->rate != d->rate) { - resamp_init(&s->mix.resamp, s->round, d->round, - slot_nch); - s->mix.resampbuf = - xmalloc(d->round * slot_nch * sizeof(adata_t)); - } s->mix.vol = MIDI_TO_ADATA(s->vol); dev_mix_adjvol(d); } if (s->mode & MODE_RECMASK) { - slot_nch = s->sub.slot_cmax - s->sub.slot_cmin + 1; - dev_nch = s->sub.dev_cmax - s->sub.dev_cmin + 1; - s->sub.encbuf = NULL; - s->sub.resampbuf = NULL; - s->sub.join = 1; - s->sub.expand = 1; - if (s->dup) { - if (dev_nch > slot_nch) - s->sub.join = dev_nch / slot_nch; - else if (dev_nch < slot_nch) - s->sub.expand = slot_nch / dev_nch; - } - cmap_init(&s->sub.cmap, - 0, ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1, - s->sub.dev_cmin, s->sub.dev_cmax, - s->sub.slot_cmin, s->sub.slot_cmax, - s->sub.slot_cmin, s->sub.slot_cmax); - if (s->rate != d->rate) { - resamp_init(&s->sub.resamp, d->round, s->round, - slot_nch); - s->sub.resampbuf = - xmalloc(d->round * slot_nch * sizeof(adata_t)); - } - if (!aparams_native(&s->par)) { - enc_init(&s->sub.enc, &s->par, slot_nch); - s->sub.encbuf = - xmalloc(s->round * slot_nch * sizeof(adata_t)); - } - - /* - * cmap_copy() doesn't write samples in all channels, - * for instance when mono->stereo conversion is - * disabled. So we have to prefill cmap_copy() output - * with silence. - */ - if (s->sub.resampbuf) { - memset(s->sub.resampbuf, 0, - d->round * slot_nch * sizeof(adata_t)); - } else if (s->sub.encbuf) { - memset(s->sub.encbuf, 0, - s->round * slot_nch * sizeof(adata_t)); - } else { - memset(s->sub.buf.data, 0, - s->appbufsz * slot_nch * sizeof(adata_t)); - } - /* * N-th recorded block is the N-th played block */ @@ -1753,59 +1814,35 @@ slot_ready(struct slot *s) void slot_start(struct slot *s) { - unsigned int bufsz; #ifdef DEBUG - struct dev *d = s->dev; - - if (s->pstate != SLOT_INIT) { slot_log(s); log_puts(": slot_start: wrong state\n"); panic(); } -#endif - bufsz = s->appbufsz; if (s->mode & MODE_PLAY) { -#ifdef DEBUG if (log_level >= 3) { slot_log(s); log_puts(": playing "); aparams_log(&s->par); log_puts(" -> "); - aparams_log(&d->par); + aparams_log(&s->dev->par); log_puts("\n"); } -#endif - s->mix.bpf = s->par.bps * - (s->mix.slot_cmax - s->mix.slot_cmin + 1); - abuf_init(&s->mix.buf, bufsz * s->mix.bpf); } if (s->mode & MODE_RECMASK) { -#ifdef DEBUG if (log_level >= 3) { slot_log(s); log_puts(": recording "); aparams_log(&s->par); log_puts(" <- "); - aparams_log(&d->par); + aparams_log(&s->dev->par); log_puts("\n"); + } } #endif - s->sub.bpf = s->par.bps * - (s->sub.slot_cmax - s->sub.slot_cmin + 1); - abuf_init(&s->sub.buf, bufsz * s->sub.bpf); - } + slot_allocbufs(s); s->mix.weight = MIDI_TO_ADATA(MIDI_MAXCTL); -#ifdef DEBUG - if (log_level >= 3) { - slot_log(s); - log_puts(": allocated "); - log_putu(s->appbufsz); - log_puts("/"); - log_putu(SLOT_BUFSZ(s)); - log_puts(" fr buffers\n"); - } -#endif if (s->mode & MODE_PLAY) { s->pstate = SLOT_START; } else { @@ -1838,19 +1875,8 @@ slot_detach(struct slot *s) #endif } *ps = s->next; - if (s->mode & MODE_RECMASK) { - if (s->sub.encbuf) - xfree(s->sub.encbuf); - if (s->sub.resampbuf) - xfree(s->sub.resampbuf); - } - if (s->mode & MODE_PLAY) { - if (s->mix.decbuf) - xfree(s->mix.decbuf); - if (s->mix.resampbuf) - xfree(s->mix.resampbuf); + if (s->mode & MODE_PLAY) dev_mix_adjvol(s->dev); - } } /* @@ -1879,9 +1905,6 @@ slot_stop(struct slot *s) if (s->tstate != MMC_OFF) s->tstate = MMC_STOP; - if (s->mode & MODE_RECMASK) - abuf_done(&s->sub.buf); - if (s->pstate == SLOT_RUN) { if (s->mode & MODE_PLAY) { /* @@ -1900,10 +1923,10 @@ slot_stop(struct slot *s) } #endif } - if (s->mode & MODE_PLAY) - abuf_done(&s->mix.buf); + s->pstate = SLOT_INIT; s->ops->eof(s->arg); + slot_freebufs(s); } void From 37ee5aa8710b94499ce2d8cff67d8471e79fa9e1 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Sun, 10 Jun 2018 22:50:35 +0200 Subject: [PATCH 05/20] sndiod: replace the gloal opt list with per-device lists. --- sndiod/dev.c | 4 ++++ sndiod/dev.h | 13 +++++++++++++ sndiod/opt.c | 25 +++++++++++-------------- sndiod/opt.h | 21 +++------------------ sndiod/sndiod.c | 6 ++---- sndiod/sock.c | 9 ++++++--- 6 files changed, 39 insertions(+), 39 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 236ac1f..0af1089 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -24,6 +24,7 @@ #include "dsp.h" #include "siofile.h" #include "midi.h" +#include "opt.h" #include "sysex.h" #include "utils.h" @@ -972,6 +973,7 @@ dev_new(char *path, struct aparams *par, d = xmalloc(sizeof(struct dev)); d->path = xstrdup(path); d->num = dev_sndnum++; + d->opt_list = NULL; /* * XXX: below, we allocate a midi input buffer, since we don't @@ -1239,6 +1241,8 @@ dev_del(struct dev *d) log_puts(": deleting\n"); } #endif + while (d->opt_list != NULL) + opt_del(d, d->opt_list); if (d->pstate != DEV_CFG) dev_close(d); for (p = &dev_list; *p != d; p = &(*p)->next) { diff --git a/sndiod/dev.h b/sndiod/dev.h index 2e35838..036c0e3 100644 --- a/sndiod/dev.h +++ b/sndiod/dev.h @@ -95,12 +95,25 @@ struct slot { unsigned int tstate; /* mmc state */ }; +struct opt { + struct opt *next; +#define OPT_NAMEMAX 11 + char name[OPT_NAMEMAX + 1]; + int maxweight; /* max dynamic range for clients */ + int pmin, pmax; /* play channels */ + int rmin, rmax; /* recording channels */ + int mmc; /* true if MMC control enabled */ + int dup; /* true if join/expand enabled */ + int mode; /* bitmap of MODE_XXX */ +}; + /* * audio device with plenty of slots */ struct dev { struct dev *next; struct slot *slot_list; /* audio streams attached */ + struct opt *opt_list; struct midi *midi; /* diff --git a/sndiod/opt.c b/sndiod/opt.c index bf25d12..53554d8 100644 --- a/sndiod/opt.c +++ b/sndiod/opt.c @@ -20,13 +20,11 @@ #include "opt.h" #include "utils.h" -struct opt *opt_list = NULL; - /* * create a new audio sub-device "configuration" */ struct opt * -opt_new(char *name, struct dev *dev, +opt_new(struct dev *d, char *name, int pmin, int pmax, int rmin, int rmax, int maxweight, int mmc, int dup, unsigned int mode) { @@ -34,7 +32,9 @@ opt_new(char *name, struct dev *dev, unsigned int len; char c; - if (opt_byname(name, dev->num)) { + if (opt_byname(d, name)) { + dev_log(d); + log_puts("."); log_puts(name); log_puts(": already defined\n"); return NULL; @@ -66,12 +66,11 @@ opt_new(char *name, struct dev *dev, o->mmc = mmc; o->dup = dup; o->mode = mode; - o->dev = dev; memcpy(o->name, name, len + 1); - o->next = opt_list; - opt_list = o; + o->next = d->opt_list; + d->opt_list = o; if (log_level >= 2) { - dev_log(o->dev); + dev_log(d); log_puts("."); log_puts(o->name); log_puts(":"); @@ -107,13 +106,11 @@ opt_new(char *name, struct dev *dev, } struct opt * -opt_byname(char *name, unsigned int num) +opt_byname(struct dev *d, char *name) { struct opt *o; - for (o = opt_list; o != NULL; o = o->next) { - if (o->dev->num != num) - continue; + for (o = d->opt_list; o != NULL; o = o->next) { if (strcmp(name, o->name) == 0) return o; } @@ -121,11 +118,11 @@ opt_byname(char *name, unsigned int num) } void -opt_del(struct opt *o) +opt_del(struct dev *d, struct opt *o) { struct opt **po; - for (po = &opt_list; *po != o; po = &(*po)->next) { + for (po = &d->opt_list; *po != o; po = &(*po)->next) { #ifdef DEBUG if (*po == NULL) { log_puts("opt_del: not on list\n"); diff --git a/sndiod/opt.h b/sndiod/opt.h index 4380f7a..b4ae622 100644 --- a/sndiod/opt.h +++ b/sndiod/opt.h @@ -19,24 +19,9 @@ struct dev; -struct opt { - struct opt *next; -#define OPT_NAMEMAX 11 - char name[OPT_NAMEMAX + 1]; - int maxweight; /* max dynamic range for clients */ - int pmin, pmax; /* play channels */ - int rmin, rmax; /* recording channels */ - int mmc; /* true if MMC control enabled */ - int dup; /* true if join/expand enabled */ - int mode; /* bitmap of MODE_XXX */ - struct dev *dev; /* device to which we're attached */ -}; - -extern struct opt *opt_list; - -struct opt *opt_new(char *, struct dev *, int, int, int, int, +struct opt *opt_new(struct dev *, char *, int, int, int, int, int, int, int, unsigned int); -void opt_del(struct opt *); -struct opt *opt_byname(char *, unsigned int); +void opt_del(struct dev *, struct opt *); +struct opt *opt_byname(struct dev *, char *); #endif /* !defined(OPT_H) */ diff --git a/sndiod/sndiod.c b/sndiod/sndiod.c index 8158966..c6acc7c 100644 --- a/sndiod/sndiod.c +++ b/sndiod/sndiod.c @@ -325,7 +325,7 @@ mkopt(char *path, struct dev *d, { struct opt *o; - o = opt_new(path, d, pmin, pmax, rmin, rmax, + o = opt_new(d, path, pmin, pmax, rmin, rmax, MIDI_TO_ADATA(vol), mmc, dup, mode); if (o == NULL) return NULL; @@ -466,7 +466,7 @@ main(int argc, char **argv) if (dev_list == NULL) mkdev(DEFAULT_DEV, &par, 0, bufsz, round, rate, hold, autovol); for (d = dev_list; d != NULL; d = d->next) { - if (opt_byname("default", d->num)) + if (opt_byname(d, "default")) continue; if (mkopt("default", d, pmin, pmax, rmin, rmax, mode, vol, mmc, dup) == NULL) @@ -534,8 +534,6 @@ main(int argc, char **argv) ; /* nothing */ midi_done(); - while (opt_list != NULL) - opt_del(opt_list); while (dev_list) dev_del(dev_list); while (port_list) diff --git a/sndiod/sock.c b/sndiod/sock.c index d8d631b..7fcaf56 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -843,14 +843,17 @@ sock_hello(struct sock *f) return 0; return 1; } - f->opt = opt_byname(p->opt, p->devnum); + d = dev_bynum(p->devnum); + if (d == NULL) + return 0; + f->opt = opt_byname(d, p->opt); if (f->opt == NULL) return 0; #ifdef DEBUG if (log_level >= 3) { sock_log(f); log_puts(": using "); - dev_log(f->opt->dev); + dev_log(d); log_puts("."); log_puts(f->opt->name); log_puts(", mode = "); @@ -869,7 +872,7 @@ sock_hello(struct sock *f) } return 0; } - s = slot_new(f->opt->dev, p->who, &sock_slotops, f, mode); + s = slot_new(d, p->who, &sock_slotops, f, mode); if (s == NULL) return 0; f->midi = NULL; From c42684a889e8a7df3978ac098ecae648aca0f5d7 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:52:40 +0200 Subject: [PATCH 06/20] sndiod: Move opt pointer from the sock to the slot struct. --- sndiod/dev.h | 1 + sndiod/sock.c | 45 +++++++++++++++++++++++---------------------- sndiod/sock.h | 2 -- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/sndiod/dev.h b/sndiod/dev.h index 036c0e3..103180c 100644 --- a/sndiod/dev.h +++ b/sndiod/dev.h @@ -39,6 +39,7 @@ struct slot { struct slotops *ops; /* client callbacks */ struct slot *next; /* next on the play list */ struct dev *dev; /* device this belongs to */ + struct opt *opt; /* config used */ void *arg; /* user data for callbacks */ struct aparams par; /* socket side params */ struct { diff --git a/sndiod/sock.c b/sndiod/sock.c index 7fcaf56..bba2692 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -275,7 +275,6 @@ sock_new(int fd) f = xmalloc(sizeof(struct sock)); f->pstate = SOCK_AUTH; - f->opt = NULL; f->slot = NULL; f->port = NULL; f->midi = NULL; @@ -628,10 +627,10 @@ sock_setpar(struct sock *f) rchan = 1; else if (rchan > NCHAN_MAX) rchan = NCHAN_MAX; - s->sub.slot_cmin = f->opt->rmin; - s->sub.slot_cmax = f->opt->rmin + rchan - 1; - s->sub.dev_cmin = f->opt->rmin; - s->sub.dev_cmax = f->opt->rmax; + s->sub.slot_cmin = s->opt->rmin; + s->sub.slot_cmax = s->opt->rmin + rchan - 1; + s->sub.dev_cmin = s->opt->rmin; + s->sub.dev_cmax = s->opt->rmax; #ifdef DEBUG if (log_level >= 3) { sock_log(f); @@ -652,10 +651,10 @@ sock_setpar(struct sock *f) pchan = 1; else if (pchan > NCHAN_MAX) pchan = NCHAN_MAX; - s->mix.slot_cmin = f->opt->pmin; - s->mix.slot_cmax = f->opt->pmin + pchan - 1; - s->mix.dev_cmin = f->opt->pmin; - s->mix.dev_cmax = f->opt->pmax; + s->mix.slot_cmin = s->opt->pmin; + s->mix.slot_cmax = s->opt->pmin + pchan - 1; + s->mix.dev_cmin = s->opt->pmin; + s->mix.dev_cmax = s->opt->pmax; #ifdef DEBUG if (log_level >= 3) { sock_log(f); @@ -715,7 +714,7 @@ sock_setpar(struct sock *f) return 0; } s->xrun = p->xrun; - if (f->opt->mmc && s->xrun == XRUN_IGNORE) + if (s->opt->mmc && s->xrun == XRUN_IGNORE) s->xrun = XRUN_SYNC; #ifdef DEBUG if (log_level >= 3) { @@ -775,6 +774,7 @@ sock_hello(struct sock *f) struct slot *s; struct port *c; struct dev *d; + struct opt *opt; unsigned int mode; mode = ntohs(p->mode); @@ -846,8 +846,8 @@ sock_hello(struct sock *f) d = dev_bynum(p->devnum); if (d == NULL) return 0; - f->opt = opt_byname(d, p->opt); - if (f->opt == NULL) + opt = opt_byname(d, p->opt); + if (opt == NULL) return 0; #ifdef DEBUG if (log_level >= 3) { @@ -855,17 +855,17 @@ sock_hello(struct sock *f) log_puts(": using "); dev_log(d); log_puts("."); - log_puts(f->opt->name); + log_puts(opt->name); log_puts(", mode = "); log_putx(mode); log_puts("\n"); } #endif - if ((mode & MODE_REC) && (f->opt->mode & MODE_MON)) { + if ((mode & MODE_REC) && (opt->mode & MODE_MON)) { mode |= MODE_MON; mode &= ~MODE_REC; } - if ((mode & f->opt->mode) != mode) { + if ((mode & opt->mode) != mode) { if (log_level >= 1) { sock_log(f); log_puts(": requested mode not allowed\n"); @@ -875,24 +875,25 @@ sock_hello(struct sock *f) s = slot_new(d, p->who, &sock_slotops, f, mode); if (s == NULL) return 0; + s->opt = opt; f->midi = NULL; if (s->mode & MODE_PLAY) { - s->mix.slot_cmin = s->mix.dev_cmin = f->opt->pmin; - s->mix.slot_cmax = s->mix.dev_cmax = f->opt->pmax; + s->mix.slot_cmin = s->mix.dev_cmin = s->opt->pmin; + s->mix.slot_cmax = s->mix.dev_cmax = s->opt->pmax; } if (s->mode & MODE_RECMASK) { - s->sub.slot_cmin = s->sub.dev_cmin = f->opt->rmin; - s->sub.slot_cmax = s->sub.dev_cmax = f->opt->rmax; + s->sub.slot_cmin = s->sub.dev_cmin = s->opt->rmin; + s->sub.slot_cmax = s->sub.dev_cmax = s->opt->rmax; } - if (f->opt->mmc) { + if (s->opt->mmc) { s->xrun = XRUN_SYNC; s->tstate = MMC_STOP; } else { s->xrun = XRUN_IGNORE; s->tstate = MMC_OFF; } - s->mix.maxweight = f->opt->maxweight; - s->dup = f->opt->dup; + s->mix.maxweight = s->opt->maxweight; + s->dup = s->opt->dup; f->slot = s; return 1; } diff --git a/sndiod/sock.h b/sndiod/sock.h index 3cda405..913be1b 100644 --- a/sndiod/sock.h +++ b/sndiod/sock.h @@ -19,7 +19,6 @@ #include "amsg.h" -struct opt; struct file; struct slot; struct midi; @@ -56,7 +55,6 @@ struct sock { unsigned int walign; /* align written data to this */ unsigned int ralign; /* read data is aligned to this */ int lastvol; /* last volume */ - struct opt *opt; /* "subdevice" definition */ struct slot *slot; /* audio device slot number */ struct midi *midi; /* midi endpoint */ struct port *port; /* midi port */ From 426a9064fa68c634cfe1545669e1af7698c2ebd8 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:02 +0200 Subject: [PATCH 07/20] sndiod: Initialize slot with parameters from the opt struct. --- sndiod/dev.c | 38 +++++++++++++++++++++++++++----------- sndiod/dev.h | 3 ++- sndiod/sock.c | 31 +------------------------------ 3 files changed, 30 insertions(+), 42 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 0af1089..ba90580 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -74,7 +74,6 @@ void dev_mmcstop(struct dev *); void dev_mmcloc(struct dev *, unsigned int); void slot_log(struct slot *); -struct slot *slot_new(struct dev *, char *, struct slotops *, void *, int); void slot_del(struct slot *); void slot_setvol(struct slot *, unsigned int); void slot_attach(struct slot *); @@ -1547,7 +1546,8 @@ slot_freebufs(struct slot *s) * allocate a new slot and register the given call-backs */ struct slot * -slot_new(struct dev *d, char *who, struct slotops *ops, void *arg, int mode) +slot_new(struct dev *d, struct opt *opt, char *who, + struct slotops *ops, void *arg, int mode) { char *p; char name[SLOT_NAMEMAX]; @@ -1642,6 +1642,17 @@ slot_new(struct dev *d, char *who, struct slotops *ops, void *arg, int mode) #endif found: + if ((mode & MODE_REC) && (opt->mode & MODE_MON)) { + mode |= MODE_MON; + mode &= ~MODE_REC; + } + if ((mode & opt->mode) != mode) { + if (log_level >= 1) { + slot_log(s); + log_puts(": requested mode not allowed\n"); + } + return 0; + } if (!dev_ref(d)) return NULL; if ((mode & d->mode) != mode) { @@ -1653,27 +1664,32 @@ found: return 0; } s->dev = d; + s->opt = opt; s->ops = ops; s->arg = arg; s->pstate = SLOT_INIT; - s->tstate = MMC_OFF; s->mode = mode; aparams_init(&s->par); if (s->mode & MODE_PLAY) { - s->mix.slot_cmin = s->mix.dev_cmin = 0; - s->mix.slot_cmax = s->mix.dev_cmax = d->pchan - 1; + s->mix.slot_cmin = s->mix.dev_cmin = s->opt->pmin; + s->mix.slot_cmax = s->mix.dev_cmax = s->opt->pmax; } if (s->mode & MODE_RECMASK) { - s->sub.slot_cmin = s->sub.dev_cmin = 0; - s->sub.slot_cmax = s->sub.dev_cmax = - ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1; + s->sub.slot_cmin = s->sub.dev_cmin = s->opt->rmin; + s->sub.slot_cmax = s->sub.dev_cmax = s->opt->rmax; } - s->xrun = XRUN_IGNORE; - s->dup = 0; + if (s->opt->mmc) { + s->xrun = XRUN_SYNC; + s->tstate = MMC_STOP; + } else { + s->xrun = XRUN_IGNORE; + s->tstate = MMC_OFF; + } + s->mix.maxweight = s->opt->maxweight; + s->dup = s->opt->dup; s->appbufsz = d->bufsz; s->round = d->round; s->rate = d->rate; - s->mix.maxweight = ADATA_UNIT; dev_midi_slotdesc(d, s); dev_midi_vol(d, s); return s; diff --git a/sndiod/dev.h b/sndiod/dev.h index 103180c..24296ea 100644 --- a/sndiod/dev.h +++ b/sndiod/dev.h @@ -237,7 +237,8 @@ void dev_midi_vol(struct dev *, struct slot *); * sio_open(3) like interface for clients */ void slot_log(struct slot *); -struct slot *slot_new(struct dev *, char *, struct slotops *, void *, int); +struct slot *slot_new(struct dev *, struct opt *, char *, + struct slotops *, void *, int); void slot_del(struct slot *); void slot_setvol(struct slot *, unsigned int); void slot_start(struct slot *); diff --git a/sndiod/sock.c b/sndiod/sock.c index bba2692..3074f08 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -861,39 +861,10 @@ sock_hello(struct sock *f) log_puts("\n"); } #endif - if ((mode & MODE_REC) && (opt->mode & MODE_MON)) { - mode |= MODE_MON; - mode &= ~MODE_REC; - } - if ((mode & opt->mode) != mode) { - if (log_level >= 1) { - sock_log(f); - log_puts(": requested mode not allowed\n"); - } - return 0; - } - s = slot_new(d, p->who, &sock_slotops, f, mode); + s = slot_new(d, opt, p->who, &sock_slotops, f, mode); if (s == NULL) return 0; - s->opt = opt; f->midi = NULL; - if (s->mode & MODE_PLAY) { - s->mix.slot_cmin = s->mix.dev_cmin = s->opt->pmin; - s->mix.slot_cmax = s->mix.dev_cmax = s->opt->pmax; - } - if (s->mode & MODE_RECMASK) { - s->sub.slot_cmin = s->sub.dev_cmin = s->opt->rmin; - s->sub.slot_cmax = s->sub.dev_cmax = s->opt->rmax; - } - if (s->opt->mmc) { - s->xrun = XRUN_SYNC; - s->tstate = MMC_STOP; - } else { - s->xrun = XRUN_IGNORE; - s->tstate = MMC_OFF; - } - s->mix.maxweight = s->opt->maxweight; - s->dup = s->opt->dup; f->slot = s; return 1; } From e20bc384e35fb1c1799dee77045ba3fe97f1200e Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:04 +0200 Subject: [PATCH 08/20] sndiod: Don't set constant {slot,dev}_cmin parameters. --- sndiod/sock.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sndiod/sock.c b/sndiod/sock.c index 3074f08..cb09f22 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -627,9 +627,7 @@ sock_setpar(struct sock *f) rchan = 1; else if (rchan > NCHAN_MAX) rchan = NCHAN_MAX; - s->sub.slot_cmin = s->opt->rmin; s->sub.slot_cmax = s->opt->rmin + rchan - 1; - s->sub.dev_cmin = s->opt->rmin; s->sub.dev_cmax = s->opt->rmax; #ifdef DEBUG if (log_level >= 3) { @@ -651,9 +649,7 @@ sock_setpar(struct sock *f) pchan = 1; else if (pchan > NCHAN_MAX) pchan = NCHAN_MAX; - s->mix.slot_cmin = s->opt->pmin; s->mix.slot_cmax = s->opt->pmin + pchan - 1; - s->mix.dev_cmin = s->opt->pmin; s->mix.dev_cmax = s->opt->pmax; #ifdef DEBUG if (log_level >= 3) { From 9eef11f53b97291c9d2eb1c357843d597f7a52a2 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:07 +0200 Subject: [PATCH 09/20] sndiod: Use opt->maxweight and remove slot->maxweight. --- sndiod/dev.c | 7 +++---- sndiod/dev.h | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index ba90580..b5dfc78 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -640,8 +640,8 @@ dev_mix_adjvol(struct dev *d) } weight /= n; } - if (weight > i->mix.maxweight) - weight = i->mix.maxweight; + if (weight > i->opt->maxweight) + weight = i->opt->maxweight; i->mix.weight = ADATA_MUL(weight, MIDI_TO_ADATA(d->master)); #ifdef DEBUG if (log_level >= 3) { @@ -649,7 +649,7 @@ dev_mix_adjvol(struct dev *d) log_puts(": set weight: "); log_puti(i->mix.weight); log_puts("/"); - log_puti(i->mix.maxweight); + log_puti(i->opt->maxweight); log_puts("\n"); } #endif @@ -1685,7 +1685,6 @@ found: s->xrun = XRUN_IGNORE; s->tstate = MMC_OFF; } - s->mix.maxweight = s->opt->maxweight; s->dup = s->opt->dup; s->appbufsz = d->bufsz; s->round = d->round; diff --git a/sndiod/dev.h b/sndiod/dev.h index 24296ea..a5693a0 100644 --- a/sndiod/dev.h +++ b/sndiod/dev.h @@ -44,7 +44,6 @@ struct slot { struct aparams par; /* socket side params */ struct { int weight; /* dynamic range */ - int maxweight; /* max dynamic range allowed */ unsigned int vol; /* volume within the vol */ struct abuf buf; /* socket side buffer */ int bpf; /* byte per frame */ From 72c6c0a9b8a27a21cf76c83144ba1ed85cf922cc Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:09 +0200 Subject: [PATCH 10/20] sndiod: Use opt->dup and remove slot->dup. --- sndiod/dev.c | 5 ++--- sndiod/dev.h | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index b5dfc78..84d42dc 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -1431,7 +1431,7 @@ slot_allocbufs(struct slot *s) s->mix.resampbuf = NULL; s->mix.join = 1; s->mix.expand = 1; - if (s->dup) { + if (s->opt->dup) { if (dev_nch > slot_nch) s->mix.expand = dev_nch / slot_nch; else if (dev_nch < slot_nch) @@ -1466,7 +1466,7 @@ slot_allocbufs(struct slot *s) s->sub.resampbuf = NULL; s->sub.join = 1; s->sub.expand = 1; - if (s->dup) { + if (s->opt->dup) { if (dev_nch > slot_nch) s->sub.join = dev_nch / slot_nch; else if (dev_nch < slot_nch) @@ -1685,7 +1685,6 @@ found: s->xrun = XRUN_IGNORE; s->tstate = MMC_OFF; } - s->dup = s->opt->dup; s->appbufsz = d->bufsz; s->round = d->round; s->rate = d->rate; diff --git a/sndiod/dev.h b/sndiod/dev.h index a5693a0..c0c4fff 100644 --- a/sndiod/dev.h +++ b/sndiod/dev.h @@ -71,7 +71,6 @@ struct slot { } sub; int xrun; /* underrun policy */ int skip; /* cycles to skip (for xrun) */ - int dup; /* mono-to-stereo and alike */ #define SLOT_BUFSZ(s) \ ((s)->appbufsz + (s)->dev->bufsz / (s)->dev->round * (s)->round) int appbufsz; /* slot-side buffer size */ From 5754ba39865dbc3c1678f0398cbb3014810468e0 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:11 +0200 Subject: [PATCH 11/20] sndiod: Remove dev_{cmin,cmax} from slot struct, use those in opt struct. --- sndiod/dev.c | 16 ++++++++-------- sndiod/dev.h | 2 -- sndiod/sock.c | 10 ++++------ 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 84d42dc..0532dfa 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -1426,7 +1426,7 @@ slot_allocbufs(struct slot *s) abuf_init(&s->mix.buf, s->appbufsz * s->mix.bpf); slot_nch = s->mix.slot_cmax - s->mix.slot_cmin + 1; - dev_nch = s->mix.dev_cmax - s->mix.dev_cmin + 1; + dev_nch = s->opt->pmax - s->opt->pmin + 1; s->mix.decbuf = NULL; s->mix.resampbuf = NULL; s->mix.join = 1; @@ -1441,7 +1441,7 @@ slot_allocbufs(struct slot *s) s->mix.slot_cmin, s->mix.slot_cmax, s->mix.slot_cmin, s->mix.slot_cmax, 0, d->pchan - 1, - s->mix.dev_cmin, s->mix.dev_cmax); + s->opt->pmin, s->opt->pmax); if (!aparams_native(&s->par)) { dec_init(&s->mix.dec, &s->par, slot_nch); s->mix.decbuf = @@ -1461,7 +1461,7 @@ slot_allocbufs(struct slot *s) abuf_init(&s->sub.buf, s->appbufsz * s->sub.bpf); slot_nch = s->sub.slot_cmax - s->sub.slot_cmin + 1; - dev_nch = s->sub.dev_cmax - s->sub.dev_cmin + 1; + dev_nch = s->opt->rmax - s->opt->rmin + 1; s->sub.encbuf = NULL; s->sub.resampbuf = NULL; s->sub.join = 1; @@ -1474,7 +1474,7 @@ slot_allocbufs(struct slot *s) } cmap_init(&s->sub.cmap, 0, ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1, - s->sub.dev_cmin, s->sub.dev_cmax, + s->opt->rmin, s->opt->rmax, s->sub.slot_cmin, s->sub.slot_cmax, s->sub.slot_cmin, s->sub.slot_cmax); if (s->rate != d->rate) { @@ -1671,12 +1671,12 @@ found: s->mode = mode; aparams_init(&s->par); if (s->mode & MODE_PLAY) { - s->mix.slot_cmin = s->mix.dev_cmin = s->opt->pmin; - s->mix.slot_cmax = s->mix.dev_cmax = s->opt->pmax; + s->mix.slot_cmin = s->opt->pmin; + s->mix.slot_cmax = s->opt->pmax; } if (s->mode & MODE_RECMASK) { - s->sub.slot_cmin = s->sub.dev_cmin = s->opt->rmin; - s->sub.slot_cmax = s->sub.dev_cmax = s->opt->rmax; + s->sub.slot_cmin = s->opt->rmin; + s->sub.slot_cmax = s->opt->rmax; } if (s->opt->mmc) { s->xrun = XRUN_SYNC; diff --git a/sndiod/dev.h b/sndiod/dev.h index c0c4fff..fd9f23f 100644 --- a/sndiod/dev.h +++ b/sndiod/dev.h @@ -48,7 +48,6 @@ struct slot { struct abuf buf; /* socket side buffer */ int bpf; /* byte per frame */ int slot_cmin, slot_cmax; /* slot source chans */ - int dev_cmin, dev_cmax; /* device destination chans */ struct cmap cmap; /* channel mapper state */ struct resamp resamp; /* resampler state */ struct conv dec; /* format decoder params */ @@ -61,7 +60,6 @@ struct slot { int prime; /* initial cycles to skip */ int bpf; /* byte per frame */ int slot_cmin, slot_cmax; /* slot destination chans */ - int dev_cmin, dev_cmax; /* device source chans */ struct cmap cmap; /* channel mapper state */ struct resamp resamp; /* buffer for resampling */ struct conv enc; /* buffer for encoding */ diff --git a/sndiod/sock.c b/sndiod/sock.c index cb09f22..2b6f7de 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -628,14 +628,13 @@ sock_setpar(struct sock *f) else if (rchan > NCHAN_MAX) rchan = NCHAN_MAX; s->sub.slot_cmax = s->opt->rmin + rchan - 1; - s->sub.dev_cmax = s->opt->rmax; #ifdef DEBUG if (log_level >= 3) { sock_log(f); log_puts(": recording channels "); - log_putu(s->sub.dev_cmin); + log_putu(s->opt->rmin); log_puts(":"); - log_putu(s->sub.dev_cmax); + log_putu(s->opt->rmax); log_puts(" -> "); log_putu(s->sub.slot_cmin); log_puts(":"); @@ -650,7 +649,6 @@ sock_setpar(struct sock *f) else if (pchan > NCHAN_MAX) pchan = NCHAN_MAX; s->mix.slot_cmax = s->opt->pmin + pchan - 1; - s->mix.dev_cmax = s->opt->pmax; #ifdef DEBUG if (log_level >= 3) { sock_log(f); @@ -659,9 +657,9 @@ sock_setpar(struct sock *f) log_puts(":"); log_putu(s->mix.slot_cmax); log_puts(" -> "); - log_putu(s->mix.dev_cmin); + log_putu(s->opt->pmin); log_puts(":"); - log_putu(s->mix.dev_cmax); + log_putu(s->opt->pmax); log_puts("\n"); } #endif From 8be24309cb20d2f134ab4d7b5328a33e3d9f284b Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:15 +0200 Subject: [PATCH 12/20] sndiod: Remove {mix,sub}.slot_cmin, already available un opt struct. --- sndiod/dev.c | 28 ++++++++++++---------------- sndiod/dev.h | 4 ++-- sndiod/sock.c | 12 ++++++------ 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 0532dfa..6f8fa83 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -634,8 +634,8 @@ dev_mix_adjvol(struct dev *d) for (j = d->slot_list; j != NULL; j = j->next) { if (!(j->mode & MODE_PLAY)) continue; - if (i->mix.slot_cmin <= j->mix.slot_cmax && - i->mix.slot_cmax >= j->mix.slot_cmin) + if (i->opt->pmin <= j->mix.slot_cmax && + i->mix.slot_cmax >= j->opt->pmin) n++; } weight /= n; @@ -1422,10 +1422,10 @@ slot_allocbufs(struct slot *s) if (s->mode & MODE_PLAY) { s->mix.bpf = s->par.bps * - (s->mix.slot_cmax - s->mix.slot_cmin + 1); + (s->mix.slot_cmax - s->opt->pmin + 1); abuf_init(&s->mix.buf, s->appbufsz * s->mix.bpf); - slot_nch = s->mix.slot_cmax - s->mix.slot_cmin + 1; + slot_nch = s->mix.slot_cmax - s->opt->pmin + 1; dev_nch = s->opt->pmax - s->opt->pmin + 1; s->mix.decbuf = NULL; s->mix.resampbuf = NULL; @@ -1438,8 +1438,8 @@ slot_allocbufs(struct slot *s) s->mix.join = slot_nch / dev_nch; } cmap_init(&s->mix.cmap, - s->mix.slot_cmin, s->mix.slot_cmax, - s->mix.slot_cmin, s->mix.slot_cmax, + s->opt->pmin, s->mix.slot_cmax, + s->opt->pmin, s->mix.slot_cmax, 0, d->pchan - 1, s->opt->pmin, s->opt->pmax); if (!aparams_native(&s->par)) { @@ -1457,10 +1457,10 @@ slot_allocbufs(struct slot *s) if (s->mode & MODE_RECMASK) { s->sub.bpf = s->par.bps * - (s->sub.slot_cmax - s->sub.slot_cmin + 1); + (s->sub.slot_cmax - s->opt->rmin + 1); abuf_init(&s->sub.buf, s->appbufsz * s->sub.bpf); - slot_nch = s->sub.slot_cmax - s->sub.slot_cmin + 1; + slot_nch = s->sub.slot_cmax - s->opt->rmin + 1; dev_nch = s->opt->rmax - s->opt->rmin + 1; s->sub.encbuf = NULL; s->sub.resampbuf = NULL; @@ -1475,8 +1475,8 @@ slot_allocbufs(struct slot *s) cmap_init(&s->sub.cmap, 0, ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1, s->opt->rmin, s->opt->rmax, - s->sub.slot_cmin, s->sub.slot_cmax, - s->sub.slot_cmin, s->sub.slot_cmax); + s->opt->rmin, s->sub.slot_cmax, + s->opt->rmin, s->sub.slot_cmax); if (s->rate != d->rate) { resamp_init(&s->sub.resamp, d->round, s->round, slot_nch); @@ -1670,14 +1670,10 @@ found: s->pstate = SLOT_INIT; s->mode = mode; aparams_init(&s->par); - if (s->mode & MODE_PLAY) { - s->mix.slot_cmin = s->opt->pmin; + if (s->mode & MODE_PLAY) s->mix.slot_cmax = s->opt->pmax; - } - if (s->mode & MODE_RECMASK) { - s->sub.slot_cmin = s->opt->rmin; + if (s->mode & MODE_RECMASK) s->sub.slot_cmax = s->opt->rmax; - } if (s->opt->mmc) { s->xrun = XRUN_SYNC; s->tstate = MMC_STOP; diff --git a/sndiod/dev.h b/sndiod/dev.h index fd9f23f..361e446 100644 --- a/sndiod/dev.h +++ b/sndiod/dev.h @@ -47,7 +47,7 @@ struct slot { unsigned int vol; /* volume within the vol */ struct abuf buf; /* socket side buffer */ int bpf; /* byte per frame */ - int slot_cmin, slot_cmax; /* slot source chans */ + int slot_cmax; /* slot source chans */ struct cmap cmap; /* channel mapper state */ struct resamp resamp; /* resampler state */ struct conv dec; /* format decoder params */ @@ -59,7 +59,7 @@ struct slot { struct abuf buf; /* socket side buffer */ int prime; /* initial cycles to skip */ int bpf; /* byte per frame */ - int slot_cmin, slot_cmax; /* slot destination chans */ + int slot_cmax; /* slot destination chans */ struct cmap cmap; /* channel mapper state */ struct resamp resamp; /* buffer for resampling */ struct conv enc; /* buffer for encoding */ diff --git a/sndiod/sock.c b/sndiod/sock.c index 2b6f7de..82f7f64 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -636,7 +636,7 @@ sock_setpar(struct sock *f) log_puts(":"); log_putu(s->opt->rmax); log_puts(" -> "); - log_putu(s->sub.slot_cmin); + log_putu(s->opt->rmin); log_puts(":"); log_putu(s->sub.slot_cmax); log_puts("\n"); @@ -653,7 +653,7 @@ sock_setpar(struct sock *f) if (log_level >= 3) { sock_log(f); log_puts(": playback channels "); - log_putu(s->mix.slot_cmin); + log_putu(s->opt->pmin); log_puts(":"); log_putu(s->mix.slot_cmax); log_puts(" -> "); @@ -1011,13 +1011,13 @@ sock_execmsg(struct sock *f) aparams_log(&s->par); if (s->mode & MODE_PLAY) { log_puts(", play "); - log_puti(s->mix.slot_cmin); + log_puti(s->opt->pmin); log_puts(":"); log_puti(s->mix.slot_cmax); } if (s->mode & MODE_RECMASK) { log_puts(", rec "); - log_puti(s->sub.slot_cmin); + log_puti(s->opt->rmin); log_puts(":"); log_puti(s->sub.slot_cmax); } @@ -1124,11 +1124,11 @@ sock_execmsg(struct sock *f) m->u.par.msb = s->par.msb; if (s->mode & MODE_PLAY) { m->u.par.pchan = htons(s->mix.slot_cmax - - s->mix.slot_cmin + 1); + s->opt->pmin + 1); } if (s->mode & MODE_RECMASK) { m->u.par.rchan = htons(s->sub.slot_cmax - - s->sub.slot_cmin + 1); + s->opt->rmin + 1); } m->u.par.rate = htonl(s->rate); m->u.par.appbufsz = htonl(s->appbufsz); From 35cff61693bb826833eaffbaede26af70967b335 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:17 +0200 Subject: [PATCH 13/20] sndiod: Instead of the max, use the number of chans in the slot struct. --- sndiod/dev.c | 68 +++++++++++++++++++++++++-------------------------- sndiod/dev.h | 4 +-- sndiod/sock.c | 24 ++++++++---------- 3 files changed, 45 insertions(+), 51 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 6f8fa83..1f8eb32 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -619,11 +619,12 @@ dev_mix_adjvol(struct dev *d) { unsigned int n; struct slot *i, *j; - int weight; + int jcmax, icmax, weight; for (i = d->slot_list; i != NULL; i = i->next) { if (!(i->mode & MODE_PLAY)) continue; + icmax = i->opt->pmin + i->mix.nch - 1; weight = ADATA_UNIT; if (d->autovol) { /* @@ -634,8 +635,9 @@ dev_mix_adjvol(struct dev *d) for (j = d->slot_list; j != NULL; j = j->next) { if (!(j->mode & MODE_PLAY)) continue; - if (i->opt->pmin <= j->mix.slot_cmax && - i->mix.slot_cmax >= j->opt->pmin) + jcmax = j->opt->pmin + j->mix.nch - 1; + if (i->opt->pmin <= jcmax && + icmax >= j->opt->pmin) n++; } weight /= n; @@ -1417,76 +1419,72 @@ dev_mmcloc(struct dev *d, unsigned int origin) void slot_allocbufs(struct slot *s) { - unsigned int slot_nch, dev_nch; + unsigned int dev_nch; struct dev *d = s->dev; if (s->mode & MODE_PLAY) { - s->mix.bpf = s->par.bps * - (s->mix.slot_cmax - s->opt->pmin + 1); + s->mix.bpf = s->par.bps * s->mix.nch; abuf_init(&s->mix.buf, s->appbufsz * s->mix.bpf); - slot_nch = s->mix.slot_cmax - s->opt->pmin + 1; dev_nch = s->opt->pmax - s->opt->pmin + 1; s->mix.decbuf = NULL; s->mix.resampbuf = NULL; s->mix.join = 1; s->mix.expand = 1; if (s->opt->dup) { - if (dev_nch > slot_nch) - s->mix.expand = dev_nch / slot_nch; - else if (dev_nch < slot_nch) - s->mix.join = slot_nch / dev_nch; + if (dev_nch > s->mix.nch) + s->mix.expand = dev_nch / s->mix.nch; + else if (dev_nch < s->mix.nch) + s->mix.join = s->mix.nch / dev_nch; } cmap_init(&s->mix.cmap, - s->opt->pmin, s->mix.slot_cmax, - s->opt->pmin, s->mix.slot_cmax, + s->opt->pmin, s->opt->pmin + s->mix.nch - 1, + s->opt->pmin, s->opt->pmin + s->mix.nch - 1, 0, d->pchan - 1, s->opt->pmin, s->opt->pmax); if (!aparams_native(&s->par)) { - dec_init(&s->mix.dec, &s->par, slot_nch); + dec_init(&s->mix.dec, &s->par, s->mix.nch); s->mix.decbuf = - xmalloc(s->round * slot_nch * sizeof(adata_t)); + xmalloc(s->round * s->mix.nch * sizeof(adata_t)); } if (s->rate != d->rate) { resamp_init(&s->mix.resamp, s->round, d->round, - slot_nch); + s->mix.nch); s->mix.resampbuf = - xmalloc(d->round * slot_nch * sizeof(adata_t)); + xmalloc(d->round * s->mix.nch * sizeof(adata_t)); } } if (s->mode & MODE_RECMASK) { - s->sub.bpf = s->par.bps * - (s->sub.slot_cmax - s->opt->rmin + 1); + s->sub.bpf = s->par.bps * s->sub.nch; abuf_init(&s->sub.buf, s->appbufsz * s->sub.bpf); - slot_nch = s->sub.slot_cmax - s->opt->rmin + 1; dev_nch = s->opt->rmax - s->opt->rmin + 1; s->sub.encbuf = NULL; s->sub.resampbuf = NULL; s->sub.join = 1; s->sub.expand = 1; if (s->opt->dup) { - if (dev_nch > slot_nch) - s->sub.join = dev_nch / slot_nch; - else if (dev_nch < slot_nch) - s->sub.expand = slot_nch / dev_nch; + if (dev_nch > s->sub.nch) + s->sub.join = dev_nch / s->sub.nch; + else if (dev_nch < s->sub.nch) + s->sub.expand = s->sub.nch / dev_nch; } cmap_init(&s->sub.cmap, 0, ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1, s->opt->rmin, s->opt->rmax, - s->opt->rmin, s->sub.slot_cmax, - s->opt->rmin, s->sub.slot_cmax); + s->opt->rmin, s->opt->rmin + s->sub.nch - 1, + s->opt->rmin, s->opt->rmin + s->sub.nch - 1); if (s->rate != d->rate) { resamp_init(&s->sub.resamp, d->round, s->round, - slot_nch); + s->sub.nch); s->sub.resampbuf = - xmalloc(d->round * slot_nch * sizeof(adata_t)); + xmalloc(d->round * s->sub.nch * sizeof(adata_t)); } if (!aparams_native(&s->par)) { - enc_init(&s->sub.enc, &s->par, slot_nch); + enc_init(&s->sub.enc, &s->par, s->sub.nch); s->sub.encbuf = - xmalloc(s->round * slot_nch * sizeof(adata_t)); + xmalloc(s->round * s->sub.nch * sizeof(adata_t)); } /* @@ -1497,13 +1495,13 @@ slot_allocbufs(struct slot *s) */ if (s->sub.resampbuf) { memset(s->sub.resampbuf, 0, - d->round * slot_nch * sizeof(adata_t)); + d->round * s->sub.nch * sizeof(adata_t)); } else if (s->sub.encbuf) { memset(s->sub.encbuf, 0, - s->round * slot_nch * sizeof(adata_t)); + s->round * s->sub.nch * sizeof(adata_t)); } else { memset(s->sub.buf.data, 0, - s->appbufsz * slot_nch * sizeof(adata_t)); + s->appbufsz * s->sub.nch * sizeof(adata_t)); } } @@ -1671,9 +1669,9 @@ found: s->mode = mode; aparams_init(&s->par); if (s->mode & MODE_PLAY) - s->mix.slot_cmax = s->opt->pmax; + s->mix.nch = s->opt->pmax - s->opt->pmin + 1; if (s->mode & MODE_RECMASK) - s->sub.slot_cmax = s->opt->rmax; + s->sub.nch = s->opt->rmax - s->opt->rmin + 1; if (s->opt->mmc) { s->xrun = XRUN_SYNC; s->tstate = MMC_STOP; diff --git a/sndiod/dev.h b/sndiod/dev.h index 361e446..ba784aa 100644 --- a/sndiod/dev.h +++ b/sndiod/dev.h @@ -47,7 +47,7 @@ struct slot { unsigned int vol; /* volume within the vol */ struct abuf buf; /* socket side buffer */ int bpf; /* byte per frame */ - int slot_cmax; /* slot source chans */ + int nch; /* number of play chans */ struct cmap cmap; /* channel mapper state */ struct resamp resamp; /* resampler state */ struct conv dec; /* format decoder params */ @@ -59,7 +59,7 @@ struct slot { struct abuf buf; /* socket side buffer */ int prime; /* initial cycles to skip */ int bpf; /* byte per frame */ - int slot_cmax; /* slot destination chans */ + int nch; /* number of rec chans */ struct cmap cmap; /* channel mapper state */ struct resamp resamp; /* buffer for resampling */ struct conv enc; /* buffer for encoding */ diff --git a/sndiod/sock.c b/sndiod/sock.c index 82f7f64..1296adb 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -627,7 +627,7 @@ sock_setpar(struct sock *f) rchan = 1; else if (rchan > NCHAN_MAX) rchan = NCHAN_MAX; - s->sub.slot_cmax = s->opt->rmin + rchan - 1; + s->sub.nch = rchan; #ifdef DEBUG if (log_level >= 3) { sock_log(f); @@ -638,7 +638,7 @@ sock_setpar(struct sock *f) log_puts(" -> "); log_putu(s->opt->rmin); log_puts(":"); - log_putu(s->sub.slot_cmax); + log_putu(s->opt->rmin + s->sub.nch - 1); log_puts("\n"); } #endif @@ -648,14 +648,14 @@ sock_setpar(struct sock *f) pchan = 1; else if (pchan > NCHAN_MAX) pchan = NCHAN_MAX; - s->mix.slot_cmax = s->opt->pmin + pchan - 1; + s->mix.nch = pchan; #ifdef DEBUG if (log_level >= 3) { sock_log(f); log_puts(": playback channels "); log_putu(s->opt->pmin); log_puts(":"); - log_putu(s->mix.slot_cmax); + log_putu(s->opt->pmin + s->mix.nch - 1); log_puts(" -> "); log_putu(s->opt->pmin); log_puts(":"); @@ -1013,13 +1013,13 @@ sock_execmsg(struct sock *f) log_puts(", play "); log_puti(s->opt->pmin); log_puts(":"); - log_puti(s->mix.slot_cmax); + log_puti(s->opt->pmin + s->mix.nch - 1); } if (s->mode & MODE_RECMASK) { log_puts(", rec "); log_puti(s->opt->rmin); log_puts(":"); - log_puti(s->sub.slot_cmax); + log_puti(s->opt->rmin + s->sub.nch - 1); } log_puts(", "); log_putu(s->appbufsz / s->round); @@ -1122,14 +1122,10 @@ sock_execmsg(struct sock *f) m->u.par.sig = s->par.sig; m->u.par.le = s->par.le; m->u.par.msb = s->par.msb; - if (s->mode & MODE_PLAY) { - m->u.par.pchan = htons(s->mix.slot_cmax - - s->opt->pmin + 1); - } - if (s->mode & MODE_RECMASK) { - m->u.par.rchan = htons(s->sub.slot_cmax - - s->opt->rmin + 1); - } + if (s->mode & MODE_PLAY) + m->u.par.pchan = htons(s->mix.nch); + if (s->mode & MODE_RECMASK) + m->u.par.rchan = htons(s->sub.nch); m->u.par.rate = htonl(s->rate); m->u.par.appbufsz = htonl(s->appbufsz); m->u.par.bufsz = htonl(SLOT_BUFSZ(s)); From b6f9ea469081e16c5030c594db7576a2a6230789 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:19 +0200 Subject: [PATCH 14/20] sndiod: Remove unused local variable in sock_hello(). --- sndiod/sock.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sndiod/sock.c b/sndiod/sock.c index 1296adb..48e6044 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -765,7 +765,6 @@ int sock_hello(struct sock *f) { struct amsg_hello *p = &f->rmsg.u.hello; - struct slot *s; struct port *c; struct dev *d; struct opt *opt; @@ -855,11 +854,10 @@ sock_hello(struct sock *f) log_puts("\n"); } #endif - s = slot_new(d, opt, p->who, &sock_slotops, f, mode); - if (s == NULL) + f->slot = slot_new(d, opt, p->who, &sock_slotops, f, mode); + if (f->slot == NULL) return 0; f->midi = NULL; - f->slot = s; return 1; } From 85a1c81bf7f758e51cd0ef79fe7324eed41b7e83 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:22 +0200 Subject: [PATCH 15/20] sndiod: Log slot in slot_new() instead of sock_hello(). --- sndiod/dev.c | 12 ++++++++++++ sndiod/sock.c | 12 ------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 1f8eb32..1af189f 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -1684,6 +1684,18 @@ found: s->rate = d->rate; dev_midi_slotdesc(d, s); dev_midi_vol(d, s); +#ifdef DEBUG + if (log_level >= 3) { + slot_log(s); + log_puts(": using "); + dev_log(d); + log_puts("."); + log_puts(opt->name); + log_puts(", mode = "); + log_putx(mode); + log_puts("\n"); + } +#endif return s; } diff --git a/sndiod/sock.c b/sndiod/sock.c index 48e6044..e369e0a 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -842,18 +842,6 @@ sock_hello(struct sock *f) opt = opt_byname(d, p->opt); if (opt == NULL) return 0; -#ifdef DEBUG - if (log_level >= 3) { - sock_log(f); - log_puts(": using "); - dev_log(d); - log_puts("."); - log_puts(opt->name); - log_puts(", mode = "); - log_putx(mode); - log_puts("\n"); - } -#endif f->slot = slot_new(d, opt, p->who, &sock_slotops, f, mode); if (f->slot == NULL) return 0; From 293d7047bdcf90ffe6612b485acf948b2eca6d0c Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:24 +0200 Subject: [PATCH 16/20] sndiod: No need to initialize s->mix.weight in slot_stop(). It is calculated by dev_mix_adjvol() called by slot_attach(). --- sndiod/dev.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 1af189f..83cad8e 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -1866,7 +1866,6 @@ slot_start(struct slot *s) } #endif slot_allocbufs(s); - s->mix.weight = MIDI_TO_ADATA(MIDI_MAXCTL); if (s->mode & MODE_PLAY) { s->pstate = SLOT_START; } else { From 84ec0ebd8c411485e9c25b2ad314f6703fa89740 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:27 +0200 Subject: [PATCH 17/20] sndiod: Remove useless check of s->ops in slot_setvol(). --- sndiod/dev.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index 83cad8e..a7d3292 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -1738,8 +1738,6 @@ slot_setvol(struct slot *s, unsigned int vol) } #endif s->vol = vol; - if (s->ops == NULL) - return; s->mix.vol = MIDI_TO_ADATA(s->vol); } From ed64776cebb35d9e9ca379ad44efb3a6bcb27443 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:30 +0200 Subject: [PATCH 18/20] sndiod: Remove redundant slot->tstate variable. It was used to determine whether the slot obeys MMC and is ready to start. The stop->opt->mmc flag indicates if it obeys MMC and the slot->pstate == SLOT_READY indicates if it's ready. So slot->tstate can be safely removed. --- sndiod/dev.c | 40 +++++++--------------------------------- sndiod/dev.h | 2 -- 2 files changed, 7 insertions(+), 35 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index a7d3292..e23c86d 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -132,9 +132,6 @@ slot_log(struct slot *s) static char *pstates[] = { "ini", "sta", "rdy", "run", "stp", "mid" }; - static char *tstates[] = { - "off", "sta", "run", "stp" - }; #endif log_puts(s->name); log_putu(s->unit); @@ -145,8 +142,6 @@ slot_log(struct slot *s) if (s->ops) { log_puts(",pst="); log_puts(pstates[s->pstate]); - log_puts(",mmc="); - log_puts(tstates[s->tstate]); } } #endif @@ -1000,7 +995,6 @@ dev_new(char *path, struct aparams *par, d->slot[i].unit = i; d->slot[i].ops = NULL; d->slot[i].vol = MIDI_MAXCTL; - d->slot[i].tstate = MMC_OFF; d->slot[i].serial = d->serial++; strlcpy(d->slot[i].name, "prog", SLOT_NAMEMAX); } @@ -1315,9 +1309,9 @@ dev_sync_attach(struct dev *d) } for (i = 0; i < DEV_NSLOT; i++) { s = d->slot + i; - if (!s->ops || s->tstate == MMC_OFF) + if (!s->ops || !s->opt->mmc) continue; - if (s->tstate != MMC_START || s->pstate != SLOT_READY) { + if (s->pstate != SLOT_READY) { #ifdef DEBUG if (log_level >= 3) { slot_log(s); @@ -1331,18 +1325,9 @@ dev_sync_attach(struct dev *d) return; for (i = 0; i < DEV_NSLOT; i++) { s = d->slot + i; - if (!s->ops) + if (!s->ops || !s->opt->mmc) continue; - if (s->tstate == MMC_START) { -#ifdef DEBUG - if (log_level >= 3) { - slot_log(s); - log_puts(": started\n"); - } -#endif - s->tstate = MMC_RUN; - slot_attach(s); - } + slot_attach(s); } d->tstate = MMC_RUN; dev_midi_full(d); @@ -1672,13 +1657,7 @@ found: s->mix.nch = s->opt->pmax - s->opt->pmin + 1; if (s->mode & MODE_RECMASK) s->sub.nch = s->opt->rmax - s->opt->rmin + 1; - if (s->opt->mmc) { - s->xrun = XRUN_SYNC; - s->tstate = MMC_STOP; - } else { - s->xrun = XRUN_IGNORE; - s->tstate = MMC_OFF; - } + s->xrun = s->opt->mmc ? XRUN_SYNC : XRUN_IGNORE; s->appbufsz = d->bufsz; s->round = d->round; s->rate = d->rate; @@ -1821,12 +1800,10 @@ slot_ready(struct slot *s) */ if (s->dev->pstate == DEV_CFG) return; - if (s->tstate == MMC_OFF) + if (!s->opt->mmc) slot_attach(s); - else { - s->tstate = MMC_START; + else dev_sync_attach(s->dev); - } } /* @@ -1923,9 +1900,6 @@ slot_stop(struct slot *s) slot_ready(s); } - if (s->tstate != MMC_OFF) - s->tstate = MMC_STOP; - if (s->pstate == SLOT_RUN) { if (s->mode & MODE_PLAY) { /* diff --git a/sndiod/dev.h b/sndiod/dev.h index ba784aa..4f91512 100644 --- a/sndiod/dev.h +++ b/sndiod/dev.h @@ -89,7 +89,6 @@ struct slot { unsigned int unit; /* instance of name */ unsigned int serial; /* global unique number */ unsigned int vol; /* current (midi) volume */ - unsigned int tstate; /* mmc state */ }; struct opt { @@ -190,7 +189,6 @@ struct dev { /* * MIDI machine control (MMC) */ -#define MMC_OFF 0 /* ignore MMC messages */ #define MMC_STOP 1 /* stopped, can't start */ #define MMC_START 2 /* attempting to start */ #define MMC_RUN 3 /* started */ From 6bc6041b302e33e8f3020de944118b7effccac05 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:32 +0200 Subject: [PATCH 19/20] sndiod: Reset skip counter in slot_start(). --- sndiod/dev.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index e23c86d..d155e7d 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -1774,17 +1774,10 @@ slot_attach(struct slot *s) #endif s->next = d->slot_list; d->slot_list = s; - s->skip = 0; if (s->mode & MODE_PLAY) { s->mix.vol = MIDI_TO_ADATA(s->vol); dev_mix_adjvol(d); } - if (s->mode & MODE_RECMASK) { - /* - * N-th recorded block is the N-th played block - */ - s->sub.prime = -startpos / (int)s->round; - } } /* @@ -1841,6 +1834,15 @@ slot_start(struct slot *s) } #endif slot_allocbufs(s); + + if (s->mode & MODE_RECMASK) { + /* + * N-th recorded block is the N-th played block + */ + s->sub.prime = -dev_getpos(s->dev) / s->dev->round; + } + s->skip = 0; + if (s->mode & MODE_PLAY) { s->pstate = SLOT_START; } else { From c9a6bf3db660c8c1bc782dbf755859409f4406e8 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Mon, 11 Jun 2018 19:53:35 +0200 Subject: [PATCH 20/20] sndiod: Set slot state outside slot_attach() as we do in slot_detach(). --- sndiod/dev.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sndiod/dev.c b/sndiod/dev.c index d155e7d..a6d10c9 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -1328,6 +1328,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); @@ -1748,7 +1749,6 @@ slot_attach(struct slot *s) s->delta = startpos + pos / (int)d->round; s->delta_rem = pos % d->round; - s->pstate = SLOT_RUN; #ifdef DEBUG if (log_level >= 2) { slot_log(s); @@ -1793,9 +1793,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); }