AlexM posted Sep 23 '16, 15:26:
Hey all
I've noticed when using 2 midi devices (eg Korg MicroKey + nanoKontrol2, or a Novation LaunchKey which is recognised as 2 devices), I get this error after every few notes played:
MidiInAlsa::alsaMidiHandler: unknown MIDI input error!
I found that Joseph has had this issue over a year ago: https://github.com/superquadratic/rtmidi-python/issues/18 -- any leads here? It would be great to utilise 2 midi devices so that I can assign pots and faders to various parameters (I'm tinkering with Erik's SamplerBox2 which utilises freeverb and some tone controls)
Cheers!
AlexM posted Sep 26 '16, 09:30:
SOLVED! Or so I hope...
Had a bit of a look around for a different MIDI module and came across RTMIDI2 which specifically says can open multiple ports at once https://pypi.python.org/pypi/rtmidi2
Installed, imported, and replaced the Midi Devices Detection / Main Loop section with the following:
midi_in = rtmidi2.MidiInMulti().open_ports("*")
midi_in.callback = MidiCallback
No more errors, ghost notes or strange behaviours.
HansEhv posted Sep 26 '16, 21:43:
Hello Alex,
Thanks for sharing this!
But how does your main loop now look like?
The original:
---snip---
while True:
for port in midi_in[0].ports:
if port not in previous and 'Midi Through' not in port:
midi_in.append(rtmidi.MidiIn())
midi_in[-1].callback = MidiCallback
midi_in[-1].open_port(port)
print 'Opened MIDI: '+ port
previous = midi_in[0].ports
time.sleep(2)
---snip---
This one relies on the individual ports, how does your version test and loop?
HansEhv posted Sep 26 '16, 21:45:
..and now with dashes showing the indent :-)
while True:
- for port in midi_in[0].ports:
-- if port not in previous and 'Midi Through' not in port:
-- midi_in.append(rtmidi.MidiIn())
-- midi_in[-1].callback = MidiCallback
-- midi_in[-1].open_port(port)
-- print 'Opened MIDI: '+ port
- previous = midi_in[0].ports
- time.sleep(2)
AlexM posted Sep 27 '16, 09:39:
I actually just replaced the whole loop/section with those 2 lines. What would you suggest?
HansEhv posted Sep 27 '16, 12:12:
I thought of having the 'while true:' infinite loop with :
-These 2 statements
-The sleep delay. This to give more room for the other processes. It could even be longer as you don't plug/replug your midi interfaces that often.
HansEhv posted Sep 27 '16, 12:19:
Sorry, forgot a question: how do you now see the opened port(s)?
AlexM posted Sep 27 '16, 16:08:
Hey Hans,
I added these lines below (I'm hoping BB code works here otherwise I'll need to post again!)
This will also close all ports when a device change is detected and attempt to reopen whatever is now connected. (although when disconnecting my nanoKontrol, RPi wigs out with "usb 1-1.3: urb status -32" errors)
[code]
stopit = False
midi_in = rtmidi2.MidiInMulti()
curr_ports = []
prev_ports = []
first_loop = True
while True:
if stopit:
break
curr_ports = rtmidi2.get_in_ports()
if (len(prev_ports) != len(curr_ports)):
midi_in.close_ports()
prev_ports = []
for port in curr_ports:
if port not in prev_ports and 'Midi Through' not in port and (len(prev_ports) != len(curr_ports)):
midi_in.open_ports(port)
midi_in.callback = MidiCallback
if first_loop:
print 'Opened MIDI port: ' + port
else:
print 'Reopening MIDI port: ' + port
prev_ports = curr_ports
first_loop = False
time.sleep(2)
[/code]
AlexM posted Sep 27 '16, 16:10:
Ah damn - does anyone know how to format code in this forum? :(
remi posted Sep 27 '16, 17:35:
If i'm not wrong this should works like github
https://help.github.com/articles/creating-and-highlighting-code-blocks/
Or just past your code in here : https://gist.github.com/ (you don't need an account)
Test
stopit = False
midi_in = rtmidi2.MidiInMulti()
curr_ports = []
prev_ports = []
first_loop = True
while True:
if stopit:
break
curr_ports = rtmidi2.get_in_ports()
if (len(prev_ports) != len(curr_ports)):
midi_in.close_ports()
prev_ports = []
for port in curr_ports:
if port not in prev_ports and 'Midi Through' not in port and (len(prev_ports) != len(curr_ports)):
midi_in.open_ports(port)
midi_in.callback = MidiCallback
if first_loop:
print 'Opened MIDI port: ' + port
else:
print 'Reopening MIDI port: ' + port
prev_ports = curr_ports
first_loop = False
time.sleep(2)
AlexM posted Sep 27 '16, 17:45:
HansEhv posted Sep 27 '16, 23:40:
Many thanks guys, this is very useful.
Kevin Chau posted Nov 7 '16, 23:29:
Installing rtmidi2 also solved ghost notes and bad midi input for the mpkmini mk2 that i am using. Thanks for the solution
AlexM posted Nov 8 '16, 06:57:
Good to know!
There's still a bug that causes SamplerBox to crash when connecting/disconnecting midi devices. I have a few ideas on the cause(s) which I'll test in time. But for the time being this solution seems to be working well for the most part!