root/dev/sequencer.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sequencerattach
  2. sequenceropen
  3. seq_sleep_timo
  4. seq_sleep
  5. seq_wakeup
  6. seq_drain
  7. seq_timeout
  8. seq_startoutput
  9. sequencerclose
  10. seq_input_event
  11. seq_event_intr
  12. sequencerread
  13. sequencerwrite
  14. sequencerioctl
  15. sequencerpoll
  16. seq_reset
  17. seq_do_command
  18. seq_do_chnvoice
  19. seq_do_chncommon
  20. seq_do_timing
  21. seq_do_local
  22. seq_do_sysex
  23. seq_timer
  24. seq_do_fullsize
  25. seq_to_new
  26. midiseq_in
  27. midiseq_open
  28. midiseq_close
  29. midiseq_reset
  30. midiseq_out
  31. midiseq_noteon
  32. midiseq_noteoff
  33. midiseq_keypressure
  34. midiseq_pgmchange
  35. midiseq_chnpressure
  36. midiseq_ctlchange
  37. midiseq_pitchbend
  38. midiseq_loadpatch
  39. midiseq_putc
  40. midi_unit_count
  41. midiopen
  42. midi_getinfo
  43. midiclose
  44. midi_writebytes

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

/* [<][>][^][v][top][bottom][index][help] */