sound/core/ump_convert.c

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

File Facts

System
Linux kernel
Corpus path
sound/core/ump_convert.c
Extension
.c
Size
13168 bytes
Lines
529
Domain
Driver Families
Bucket
sound/core
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (midi2->pg.bank_valid) {
			buf[0] = channel | (UMP_MSG_STATUS_CC << 4);
			buf[1] = UMP_CC_BANK_SELECT;
			buf[2] = midi2->pg.bank_msb;
			buf[3] = channel | (UMP_MSG_STATUS_CC << 4);
			buf[4] = UMP_CC_BANK_SELECT_LSB;
			buf[5] = midi2->pg.bank_lsb;
			buf[6] = channel | (UMP_MSG_STATUS_PROGRAM << 4);
			buf[7] = midi2->pg.program;
			return 8;
		}
		buf[1] = midi2->pg.program;
		return 2;
	case UMP_MSG_STATUS_PITCH_BEND:
		v = downscale_32_to_14bit(midi2->pb.data);
		buf[1] = v & 0x7f;
		buf[2] = v >> 7;
		return 3;
	case UMP_MSG_STATUS_RPN:
	case UMP_MSG_STATUS_NRPN:
		buf[0] = channel | (UMP_MSG_STATUS_CC << 4);
		buf[1] = status == UMP_MSG_STATUS_RPN ? UMP_CC_RPN_MSB : UMP_CC_NRPN_MSB;
		buf[2] = midi2->rpn.bank;
		buf[3] = buf[0];
		buf[4] = status == UMP_MSG_STATUS_RPN ? UMP_CC_RPN_LSB : UMP_CC_NRPN_LSB;
		buf[5] = midi2->rpn.index;
		buf[6] = buf[0];
		buf[7] = UMP_CC_DATA;
		v = downscale_32_to_14bit(midi2->rpn.data);
		buf[8] = v >> 7;
		buf[9] = buf[0];
		buf[10] = UMP_CC_DATA_LSB;
		buf[11] = v & 0x7f;
		return 12;
	default:
		return 0;
	}
}

/* convert a UMP 7-bit SysEx message to MIDI 1.0 byte stream */
static int cvt_ump_sysex7_to_legacy(const u32 *data, unsigned char *buf)
{
	unsigned char status;
	unsigned char bytes;
	int size, offset;

	status = ump_sysex_message_status(*data);
	if (status > UMP_SYSEX_STATUS_END)
		return 0; // unsupported, skip
	bytes = ump_sysex_message_length(*data);
	if (bytes > 6)
		return 0; // skip

	size = 0;
	if (status == UMP_SYSEX_STATUS_SINGLE ||
	    status == UMP_SYSEX_STATUS_START) {
		buf[0] = UMP_MIDI1_MSG_SYSEX_START;
		size = 1;
	}

	offset = 8;
	for (; bytes; bytes--, size++) {
		buf[size] = (*data >> offset) & 0x7f;
		if (!offset) {
			offset = 24;
			data++;
		} else {
			offset -= 8;
		}
	}

	if (status == UMP_SYSEX_STATUS_SINGLE ||
	    status == UMP_SYSEX_STATUS_END)
		buf[size++] = UMP_MIDI1_MSG_SYSEX_END;

	return size;
}

/**
 * snd_ump_convert_from_ump - convert from UMP to legacy MIDI
 * @data: UMP packet
 * @buf: buffer to store legacy MIDI data
 * @group_ret: pointer to store the target group
 *
 * Convert from a UMP packet @data to MIDI 1.0 bytes at @buf.
 * The target group is stored at @group_ret.
 *
 * The function returns the number of bytes of MIDI 1.0 stream.
 */
int snd_ump_convert_from_ump(const u32 *data,

Annotation

Implementation Notes