[BACK]Return to sequencer.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev

Annotation of src/sys/dev/sequencer.c, Revision 1.41.6.2

1.41.6.2! jmcneill    1: /*     $NetBSD: sequencer.c,v 1.43 2007/12/05 17:19:48 pooka Exp $     */
1.1       augustss    2:
                      3: /*
                      4:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
1.13      augustss    7:  * This code is derived from software contributed to The NetBSD Foundation
1.25      keihan      8:  * by Lennart Augustsson (augustss@NetBSD.org).
1.1       augustss    9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *        This product includes software developed by the NetBSD
                     21:  *        Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
1.17      lukem      38:
                     39: #include <sys/cdefs.h>
1.41.6.2! jmcneill   40: __KERNEL_RCSID(0, "$NetBSD: sequencer.c,v 1.43 2007/12/05 17:19:48 pooka Exp $");
1.1       augustss   41:
                     42: #include "sequencer.h"
                     43:
                     44: #include <sys/param.h>
                     45: #include <sys/ioctl.h>
                     46: #include <sys/fcntl.h>
                     47: #include <sys/vnode.h>
                     48: #include <sys/select.h>
                     49: #include <sys/poll.h>
                     50: #include <sys/malloc.h>
                     51: #include <sys/proc.h>
                     52: #include <sys/systm.h>
                     53: #include <sys/syslog.h>
                     54: #include <sys/kernel.h>
                     55: #include <sys/signalvar.h>
                     56: #include <sys/conf.h>
                     57: #include <sys/audioio.h>
                     58: #include <sys/midiio.h>
                     59: #include <sys/device.h>
1.41.6.1  joerg      60: #include <sys/intr.h>
1.1       augustss   61:
1.8       augustss   62: #include <dev/midi_if.h>
1.1       augustss   63: #include <dev/midivar.h>
                     64: #include <dev/sequencervar.h>
                     65:
                     66: #define ADDTIMEVAL(a, b) ( \
                     67:        (a)->tv_sec += (b)->tv_sec, \
                     68:        (a)->tv_usec += (b)->tv_usec, \
                     69:        (a)->tv_usec > 1000000 ? ((a)->tv_sec++, (a)->tv_usec -= 1000000) : 0\
                     70:        )
                     71:
                     72: #define SUBTIMEVAL(a, b) ( \
                     73:        (a)->tv_sec -= (b)->tv_sec, \
                     74:        (a)->tv_usec -= (b)->tv_usec, \
                     75:        (a)->tv_usec < 0 ? ((a)->tv_sec--, (a)->tv_usec += 1000000) : 0\
                     76:        )
                     77:
                     78: #ifdef AUDIO_DEBUG
                     79: #define DPRINTF(x)     if (sequencerdebug) printf x
                     80: #define DPRINTFN(n,x)  if (sequencerdebug >= (n)) printf x
                     81: int    sequencerdebug = 0;
                     82: #else
                     83: #define DPRINTF(x)
                     84: #define DPRINTFN(n,x)
                     85: #endif
                     86:
                     87: #define SEQ_NOTE_MAX 128
                     88: #define SEQ_NOTE_XXX 255
                     89:
1.32      chap       90: #define RECALC_USPERDIV(t) \
                     91: ((t)->usperdiv = 60*1000000L/((t)->tempo_beatpermin*(t)->timebase_divperbeat))
1.1       augustss   92:
                     93: struct sequencer_softc seqdevs[NSEQUENCER];
                     94:
1.26      perry      95: void sequencerattach(int);
1.32      chap       96: static void seq_reset(struct sequencer_softc *);
                     97: static int seq_do_command(struct sequencer_softc *, seq_event_t *);
                     98: static int seq_do_chnvoice(struct sequencer_softc *, seq_event_t *);
                     99: static int seq_do_chncommon(struct sequencer_softc *, seq_event_t *);
                    100: static void seq_timer_waitabs(struct sequencer_softc *, uint32_t);
                    101: static int seq_do_timing(struct sequencer_softc *, seq_event_t *);
                    102: static int seq_do_local(struct sequencer_softc *, seq_event_t *);
                    103: static int seq_do_sysex(struct sequencer_softc *, seq_event_t *);
                    104: static int seq_do_fullsize(struct sequencer_softc *, seq_event_t *, struct uio *);
                    105: static int seq_input_event(struct sequencer_softc *, seq_event_t *);
                    106: static int seq_drain(struct sequencer_softc *);
                    107: static void seq_startoutput(struct sequencer_softc *);
                    108: static void seq_timeout(void *);
                    109: static int seq_to_new(seq_event_t *, struct uio *);
1.28      christos  110: static int seq_sleep_timo(int *, const char *, int);
                    111: static int seq_sleep(int *, const char *);
1.1       augustss  112: static void seq_wakeup(int *);
1.39      ad        113: static void seq_softintr(void *);
1.1       augustss  114:
                    115: struct midi_softc;
1.32      chap      116: static int midiseq_out(struct midi_dev *, u_char *, u_int, int);
                    117: static struct midi_dev *midiseq_open(int, int);
                    118: static void midiseq_close(struct midi_dev *);
                    119: static void midiseq_reset(struct midi_dev *);
                    120: static int midiseq_noteon(struct midi_dev *, int, int, seq_event_t *);
                    121: static int midiseq_noteoff(struct midi_dev *, int, int, seq_event_t *);
                    122: static int midiseq_keypressure(struct midi_dev *, int, int, seq_event_t *);
                    123: static int midiseq_pgmchange(struct midi_dev *, int, seq_event_t *);
                    124: static int midiseq_chnpressure(struct midi_dev *, int, seq_event_t *);
                    125: static int midiseq_ctlchange(struct midi_dev *, int, seq_event_t *);
                    126: static int midiseq_pitchbend(struct midi_dev *, int, seq_event_t *);
                    127: static int midiseq_loadpatch(struct midi_dev *, struct sysex_info *, struct uio *);
1.26      perry     128: void midiseq_in(struct midi_dev *, u_char *, int);
1.1       augustss  129:
1.32      chap      130: static dev_type_open(sequenceropen);
                    131: static dev_type_close(sequencerclose);
                    132: static dev_type_read(sequencerread);
                    133: static dev_type_write(sequencerwrite);
                    134: static dev_type_ioctl(sequencerioctl);
                    135: static dev_type_poll(sequencerpoll);
                    136: static dev_type_kqfilter(sequencerkqfilter);
1.20      gehenna   137:
                    138: const struct cdevsw sequencer_cdevsw = {
                    139:        sequenceropen, sequencerclose, sequencerread, sequencerwrite,
                    140:        sequencerioctl, nostop, notty, sequencerpoll, nommap,
1.34      christos  141:        sequencerkqfilter, D_OTHER,
1.20      gehenna   142: };
                    143:
1.1       augustss  144: void
1.32      chap      145: sequencerattach(int n)
1.1       augustss  146: {
1.39      ad        147:        struct sequencer_softc *sc;
1.15      thorpej   148:
1.39      ad        149:        for (n = 0; n < NSEQUENCER; n++) {
                    150:                sc = &seqdevs[n];
1.41      ad        151:                callout_init(&sc->sc_callout, 0);
1.41.6.1  joerg     152:                sc->sih = softint_establish(SOFTINT_SERIAL, seq_softintr, sc);
1.39      ad        153:        }
1.1       augustss  154: }
                    155:
1.32      chap      156: static int
1.37      christos  157: sequenceropen(dev_t dev, int flags, int ifmt, struct lwp *l)
1.1       augustss  158: {
                    159:        int unit = SEQUENCERUNIT(dev);
                    160:        struct sequencer_softc *sc;
                    161:        struct midi_dev *md;
                    162:        int nmidi;
                    163:
                    164:        DPRINTF(("sequenceropen\n"));
                    165:
                    166:        if (unit >= NSEQUENCER)
                    167:                return (ENXIO);
                    168:        sc = &seqdevs[unit];
                    169:        if (sc->isopen)
                    170:                return EBUSY;
                    171:        if (SEQ_IS_OLD(unit))
                    172:                sc->mode = SEQ_OLD;
                    173:        else
                    174:                sc->mode = SEQ_NEW;
                    175:        sc->isopen++;
                    176:        sc->flags = flags & (FREAD|FWRITE);
                    177:        sc->rchan = 0;
                    178:        sc->wchan = 0;
                    179:        sc->pbus = 0;
                    180:        sc->async = 0;
                    181:        sc->input_stamp = ~0;
                    182:
                    183:        sc->nmidi = 0;
                    184:        nmidi = midi_unit_count();
                    185:
                    186:        sc->devs = malloc(nmidi * sizeof(struct midi_dev *),
                    187:                          M_DEVBUF, M_WAITOK);
                    188:        for (unit = 0; unit < nmidi; unit++) {
1.3       augustss  189:                md = midiseq_open(unit, flags);
1.1       augustss  190:                if (md) {
                    191:                        sc->devs[sc->nmidi++] = md;
                    192:                        md->seq = sc;
1.32      chap      193:                        md->doingsysex = 0;
1.1       augustss  194:                }
                    195:        }
                    196:
1.32      chap      197:        sc->timer.timebase_divperbeat = 100;
                    198:        sc->timer.tempo_beatpermin = 60;
                    199:        RECALC_USPERDIV(&sc->timer);
                    200:        sc->timer.divs_lastevent = sc->timer.divs_lastchange = 0;
                    201:        microtime(&sc->timer.reftime);
1.1       augustss  202:
                    203:        SEQ_QINIT(&sc->inq);
                    204:        SEQ_QINIT(&sc->outq);
                    205:        sc->lowat = SEQ_MAXQ / 2;
                    206:
1.5       augustss  207:        seq_reset(sc);
                    208:
1.1       augustss  209:        DPRINTF(("sequenceropen: mode=%d, nmidi=%d\n", sc->mode, sc->nmidi));
                    210:        return 0;
                    211: }
                    212:
                    213: static int
1.32      chap      214: seq_sleep_timo(int *chan, const char *label, int timo)
1.1       augustss  215: {
                    216:        int st;
                    217:
                    218:        if (!label)
                    219:                label = "seq";
                    220:
                    221:        DPRINTFN(5, ("seq_sleep_timo: %p %s %d\n", chan, label, timo));
                    222:        *chan = 1;
                    223:        st = tsleep(chan, PWAIT | PCATCH, label, timo);
                    224:        *chan = 0;
                    225: #ifdef MIDI_DEBUG
                    226:        if (st != 0)
                    227:            printf("seq_sleep: %d\n", st);
                    228: #endif
                    229:        return st;
                    230: }
                    231:
                    232: static int
1.32      chap      233: seq_sleep(int *chan, const char *label)
1.1       augustss  234: {
                    235:        return seq_sleep_timo(chan, label, 0);
                    236: }
                    237:
                    238: static void
1.32      chap      239: seq_wakeup(int *chan)
1.1       augustss  240: {
                    241:        if (*chan) {
                    242:                DPRINTFN(5, ("seq_wakeup: %p\n", chan));
                    243:                wakeup(chan);
                    244:                *chan = 0;
                    245:        }
                    246: }
                    247:
1.32      chap      248: static int
                    249: seq_drain(struct sequencer_softc *sc)
1.1       augustss  250: {
                    251:        int error;
                    252:
                    253:        DPRINTFN(3, ("seq_drain: %p, len=%d\n", sc, SEQ_QLEN(&sc->outq)));
                    254:        seq_startoutput(sc);
                    255:        error = 0;
                    256:        while(!SEQ_QEMPTY(&sc->outq) && !error)
1.7       augustss  257:                error = seq_sleep_timo(&sc->wchan, "seq_dr", 60*hz);
1.5       augustss  258:        return (error);
1.1       augustss  259: }
                    260:
1.32      chap      261: static void
                    262: seq_timeout(void *addr)
1.1       augustss  263: {
                    264:        struct sequencer_softc *sc = addr;
1.39      ad        265:        struct proc *p;
                    266:
1.1       augustss  267:        DPRINTFN(4, ("seq_timeout: %p\n", sc));
                    268:        sc->timeout = 0;
                    269:        seq_startoutput(sc);
                    270:        if (SEQ_QLEN(&sc->outq) < sc->lowat) {
                    271:                seq_wakeup(&sc->wchan);
1.21      jdolecek  272:                selnotify(&sc->wsel, 0);
1.39      ad        273:                if (sc->async != NULL) {
                    274:                        mutex_enter(&proclist_mutex);
                    275:                        if ((p = sc->async) != NULL)
                    276:                                psignal(p, SIGIO);
                    277:                        mutex_exit(&proclist_mutex);
                    278:                }
1.1       augustss  279:        }
1.27      perry     280:
1.1       augustss  281: }
                    282:
1.32      chap      283: static void
                    284: seq_startoutput(struct sequencer_softc *sc)
1.1       augustss  285: {
                    286:        struct sequencer_queue *q = &sc->outq;
1.32      chap      287:        seq_event_t cmd;
1.1       augustss  288:
                    289:        if (sc->timeout)
                    290:                return;
                    291:        DPRINTFN(4, ("seq_startoutput: %p, len=%d\n", sc, SEQ_QLEN(q)));
                    292:        while(!SEQ_QEMPTY(q) && !sc->timeout) {
                    293:                SEQ_QGET(q, cmd);
                    294:                seq_do_command(sc, &cmd);
                    295:        }
                    296: }
                    297:
1.32      chap      298: static int
1.37      christos  299: sequencerclose(dev_t dev, int flags, int ifmt,
                    300:     struct lwp *l)
1.1       augustss  301: {
                    302:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
1.5       augustss  303:        int n, s;
1.1       augustss  304:
                    305:        DPRINTF(("sequencerclose: %p\n", sc));
                    306:
                    307:        seq_drain(sc);
1.5       augustss  308:        s = splaudio();
1.7       augustss  309:        if (sc->timeout) {
1.15      thorpej   310:                callout_stop(&sc->sc_callout);
1.7       augustss  311:                sc->timeout = 0;
                    312:        }
1.5       augustss  313:        splx(s);
1.1       augustss  314:
                    315:        for (n = 0; n < sc->nmidi; n++)
1.3       augustss  316:                midiseq_close(sc->devs[n]);
1.1       augustss  317:        free(sc->devs, M_DEVBUF);
                    318:        sc->isopen = 0;
                    319:        return (0);
                    320: }
                    321:
1.39      ad        322: static void
                    323: seq_softintr(void *cookie)
                    324: {
                    325:        struct sequencer_softc *sc = cookie;
                    326:        struct proc *p;
                    327:
                    328:        seq_wakeup(&sc->rchan);
                    329:        selnotify(&sc->rsel, 0);
                    330:        if (sc->async != NULL) {
                    331:                mutex_enter(&proclist_mutex);
                    332:                if ((p = sc->async) != NULL)
                    333:                        psignal(p, SIGIO);
                    334:                mutex_exit(&proclist_mutex);
                    335:        }
                    336: }
                    337:
1.12      augustss  338: static int
1.32      chap      339: seq_input_event(struct sequencer_softc *sc, seq_event_t *cmd)
1.1       augustss  340: {
                    341:        struct sequencer_queue *q = &sc->inq;
                    342:
1.27      perry     343:        DPRINTFN(2, ("seq_input_event: %02x %02x %02x %02x %02x %02x %02x %02x\n",
1.32      chap      344:                     cmd->tag,
                    345:                     cmd->unknown.byte[0], cmd->unknown.byte[1],
                    346:                     cmd->unknown.byte[2], cmd->unknown.byte[3],
                    347:                     cmd->unknown.byte[4], cmd->unknown.byte[5],
                    348:                     cmd->unknown.byte[6]));
1.1       augustss  349:        if (SEQ_QFULL(q))
                    350:                return (ENOMEM);
                    351:        SEQ_QPUT(q, *cmd);
1.41.6.1  joerg     352:        softint_schedule(sc->sih);
1.1       augustss  353:        return 0;
                    354: }
                    355:
                    356: void
1.32      chap      357: seq_event_intr(void *addr, seq_event_t *iev)
1.1       augustss  358: {
                    359:        struct sequencer_softc *sc = addr;
                    360:        u_long t;
                    361:        struct timeval now;
1.32      chap      362:        int s;
1.1       augustss  363:
                    364:        microtime(&now);
1.32      chap      365:        s = splsoftclock();
                    366:        if (!sc->timer.running)
                    367:                now = sc->timer.stoptime;
                    368:        SUBTIMEVAL(&now, &sc->timer.reftime);
1.1       augustss  369:        t = now.tv_sec * 1000000 + now.tv_usec;
1.32      chap      370:        t /= sc->timer.usperdiv;
                    371:        t += sc->timer.divs_lastchange;
                    372:        splx(s);
1.1       augustss  373:        if (t != sc->input_stamp) {
1.32      chap      374:                seq_input_event(sc, &SEQ_MK_TIMING(WAIT_ABS, .divisions=t));
                    375:                sc->input_stamp = t; /* XXX wha hoppen if timer is reset? */
