summaryrefslogtreecommitdiff
path: root/sound/core/seq/seq_clientmgr.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2023-05-23 09:53:51 +0200
committerTakashi Iwai <tiwai@suse.de>2023-05-23 12:11:28 +0200
commite9e02819a98a50fefe2f8016b1e5237742637cd1 (patch)
treecaabcac9fedb9005043a9dc35e2a413bce9f559b /sound/core/seq/seq_clientmgr.c
parenta3ca3b30800da0a334e2d6eb68d123ec8e2d2bf6 (diff)
ALSA: seq: Automatic conversion of UMP events
This patch enables the automatic conversion of UMP events from/to the legacy ALSA sequencer MIDI events. Also, as UMP itself has two different modes (MIDI 1.0 and MIDI 2.0), yet another converters between them are needed, too. Namely, we have conversions between the legacy and UMP like: - seq legacy event -> seq UMP MIDI 1.0 event - seq legacy event -> seq UMP MIDI 2.0 event - seq UMP MIDI 1.0 event -> seq legacy event - seq UMP MIDI 2.0 event -> seq legacy event and the conversions between UMP MIDI 1.0 and 2.0 clients like: - seq UMP MIDI 1.0 event -> seq UMP MIDI 2.0 event - seq UMP MIDI 2.0 event -> seq UMP MIDI 1.0 event The translation is per best-effort; some MIDI 2.0 specific events are ignored when translated to MIDI 1.0. Reviewed-by: Jaroslav Kysela <perex@perex.cz> Link: https://lore.kernel.org/r/20230523075358.9672-31-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/seq/seq_clientmgr.c')
-rw-r--r--sound/core/seq/seq_clientmgr.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 33aa6c5c5c9e..07b090f76b5f 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -20,6 +20,7 @@
#include "seq_timer.h"
#include "seq_info.h"
#include "seq_system.h"
+#include "seq_ump_convert.h"
#include <sound/seq_device.h>
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
@@ -612,6 +613,27 @@ static int update_timestamp_of_queue(struct snd_seq_event *event,
return 1;
}
+/* deliver a single event; called from below and UMP converter */
+int __snd_seq_deliver_single_event(struct snd_seq_client *dest,
+ struct snd_seq_client_port *dest_port,
+ struct snd_seq_event *event,
+ int atomic, int hop)
+{
+ switch (dest->type) {
+ case USER_CLIENT:
+ if (!dest->data.user.fifo)
+ return 0;
+ return snd_seq_fifo_event_in(dest->data.user.fifo, event);
+ case KERNEL_CLIENT:
+ if (!dest_port->event_input)
+ return 0;
+ return dest_port->event_input(event,
+ snd_seq_ev_is_direct(event),
+ dest_port->private_data,
+ atomic, hop);
+ }
+ return 0;
+}
/*
* deliver an event to the specified destination.
@@ -648,22 +670,20 @@ static int snd_seq_deliver_single_event(struct snd_seq_client *client,
update_timestamp_of_queue(event, dest_port->time_queue,
dest_port->time_real);
- switch (dest->type) {
- case USER_CLIENT:
- if (dest->data.user.fifo)
- result = snd_seq_fifo_event_in(dest->data.user.fifo, event);
- break;
+#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
+ if (snd_seq_ev_is_ump(event)) {
+ result = snd_seq_deliver_from_ump(client, dest, dest_port,
+ event, atomic, hop);
+ goto __skip;
+ } else if (snd_seq_client_is_ump(dest)) {
+ result = snd_seq_deliver_to_ump(client, dest, dest_port,
+ event, atomic, hop);
+ goto __skip;
+ }
+#endif /* CONFIG_SND_SEQ_UMP */
- case KERNEL_CLIENT:
- if (dest_port->event_input == NULL)
- break;
- result = dest_port->event_input(event, direct,
- dest_port->private_data,
+ result = __snd_seq_deliver_single_event(dest, dest_port, event,
atomic, hop);
- break;
- default:
- break;
- }
__skip:
if (dest_port)