The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ 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  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  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 
SearchContext: -  none  -  3  -  10 

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

Cache object: d27f03b7b0a183be5f367ea6a993eaad


[ 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.