alsa: add UMP support

Use the new UMP alsa sequencer API to make it produce UMP packets.

Set the alsa sequencer to MIDI2.0, which will make it convert all
messages to MIDI-2.0 UMP automatically. We can copy this straight into
the control buffers.

This also solves some problems with large sysex messages that are now
nicely split into chunks with UMP.
This commit is contained in:
Wim Taymans 2024-07-26 15:15:52 +02:00
parent 7f38653589
commit 94bb5a2dd2
3 changed files with 42 additions and 55 deletions

View file

@ -17,6 +17,7 @@
#include <spa/monitor/device.h>
#include <spa/param/audio/format.h>
#include <spa/param/latency-utils.h>
#include <spa/control/control.h>
#include <spa/pod/filter.h>
#include "alsa-seq.h"
@ -290,7 +291,7 @@ static void emit_port_info(struct seq_state *this, struct seq_port *port, bool f
clean_name(alias);
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi");
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP");
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_OBJECT_PATH, path);
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, name);
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_ALIAS, alias);
@ -544,7 +545,8 @@ impl_node_port_enum_params(void *object, int seq,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control));
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control),
SPA_FORMAT_CONTROL_types, SPA_POD_CHOICE_FLAGS_Int(1u<<SPA_CONTROL_UMP));
break;
case SPA_PARAM_Format:
@ -555,7 +557,8 @@ impl_node_port_enum_params(void *object, int seq,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Format, SPA_PARAM_Format,
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control));
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control),
SPA_FORMAT_CONTROL_types, SPA_POD_Int(1u<<SPA_CONTROL_UMP));
break;
case SPA_PARAM_Buffers:
@ -648,6 +651,7 @@ static int port_set_format(void *object, struct seq_port *port,
port->have_format = false;
} else {
struct spa_audio_info info = { 0 };
uint32_t types;
if ((err = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0)
return err;
@ -656,6 +660,13 @@ static int port_set_format(void *object, struct seq_port *port,
info.media_subtype != SPA_MEDIA_SUBTYPE_control)
return -EINVAL;
if ((err = spa_pod_parse_object(format,
SPA_TYPE_OBJECT_Format, NULL,
SPA_FORMAT_CONTROL_types, SPA_POD_Int(&types))) < 0)
return err;
if (types != 1u << SPA_CONTROL_UMP)
return -EINVAL;
port->current_format = info;
port->have_format = true;
}