Read MIDI keyboard input? (Samson Graphite M25)

Hi All, I’m wondering is there any way to get MIDI piano/keyboard input into Grasshopper? I googled some discussions which are all years ago that most sources are either too expired or really technical.

Before getting into the technical rabbit hole, I’m wondering is there any simplified method to read MIDI keyboard input in Grasshopper these days?

Thanks in advance :slight_smile:

1 Like

Bump

This thread is relevant to my expensive hobby of audio as well.

2 Likes

After a bit of research it looks like e.g Python’s Mido library could be helpful. This with the Hops functionality could work out. Will check it out :slight_smile:

1 Like

While we’re in the general topic, has anyone ever gotten Grasshopper and Cycling 74’s Max to talk to each other?

1 Like

Stupid question but has anyone tried this yet?

I hadn’t tried Mandrill.

What I succeed finally was getting the MIDI signal with Python using Mido library.
What stopping me from getting it to GH is:

  • in Hops I don’t know the method how to keep returning new signal after every hit. It just returns values after recompution of component, but I want to keep sending an information all the time
  • in RhinoCode (Rhino 8 WiP) currently it’s too early to do anything with it

With the Hops component method, could you use the Trigger component to get it to send requests at a given interval? Ideally fast enough so it feels “instantaneous” from when you hit a key to when you get the value in Grasshopper?

1 Like

Yes, right now I am trying it, at first it didn’t worked out, because it doesn’t update the output values if the Hops component options to Catche are turned on (which is the default settings). So right now I know how to keep updating it, but currently fighting with Mido itself, as for some reason when I copy-paste Mido library code from normal script into the Hops part - I got an error message that suggests that my Midi port is being used in parallel by another process, which is not true. So trying to figure out this part right now :wink:

Ok finally got it!

Will post some results later :wink:

2 Likes

Ok, so here is a quick presentation of how it works:

Source code used here for Hops looks like this:

from flask import Flask
import ghhops_server as hs
import time
import mido

app = Flask(__name__)
hops: hs.HopsFlask = hs.Hops(app)

@hops.component(
    "/listenMidi",
    name="Listen Midi",
    nickname="Listen Midi",
    description="Listens to Midi",
    inputs=[],
    outputs=[hs.HopsString("Time Stamp"),
             hs.HopsString("1"),
             hs.HopsString("2"),
             hs.HopsString("3"),
             hs.HopsString("4"),
             hs.HopsString("5"),
             hs.HopsString("6")]
)
def listen_midi():
    time_stamp = time.time()
    default_value = 10
    note_1 = default_value
    note_2 = default_value
    note_3 = default_value
    note_4 = default_value
    note_5 = default_value
    note_6 = default_value
    with mido.open_input() as in_port:
        for msg in in_port:
            if msg.type == "note_on":
                if msg.note == 60:
                    note_1 = msg.velocity
                elif msg.note == 62:
                    note_2 = msg.velocity
                elif msg.note == 64:
                    note_3 = msg.velocity
                elif msg.note == 65:
                    note_4 = msg.velocity
                elif msg.note == 67:
                    note_5 = msg.velocity
                elif msg.note == 69:
                    note_6 = msg.velocity

                break

    return time_stamp, note_1, note_2, note_3, note_4, note_5, note_6


if __name__ == "__main__":
    app.run(debug=True)
  • Cache of Hops component should be switched off
  • Timer is connected to the Hops component to keep updating it (in this case it was 10 ms)
  • It works only if MIDI cable is properly connected (check it in MIDI-OX first if you’re not sure)
  • It freezes the GH while running. Need to switch off Python script first to unfreeze it
  • To run it I have to first run Python script, then click the Timer to start, and then hit the drum
  • Inside the code you can see I filter only “note_on”, because in drums “note_off” doesn’t matter, but if you’re using keyboard, then you might find it useful.

If you want to start slow without Hops, then here is some code to just print the MIDI message with Python and Mido only:

import mido

in_port = mido.open_input()

while True:
    for msg in in_port.iter_pending():
        if (msg.type == "note_on"):
            print(msg)
4 Likes

That’s great! Thanks for sharing this.

1 Like

Hi W,

I’m REALLY keen to get this working, but I’m afraid I’m not too great with programming. Could you possibly explain this to me like I’m 3 year old? Here’s my ideal scenario:

I’m running Reaper with recorded Midi. I can send the Midi out of Reaper via a virtual midi cable (LoopBe1).

I’ve downloaded the Mido library and placed the whole unzipped folder in my ProgramFiles/Rhino7/System folder, but Python doesn’t see it. Could someone help a brother figure this out?

tx,

dh

Hey Declan,

if you want to install Python library, then go to the command prompt (cmd) and type in:
pip install mido

Then you can check if it’s installed correctly by trying out
import mido

cmd line doesn’t look too happy.

image

Propably you don’t have Python installed on your machine. Install Python first: Download Python | Python.org

Hello W,

I’ve installed Python and installed mido from the cmd line. However,

import mido

doesn’t seem to be successful:

‘import’ is not recognized as an internal or external command,
operable program or batch file.

Thank you in advance for your help - this is something I would LOVE to get working.

Hey,

the sample code that was written here is a Python script. You can run it in cmd in a slightly different way, but it will be better if you’d install some sort of code editor / IDE for Python. Personally I’m using Pycharm, but there are also: Atom, Visual Studio Code, Spyder etc. Once it’s installed you can copy paste the shorter example posted and try to run it. But generally I’d recommend checking out some basics of Python, because without it it would be difficult to change script the way you’d like. Or if something won’t work, then without it would be hard to say which part has failed. Good news is Python on a basic level is quite easy to learn.