mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
ump: Add helpers for handling SysEx data
Yet a few more helpers for handling SysEx data with UMP packets. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
040356ecf0
commit
e80ee6ae75
2 changed files with 113 additions and 0 deletions
|
|
@ -500,6 +500,14 @@ enum {
|
|||
SND_UMP_MSG_RESET = 0xff,
|
||||
};
|
||||
|
||||
/** MIDI 2.0 SysEx / Data Status; same values for both 7-bit and 8-bit SysEx */
|
||||
enum {
|
||||
SND_UMP_SYSEX_STATUS_SINGLE = 0,
|
||||
SND_UMP_SYSEX_STATUS_START = 1,
|
||||
SND_UMP_SYSEX_STATUS_CONTINUE = 2,
|
||||
SND_UMP_SYSEX_STATUS_END = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief get UMP status (4bit) from 32bit UMP message header
|
||||
*/
|
||||
|
|
@ -564,6 +572,25 @@ static inline uint8_t snd_ump_msg_group(const uint32_t *ump)
|
|||
return snd_ump_msg_hdr_group(*ump);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get UMP sysex message status
|
||||
*/
|
||||
static inline uint8_t snd_ump_sysex_msg_status(const uint32_t *ump)
|
||||
{
|
||||
return (*ump >> 20) & 0xf;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get UMP sysex message length
|
||||
*/
|
||||
static inline uint8_t snd_ump_sysex_msg_length(const uint32_t *ump)
|
||||
{
|
||||
return (*ump >> 16) & 0xf;
|
||||
}
|
||||
|
||||
int snd_ump_msg_sysex_expand(const uint32_t *ump, uint8_t *buf, size_t maxlen,
|
||||
size_t *filled);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -614,3 +614,89 @@ int snd_ump_block_info(snd_ump_t *ump, snd_ump_block_info_t *info)
|
|||
{
|
||||
return _snd_rawmidi_ump_block_info(ump->rawmidi, info);
|
||||
}
|
||||
|
||||
/*
|
||||
* UMP sysex helpers
|
||||
*/
|
||||
static int expand_sysex_data(const uint32_t *data, uint8_t *buf,
|
||||
size_t maxlen, unsigned char bytes, int offset)
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
for (; bytes; bytes--, size++) {
|
||||
if (!maxlen)
|
||||
break;
|
||||
buf[size] = (*data >> offset) & 0x7f;
|
||||
if (!offset) {
|
||||
offset = 24;
|
||||
data++;
|
||||
} else {
|
||||
offset -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int expand_sysex7(const uint32_t *ump, uint8_t *buf, size_t maxlen,
|
||||
size_t *filled)
|
||||
{
|
||||
unsigned char status;
|
||||
unsigned char bytes;
|
||||
|
||||
*filled = 0;
|
||||
if (!maxlen)
|
||||
return 0;
|
||||
|
||||
status = snd_ump_sysex_msg_status(ump);
|
||||
bytes = snd_ump_sysex_msg_length(ump);
|
||||
if (bytes > 6)
|
||||
return 0; // invalid - skip
|
||||
|
||||
*filled = expand_sysex_data(ump, buf, maxlen, bytes, 8);
|
||||
return (status == SND_UMP_SYSEX_STATUS_SINGLE ||
|
||||
status == SND_UMP_SYSEX_STATUS_END);
|
||||
}
|
||||
|
||||
static int expand_sysex8(const uint32_t *ump, uint8_t *buf, size_t maxlen,
|
||||
size_t *filled)
|
||||
{
|
||||
unsigned char status;
|
||||
unsigned char bytes;
|
||||
|
||||
*filled = 0;
|
||||
if (!maxlen)
|
||||
return 0;
|
||||
|
||||
status = snd_ump_sysex_msg_status(ump);
|
||||
if (status > SND_UMP_SYSEX_STATUS_END)
|
||||
return 0; // unsupported, skip
|
||||
bytes = snd_ump_sysex_msg_length(ump);
|
||||
if (!bytes || bytes > 14)
|
||||
return 0; // skip
|
||||
|
||||
*filled = expand_sysex_data(ump, buf, maxlen, bytes - 1, 0);
|
||||
return (status == SND_UMP_SYSEX_STATUS_SINGLE ||
|
||||
status == SND_UMP_SYSEX_STATUS_END);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief fill sysex byte from a UMP packet
|
||||
* \param ump UMP packet pointer
|
||||
* \param buf buffer point to fill sysex bytes
|
||||
* \param maxlen max buffer size in bytes
|
||||
* \param filled the size of filled sysex bytes on the buffer
|
||||
* \return 1 if the sysex finished, otherwise 0
|
||||
*/
|
||||
int snd_ump_msg_sysex_expand(const uint32_t *ump, uint8_t *buf, size_t maxlen,
|
||||
size_t *filled)
|
||||
{
|
||||
switch (snd_ump_msg_type(ump)) {
|
||||
case SND_UMP_MSG_TYPE_DATA:
|
||||
return expand_sysex7(ump, buf, maxlen, filled);
|
||||
case SND_UMP_MSG_TYPE_EXTENDED_DATA:
|
||||
return expand_sysex8(ump, buf, maxlen, filled);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue