Skip to content

aseqsend silently fails (ENODEV) with hardware port #300

@michaelforney

Description

@michaelforney

When I use aseqsend to send a sysex message to a device, it doesn't seem to work, though there is no error message. Running with strace, it seems it is failing with ENODEV.

$ strace aseqsend -p 32:0 'F0 43 7D 10 41 30 01 00 00 01 F7'
...
open("/dev/snd/seq", O_WRONLY|O_LARGEFILE|O_CLOEXEC) = 3
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
ioctl(3, SNDRV_SEQ_IOCTL_PVERSION, 0x7fffef1ae678) = 0
ioctl(3, SNDRV_SEQ_IOCTL_USER_PVERSION, 0x7fffef1ae67c) = 0
mmap(NULL, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6ae25f7000
ioctl(3, SNDRV_SEQ_IOCTL_CLIENT_ID, 0x7fffef1ae67c) = 0
ioctl(3, SNDRV_SEQ_IOCTL_RUNNING_MODE, 0x7fffef1ae680) = 0
ioctl(3, SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, 0x7fffef1ae940) = 0
ioctl(3, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, 0x7fffef1ae940) = 0
ioctl(3, SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, 0x7fffef1ae940) = 0
ioctl(3, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, 0x7fffef1ae940) = 0
ioctl(3, SNDRV_SEQ_IOCTL_CREATE_PORT, 0x7fffef1ae960) = 0
write(3, "\202\4\0\375\0\0\0\0\0\0\0\0\0\0 \0\v\0\0\0\320\212WN\361U\0\0\360C}\20"..., 39) = -1 ENODEV (No such device)
nanosleep({tv_sec=0, tv_nsec=1000000}, 0x7fffef1aea20) = 0
close(3)                                = 0
munmap(0x7f6ae25f7000, 20480)           = 0
exit_group(0)                           = ?
+++ exited with 0 +++
$

amidi -S ... works as expected. If I modify aseqsend to first subscribe to the port, it seems to work:

diff --git a/seq/aseqsend/aseqsend.c b/seq/aseqsend/aseqsend.c
index 92354eb..ad0a636 100644
--- a/seq/aseqsend/aseqsend.c
+++ b/seq/aseqsend/aseqsend.c
@@ -364,6 +364,7 @@ int main(int argc, char *argv[])
 	char do_port_list = 0;
 	char verbose = 0;
 	int k;
+	int err;
 
 	while ((c = getopt_long(argc, argv, "hi:Vvlp:s:u:", long_options, NULL)) != -1) {
 		switch (c) {
@@ -439,6 +440,8 @@ int main(int argc, char *argv[])
 		error("Unable to parse port name!");
 		exit(EXIT_FAILURE);
 	}
+	err = snd_seq_connect_to(seq, 0, addr.client, addr.port);
+	check_snd("connect to port", err);
 
 	sent_data_c = 0; //counter of actually sent bytes

From what I've read, I don't think it should be necessary to subscribe to a port to send it messages. However, I did find one sentence in the alsa-lib docs that seem to indicate that it is needed for hardware ports:

There is another subscription type for opposite direction: Suppose a MIDI sequencer program which sends events to a MIDI output device. In ALSA system, MIDI device is not opened until the associated MIDI port is accessed. Thus, in order to activate MIDI device, we have to subscribe to MIDI port for write. After this connection is established, events will be properly sent to MIDI output device.

This seems to be a pretty basic use of aseqsend, so I am a bit surprised that it wasn't working. Is the subscription the right way to fix the problem, or am I doing something else wrong?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions