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

Cache object: 22fe154be8c2986b177e6a43ad806d2c


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