Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

alsa names are a bit too mutch #348

Open
shemeshg opened this issue Mar 7, 2025 · 9 comments
Open

alsa names are a bit too mutch #348

shemeshg opened this issue Mar 7, 2025 · 9 comments

Comments

@shemeshg
Copy link

shemeshg commented Mar 7, 2025

isn't this, a bit too match, and needs to be optional with flags?

    os << snd_seq_client_info_get_name( cinfo );
    os << ":";
    os << snd_seq_port_info_get_name( pinfo );
    os << " ";                                    // These lines added to make sure devices are listed
    os << snd_seq_port_info_get_client( pinfo );  // with full portnames added to ensure individual device names
    os << ":";
    os << snd_seq_port_info_get_port( pinfo );

I don't mind filter that myself on my side

    std::string IMidiInOut::extractAlsaNameIfRequired(const std::string& input) {
        // Regex pattern to match the desired part
        std::regex pattern(R"((.*):(.* \d+:\d+$))");
        std::smatch match;
    
        if (std::regex_match(input, match, pattern)) {
            // match[2] contains the part after the first colon, but includes the numbers at the end
            std::string namePart = match[2];
    
            // Find the position of the last space
            size_t lastSpace = namePart.find_last_of(' ');
            if (lastSpace != std::string::npos) {
                // Remove the digits part after the last space
                namePart = namePart.substr(0, lastSpace);
            }
            
            return namePart;
        }
    
        // Return an empty string if the pattern does not match
        return input;
    }

but I don't think all this verbosity is required by anyone, aseptically it yields different string for each call.

@insolace
Copy link
Contributor

insolace commented Mar 7, 2025 via email

@smoothdeveloper
Copy link

@shemeshg what is the output actually looking like?

Are you sure all the information is not necessary when a given client has or connects to several ports?

@shemeshg
Copy link
Author

shemeshg commented Mar 7, 2025

  1. very sure,
    I;ve managed to reproduce he problem where it's yield different string over time... see below
    (the 20:0 was not consistent)

attached one line complete name, one line a manipulated...

Midi Through:Midi Through Port-0 14:0
Midi Through Port-0
Launch Control XL:Launch Control XL Launch Contro 20:0
Launch Control XL Launch Contro
Launch Control XL:Launch Control XL Launch Contro 20:1
Launch Control XL Launch Contro
Midi Through:Midi Through Port-0 14:0
Midi Through Port-0
Launch Control XL:Launch Control XL Launch Contro 20:0
Launch Control XL Launch Contro
Launch Control XL:Launch Control XL Launch Contro 20:1
Launch Control XL Launch Contro
Midi Through:Midi Through Port-0 14:0
Midi Through Port-0
Launch Control XL:Launch Control XL Launch Contro 20:0
Launch Control XL Launch Contro
Launch Control XL:Launch Control XL Launch Contro 20:1
Launch Control XL Launch Contro
Midi Through:Midi Through Port-0 14:0
Midi Through Port-0
Launch Control XL:Launch Control XL Launch Contro 20:0
Launch Control XL Launch Contro
Launch Control XL:Launch Control XL Launch Contro 20:1
Launch Control XL Launch Contro
Midi Through:Midi Through Port-0 14:0
Midi Through Port-0
Launch Control XL:Launch Control XL Launch Contro 20:0
Launch Control XL Launch Contro
Launch Control XL:Launch Control XL Launch Contro 20:1
Launch Control XL Launch Contro
Midi Through:Midi Through Port-0 14:0
Midi Through Port-0
Launch Control XL:Launch Control XL Launch Contro 20:0
Launch Control XL Launch Contro
Launch Control XL:Launch Control XL Launch Contro 20:1
Launch Control XL Launch Contro
Midi Through:Midi Through Port-0 14:0
Midi Through Port-0
Launch Control XL:Launch Control XL Launch Contro 20:0
Launch Control XL Launch Contro
Launch Control XL:Launch Control XL Launch Contro 20:1
Launch Control XL Launch Contro
Midi Through:Midi Through Port-0 14:0
Midi Through Port-0
Launch Control XL:Launch Control XL Launch Contro 20:0
Launch Control XL Launch Contro
Launch Control XL:Launch Control XL Launch Contro 20:1
Launch Control XL Launch Contro
  1. When connected to several ports with same name, it might make sance,
    supposed it keeped consistent basted on USB ID,