1.1       augustss  376:        }
                    377:        seq_input_event(sc, iev);
                    378: }
                    379:
1.32      chap      380: static int
                    381: sequencerread(dev_t dev, struct uio *uio, int ioflag)
1.1       augustss  382: {
                    383:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
                    384:        struct sequencer_queue *q = &sc->inq;
1.32      chap      385:        seq_event_t ev;
1.1       augustss  386:        int error, s;
                    387:
1.27      perry     388:        DPRINTFN(20, ("sequencerread: %p, count=%d, ioflag=%x\n",
1.16      reinoud   389:                     sc, (int) uio->uio_resid, ioflag));
1.1       augustss  390:
                    391:        if (sc->mode == SEQ_OLD) {
1.5       augustss  392:                DPRINTFN(-1,("sequencerread: old read\n"));
1.1       augustss  393:                return (EINVAL); /* XXX unimplemented */
                    394:        }
                    395:
                    396:        error = 0;
                    397:        while (SEQ_QEMPTY(q)) {
                    398:                if (ioflag & IO_NDELAY)
                    399:                        return EWOULDBLOCK;
                    400:                else {
                    401:                        error = seq_sleep(&sc->rchan, "seq rd");
                    402:                        if (error)
                    403:                                return error;
                    404:                }
                    405:        }
                    406:        s = splaudio();
                    407:        while (uio->uio_resid >= sizeof ev && !error && !SEQ_QEMPTY(q)) {
                    408:                SEQ_QGET(q, ev);
                    409:                error = uiomove(&ev, sizeof ev, uio);
                    410:        }
                    411:        splx(s);
                    412:        return error;
                    413: }
                    414:
