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
710710 * Raw MIDI section - /dev/snd/midi??
711711 */
712712
713−#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 1)
713+#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 2)
714714
715715 enum {
716716 SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
@@ -736,12 +736,38 @@ struct snd_rawmidi_info { · 19 unmodified lines
736736 unsigned char reserved[64]; /* reserved for future use */
737737 };
738738
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+
752+struct 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+
739764 struct snd_rawmidi_params {
740765 int stream;
741766 size_t buffer_size; /* queue size in bytes */
742767 size_t avail_min; /* minimum avail bytes for wakeup */
743768 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 */
745771 };
746772
747773 #ifndef __KERNEL__