[BACK]Return to sequencer.c CVS log [TXT][DIR] Up to [local] / sys / dev

Annotation of sys/dev/sequencer.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: sequencer.c,v 1.13 2007/06/06 19:42:28 mk Exp $       */
                      2: /*     $NetBSD: sequencer.c,v 1.13 1998/11/25 22:17:07 augustss Exp $  */
                      3:
                      4: /*
                      5:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Lennart Augustsson (augustss@netbsd.org).
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *        This product includes software developed by the NetBSD
                     22:  *        Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: #include "sequencer.h"
                     41: #if NSEQUENCER > 0
                     42:
                     43: #include <sys/param.h>
                     44: #include <sys/ioctl.h>
                     45: #include <sys/fcntl.h>
                     46: #include <sys/vnode.h>
                     47: #include <sys/selinfo.h>
                     48: #include <sys/poll.h>
                     49: #include <sys/malloc.h>
                     50: #include <sys/proc.h>
                     51: #include <sys/systm.h>
                     52: #include <sys/syslog.h>
                     53: #include <sys/kernel.h>
                     54: #include <sys/signalvar.h>
                     55: #include <sys/conf.h>
                     56: #include <sys/audioio.h>
                     57: #include <sys/midiio.h>
                     58: #include <sys/device.h>
                     59:
                     60: #include <dev/midi_if.h>
                     61: #include <dev/midivar.h>
                     62: #include <dev/sequencervar.h>
                     63:
                     64: #ifndef splaudio
                     65: #define splaudio() splbio()    /* XXX found in audio_if.h normally */
                     66: #endif
                     67:
                     68: #define ADDTIMEVAL(a, b) ( \
                     69:        (a)->tv_sec += (b)->tv_sec, \
                     70:        (a)->tv_usec += (b)->tv_usec, \
                     71:        (a)->tv_usec >= 1000000 ? ((a)->tv_sec++, (a)->tv_usec -= 1000000) : 0\
                     72:        )
                     73:
                     74: #define SUBTIMEVAL(a, b) ( \
                     75:        (a)->tv_sec -= (b)->tv_sec, \
                     76:        (a)->tv_usec -= (b)->tv_usec, \
                     77:        (a)->tv_usec < 0 ? ((a)->tv_sec--, (a)->tv_usec += 1000000) : 0\
                     78:        )
                     79:
                     80: #ifdef AUDIO_DEBUG
                     81: #define DPRINTF(x)     if (sequencerdebug) printf x
                     82: #define DPRINTFN(n,x)  if (sequencerdebug >= (n)) printf x
                     83: int    sequencerdebug = 0;
                     84: #else
                     85: #define DPRINTF(x)
                     86: #define DPRINTFN(n,x)
                     87: #endif
                     88:
                     89: #define SEQ_CMD(b)  ((b)->arr[0])
                     90:
                     91: #define SEQ_EDEV(b)  ((b)->arr[1])
                     92: #define SEQ_ECMD(b)  ((b)->arr[2])
                     93: #define SEQ_ECHAN(b) ((b)->arr[3])
                     94: #define SEQ_ENOTE(b) ((b)->arr[4])
                     95: #define SEQ_EPARM(b) ((b)->arr[5])
                     96:
                     97: #define SEQ_EP1(b)   ((b)->arr[4])
                     98: #define SEQ_EP2(b)   ((b)->arr[5])
                     99:
                    100: #define SEQ_XCMD(b)  ((b)->arr[1])
                    101: #define SEQ_XDEV(b)  ((b)->arr[2])
                    102: #define SEQ_XCHAN(b) ((b)->arr[3])
                    103: #define SEQ_XNOTE(b) ((b)->arr[4])
                    104: #define SEQ_XVEL(b)  ((b)->arr[5])
                    105:
                    106: #define SEQ_TCMD(b)  ((b)->arr[1])
                    107: #define SEQ_TPARM(b) ((b)->arr[4])
                    108:
                    109: #define SEQ_NOTE_MAX 128
                    110: #define SEQ_NOTE_XXX 255
                    111: #define SEQ_VEL_OFF 0
                    112:
                    113: #define RECALC_TICK(t) ((t)->tick = 60 * 1000000L / ((t)->tempo * (t)->timebase))
                    114:
                    115: struct sequencer_softc seqdevs[NSEQUENCER];
                    116:
                    117: void sequencerattach(int);
                    118: void seq_reset(struct sequencer_softc *);
                    119: int seq_do_command(struct sequencer_softc *, seq_event_rec *);
                    120: int seq_do_extcommand(struct sequencer_softc *, seq_event_rec *);
                    121: int seq_do_chnvoice(struct sequencer_softc *, seq_event_rec *);
                    122: int seq_do_chncommon(struct sequencer_softc *, seq_event_rec *);
                    123: int seq_do_timing(struct sequencer_softc *, seq_event_rec *);
                    124: int seq_do_local(struct sequencer_softc *, seq_event_rec *);
                    125: int seq_do_sysex(struct sequencer_softc *, seq_event_rec *);
                    126: int seq_do_fullsize(struct sequencer_softc *, seq_event_rec *,
                    127:                         struct uio *);
                    128: int seq_timer(struct sequencer_softc *, int, int, seq_event_rec *);
                    129: static int seq_input_event(struct sequencer_softc *, seq_event_rec *);
                    130: int seq_drain(struct sequencer_softc *);
                    131: void seq_startoutput(struct sequencer_softc *);
                    132: void seq_timeout(void *);
                    133: int seq_to_new(seq_event_rec *, struct uio *);
                    134: static int seq_sleep_timo(int *, char *, int);
                    135: static int seq_sleep(int *, char *);
                    136: static void seq_wakeup(int *);
                    137:
                    138: struct midi_softc;
                    139: int midiseq_out(struct midi_dev *, u_char *, u_int, int);
                    140: struct midi_dev *midiseq_open(int, int);
                    141: void midiseq_close(struct midi_dev *);
                    142: void midiseq_reset(struct midi_dev *);
                    143: int midiseq_noteon(struct midi_dev *, int, int, int);
                    144: int midiseq_noteoff(struct midi_dev *, int, int, int);
                    145: int midiseq_keypressure(struct midi_dev *, int, int, int);
                    146: int midiseq_pgmchange(struct midi_dev *, int, int);
                    147: int midiseq_chnpressure(struct midi_dev *, int, int);
                    148: int midiseq_ctlchange(struct midi_dev *, int, int, int);
                    149: int midiseq_pitchbend(struct midi_dev *, int, int);
                    150: int midiseq_loadpatch(struct midi_dev *, struct sysex_info *,
                    151:                           struct uio *);
                    152: int midiseq_putc(struct midi_dev *, int);
                    153: void midiseq_in(struct midi_dev *, u_char *, int);
                    154:
                    155: void
                    156: sequencerattach(int n)
                    157: {
                    158: }
                    159:
                    160: int
                    161: sequenceropen(dev_t dev, int flags, int ifmt, struct proc *p)
                    162: {
                    163:        int unit = SEQUENCERUNIT(dev);
                    164:        struct sequencer_softc *sc;
                    165:        struct midi_dev *md;
                    166:        int nmidi;
                    167:
                    168:        DPRINTF(("sequenceropen\n"));
                    169:
                    170:        if (unit >= NSEQUENCER)
                    171:                return (ENXIO);
                    172:        sc = &seqdevs[unit];
                    173:        if (sc->isopen)
                    174:                return (EBUSY);
                    175:        if (SEQ_IS_OLD(dev))
                    176:                sc->mode = SEQ_OLD;
                    177:        else
                    178:                sc->mode = SEQ_NEW;
                    179:        sc->isopen++;
                    180:        sc->flags = flags & (FREAD|FWRITE);
                    181:        sc->rchan = 0;
                    182:        sc->wchan = 0;
                    183:        sc->pbus = 0;
                    184:        sc->async = 0;
                    185:        sc->input_stamp = ~0;
                    186:
                    187:        sc->nmidi = 0;
                    188:        nmidi = midi_unit_count();
                    189:
                    190:        sc->devs = malloc(nmidi * sizeof(struct midi_dev *),
                    191:                          M_DEVBUF, M_WAITOK);
                    192:        for (unit = 0; unit < nmidi; unit++) {
                    193:                md = midiseq_open(unit, flags);
                    194:                if (md) {
                    195:                        sc->devs[sc->nmidi++] = md;
                    196:                        md->seq = sc;
                    197:                }
                    198:        }
                    199:
                    200:        sc->timer.timebase = 100;
                    201:        sc->timer.tempo = 60;
                    202:        sc->doingsysex = 0;
                    203:        RECALC_TICK(&sc->timer);
                    204:        sc->timer.last = 0;
                    205:        microtime(&sc->timer.start);
                    206:
                    207:        SEQ_QINIT(&sc->inq);
                    208:        SEQ_QINIT(&sc->outq);
                    209:        sc->lowat = SEQ_MAXQ / 2;
                    210:        timeout_set(&sc->timo, seq_timeout, sc);
                    211:
                    212:        seq_reset(sc);
                    213:
                    214:        DPRINTF(("sequenceropen: mode=%d, nmidi=%d\n", sc->mode, sc->nmidi));
                    215:        return (0);
                    216: }
                    217:
                    218: static int
                    219: seq_sleep_timo(int *chan, char *label, int timo)
                    220: {
                    221:        int st;
                    222:
                    223:        if (!label)
                    224:                label = "seq";
                    225:
                    226:        DPRINTFN(5, ("seq_sleep_timo: %p %s %d\n", chan, label, timo));
                    227:        *chan = 1;
                    228:        st = tsleep(chan, PWAIT | PCATCH, label, timo);
                    229:        *chan = 0;
                    230: #ifdef MIDI_DEBUG
                    231:        if (st != 0)
                    232:            printf("seq_sleep: %d\n", st);
                    233: #endif
                    234:        return (st);
                    235: }
                    236:
                    237: static int
                    238: seq_sleep(int *chan, char *label)
                    239: {
                    240:        return (seq_sleep_timo(chan, label, 0));
                    241: }
                    242:
                    243: static void
                    244: seq_wakeup(int *chan)
                    245: {
                    246:        if (*chan) {
                    247:                DPRINTFN(5, ("seq_wakeup: %p\n", chan));
                    248:                wakeup(chan);
                    249:                *chan = 0;
                    250:        }
                    251: }
                    252:
                    253: int
                    254: seq_drain(struct sequencer_softc *sc)
                    255: {
                    256:        int error;
                    257:
                    258:        DPRINTFN(3, ("seq_drain: %p, len=%d\n", sc, SEQ_QLEN(&sc->outq)));
                    259:        seq_startoutput(sc);
                    260:        error = 0;
                    261:        while(!SEQ_QEMPTY(&sc->outq) && !error)
                    262:                error = seq_sleep_timo(&sc->wchan, "seq_dr", 60*hz);
                    263:        return (error);
                    264: }
                    265:
                    266: void
                    267: seq_timeout(void *addr)
                    268: {
                    269:        struct sequencer_softc *sc = addr;
                    270:        DPRINTFN(4, ("seq_timeout: %p\n", sc));
                    271:        sc->timeout = 0;
                    272:        seq_startoutput(sc);
                    273:        if (SEQ_QLEN(&sc->outq) < sc->lowat) {
                    274:                seq_wakeup(&sc->wchan);
                    275:                selwakeup(&sc->wsel);
                    276:                if (sc->async)
                    277:                        psignal(sc->async, SIGIO);
                    278:        }
                    279:
                    280: }
                    281:
                    282: void
                    283: seq_startoutput(struct sequencer_softc *sc)
                    284: {
                    285:        struct sequencer_queue *q = &sc->outq;
                    286:        seq_event_rec cmd;
                    287:
                    288:        if (sc->timeout)
                    289:                return;
                    290:        DPRINTFN(4, ("seq_startoutput: %p, len=%d\n", sc, SEQ_QLEN(q)));
                    291:        while(!SEQ_QEMPTY(q) && !sc->timeout) {
                    292:                SEQ_QGET(q, cmd);
                    293:                seq_do_command(sc, &cmd);
                    294:        }
                    295: }
                    296:
                    297: int
                    298: sequencerclose(dev_t dev, int flags, int ifmt, struct proc *p)
                    299: {
                    300:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
                    301:        int n, s;
                    302:
                    303:        DPRINTF(("sequencerclose: %p\n", sc));
                    304:
                    305:        seq_drain(sc);
                    306:        s = splaudio();
                    307:        if (sc->timeout) {
                    308:                timeout_del(&sc->timo);
                    309:                sc->timeout = 0;
                    310:        }
                    311:        splx(s);
                    312:
                    313:        for (n = 0; n < sc->nmidi; n++)
                    314:                midiseq_close(sc->devs[n]);
                    315:        free(sc->devs, M_DEVBUF);
                    316:        sc->isopen = 0;
                    317:        return (0);
                    318: }
                    319:
                    320: static int
                    321: seq_input_event(struct sequencer_softc *sc, seq_event_rec *cmd)
                    322: {
                    323:        struct sequencer_queue *q = &sc->inq;
                    324:
                    325:        DPRINTFN(2, ("seq_input_event: %02x %02x %02x %02x %02x %02x %02x %02x\n",
                    326:                     cmd->arr[0], cmd->arr[1], cmd->arr[2], cmd->arr[3],
                    327:                     cmd->arr[4], cmd->arr[5], cmd->arr[6], cmd->arr[7]));
                    328:        if (SEQ_QFULL(q))
                    329:                return (ENOMEM);
                    330:        SEQ_QPUT(q, *cmd);
                    331:        seq_wakeup(&sc->rchan);
                    332:        selwakeup(&sc->rsel);
                    333:        if (sc->async)
                    334:                psignal(sc->async, SIGIO);
                    335:        return (0);
                    336: }
                    337:
                    338: void
                    339: seq_event_intr(void *addr, seq_event_rec *iev)
                    340: {
                    341:        struct sequencer_softc *sc = addr;
                    342:        union {
                    343:                u_int32_t l;
                    344:                u_int8_t b[4];
                    345:        } u;
                    346:        u_long t;
                    347:        struct timeval now;
                    348:        seq_event_rec ev;
                    349:
                    350:        microtime(&now);
                    351:        SUBTIMEVAL(&now, &sc->timer.start);
                    352:        t = now.tv_sec * 1000000 + now.tv_usec;
                    353:        t /= sc->timer.tick;
                    354:        if (t != sc->input_stamp) {
                    355:                ev.arr[0] = SEQ_TIMING;
                    356:                ev.arr[1] = TMR_WAIT_ABS;
                    357:                ev.arr[2] = 0;
                    358:                ev.arr[3] = 0;
                    359:                u.l = t;
                    360:                ev.arr[4] = u.b[0];
                    361:                ev.arr[5] = u.b[1];
                    362:                ev.arr[6] = u.b[2];
                    363:                ev.arr[7] = u.b[3];
                    364:                seq_input_event(sc, &ev);
                    365:                sc->input_stamp = t;
                    366:        }
                    367:        seq_input_event(sc, iev);
                    368: }
                    369:
                    370: int
                    371: sequencerread(dev_t dev, struct uio *uio, int ioflag)
                    372: {
                    373:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
                    374:        struct sequencer_queue *q = &sc->inq;
                    375:        seq_event_rec ev;
                    376:        int error, s;
                    377:
                    378:        DPRINTFN(20, ("sequencerread: %p, count=%d, ioflag=%x\n",
                    379:                     sc, uio->uio_resid, ioflag));
                    380:
                    381:        if (sc->mode == SEQ_OLD) {
                    382:                DPRINTFN(-1,("sequencerread: old read\n"));
                    383:                return (EINVAL); /* XXX unimplemented */
                    384:        }
                    385:
                    386:        error = 0;
                    387:        while (SEQ_QEMPTY(q)) {
                    388:                if (ioflag & IO_NDELAY)
                    389:                        return (EWOULDBLOCK);
                    390:                else {
                    391:                        error = seq_sleep(&sc->rchan, "seq rd");
                    392:                        if (error)
                    393:                                return (error);
                    394:                }
                    395:        }
                    396:        s = splaudio();
                    397:        while (uio->uio_resid >= sizeof ev && !error && !SEQ_QEMPTY(q)) {
                    398:                SEQ_QGET(q, ev);
                    399:                error = uiomove((caddr_t)&ev, sizeof ev, uio);
                    400:        }
                    401:        splx(s);
                    402:        return (error);
                    403: }
                    404:
                    405: int
                    406: sequencerwrite(dev_t dev, struct uio *uio, int ioflag)
                    407: {
                    408:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
                    409:        struct sequencer_queue *q = &sc->outq;
                    410:        int error;
                    411:        seq_event_rec cmdbuf;
                    412:        int size;
                    413:
                    414:        DPRINTFN(2, ("sequencerwrite: %p, count=%d\n", sc, uio->uio_resid));
                    415:
                    416:        error = 0;
                    417:        size = sc->mode == SEQ_NEW ? sizeof cmdbuf : SEQOLD_CMDSIZE;
                    418:        while (uio->uio_resid >= size) {
                    419:                error = uiomove((caddr_t)&cmdbuf, size, uio);
                    420:                if (error)
                    421:                        break;
                    422:                if (sc->mode == SEQ_OLD)
                    423:                        if (seq_to_new(&cmdbuf, uio))
                    424:                                continue;
                    425:                if (SEQ_CMD(&cmdbuf) == SEQ_FULLSIZE) {
                    426:                        /* We do it like OSS does, asynchronously */
                    427:                        error = seq_do_fullsize(sc, &cmdbuf, uio);
                    428:                        if (error)
                    429:                                break;
                    430:                        continue;
                    431:                }
                    432:                while (SEQ_QFULL(q)) {
                    433:                        seq_startoutput(sc);
                    434:                        if (SEQ_QFULL(q)) {
                    435:                                if (ioflag & IO_NDELAY)
                    436:                                        return (EWOULDBLOCK);
                    437:                                error = seq_sleep(&sc->wchan, "seq_wr");
                    438:                                if (error)
                    439:                                        return (error);
                    440:                        }
                    441:                }
                    442:                SEQ_QPUT(q, cmdbuf);
                    443:        }
                    444:        seq_startoutput(sc);
                    445:
                    446: #ifdef SEQUENCER_DEBUG
                    447:        if (error)
                    448:                DPRINTFN(2, ("sequencerwrite: error=%d\n", error));
                    449: #endif
                    450:        return (error);
                    451: }
                    452:
                    453: int
                    454: sequencerioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
                    455: {
                    456:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
                    457:        struct synth_info *si;
                    458:        struct midi_dev *md;
                    459:        int devno;
                    460:        int error;
                    461:        int t;
                    462:
                    463:        DPRINTFN(2, ("sequencerioctl: %p cmd=0x%08lx\n", sc, cmd));
                    464:
                    465:        error = 0;
                    466:        switch (cmd) {
                    467:        case FIONBIO:
                    468:                /* All handled in the upper FS layer. */
                    469:                break;
                    470:
                    471:        case FIOASYNC:
                    472:                if (*(int *)addr) {
                    473:                        if (sc->async)
                    474:                                return (EBUSY);
                    475:                        sc->async = p;
                    476:                        DPRINTF(("sequencer_ioctl: FIOASYNC %p\n", p));
                    477:                } else
                    478:                        sc->async = 0;
                    479:                break;
                    480:
                    481:        case SEQUENCER_RESET:
                    482:                seq_reset(sc);
                    483:                break;
                    484:
                    485:        case SEQUENCER_PANIC:
                    486:                seq_reset(sc);
                    487:                /* Do more?  OSS doesn't */
                    488:                break;
                    489:
                    490:        case SEQUENCER_SYNC:
                    491:                if (sc->flags == FREAD)
                    492:                        return (0);
                    493:                seq_drain(sc);
                    494:                error = 0;
                    495:                break;
                    496:
                    497:        case SEQUENCER_INFO:
                    498:                si = (struct synth_info*)addr;
                    499:                devno = si->device;
                    500:                if (devno < 0 || devno >= sc->nmidi)
                    501:                        return (EINVAL);
                    502:                md = sc->devs[devno];
                    503:                strncpy(si->name, md->name, sizeof si->name);
                    504:                si->synth_type = SYNTH_TYPE_MIDI;
                    505:                si->synth_subtype = md->subtype;
                    506:                si->nr_voices = md->nr_voices;
                    507:                si->instr_bank_size = md->instr_bank_size;
                    508:                si->capabilities = md->capabilities;
                    509:                break;
                    510:
                    511:        case SEQUENCER_NRSYNTHS:
                    512:                *(int *)addr = sc->nmidi;
                    513:                break;
                    514:
                    515:        case SEQUENCER_NRMIDIS:
                    516:                *(int *)addr = sc->nmidi;
                    517:                break;
                    518:
                    519:        case SEQUENCER_OUTOFBAND:
                    520:                DPRINTFN(3, ("sequencer_ioctl: OOB=%02x %02x %02x %02x %02x %02x %02x %02x\n",
                    521:                             *(u_char *)addr, *(u_char *)(addr+1),
                    522:                             *(u_char *)(addr+2), *(u_char *)(addr+3),
                    523:                             *(u_char *)(addr+4), *(u_char *)(addr+5),
                    524:                             *(u_char *)(addr+6), *(u_char *)(addr+7)));
                    525:                error = seq_do_command(sc, (seq_event_rec *)addr);
                    526:                break;
                    527:
                    528:        case SEQUENCER_TMR_TIMEBASE:
                    529:                t = *(int *)addr;
                    530:                if (t < 1)
                    531:                        t = 1;
                    532:                if (t > 1000)
                    533:                        t = 1000;
                    534:                sc->timer.timebase = t;
                    535:                *(int *)addr = t;
                    536:                RECALC_TICK(&sc->timer);
                    537:                break;
                    538:
                    539:        case SEQUENCER_TMR_START:
                    540:                error = seq_timer(sc, TMR_START, 0, 0);
                    541:                break;
                    542:
                    543:        case SEQUENCER_TMR_STOP:
                    544:                error = seq_timer(sc, TMR_STOP, 0, 0);
                    545:                break;
                    546:
                    547:        case SEQUENCER_TMR_CONTINUE:
                    548:                error = seq_timer(sc, TMR_CONTINUE, 0, 0);
                    549:                break;
                    550:
                    551:        case SEQUENCER_TMR_TEMPO:
                    552:                t = *(int *)addr;
                    553:                if (t < 8)
                    554:                        t = 8;
                    555:                if (t > 250)
                    556:                        t = 250;
                    557:                sc->timer.tempo = t;
                    558:                *(int *)addr = t;
                    559:                RECALC_TICK(&sc->timer);
                    560:                break;
                    561:
                    562:        case SEQUENCER_TMR_SOURCE:
                    563:                *(int *)addr = SEQUENCER_TMR_INTERNAL;
                    564:                break;
                    565:
                    566:        case SEQUENCER_TMR_METRONOME:
                    567:                /* noop */
                    568:                break;
                    569:
                    570:        case SEQUENCER_THRESHOLD:
                    571:                t = SEQ_MAXQ - *(int *)addr / sizeof (seq_event_rec);
                    572:                if (t < 1)
                    573:                        t = 1;
                    574:                if (t > SEQ_MAXQ)
                    575:                        t = SEQ_MAXQ;
                    576:                sc->lowat = t;
                    577:                break;
                    578:
                    579:        case SEQUENCER_CTRLRATE:
                    580:                *(int *)addr = (sc->timer.tempo*sc->timer.timebase + 30) / 60;
                    581:                break;
                    582:
                    583:        case SEQUENCER_GETTIME:
                    584:        {
                    585:                struct timeval now;
                    586:                u_long t;
                    587:                microtime(&now);
                    588:                SUBTIMEVAL(&now, &sc->timer.start);
                    589:                t = now.tv_sec * 1000000 + now.tv_usec;
                    590:                t /= sc->timer.tick;
                    591:                *(int *)addr = t;
                    592:                break;
                    593:        }
                    594:
                    595:        default:
                    596:                DPRINTFN(-1,("sequencer_ioctl: unimpl %08lx\n", cmd));
                    597:                error = ENOTTY;
                    598:                break;
                    599:        }
                    600:        return (error);
                    601: }
                    602:
                    603: int
                    604: sequencerpoll(dev_t dev, int events, struct proc *p)
                    605: {
                    606:        struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)];
                    607:        int revents = 0;
                    608:
                    609:        DPRINTF(("sequencerpoll: %p rw=0x%x\n", sc, events));
                    610:
                    611:        if (events & (POLLIN | POLLRDNORM)) {
                    612:                if (!SEQ_QEMPTY(&sc->inq))
                    613:                        revents |= events & (POLLIN | POLLRDNORM);
                    614:        }
                    615:        if (events & (POLLOUT | POLLWRNORM)) {
                    616:                if (SEQ_QLEN(&sc->outq) < sc->lowat)
                    617:                        revents |= events & (POLLOUT | POLLWRNORM);
                    618:        }
                    619:        if (revents == 0) {
                    620:                if (events & (POLLIN | POLLRDNORM))
                    621:                        selrecord(p, &sc->rsel);
                    622:                if (events & (POLLOUT | POLLWRNORM))
                    623:                        selrecord(p, &sc->wsel);
                    624:        }
                    625:        return (revents);
                    626: }
                    627:
                    628: void
                    629: seq_reset(struct sequencer_softc *sc)
                    630: {
                    631:        int i, chn;
                    632:        struct midi_dev *md;
                    633:
                    634:        for (i = 0; i < sc->nmidi; i++) {
                    635:                md = sc->devs[i];
                    636:                midiseq_reset(md);
                    637:                for (chn = 0; chn < MAXCHAN; chn++) {
                    638:                        midiseq_ctlchange(md, chn, MIDI_CTRL_ALLOFF, 0);
                    639:                        midiseq_ctlchange(md, chn, MIDI_CTRL_RESET, 0);
                    640:                        midiseq_pitchbend(md, chn, MIDI_BEND_NEUTRAL);
                    641:                }
                    642:        }
                    643: }
                    644:
                    645: int
                    646: seq_do_command(struct sequencer_softc *sc, seq_event_rec *b)
                    647: {
                    648:        int dev;
                    649:
                    650:        DPRINTFN(4, ("seq_do_command: %p cmd=0x%02x\n", sc, SEQ_CMD(b)));
                    651:
                    652:        switch(SEQ_CMD(b)) {
                    653:        case SEQ_LOCAL:
                    654:                return (seq_do_local(sc, b));
                    655:        case SEQ_TIMING:
                    656:                return (seq_do_timing(sc, b));
                    657:        case SEQ_CHN_VOICE:
                    658:                return (seq_do_chnvoice(sc, b));
                    659:        case SEQ_CHN_COMMON:
                    660:                return (seq_do_chncommon(sc, b));
                    661:        case SEQ_SYSEX:
                    662:                return (seq_do_sysex(sc, b));
                    663:        /* COMPAT */
                    664:        case SEQOLD_MIDIPUTC:
                    665:                dev = b->arr[2];
                    666:                if (dev < 0 || dev >= sc->nmidi)
                    667:                        return (ENXIO);
                    668:                return (midiseq_putc(sc->devs[dev], b->arr[1]));
                    669:        default:
                    670:                DPRINTFN(-1,("seq_do_command: unimpl command %02x\n",
                    671:                             SEQ_CMD(b)));
                    672:                return (EINVAL);
                    673:        }
                    674: }
                    675:
                    676: int
                    677: seq_do_chnvoice(struct sequencer_softc *sc, seq_event_rec *b)
                    678: {
                    679:        int cmd, dev, chan, note, parm, voice;
                    680:        int error;
                    681:        struct midi_dev *md;
                    682:
                    683:        dev = SEQ_EDEV(b);
                    684:        if (dev < 0 || dev >= sc->nmidi)
                    685:                return (ENXIO);
                    686:        md = sc->devs[dev];
                    687:        cmd = SEQ_ECMD(b);
                    688:        chan = SEQ_ECHAN(b);
                    689:        note = SEQ_ENOTE(b);
                    690:        parm = SEQ_EPARM(b);
                    691:        DPRINTFN(2,("seq_do_chnvoice: cmd=%02x dev=%d chan=%d note=%d parm=%d\n",
                    692:                    cmd, dev, chan, note, parm));
                    693:        voice = chan;
                    694:        if (cmd == MIDI_NOTEON && parm == 0) {
                    695:                cmd = MIDI_NOTEOFF;
                    696:                parm = MIDI_HALF_VEL;
                    697:        }
                    698:        switch(cmd) {
                    699:        case MIDI_NOTEON:
                    700:                DPRINTFN(5, ("seq_do_chnvoice: noteon %p %d %d %d\n",
                    701:                             md, voice, note, parm));
                    702:                error = midiseq_noteon(md, voice, note, parm);
                    703:                break;
                    704:        case MIDI_NOTEOFF:
                    705:                error = midiseq_noteoff(md, voice, note, parm);
                    706:                break;
                    707:        case MIDI_KEY_PRESSURE:
                    708:                error = midiseq_keypressure(md, voice, note, parm);
                    709:                break;
                    710:        default:
                    711:                DPRINTFN(-1,("seq_do_chnvoice: unimpl command %02x\n", cmd));
                    712:                error = EINVAL;
                    713:                break;
                    714:        }
                    715:        return (error);
                    716: }
                    717:
                    718: int
                    719: seq_do_chncommon(struct sequencer_softc *sc, seq_event_rec *b)
                    720: {
                    721:        int cmd, dev, chan, p1, w14;
                    722:        int error;
                    723:        struct midi_dev *md;
                    724:        union {
                    725:                int16_t s;
                    726:                u_int8_t b[2];
                    727:        } u;
                    728:
                    729:        dev = SEQ_EDEV(b);
                    730:        if (dev < 0 || dev >= sc->nmidi)
                    731:                return (ENXIO);
                    732:        md = sc->devs[dev];
                    733:        cmd = SEQ_ECMD(b);
                    734:        chan = SEQ_ECHAN(b);
                    735:        p1 = SEQ_EP1(b);
                    736:        u.b[0] = b->arr[6];
                    737:        u.b[1] = b->arr[7];
                    738:        w14 = u.s;
                    739:        DPRINTFN(2,("seq_do_chncommon: %02x\n", cmd));
                    740:
                    741:        error = 0;
                    742:        switch(cmd) {
                    743:        case MIDI_PGM_CHANGE:
                    744:                error = midiseq_pgmchange(md, chan, p1);
                    745:                break;
                    746:        case MIDI_CTL_CHANGE:
                    747:                if (chan > 15 || p1 > 127)
                    748:                        return (0); /* EINVAL */
                    749:                error = midiseq_ctlchange(md, chan, p1, w14);
                    750:                break;
                    751:        case MIDI_PITCH_BEND:
                    752:                error = midiseq_pitchbend(md, chan, w14);
                    753:                break;
                    754:        case MIDI_CHN_PRESSURE:
                    755:                error = midiseq_chnpressure(md, chan, p1);
                    756:                break;
                    757:        default:
                    758:                DPRINTFN(-1,("seq_do_chncommon: unimpl command %02x\n", cmd));
                    759:                error = EINVAL;
                    760:                break;
                    761:        }
                    762:        return (error);
                    763: }
                    764:
                    765: int
                    766: seq_do_timing(struct sequencer_softc *sc, seq_event_rec *b)
                    767: {
                    768:        union {
                    769:                int32_t i;
                    770:                u_int8_t b[4];
                    771:        } u;
                    772:
                    773:        u.b[0] = b->arr[4];
                    774:        u.b[1] = b->arr[5];
                    775:        u.b[2] = b->arr[6];
                    776:        u.b[3] = b->arr[7];
                    777:        return (seq_timer(sc, SEQ_TCMD(b), u.i, b));
                    778: }
                    779:
                    780: int
                    781: seq_do_local(struct sequencer_softc *sc, seq_event_rec *b)
                    782: {
                    783:        return (EINVAL);
                    784: }
                    785:
                    786: int
                    787: seq_do_sysex(struct sequencer_softc *sc, seq_event_rec *b)
                    788: {
                    789:        int dev, i;
                    790:        struct midi_dev *md;
                    791:        u_int8_t c, *buf = &b->arr[2];
                    792:
                    793:        dev = SEQ_EDEV(b);
                    794:        if (dev < 0 || dev >= sc->nmidi)
                    795:                return (ENXIO);
                    796:        DPRINTF(("seq_do_sysex: dev=%d\n", dev));
                    797:        md = sc->devs[dev];
                    798:
                    799:        if (!sc->doingsysex) {
                    800:                c = MIDI_SYSEX_START;
                    801:                midiseq_out(md, &c, 1, 0);
                    802:                sc->doingsysex = 1;
                    803:        }
                    804:
                    805:        for (i = 0; i < 6 && buf[i] != 0xff; i++)
                    806:                ;
                    807:        midiseq_out(md, buf, i, 0);
                    808:        if (i < 6 || (i > 0 && buf[i-1] == MIDI_SYSEX_END))
                    809:                sc->doingsysex = 0;
                    810:        return (0);
                    811: }
                    812:
                    813: int
                    814: seq_timer(struct sequencer_softc *sc, int cmd, int parm, seq_event_rec *b)
                    815: {
                    816:        struct syn_timer *t = &sc->timer;
                    817:        struct timeval when;
                    818:        int ticks;
                    819:        int error;
                    820:        long long usec;
                    821:
                    822:        DPRINTFN(2,("seq_timer: %02x %d\n", cmd, parm));
                    823:
                    824:        error = 0;
                    825:        switch(cmd) {
                    826:        case TMR_WAIT_REL:
                    827:                parm += t->last;
                    828:                /* FALLTHROUGH */
                    829:        case TMR_WAIT_ABS:
                    830:                t->last = parm;
                    831:                usec = (long long)parm * (long long)t->tick; /* convert to usec */
                    832:                when.tv_sec = usec / 1000000;
                    833:                when.tv_usec = usec % 1000000;
                    834:                DPRINTFN(4, ("seq_timer: parm=%d, sleep when=%ld.%06ld", parm,
                    835:                             when.tv_sec, when.tv_usec));
                    836:                ADDTIMEVAL(&when, &t->start); /* abstime for end */
                    837:                ticks = hzto(&when);
                    838:                DPRINTFN(4, (" when+start=%ld.%06ld, ticks=%d\n",
                    839:                             when.tv_sec, when.tv_usec, ticks));
                    840:                if (ticks > 0) {
                    841: #ifdef DIAGNOSTIC
                    842:                        if (ticks > 20 * hz) {
                    843:                                /* Waiting more than 20s */
                    844:                                printf("seq_timer: funny ticks=%d, usec=%lld, parm=%d, tick=%ld\n",
                    845:                                       ticks, usec, parm, t->tick);
                    846:                        }
                    847: #endif
                    848:                        sc->timeout = 1;
                    849:                        timeout_add(&sc->timo, ticks);
                    850:                }
                    851: #ifdef SEQUENCER_DEBUG
                    852:                else if (ticks < 0)
                    853:                        DPRINTF(("seq_timer: ticks = %d\n", ticks));
                    854: #endif
                    855:                break;
                    856:        case TMR_START:
                    857:                microtime(&t->start);
                    858:                t->running = 1;
                    859:                break;
                    860:        case TMR_STOP:
                    861:                microtime(&t->stop);
                    862:                t->running = 0;
                    863:                break;
                    864:        case TMR_CONTINUE:
                    865:                microtime(&when);
                    866:                SUBTIMEVAL(&when, &t->stop);
                    867:                ADDTIMEVAL(&t->start, &when);
                    868:                t->running = 1;
                    869:                break;
                    870:        case TMR_TEMPO:
                    871:                /* parm is ticks per minute / timebase */
                    872:                if (parm < 8)
                    873:                        parm = 8;
                    874:                if (parm > 360)
                    875:                        parm = 360;
                    876:                t->tempo = parm;
                    877:                RECALC_TICK(t);
                    878:                break;
                    879:        case TMR_ECHO:
                    880:                error = seq_input_event(sc, b);
                    881:                break;
                    882:        case TMR_RESET:
                    883:                t->last = 0;
                    884:                microtime(&t->start);
                    885:                break;
                    886:        default:
                    887:                DPRINTF(("seq_timer: unknown %02x\n", cmd));
                    888:                error = EINVAL;
                    889:                break;
                    890:        }
                    891:        return (error);
                    892: }
                    893:
                    894: int
                    895: seq_do_fullsize(struct sequencer_softc *sc, seq_event_rec *b, struct uio *uio)
                    896: {
                    897:        struct sysex_info sysex;
                    898:        u_int dev;
                    899:
                    900: #ifdef DIAGNOSTIC
                    901:        if (sizeof(seq_event_rec) != SEQ_SYSEX_HDRSIZE) {
                    902:                printf("seq_do_fullsize: sysex size ??\n");
                    903:                return (EINVAL);
                    904:        }
                    905: #endif
                    906:        memcpy(&sysex, b, sizeof sysex);
                    907:        dev = sysex.device_no;
                    908:        DPRINTFN(2, ("seq_do_fullsize: fmt=%04x, dev=%d, len=%d\n",
                    909:                     sysex.key, dev, sysex.len));
                    910:        return (midiseq_loadpatch(sc->devs[dev], &sysex, uio));
                    911: }
                    912:
                    913: /* Convert an old sequencer event to a new one. */
                    914: int
                    915: seq_to_new(seq_event_rec *ev, struct uio *uio)
                    916: {
                    917:        int cmd, chan, note, parm;
                    918:        u_int32_t delay;
                    919:        int error;
                    920:
                    921:        cmd = SEQ_CMD(ev);
                    922:        chan = ev->arr[1];
                    923:        note = ev->arr[2];
                    924:        parm = ev->arr[3];
                    925:        DPRINTFN(3, ("seq_to_new: 0x%02x %d %d %d\n", cmd, chan, note, parm));
                    926:
                    927:        if (cmd >= 0x80) {
                    928:                /* Fill the event record */
                    929:                if (uio->uio_resid >= sizeof *ev - SEQOLD_CMDSIZE) {
                    930:                        error = uiomove(&ev->arr[SEQOLD_CMDSIZE],
                    931:                                        sizeof *ev - SEQOLD_CMDSIZE, uio);
                    932:                        if (error)
                    933:                                return (error);
                    934:                } else
                    935:                        return (EINVAL);
                    936:        }
                    937:
                    938:        switch(cmd) {
                    939:        case SEQOLD_NOTEOFF:
                    940:                note = 255;
                    941:                SEQ_ECMD(ev) = MIDI_NOTEOFF;
                    942:                goto onoff;
                    943:        case SEQOLD_NOTEON:
                    944:                SEQ_ECMD(ev) = MIDI_NOTEON;
                    945:        onoff:
                    946:                SEQ_CMD(ev) = SEQ_CHN_VOICE;
                    947:                SEQ_EDEV(ev) = 0;
                    948:                SEQ_ECHAN(ev) = chan;
                    949:                SEQ_ENOTE(ev) = note;
                    950:                SEQ_EPARM(ev) = parm;
                    951:                break;
                    952:        case SEQOLD_WAIT:
                    953:                delay = *(u_int32_t *)ev->arr >> 8;
                    954:                SEQ_CMD(ev) = SEQ_TIMING;
                    955:                SEQ_TCMD(ev) = TMR_WAIT_REL;
                    956:                *(u_int32_t *)&ev->arr[4] = delay;
                    957:                break;
                    958:        case SEQOLD_SYNCTIMER:
                    959:                SEQ_CMD(ev) = SEQ_TIMING;
                    960:                SEQ_TCMD(ev) = TMR_RESET;
                    961:                break;
                    962:        case SEQOLD_PGMCHANGE:
                    963:                SEQ_ECMD(ev) = MIDI_PGM_CHANGE;
                    964:                SEQ_CMD(ev) = SEQ_CHN_COMMON;
                    965:                SEQ_EDEV(ev) = 0;
                    966:                SEQ_ECHAN(ev) = chan;
                    967:                SEQ_EP1(ev) = note;
                    968:                break;
                    969:        case SEQOLD_MIDIPUTC:
                    970:                break;          /* interpret in normal mode */
                    971:        case SEQOLD_ECHO:
                    972:        case SEQOLD_PRIVATE:
                    973:        case SEQOLD_EXTENDED:
                    974:        default:
                    975:                DPRINTF(("seq_to_new: not impl 0x%02x\n", cmd));
                    976:                return (EINVAL);
                    977:        /* In case new events show up */
                    978:        case SEQ_TIMING:
                    979:        case SEQ_CHN_VOICE:
                    980:        case SEQ_CHN_COMMON:
                    981:        case SEQ_FULLSIZE:
                    982:                break;
                    983:        }
                    984:        return (0);
                    985: }
                    986:
                    987: /**********************************************/
                    988:
                    989: void
                    990: midiseq_in(struct midi_dev *md, u_char *msg, int len)
                    991: {
                    992:        int unit = md->unit;
                    993:        seq_event_rec ev;
                    994:        int status, chan;
                    995:
                    996:        DPRINTFN(2, ("midiseq_in: %p %02x %02x %02x\n",
                    997:                     md, msg[0], msg[1], msg[2]));
                    998:
                    999:        status = MIDI_GET_STATUS(msg[0]);
                   1000:        chan = MIDI_GET_CHAN(msg[0]);
                   1001:        switch (status) {
                   1002:        case MIDI_NOTEON:
                   1003:                if (msg[2] == 0) {
                   1004:                        status = MIDI_NOTEOFF;
                   1005:                        msg[2] = MIDI_HALF_VEL;
                   1006:                }
                   1007:                /* FALLTHROUGH */
                   1008:        case MIDI_NOTEOFF:
                   1009:        case MIDI_KEY_PRESSURE:
                   1010:                SEQ_MK_CHN_VOICE(&ev, unit, status, chan, msg[1], msg[2]);
                   1011:                break;
                   1012:        case MIDI_CTL_CHANGE:
                   1013:                SEQ_MK_CHN_COMMON(&ev, unit, status, chan, msg[1], 0, msg[2]);
                   1014:                break;
                   1015:        case MIDI_PGM_CHANGE:
                   1016:        case MIDI_CHN_PRESSURE:
                   1017:                SEQ_MK_CHN_COMMON(&ev, unit, status, chan, msg[1], 0, 0);
                   1018:                break;
                   1019:        case MIDI_PITCH_BEND:
                   1020:                SEQ_MK_CHN_COMMON(&ev, unit, status, chan, 0, 0,
                   1021:                                  (msg[1] & 0x7f) | ((msg[2] & 0x7f) << 7));
                   1022:                break;
                   1023:        default:
                   1024:                return;
                   1025:        }
                   1026:        seq_event_intr(md->seq, &ev);
                   1027: }
                   1028:
                   1029: struct midi_dev *
                   1030: midiseq_open(int unit, int flags)
                   1031: {
                   1032:        extern struct cfdriver midi_cd;
                   1033:        int error;
                   1034:        struct midi_dev *md;
                   1035:        struct midi_softc *sc;
                   1036:        struct midi_info mi;
                   1037:
                   1038:        DPRINTFN(2, ("midiseq_open: %d %d\n", unit, flags));
                   1039:        error = midiopen(makedev(0, unit), flags, 0, 0);
                   1040:        if (error)
                   1041:                return (0);
                   1042:        sc = midi_cd.cd_devs[unit];
                   1043:        sc->seqopen = 1;
                   1044:        md = malloc(sizeof *md, M_DEVBUF, M_WAITOK);
                   1045:        sc->seq_md = md;
                   1046:        memset(md, 0, sizeof *md);
                   1047:        md->msc = sc;
                   1048:        midi_getinfo(makedev(0, unit), &mi);
                   1049:        md->unit = unit;
                   1050:        md->name = mi.name;
                   1051:        md->subtype = 0;
                   1052:        md->nr_voices = 128;    /* XXX */
                   1053:        md->instr_bank_size = 128; /* XXX */
                   1054:        if (mi.props & MIDI_PROP_CAN_INPUT)
                   1055:                md->capabilities |= SYNTH_CAP_INPUT;
                   1056:        return (md);
                   1057: }
                   1058:
                   1059: void
                   1060: midiseq_close(struct midi_dev *md)
                   1061: {
                   1062:        DPRINTFN(2, ("midiseq_close: %d\n", md->unit));
                   1063:        midiclose(makedev(0, md->unit), 0, 0, 0);
                   1064:        free(md, M_DEVBUF);
                   1065: }
                   1066:
                   1067: void
                   1068: midiseq_reset(struct midi_dev *md)
                   1069: {
                   1070:        /* XXX send GM reset? */
                   1071:        DPRINTFN(3, ("midiseq_reset: %d\n", md->unit));
                   1072: }
                   1073:
                   1074: int
                   1075: midiseq_out(struct midi_dev *md, u_char *buf, u_int cc, int chk)
                   1076: {
                   1077:        DPRINTFN(5, ("midiseq_out: m=%p, unit=%d, buf[0]=0x%02x, cc=%d\n",
                   1078:                     md->msc, md->unit, buf[0], cc));
                   1079:
                   1080:        /* The MIDI "status" byte does not have to be repeated. */
                   1081:        if (chk && md->last_cmd == buf[0])
                   1082:                buf++, cc--;
                   1083:        else
                   1084:                md->last_cmd = buf[0];
                   1085:        return (midi_writebytes(md->unit, buf, cc));
                   1086: }
                   1087:
                   1088: int
                   1089: midiseq_noteon(struct midi_dev *md, int chan, int note, int vel)
                   1090: {
                   1091:        u_char buf[3];
                   1092:
                   1093:        DPRINTFN(6, ("midiseq_noteon 0x%02x %d %d\n",
                   1094:                     MIDI_NOTEON | chan, note, vel));
                   1095:        if (chan < 0 || chan > 15 ||
                   1096:            note < 0 || note > 127)
                   1097:                return (EINVAL);
                   1098:        if (vel < 0) vel = 0;
                   1099:        if (vel > 127) vel = 127;
                   1100:        buf[0] = MIDI_NOTEON | chan;
                   1101:        buf[1] = note;
                   1102:        buf[2] = vel;
                   1103:        return (midiseq_out(md, buf, 3, 1));
                   1104: }
                   1105:
                   1106: int
                   1107: midiseq_noteoff(struct midi_dev *md, int chan, int note, int vel)
                   1108: {
                   1109:        u_char buf[3];
                   1110:
                   1111:        if (chan < 0 || chan > 15 ||
                   1112:            note < 0 || note > 127)
                   1113:                return (EINVAL);
                   1114:        if (vel < 0) vel = 0;
                   1115:        if (vel > 127) vel = 127;
                   1116:        buf[0] = MIDI_NOTEOFF | chan;
                   1117:        buf[1] = note;
                   1118:        buf[2] = vel;
                   1119:        return (midiseq_out(md, buf, 3, 1));
                   1120: }
                   1121:
                   1122: int
                   1123: midiseq_keypressure(struct midi_dev *md, int chan, int note, int vel)
                   1124: {
                   1125:        u_char buf[3];
                   1126:
                   1127:        if (chan < 0 || chan > 15 ||
                   1128:            note < 0 || note > 127)
                   1129:                return (EINVAL);
                   1130:        if (vel < 0) vel = 0;
                   1131:        if (vel > 127) vel = 127;
                   1132:        buf[0] = MIDI_KEY_PRESSURE | chan;
                   1133:        buf[1] = note;
                   1134:        buf[2] = vel;
                   1135:        return (midiseq_out(md, buf, 3, 1));
                   1136: }
                   1137:
                   1138: int
                   1139: midiseq_pgmchange(struct midi_dev *md, int chan, int parm)
                   1140: {
                   1141:        u_char buf[2];
                   1142:
                   1143:        if (chan < 0 || chan > 15 ||
                   1144:            parm < 0 || parm > 127)
                   1145:                return (EINVAL);
                   1146:        buf[0] = MIDI_PGM_CHANGE | chan;
                   1147:        buf[1] = parm;
                   1148:        return (midiseq_out(md, buf, 2, 1));
                   1149: }
                   1150:
                   1151: int
                   1152: midiseq_chnpressure(struct midi_dev *md, int chan, int parm)
                   1153: {
                   1154:        u_char buf[2];
                   1155:
                   1156:        if (chan < 0 || chan > 15 ||
                   1157:            parm < 0 || parm > 127)
                   1158:                return (EINVAL);
                   1159:        buf[0] = MIDI_CHN_PRESSURE | chan;
                   1160:        buf[1] = parm;
                   1161:        return (midiseq_out(md, buf, 2, 1));
                   1162: }
                   1163:
                   1164: int
                   1165: midiseq_ctlchange(struct midi_dev *md, int chan, int parm, int w14)
                   1166: {
                   1167:        u_char buf[3];
                   1168:
                   1169:        if (chan < 0 || chan > 15 ||
                   1170:            parm < 0 || parm > 127)
                   1171:                return (EINVAL);
                   1172:        buf[0] = MIDI_CTL_CHANGE | chan;
                   1173:        buf[1] = parm;
                   1174:        buf[2] = w14 & 0x7f;
                   1175:        return (midiseq_out(md, buf, 3, 1));
                   1176: }
                   1177:
                   1178: int
                   1179: midiseq_pitchbend(struct midi_dev *md, int chan, int parm)
                   1180: {
                   1181:        u_char buf[3];
                   1182:
                   1183:        if (chan < 0 || chan > 15)
                   1184:                return (EINVAL);
                   1185:        buf[0] = MIDI_PITCH_BEND | chan;
                   1186:        buf[1] = parm & 0x7f;
                   1187:        buf[2] = (parm >> 7) & 0x7f;
                   1188:        return (midiseq_out(md, buf, 3, 1));
                   1189: }
                   1190:
                   1191: int
                   1192: midiseq_loadpatch(struct midi_dev *md, struct sysex_info *sysex, struct uio *uio)
                   1193: {
                   1194:        u_char c, buf[128];
                   1195:        int i, cc, error;
                   1196:
                   1197:        if (sysex->key != SEQ_SYSEX_PATCH) {
                   1198:                DPRINTFN(-1,("midiseq_loadpatch: bad patch key 0x%04x\n",
                   1199:                             sysex->key));
                   1200:                return (EINVAL);
                   1201:        }
                   1202:        if (uio->uio_resid < sysex->len)
                   1203:                /* adjust length, should be an error */
                   1204:                sysex->len = uio->uio_resid;
                   1205:
                   1206:        DPRINTFN(2, ("midiseq_loadpatch: len=%d\n", sysex->len));
                   1207:        if (sysex->len == 0)
                   1208:                return (EINVAL);
                   1209:        error = uiomove(&c, 1, uio);
                   1210:        if (error)
                   1211:                return error;
                   1212:        if (c != MIDI_SYSEX_START)              /* must start like this */
                   1213:                return (EINVAL);
                   1214:        error = midiseq_out(md, &c, 1, 0);
                   1215:        if (error)
                   1216:                return (error);
                   1217:        --sysex->len;
                   1218:        while (sysex->len > 0) {
                   1219:                cc = sysex->len;
                   1220:                if (cc > sizeof buf)
                   1221:                        cc = sizeof buf;
                   1222:                error = uiomove(buf, cc, uio);
                   1223:                if (error)
                   1224:                        break;
                   1225:                for(i = 0; i < cc && !MIDI_IS_STATUS(buf[i]); i++)
                   1226:                        ;
                   1227:                error = midiseq_out(md, buf, i, 0);
                   1228:                if (error)
                   1229:                        break;
                   1230:                sysex->len -= i;
                   1231:                if (i != cc)
                   1232:                        break;
                   1233:        }
                   1234:        /* Any leftover data in uio is rubbish;
                   1235:         * the SYSEX should be one write ending in SYSEX_END.
                   1236:         */
                   1237:        uio->uio_resid = 0;
                   1238:        c = MIDI_SYSEX_END;
                   1239:        return (midiseq_out(md, &c, 1, 0));
                   1240: }
                   1241:
                   1242: int
                   1243: midiseq_putc(struct midi_dev *md, int data)
                   1244: {
                   1245:        u_char c = data;
                   1246:        DPRINTFN(4,("midiseq_putc: 0x%02x\n", data));
                   1247:        return (midiseq_out(md, &c, 1, 0));
                   1248: }
                   1249:
                   1250: #include "midi.h"
                   1251: #if NMIDI == 0
                   1252: /*
                   1253:  * If someone has a sequencer, but no midi devices there will
                   1254:  * be unresolved references, so we provide little stubs.
                   1255:  */
                   1256:
                   1257: int
                   1258: midi_unit_count()
                   1259: {
                   1260:        return (0);
                   1261: }
                   1262:
                   1263: int
                   1264: midiopen(dev_t dev, int flags, int ifmt, struct proc *p)
                   1265: {
                   1266:        return (ENXIO);
                   1267: }
                   1268:
                   1269: struct cfdriver midi_cd;
                   1270:
                   1271: void
                   1272: midi_getinfo(dev_t dev, struct midi_info *mi)
                   1273: {
                   1274: }
                   1275:
                   1276: int
                   1277: midiclose(dev_t dev, int flags, int ifmt, struct proc *p)
                   1278: {
                   1279:        return (ENXIO);
                   1280: }
                   1281:
                   1282: int
                   1283: midi_writebytes(int unit, u_char *buf, int cc)
                   1284: {
                   1285:        return (ENXIO);
                   1286: }
                   1287: #endif /* NMIDI == 0 */
                   1288:
                   1289: #endif /* NSEQUENCER > 0 */
                   1290:

CVSweb