32 static void snd_opl3_note_off_unsafe(
void *
p,
int note,
int vel,
44 static char opl3_volume_table[128] =
46 -63, -48, -40, -35, -32, -29, -27, -26,
47 -24, -23, -21, -20, -19, -18, -18, -17,
48 -16, -15, -15, -14, -13, -13, -12, -12,
49 -11, -11, -10, -10, -10, -9, -9, -8,
50 -8, -8, -7, -7, -7, -6, -6, -6,
51 -5, -5, -5, -5, -4, -4, -4, -4,
52 -3, -3, -3, -3, -2, -2, -2, -2,
53 -2, -1, -1, -1, -1, 0, 0, 0,
54 0, 0, 0, 1, 1, 1, 1, 1,
55 1, 2, 2, 2, 2, 2, 2, 2,
56 3, 3, 3, 3, 3, 3, 3, 4,
57 4, 4, 4, 4, 4, 4, 4, 5,
58 5, 5, 5, 5, 5, 5, 5, 5,
59 6, 6, 6, 6, 6, 6, 6, 6,
60 6, 7, 7, 7, 7, 7, 7, 7,
61 7, 7, 7, 8, 8, 8, 8, 8
67 int oldvol, newvol,
n;
70 volume = (vel * chan->gm_volume * chan->gm_expression) / (127*127);
76 newvol = opl3_volume_table[
volume] + oldvol;
90 static short opl3_note_table[16] =
93 343, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647,
97 static void snd_opl3_calc_pitch(
unsigned char *fnum,
unsigned char *blocknum,
100 int block = ((note / 12) & 0x07) - 1;
101 int idx = (note % 12) + 2;
108 if (pitchbend > 0x1FFF)
111 segment = pitchbend / 0x1000;
112 freq = opl3_note_table[idx+
segment];
113 freq += ((opl3_note_table[idx+segment+1] -
freq) *
114 (pitchbend % 0x1000)) / 0x1000;
116 freq = opl3_note_table[
idx];
119 *fnum = (
unsigned char) freq;
126 static void debug_alloc(
struct snd_opl3 *opl3,
char *
s,
int voice) {
132 printk(
"%c", *(str + opl3->voices[i].state + 1));
140 static int opl3_get_voice(
struct snd_opl3 *opl3,
int instr_4op,
146 unsigned int voice_time;
150 char *alloc_type[3] = {
"FREE ",
"CHEAP ",
"EXPENSIVE" };
155 FREE = 0, CHEAP, EXPENSIVE,
END
165 for (i = 0; i <
END; i++) {
166 best[
i].time = (
unsigned int)(-1);
172 vp = &opl3->voices[
i];
179 voice_time = vp->
time;
182 chan_4op_1 = ((i < 3) || (i > 8 && i < 12));
183 chan_4op_2 = ((i > 2 && i < 6) || (i > 11 && i < 15));
195 vp2 = &opl3->voices[i + 3];
199 voice_time = (voice_time > vp->
time) ?
200 voice_time : vp->
time;
204 if ((chan_4op_1) || (chan_4op_2))
214 if (voice_time < bp->
time) {
215 bp->time = voice_time;
220 for (i = 0; i <
END; i++) {
221 if (best[i].voice >= 0) {
224 alloc_type[i], instr_4op ? 4 : 2,
227 return best[
i].voice;
252 snd_opl3_note_off_unsafe(opl3, vp->
note, 0,
258 spin_unlock_irqrestore(&opl3->voice_lock, flags);
262 opl3->tlist.expires =
jiffies + 1;
265 opl3->sys_timer_status = 0;
267 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
273 static void snd_opl3_start_timer(
struct snd_opl3 *opl3)
277 if (! opl3->sys_timer_status) {
278 opl3->tlist.expires =
jiffies + 1;
280 opl3->sys_timer_status = 1;
282 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
289 0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17, 3, 4 ,5, 12, 13, 14
302 unsigned short connect_mask;
304 unsigned char vol_op[4];
308 unsigned short reg_side;
309 unsigned char op_offset;
310 unsigned char voice_offset;
311 unsigned short opl3_reg;
313 unsigned char prg, bank;
316 unsigned char fnum, blocknum;
332 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
338 bank = chan->gm_bank_select;
355 spin_unlock_irqrestore(&opl3->voice_lock, flags);
360 patch = snd_opl3_find_patch(opl3, prg, bank, 0);
362 spin_unlock_irqrestore(&opl3->voice_lock, flags);
367 switch (patch->
type) {
377 spin_unlock_irqrestore(&opl3->voice_lock, flags);
382 instr_4op ? 3 : 2, patch->
name);
386 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
387 voice = opl3_get_voice(opl3, instr_4op, chan);
390 voice = snd_opl3_oss_map[chan->
number];
396 voice_offset = voice;
406 vp = &opl3->voices[voice];
410 opl3->
command(opl3, opl3_reg, reg_val);
413 vp2 = &opl3->voices[voice + 3];
418 opl3->
command(opl3, opl3_reg, reg_val);
424 if ((opl3->connection_reg ^ connect_mask) & connect_mask) {
425 opl3->connection_reg |= connect_mask;
428 opl3->
command(opl3, opl3_reg, opl3->connection_reg);
431 if ((opl3->connection_reg ^ ~connect_mask) & connect_mask) {
432 opl3->connection_reg &= ~connect_mask;
435 opl3->
command(opl3, opl3_reg, opl3->connection_reg);
441 opl3->connection_reg);
447 for (i = 0; i < (instr_4op ? 4 : 2); i++)
448 vol_op[i] = fm->
op[i].ksl_level;
456 switch (connection) {
473 for (i = 0; i < (instr_4op ? 4 : 2); i++) {
480 reg_val = fm->
op[
i].am_vib;
482 opl3->
command(opl3, opl3_reg, reg_val);
487 opl3->
command(opl3, opl3_reg, reg_val);
490 reg_val = fm->
op[
i].attack_decay;
492 opl3->
command(opl3, opl3_reg, reg_val);
495 reg_val = fm->
op[
i].sustain_release;
497 opl3->
command(opl3, opl3_reg, reg_val);
500 reg_val = fm->
op[
i].wave_select;
502 opl3->
command(opl3, opl3_reg, reg_val);
509 if (chan->gm_pan < 43)
511 if (chan->gm_pan > 85)
514 opl3->
command(opl3, opl3_reg, reg_val);
521 if (chan->gm_pan < 43)
523 if (chan->gm_pan > 85)
527 opl3->
command(opl3, opl3_reg, reg_val);
541 note += (fm->
trnsps - 64);
543 snd_opl3_calc_pitch(&fnum, &blocknum, note, chan);
547 opl3->
command(opl3, opl3_reg, fnum);
549 opl3->voices[voice].keyon_reg = blocknum;
559 opl3->
command(opl3, opl3_reg, blocknum);
563 opl3->voices[voice].note_off =
jiffies +
565 snd_opl3_start_timer(opl3);
566 opl3->voices[voice].note_off_check = 1;
568 opl3->voices[voice].note_off_check = 0;
571 extra_prg = (extra_prg) ? 0 : fm->
modes;
574 vp->
time = opl3->use_time++;
581 vp2 = &opl3->voices[voice + 3];
582 vp2->
time = opl3->use_time++;
589 vp2 = &opl3->voices[voice + 3];
590 vp2->
time = opl3->use_time++;
597 debug_alloc(opl3,
"note on ", voice);
602 if (extra_prg > 128) {
605 prg = extra_prg - 128 + 35 - 1;
615 spin_unlock_irqrestore(&opl3->voice_lock, flags);
618 static void snd_opl3_kill_voice(
struct snd_opl3 *opl3,
int voice)
620 unsigned short reg_side;
621 unsigned char voice_offset;
622 unsigned short opl3_reg;
629 vp = &opl3->voices[voice];
633 voice_offset = voice;
649 vp->
time = opl3->use_time++;
652 vp2 = &opl3->voices[voice + 3];
654 vp2->
time = opl3->use_time++;
659 debug_alloc(opl3,
"note off", voice);
667 static void snd_opl3_note_off_unsafe(
void *
p,
int note,
int vel,
682 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
689 for (voice = 0; voice < opl3->
max_voices; voice++) {
690 vp = &opl3->voices[voice];
692 snd_opl3_kill_voice(opl3, voice);
698 voice = snd_opl3_oss_map[chan->
number];
699 snd_opl3_kill_voice(opl3, voice);
711 snd_opl3_note_off_unsafe(p, note, vel, chan);
712 spin_unlock_irqrestore(&opl3->voice_lock, flags);
743 static void snd_opl3_update_pitch(
struct snd_opl3 *opl3,
int voice)
745 unsigned short reg_side;
746 unsigned char voice_offset;
747 unsigned short opl3_reg;
749 unsigned char fnum, blocknum;
756 vp = &opl3->voices[voice];
763 voice_offset = voice;
770 snd_opl3_calc_pitch(&fnum, &blocknum, vp->
note, vp->
chan);
774 opl3->
command(opl3, opl3_reg, fnum);
783 opl3->
command(opl3, opl3_reg, blocknum);
785 vp->
time = opl3->use_time++;
800 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
801 for (voice = 0; voice < opl3->
max_voices; voice++) {
802 vp = &opl3->voices[voice];
804 snd_opl3_update_pitch(opl3, voice);
810 voice = snd_opl3_oss_map[chan->
number];
811 snd_opl3_update_pitch(opl3, voice);
814 spin_unlock_irqrestore(&opl3->voice_lock, flags);
849 snd_opl3_pitch_ctrl(opl3, chan);