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>
14 static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
19 * for i=0. This log-table converts a linear volume-scaling (0..127) to a
20 * logarithmic scaling as present in the FM-synthesizer chips. so : Volume
21 * 64 = 0 db = relative volume 0 and: Volume 32 = -6 db = relative
22 * volume -8 it was implemented as a table because it is only 128 bytes and
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,
52 volume = (vel * chan->gm_volume * chan->gm_expression) / (127*127); in snd_opl3_calc_volume()
56 oldvol = OPL3_TOTAL_LEVEL_MASK - (*volbyte & OPL3_TOTAL_LEVEL_MASK); in snd_opl3_calc_volume()
64 n = OPL3_TOTAL_LEVEL_MASK - (newvol & OPL3_TOTAL_LEVEL_MASK); in snd_opl3_calc_volume()
74 305, 323, /* for pitch bending, -2 semitones */
82 int block = ((note / 12) & 0x07) - 1; in snd_opl3_calc_pitch()
86 if (chan->midi_pitchbend) { in snd_opl3_calc_pitch()
87 int pitchbend = chan->midi_pitchbend; in snd_opl3_calc_pitch()
90 if (pitchbend < -0x2000) in snd_opl3_calc_pitch()
91 pitchbend = -0x2000; in snd_opl3_calc_pitch()
97 freq += ((opl3_note_table[idx+segment+1] - freq) * in snd_opl3_calc_pitch()
114 printk(KERN_DEBUG "time %.5i: %s [%.2i]: ", opl3->use_time, s, voice); in debug_alloc()
115 for (i = 0; i < opl3->max_voices; i++) in debug_alloc()
116 printk(KERN_CONT "%c", *(str + opl3->voices[i].state + 1)); in debug_alloc()
129 struct snd_opl3_voice *vp, *vp2; in opl3_get_voice() local
150 best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */ in opl3_get_voice()
151 best[i].voice = -1; in opl3_get_voice()
155 for (i = 0; i < opl3->max_voices; i++) { in opl3_get_voice()
156 vp = &opl3->voices[i]; in opl3_get_voice()
158 if (vp->state == SNDRV_OPL3_ST_NOT_AVAIL) in opl3_get_voice()
163 voice_time = vp->time; in opl3_get_voice()
174 if (vp->state) in opl3_get_voice()
179 vp2 = &opl3->voices[i + 3]; in opl3_get_voice()
180 if (vp2->state == SNDRV_OPL3_ST_ON_2OP) { in opl3_get_voice()
183 voice_time = max(voice_time, vp2->time); in opl3_get_voice()
190 else if (vp->state) in opl3_get_voice()
194 if (vp->state) in opl3_get_voice()
197 if (voice_time < bp->time) { in opl3_get_voice()
198 bp->time = voice_time; in opl3_get_voice()
199 bp->voice = i; in opl3_get_voice()
214 return -1; in opl3_get_voice()
217 /* ------------------------------ */
230 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_timer_func()
231 for (i = 0; i < opl3->max_voices; i++) { in snd_opl3_timer_func()
232 struct snd_opl3_voice *vp = &opl3->voices[i]; in snd_opl3_timer_func() local
233 if (vp->state > 0 && vp->note_off_check) { in snd_opl3_timer_func()
234 if (vp->note_off == jiffies) in snd_opl3_timer_func()
235 snd_opl3_note_off_unsafe(opl3, vp->note, 0, in snd_opl3_timer_func()
236 vp->chan); in snd_opl3_timer_func()
241 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_timer_func()
243 spin_lock_irqsave(&opl3->sys_timer_lock, flags); in snd_opl3_timer_func()
245 mod_timer(&opl3->tlist, jiffies + 1); /* invoke again */ in snd_opl3_timer_func()
247 opl3->sys_timer_status = 0; in snd_opl3_timer_func()
248 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); in snd_opl3_timer_func()
257 spin_lock_irqsave(&opl3->sys_timer_lock, flags); in snd_opl3_start_timer()
258 if (! opl3->sys_timer_status) { in snd_opl3_start_timer()
259 mod_timer(&opl3->tlist, jiffies + 1); in snd_opl3_start_timer()
260 opl3->sys_timer_status = 1; in snd_opl3_start_timer()
262 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); in snd_opl3_start_timer()
265 /* ------------------------------ */
275 void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) in snd_opl3_note_on() argument
281 struct snd_opl3_voice *vp, *vp2; in snd_opl3_note_on() local
303 opl3 = p; in snd_opl3_note_on()
307 chan->number, chan->midi_program, note, vel); in snd_opl3_note_on()
312 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_note_on()
313 if (chan->drum_channel) { in snd_opl3_note_on()
318 bank = chan->gm_bank_select; in snd_opl3_note_on()
319 prg = chan->midi_program; in snd_opl3_note_on()
323 if (chan->number >= MAX_OPL3_VOICES) in snd_opl3_note_on()
328 prg = chan->midi_program; in snd_opl3_note_on()
331 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_note_on()
335 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
342 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
346 fm = &patch->inst; in snd_opl3_note_on()
347 switch (patch->type) { in snd_opl3_note_on()
352 if (opl3->hardware >= OPL3_HW_OPL3) { in snd_opl3_note_on()
358 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
362 snd_printk(KERN_DEBUG " --> OPL%i instrument: %s\n", in snd_opl3_note_on()
363 instr_4op ? 3 : 2, patch->name); in snd_opl3_note_on()
367 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_note_on()
371 voice = snd_opl3_oss_map[chan->number]; in snd_opl3_note_on()
375 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
387 voice_offset = voice - MAX_OPL2_VOICES; in snd_opl3_note_on()
392 vp = &opl3->voices[voice]; in snd_opl3_note_on()
393 if (vp->state > 0) { in snd_opl3_note_on()
395 reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT; in snd_opl3_note_on()
396 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
399 vp2 = &opl3->voices[voice + 3]; in snd_opl3_note_on()
400 if (vp2->state > 0) { in snd_opl3_note_on()
403 reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT; in snd_opl3_note_on()
404 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
410 if ((opl3->connection_reg ^ connect_mask) & connect_mask) { in snd_opl3_note_on()
411 opl3->connection_reg |= connect_mask; in snd_opl3_note_on()
414 opl3->command(opl3, opl3_reg, opl3->connection_reg); 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()
426 snd_printk(KERN_DEBUG " --> setting OPL3 connection: 0x%x\n", in snd_opl3_note_on()
427 opl3->connection_reg); in snd_opl3_note_on()
434 vol_op[i] = fm->op[i].ksl_level; in snd_opl3_note_on()
436 connection = fm->feedback_connection[0] & 0x01; in snd_opl3_note_on()
439 connection |= fm->feedback_connection[1] & 0x01; in snd_opl3_note_on()
461 snd_printk(KERN_DEBUG " --> programming operator %i\n", i); in snd_opl3_note_on()
466 reg_val = fm->op[i].am_vib; in snd_opl3_note_on()
468 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
473 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
476 reg_val = fm->op[i].attack_decay; in snd_opl3_note_on()
478 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
481 reg_val = fm->op[i].sustain_release; in snd_opl3_note_on()
483 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
486 reg_val = fm->op[i].wave_select; in snd_opl3_note_on()
488 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
491 /* Set operator feedback and 2op inter-operator connection */ in snd_opl3_note_on()
492 reg_val = fm->feedback_connection[0]; in snd_opl3_note_on()
495 if (chan->gm_pan < 43) in snd_opl3_note_on()
497 if (chan->gm_pan > 85) in snd_opl3_note_on()
500 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
503 /* Set 4op inter-operator connection */ in snd_opl3_note_on()
504 reg_val = fm->feedback_connection[1] & OPL3_CONNECTION_BIT; in snd_opl3_note_on()
507 if (chan->gm_pan < 43) in snd_opl3_note_on()
509 if (chan->gm_pan > 85) in snd_opl3_note_on()
513 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
521 if (fm->fix_key) in snd_opl3_note_on()
522 note = fm->fix_key; in snd_opl3_note_on()
526 if (fm->trnsps) in snd_opl3_note_on()
527 note += (fm->trnsps - 64); in snd_opl3_note_on()
533 opl3->command(opl3, opl3_reg, fnum); in snd_opl3_note_on()
535 opl3->voices[voice].keyon_reg = blocknum; in snd_opl3_note_on()
541 snd_printk(KERN_DEBUG " --> trigger voice %i\n", voice); in snd_opl3_note_on()
545 opl3->command(opl3, opl3_reg, blocknum); in snd_opl3_note_on()
548 if (fm->fix_dur) { in snd_opl3_note_on()
549 opl3->voices[voice].note_off = jiffies + in snd_opl3_note_on()
550 (fm->fix_dur * HZ) / 100; in snd_opl3_note_on()
552 opl3->voices[voice].note_off_check = 1; in snd_opl3_note_on()
554 opl3->voices[voice].note_off_check = 0; in snd_opl3_note_on()
557 extra_prg = (extra_prg) ? 0 : fm->modes; in snd_opl3_note_on()
560 vp->time = opl3->use_time++; in snd_opl3_note_on()
561 vp->note = key; in snd_opl3_note_on()
562 vp->chan = chan; in snd_opl3_note_on()
565 vp->state = SNDRV_OPL3_ST_ON_4OP; in snd_opl3_note_on()
567 vp2 = &opl3->voices[voice + 3]; in snd_opl3_note_on()
568 vp2->time = opl3->use_time++; in snd_opl3_note_on()
569 vp2->note = key; in snd_opl3_note_on()
570 vp2->chan = chan; in snd_opl3_note_on()
571 vp2->state = SNDRV_OPL3_ST_NOT_AVAIL; in snd_opl3_note_on()
573 if (vp->state == SNDRV_OPL3_ST_ON_4OP) { in snd_opl3_note_on()
575 vp2 = &opl3->voices[voice + 3]; in snd_opl3_note_on()
576 vp2->time = opl3->use_time++; in snd_opl3_note_on()
577 vp2->state = SNDRV_OPL3_ST_OFF; in snd_opl3_note_on()
579 vp->state = SNDRV_OPL3_ST_ON_2OP; in snd_opl3_note_on()
591 prg = extra_prg - 128 + 35 - 1; in snd_opl3_note_on()
594 prg = extra_prg - 1; in snd_opl3_note_on()
601 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
610 struct snd_opl3_voice *vp, *vp2; in snd_opl3_kill_voice() local
615 vp = &opl3->voices[voice]; in snd_opl3_kill_voice()
623 voice_offset = voice - MAX_OPL2_VOICES; in snd_opl3_kill_voice()
628 snd_printk(KERN_DEBUG " --> kill voice %i\n", voice); in snd_opl3_kill_voice()
632 opl3->command(opl3, opl3_reg, vp->keyon_reg); in snd_opl3_kill_voice()
635 vp->time = opl3->use_time++; in snd_opl3_kill_voice()
637 if (vp->state == SNDRV_OPL3_ST_ON_4OP) { in snd_opl3_kill_voice()
638 vp2 = &opl3->voices[voice + 3]; in snd_opl3_kill_voice()
640 vp2->time = opl3->use_time++; in snd_opl3_kill_voice()
641 vp2->state = SNDRV_OPL3_ST_OFF; in snd_opl3_kill_voice()
643 vp->state = SNDRV_OPL3_ST_OFF; in snd_opl3_kill_voice()
653 static void snd_opl3_note_off_unsafe(void *p, int note, int vel, in snd_opl3_note_off_unsafe() argument
659 struct snd_opl3_voice *vp; in snd_opl3_note_off_unsafe() local
661 opl3 = p; in snd_opl3_note_off_unsafe()
665 chan->number, chan->midi_program, note); in snd_opl3_note_off_unsafe()
668 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_note_off_unsafe()
669 if (chan->drum_channel && use_internal_drums) { in snd_opl3_note_off_unsafe()
675 for (voice = 0; voice < opl3->max_voices; voice++) { in snd_opl3_note_off_unsafe()
676 vp = &opl3->voices[voice]; in snd_opl3_note_off_unsafe()
677 if (vp->state > 0 && vp->chan == chan && vp->note == note) { in snd_opl3_note_off_unsafe()
683 if (chan->number < MAX_OPL3_VOICES) { in snd_opl3_note_off_unsafe()
684 voice = snd_opl3_oss_map[chan->number]; in snd_opl3_note_off_unsafe()
690 void snd_opl3_note_off(void *p, int note, int vel, in snd_opl3_note_off() argument
693 struct snd_opl3 *opl3 = p; in snd_opl3_note_off()
696 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_note_off()
697 snd_opl3_note_off_unsafe(p, note, vel, chan); in snd_opl3_note_off()
698 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_off()
704 void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan) in snd_opl3_key_press() argument
708 chan->number, chan->midi_program); in snd_opl3_key_press()
715 void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan) in snd_opl3_terminate_note() argument
719 chan->number, chan->midi_program); in snd_opl3_terminate_note()
731 struct snd_opl3_voice *vp; in snd_opl3_update_pitch() local
736 vp = &opl3->voices[voice]; in snd_opl3_update_pitch()
737 if (vp->chan == NULL) in snd_opl3_update_pitch()
747 voice_offset = voice - MAX_OPL2_VOICES; in snd_opl3_update_pitch()
750 snd_opl3_calc_pitch(&fnum, &blocknum, vp->note, vp->chan); in snd_opl3_update_pitch()
754 opl3->command(opl3, opl3_reg, fnum); in snd_opl3_update_pitch()
756 vp->keyon_reg = blocknum; in snd_opl3_update_pitch()
763 opl3->command(opl3, opl3_reg, blocknum); in snd_opl3_update_pitch()
765 vp->time = opl3->use_time++; in snd_opl3_update_pitch()
774 struct snd_opl3_voice *vp; in snd_opl3_pitch_ctrl() local
778 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_pitch_ctrl()
780 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_pitch_ctrl()
781 for (voice = 0; voice < opl3->max_voices; voice++) { in snd_opl3_pitch_ctrl()
782 vp = &opl3->voices[voice]; in snd_opl3_pitch_ctrl()
783 if (vp->state > 0 && vp->chan == chan) { in snd_opl3_pitch_ctrl()
789 if (chan->number < MAX_OPL3_VOICES) { in snd_opl3_pitch_ctrl()
790 voice = snd_opl3_oss_map[chan->number]; in snd_opl3_pitch_ctrl()
794 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_pitch_ctrl()
801 void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan) in snd_opl3_control() argument
805 opl3 = p; in snd_opl3_control()
808 type, chan->number, chan->midi_program); in snd_opl3_control()
813 if (chan->control[MIDI_CTL_MSB_MODWHEEL] > 63) in snd_opl3_control()
814 opl3->drum_reg |= OPL3_VIBRATO_DEPTH; in snd_opl3_control()
816 opl3->drum_reg &= ~OPL3_VIBRATO_DEPTH; in snd_opl3_control()
817 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, in snd_opl3_control()
818 opl3->drum_reg); in snd_opl3_control()
821 if (chan->control[MIDI_CTL_E2_TREMOLO_DEPTH] > 63) in snd_opl3_control()
822 opl3->drum_reg |= OPL3_TREMOLO_DEPTH; in snd_opl3_control()
824 opl3->drum_reg &= ~OPL3_TREMOLO_DEPTH; in snd_opl3_control()
825 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, in snd_opl3_control()
826 opl3->drum_reg); in snd_opl3_control()
837 void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan, in snd_opl3_nrpn() argument
842 chan->number, chan->midi_program); in snd_opl3_nrpn()
849 void snd_opl3_sysex(void *p, unsigned char *buf, int len, in snd_opl3_sysex() argument