diff options
author | Takashi Iwai <tiwai@suse.de> | 2023-05-23 10:53:51 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2023-05-23 13:11:28 +0300 |
commit | e9e02819a98a50fefe2f8016b1e5237742637cd1 (patch) | |
tree | caabcac9fedb9005043a9dc35e2a413bce9f559b /sound/core/seq/seq_clientmgr.c | |
parent | a3ca3b30800da0a334e2d6eb68d123ec8e2d2bf6 (diff) | |
download | linux-e9e02819a98a50fefe2f8016b1e5237742637cd1.tar.xz |
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.c | 48 |
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) |