sound/synth/emux/emux_synth.c
Source file repositories/reference/linux-study-clean/sound/synth/emux/emux_synth.c
File Facts
- System
- Linux kernel
- Corpus path
sound/synth/emux/emux_synth.c- Extension
.c- Size
- 24437 bytes
- Lines
- 942
- Domain
- Driver Families
- Bucket
- sound/synth
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hemux_voice.hsound/asoundef.h
Detected Declarations
function snd_emux_note_onfunction snd_emux_note_offfunction snd_emux_timer_callbackfunction snd_emux_key_pressfunction snd_emux_update_channelfunction snd_emux_update_portfunction snd_emux_controlfunction terminate_note1function snd_emux_terminate_notefunction snd_emux_terminate_allfunction snd_emux_sounds_off_allfunction exclusive_note_offfunction terminate_voicefunction update_voicefunction setup_voicefunction calc_panfunction volumefunction calc_pitchfunction get_bankfunction get_zonefunction snd_emux_init_voicesfunction snd_emux_lock_voicefunction snd_emux_unlock_voiceexport snd_emux_terminate_allexport snd_emux_lock_voiceexport snd_emux_unlock_voice
Annotated Snippet
if (emu->ops.prepare) {
vp->state = SNDRV_EMUX_ST_OFF;
if (emu->ops.prepare(vp) >= 0)
vp->state = SNDRV_EMUX_ST_STANDBY;
}
}
/* start envelope now */
for (i = 0; i < emu->max_voices; i++) {
vp = &emu->voices[i];
if (vp->state == SNDRV_EMUX_ST_STANDBY &&
vp->chan == chan) {
emu->ops.trigger(vp);
vp->state = SNDRV_EMUX_ST_ON;
vp->ontime = jiffies; /* remember the trigger timing */
}
}
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
/* clear voice position for the next note on this channel */
struct snd_emux_effect_table *fx = chan->private;
if (fx) {
fx->flag[EMUX_FX_SAMPLE_START] = 0;
fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
}
}
#endif
}
/*
* Release a note in response to a midi note off.
*/
void
snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
{
int ch;
struct snd_emux *emu;
struct snd_emux_voice *vp;
struct snd_emux_port *port;
port = p;
if (snd_BUG_ON(!port || !chan))
return;
emu = port->emu;
if (snd_BUG_ON(!emu || !emu->ops.release))
return;
guard(spinlock_irqsave)(&emu->voice_lock);
for (ch = 0; ch < emu->max_voices; ch++) {
vp = &emu->voices[ch];
if (STATE_IS_PLAYING(vp->state) &&
vp->chan == chan && vp->key == note) {
vp->state = SNDRV_EMUX_ST_RELEASED;
if (vp->ontime == jiffies) {
/* if note-off is sent too shortly after
* note-on, emuX engine cannot produce the sound
* correctly. so we'll release this note
* a bit later via timer callback.
*/
vp->state = SNDRV_EMUX_ST_PENDING;
if (! emu->timer_active) {
mod_timer(&emu->tlist, jiffies + 1);
emu->timer_active = 1;
}
} else
/* ok now release the note */
emu->ops.release(vp);
}
}
}
/*
* timer callback
*
* release the pending note-offs
*/
void snd_emux_timer_callback(struct timer_list *t)
{
struct snd_emux *emu = timer_container_of(emu, t, tlist);
struct snd_emux_voice *vp;
int ch, do_again = 0;
guard(spinlock_irqsave)(&emu->voice_lock);
for (ch = 0; ch < emu->max_voices; ch++) {
vp = &emu->voices[ch];
if (vp->state == SNDRV_EMUX_ST_PENDING) {
if (vp->ontime == jiffies)
do_again++; /* release this at the next interrupt */
Annotation
- Immediate include surface: `linux/export.h`, `emux_voice.h`, `sound/asoundef.h`.
- Detected declarations: `function snd_emux_note_on`, `function snd_emux_note_off`, `function snd_emux_timer_callback`, `function snd_emux_key_press`, `function snd_emux_update_channel`, `function snd_emux_update_port`, `function snd_emux_control`, `function terminate_note1`, `function snd_emux_terminate_note`, `function snd_emux_terminate_all`.
- Atlas domain: Driver Families / sound/synth.
- Implementation status: integration 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.