Tested:
it is useless, these numbers 20 24 generated not based on the usb ID, but the order connected

This is very match unlike chrome webmidi where id's are uniqued by USB id.

Neutron(1):Neutron(1) MIDI 1 20:0
Neutron(1) MIDI 1
Launch Control XL:Launch Control XL Launch Contro 24:0
Launch Control XL Launch Contro
Launch Control XL:Launch Control XL Launch Contro 24:1
Launch Control XL Launch Contro

also if it were as expected wouldn't you rather a struct that return these? (or even better - accepted struct byref to maintain polymorphism)

also in the name of consistency, if these numbers had any meaning, we'd have to keep unique id's logic for Virtual Ports (this was not tested), though it might by be argued as "none issue" since I don't know how webmidi manages this)

in a way, these numbers 20:0 are misleading.

@insolace
Copy link
Contributor

insolace commented Mar 7, 2025 via email

@shemeshg
Copy link
Author

shemeshg commented Mar 7, 2025

these are just in and out respectively. xx.0 - in xx.1-out
the xx are arbitrary as concluded (but sequential based on time of connection, and also random after boot)

@smoothdeveloper
Copy link

thanks @shemeshg, I'm not familiar with the alsa APIs but I had to deal with parsing the output of "alsaconnect" program: https://github.com/smoothdeveloper/alsa.aconnect/blob/main/tests/alsa.aconnect.tests/tests.fs#L40

What feels likely, is that if changes are made to rtmidi, it should probably use the same information as that command line

https://github.com/bear24rw/alsa-utils/blob/master/seq/aconnect/aconnect.c

I think the fact that ids may change over time is normal, especially with many devices and probably non deterministic things occuring with USB & drivers loading or listing order.

@keinstein
Copy link

All this information is necessary because the construction varies from device to device.
Some Devices/Programs contain the device name in the port name, some not.
Some Authors are not very creative in naming their ports:

Device A:
Port 1
Port 2

Device B:
Port 1
Port 2

If two identical devices or client instances are connected the port numbers are the only thing that allows to uniquely identify the port that shall be connected.

Note: RtMidi ports numbers may change during runtime of your software while ALSA device and port numbers are stable. So between runs the numbers have no meaning but during runs they have a unique meaning.

@shemeshg
Copy link
Author

shemeshg commented Mar 8, 2025

In that case, it might be beneficial if RTMidi sorted its own port ID based on the ALSA snd_seq_port_info_get_port.
Additionally, it makes sense to determine the equivalent function for macOS, UMP, and Windows.

The focus should be on sorting by a consistent integer to provide reasonably ordered RTMidi port number, (not necessarily presenting them),
and maybe provide another means to retrieve that information.

Alternatively, it would be better to provide a hash of PortId + PortName.

This could be achieved by having one common class for all operating systems, passed by reference (to avoid damaging current implementations), or using an #IFDEF class for each OS.

In my software I do what LogicPro does (add prefix n_) based on the order returned for port IDs enumeration

0_Midi name
1_Midi name
0_Othe Midi name with a different name

the code for the 0_
check if name already appeared before, if yes, return count how many

    unsigned int IMidiInOut::unqIdPortNumber(unsigned int portNumber)
    {
        unsigned unqId = 0;
        std::string portnameWithoutUnqIdx = p_midi->getPortName(portNumber);
        for ( unsigned i=0; i<portNumber; i++ ) {
          if ( p_midi->getPortName(i) == portnameWithoutUnqIdx){unqId ++;}
        }
        return unqId;
    }

this is why I find consistent ordering important

@insolace
Copy link
Contributor

insolace commented Mar 9, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants