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