1.32      chap      415: static int
                    416: sequencerwrite(dev_t dev, struct uio *uio, int ioflag)
1.1       augustss  417: {
                    418:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
                    419:        struct sequencer_queue *q = &sc->outq;
                    420:        int error;
1.32      chap      421:        seq_event_t cmdbuf;
1.1       augustss  422:        int size;
1.32      chap      423:
1.16      reinoud   424:        DPRINTFN(2, ("sequencerwrite: %p, count=%d\n", sc, (int) uio->uio_resid));
1.1       augustss  425:
                    426:        error = 0;
                    427:        size = sc->mode == SEQ_NEW ? sizeof cmdbuf : SEQOLD_CMDSIZE;
                    428:        while (uio->uio_resid >= size) {
                    429:                error = uiomove(&cmdbuf, size, uio);
                    430:                if (error)
                    431:                        break;
                    432:                if (sc->mode == SEQ_OLD)
                    433:                        if (seq_to_new(&cmdbuf, uio))
                    434:                                continue;
1.32      chap      435:                if (cmdbuf.tag == SEQ_FULLSIZE) {
1.1       augustss  436:                        /* We do it like OSS does, asynchronously */
                    437:                        error = seq_do_fullsize(sc, &cmdbuf, uio);
                    438:                        if (error)
                    439:                                break;
                    440:                        continue;
                    441:                }
                    442:                while (SEQ_QFULL(q)) {
                    443:                        seq_startoutput(sc);
                    444:                        if (SEQ_QFULL(q)) {
                    445:                                if (ioflag & IO_NDELAY)
                    446:                                        return EWOULDBLOCK;
1.3       augustss  447:                                error = seq_sleep(&sc->wchan, "seq_wr");
1.1       augustss  448:                                if (error)
                    449:                                        return error;
                    450:                        }
                    451:                }
                    452:                SEQ_QPUT(q, cmdbuf);
                    453:        }
                    454:        seq_startoutput(sc);
                    455:
                    456: #ifdef SEQUENCER_DEBUG
                    457:        if (error)
                    458:                DPRINTFN(2, ("sequencerwrite: error=%d\n", error));
                    459: #endif
                    460:        return error;
                    461: }
                    462:
1.32      chap      463: static int
1.40      christos  464: sequencerioctl(dev_t dev, u_long cmd, void *addr, int flag,
1.35      christos  465:     struct lwp *l)
1.1       augustss  466: {
                    467:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
                    468:        struct synth_info *si;
1.2       augustss  469:        struct midi_dev *md;
1.1       augustss  470:        int devno;
                    471:        int error;
1.32      chap      472:        int s;
1.1       augustss  473:        int t;
                    474:
                    475:        DPRINTFN(2, ("sequencerioctl: %p cmd=0x%08lx\n", sc, cmd));
                    476:
                    477:        error = 0;
                    478:        switch (cmd) {
                    479:        case FIONBIO:
                    480:                /* All handled in the upper FS layer. */
                    481:                break;
                    482:
                    483:        case FIOASYNC:
                    484:                if (*(int *)addr) {
                    485:                        if (sc->async)
                    486:                                return EBUSY;
1.30      christos  487:                        sc->async = l->l_proc;
                    488:                        DPRINTF(("sequencer_ioctl: FIOASYNC %p\n", l));
1.1       augustss  489:                } else
                    490:                        sc->async = 0;
                    491:                break;
                    492:
                    493:        case SEQUENCER_RESET:
                    494:                seq_reset(sc);
                    495:                break;
                    496:
                    497:        case SEQUENCER_PANIC:
                    498:                seq_reset(sc);
                    499:                /* Do more?  OSS doesn't */
                    500:                break;
                    501:
                    502:        case SEQUENCER_SYNC:
                    503:                if (sc->flags == FREAD)
                    504:                        return 0;
                    505:                seq_drain(sc);
                    506:                error = 0;
                    507:                break;
                    508:
                    509:        case SEQUENCER_INFO:
                    510:                si = (struct synth_info*)addr;
                    511:                devno = si->device;
                    512:                if (devno < 0 || devno >= sc->nmidi)
                    513:                        return EINVAL;
1.2       augustss  514:                md = sc->devs[devno];
                    515:                strncpy(si->name, md->name, sizeof si->name);
1.1       augustss  516:                si->synth_type = SYNTH_TYPE_MIDI;
1.2       augustss  517:                si->synth_subtype = md->subtype;
                    518:                si->nr_voices = md->nr_voices;
                    519:                si->instr_bank_size = md->instr_bank_size;
                    520:                si->capabilities = md->capabilities;
1.1       augustss  521:                break;
                    522:
                    523:        case SEQUENCER_NRSYNTHS:
1.3       augustss  524:                *(int *)addr = sc->nmidi;
1.1       augustss  525:                break;
                    526:
                    527:        case SEQUENCER_NRMIDIS:
                    528:                *(int *)addr = sc->nmidi;
                    529:                break;
                    530:
                    531:        case SEQUENCER_OUTOFBAND:
1.27      perry     532:                DPRINTFN(3, ("sequencer_ioctl: OOB=%02x %02x %02x %02x %02x %02x %02x %02x\n",
1.40      christos  533:                             *(u_char *)addr, *((u_char *)addr+1),
                    534:                             *((u_char *)addr+2), *((u_char *)addr+3),
                    535:                             *((u_char *)addr+4), *((u_char *)addr+5),
                    536:                             *((u_char *)addr+6), *((u_char *)addr+7)));
1.32      chap      537:                if ( !(sc->flags & FWRITE ) )
                    538:                        return EBADF;
                    539:                error = seq_do_command(sc, (seq_event_t *)addr);
1.1       augustss  540:                break;
                    541:
                    542:        case SEQUENCER_TMR_TIMEBASE:
                    543:                t = *(int *)addr;
                    544:                if (t < 1)
                    545:                        t = 1;
1.14      augustss  546:                if (t > 10000)
                    547:                        t = 10000;
1.1       augustss  548:                *(int *)addr = t;
1.32      chap      549:                s = splsoftclock();
                    550:                sc->timer.timebase_divperbeat = t;
                    551:                sc->timer.divs_lastchange = sc->timer.divs_lastevent;
                    552:                microtime(&sc->timer.reftime);
                    553:                RECALC_USPERDIV(&sc->timer);
                    554:                splx(s);
1.1       augustss  555:                break;
                    556:
                    557:        case SEQUENCER_TMR_START:
1.32      chap      558:                s = splsoftclock();
                    559:                error = seq_do_timing(sc, &SEQ_MK_TIMING(START));
                    560:                splx(s);
1.1       augustss  561:                break;
                    562:
                    563:        case SEQUENCER_TMR_STOP:
1.32      chap      564:                s = splsoftclock();
                    565:                error = seq_do_timing(sc, &SEQ_MK_TIMING(STOP));
                    566:                splx(s);
1.1       augustss  567:                break;
                    568:
                    569:        case SEQUENCER_TMR_CONTINUE:
1.32      chap      570:                s = splsoftclock();
                    571:                error = seq_do_timing(sc, &SEQ_MK_TIMING(CONTINUE));
                    572:                splx(s);
1.1       augustss  573:                break;
                    574:
                    575:        case SEQUENCER_TMR_TEMPO:
1.32      chap      576:                s = splsoftclock();
                    577:                error = seq_do_timing(sc,
                    578:                    &SEQ_MK_TIMING(TEMPO, .bpm=*(int *)addr));
                    579:                splx(s);
                    580:                if (!error)
                    581:                    *(int *)addr = sc->timer.tempo_beatpermin;
1.1       augustss  582:                break;
                    583:
                    584:        case SEQUENCER_TMR_SOURCE:
                    585:                *(int *)addr = SEQUENCER_TMR_INTERNAL;
                    586:                break;
                    587:
                    588:        case SEQUENCER_TMR_METRONOME:
                    589:                /* noop */
                    590:                break;
                    591:
                    592:        case SEQUENCER_THRESHOLD:
                    593:                t = SEQ_MAXQ - *(int *)addr / sizeof (seq_event_rec);
                    594:                if (t < 1)
                    595:                        t = 1;
                    596:                if (t > SEQ_MAXQ)
                    597:                        t = SEQ_MAXQ;
                    598:                sc->lowat = t;
                    599:                break;
                    600:
                    601:        case SEQUENCER_CTRLRATE:
1.32      chap      602:                s = splsoftclock();
                    603:                *(int *)addr = (sc->timer.tempo_beatpermin
                    604:                               *sc->timer.timebase_divperbeat + 30) / 60;
                    605:                splx(s);
1.1       augustss  606:                break;
                    607:
                    608:        case SEQUENCER_GETTIME:
                    609:        {
                    610:                struct timeval now;
1.28      christos  611:                u_long tx;
1.1       augustss  612:                microtime(&now);
1.32      chap      613:                s = splsoftclock();
                    614:                SUBTIMEVAL(&now, &sc->timer.reftime);
1.28      christos  615:                tx = now.tv_sec * 1000000 + now.tv_usec;
1.32      chap      616:                tx /= sc->timer.usperdiv;
                    617:                tx += sc->timer.divs_lastchange;
                    618:                splx(s);
1.28      christos  619:                *(int *)addr = tx;
1.1       augustss  620:                break;
                    621:        }
                    622:
                    623:        default:
1.5       augustss  624:                DPRINTFN(-1,("sequencer_ioctl: unimpl %08lx\n", cmd));
1.1       augustss  625:                error = EINVAL;
                    626:                break;
                    627:        }
                    628:        return error;
                    629: }
                    630:
