History

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.

David Henningsson committed 5 years ago

Commit 08fdced1 parent bac59054 files · +124 −5Browse files

Showing the changes to include/uapi (1 of 4 files). Show all

Unified · Split

include/uapi/sound/asound.h+28−2
@@ -710,7 +710,7 @@ enum { · 709 unmodified lines
710 * Raw MIDI section - /dev/snd/midi??710 * Raw MIDI section - /dev/snd/midi??
711 */711 */
712 712
713#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 1)713#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 2)
714 714
715enum {715enum {
716 SNDRV_RAWMIDI_STREAM_OUTPUT = 0,716 SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
@@ -736,12 +736,38 @@ struct snd_rawmidi_info { · 19 unmodified lines
736 unsigned char reserved[64]; /* reserved for future use */736 unsigned char reserved[64]; /* reserved for future use */
737};737};
738 738
739#define SNDRV_RAWMIDI_MODE_FRAMING_MASK (7<<0)
740#define SNDRV_RAWMIDI_MODE_FRAMING_SHIFT 0
741#define SNDRV_RAWMIDI_MODE_FRAMING_NONE (0<<0)
742#define SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP (1<<0)
743#define SNDRV_RAWMIDI_MODE_CLOCK_MASK (7<<3)
744#define SNDRV_RAWMIDI_MODE_CLOCK_SHIFT 3
745#define SNDRV_RAWMIDI_MODE_CLOCK_NONE (0<<3)
746#define SNDRV_RAWMIDI_MODE_CLOCK_REALTIME (1<<3)
747#define SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC (2<<3)
748#define SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC_RAW (3<<3)
749
750#define SNDRV_RAWMIDI_FRAMING_DATA_LENGTH 16
751
752struct snd_rawmidi_framing_tstamp {
753 /* For now, frame_type is always 0. Midi 2.0 is expected to add new
754 * types here. Applications are expected to skip unknown frame types.
755 */
756 __u8 frame_type;
757 __u8 length; /* number of valid bytes in data field */
758 __u8 reserved[2];
759 __u32 tv_nsec; /* nanoseconds */
760 __u64 tv_sec; /* seconds */
761 __u8 data[SNDRV_RAWMIDI_FRAMING_DATA_LENGTH];
762} __packed;
763
739struct snd_rawmidi_params {764struct snd_rawmidi_params {
740 int stream;765 int stream;
741 size_t buffer_size; /* queue size in bytes */766 size_t buffer_size; /* queue size in bytes */
742 size_t avail_min; /* minimum avail bytes for wakeup */767 size_t avail_min; /* minimum avail bytes for wakeup */
743 unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */768 unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */
744 unsigned char reserved[16]; /* reserved for future use */769 unsigned int mode; /* For input data only, frame incoming data */
770 unsigned char reserved[12]; /* reserved for future use */
745};771};
746 772
747#ifndef __KERNEL__773#ifndef __KERNEL__