ALSA: rawmidi: Add framing mode
This commit adds a new framing mode that frames all MIDI data into 32-byte frames with a timestamp. The main benefit is that we can get accurate timestamps even if userspace wakeup and processing is not immediate. Testing on a Celeron N3150 with this mode has a max jitter of 2.8 ms, compared to the in-kernel seq implementation which has a max jitter of 5 ms during idle and much worse when running scheduler stress tests in parallel. Signed-off-by: David Henningsson <coding@diwic.se> Reviewed-by: Jaroslav Kysela <perex@perex.cz> Link: https://lore.kernel.org/r/20210515071533.55332-1-coding@diwic.se Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
committed by
Takashi Iwai
parent
bac5905454
commit
08fdced60c
@@ -710,7 +710,7 @@ enum {
|
||||
* Raw MIDI section - /dev/snd/midi??
|
||||
*/
|
||||
|
||||
#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 1)
|
||||
#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 2)
|
||||
|
||||
enum {
|
||||
SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
|
||||
@@ -736,12 +736,38 @@ struct snd_rawmidi_info {
|
||||
unsigned char reserved[64]; /* reserved for future use */
|
||||
};
|
||||
|
||||
#define SNDRV_RAWMIDI_MODE_FRAMING_MASK (7<<0)
|
||||
#define SNDRV_RAWMIDI_MODE_FRAMING_SHIFT 0
|
||||
#define SNDRV_RAWMIDI_MODE_FRAMING_NONE (0<<0)
|
||||
#define SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP (1<<0)
|
||||
#define SNDRV_RAWMIDI_MODE_CLOCK_MASK (7<<3)
|
||||
#define SNDRV_RAWMIDI_MODE_CLOCK_SHIFT 3
|
||||
#define SNDRV_RAWMIDI_MODE_CLOCK_NONE (0<<3)
|
||||
#define SNDRV_RAWMIDI_MODE_CLOCK_REALTIME (1<<3)
|
||||
#define SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC (2<<3)
|
||||
#define SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC_RAW (3<<3)
|
||||
|
||||
#define SNDRV_RAWMIDI_FRAMING_DATA_LENGTH 16
|
||||
|
||||
struct snd_rawmidi_framing_tstamp {
|
||||
/* For now, frame_type is always 0. Midi 2.0 is expected to add new
|
||||
* types here. Applications are expected to skip unknown frame types.
|
||||
*/
|
||||
__u8 frame_type;
|
||||
__u8 length; /* number of valid bytes in data field */
|
||||
__u8 reserved[2];
|
||||
__u32 tv_nsec; /* nanoseconds */
|
||||
__u64 tv_sec; /* seconds */
|
||||
__u8 data[SNDRV_RAWMIDI_FRAMING_DATA_LENGTH];
|
||||
} __packed;
|
||||
|
||||
struct snd_rawmidi_params {
|
||||
int stream;
|
||||
size_t buffer_size; /* queue size in bytes */
|
||||
size_t avail_min; /* minimum avail bytes for wakeup */
|
||||
unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */
|
||||
unsigned char reserved[16]; /* reserved for future use */
|
||||
unsigned int mode; /* For input data only, frame incoming data */
|
||||
unsigned char reserved[12]; /* reserved for future use */
|
||||
};
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
Reference in New Issue
Block a user