1.32      chap      631: static int
                    632: sequencerpoll(dev_t dev, int events, struct lwp *l)
1.1       augustss  633: {
                    634:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
                    635:        int revents = 0;
                    636:
                    637:        DPRINTF(("sequencerpoll: %p events=0x%x\n", sc, events));
                    638:
                    639:        if (events & (POLLIN | POLLRDNORM))
1.32      chap      640:                if ((sc->flags&FREAD) && !SEQ_QEMPTY(&sc->inq))
1.1       augustss  641:                        revents |= events & (POLLIN | POLLRDNORM);
                    642:
                    643:        if (events & (POLLOUT | POLLWRNORM))
1.32      chap      644:                if ((sc->flags&FWRITE) && SEQ_QLEN(&sc->outq) < sc->lowat)
1.1       augustss  645:                        revents |= events & (POLLOUT | POLLWRNORM);
                    646:
                    647:        if (revents == 0) {
1.32      chap      648:                if ((sc->flags&FREAD) && (events & (POLLIN | POLLRDNORM)))
1.30      christos  649:                        selrecord(l, &sc->rsel);
1.1       augustss  650:
1.32      chap      651:                if ((sc->flags&FWRITE) && (events & (POLLOUT | POLLWRNORM)))
1.30      christos  652:                        selrecord(l, &sc->wsel);
1.1       augustss  653:        }
                    654:
                    655:        return revents;
1.21      jdolecek  656: }
                    657:
                    658: static void
                    659: filt_sequencerrdetach(struct knote *kn)
                    660: {
                    661:        struct sequencer_softc *sc = kn->kn_hook;
                    662:        int s;
                    663:
                    664:        s = splaudio();
1.22      christos  665:        SLIST_REMOVE(&sc->rsel.sel_klist, kn, knote, kn_selnext);
1.21      jdolecek  666:        splx(s);
                    667: }
                    668:
                    669: static int
1.37      christos  670: filt_sequencerread(struct knote *kn, long hint)
1.21      jdolecek  671: {
                    672:        struct sequencer_softc *sc = kn->kn_hook;
                    673:
                    674:        /* XXXLUKEM (thorpej): make sure this is correct */
                    675:
                    676:        if (SEQ_QEMPTY(&sc->inq))
                    677:                return (0);
                    678:        kn->kn_data = sizeof(seq_event_rec);
                    679:        return (1);
                    680: }
                    681:
                    682: static const struct filterops sequencerread_filtops =
                    683:        { 1, NULL, filt_sequencerrdetach, filt_sequencerread };
                    684:
                    685: static void
                    686: filt_sequencerwdetach(struct knote *kn)
                    687: {
                    688:        struct sequencer_softc *sc = kn->kn_hook;
                    689:        int s;
                    690:
                    691:        s = splaudio();
1.22      christos  692:        SLIST_REMOVE(&sc->wsel.sel_klist, kn, knote, kn_selnext);
1.21      jdolecek  693:        splx(s);
                    694: }
                    695:
                    696: static int
1.37      christos  697: filt_sequencerwrite(struct knote *kn, long hint)
1.21      jdolecek  698: {
                    699:        struct sequencer_softc *sc = kn->kn_hook;
                    700:
                    701:        /* XXXLUKEM (thorpej): make sure this is correct */
                    702:
                    703:        if (SEQ_QLEN(&sc->outq) >= sc->lowat)
                    704:                return (0);
                    705:        kn->kn_data = sizeof(seq_event_rec);
                    706:        return (1);
                    707: }
                    708:
                    709: static const struct filterops sequencerwrite_filtops =
                    710:        { 1, NULL, filt_sequencerwdetach, filt_sequencerwrite };
                    711:
1.32      chap      712: static int
1.21      jdolecek  713: sequencerkqfilter(dev_t dev, struct knote *kn)
                    714: {
                    715:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
                    716:        struct klist *klist;
                    717:        int s;
                    718:
                    719:        switch (kn->kn_filter) {
                    720:        case EVFILT_READ:
1.22      christos  721:                klist = &sc->rsel.sel_klist;
1.21      jdolecek  722:                kn->kn_fop = &sequencerread_filtops;
                    723:                break;
                    724:
                    725:        case EVFILT_WRITE:
1.22      christos  726:                klist = &sc->wsel.sel_klist;
1.21      jdolecek  727:                kn->kn_fop = &sequencerwrite_filtops;
                    728:                break;
                    729:
                    730:        default:
1.41.6.2! jmcneill  731:                return (EINVAL);
1.21      jdolecek  732:        }
                    733:
                    734:        kn->kn_hook = sc;
                    735:
                    736:        s = splaudio();
                    737:        SLIST_INSERT_HEAD(klist, kn, kn_selnext);
                    738:        splx(s);
                    739:
                    740:        return (0);
1.1       augustss  741: }
                    742:
1.32      chap      743: static void
                    744: seq_reset(struct sequencer_softc *sc)
1.1       augustss  745: {
                    746:        int i, chn;
                    747:        struct midi_dev *md;
                    748:
1.32      chap      749:        if ( !(sc->flags & FWRITE) )
                    750:                return;
1.1       augustss  751:        for (i = 0; i < sc->nmidi; i++) {
                    752:                md = sc->devs[i];
1.3       augustss  753:                midiseq_reset(md);
1.1       augustss  754:                for (chn = 0; chn < MAXCHAN; chn++) {
1.32      chap      755:                        midiseq_ctlchange(md, chn, &SEQ_MK_CHN(CTL_CHANGE,
                    756:                            .controller=MIDI_CTRL_NOTES_OFF));
                    757:                        midiseq_ctlchange(md, chn, &SEQ_MK_CHN(CTL_CHANGE,
                    758:                            .controller=MIDI_CTRL_RESET));
                    759:                        midiseq_pitchbend(md, chn, &SEQ_MK_CHN(PITCH_BEND,
                    760:                            .value=MIDI_BEND_NEUTRAL));
1.1       augustss  761:                }
                    762:        }
                    763: }
                    764:
