From ddf5e0dfa7cb30c9c6358ba0f18e1185c07d78b8 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Sat, 9 Jun 2018 09:27:27 +0200 Subject: [PATCH] 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