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

Client Demo code #16

Open
skandix opened this issue Jan 13, 2020 · 15 comments
Open

Client Demo code #16

skandix opened this issue Jan 13, 2020 · 15 comments

Comments

@skandix
Copy link

skandix commented Jan 13, 2020

Is it possible that you could make an example of how one could use this to communicate with for example Tobias Erichsen rtpMidi (https://www.tobias-erichsen.de/software/rtpmidi.html)

@jldiaz
Copy link

jldiaz commented Jan 31, 2020

I second Skandix request. I think that using Python as a client has more sense than using it as a server. As a client, Python can be used to generate midi events and control different hardware or software synthethisers, allowing algorithmically created/generative music.

I'm specially interested in using Python in iPad (either with Pythonista or Pyto) to control other iPad synths. Neither Pythonista nor Pyto provide any kind of access to CoreMidi API, nor virtual ports, so it occured to me that a possible way could be to use RTP-MIDI.

Indeed, pymidi can be used from Pythonista/Pyto, and I successfully ran the server example in Pyto, and connected it to rtpmidi (the server shows the peer joining). But since I don't have a hardware midi keyboard attached to the computer, I was unable to send any midi event to pymidi server. I hoped than connecting a virtual keyboard in the iPad to the same network midi session would work, but no. When keys were pressed in the virtual keyboard in the iPad, those keys were sent via wifi to the computer, but the computer did not broadcast them among the session participants as I hoped. I guess I lack a proprer understanding of how midi network sessions work.

Do you think that my goal would be possible? I mean, to run in the iPad one or more synths, all of them conected to a network midi session, and control them from python also running in the ipad. Preferibly also without needing a computer in the same wifi.

@scottmetoyer
Copy link

Right - any examples or code on how to send MIDI back to a connected peer would be very useful.

@skandix
Copy link
Author

skandix commented Jan 22, 2021

@mik3y Maybe take a look at the issues once in a while?

@mik3y
Copy link
Owner

mik3y commented Jan 22, 2021

@skandix I've seen the issue. Unfortunately having time to address it is a different matter.

@lepetitjardin
Copy link

Is it possible that you could make an example of how one could use this to communicate with for example Tobias Erichsen rtpMidi (https://www.tobias-erichsen.de/software/rtpmidi.html)

I'll have a go at answering this one as it's quite easy to do. Two parts, configuring the Windows end of rtpMIDI and then the pymidi end om whatever device you're running it, in my case a Raspberry Pi, which I've named on the network as "rpi-midi".

rtpMIDI on Windows

  1. Add a Session, give it a local name, a bonjour name and a port number. These can be anything on your Windows machine, I don't think you need the info for pymidi, as pymidi is the server and these details are for when rtpMIDI is the server I think. Then enable it by ticking the box.
  2. Under Directory, you have to manually add the server details (in my case the Raspberry Pi) running pymidi. Click the + box under Directory and fill in Name, Hostname / IP-Address and Port of the device running pymidi. In my case, Name=anything, Hostname=rpi-midi, Port=5004. You could use IP addresses here if you want.
  3. With this new entry in the Directory selected, click the Connect button underneath and it should now be added to the Participants box on the right of the rtpMIDI dialogue box.

pymidi setup

  1. Using the example code given for pymidi, all you need to do is run the code but include the port number you used in Step 2 above (in my example 5004) in the line:
    myServer = server.Server([('0.0.0.0', 5004)])

Now you should see connection message appear in pymidi output, and on Windows under rtpMIDI, you should hopefully now see some value under latency.

To test, I just opened MIDI-OX, selected the MIDI port from the local name in the first step of the Windows setup, set MIDI-OX to use the keyboard for MIDI keys and hitting keys, you should see messages reported from pymidi.

@mik3y
Copy link
Owner

mik3y commented Jan 25, 2021

@lepetitjardin thank you! I really appreciate you chipping in and adding some knowledge/examples here. I copied your example over to the wiki here: https://github.com/mik3y/pymidi/wiki/Example-with-rtpMIDI

However... I think what people are after are how to use pymidi in the other direction, as a client. Maybe something like:

c = pymidi.Client(host, port)
c.send_note_on('B6', velocity=100)

Unfortunately, I originally/only wrote pymidi to be a server, so this doesn't exist yet.

I took a look over the weekend and have merged a work-in-progress. When it works, I'll cut a new release. In the meantime, anyone adventurous can had around from source. 8a017c6

@lepetitjardin
Copy link

@lepetitjardin thank you! I really appreciate you chipping in and adding some knowledge/examples here. I copied your example over to the wiki here: https://github.com/mik3y/pymidi/wiki/Example-with-rtpMIDI

And thank you for your code too. I can send over some screenshots if you want to add those to the Wiki.

However... I think what people are after are how to use pymidi in the other direction, as a client. Maybe something like:

c = pymidi.Client(host, port)
c.send_note_on('B6', velocity=100)

Yes, that would be awesome.

However, I think we need to be careful about the use of client and server here as the RTP MIDI protocol can be bi-directional between client and server anyway, at least from my limited reading of the specification and the diagram on the Wikipedia page about it.

Unfortunately, I originally/only wrote pymidi to be a server, so this doesn't exist yet.

So I think pymidi acting as a server could still possibly transmit or send RTP MIDI messages.

I took a look over the weekend and have merged a work-in-progress. When it works, I'll cut a new release. In the meantime, anyone adventurous can had around from source. 8a017c6

Will have a look, thanks.

@mik3y
Copy link
Owner

mik3y commented Jan 26, 2021

However, I think we need to be careful about the use of client and server here as the RTP MIDI protocol can be bi-directional between client and server anyway, at least from my limited reading of the specification and the diagram on the Wikipedia page about it.

You know, I'm not sure how I overlooked that for so long but you're definitely right. In completing this work, refactoring the "Server" interface to be bi-directional, and consistent with the rest of the MIDI, would probably make a lot of sense. Great suggestion thanks.

@DhSufi
Copy link

DhSufi commented Nov 25, 2021

Hello, any update on this topic? It would be very useful not just to get and send midi messages in server mode. Thanks for your work.

@fmillion
Copy link

fmillion commented May 6, 2022

In my case, having Pymidi act as a client makes a lot more sense. My setup is to have a softsynth running on Windows, with the rtpmidi driver on Windows acting as a server listening for data. I want a RasPi to send MIDI data to the Windows box, which will be played through the synth. Since the RasPi is the transient device here, definitely want it to be able to do the outbound connection to another RTP-MIDI device.

The version of pymidi that gets installed from pip is apparently quite different than the one here, even though the version numbers match (0.5.0). As-is, the pip version is not compatible with the exampe code:

user@raspi:$ python3 client_test.py
b'\x80\xe1\x00\x00\x00\x00\x00\x00o\x1e\xb0\xa4C\x90\x00\x7f'
INFO:pymidi.examples.client:Connecting to RTP-MIDI server ...
INFO:pymidi.examples.client:Connecting!
INFO:pymidi.examples.client:Striking key...
Traceback (most recent call last):
  File "client_test.py", line 14, in <module>
    client.send_note_on('B6',velocity=127)
  File "/usr/local/lib/python3.9/dist-packages/pymidi/client.py", line 64, in send_note_on
    data = b'\x43' + command.to_bytes(1, 'big') + key.to_bytes(1, 'big') + velocity.to_bytes(1, 'big')
AttributeError: 'str' object has no attribute 'to_bytes'

I haven't yet tried pulling the Git version, I'll do that in a bit here, but I'm going to play around with the code to see if I can improve on the client side code. I was planning to implement my own version, but if I can improve on this one hopefully it will be more useful on a broad scale.

@mik3y
Copy link
Owner

mik3y commented May 9, 2022

The version of pymidi that gets installed from pip is apparently quite different than the one here, even though the version numbers match (0.5.0).

Sorry about that - I typically tag releases but continue marching forward in master after doing so. You'll see v0.5.0 in history - that should match pip.

I'm going to play around with the code to see if I can improve on the client side code. I was planning to implement my own version, but if I can improve on this one hopefully it will be more useful on a broad scale.

I will happily support as best I can! (review PRs, share what I know, etc).

@QuentinX5
Copy link

Has there been any update on this? The version on pip is different, but I updated it with the code on here and still can't get messages going out using the examples.

@guysoft
Copy link

guysoft commented Jul 23, 2023

This seems to work for me, however, I can't find any information on how to disconnect from a server.

https://github.com/mik3y/pymidi/blob/main/examples/example_client.py

I tried looking but not sure what should be sent

@jldiaz
Copy link

jldiaz commented Jul 23, 2023

@guysoft I guess that client.socket.close() should do.

@guysoft
Copy link

guysoft commented Jul 25, 2023

@jldiaz Nope, does not work.

Here is how it looks:
What i get is a new midi device each time I run it on rtpmidi jack:
Screenshot_20230725_012841

If I look at the server side there is some kind of disconnect message. But I need to capture traffic so I can pinpoint it

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

9 participants