1.32      chap      765: static int
                    766: seq_do_command(struct sequencer_softc *sc, seq_event_t *b)
1.1       augustss  767: {
                    768:        int dev;
                    769:
1.33      christos  770:        DPRINTFN(4, ("seq_do_command: %p cmd=0x%02x\n", sc, b->timing.op));
1.1       augustss  771:
1.32      chap      772:        switch(b->tag) {
1.1       augustss  773:        case SEQ_LOCAL:
                    774:                return seq_do_local(sc, b);
                    775:        case SEQ_TIMING:
                    776:                return seq_do_timing(sc, b);
                    777:        case SEQ_CHN_VOICE:
                    778:                return seq_do_chnvoice(sc, b);
                    779:        case SEQ_CHN_COMMON:
                    780:                return seq_do_chncommon(sc, b);
1.4       augustss  781:        case SEQ_SYSEX:
                    782:                return seq_do_sysex(sc, b);
1.1       augustss  783:        /* COMPAT */
                    784:        case SEQOLD_MIDIPUTC:
1.32      chap      785:                dev = b->putc.device;
1.1       augustss  786:                if (dev < 0 || dev >= sc->nmidi)
                    787:                        return (ENXIO);
1.32      chap      788:                return midiseq_out(sc->devs[dev], &b->putc.byte, 1, 0);
1.1       augustss  789:        default:
1.32      chap      790:                DPRINTFN(-1,("seq_do_command: unimpl command %02x\n", b->tag));
1.1       augustss  791:                return (EINVAL);
                    792:        }
                    793: }
                    794:
1.32      chap      795: static int
                    796: seq_do_chnvoice(struct sequencer_softc *sc, seq_event_t *b)
1.1       augustss  797: {
1.32      chap      798:        int dev;
1.1       augustss  799:        int error;
                    800:        struct midi_dev *md;
                    801:
1.32      chap      802:        dev = b->voice.device;
                    803:        if (dev < 0 || dev >= sc->nmidi ||
                    804:            b->voice.channel > 15 ||
                    805:            b->voice.key >= SEQ_NOTE_MAX)
1.1       augustss  806:                return ENXIO;
                    807:        md = sc->devs[dev];
1.32      chap      808:        switch(b->voice.op) {
                    809:        case MIDI_NOTEON: /* no need to special-case hidden noteoff here */
                    810:                error = midiseq_noteon(md, b->voice.channel, b->voice.key, b);
1.1       augustss  811:                break;
                    812:        case MIDI_NOTEOFF:
1.32      chap      813:                error = midiseq_noteoff(md, b->voice.channel, b->voice.key, b);
1.1       augustss  814:                break;
                    815:        case MIDI_KEY_PRESSURE:
1.32      chap      816:                error = midiseq_keypressure(md,
                    817:                    b->voice.channel, b->voice.key, b);
1.1       augustss  818:                break;
                    819:        default:
1.32      chap      820:                DPRINTFN(-1,("seq_do_chnvoice: unimpl command %02x\n",
                    821:                        b->voice.op));
1.1       augustss  822:                error = EINVAL;
                    823:                break;
                    824:        }
                    825:        return error;
                    826: }
                    827:
1.32      chap      828: static int
                    829: seq_do_chncommon(struct sequencer_softc *sc, seq_event_t *b)
1.1       augustss  830: {
1.32      chap      831:        int dev;
1.1       augustss  832:        int error;
                    833:        struct midi_dev *md;
                    834:
1.32      chap      835:        dev = b->common.device;
                    836:        if (dev < 0 || dev >= sc->nmidi ||
                    837:            b->common.channel > 15)
1.1       augustss  838:                return ENXIO;
                    839:        md = sc->devs[dev];
1.32      chap      840:        DPRINTFN(2,("seq_do_chncommon: %02x\n", b->common.op));
1.1       augustss  841:
                    842:        error = 0;
1.32      chap      843:        switch(b->common.op) {
1.1       augustss  844:        case MIDI_PGM_CHANGE:
1.32      chap      845:                error = midiseq_pgmchange(md, b->common.channel, b);
1.1       augustss  846:                break;
                    847:        case MIDI_CTL_CHANGE:
1.32      chap      848:                error = midiseq_ctlchange(md, b->common.channel, b);
1.1       augustss  849:                break;
                    850:        case MIDI_PITCH_BEND:
1.32      chap      851:                error = midiseq_pitchbend(md, b->common.channel, b);
1.1       augustss  852:                break;
1.8       augustss  853:        case MIDI_CHN_PRESSURE:
1.32      chap      854:                error = midiseq_chnpressure(md, b->common.channel, b);
1.8       augustss  855:                break;
1.1       augustss  856:        default:
1.32      chap      857:                DPRINTFN(-1,("seq_do_chncommon: unimpl command %02x\n",
                    858:                        b->common.op));
1.1       augustss  859:                error = EINVAL;
                    860:                break;
                    861:        }
1.32      chap      862:        return error;
1.1       augustss  863: }
                    864:
1.32      chap      865: static int
1.37      christos  866: seq_do_local(struct sequencer_softc *sc, seq_event_t *b)
1.1       augustss  867: {
                    868:        return (EINVAL);
1.4       augustss  869: }
                    870:
1.32      chap      871: static int
                    872: seq_do_sysex(struct sequencer_softc *sc, seq_event_t *b)
1.4       augustss  873: {
                    874:        int dev, i;
                    875:        struct midi_dev *md;
1.32      chap      876:        uint8_t *bf = b->sysex.buffer;
1.4       augustss  877:
1.32      chap      878:        dev = b->sysex.device;
1.4       augustss  879:        if (dev < 0 || dev >= sc->nmidi)
                    880:                return (ENXIO);
1.5       augustss  881:        DPRINTF(("seq_do_sysex: dev=%d\n", dev));
1.4       augustss  882:        md = sc->devs[dev];
                    883:
1.32      chap      884:        if (!md->doingsysex) {
                    885:                midiseq_out(md, (uint8_t[]){MIDI_SYSEX_START}, 1, 0);
                    886:                md->doingsysex = 1;
1.4       augustss  887:        }
                    888:
1.28      christos  889:        for (i = 0; i < 6 && bf[i] != 0xff; i++)
1.4       augustss  890:                ;
1.28      christos  891:        midiseq_out(md, bf, i, 0);
                    892:        if (i < 6 || (i > 0 && bf[i-1] == MIDI_SYSEX_END))
1.32      chap      893:                md->doingsysex = 0;
                    894:        return 0;
                    895: }
                    896:
                    897: static void
                    898: seq_timer_waitabs(struct sequencer_softc *sc, uint32_t divs)
                    899: {
                    900:        struct timeval when;
                    901:        long long usec;
                    902:        struct syn_timer *t;
                    903:        int ticks;
                    904:
                    905:        t = &sc->timer;
                    906:        t->divs_lastevent = divs;
                    907:        divs -= t->divs_lastchange;
                    908:        usec = (long long)divs * (long long)t->usperdiv; /* convert to usec */
                    909:        when.tv_sec = usec / 1000000;
                    910:        when.tv_usec = usec % 1000000;
                    911:        DPRINTFN(4, ("seq_timer_waitabs: adjdivs=%d, sleep when=%ld.%06ld",
                    912:                     divs, when.tv_sec, when.tv_usec));
                    913:        ADDTIMEVAL(&when, &t->reftime); /* abstime for end */
                    914:        ticks = hzto(&when);
                    915:        DPRINTFN(4, (" when+start=%ld.%06ld, tick=%d\n",
                    916:                     when.tv_sec, when.tv_usec, ticks));
                    917:        if (ticks > 0) {
                    918: #ifdef DIAGNOSTIC
                    919:                if (ticks > 20 * hz) {
                    920:                        /* Waiting more than 20s */
                    921:                        printf("seq_timer_waitabs: funny ticks=%d, "
                    922:                               "usec=%lld\n", ticks, usec);
                    923:                }
                    924: #endif
                    925:                sc->timeout = 1;
                    926:                callout_reset(&sc->sc_callout, ticks,
                    927:                    seq_timeout, sc);
                    928:        }
                    929: #ifdef SEQUENCER_DEBUG
                    930:        else if (tick < 0)
                    931:                DPRINTF(("seq_timer_waitabs: ticks = %d\n", ticks));
                    932: #endif
1.1       augustss  933: }
                    934:
