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

RtMidi is not able to see PureData #107

Closed
jcelerier opened this issue Apr 21, 2017 · 9 comments
Closed

RtMidi is not able to see PureData #107

jcelerier opened this issue Apr 21, 2017 · 9 comments

Comments

@jcelerier
Copy link
Contributor

jcelerier commented Apr 21, 2017

In the software I work on I couldn't see Pd's virtual ports (Linux ALSA). So I tested with the Python mido library which is a wrapper over RtMidi and PortMidi, and it does not see them either. However, mido with the PortMidi backend is able to see the Pd ports.

import rtmidi
import mido

portmidi = mido.Backend('mido.backends.portmidi')
rtmidi = mido.Backend('mido.backends.rtmidi')

rtmidi.get_input_names()
> ['KMidimon:KMidimon 128:0', 'Midi Through:Midi Through Port-0 14:0']

portmidi.get_input_names()
> ['KMidimon', 'Midi Through Port-0', 'Pure Data Midi-Out 1', 'Pure Data Midi-Out 2']
@radarsat1
Copy link
Contributor

It seems worth noting that PureData users PortMidi as well, so it's not super surprising that the portmidi backend is compatible. Also, from a glance at RtMidi.cpp, it appears there are two separate functions for normal ports (MidiInAlsa::openPort) and virtual ports (MidiInAlsa::openVirtualPort), so I assume that has something to do with it.

When running PureData on my Ubuntu laptop, with 2 open virtual midi ports, here is some output of relevant commands:

rtmidi's midiproble,

$ ./midiprobe 

Compiled APIs:
  Linux ALSA

Current input API: Linux ALSA

There are 1 MIDI input sources available.
  Input Port #1: Midi Through 14:0

Current output API: Linux ALSA

There are 1 MIDI output ports available.
  Output Port #1: Midi Through 14:0

alsa midi utility,

$ amidi -l
Dir Device    Name

aconnect,

$ aconnect -l
client 0: 'System' [type=kernel]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 128: 'Pure Data' [type=user]
    0 'Pure Data Midi-In 1'
    1 'Pure Data Midi-In 2'
    2 'Pure Data Midi-Out 1'
    3 'Pure Data Midi-Out 2'

So, it would appear that RtMidi is not showing the "type=user" ports.

@radarsat1
Copy link
Contributor

The function used to get port information is called portInfo() in RtMidi.cpp. (It should really be static..)

Anyways it contains a predicate that causes it specifically to skip "synth" ports,

      if ( ( ( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC ) == 0 ) &&                         
        ( ( atyp & SND_SEQ_PORT_TYPE_SYNTH ) == 0 ) ) continue;   

If I comment this out, I get the following output from midiprobe,

$ ./midiprobe 

Compiled APIs:
  Linux ALSA

Current input API: Linux ALSA

There are 3 MIDI input sources available.
  Input Port #1: Midi Through 14:0
  Input Port #2: Pure Data 128:2
  Input Port #3: Pure Data 128:3

Current output API: Linux ALSA

There are 3 MIDI output ports available.
  Output Port #1: Midi Through 14:0
  Output Port #2: Pure Data 128:0
  Output Port #3: Pure Data 128:1

I am not entirely sure what the motivation for this filtering predicate is, so I hesitate to change it. Perhaps @garyscavone can comment? I think the idea actually is to specifically restrict the list to hardware ports, but I am not sure why.

@jcelerier
Copy link
Contributor Author

jcelerier commented Apr 21, 2017

this was apparently added in this commit: 28321c0 so there must have been a good reason :p

@jcelerier
Copy link
Contributor Author

jcelerier commented Apr 21, 2017

Apparently, the flag means:

This port understands SND_SEQ_EVENT_SAMPLE_xxx messages (these are not MIDI messages)

@jcelerier
Copy link
Contributor Author

Sorry, this was dumb: just removing the second flag does not change anything. Removing the whole check however seems to work for me.

@jcelerier
Copy link
Contributor Author

jcelerier commented Apr 21, 2017

When printing all flags, it seems that the only flag set for puredata is :

SND_SEQ_PORT_TYPE_APPLICATION


      std::cerr << snd_seq_client_info_get_name(cinfo) << ": "
              << " " << bool( atyp & SND_SEQ_PORT_TYPE_SPECIFIC )
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC )
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_MIDI_GM )
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_MIDI_GS )
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_MIDI_XG )
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_MIDI_MT32 )
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_MIDI_GM2 )
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_SYNTH )
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_DIRECT_SAMPLE )
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_SAMPLE )
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_HARDWARE)
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_SOFTWARE)
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_SYNTHESIZER)
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_PORT)
             << " " << bool( atyp & SND_SEQ_PORT_TYPE_APPLICATION)
             << std::endl;

==>

Pure Data: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1

@jcelerier
Copy link
Contributor Author

Interestingly, portmidi seems to set both APPLICATION and GENERIC:

https://github.com/pure-data/pure-data/blob/master/portmidi/portmidi/pm_linux/pmlinuxalsa.c#L143

@garyscavone
Copy link
Contributor

garyscavone commented Apr 21, 2017 via email

@jcelerier
Copy link
Contributor Author

jcelerier commented Apr 21, 2017

@garyscavone : #108 . Thanks ! I could not see another flag that could make sense alone.

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

3 participants