Lines Matching +full:vp +full:- +full:p
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) by Uros Bizjak <uros@kss-loka.si>
16 dev_dbg(((struct snd_opl3 *)(opl3))->card->dev, fmt, ##__VA_ARGS__)
21 static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
26 * for i=0. This log-table converts a linear volume-scaling (0..127) to a
27 * logarithmic scaling as present in the FM-synthesizer chips. so : Volume
28 * 64 = 0 db = relative volume 0 and: Volume 32 = -6 db = relative
29 * volume -8 it was implemented as a table because it is only 128 bytes and
35 -63, -48, -40, -35, -32, -29, -27, -26,
36 -24, -23, -21, -20, -19, -18, -18, -17,
37 -16, -15, -15, -14, -13, -13, -12, -12,
38 -11, -11, -10, -10, -10, -9, -9, -8,
39 -8, -8, -7, -7, -7, -6, -6, -6,
40 -5, -5, -5, -5, -4, -4, -4, -4,
41 -3, -3, -3, -3, -2, -2, -2, -2,
42 -2, -1, -1, -1, -1, 0, 0, 0,
59 volume = (vel * chan->gm_volume * chan->gm_expression) / (127*127); in snd_opl3_calc_volume()
63 oldvol = OPL3_TOTAL_LEVEL_MASK - (*volbyte & OPL3_TOTAL_LEVEL_MASK); in snd_opl3_calc_volume()
71 n = OPL3_TOTAL_LEVEL_MASK - (newvol & OPL3_TOTAL_LEVEL_MASK); in snd_opl3_calc_volume()
81 305, 323, /* for pitch bending, -2 semitones */
89 int block = ((note / 12) & 0x07) - 1; in snd_opl3_calc_pitch()
93 if (chan->midi_pitchbend) { in snd_opl3_calc_pitch()
94 int pitchbend = chan->midi_pitchbend; in snd_opl3_calc_pitch()
97 if (pitchbend < -0x2000) in snd_opl3_calc_pitch()
98 pitchbend = -0x2000; in snd_opl3_calc_pitch()
104 freq += ((opl3_note_table[idx+segment+1] - freq) * in snd_opl3_calc_pitch()
123 for (i = 0; i < opl3->max_voices; i++) in debug_alloc()
124 buf[i] = str[opl3->voices[i].state + 1]; in debug_alloc()
126 dev_dbg(opl3->card->dev, "time %.5i: %s [%.2i]: %s\n", in debug_alloc()
127 opl3->use_time, s, voice, buf); in debug_alloc()
139 struct snd_opl3_voice *vp, *vp2; in opl3_get_voice() local
160 best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */ in opl3_get_voice()
161 best[i].voice = -1; in opl3_get_voice()
165 for (i = 0; i < opl3->max_voices; i++) { in opl3_get_voice()
166 vp = &opl3->voices[i]; in opl3_get_voice()
168 if (vp->state == SNDRV_OPL3_ST_NOT_AVAIL) in opl3_get_voice()
173 voice_time = vp->time; in opl3_get_voice()
184 if (vp->state) in opl3_get_voice()
189 vp2 = &opl3->voices[i + 3]; in opl3_get_voice()
190 if (vp2->state == SNDRV_OPL3_ST_ON_2OP) { in opl3_get_voice()
193 voice_time = max(voice_time, vp2->time); in opl3_get_voice()
200 else if (vp->state) in opl3_get_voice()
204 if (vp->state) in opl3_get_voice()
207 if (voice_time < bp->time) { in opl3_get_voice()
208 bp->time = voice_time; in opl3_get_voice()
209 bp->voice = i; in opl3_get_voice()
216 dev_dbg(opl3->card->dev, in opl3_get_voice()
225 return -1; in opl3_get_voice()
228 /* ------------------------------ */
241 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_timer_func()
242 for (i = 0; i < opl3->max_voices; i++) { in snd_opl3_timer_func()
243 struct snd_opl3_voice *vp = &opl3->voices[i]; in snd_opl3_timer_func() local
244 if (vp->state > 0 && vp->note_off_check) { in snd_opl3_timer_func()
245 if (vp->note_off == jiffies) in snd_opl3_timer_func()
246 snd_opl3_note_off_unsafe(opl3, vp->note, 0, in snd_opl3_timer_func()
247 vp->chan); in snd_opl3_timer_func()
252 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_timer_func()
254 spin_lock_irqsave(&opl3->sys_timer_lock, flags); in snd_opl3_timer_func()
256 mod_timer(&opl3->tlist, jiffies + 1); /* invoke again */ in snd_opl3_timer_func()
258 opl3->sys_timer_status = 0; in snd_opl3_timer_func()
259 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); in snd_opl3_timer_func()
268 spin_lock_irqsave(&opl3->sys_timer_lock, flags); in snd_opl3_start_timer()
269 if (! opl3->sys_timer_status) { in snd_opl3_start_timer()
270 mod_timer(&opl3->tlist, jiffies + 1); in snd_opl3_start_timer()
271 opl3->sys_timer_status = 1; in snd_opl3_start_timer()
273 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); in snd_opl3_start_timer()
276 /* ------------------------------ */
286 void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) in snd_opl3_note_on() argument
292 struct snd_opl3_voice *vp, *vp2; in snd_opl3_note_on() local
314 opl3 = p; in snd_opl3_note_on()
317 chan->number, chan->midi_program, note, vel); in snd_opl3_note_on()
321 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_note_on()
322 if (chan->drum_channel) { in snd_opl3_note_on()
327 bank = chan->gm_bank_select; in snd_opl3_note_on()
328 prg = chan->midi_program; in snd_opl3_note_on()
332 if (chan->number >= MAX_OPL3_VOICES) in snd_opl3_note_on()
337 prg = chan->midi_program; in snd_opl3_note_on()
340 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_note_on()
344 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
351 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
355 fm = &patch->inst; in snd_opl3_note_on()
356 switch (patch->type) { in snd_opl3_note_on()
361 if (opl3->hardware >= OPL3_HW_OPL3) { in snd_opl3_note_on()
367 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
370 opl3_dbg(opl3, " --> OPL%i instrument: %s\n", in snd_opl3_note_on()
371 instr_4op ? 3 : 2, patch->name); in snd_opl3_note_on()
374 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_note_on()
378 voice = snd_opl3_oss_map[chan->number]; in snd_opl3_note_on()
382 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
394 voice_offset = voice - MAX_OPL2_VOICES; in snd_opl3_note_on()
399 vp = &opl3->voices[voice]; in snd_opl3_note_on()
400 if (vp->state > 0) { in snd_opl3_note_on()
402 reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT; in snd_opl3_note_on()
403 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
406 vp2 = &opl3->voices[voice + 3]; in snd_opl3_note_on()
407 if (vp2->state > 0) { in snd_opl3_note_on()
410 reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT; in snd_opl3_note_on()
411 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
417 if ((opl3->connection_reg ^ connect_mask) & connect_mask) { in snd_opl3_note_on()
418 opl3->connection_reg |= connect_mask; in snd_opl3_note_on()
421 opl3->command(opl3, opl3_reg, opl3->connection_reg); in snd_opl3_note_on()
424 if ((opl3->connection_reg ^ ~connect_mask) & connect_mask) { in snd_opl3_note_on()
425 opl3->connection_reg &= ~connect_mask; in snd_opl3_note_on()
428 opl3->command(opl3, opl3_reg, opl3->connection_reg); in snd_opl3_note_on()
432 opl3_dbg(opl3, " --> setting OPL3 connection: 0x%x\n", in snd_opl3_note_on()
433 opl3->connection_reg); in snd_opl3_note_on()
439 vol_op[i] = fm->op[i].ksl_level; in snd_opl3_note_on()
441 connection = fm->feedback_connection[0] & 0x01; in snd_opl3_note_on()
444 connection |= fm->feedback_connection[1] & 0x01; in snd_opl3_note_on()
465 opl3_dbg(opl3, " --> programming operator %i\n", i); in snd_opl3_note_on()
469 reg_val = fm->op[i].am_vib; in snd_opl3_note_on()
471 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
476 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
479 reg_val = fm->op[i].attack_decay; in snd_opl3_note_on()
481 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
484 reg_val = fm->op[i].sustain_release; in snd_opl3_note_on()
486 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
489 reg_val = fm->op[i].wave_select; in snd_opl3_note_on()
491 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
494 /* Set operator feedback and 2op inter-operator connection */ in snd_opl3_note_on()
495 reg_val = fm->feedback_connection[0]; in snd_opl3_note_on()
498 if (chan->gm_pan < 43) in snd_opl3_note_on()
500 if (chan->gm_pan > 85) in snd_opl3_note_on()
503 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
506 /* Set 4op inter-operator connection */ in snd_opl3_note_on()
507 reg_val = fm->feedback_connection[1] & OPL3_CONNECTION_BIT; in snd_opl3_note_on()
510 if (chan->gm_pan < 43) in snd_opl3_note_on()
512 if (chan->gm_pan > 85) in snd_opl3_note_on()
516 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
524 if (fm->fix_key) in snd_opl3_note_on()
525 note = fm->fix_key; in snd_opl3_note_on()
529 if (fm->trnsps) in snd_opl3_note_on()
530 note += (fm->trnsps - 64); in snd_opl3_note_on()
536 opl3->command(opl3, opl3_reg, fnum); in snd_opl3_note_on()
538 opl3->voices[voice].keyon_reg = blocknum; in snd_opl3_note_on()
543 opl3_dbg(opl3, " --> trigger voice %i\n", voice); in snd_opl3_note_on()
546 opl3->command(opl3, opl3_reg, blocknum); in snd_opl3_note_on()
549 if (fm->fix_dur) { in snd_opl3_note_on()
550 opl3->voices[voice].note_off = jiffies + in snd_opl3_note_on()
551 (fm->fix_dur * HZ) / 100; in snd_opl3_note_on()
553 opl3->voices[voice].note_off_check = 1; in snd_opl3_note_on()
555 opl3->voices[voice].note_off_check = 0; in snd_opl3_note_on()
558 extra_prg = (extra_prg) ? 0 : fm->modes; in snd_opl3_note_on()
561 vp->time = opl3->use_time++; in snd_opl3_note_on()
562 vp->note = key; in snd_opl3_note_on()
563 vp->chan = chan; in snd_opl3_note_on()
566 vp->state = SNDRV_OPL3_ST_ON_4OP; in snd_opl3_note_on()
568 vp2 = &opl3->voices[voice + 3]; in snd_opl3_note_on()
569 vp2->time = opl3->use_time++; in snd_opl3_note_on()
570 vp2->note = key; in snd_opl3_note_on()
571 vp2->chan = chan; in snd_opl3_note_on()
572 vp2->state = SNDRV_OPL3_ST_NOT_AVAIL; in snd_opl3_note_on()
574 if (vp->state == SNDRV_OPL3_ST_ON_4OP) { in snd_opl3_note_on()
576 vp2 = &opl3->voices[voice + 3]; in snd_opl3_note_on()
577 vp2->time = opl3->use_time++; in snd_opl3_note_on()
578 vp2->state = SNDRV_OPL3_ST_OFF; in snd_opl3_note_on()
580 vp->state = SNDRV_OPL3_ST_ON_2OP; in snd_opl3_note_on()
592 prg = extra_prg - 128 + 35 - 1; in snd_opl3_note_on()
595 prg = extra_prg - 1; in snd_opl3_note_on()
600 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
609 struct snd_opl3_voice *vp, *vp2; in snd_opl3_kill_voice() local
614 vp = &opl3->voices[voice]; in snd_opl3_kill_voice()
622 voice_offset = voice - MAX_OPL2_VOICES; in snd_opl3_kill_voice()
626 opl3_dbg(opl3, " --> kill voice %i\n", voice); in snd_opl3_kill_voice()
629 opl3->command(opl3, opl3_reg, vp->keyon_reg); in snd_opl3_kill_voice()
632 vp->time = opl3->use_time++; in snd_opl3_kill_voice()
634 if (vp->state == SNDRV_OPL3_ST_ON_4OP) { in snd_opl3_kill_voice()
635 vp2 = &opl3->voices[voice + 3]; in snd_opl3_kill_voice()
637 vp2->time = opl3->use_time++; in snd_opl3_kill_voice()
638 vp2->state = SNDRV_OPL3_ST_OFF; in snd_opl3_kill_voice()
640 vp->state = SNDRV_OPL3_ST_OFF; in snd_opl3_kill_voice()
650 static void snd_opl3_note_off_unsafe(void *p, int note, int vel, in snd_opl3_note_off_unsafe() argument
656 struct snd_opl3_voice *vp; in snd_opl3_note_off_unsafe() local
658 opl3 = p; in snd_opl3_note_off_unsafe()
661 chan->number, chan->midi_program, note); in snd_opl3_note_off_unsafe()
663 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_note_off_unsafe()
664 if (chan->drum_channel && use_internal_drums) { in snd_opl3_note_off_unsafe()
670 for (voice = 0; voice < opl3->max_voices; voice++) { in snd_opl3_note_off_unsafe()
671 vp = &opl3->voices[voice]; in snd_opl3_note_off_unsafe()
672 if (vp->state > 0 && vp->chan == chan && vp->note == note) { in snd_opl3_note_off_unsafe()
678 if (chan->number < MAX_OPL3_VOICES) { in snd_opl3_note_off_unsafe()
679 voice = snd_opl3_oss_map[chan->number]; in snd_opl3_note_off_unsafe()
685 void snd_opl3_note_off(void *p, int note, int vel, in snd_opl3_note_off() argument
688 struct snd_opl3 *opl3 = p; in snd_opl3_note_off()
691 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_note_off()
692 snd_opl3_note_off_unsafe(p, note, vel, chan); in snd_opl3_note_off()
693 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_off()
699 void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan) in snd_opl3_key_press() argument
701 opl3_dbg(p, "Key pressure, ch#: %i, inst#: %i\n", in snd_opl3_key_press()
702 chan->number, chan->midi_program); in snd_opl3_key_press()
708 void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan) in snd_opl3_terminate_note() argument
710 opl3_dbg(p, "Terminate note, ch#: %i, inst#: %i\n", in snd_opl3_terminate_note()
711 chan->number, chan->midi_program); in snd_opl3_terminate_note()
722 struct snd_opl3_voice *vp; in snd_opl3_update_pitch() local
727 vp = &opl3->voices[voice]; in snd_opl3_update_pitch()
728 if (vp->chan == NULL) in snd_opl3_update_pitch()
738 voice_offset = voice - MAX_OPL2_VOICES; in snd_opl3_update_pitch()
741 snd_opl3_calc_pitch(&fnum, &blocknum, vp->note, vp->chan); in snd_opl3_update_pitch()
745 opl3->command(opl3, opl3_reg, fnum); in snd_opl3_update_pitch()
747 vp->keyon_reg = blocknum; in snd_opl3_update_pitch()
754 opl3->command(opl3, opl3_reg, blocknum); in snd_opl3_update_pitch()
756 vp->time = opl3->use_time++; in snd_opl3_update_pitch()
765 struct snd_opl3_voice *vp; in snd_opl3_pitch_ctrl() local
769 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_pitch_ctrl()
771 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_pitch_ctrl()
772 for (voice = 0; voice < opl3->max_voices; voice++) { in snd_opl3_pitch_ctrl()
773 vp = &opl3->voices[voice]; in snd_opl3_pitch_ctrl()
774 if (vp->state > 0 && vp->chan == chan) { in snd_opl3_pitch_ctrl()
780 if (chan->number < MAX_OPL3_VOICES) { in snd_opl3_pitch_ctrl()
781 voice = snd_opl3_oss_map[chan->number]; in snd_opl3_pitch_ctrl()
785 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_pitch_ctrl()
792 void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan) in snd_opl3_control() argument
796 opl3 = p; in snd_opl3_control()
798 type, chan->number, chan->midi_program); in snd_opl3_control()
802 if (chan->control[MIDI_CTL_MSB_MODWHEEL] > 63) in snd_opl3_control()
803 opl3->drum_reg |= OPL3_VIBRATO_DEPTH; in snd_opl3_control()
805 opl3->drum_reg &= ~OPL3_VIBRATO_DEPTH; in snd_opl3_control()
806 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, in snd_opl3_control()
807 opl3->drum_reg); in snd_opl3_control()
810 if (chan->control[MIDI_CTL_E2_TREMOLO_DEPTH] > 63) in snd_opl3_control()
811 opl3->drum_reg |= OPL3_TREMOLO_DEPTH; in snd_opl3_control()
813 opl3->drum_reg &= ~OPL3_TREMOLO_DEPTH; in snd_opl3_control()
814 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, in snd_opl3_control()
815 opl3->drum_reg); in snd_opl3_control()
826 void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan, in snd_opl3_nrpn() argument
829 opl3_dbg(p, "NRPN, ch#: %i, inst#: %i\n", in snd_opl3_nrpn()
830 chan->number, chan->midi_program); in snd_opl3_nrpn()
836 void snd_opl3_sysex(void *p, unsigned char *buf, int len, in snd_opl3_sysex() argument
839 opl3_dbg(p, "SYSEX\n"); in snd_opl3_sysex()