sound/core/seq/seq_ump_convert.c

Source file repositories/reference/linux-study-clean/sound/core/seq/seq_ump_convert.c

File Facts

System
Linux kernel
Corpus path
sound/core/seq/seq_ump_convert.c
Extension
.c
Size
39978 bytes
Lines
1313
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct seq_ump_midi1_to_ev {
	int seq_type;
	void (*encode)(const union snd_ump_midi1_msg *val, struct snd_seq_event *ev);
};

/* Encoders for MIDI1 status 0x80-0xe0 */
static struct seq_ump_midi1_to_ev midi1_msg_encoders[] = {
	{SNDRV_SEQ_EVENT_NOTEOFF,	ump_midi1_to_note_ev},	/* 0x80 */
	{SNDRV_SEQ_EVENT_NOTEON,	ump_midi1_to_note_ev},	/* 0x90 */
	{SNDRV_SEQ_EVENT_KEYPRESS,	ump_midi1_to_note_ev},	/* 0xa0 */
	{SNDRV_SEQ_EVENT_CONTROLLER,	ump_midi1_to_cc_ev},	/* 0xb0 */
	{SNDRV_SEQ_EVENT_PGMCHANGE,	ump_midi1_to_ctrl_ev},	/* 0xc0 */
	{SNDRV_SEQ_EVENT_CHANPRESS,	ump_midi1_to_ctrl_ev},	/* 0xd0 */
	{SNDRV_SEQ_EVENT_PITCHBEND,	ump_midi1_to_pitchbend_ev}, /* 0xe0 */
};

static int cvt_ump_midi1_to_event(const union snd_ump_midi1_msg *val,
				  struct snd_seq_event *ev)
{
	unsigned char status = val->note.status;

	if (status < 0x8 || status > 0xe)
		return 0; /* invalid - skip */
	status -= 8;
	ev->type = midi1_msg_encoders[status].seq_type;
	ev->flags = SNDRV_SEQ_EVENT_LENGTH_FIXED;
	midi1_msg_encoders[status].encode(val, ev);
	return 1;
}

/* MIDI System message */

/* encode one parameter value*/
static void ump_system_to_one_param_ev(const union snd_ump_midi1_msg *val,
				       struct snd_seq_event *ev)
{
	ev->data.control.value = val->system.parm1;
}

/* encode song position */
static void ump_system_to_songpos_ev(const union snd_ump_midi1_msg *val,
				     struct snd_seq_event *ev)
{
	ev->data.control.value = (val->system.parm2 << 7) | val->system.parm1;
}

/* Encoders for 0xf0 - 0xff */
static struct seq_ump_midi1_to_ev system_msg_encoders[] = {
	{SNDRV_SEQ_EVENT_NONE,		NULL},	 /* 0xf0 */
	{SNDRV_SEQ_EVENT_QFRAME,	ump_system_to_one_param_ev}, /* 0xf1 */
	{SNDRV_SEQ_EVENT_SONGPOS,	ump_system_to_songpos_ev}, /* 0xf2 */
	{SNDRV_SEQ_EVENT_SONGSEL,	ump_system_to_one_param_ev}, /* 0xf3 */
	{SNDRV_SEQ_EVENT_NONE,		NULL}, /* 0xf4 */
	{SNDRV_SEQ_EVENT_NONE,		NULL}, /* 0xf5 */
	{SNDRV_SEQ_EVENT_TUNE_REQUEST,	NULL}, /* 0xf6 */
	{SNDRV_SEQ_EVENT_NONE,		NULL}, /* 0xf7 */
	{SNDRV_SEQ_EVENT_CLOCK,		NULL}, /* 0xf8 */
	{SNDRV_SEQ_EVENT_NONE,		NULL}, /* 0xf9 */
	{SNDRV_SEQ_EVENT_START,		NULL}, /* 0xfa */
	{SNDRV_SEQ_EVENT_CONTINUE,	NULL}, /* 0xfb */
	{SNDRV_SEQ_EVENT_STOP,		NULL}, /* 0xfc */
	{SNDRV_SEQ_EVENT_NONE,		NULL}, /* 0xfd */
	{SNDRV_SEQ_EVENT_SENSING,	NULL}, /* 0xfe */
	{SNDRV_SEQ_EVENT_RESET,		NULL}, /* 0xff */
};

static int cvt_ump_system_to_event(const union snd_ump_midi1_msg *val,
				   struct snd_seq_event *ev)
{
	unsigned char status = val->system.status;

	if ((status & 0xf0) != UMP_MIDI1_MSG_REALTIME)
		return 0; /* invalid status - skip */
	status &= 0x0f;
	ev->type = system_msg_encoders[status].seq_type;
	ev->flags = SNDRV_SEQ_EVENT_LENGTH_FIXED;
	if (ev->type == SNDRV_SEQ_EVENT_NONE)
		return 0;
	if (system_msg_encoders[status].encode)
		system_msg_encoders[status].encode(val, ev);
	return 1;
}

/* MIDI 2.0 CVM */

/* encode note event */
static int ump_midi2_to_note_ev(const union snd_ump_midi2_msg *val,
				struct snd_seq_event *ev)
{
	ev->data.note.channel = val->note.channel;

Annotation

Implementation Notes