Annotation of sys/dev/ic/opl.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: opl.c,v 1.8 2006/07/27 05:55:00 miod Exp $ */
2: /* $NetBSD: opl.c,v 1.7 1998/12/08 14:26:56 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: /*
41: * The OPL3 (YMF262) manual can be found at
42: * ftp://ftp.yamahayst.com/pub/Fax_Back_Doc/Sound/YMF262.PDF
43: */
44:
45: #include <sys/param.h>
46: #include <sys/systm.h>
47: #include <sys/errno.h>
48: #include <sys/ioctl.h>
49: #include <sys/syslog.h>
50: #include <sys/device.h>
51: #include <sys/selinfo.h>
52:
53: #include <machine/cpu.h>
54: #include <machine/bus.h>
55:
56: #include <sys/audioio.h>
57: #include <sys/midiio.h>
58: #include <dev/audio_if.h>
59:
60: #include <dev/midi_if.h>
61: #include <dev/midivar.h>
62: #include <dev/midisynvar.h>
63:
64: #include <dev/ic/oplreg.h>
65: #include <dev/ic/oplvar.h>
66:
67: #ifdef AUDIO_DEBUG
68: #define DPRINTF(x) if (opldebug) printf x
69: #define DPRINTFN(n,x) if (opldebug >= (n)) printf x
70: int opldebug = 0;
71: #else
72: #define DPRINTF(x)
73: #define DPRINTFN(n,x)
74: #endif
75:
76: struct real_voice {
77: u_int8_t voice_num;
78: u_int8_t voice_mode; /* 0=unavailable, 2=2 OP, 4=4 OP */
79: u_int8_t iooffs; /* I/O port (left or right side) */
80: u_int8_t op[4]; /* Operator offsets */
81: };
82:
83: const struct opl_voice voicetab[] = {
84: /* No I/O offs OP1 OP2 OP3 OP4 */
85: /* --------------------------------------------------- */
86: { 0, OPL_L, {0x00, 0x03, 0x08, 0x0b}},
87: { 1, OPL_L, {0x01, 0x04, 0x09, 0x0c}},
88: { 2, OPL_L, {0x02, 0x05, 0x0a, 0x0d}},
89:
90: { 3, OPL_L, {0x08, 0x0b, 0x00, 0x00}},
91: { 4, OPL_L, {0x09, 0x0c, 0x00, 0x00}},
92: { 5, OPL_L, {0x0a, 0x0d, 0x00, 0x00}},
93:
94: { 6, OPL_L, {0x10, 0x13, 0x00, 0x00}},
95: { 7, OPL_L, {0x11, 0x14, 0x00, 0x00}},
96: { 8, OPL_L, {0x12, 0x15, 0x00, 0x00}},
97:
98: { 0, OPL_R, {0x00, 0x03, 0x08, 0x0b}},
99: { 1, OPL_R, {0x01, 0x04, 0x09, 0x0c}},
100: { 2, OPL_R, {0x02, 0x05, 0x0a, 0x0d}},
101: { 3, OPL_R, {0x08, 0x0b, 0x00, 0x00}},
102: { 4, OPL_R, {0x09, 0x0c, 0x00, 0x00}},
103: { 5, OPL_R, {0x0a, 0x0d, 0x00, 0x00}},
104:
105: { 6, OPL_R, {0x10, 0x13, 0x00, 0x00}},
106: { 7, OPL_R, {0x11, 0x14, 0x00, 0x00}},
107: { 8, OPL_R, {0x12, 0x15, 0x00, 0x00}}
108: };
109:
110: static void opl_probe_command(struct opl_attach_arg *, int, int);
111: static void opl_command(struct opl_softc *, int, int, int);
112: void opl_reset(struct opl_softc *);
113: void opl_freq_to_fnum (int freq, int *block, int *fnum);
114:
115: int oplsyn_open(midisyn *ms, int);
116: void oplsyn_close(midisyn *);
117: void oplsyn_reset(void *);
118: void oplsyn_noteon(midisyn *, u_int32_t, u_int32_t, u_int32_t);
119: void oplsyn_noteoff(midisyn *, u_int32_t, u_int32_t, u_int32_t);
120: void oplsyn_keypressure(midisyn *, u_int32_t, u_int32_t, u_int32_t);
121: void oplsyn_ctlchange(midisyn *, u_int32_t, u_int32_t, u_int32_t);
122: void oplsyn_pitchbend(midisyn *, u_int32_t, u_int32_t, u_int32_t);
123: void oplsyn_loadpatch(midisyn *, struct sysex_info *, struct uio *);
124:
125:
126: void opl_set_op_reg(struct opl_softc *, int, int, int, u_char);
127: void opl_set_ch_reg(struct opl_softc *, int, int, u_char);
128: void opl_load_patch(struct opl_softc *, int);
129: u_int32_t opl_get_block_fnum(int freq);
130: int opl_calc_vol(int regbyte, int volume, int main_vol);
131:
132: struct cfdriver opl_cd = {
133: NULL, "opl", DV_DULL
134: };
135:
136: struct midisyn_methods opl3_midi = {
137: oplsyn_open,
138: oplsyn_close,
139: 0,
140: 0,
141: oplsyn_noteon,
142: oplsyn_noteoff,
143: oplsyn_keypressure,
144: oplsyn_ctlchange,
145: 0,
146: 0,
147: oplsyn_pitchbend,
148: 0
149: };
150:
151: void
152: opl_attach(sc)
153: struct opl_softc *sc;
154: {
155: int i;
156: struct opl_attach_arg oaa;
157:
158: oaa.iot = sc->iot;
159: oaa.ioh = sc->ioh;
160: oaa.offs = sc->offs;
161: oaa.done = 0;
162:
163: if ((sc->model = opl_find(&oaa)) == 0) {
164: printf("\nopl: find failed\n");
165: return;
166: }
167:
168: sc->syn.mets = &opl3_midi;
169: snprintf(sc->syn.name, sizeof sc->syn.name, "%sYamaha OPL%d",
170: sc->syn.name, sc->model);
171: sc->syn.data = sc;
172: sc->syn.nvoice = sc->model == OPL_2 ? OPL2_NVOICE : OPL3_NVOICE;
173: sc->syn.flags = MS_DOALLOC | MS_FREQXLATE;
174: midisyn_attach(&sc->mididev, &sc->syn);
175:
176: /* Set up voice table */
177: for (i = 0; i < OPL3_NVOICE; i++)
178: sc->voices[i] = voicetab[i];
179:
180: opl_reset(sc);
181:
182: printf(": model OPL%d\n", sc->model);
183:
184: midi_attach_mi(&midisyn_hw_if, &sc->syn, &sc->mididev.dev);
185: }
186:
187: static void
188: opl_probe_command(oaa, addr, data)
189: struct opl_attach_arg *oaa;
190: int addr, data;
191: {
192: DPRINTFN(4, ("opl_probe_command: addr=0x%02x data=0x%02x\n",
193: addr, data));
194: bus_space_write_1(oaa->iot, oaa->ioh, OPL_ADDR + OPL_L + oaa->offs,
195: addr);
196: delay(10);
197: bus_space_write_1(oaa->iot, oaa->ioh, OPL_DATA + OPL_L + oaa->offs,
198: data);
199: delay(30);
200: }
201:
202: static void
203: opl_command(sc, offs, addr, data)
204: struct opl_softc *sc;
205: int offs;
206: int addr, data;
207: {
208: DPRINTFN(4, ("opl_command: sc=%p, offs=%d addr=0x%02x data=0x%02x\n",
209: sc, offs, addr, data));
210: offs += sc->offs;
211: bus_space_write_1(sc->iot, sc->ioh, OPL_ADDR+offs, addr);
212: if (sc->model == OPL_2)
213: delay(10);
214: else
215: delay(6);
216: bus_space_write_1(sc->iot, sc->ioh, OPL_DATA+offs, data);
217: if (sc->model == OPL_2)
218: delay(30);
219: else
220: delay(6);
221: }
222:
223: int
224: opl_find(oaa)
225: struct opl_attach_arg *oaa;
226: {
227: u_int8_t status1, status2;
228: int model;
229:
230: DPRINTFN(2,("opl_find: ioh=0x%x\n", (int)oaa->ioh));
231: model = OPL_2; /* worst case assumption */
232:
233: /* Reset timers 1 and 2 */
234: opl_probe_command(oaa, OPL_TIMER_CONTROL,
235: OPL_TIMER1_MASK | OPL_TIMER2_MASK);
236: /* Reset the IRQ of the FM chip */
237: opl_probe_command(oaa, OPL_TIMER_CONTROL, OPL_IRQ_RESET);
238:
239: /* get status bits */
240: status1 = bus_space_read_1(oaa->iot, oaa->ioh,
241: OPL_STATUS + OPL_L + oaa->offs);
242:
243: opl_probe_command(oaa, OPL_TIMER1, -2); /* wait 2 ticks */
244: opl_probe_command(oaa, OPL_TIMER_CONTROL, /* start timer1 */
245: OPL_TIMER1_START | OPL_TIMER2_MASK);
246: delay(1000); /* wait for timer to expire */
247:
248: /* get status bits again */
249: status2 = bus_space_read_1(oaa->iot, oaa->ioh,
250: OPL_STATUS + OPL_L + oaa->offs);
251:
252: opl_probe_command(oaa, OPL_TIMER_CONTROL,
253: OPL_TIMER1_MASK | OPL_TIMER2_MASK);
254: opl_probe_command(oaa, OPL_TIMER_CONTROL, OPL_IRQ_RESET);
255:
256: DPRINTFN(2,("opl_find: %02x %02x\n", status1, status2));
257:
258: if ((status1 & OPL_STATUS_MASK) != 0 ||
259: (status2 & OPL_STATUS_MASK) != (OPL_STATUS_IRQ | OPL_STATUS_FT1))
260: return (0);
261:
262: switch(status1) {
263: case 0x00:
264: case 0x0f:
265: model = OPL_3;
266: break;
267: case 0x06:
268: model = OPL_2;
269: break;
270: default:
271: return 0;
272: }
273:
274: DPRINTFN(2,("opl_find: OPL%d at 0x%x detected\n",
275: model, (int)oaa->ioh));
276: return (model);
277: }
278:
279: void
280: opl_set_op_reg(sc, base, voice, op, value)
281: struct opl_softc *sc;
282: int base;
283: int voice;
284: int op;
285: u_char value;
286: {
287: struct opl_voice *v = &sc->voices[voice];
288: opl_command(sc, v->iooffs, base + v->op[op], value);
289: }
290:
291: void
292: opl_set_ch_reg(sc, base, voice, value)
293: struct opl_softc *sc;
294: int base;
295: int voice;
296: u_char value;
297: {
298: struct opl_voice *v = &sc->voices[voice];
299: opl_command(sc, v->iooffs, base + v->voiceno, value);
300: }
301:
302:
303: void
304: opl_load_patch(sc, v)
305: struct opl_softc *sc;
306: int v;
307: {
308: const struct opl_operators *p = sc->voices[v].patch;
309:
310: opl_set_op_reg(sc, OPL_AM_VIB, v, 0, p->ops[OO_CHARS+0]);
311: opl_set_op_reg(sc, OPL_AM_VIB, v, 1, p->ops[OO_CHARS+1]);
312: opl_set_op_reg(sc, OPL_KSL_LEVEL, v, 0, p->ops[OO_KSL_LEV+0]);
313: opl_set_op_reg(sc, OPL_KSL_LEVEL, v, 1, p->ops[OO_KSL_LEV+1]);
314: opl_set_op_reg(sc, OPL_ATTACK_DECAY, v, 0, p->ops[OO_ATT_DEC+0]);
315: opl_set_op_reg(sc, OPL_ATTACK_DECAY, v, 1, p->ops[OO_ATT_DEC+1]);
316: opl_set_op_reg(sc, OPL_SUSTAIN_RELEASE, v, 0, p->ops[OO_SUS_REL+0]);
317: opl_set_op_reg(sc, OPL_SUSTAIN_RELEASE, v, 1, p->ops[OO_SUS_REL+1]);
318: opl_set_op_reg(sc, OPL_WAVE_SELECT, v, 0, p->ops[OO_WAV_SEL+0]);
319: opl_set_op_reg(sc, OPL_WAVE_SELECT, v, 1, p->ops[OO_WAV_SEL+1]);
320: opl_set_ch_reg(sc, OPL_FEEDBACK_CONNECTION, v, p->ops[OO_FB_CONN]);
321: }
322:
323: #define OPL_FNUM_FAIL 0xffff
324: u_int32_t
325: opl_get_block_fnum(freq)
326: int freq;
327: {
328: u_int32_t f_num = freq / 3125;
329: u_int32_t block = 0;
330:
331: while (f_num > 0x3FF && block < 8) {
332: block++;
333: f_num >>= 1;
334: }
335:
336: if (block > 7)
337: return (OPL_FNUM_FAIL);
338: else
339: return ((block << 10) | f_num);
340: }
341:
342:
343: void
344: opl_reset(sc)
345: struct opl_softc *sc;
346: {
347: int i;
348:
349: for (i = 1; i <= OPL_MAXREG; i++)
350: opl_command(sc, OPL_L, OPL_KEYON_BLOCK + i, 0);
351:
352: opl_command(sc, OPL_L, OPL_TEST, OPL_ENABLE_WAVE_SELECT);
353: opl_command(sc, OPL_L, OPL_PERCUSSION, 0);
354: if (sc->model == OPL_3) {
355: opl_command(sc, OPL_R, OPL_MODE, OPL3_ENABLE);
356: opl_command(sc, OPL_R,OPL_CONNECTION_SELECT,OPL_NOCONNECTION);
357: }
358:
359: sc->volume = 64;
360: }
361:
362: int
363: oplsyn_open(ms, flags)
364: midisyn *ms;
365: int flags;
366: {
367: struct opl_softc *sc = ms->data;
368:
369: DPRINTFN(2, ("oplsyn_open: %d\n", flags));
370:
371: opl_reset(ms->data);
372: if (sc->spkrctl)
373: sc->spkrctl(sc->spkrarg, 1);
374: return (0);
375: }
376:
377: void
378: oplsyn_close(ms)
379: midisyn *ms;
380: {
381: struct opl_softc *sc = ms->data;
382:
383: DPRINTFN(2, ("oplsyn_close:\n"));
384:
385: /*opl_reset(ms->data);*/
386: if (sc->spkrctl)
387: sc->spkrctl(sc->spkrarg, 0);
388: }
389:
390: #if 0
391: void
392: oplsyn_getinfo(addr, sd)
393: void *addr;
394: struct synth_dev *sd;
395: {
396: struct opl_softc *sc = addr;
397:
398: sd->name = sc->model == OPL_2 ? "Yamaha OPL2" : "Yamaha OPL3";
399: sd->type = SYNTH_TYPE_FM;
400: sd->subtype = sc->model == OPL_2 ? SYNTH_SUB_FM_TYPE_ADLIB
401: : SYNTH_SUB_FM_TYPE_OPL3;
402: sd->capabilities = 0;
403: }
404: #endif
405:
406: void
407: oplsyn_reset(addr)
408: void *addr;
409: {
410: struct opl_softc *sc = addr;
411: DPRINTFN(3, ("oplsyn_reset:\n"));
412: opl_reset(sc);
413: }
414:
415: int8_t opl_volume_table[128] =
416: {-64, -48, -40, -35, -32, -29, -27, -26,
417: -24, -23, -21, -20, -19, -18, -18, -17,
418: -16, -15, -15, -14, -13, -13, -12, -12,
419: -11, -11, -10, -10, -10, -9, -9, -8,
420: -8, -8, -7, -7, -7, -6, -6, -6,
421: -5, -5, -5, -5, -4, -4, -4, -4,
422: -3, -3, -3, -3, -2, -2, -2, -2,
423: -2, -1, -1, -1, -1, 0, 0, 0,
424: 0, 0, 0, 1, 1, 1, 1, 1,
425: 1, 2, 2, 2, 2, 2, 2, 2,
426: 3, 3, 3, 3, 3, 3, 3, 4,
427: 4, 4, 4, 4, 4, 4, 4, 5,
428: 5, 5, 5, 5, 5, 5, 5, 5,
429: 6, 6, 6, 6, 6, 6, 6, 6,
430: 6, 7, 7, 7, 7, 7, 7, 7,
431: 7, 7, 7, 8, 8, 8, 8, 8};
432:
433: int
434: opl_calc_vol(regbyte, volume, mainvol)
435: int regbyte;
436: int volume;
437: int mainvol;
438: {
439: int level = ~regbyte & OPL_TOTAL_LEVEL_MASK;
440:
441: if (mainvol > 127)
442: mainvol = 127;
443:
444: volume = (volume * mainvol) / 127;
445:
446: if (level)
447: level += opl_volume_table[volume];
448:
449: if (level > OPL_TOTAL_LEVEL_MASK)
450: level = OPL_TOTAL_LEVEL_MASK;
451: if (level < 0)
452: level = 0;
453:
454: return (~level & OPL_TOTAL_LEVEL_MASK);
455: }
456:
457: void
458: oplsyn_noteon(ms, voice, freq, vel)
459: midisyn *ms;
460: u_int32_t voice, freq, vel;
461: {
462: struct opl_softc *sc = ms->data;
463: struct opl_voice *v;
464: const struct opl_operators *p;
465: u_int32_t block_fnum;
466: int mult;
467: int c_mult, m_mult;
468: u_int8_t chars0, chars1, ksl0, ksl1, fbc;
469: u_int8_t r20m, r20c, r40m, r40c, rA0, rB0;
470: u_int8_t vol0, vol1;
471:
472: DPRINTFN(3, ("oplsyn_noteon: %p %d %d\n", sc, voice,
473: MIDISYN_FREQ_TO_HZ(freq)));
474:
475: #ifdef DIAGNOSTIC
476: if (voice < 0 || voice >= sc->syn.nvoice) {
477: printf("oplsyn_noteon: bad voice %d\n", voice);
478: return;
479: }
480: #endif
481: /* Turn off old note */
482: opl_set_op_reg(sc, OPL_KSL_LEVEL, voice, 0, 0xff);
483: opl_set_op_reg(sc, OPL_KSL_LEVEL, voice, 1, 0xff);
484: opl_set_ch_reg(sc, OPL_KEYON_BLOCK, voice, 0);
485:
486: v = &sc->voices[voice];
487:
488: p = &opl2_instrs[MS_GETPGM(ms, voice)];
489: v->patch = p;
490: opl_load_patch(sc, voice);
491:
492: mult = 1;
493: for (;;) {
494: block_fnum = opl_get_block_fnum(freq / mult);
495: if (block_fnum != OPL_FNUM_FAIL)
496: break;
497: mult *= 2;
498: if (mult == 16)
499: mult = 15;
500: }
501:
502: chars0 = p->ops[OO_CHARS+0];
503: chars1 = p->ops[OO_CHARS+1];
504: m_mult = (chars0 & OPL_MULTIPLE_MASK) * mult;
505: c_mult = (chars1 & OPL_MULTIPLE_MASK) * mult;
506: if ((block_fnum == OPL_FNUM_FAIL) || (m_mult > 15) || (c_mult > 15)) {
507: printf("oplsyn_noteon: frequence out of range %d\n",
508: MIDISYN_FREQ_TO_HZ(freq));
509: return;
510: }
511: r20m = (chars0 &~ OPL_MULTIPLE_MASK) | m_mult;
512: r20c = (chars1 &~ OPL_MULTIPLE_MASK) | c_mult;
513:
514: /* 2 voice */
515: ksl0 = p->ops[OO_KSL_LEV+0];
516: ksl1 = p->ops[OO_KSL_LEV+1];
517: if (p->ops[OO_FB_CONN] & 0x01) {
518: vol0 = opl_calc_vol(ksl0, vel, sc->volume);
519: vol1 = opl_calc_vol(ksl1, vel, sc->volume);
520: } else {
521: vol0 = ksl0;
522: vol1 = opl_calc_vol(ksl1, vel, sc->volume);
523: }
524: r40m = (ksl0 & OPL_KSL_MASK) | vol0;
525: r40c = (ksl1 & OPL_KSL_MASK) | vol1;
526:
527: rA0 = block_fnum & 0xFF;
528: rB0 = (block_fnum >> 8) | OPL_KEYON_BIT;
529:
530: v->rB0 = rB0;
531:
532: fbc = p->ops[OO_FB_CONN];
533: if (sc->model == OPL_3) {
534: fbc &= ~OPL_STEREO_BITS;
535: /* XXX use pan */
536: fbc |= OPL_VOICE_TO_LEFT | OPL_VOICE_TO_RIGHT;
537: }
538: opl_set_ch_reg(sc, OPL_FEEDBACK_CONNECTION, voice, fbc);
539:
540: opl_set_op_reg(sc, OPL_AM_VIB, voice, 0, r20m);
541: opl_set_op_reg(sc, OPL_AM_VIB, voice, 1, r20c);
542: opl_set_op_reg(sc, OPL_KSL_LEVEL, voice, 0, r40m);
543: opl_set_op_reg(sc, OPL_KSL_LEVEL, voice, 1, r40c);
544: opl_set_ch_reg(sc, OPL_FNUM_LOW, voice, rA0);
545: opl_set_ch_reg(sc, OPL_KEYON_BLOCK, voice, rB0);
546: }
547:
548: void
549: oplsyn_noteoff(ms, voice, note, vel)
550: midisyn *ms;
551: u_int32_t voice, note, vel;
552: {
553: struct opl_softc *sc = ms->data;
554: struct opl_voice *v;
555:
556: DPRINTFN(3, ("oplsyn_noteoff: %p %d %d\n", sc, voice,
557: MIDISYN_FREQ_TO_HZ(note)));
558:
559: #ifdef DIAGNOSTIC
560: if (voice < 0 || voice >= sc->syn.nvoice) {
561: printf("oplsyn_noteoff: bad voice %d\n", voice);
562: return;
563: }
564: #endif
565: v = &sc->voices[voice];
566: opl_set_ch_reg(sc, 0xB0, voice, v->rB0 & ~OPL_KEYON_BIT);
567: }
568:
569: void
570: oplsyn_keypressure(ms, voice, note, vel)
571: midisyn *ms;
572: u_int32_t voice, note, vel;
573: {
574: #ifdef AUDIO_DEBUG
575: struct opl_softc *sc = ms->data;
576: DPRINTFN(1, ("oplsyn_keypressure: %p %d\n", sc, note));
577: #endif
578: }
579:
580: void
581: oplsyn_ctlchange(ms, voice, parm, w14)
582: midisyn *ms;
583: u_int32_t voice, parm, w14;
584: {
585: #ifdef AUDIO_DEBUG
586: struct opl_softc *sc = ms->data;
587: DPRINTFN(1, ("oplsyn_ctlchange: %p %d\n", sc, voice));
588: #endif
589: }
590:
591: void
592: oplsyn_pitchbend(ms, voice, parm, x)
593: midisyn *ms;
594: u_int32_t voice, parm, x;
595: {
596: #ifdef AUDIO_DEBUG
597: struct opl_softc *sc = ms->data;
598: DPRINTFN(1, ("oplsyn_pitchbend: %p %d\n", sc, voice));
599: #endif
600: }
601:
602: void
603: oplsyn_loadpatch(ms, sysex, uio)
604: midisyn *ms;
605: struct sysex_info *sysex;
606: struct uio *uio;
607: {
608: #if 0
609: struct opl_softc *sc = ms->data;
610: struct sbi_instrument ins;
611:
612: DPRINTFN(1, ("oplsyn_loadpatch: %p\n", sc));
613:
614: memcpy(&ins, sysex, sizeof *sysex);
615: if (uio->uio_resid >= sizeof ins - sizeof *sysex)
616: return EINVAL;
617: uiomove((char *)&ins + sizeof *sysex, sizeof ins - sizeof *sysex, uio);
618: /* XXX */
619: #endif
620: }
CVSweb