This source file includes following definitions.
- snd_opl3_calc_volume
- snd_opl3_calc_pitch
- debug_alloc
- opl3_get_voice
- snd_opl3_timer_func
- snd_opl3_start_timer
- snd_opl3_note_on
- snd_opl3_kill_voice
- snd_opl3_note_off_unsafe
- snd_opl3_note_off
- snd_opl3_key_press
- snd_opl3_terminate_note
- snd_opl3_update_pitch
- snd_opl3_pitch_ctrl
- snd_opl3_control
- snd_opl3_nrpn
- snd_opl3_sysex
1
2
3
4
5
6
7
8 #undef DEBUG_ALLOC
9 #undef DEBUG_MIDI
10
11 #include "opl3_voice.h"
12 #include <sound/asoundef.h>
13
14 static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
15 struct snd_midi_channel *chan);
16
17
18
19
20
21
22
23
24
25
26 static char opl3_volume_table[128] =
27 {
28 -63, -48, -40, -35, -32, -29, -27, -26,
29 -24, -23, -21, -20, -19, -18, -18, -17,
30 -16, -15, -15, -14, -13, -13, -12, -12,
31 -11, -11, -10, -10, -10, -9, -9, -8,
32 -8, -8, -7, -7, -7, -6, -6, -6,
33 -5, -5, -5, -5, -4, -4, -4, -4,
34 -3, -3, -3, -3, -2, -2, -2, -2,
35 -2, -1, -1, -1, -1, 0, 0, 0,
36 0, 0, 0, 1, 1, 1, 1, 1,
37 1, 2, 2, 2, 2, 2, 2, 2,
38 3, 3, 3, 3, 3, 3, 3, 4,
39 4, 4, 4, 4, 4, 4, 4, 5,
40 5, 5, 5, 5, 5, 5, 5, 5,
41 6, 6, 6, 6, 6, 6, 6, 6,
42 6, 7, 7, 7, 7, 7, 7, 7,
43 7, 7, 7, 8, 8, 8, 8, 8
44 };
45
46 void snd_opl3_calc_volume(unsigned char *volbyte, int vel,
47 struct snd_midi_channel *chan)
48 {
49 int oldvol, newvol, n;
50 int volume;
51
52 volume = (vel * chan->gm_volume * chan->gm_expression) / (127*127);
53 if (volume > 127)
54 volume = 127;
55
56 oldvol = OPL3_TOTAL_LEVEL_MASK - (*volbyte & OPL3_TOTAL_LEVEL_MASK);
57
58 newvol = opl3_volume_table[volume] + oldvol;
59 if (newvol > OPL3_TOTAL_LEVEL_MASK)
60 newvol = OPL3_TOTAL_LEVEL_MASK;
61 else if (newvol < 0)
62 newvol = 0;
63
64 n = OPL3_TOTAL_LEVEL_MASK - (newvol & OPL3_TOTAL_LEVEL_MASK);
65
66 *volbyte = (*volbyte & OPL3_KSL_MASK) | (n & OPL3_TOTAL_LEVEL_MASK);
67 }
68
69
70
71
72 static short opl3_note_table[16] =
73 {
74 305, 323,
75 343, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647,
76 686, 726
77 };
78
79 static void snd_opl3_calc_pitch(unsigned char *fnum, unsigned char *blocknum,
80 int note, struct snd_midi_channel *chan)
81 {
82 int block = ((note / 12) & 0x07) - 1;
83 int idx = (note % 12) + 2;
84 int freq;
85
86 if (chan->midi_pitchbend) {
87 int pitchbend = chan->midi_pitchbend;
88 int segment;
89
90 if (pitchbend < -0x2000)
91 pitchbend = -0x2000;
92 if (pitchbend > 0x1FFF)
93 pitchbend = 0x1FFF;
94
95 segment = pitchbend / 0x1000;
96 freq = opl3_note_table[idx+segment];
97 freq += ((opl3_note_table[idx+segment+1] - freq) *
98 (pitchbend % 0x1000)) / 0x1000;
99 } else {
100 freq = opl3_note_table[idx];
101 }
102
103 *fnum = (unsigned char) freq;
104 *blocknum = ((freq >> 8) & OPL3_FNUM_HIGH_MASK) |
105 ((block << 2) & OPL3_BLOCKNUM_MASK);
106 }
107
108
109 #ifdef DEBUG_ALLOC
110 static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) {
111 int i;
112 char *str = "x.24";
113
114 printk(KERN_DEBUG "time %.5i: %s [%.2i]: ", opl3->use_time, s, voice);
115 for (i = 0; i < opl3->max_voices; i++)
116 printk(KERN_CONT "%c", *(str + opl3->voices[i].state + 1));
117 printk(KERN_CONT "\n");
118 }
119 #endif
120
121
122
123
124 static int opl3_get_voice(struct snd_opl3 *opl3, int instr_4op,
125 struct snd_midi_channel *chan) {
126 int chan_4op_1;
127 int chan_4op_2;
128
129 struct snd_opl3_voice *vp, *vp2;
130 unsigned int voice_time;
131 int i;
132
133 #ifdef DEBUG_ALLOC
134 char *alloc_type[3] = { "FREE ", "CHEAP ", "EXPENSIVE" };
135 #endif
136
137
138 enum {
139 FREE = 0, CHEAP, EXPENSIVE, END
140 };
141
142
143 struct best {
144 unsigned int time;
145 int voice;
146 } best[END];
147 struct best *bp;
148
149 for (i = 0; i < END; i++) {
150 best[i].time = (unsigned int)(-1);
151 best[i].voice = -1;
152 }
153
154
155 for (i = 0; i < opl3->max_voices; i++) {
156 vp = &opl3->voices[i];
157
158 if (vp->state == SNDRV_OPL3_ST_NOT_AVAIL)
159
160
161 continue;
162
163 voice_time = vp->time;
164 bp = best;
165
166 chan_4op_1 = ((i < 3) || (i > 8 && i < 12));
167 chan_4op_2 = ((i > 2 && i < 6) || (i > 11 && i < 15));
168 if (instr_4op) {
169
170
171 if (!chan_4op_1)
172 continue;
173
174 if (vp->state)
175
176 bp++;
177
178
179 vp2 = &opl3->voices[i + 3];
180 if (vp2->state == SNDRV_OPL3_ST_ON_2OP) {
181
182 bp++;
183 voice_time = (voice_time > vp->time) ?
184 voice_time : vp->time;
185 }
186 } else {
187
188 if ((chan_4op_1) || (chan_4op_2))
189
190 bp++;
191 else if (vp->state)
192
193 bp++;
194
195 if (vp->state)
196 bp++;
197 }
198 if (voice_time < bp->time) {
199 bp->time = voice_time;
200 bp->voice = i;
201 }
202 }
203
204 for (i = 0; i < END; i++) {
205 if (best[i].voice >= 0) {
206 #ifdef DEBUG_ALLOC
207 printk(KERN_DEBUG "%s %iop allocation on voice %i\n",
208 alloc_type[i], instr_4op ? 4 : 2,
209 best[i].voice);
210 #endif
211 return best[i].voice;
212 }
213 }
214
215 return -1;
216 }
217
218
219
220
221
222
223 void snd_opl3_timer_func(struct timer_list *t)
224 {
225
226 struct snd_opl3 *opl3 = from_timer(opl3, t, tlist);
227 unsigned long flags;
228 int again = 0;
229 int i;
230
231 spin_lock_irqsave(&opl3->voice_lock, flags);
232 for (i = 0; i < opl3->max_voices; i++) {
233 struct snd_opl3_voice *vp = &opl3->voices[i];
234 if (vp->state > 0 && vp->note_off_check) {
235 if (vp->note_off == jiffies)
236 snd_opl3_note_off_unsafe(opl3, vp->note, 0,
237 vp->chan);
238 else
239 again++;
240 }
241 }
242 spin_unlock_irqrestore(&opl3->voice_lock, flags);
243
244 spin_lock_irqsave(&opl3->sys_timer_lock, flags);
245 if (again)
246 mod_timer(&opl3->tlist, jiffies + 1);
247 else
248 opl3->sys_timer_status = 0;
249 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
250 }
251
252
253
254
255 static void snd_opl3_start_timer(struct snd_opl3 *opl3)
256 {
257 unsigned long flags;
258 spin_lock_irqsave(&opl3->sys_timer_lock, flags);
259 if (! opl3->sys_timer_status) {
260 mod_timer(&opl3->tlist, jiffies + 1);
261 opl3->sys_timer_status = 1;
262 }
263 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
264 }
265
266
267
268
269 static int snd_opl3_oss_map[MAX_OPL3_VOICES] = {
270 0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17, 3, 4 ,5, 12, 13, 14
271 };
272
273
274
275
276 void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
277 {
278 struct snd_opl3 *opl3;
279 int instr_4op;
280
281 int voice;
282 struct snd_opl3_voice *vp, *vp2;
283 unsigned short connect_mask;
284 unsigned char connection;
285 unsigned char vol_op[4];
286
287 int extra_prg = 0;
288
289 unsigned short reg_side;
290 unsigned char op_offset;
291 unsigned char voice_offset;
292 unsigned short opl3_reg;
293 unsigned char reg_val;
294 unsigned char prg, bank;
295
296 int key = note;
297 unsigned char fnum, blocknum;
298 int i;
299
300 struct fm_patch *patch;
301 struct fm_instrument *fm;
302 unsigned long flags;
303
304 opl3 = p;
305
306 #ifdef DEBUG_MIDI
307 snd_printk(KERN_DEBUG "Note on, ch %i, inst %i, note %i, vel %i\n",
308 chan->number, chan->midi_program, note, vel);
309 #endif
310
311
312
313 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
314 if (chan->drum_channel) {
315
316 bank = 128;
317 prg = note;
318 } else {
319 bank = chan->gm_bank_select;
320 prg = chan->midi_program;
321 }
322 } else {
323
324 if (chan->number >= MAX_OPL3_VOICES)
325 return;
326
327
328 bank = 127;
329 prg = chan->midi_program;
330 }
331
332 spin_lock_irqsave(&opl3->voice_lock, flags);
333
334 if (use_internal_drums) {
335 snd_opl3_drum_switch(opl3, note, vel, 1, chan);
336 spin_unlock_irqrestore(&opl3->voice_lock, flags);
337 return;
338 }
339
340 __extra_prg:
341 patch = snd_opl3_find_patch(opl3, prg, bank, 0);
342 if (!patch) {
343 spin_unlock_irqrestore(&opl3->voice_lock, flags);
344 return;
345 }
346
347 fm = &patch->inst;
348 switch (patch->type) {
349 case FM_PATCH_OPL2:
350 instr_4op = 0;
351 break;
352 case FM_PATCH_OPL3:
353 if (opl3->hardware >= OPL3_HW_OPL3) {
354 instr_4op = 1;
355 break;
356 }
357
358 default:
359 spin_unlock_irqrestore(&opl3->voice_lock, flags);
360 return;
361 }
362 #ifdef DEBUG_MIDI
363 snd_printk(KERN_DEBUG " --> OPL%i instrument: %s\n",
364 instr_4op ? 3 : 2, patch->name);
365 #endif
366
367
368 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
369 voice = opl3_get_voice(opl3, instr_4op, chan);
370 } else {
371
372 voice = snd_opl3_oss_map[chan->number];
373 }
374
375 if (voice < 0) {
376 spin_unlock_irqrestore(&opl3->voice_lock, flags);
377 return;
378 }
379
380 if (voice < MAX_OPL2_VOICES) {
381
382 reg_side = OPL3_LEFT;
383 voice_offset = voice;
384 connect_mask = (OPL3_LEFT_4OP_0 << voice_offset) & 0x07;
385 } else {
386
387 reg_side = OPL3_RIGHT;
388 voice_offset = voice - MAX_OPL2_VOICES;
389 connect_mask = (OPL3_RIGHT_4OP_0 << voice_offset) & 0x38;
390 }
391
392
393 vp = &opl3->voices[voice];
394 if (vp->state > 0) {
395 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
396 reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
397 opl3->command(opl3, opl3_reg, reg_val);
398 }
399 if (instr_4op) {
400 vp2 = &opl3->voices[voice + 3];
401 if (vp->state > 0) {
402 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK +
403 voice_offset + 3);
404 reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
405 opl3->command(opl3, opl3_reg, reg_val);
406 }
407 }
408
409
410 if (instr_4op) {
411 if ((opl3->connection_reg ^ connect_mask) & connect_mask) {
412 opl3->connection_reg |= connect_mask;
413
414 opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
415 opl3->command(opl3, opl3_reg, opl3->connection_reg);
416 }
417 } else {
418 if ((opl3->connection_reg ^ ~connect_mask) & connect_mask) {
419 opl3->connection_reg &= ~connect_mask;
420
421 opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
422 opl3->command(opl3, opl3_reg, opl3->connection_reg);
423 }
424 }
425
426 #ifdef DEBUG_MIDI
427 snd_printk(KERN_DEBUG " --> setting OPL3 connection: 0x%x\n",
428 opl3->connection_reg);
429 #endif
430
431
432
433
434 for (i = 0; i < (instr_4op ? 4 : 2); i++)
435 vol_op[i] = fm->op[i].ksl_level;
436
437 connection = fm->feedback_connection[0] & 0x01;
438 if (instr_4op) {
439 connection <<= 1;
440 connection |= fm->feedback_connection[1] & 0x01;
441
442 snd_opl3_calc_volume(&vol_op[3], vel, chan);
443 switch (connection) {
444 case 0x03:
445 snd_opl3_calc_volume(&vol_op[2], vel, chan);
446
447 case 0x02:
448 snd_opl3_calc_volume(&vol_op[0], vel, chan);
449 break;
450 case 0x01:
451 snd_opl3_calc_volume(&vol_op[1], vel, chan);
452 }
453 } else {
454 snd_opl3_calc_volume(&vol_op[1], vel, chan);
455 if (connection)
456 snd_opl3_calc_volume(&vol_op[0], vel, chan);
457 }
458
459
460 for (i = 0; i < (instr_4op ? 4 : 2); i++) {
461 #ifdef DEBUG_MIDI
462 snd_printk(KERN_DEBUG " --> programming operator %i\n", i);
463 #endif
464 op_offset = snd_opl3_regmap[voice_offset][i];
465
466
467 reg_val = fm->op[i].am_vib;
468 opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset);
469 opl3->command(opl3, opl3_reg, reg_val);
470
471
472 reg_val = vol_op[i];
473 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset);
474 opl3->command(opl3, opl3_reg, reg_val);
475
476
477 reg_val = fm->op[i].attack_decay;
478 opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset);
479 opl3->command(opl3, opl3_reg, reg_val);
480
481
482 reg_val = fm->op[i].sustain_release;
483 opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset);
484 opl3->command(opl3, opl3_reg, reg_val);
485
486
487 reg_val = fm->op[i].wave_select;
488 opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset);
489 opl3->command(opl3, opl3_reg, reg_val);
490 }
491
492
493 reg_val = fm->feedback_connection[0];
494
495 reg_val |= OPL3_STEREO_BITS;
496 if (chan->gm_pan < 43)
497 reg_val &= ~OPL3_VOICE_TO_RIGHT;
498 if (chan->gm_pan > 85)
499 reg_val &= ~OPL3_VOICE_TO_LEFT;
500 opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
501 opl3->command(opl3, opl3_reg, reg_val);
502
503 if (instr_4op) {
504
505 reg_val = fm->feedback_connection[1] & OPL3_CONNECTION_BIT;
506
507 reg_val |= OPL3_STEREO_BITS;
508 if (chan->gm_pan < 43)
509 reg_val &= ~OPL3_VOICE_TO_RIGHT;
510 if (chan->gm_pan > 85)
511 reg_val &= ~OPL3_VOICE_TO_LEFT;
512 opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION +
513 voice_offset + 3);
514 opl3->command(opl3, opl3_reg, reg_val);
515 }
516
517
518
519
520
521
522 if (fm->fix_key)
523 note = fm->fix_key;
524
525
526
527 if (fm->trnsps)
528 note += (fm->trnsps - 64);
529
530 snd_opl3_calc_pitch(&fnum, &blocknum, note, chan);
531
532
533 opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
534 opl3->command(opl3, opl3_reg, fnum);
535
536 opl3->voices[voice].keyon_reg = blocknum;
537
538
539 blocknum |= OPL3_KEYON_BIT;
540
541 #ifdef DEBUG_MIDI
542 snd_printk(KERN_DEBUG " --> trigger voice %i\n", voice);
543 #endif
544
545 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
546 opl3->command(opl3, opl3_reg, blocknum);
547
548
549 if (fm->fix_dur) {
550 opl3->voices[voice].note_off = jiffies +
551 (fm->fix_dur * HZ) / 100;
552 snd_opl3_start_timer(opl3);
553 opl3->voices[voice].note_off_check = 1;
554 } else
555 opl3->voices[voice].note_off_check = 0;
556
557
558 extra_prg = (extra_prg) ? 0 : fm->modes;
559
560
561 vp->time = opl3->use_time++;
562 vp->note = key;
563 vp->chan = chan;
564
565 if (instr_4op) {
566 vp->state = SNDRV_OPL3_ST_ON_4OP;
567
568 vp2 = &opl3->voices[voice + 3];
569 vp2->time = opl3->use_time++;
570 vp2->note = key;
571 vp2->chan = chan;
572 vp2->state = SNDRV_OPL3_ST_NOT_AVAIL;
573 } else {
574 if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
575
576 vp2 = &opl3->voices[voice + 3];
577 vp2->time = opl3->use_time++;
578 vp2->state = SNDRV_OPL3_ST_OFF;
579 }
580 vp->state = SNDRV_OPL3_ST_ON_2OP;
581 }
582
583 #ifdef DEBUG_ALLOC
584 debug_alloc(opl3, "note on ", voice);
585 #endif
586
587
588 if (extra_prg) {
589 if (extra_prg > 128) {
590 bank = 128;
591
592 prg = extra_prg - 128 + 35 - 1;
593 } else {
594 bank = 0;
595 prg = extra_prg - 1;
596 }
597 #ifdef DEBUG_MIDI
598 snd_printk(KERN_DEBUG " *** allocating extra program\n");
599 #endif
600 goto __extra_prg;
601 }
602 spin_unlock_irqrestore(&opl3->voice_lock, flags);
603 }
604
605 static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
606 {
607 unsigned short reg_side;
608 unsigned char voice_offset;
609 unsigned short opl3_reg;
610
611 struct snd_opl3_voice *vp, *vp2;
612
613 if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
614 return;
615
616 vp = &opl3->voices[voice];
617 if (voice < MAX_OPL2_VOICES) {
618
619 reg_side = OPL3_LEFT;
620 voice_offset = voice;
621 } else {
622
623 reg_side = OPL3_RIGHT;
624 voice_offset = voice - MAX_OPL2_VOICES;
625 }
626
627
628 #ifdef DEBUG_MIDI
629 snd_printk(KERN_DEBUG " --> kill voice %i\n", voice);
630 #endif
631 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
632
633 opl3->command(opl3, opl3_reg, vp->keyon_reg);
634
635
636 vp->time = opl3->use_time++;
637
638 if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
639 vp2 = &opl3->voices[voice + 3];
640
641 vp2->time = opl3->use_time++;
642 vp2->state = SNDRV_OPL3_ST_OFF;
643 }
644 vp->state = SNDRV_OPL3_ST_OFF;
645 #ifdef DEBUG_ALLOC
646 debug_alloc(opl3, "note off", voice);
647 #endif
648
649 }
650
651
652
653
654 static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
655 struct snd_midi_channel *chan)
656 {
657 struct snd_opl3 *opl3;
658
659 int voice;
660 struct snd_opl3_voice *vp;
661
662 opl3 = p;
663
664 #ifdef DEBUG_MIDI
665 snd_printk(KERN_DEBUG "Note off, ch %i, inst %i, note %i\n",
666 chan->number, chan->midi_program, note);
667 #endif
668
669 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
670 if (chan->drum_channel && use_internal_drums) {
671 snd_opl3_drum_switch(opl3, note, vel, 0, chan);
672 return;
673 }
674
675
676 for (voice = 0; voice < opl3->max_voices; voice++) {
677 vp = &opl3->voices[voice];
678 if (vp->state > 0 && vp->chan == chan && vp->note == note) {
679 snd_opl3_kill_voice(opl3, voice);
680 }
681 }
682 } else {
683
684 if (chan->number < MAX_OPL3_VOICES) {
685 voice = snd_opl3_oss_map[chan->number];
686 snd_opl3_kill_voice(opl3, voice);
687 }
688 }
689 }
690
691 void snd_opl3_note_off(void *p, int note, int vel,
692 struct snd_midi_channel *chan)
693 {
694 struct snd_opl3 *opl3 = p;
695 unsigned long flags;
696
697 spin_lock_irqsave(&opl3->voice_lock, flags);
698 snd_opl3_note_off_unsafe(p, note, vel, chan);
699 spin_unlock_irqrestore(&opl3->voice_lock, flags);
700 }
701
702
703
704
705 void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
706 {
707 #ifdef DEBUG_MIDI
708 snd_printk(KERN_DEBUG "Key pressure, ch#: %i, inst#: %i\n",
709 chan->number, chan->midi_program);
710 #endif
711 }
712
713
714
715
716 void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan)
717 {
718 #ifdef DEBUG_MIDI
719 snd_printk(KERN_DEBUG "Terminate note, ch#: %i, inst#: %i\n",
720 chan->number, chan->midi_program);
721 #endif
722 }
723
724 static void snd_opl3_update_pitch(struct snd_opl3 *opl3, int voice)
725 {
726 unsigned short reg_side;
727 unsigned char voice_offset;
728 unsigned short opl3_reg;
729
730 unsigned char fnum, blocknum;
731
732 struct snd_opl3_voice *vp;
733
734 if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
735 return;
736
737 vp = &opl3->voices[voice];
738 if (vp->chan == NULL)
739 return;
740
741 if (voice < MAX_OPL2_VOICES) {
742
743 reg_side = OPL3_LEFT;
744 voice_offset = voice;
745 } else {
746
747 reg_side = OPL3_RIGHT;
748 voice_offset = voice - MAX_OPL2_VOICES;
749 }
750
751 snd_opl3_calc_pitch(&fnum, &blocknum, vp->note, vp->chan);
752
753
754 opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
755 opl3->command(opl3, opl3_reg, fnum);
756
757 vp->keyon_reg = blocknum;
758
759
760 blocknum |= OPL3_KEYON_BIT;
761
762
763 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
764 opl3->command(opl3, opl3_reg, blocknum);
765
766 vp->time = opl3->use_time++;
767 }
768
769
770
771
772 static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *chan)
773 {
774 int voice;
775 struct snd_opl3_voice *vp;
776
777 unsigned long flags;
778
779 spin_lock_irqsave(&opl3->voice_lock, flags);
780
781 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
782 for (voice = 0; voice < opl3->max_voices; voice++) {
783 vp = &opl3->voices[voice];
784 if (vp->state > 0 && vp->chan == chan) {
785 snd_opl3_update_pitch(opl3, voice);
786 }
787 }
788 } else {
789
790 if (chan->number < MAX_OPL3_VOICES) {
791 voice = snd_opl3_oss_map[chan->number];
792 snd_opl3_update_pitch(opl3, voice);
793 }
794 }
795 spin_unlock_irqrestore(&opl3->voice_lock, flags);
796 }
797
798
799
800
801
802 void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan)
803 {
804 struct snd_opl3 *opl3;
805
806 opl3 = p;
807 #ifdef DEBUG_MIDI
808 snd_printk(KERN_DEBUG "Controller, TYPE = %i, ch#: %i, inst#: %i\n",
809 type, chan->number, chan->midi_program);
810 #endif
811
812 switch (type) {
813 case MIDI_CTL_MSB_MODWHEEL:
814 if (chan->control[MIDI_CTL_MSB_MODWHEEL] > 63)
815 opl3->drum_reg |= OPL3_VIBRATO_DEPTH;
816 else
817 opl3->drum_reg &= ~OPL3_VIBRATO_DEPTH;
818 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
819 opl3->drum_reg);
820 break;
821 case MIDI_CTL_E2_TREMOLO_DEPTH:
822 if (chan->control[MIDI_CTL_E2_TREMOLO_DEPTH] > 63)
823 opl3->drum_reg |= OPL3_TREMOLO_DEPTH;
824 else
825 opl3->drum_reg &= ~OPL3_TREMOLO_DEPTH;
826 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
827 opl3->drum_reg);
828 break;
829 case MIDI_CTL_PITCHBEND:
830 snd_opl3_pitch_ctrl(opl3, chan);
831 break;
832 }
833 }
834
835
836
837
838 void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan,
839 struct snd_midi_channel_set *chset)
840 {
841 #ifdef DEBUG_MIDI
842 snd_printk(KERN_DEBUG "NRPN, ch#: %i, inst#: %i\n",
843 chan->number, chan->midi_program);
844 #endif
845 }
846
847
848
849
850 void snd_opl3_sysex(void *p, unsigned char *buf, int len,
851 int parsed, struct snd_midi_channel_set *chset)
852 {
853 #ifdef DEBUG_MIDI
854 snd_printk(KERN_DEBUG "SYSEX\n");
855 #endif
856 }