1.32      chap      935: static int
                    936: seq_do_timing(struct sequencer_softc *sc, seq_event_t *b)
1.1       augustss  937: {
                    938:        struct syn_timer *t = &sc->timer;
                    939:        struct timeval when;
                    940:        int error;
                    941:
                    942:        error = 0;
1.32      chap      943:        switch(b->timing.op) {
1.1       augustss  944:        case TMR_WAIT_REL:
1.32      chap      945:                seq_timer_waitabs(sc,
                    946:                                  b->t_WAIT_REL.divisions + t->divs_lastevent);
                    947:                break;
1.1       augustss  948:        case TMR_WAIT_ABS:
1.32      chap      949:                seq_timer_waitabs(sc, b->t_WAIT_ABS.divisions);
1.1       augustss  950:                break;
                    951:        case TMR_START:
1.32      chap      952:                microtime(&t->reftime);
                    953:                t->divs_lastevent = t->divs_lastchange = 0;
1.1       augustss  954:                t->running = 1;
                    955:                break;
                    956:        case TMR_STOP:
1.32      chap      957:                microtime(&t->stoptime);
1.1       augustss  958:                t->running = 0;
                    959:                break;
                    960:        case TMR_CONTINUE:
1.32      chap      961:                if (t->running)
                    962:                        break;
1.1       augustss  963:                microtime(&when);
1.32      chap      964:                SUBTIMEVAL(&when, &t->stoptime);
                    965:                ADDTIMEVAL(&t->reftime, &when);
1.1       augustss  966:                t->running = 1;
                    967:                break;
                    968:        case TMR_TEMPO:
1.32      chap      969:                /* bpm is unambiguously MIDI clocks per minute / 24 */
                    970:                /* (24 MIDI clocks are usually but not always a quarter note) */
                    971:                if (b->t_TEMPO.bpm < 8) /* where are these limits specified? */
                    972:                        t->tempo_beatpermin = 8;
                    973:                else if (b->t_TEMPO.bpm > 360) /* ? */
                    974:                        t->tempo_beatpermin = 360;
                    975:                else
                    976:                        t->tempo_beatpermin = b->t_TEMPO.bpm;
                    977:                t->divs_lastchange = t->divs_lastevent;
                    978:                microtime(&t->reftime);
                    979:                RECALC_USPERDIV(t);
1.1       augustss  980:                break;
                    981:        case TMR_ECHO:
                    982:                error = seq_input_event(sc, b);
                    983:                break;
                    984:        case TMR_RESET:
1.32      chap      985:                t->divs_lastevent = t->divs_lastchange = 0;
                    986:                microtime(&t->reftime);
                    987:                break;
                    988:        case TMR_SPP:
                    989:        case TMR_TIMESIG:
                    990:                DPRINTF(("seq_do_timing: unimplemented %02x\n", b->timing.op));
                    991:                error = EINVAL; /* not quite accurate... */
1.1       augustss  992:                break;
                    993:        default:
1.33      christos  994:                DPRINTF(("seq_timer: unknown %02x\n", b->timing.op));
1.1       augustss  995:                error = EINVAL;
                    996:                break;
                    997:        }
                    998:        return (error);
                    999: }
                   1000:
1.32      chap     1001: static int
                   1002: seq_do_fullsize(struct sequencer_softc *sc, seq_event_t *b, struct uio *uio)
1.1       augustss 1003: {
                   1004:        struct sysex_info sysex;
                   1005:        u_int dev;
                   1006:
                   1007: #ifdef DIAGNOSTIC
                   1008:        if (sizeof(seq_event_rec) != SEQ_SYSEX_HDRSIZE) {
                   1009:                printf("seq_do_fullsize: sysex size ??\n");
                   1010:                return EINVAL;
                   1011:        }
                   1012: #endif
                   1013:        memcpy(&sysex, b, sizeof sysex);
                   1014:        dev = sysex.device_no;
1.34      christos 1015:        if (/* dev < 0 || */ dev >= sc->nmidi)
1.32      chap     1016:                return (ENXIO);
1.1       augustss 1017:        DPRINTFN(2, ("seq_do_fullsize: fmt=%04x, dev=%d, len=%d\n",
                   1018:                     sysex.key, dev, sysex.len));
1.3       augustss 1019:        return (midiseq_loadpatch(sc->devs[dev], &sysex, uio));
1.1       augustss 1020: }
                   1021:
1.32      chap     1022: /*
                   1023:  * Convert an old sequencer event to a new one.
                   1024:  * NOTE: on entry, *ev may contain valid data only in the first 4 bytes.
                   1025:  * That may be true even on exit (!) in the case of SEQOLD_MIDIPUTC; the
                   1026:  * caller will only look at the first bytes in that case anyway. Ugly? Sure.
                   1027:  */
                   1028: static int
                   1029: seq_to_new(seq_event_t *ev, struct uio *uio)
1.1       augustss 1030: {
                   1031:        int cmd, chan, note, parm;
1.32      chap     1032:        uint32_t tmp_delay;
1.1       augustss 1033:        int error;
1.32      chap     1034:        uint8_t *bfp;
1.1       augustss 1035:
1.32      chap     1036:        cmd = ev->tag;
                   1037:        bfp = ev->unknown.byte;
                   1038:        chan = *bfp++;
                   1039:        note = *bfp++;
                   1040:        parm = *bfp++;
1.1       augustss 1041:        DPRINTFN(3, ("seq_to_new: 0x%02x %d %d %d\n", cmd, chan, note, parm));
                   1042:
                   1043:        if (cmd >= 0x80) {
                   1044:                /* Fill the event record */
                   1045:                if (uio->uio_resid >= sizeof *ev - SEQOLD_CMDSIZE) {
1.32      chap     1046:                        error = uiomove(bfp, sizeof *ev - SEQOLD_CMDSIZE, uio);
1.1       augustss 1047:                        if (error)
                   1048:                                return error;
                   1049:                } else
                   1050:                        return EINVAL;
                   1051:        }
                   1052:
                   1053:        switch(cmd) {
                   1054:        case SEQOLD_NOTEOFF:
1.32      chap     1055:                /*
                   1056:                 * What's with the SEQ_NOTE_XXX?  In OSS this seems to have
                   1057:                 * been undocumented magic for messing with the overall volume
                   1058:                 * of a 'voice', equated precariously with 'channel' and
                   1059:                 * pretty much unimplementable except by directly frobbing a
                   1060:                 * synth chip. For us, who treat everything as interfaced over
                   1061:                 * MIDI, this will just be unceremoniously discarded as
                   1062:                 * invalid in midiseq_noteoff, making the whole event an
                   1063:                 * elaborate no-op, and that doesn't seem to be any different
                   1064:                 * from what happens on linux with a MIDI-interfaced device,
                   1065:                 * by the way. The moral is ... use the new /dev/music API, ok?
                   1066:                 */
                   1067:                *ev = SEQ_MK_CHN(NOTEOFF, .device=0, .channel=chan,
                   1068:                    .key=SEQ_NOTE_XXX, .velocity=parm);
                   1069:                break;
1.1       augustss 1070:        case SEQOLD_NOTEON:
1.32      chap     1071:                *ev = SEQ_MK_CHN(NOTEON,
                   1072:                    .device=0, .channel=chan, .key=note, .velocity=parm);
1.1       augustss 1073:                break;
                   1074:        case SEQOLD_WAIT:
1.32      chap     1075:                /*
                   1076:                 * This event cannot even /exist/ on non-littleendian machines,
                   1077:                 * and so help me, that's exactly the way OSS defined it.
                   1078:                 * Also, the OSS programmer's guide states (p. 74, v1.11)
                   1079:                 * that seqold time units are system clock ticks, unlike
                   1080:                 * the new 'divisions' which are determined by timebase. In
                   1081:                 * that case we would need to do scaling here - but no such
                   1082:                 * behavior is visible in linux either--which also treats this
                   1083:                 * value, surprisingly, as an absolute, not relative, time.
                   1084:                 * My guess is that this event has gone unused so long that
                   1085:                 * nobody could agree we got it wrong no matter what we do.
                   1086:                 */
                   1087:                tmp_delay = *(uint32_t *)ev >> 8;
                   1088:                *ev = SEQ_MK_TIMING(WAIT_ABS, .divisions=tmp_delay);
1.1       augustss 1089:                break;
                   1090:        case SEQOLD_SYNCTIMER:
1.32      chap     1091:                /*
                   1092:                 * The TMR_RESET event is not defined in any OSS materials
                   1093:                 * I can find; it may have been invented here just to provide
                   1094:                 * an accurate _to_new translation of this event.
                   1095:                 */
                   1096:                *ev = SEQ_MK_TIMING(RESET);
1.1       augustss 1097:                break;
                   1098:        case SEQOLD_PGMCHANGE:
1.32      chap     1099:                *ev = SEQ_MK_CHN(PGM_CHANGE,
                   1100:                    .device=0, .channel=chan, .program=note);
1.1       augustss 1101:                break;
                   1102:        case SEQOLD_MIDIPUTC:
                   1103:                break;          /* interpret in normal mode */
                   1104:        case SEQOLD_ECHO:
                   1105:        case SEQOLD_PRIVATE:
                   1106:        case SEQOLD_EXTENDED:
                   1107:        default:
                   1108:                DPRINTF(("seq_to_new: not impl 0x%02x\n", cmd));
                   1109:                return EINVAL;
1.32      chap     1110:        /* In case new-style events show up */
1.1       augustss 1111:        case SEQ_TIMING:
                   1112:        case SEQ_CHN_VOICE:
                   1113:        case SEQ_CHN_COMMON:
                   1114:        case SEQ_FULLSIZE:
                   1115:                break;
                   1116:        }
                   1117:        return 0;
                   1118: }
                   1119:
                   1120: /**********************************************/
                   1121:
                   1122: void
