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 = (voice_time > vp->time) ? in opl3_get_voice()
184 voice_time : vp->time; in opl3_get_voice()
191 else if (vp->state) in opl3_get_voice()
195 if (vp->state) in opl3_get_voice()
198 if (voice_time < bp->time) { in opl3_get_voice()
199 bp->time = voice_time; in opl3_get_voice()
200 bp->voice = i; in opl3_get_voice()
215 return -1; in opl3_get_voice()
218 /* ------------------------------ */
231 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_timer_func()
232 for (i = 0; i < opl3->max_voices; i++) { in snd_opl3_timer_func()
233 struct snd_opl3_voice *vp = &opl3->voices[i]; in snd_opl3_timer_func() local
234 if (vp->state > 0 && vp->note_off_check) { in snd_opl3_timer_func()
235 if (vp->note_off == jiffies) in snd_opl3_timer_func()
236 snd_opl3_note_off_unsafe(opl3, vp->note, 0, in snd_opl3_timer_func()
237 vp->chan); in snd_opl3_timer_func()
242 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_timer_func()
244 spin_lock_irqsave(&opl3->sys_timer_lock, flags); in snd_opl3_timer_func()
246 mod_timer(&opl3->tlist, jiffies + 1); /* invoke again */ in snd_opl3_timer_func()
248 opl3->sys_timer_status = 0; in snd_opl3_timer_func()
249 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); in snd_opl3_timer_func()
258 spin_lock_irqsave(&opl3->sys_timer_lock, flags); in snd_opl3_start_timer()
259 if (! opl3->sys_timer_status) { in snd_opl3_start_timer()
260 mod_timer(&opl3->tlist, jiffies + 1); in snd_opl3_start_timer()
261 opl3->sys_timer_status = 1; in snd_opl3_start_timer()
263 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); in snd_opl3_start_timer()
266 /* ------------------------------ */
276 void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) in snd_opl3_note_on() argument
282 struct snd_opl3_voice *vp, *vp2; in snd_opl3_note_on() local
304 opl3 = p; in snd_opl3_note_on()
308 chan->number, chan->midi_program, note, vel); in snd_opl3_note_on()
313 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_note_on()
314 if (chan->drum_channel) { in snd_opl3_note_on()
319 bank = chan->gm_bank_select; in snd_opl3_note_on()
320 prg = chan->midi_program; in snd_opl3_note_on()
324 if (chan->number >= MAX_OPL3_VOICES) in snd_opl3_note_on()
329 prg = chan->midi_program; in snd_opl3_note_on()
332 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_note_on()
336 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
343 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
347 fm = &patch->inst; in snd_opl3_note_on()
348 switch (patch->type) { in snd_opl3_note_on()
353 if (opl3->hardware >= OPL3_HW_OPL3) { in snd_opl3_note_on()
359 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
363 snd_printk(KERN_DEBUG " --> OPL%i instrument: %s\n", in snd_opl3_note_on()
364 instr_4op ? 3 : 2, patch->name); in snd_opl3_note_on()
368 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_note_on()
372 voice = snd_opl3_oss_map[chan->number]; in snd_opl3_note_on()
376 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
388 voice_offset = voice - MAX_OPL2_VOICES; in snd_opl3_note_on()
393 vp = &opl3->voices[voice]; in snd_opl3_note_on()
394 if (vp->state > 0) { in snd_opl3_note_on()
396 reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT; in snd_opl3_note_on()
397 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
400 vp2 = &opl3->voices[voice + 3]; in snd_opl3_note_on()
401 if (vp2->state > 0) { in snd_opl3_note_on()
404 reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT; in snd_opl3_note_on()
405 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
411 if ((opl3->connection_reg ^ connect_mask) & connect_mask) { in snd_opl3_note_on()
412 opl3->connection_reg |= connect_mask; in snd_opl3_note_on()
415 opl3->command(opl3, opl3_reg, opl3->connection_reg); in snd_opl3_note_on()
418 if ((opl3->connection_reg ^ ~connect_mask) & connect_mask) { in snd_opl3_note_on()
419 opl3->connection_reg &= ~connect_mask; in snd_opl3_note_on()
422 opl3->command(opl3, opl3_reg, opl3->connection_reg); in snd_opl3_note_on()
427 snd_printk(KERN_DEBUG " --> setting OPL3 connection: 0x%x\n", in snd_opl3_note_on()
428 opl3->connection_reg); in snd_opl3_note_on()
435 vol_op[i] = fm->op[i].ksl_level; in snd_opl3_note_on()
437 connection = fm->feedback_connection[0] & 0x01; in snd_opl3_note_on()
440 connection |= fm->feedback_connection[1] & 0x01; in snd_opl3_note_on()
462 snd_printk(KERN_DEBUG " --> programming operator %i\n", i); in snd_opl3_note_on()
467 reg_val = fm->op[i].am_vib; in snd_opl3_note_on()
469 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
474 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
477 reg_val = fm->op[i].attack_decay; in snd_opl3_note_on()
479 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
482 reg_val = fm->op[i].sustain_release; in snd_opl3_note_on()
484 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
487 reg_val = fm->op[i].wave_select; in snd_opl3_note_on()
489 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
492 /* Set operator feedback and 2op inter-operator connection */ in snd_opl3_note_on()
493 reg_val = fm->feedback_connection[0]; in snd_opl3_note_on()
496 if (chan->gm_pan < 43) in snd_opl3_note_on()
498 if (chan->gm_pan > 85) in snd_opl3_note_on()
501 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
504 /* Set 4op inter-operator connection */ in snd_opl3_note_on()
505 reg_val = fm->feedback_connection[1] & OPL3_CONNECTION_BIT; in snd_opl3_note_on()
508 if (chan->gm_pan < 43) in snd_opl3_note_on()
510 if (chan->gm_pan > 85) in snd_opl3_note_on()
514 opl3->command(opl3, opl3_reg, reg_val); in snd_opl3_note_on()
522 if (fm->fix_key) in snd_opl3_note_on()
523 note = fm->fix_key; in snd_opl3_note_on()
527 if (fm->trnsps) in snd_opl3_note_on()
528 note += (fm->trnsps - 64); in snd_opl3_note_on()
534 opl3->command(opl3, opl3_reg, fnum); in snd_opl3_note_on()
536 opl3->voices[voice].keyon_reg = blocknum; in snd_opl3_note_on()
542 snd_printk(KERN_DEBUG " --> 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()
602 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_on()
611 struct snd_opl3_voice *vp, *vp2; in snd_opl3_kill_voice() local
616 vp = &opl3->voices[voice]; in snd_opl3_kill_voice()
624 voice_offset = voice - MAX_OPL2_VOICES; in snd_opl3_kill_voice()
629 snd_printk(KERN_DEBUG " --> kill voice %i\n", voice); in snd_opl3_kill_voice()
633 opl3->command(opl3, opl3_reg, vp->keyon_reg); in snd_opl3_kill_voice()
636 vp->time = opl3->use_time++; in snd_opl3_kill_voice()
638 if (vp->state == SNDRV_OPL3_ST_ON_4OP) { in snd_opl3_kill_voice()
639 vp2 = &opl3->voices[voice + 3]; in snd_opl3_kill_voice()
641 vp2->time = opl3->use_time++; in snd_opl3_kill_voice()
642 vp2->state = SNDRV_OPL3_ST_OFF; in snd_opl3_kill_voice()
644 vp->state = SNDRV_OPL3_ST_OFF; in snd_opl3_kill_voice()
654 static void snd_opl3_note_off_unsafe(void *p, int note, int vel, in snd_opl3_note_off_unsafe() argument
660 struct snd_opl3_voice *vp; in snd_opl3_note_off_unsafe() local
662 opl3 = p; in snd_opl3_note_off_unsafe()
666 chan->number, chan->midi_program, note); in snd_opl3_note_off_unsafe()
669 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_note_off_unsafe()
670 if (chan->drum_channel && use_internal_drums) { in snd_opl3_note_off_unsafe()
676 for (voice = 0; voice < opl3->max_voices; voice++) { in snd_opl3_note_off_unsafe()
677 vp = &opl3->voices[voice]; in snd_opl3_note_off_unsafe()
678 if (vp->state > 0 && vp->chan == chan && vp->note == note) { in snd_opl3_note_off_unsafe()
684 if (chan->number < MAX_OPL3_VOICES) { in snd_opl3_note_off_unsafe()
685 voice = snd_opl3_oss_map[chan->number]; in snd_opl3_note_off_unsafe()
691 void snd_opl3_note_off(void *p, int note, int vel, in snd_opl3_note_off() argument
694 struct snd_opl3 *opl3 = p; in snd_opl3_note_off()
697 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_note_off()
698 snd_opl3_note_off_unsafe(p, note, vel, chan); in snd_opl3_note_off()
699 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_note_off()
705 void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan) in snd_opl3_key_press() argument
709 chan->number, chan->midi_program); in snd_opl3_key_press()
716 void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan) in snd_opl3_terminate_note() argument
720 chan->number, chan->midi_program); in snd_opl3_terminate_note()
732 struct snd_opl3_voice *vp; in snd_opl3_update_pitch() local
737 vp = &opl3->voices[voice]; in snd_opl3_update_pitch()
738 if (vp->chan == NULL) in snd_opl3_update_pitch()
748 voice_offset = voice - MAX_OPL2_VOICES; in snd_opl3_update_pitch()
751 snd_opl3_calc_pitch(&fnum, &blocknum, vp->note, vp->chan); in snd_opl3_update_pitch()
755 opl3->command(opl3, opl3_reg, fnum); in snd_opl3_update_pitch()
757 vp->keyon_reg = blocknum; in snd_opl3_update_pitch()
764 opl3->command(opl3, opl3_reg, blocknum); in snd_opl3_update_pitch()
766 vp->time = opl3->use_time++; in snd_opl3_update_pitch()
775 struct snd_opl3_voice *vp; in snd_opl3_pitch_ctrl() local
779 spin_lock_irqsave(&opl3->voice_lock, flags); in snd_opl3_pitch_ctrl()
781 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { in snd_opl3_pitch_ctrl()
782 for (voice = 0; voice < opl3->max_voices; voice++) { in snd_opl3_pitch_ctrl()
783 vp = &opl3->voices[voice]; in snd_opl3_pitch_ctrl()
784 if (vp->state > 0 && vp->chan == chan) { in snd_opl3_pitch_ctrl()
790 if (chan->number < MAX_OPL3_VOICES) { in snd_opl3_pitch_ctrl()
791 voice = snd_opl3_oss_map[chan->number]; in snd_opl3_pitch_ctrl()
795 spin_unlock_irqrestore(&opl3->voice_lock, flags); in snd_opl3_pitch_ctrl()
802 void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan) in snd_opl3_control() argument
806 opl3 = p; in snd_opl3_control()
809 type, chan->number, chan->midi_program); in snd_opl3_control()
814 if (chan->control[MIDI_CTL_MSB_MODWHEEL] > 63) in snd_opl3_control()
815 opl3->drum_reg |= OPL3_VIBRATO_DEPTH; in snd_opl3_control()
817 opl3->drum_reg &= ~OPL3_VIBRATO_DEPTH; in snd_opl3_control()
818 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, in snd_opl3_control()
819 opl3->drum_reg); in snd_opl3_control()
822 if (chan->control[MIDI_CTL_E2_TREMOLO_DEPTH] > 63) in snd_opl3_control()
823 opl3->drum_reg |= OPL3_TREMOLO_DEPTH; in snd_opl3_control()
825 opl3->drum_reg &= ~OPL3_TREMOLO_DEPTH; in snd_opl3_control()
826 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, in snd_opl3_control()
827 opl3->drum_reg); in snd_opl3_control()
838 void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan, in snd_opl3_nrpn() argument
843 chan->number, chan->midi_program); in snd_opl3_nrpn()
850 void snd_opl3_sysex(void *p, unsigned char *buf, int len, in snd_opl3_sysex() argument