[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sequencer.c

Version: -  FREEBSD  -  FREEBSD10  -  FREEBSD9  -  FREEBSD92  -  FREEBSD91  -  FREEBSD90  -  FREEBSD8  -  FREEBSD82  -  FREEBSD81  -  FREEBSD80  -  FREEBSD7  -  FREEBSD74  -  FREEBSD73  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  cheribsd  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1  -  FREEBSD-LIBC  -  FREEBSD8-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  3  -  10 

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

Cache object: 488bac29901ba483b06083787ffe5870


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.