sound/core/seq/seq_midi.c
Source file repositories/reference/linux-study-clean/sound/core/seq/seq_midi.c
File Facts
- System
- Linux kernel
- Corpus path
sound/core/seq/seq_midi.c- Extension
.c- Size
- 14003 bytes
- Lines
- 480
- Domain
- Driver Families
- Bucket
- sound/core
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/init.hlinux/slab.hlinux/errno.hlinux/string.hlinux/module.hlinux/mutex.hsound/core.hsound/rawmidi.hsound/seq_kernel.hsound/seq_device.hsound/seq_midi_event.hsound/initval.hseq_lock.h
Detected Declarations
struct seq_midisynthstruct seq_midisynth_clientfunction snd_midi_input_eventfunction dump_midifunction __dump_midifunction event_process_midifunction scoped_guardfunction snd_seq_midisynth_newfunction midisynth_subscribefunction midisynth_unsubscribefunction midisynth_usefunction midisynth_unusefunction scoped_guardfunction snd_seq_midisynth_deletefunction snd_seq_midisynth_probefunction snd_seq_midisynth_remove
Annotated Snippet
struct seq_midisynth {
struct snd_card *card;
struct snd_rawmidi *rmidi;
int device;
int subdevice;
struct snd_rawmidi_file input_rfile;
spinlock_t output_lock; /* protects output_rfile publication */
snd_use_lock_t output_use_lock; /* in-flight event_input users */
struct snd_rawmidi_file output_rfile;
int seq_client;
int seq_port;
struct snd_midi_event *parser;
};
struct seq_midisynth_client {
int seq_client;
int num_ports;
int ports_per_device[SNDRV_RAWMIDI_DEVICES];
struct seq_midisynth *ports[SNDRV_RAWMIDI_DEVICES];
};
static struct seq_midisynth_client *synths[SNDRV_CARDS];
static DEFINE_MUTEX(register_mutex);
/* handle rawmidi input event (MIDI v1.0 stream) */
static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
{
struct snd_rawmidi_runtime *runtime;
struct seq_midisynth *msynth;
struct snd_seq_event ev;
char buf[16], *pbuf;
long res;
if (substream == NULL)
return;
runtime = substream->runtime;
msynth = runtime->private_data;
if (msynth == NULL)
return;
memset(&ev, 0, sizeof(ev));
while (runtime->avail > 0) {
res = snd_rawmidi_kernel_read(substream, buf, sizeof(buf));
if (res <= 0)
continue;
if (msynth->parser == NULL)
continue;
pbuf = buf;
while (res-- > 0) {
if (!snd_midi_event_encode_byte(msynth->parser,
*pbuf++, &ev))
continue;
ev.source.port = msynth->seq_port;
ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
snd_seq_kernel_client_dispatch(msynth->seq_client, &ev, 1, 0);
/* clear event and reset header */
memset(&ev, 0, sizeof(ev));
}
}
}
static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, int count)
{
struct snd_rawmidi_runtime *runtime;
int tmp;
if (snd_BUG_ON(!substream || !buf))
return -EINVAL;
runtime = substream->runtime;
tmp = runtime->avail;
if (tmp < count) {
if (printk_ratelimit())
pr_err("ALSA: seq_midi: MIDI output buffer overrun\n");
return -ENOMEM;
}
if (snd_rawmidi_kernel_write(substream, buf, count) < count)
return -EINVAL;
return 0;
}
/* callback for snd_seq_dump_var_event(), bridging to dump_midi() */
static int __dump_midi(void *ptr, void *buf, int count)
{
return dump_midi(ptr, buf, count);
}
static int event_process_midi(struct snd_seq_event *ev, int direct,
void *private_data, int atomic, int hop)
{
struct seq_midisynth *msynth = private_data;
unsigned char msg[10]; /* buffer for constructing midi messages */
Annotation
- Immediate include surface: `linux/init.h`, `linux/slab.h`, `linux/errno.h`, `linux/string.h`, `linux/module.h`, `linux/mutex.h`, `sound/core.h`, `sound/rawmidi.h`.
- Detected declarations: `struct seq_midisynth`, `struct seq_midisynth_client`, `function snd_midi_input_event`, `function dump_midi`, `function __dump_midi`, `function event_process_midi`, `function scoped_guard`, `function snd_seq_midisynth_new`, `function midisynth_subscribe`, `function midisynth_unsubscribe`.
- Atlas domain: Driver Families / sound/core.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.