Direct MIDI event delivery to ALSA sequencer's hardware port without any connections/subscriptions fails with -ENODEV.
Hello,
I had written an `aseqsend` utility to send MIDI events from hex strings to ALSA sequencer ports, similar to the -S arg of `amidi`, but I just noticed that while sending events directly to application ALSA Sequencer ports works just fine, trying to send to a hardware MIDI port fails with -19 (-ENODEV).
Here's the aseqsend utility code, the highlighted line is the one returning -ENODEV:
https://github.com/BlokasLabs/aseqsend/blob/main/aseqsend.c#L173
Here's some sample commands showcasing the problem (I've added a printf with drain result just after the indicated line above locally):
https://paste.debian.net/hidden/9690d660/
It shows that in case there's no active subscriptions to the port, the event delivery fails, with no data ever reaching the hardware device. As long as there's at least one subscription to the port, it works ok. I've reproduced this on 5.15.36-rt41-v7+ and 6.6.58-v8-16k (running on Raspberry Pi, based on https://github.com/raspberrypi/linux)
I've traced the -ENODEV to be returned at this location: https://elixir.bootlin.com/linux/v6.6.58/source/sound/core/seq/seq_midi.c#L1...
Whenever there's a subscription, the 'substream' is not NULL.
But what I would naturally expect is for the events to get delivered to the hardware port when using direct addressing, regardless of its subscription status, the same way how it's possible to send events to application aseq ports:
-- Terminal 1 -- patch@patchbox:~ $ aseqdump Waiting for data at port 128:0. Press Ctrl+C to end. Source Event Ch Data 129:0 Note on 0, note 64, velocity 48
-- Terminal 2 -- patch@patchbox:~/work/aseqsend $ ./aseqsend 128:0 90 40 30 drain: 0
Is this a bug in ALSA Sequencer, or is my expectation of being able to write directly to a hardware ALSA sequencer port incorrect?
On Thu, 31 Oct 2024 08:49:02 +0100, giedrius@blokas.io wrote:
Hello,
I had written an `aseqsend` utility to send MIDI events from hex strings to ALSA sequencer ports, similar to the -S arg of `amidi`, but I just noticed that while sending events directly to application ALSA Sequencer ports works just fine, trying to send to a hardware MIDI port fails with -19 (-ENODEV).
Here's the aseqsend utility code, the highlighted line is the one returning -ENODEV:
https://github.com/BlokasLabs/aseqsend/blob/main/aseqsend.c#L173
Here's some sample commands showcasing the problem (I've added a printf with drain result just after the indicated line above locally):
https://paste.debian.net/hidden/9690d660/
It shows that in case there's no active subscriptions to the port, the event delivery fails, with no data ever reaching the hardware device. As long as there's at least one subscription to the port, it works ok. I've reproduced this on 5.15.36-rt41-v7+ and 6.6.58-v8-16k (running on Raspberry Pi, based on https://github.com/raspberrypi/linux)
I've traced the -ENODEV to be returned at this location: https://elixir.bootlin.com/linux/v6.6.58/source/sound/core/seq/seq_midi.c#L1...
Whenever there's a subscription, the 'substream' is not NULL.
But what I would naturally expect is for the events to get delivered to the hardware port when using direct addressing, regardless of its subscription status, the same way how it's possible to send events to application aseq ports:
-- Terminal 1 -- patch@patchbox:~ $ aseqdump Waiting for data at port 128:0. Press Ctrl+C to end. Source Event Ch Data 129:0 Note on 0, note 64, velocity 48
-- Terminal 2 -- patch@patchbox:~/work/aseqsend $ ./aseqsend 128:0 90 40 30 drain: 0
Is this a bug in ALSA Sequencer, or is my expectation of being able to write directly to a hardware ALSA sequencer port incorrect?
The behavior depends on the sequencer client, but in the case of the normal MIDI clients, the subscription is mandatory for delivering events properly. It corresponds to open/close the device.
HTH,
Takashi
Hi Takashi,
So the pattern instead should be to subscribe own simple port to the destination port(s) and then send the events using 'snd_seq_ev_set_subs'?
I see aseqsend appeared in ALSA-utils as well, it would also be impacted by the same access pattern if trying to send to an unsubscribed hardware port.
Thank you! Giedrius.
On Thu, Oct 31, 2024 at 11:02 AM Takashi Iwai tiwai@suse.de wrote:
On Thu, 31 Oct 2024 08:49:02 +0100, giedrius@blokas.io wrote:
Hello,
I had written an `aseqsend` utility to send MIDI events from hex strings
to ALSA sequencer ports, similar to the -S arg of `amidi`, but I just noticed that while sending events directly to application ALSA Sequencer ports works just fine, trying to send to a hardware MIDI port fails with -19 (-ENODEV).
Here's the aseqsend utility code, the highlighted line is the one
returning -ENODEV:
https://github.com/BlokasLabs/aseqsend/blob/main/aseqsend.c#L173
Here's some sample commands showcasing the problem (I've added a printf
with drain result just after the indicated line above locally):
https://paste.debian.net/hidden/9690d660/
It shows that in case there's no active subscriptions to the port, the
event delivery fails, with no data ever reaching the hardware device. As long as there's at least one subscription to the port, it works ok. I've reproduced this on 5.15.36-rt41-v7+ and 6.6.58-v8-16k (running on Raspberry Pi, based on https://github.com/raspberrypi/linux)
I've traced the -ENODEV to be returned at this location:
https://elixir.bootlin.com/linux/v6.6.58/source/sound/core/seq/seq_midi.c#L1...
Whenever there's a subscription, the 'substream' is not NULL.
But what I would naturally expect is for the events to get delivered to
the hardware port when using direct addressing, regardless of its subscription status, the same way how it's possible to send events to application aseq ports:
-- Terminal 1 -- patch@patchbox:~ $ aseqdump Waiting for data at port 128:0. Press Ctrl+C to end. Source Event Ch Data 129:0 Note on 0, note 64, velocity 48
-- Terminal 2 -- patch@patchbox:~/work/aseqsend $ ./aseqsend 128:0 90 40 30 drain: 0
Is this a bug in ALSA Sequencer, or is my expectation of being able to
write directly to a hardware ALSA sequencer port incorrect?
The behavior depends on the sequencer client, but in the case of the normal MIDI clients, the subscription is mandatory for delivering events properly. It corresponds to open/close the device.
HTH,
Takashi
On Thu, 31 Oct 2024 10:52:23 +0100, Giedrius Trainavičius wrote:
Hi Takashi,
So the pattern instead should be to subscribe own simple port to the destination port(s) and then send the events using 'snd_seq_ev_set_subs'?
Yes. The destination can be explicitly specified, too, but the subscription should have been established.
I see aseqsend appeared in ALSA-utils as well, it would also be impacted by the same access pattern if trying to send to an unsubscribed hardware port.
True. As mentioned, the behavior depends on the client, and the tool was designed to be simplistic, as it seems.
Takashi
Thank you! Giedrius.
On Thu, Oct 31, 2024 at 11:02 AM Takashi Iwai tiwai@suse.de wrote:
On Thu, 31 Oct 2024 08:49:02 +0100, giedrius@blokas.io wrote: > > Hello, > > I had written an `aseqsend` utility to send MIDI events from hex strings to ALSA sequencer ports, similar to the -S arg of `amidi`, but I just noticed that while sending events directly to application ALSA Sequencer ports works just fine, trying to send to a hardware MIDI port fails with -19 (-ENODEV). > > Here's the aseqsend utility code, the highlighted line is the one returning -ENODEV: > > https://github.com/BlokasLabs/aseqsend/blob/main/aseqsend.c#L173 > > Here's some sample commands showcasing the problem (I've added a printf with drain result just after the indicated line above locally): > > https://paste.debian.net/hidden/9690d660/ > > It shows that in case there's no active subscriptions to the port, the event delivery fails, with no data ever reaching the hardware device. As long as there's at least one subscription to the port, it works ok. I've reproduced this on 5.15.36-rt41-v7+ and 6.6.58-v8-16k (running on Raspberry Pi, based on https://github.com/raspberrypi/linux) > > I've traced the -ENODEV to be returned at this location: https://elixir.bootlin.com/linux/v6.6.58/source/sound/core/seq/seq_midi.c#L134 > > Whenever there's a subscription, the 'substream' is not NULL. > > But what I would naturally expect is for the events to get delivered to the hardware port when using direct addressing, regardless of its subscription status, the same way how it's possible to send events to application aseq ports: > > -- Terminal 1 -- > patch@patchbox:~ $ aseqdump > Waiting for data at port 128:0. Press Ctrl+C to end. > Source Event Ch Data > 129:0 Note on 0, note 64, velocity 48 > > -- Terminal 2 -- > patch@patchbox:~/work/aseqsend $ ./aseqsend 128:0 90 40 30 > drain: 0 > > > Is this a bug in ALSA Sequencer, or is my expectation of being able to write directly to a hardware ALSA sequencer port incorrect? The behavior depends on the sequencer client, but in the case of the normal MIDI clients, the subscription is mandatory for delivering events properly. It corresponds to open/close the device. HTH, Takashi
participants (3)
-
Giedrius Trainavičius
-
giedrius@blokas.io
-
Takashi Iwai