sound/drivers/opl3/opl3_midi.c
Source file repositories/reference/linux-study-clean/sound/drivers/opl3/opl3_midi.c
File Facts
- System
- Linux kernel
- Corpus path
sound/drivers/opl3/opl3_midi.c- Extension
.c- Size
- 21074 bytes
- Lines
- 824
- Domain
- Driver Families
- Bucket
- sound/drivers
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
opl3_voice.hsound/asoundef.h
Detected Declarations
struct bestfunction snd_opl3_calc_volumefunction snd_opl3_calc_pitchfunction debug_allocfunction voicefunction snd_opl3_timer_funcfunction scoped_guardfunction snd_opl3_start_timerfunction snd_opl3_note_onfunction snd_opl3_kill_voicefunction snd_opl3_note_off_unsafefunction snd_opl3_note_offfunction snd_opl3_key_pressfunction snd_opl3_terminate_notefunction snd_opl3_update_pitchfunction snd_opl3_pitch_ctrlfunction snd_opl3_controlfunction snd_opl3_nrpnfunction snd_opl3_sysex
Annotated Snippet
struct best {
unsigned int time;
int voice;
} best[END];
struct best *bp;
for (i = 0; i < END; i++) {
best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */
best[i].voice = -1;
}
/* Look through all the channels for the most suitable. */
for (i = 0; i < opl3->max_voices; i++) {
vp = &opl3->voices[i];
if (vp->state == SNDRV_OPL3_ST_NOT_AVAIL)
/* skip unavailable channels, allocated by
drum voices or by bounded 4op voices) */
continue;
voice_time = vp->time;
bp = best;
chan_4op_1 = ((i < 3) || (i > 8 && i < 12));
chan_4op_2 = ((i > 2 && i < 6) || (i > 11 && i < 15));
if (instr_4op) {
/* allocate 4op voice */
/* skip channels unavailable to 4op instrument */
if (!chan_4op_1)
continue;
if (vp->state)
/* kill one voice, CHEAP */
bp++;
/* get state of bounded 2op channel
to be allocated for 4op instrument */
vp2 = &opl3->voices[i + 3];
if (vp2->state == SNDRV_OPL3_ST_ON_2OP) {
/* kill two voices, EXPENSIVE */
bp++;
voice_time = max(voice_time, vp2->time);
}
} else {
/* allocate 2op voice */
if ((chan_4op_1) || (chan_4op_2))
/* use bounded channels for 2op, CHEAP */
bp++;
else if (vp->state)
/* kill one voice on 2op channel, CHEAP */
bp++;
/* raise kill cost to EXPENSIVE for all channels */
if (vp->state)
bp++;
}
if (voice_time < bp->time) {
bp->time = voice_time;
bp->voice = i;
}
}
for (i = 0; i < END; i++) {
if (best[i].voice >= 0) {
#ifdef DEBUG_ALLOC
dev_dbg(opl3->card->dev,
"%s %iop allocation on voice %i\n",
alloc_type[i], instr_4op ? 4 : 2,
best[i].voice);
#endif
return best[i].voice;
}
}
/* not found */
return -1;
}
/* ------------------------------ */
/*
* System timer interrupt function
*/
void snd_opl3_timer_func(struct timer_list *t)
{
struct snd_opl3 *opl3 = timer_container_of(opl3, t, tlist);
int again = 0;
int i;
scoped_guard(spinlock_irqsave, &opl3->voice_lock) {
for (i = 0; i < opl3->max_voices; i++) {
struct snd_opl3_voice *vp = &opl3->voices[i];
Annotation
- Immediate include surface: `opl3_voice.h`, `sound/asoundef.h`.
- Detected declarations: `struct best`, `function snd_opl3_calc_volume`, `function snd_opl3_calc_pitch`, `function debug_alloc`, `function voice`, `function snd_opl3_timer_func`, `function scoped_guard`, `function snd_opl3_start_timer`, `function snd_opl3_note_on`, `function snd_opl3_kill_voice`.
- Atlas domain: Driver Families / sound/drivers.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.