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-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: eb7b2512e8b2d547dfa317451b00c43f


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