1.37      christos 1123: midiseq_in(struct midi_dev *md, u_char *msg, int len)
1.1       augustss 1124: {
                   1125:        int unit = md->unit;
1.32      chap     1126:        seq_event_t ev;
1.1       augustss 1127:        int status, chan;
                   1128:
1.27      perry    1129:        DPRINTFN(2, ("midiseq_in: %p %02x %02x %02x\n",
1.1       augustss 1130:                     md, msg[0], msg[1], msg[2]));
                   1131:
                   1132:        status = MIDI_GET_STATUS(msg[0]);
                   1133:        chan = MIDI_GET_CHAN(msg[0]);
                   1134:        switch (status) {
1.32      chap     1135:        case MIDI_NOTEON: /* midi(4) always canonicalizes hidden note-off */
                   1136:                ev = SEQ_MK_CHN(NOTEON, .device=unit, .channel=chan,
                   1137:                    .key=msg[1], .velocity=msg[2]);
                   1138:                break;
1.1       augustss 1139:        case MIDI_NOTEOFF:
1.32      chap     1140:                ev = SEQ_MK_CHN(NOTEOFF, .device=unit, .channel=chan,
                   1141:                    .key=msg[1], .velocity=msg[2]);
                   1142:                break;
1.1       augustss 1143:        case MIDI_KEY_PRESSURE:
1.32      chap     1144:                ev = SEQ_MK_CHN(KEY_PRESSURE, .device=unit, .channel=chan,
                   1145:                    .key=msg[1], .pressure=msg[2]);
1.1       augustss 1146:                break;
1.32      chap     1147:        case MIDI_CTL_CHANGE: /* XXX not correct for MSB */
                   1148:                ev = SEQ_MK_CHN(CTL_CHANGE, .device=unit, .channel=chan,
                   1149:                    .controller=msg[1], .value=msg[2]);
1.1       augustss 1150:                break;
                   1151:        case MIDI_PGM_CHANGE:
1.32      chap     1152:                ev = SEQ_MK_CHN(PGM_CHANGE, .device=unit, .channel=chan,
                   1153:                    .program=msg[1]);
                   1154:                break;
1.1       augustss 1155:        case MIDI_CHN_PRESSURE:
1.32      chap     1156:                ev = SEQ_MK_CHN(CHN_PRESSURE, .device=unit, .channel=chan,
                   1157:                    .pressure=msg[1]);
1.1       augustss 1158:                break;
                   1159:        case MIDI_PITCH_BEND:
1.32      chap     1160:                ev = SEQ_MK_CHN(PITCH_BEND, .device=unit, .channel=chan,
                   1161:                    .value=(msg[1] & 0x7f) | ((msg[2] & 0x7f) << 7));
1.1       augustss 1162:                break;
1.32      chap     1163:        default: /* this is now the point where MIDI_ACKs disappear */
1.1       augustss 1164:                return;
                   1165:        }
                   1166:        seq_event_intr(md->seq, &ev);
                   1167: }
                   1168:
1.32      chap     1169: static struct midi_dev *
                   1170: midiseq_open(int unit, int flags)
1.1       augustss 1171: {
                   1172:        extern struct cfdriver midi_cd;
                   1173:        int error;
                   1174:        struct midi_dev *md;
                   1175:        struct midi_softc *sc;
                   1176:        struct midi_info mi;
1.41      ad       1177:        int major;
                   1178:        dev_t dev;
                   1179:
                   1180:        major = devsw_name2blk("midi", NULL, 0);
                   1181:        dev = makedev(major, unit);
1.1       augustss 1182:
1.41      ad       1183:        midi_getinfo(dev, &mi);
1.32      chap     1184:        if ( !(mi.props & MIDI_PROP_CAN_INPUT) )
                   1185:                flags &= ~FREAD;
                   1186:        if ( 0 == ( flags & ( FREAD | FWRITE ) ) )
                   1187:                return 0;
1.3       augustss 1188:        DPRINTFN(2, ("midiseq_open: %d %d\n", unit, flags));
1.41      ad       1189:        error = cdev_open(dev, flags, 0, 0);
1.1       augustss 1190:        if (error)
                   1191:                return (0);
                   1192:        sc = midi_cd.cd_devs[unit];
                   1193:        sc->seqopen = 1;
1.19      tsutsui  1194:        md = malloc(sizeof *md, M_DEVBUF, M_WAITOK|M_ZERO);
1.11      augustss 1195:        sc->seq_md = md;
1.1       augustss 1196:        md->msc = sc;
                   1197:        md->unit = unit;
                   1198:        md->name = mi.name;
                   1199:        md->subtype = 0;
1.2       augustss 1200:        md->nr_voices = 128;    /* XXX */
                   1201:        md->instr_bank_size = 128; /* XXX */
1.1       augustss 1202:        if (mi.props & MIDI_PROP_CAN_INPUT)
                   1203:                md->capabilities |= SYNTH_CAP_INPUT;
                   1204:        return (md);
                   1205: }
                   1206:
1.32      chap     1207: static void
                   1208: midiseq_close(struct midi_dev *md)
1.1       augustss 1209: {
1.41      ad       1210:        int major;
                   1211:        dev_t dev;
                   1212:
                   1213:        major = devsw_name2blk("midi", NULL, 0);
                   1214:        dev = makedev(major, md->unit);
1.20      gehenna  1215:
1.3       augustss 1216:        DPRINTFN(2, ("midiseq_close: %d\n", md->unit));
1.41      ad       1217:        cdev_close(dev, 0, 0, 0);
1.1       augustss 1218:        free(md, M_DEVBUF);
                   1219: }
                   1220:
1.32      chap     1221: static void
1.37      christos 1222: midiseq_reset(struct midi_dev *md)
1.1       augustss 1223: {
1.5       augustss 1224:        /* XXX send GM reset? */
1.3       augustss 1225:        DPRINTFN(3, ("midiseq_reset: %d\n", md->unit));
1.1       augustss 1226: }
                   1227:
1.32      chap     1228: static int
1.37      christos 1229: midiseq_out(struct midi_dev *md, u_char *bf, u_int cc, int chk)
1.1       augustss 1230: {
1.28      christos 1231:        DPRINTFN(5, ("midiseq_out: m=%p, unit=%d, bf[0]=0x%02x, cc=%d\n",
                   1232:                     md->msc, md->unit, bf[0], cc));
1.10      augustss 1233:
1.32      chap     1234:        /* midi(4) does running status compression where appropriate. */
1.28      christos 1235:        return midi_writebytes(md->unit, bf, cc);
1.1       augustss 1236: }
                   1237:
1.32      chap     1238: /*
                   1239:  * If the writing process hands us a hidden note-off in a note-on event,
                   1240:  * we will simply write it that way; no need to special case it here,
                   1241:  * as midi(4) will always canonicalize or compress as appropriate anyway.
                   1242:  */
                   1243: static int
                   1244: midiseq_noteon(struct midi_dev *md, int chan, int key, seq_event_t *ev)
1.1       augustss 1245: {
1.32      chap     1246:        return midiseq_out(md, (uint8_t[]){
                   1247:            MIDI_NOTEON | chan, key, ev->c_NOTEON.velocity & 0x7f}, 3, 1);
1.1       augustss 1248: }
                   1249:
1.32      chap     1250: static int
                   1251: midiseq_noteoff(struct midi_dev *md, int chan, int key, seq_event_t *ev)
1.1       augustss 1252: {
1.32      chap     1253:        return midiseq_out(md, (uint8_t[]){
                   1254:            MIDI_NOTEOFF | chan, key, ev->c_NOTEOFF.velocity & 0x7f}, 3, 1);
1.1       augustss 1255: }
                   1256:
1.32      chap     1257: static int
                   1258: midiseq_keypressure(struct midi_dev *md, int chan, int key, seq_event_t *ev)
1.1       augustss 1259: {
1.32      chap     1260:        return midiseq_out(md, (uint8_t[]){
                   1261:            MIDI_KEY_PRESSURE | chan, key,
                   1262:            ev->c_KEY_PRESSURE.pressure & 0x7f}, 3, 1);
1.1       augustss 1263: }
                   1264:
1.32      chap     1265: static int
                   1266: midiseq_pgmchange(struct midi_dev *md, int chan, seq_event_t *ev)
1.1       augustss 1267: {
1.32      chap     1268:        if (ev->c_PGM_CHANGE.program > 127)
1.1       augustss 1269:                return EINVAL;
1.32      chap     1270:        return midiseq_out(md, (uint8_t[]){
                   1271:            MIDI_PGM_CHANGE | chan, ev->c_PGM_CHANGE.program}, 2, 1);
1.8       augustss 1272: }
                   1273:
1.32      chap     1274: static int
                   1275: midiseq_chnpressure(struct midi_dev *md, int chan, seq_event_t *ev)
1.8       augustss 1276: {
1.32      chap     1277:        if (ev->c_CHN_PRESSURE.pressure > 127)
1.8       augustss 1278:                return EINVAL;
1.32      chap     1279:        return midiseq_out(md, (uint8_t[]){
                   1280:            MIDI_CHN_PRESSURE | chan, ev->c_CHN_PRESSURE.pressure}, 2, 1);
1.1       augustss 1281: }
                   1282:
1.32      chap     1283: static int
                   1284: midiseq_ctlchange(struct midi_dev *md, int chan, seq_event_t *ev)
1.1       augustss 1285: {
1.32      chap     1286:        if (ev->c_CTL_CHANGE.controller > 127)
1.1       augustss 1287:                return EINVAL;
1.32      chap     1288:        return midiseq_out( md, (uint8_t[]){
                   1289:            MIDI_CTL_CHANGE | chan, ev->c_CTL_CHANGE.controller,
                   1290:            ev->c_CTL_CHANGE.value & 0x7f /* XXX this is SO wrong */
                   1291:            }, 3, 1);
1.1       augustss 1292: }
                   1293:
1.32      chap     1294: static int
                   1295: midiseq_pitchbend(struct midi_dev *md, int chan, seq_event_t *ev)
1.1       augustss 1296: {
1.32      chap     1297:        return midiseq_out(md, (uint8_t[]){
                   1298:            MIDI_PITCH_BEND | chan,
                   1299:            ev->c_PITCH_BEND.value & 0x7f,
                   1300:            (ev->c_PITCH_BEND.value >> 7) & 0x7f}, 3, 1);
1.1       augustss 1301: }
                   1302:
1.32      chap     1303: static int
                   1304: midiseq_loadpatch(struct midi_dev *md,
                   1305:                   struct sysex_info *sysex, struct uio *uio)
1.1       augustss 1306: {
1.28      christos 1307:        u_char c, bf[128];
1.1       augustss 1308:        int i, cc, error;
                   1309:
1.5       augustss 1310:        if (sysex->key != SEQ_SYSEX_PATCH) {
                   1311:                DPRINTFN(-1,("midiseq_loadpatch: bad patch key 0x%04x\n",
                   1312:                             sysex->key));
                   1313:                return (EINVAL);
                   1314:        }
1.1       augustss 1315:        if (uio->uio_resid < sysex->len)
                   1316:                /* adjust length, should be an error */
                   1317:                sysex->len = uio->uio_resid;
                   1318:
1.3       augustss 1319:        DPRINTFN(2, ("midiseq_loadpatch: len=%d\n", sysex->len));
1.1       augustss 1320:        if (sysex->len == 0)
                   1321:                return EINVAL;
                   1322:        error = uiomove(&c, 1, uio);
                   1323:        if (error)
                   1324:                return error;
                   1325:        if (c != MIDI_SYSEX_START)              /* must start like this */
                   1326:                return EINVAL;
1.7       augustss 1327:        error = midiseq_out(md, &c, 1, 0);
1.1       augustss 1328:        if (error)
                   1329:                return error;
                   1330:        --sysex->len;
                   1331:        while (sysex->len > 0) {
                   1332:                cc = sysex->len;
1.28      christos 1333:                if (cc > sizeof bf)
                   1334:                        cc = sizeof bf;
                   1335:                error = uiomove(bf, cc, uio);
1.1       augustss 1336:                if (error)
                   1337:                        break;
1.28      christos 1338:                for(i = 0; i < cc && !MIDI_IS_STATUS(bf[i]); i++)
1.1       augustss 1339:                        ;
1.32      chap     1340:                /*
1.38      christos 1341:                 * XXX midi(4)'s buffer might not accommodate this, and the
1.32      chap     1342:                 * function will not block us (though in this case we have
                   1343:                 * a process and could in principle block).
                   1344:                 */
1.28      christos 1345:                error = midiseq_out(md, bf, i, 0);
1.1       augustss 1346:                if (error)
                   1347:                        break;
                   1348:                sysex->len -= i;
                   1349:                if (i != cc)
                   1350:                        break;
                   1351:        }
1.32      chap     1352:        /*
                   1353:         * Any leftover data in uio is rubbish;
1.27      perry    1354:         * the SYSEX should be one write ending in SYSEX_END.
1.1       augustss 1355:         */
                   1356:        uio->uio_resid = 0;
                   1357:        c = MIDI_SYSEX_END;
1.7       augustss 1358:        return midiseq_out(md, &c, 1, 0);
1.1       augustss 1359: }
                   1360:
1.9       augustss 1361: #include "midi.h"
                   1362: #if NMIDI == 0
1.32      chap     1363: static dev_type_open(midiopen);
                   1364: static dev_type_close(midiclose);
1.20      gehenna  1365:
                   1366: const struct cdevsw midi_cdevsw = {
                   1367:        midiopen, midiclose, noread, nowrite, noioctl,
1.36      pooka    1368:        nostop, notty, nopoll, nommap, nokqfilter, D_OTHER
1.20      gehenna  1369: };
                   1370:
1.9       augustss 1371: /*
                   1372:  * If someone has a sequencer, but no midi devices there will
                   1373:  * be unresolved references, so we provide little stubs.
                   1374:  */
                   1375:
                   1376: int
                   1377: midi_unit_count()
                   1378: {
                   1379:        return (0);
                   1380: }
                   1381:
1.32      chap     1382: static int
                   1383: midiopen(dev_t dev, int flags, int ifmt, struct lwp *l)
1.9       augustss 1384: {
                   1385:        return (ENXIO);
                   1386: }
                   1387:
                   1388: struct cfdriver midi_cd;
                   1389:
                   1390: void
1.32      chap     1391: midi_getinfo(dev_t dev, struct midi_info *mi)
1.9       augustss 1392: {
1.31      tron     1393:         mi->name = "Dummy MIDI device";
                   1394:        mi->props = 0;
1.9       augustss 1395: }
                   1396:
1.32      chap     1397: static int
                   1398: midiclose(dev_t dev, int flags, int ifmt, struct lwp *l)
1.9       augustss 1399: {
                   1400:        return (ENXIO);
                   1401: }
                   1402:
                   1403: int
1.32      chap     1404: midi_writebytes(int unit, u_char *bf, int cc)
1.9       augustss 1405: {
                   1406:        return (ENXIO);
                   1407: }
                   1408: #endif /* NMIDI == 0 */

CVSweb <webmaster@jp.NetBSD.org>