MIDI

Official forum for open source FreePIE discussion and development.
Ju4n
One Eyed Hopeful
Posts: 3
Joined: Fri Dec 12, 2014 12:39 am

MIDI

Post by Ju4n »

Hello! I couldn't find any support on MIDI. I was looking to achieve what I finally got to do with GlovePie: use a secondary keyboard as a midi controller.
Everything works fine, I use loopMIDI to generate a midi input for the secondary usb keyboard, chose it in Ableton Live and voilà! New MIDI Controller out of a cheap kb.
Now the thing is that as it says here: http://glovepie.org/w/index.php?title=P ... 5#Keyboard if I want to swallow this keys not to interfere with anything else, it will also swallow my primary laptop keyboard.
Since FreePie is newer I thought this issue/feature would be overcome. Anyway, is there a way to swallow just one keyboard and send midi data to a virtual midi input from it?
Thank you in advance for everything.
Cheers!
JM
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

We had a discussion about this a long time ago, I recall that we didnt find a solution for swallowing keyboard presses
edit: Midi is currently not supported, basicly because I dont have such hardware myself, but If someone would fix a plugin I would pull that code. Also there might be python code that can do it
Ju4n
One Eyed Hopeful
Posts: 3
Joined: Fri Dec 12, 2014 12:39 am

Re: MIDI

Post by Ju4n »

Thank you for your response.
What exactly would you need coded in order to pull code from? Sorry if a Google search would answer the question but being new to this input world I find it hard to relate.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

There are a .NET library for Midi, but since I dont have any midi device its hard for me to try it. Do you have any experience in Visual Studio and .Net?
Ju4n
One Eyed Hopeful
Posts: 3
Joined: Fri Dec 12, 2014 12:39 am

Re: MIDI

Post by Ju4n »

Hmmm I used to program (even study IT engineering) but I'm far from that now... I do own some MIDI hardware though. With a lot of time, I could try to learn something again.. but I should step aside for someone who knows better.
I recently acquired a taiwanese copy of Novation's Launchpad called Midiplus Smartpad. So, after some research, reached the conclusion that for it to correctly function with Ableton Live I should code its behaviour in python. When I saw Live's API just surrenderd... :? :woot
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

Hi!
I just want to say, that FreePIE would immensely benefit from MIDI support.

DJ equipment is ridiculously cheap compared to e.g. flightsim enthusiast panels (those poor dudes get milked for their enthusiasm) but essentially they do the same thing:
Lots of different knobs and sliders, just a different interface: MIDI.
It would be totally awesome to feed e.g. VJoy with those MIDI devices!
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Yes, it would be really nice, but it would be great if a dev with MIDI hardware would step forward, because if I did it it would be like coding in the dark since I cant test it
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Looks pretty staight forward to connect to a midi port with that API


https://midinet.codeplex.com/SourceCont ... eceiver.cs

edit: I can try to fix a plugin using this API and then you gusy can test it?

It seems there are two types of data, short data which is a int?
And long data which is a byte buffer, i guess we need to support both of these?
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

Midi Channels have 32 14bit and 32 7bit controls - maybe that's what long and short is referencing?

Of course I would test it with my device :D

It's only a simple slider which uses only one MIDI controller. Hopefully someone with more complex hardware or an actual instrument can test a wider range of input.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Please try this little program i made, see if you receive anything
You do not have the required permissions to view the files attached to this post.
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

Works like a charm on my MIDI slider (Curious Inventor VMeter)

"S" ranges from 5296 to 8328368. I don't really know what this represents, but the device is using MIDI Channel 1, Controller 20, 0-127 or, in bytespeak: B0 14 00 to B0 14 7F - maybe thats related to those numbers?

"Time" is just that :)

EDIT: yes - of course they're related :D: If you put 5296 into a hexadecimal calculator you'll get "14B0". 8328368 equals "7F14B0"
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Hmm ok so your device only sends short data (S), we would probably need to try this with a device that also sends long data. But cool that it worked as easy.

edit: antoher question, would it be better to represent that 32 bit integer as a 4 byte word?

That way I could make long and short data more the same, return a byte word each time (Byte buffer)

edit: Also looks like the endian differs from what you want
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Heres a version that outputs the data as a byte word instead
You do not have the required permissions to view the files attached to this post.
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

Yes, I can read that version perfectly! e.g. at 100% slider it displays Data: B0 14 7F 0.

I don't know what the zero at the end means, (something with long and short data, because there's no "S" this time?) but the rest is something I can work with.

For 100% user friendliness you would need to convert those bytewords into their actual meaning in the MIDI context like "Control 20, 127" for the example above but there's the documentation of the standard and probing programs like Bome's which can do that as well. I think implementing that would be asking too much from you, considering you don't have a MIDI device.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

The data is 32 bits not 24 thats why there is a zero at the end, the FreePIE plugin will have a byte array so you will have to parse that yourself as the user of the plugin, so getting the 0-127 bit would be somethign like

Code: Select all

midi[0].data[2]
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

I found this post

https://forums.frontier.co.uk/showthrea ... ost1410445

Would this be a better syntax?

Code: Select all

midi[0].control[20]
0x14 is the control (20) but what does 0xB0 (176) stand for?

edit: This synstax better supports FreePIE's code completion etc

Code: Select all

def onMidi(): 
	diagnostics.watch(midi[0].getControl(20))

if starting: 
	midi[0].update += onMidi
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

B0 defines the status byte (aka midi message type) and MIDI channel [0-15 + 1]

B0 equals "control change in channel 1"

E2 would be "pitch bending in channel 3"

The german wikipedia page on MIDI has a nice overview of status bytes and control channels (with english descriptions as well)
https://de.wikipedia.org/wiki/Musical_I ... chtentypen
https://de.wikipedia.org/wiki/Musical_I ... Controller

EDIT: Of course there's the official documentation as well:
http://www.midi.org/techspecs/midimessages.php#2
Last edited by DrDim on Wed Jan 07, 2015 7:53 am, edited 1 time in total.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Ok, so its port / channel / control?

Anyway, so I ignore first byte (Status byte) and use second byte for channel then?
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

you could ignore it in the case of my device as it uses only "B" aka control anyway.

of course other MIDI devices would use all kinds of different status bytes [and channels] like notes etc.

the port is only the number the actual device got assigned to differenciate it from other MIDI devices
(which can be different for input and output on the same device - e.g. my slider has Port 0 for input and Port 5 for output)
Last edited by DrDim on Wed Jan 07, 2015 8:06 am, edited 1 time in total.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

But it belongs to the channel so this would seem logical?

Code: Select all

midi[0].getChannel(0).status  #will be 0xB in your case, also midi[0] means port 0
midi[0].getChannel(0).getControl(20) #will be value from your slider
edit: Acutally getControl(20) will return a byte array with two slots because there are two data bytes (Yours only use one) http://www.midi.org/techspecs/midimessages.php#2
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

So in the potential case when I would have a MIDI usb piano (on port 1) and play note "1"

Code: Select all

midi[1].getChannel(0).status  #will be 0x9
midi[1].getChannel(0).getNote(1) #will be the velocity of note "1"
Wouldn't it be better to call it "get2ndByte" to be more generic insteat of implementing all status byte types?
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

getControl would return a array of bytes so

Code: Select all

midi[0].getChannel(0).getControl(20)[0] #returns first byte
midi[0].getChannel(0).getControl(20)[1] #returns second byte
edit: ah, control is a bad name, its only true if satus byte = 0xB, maybe getData then?
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

yes - that would be a better name!
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Will get to work now :D Just to be clear, first version will only support reading MIDI
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

Aweseome! :D

(also congrats on finding my thread ;) - it will be a blessing when I can use 2/3 of my keyboard in the game again insteat of using the keystrokes for that crude hack I described there ^^)
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Why is glovepie calling it control btw? And not data etc?
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

GlovePIE uses all kinds of commands for MIDI IO. You can use actual notes like "csharp" or instruments like "maracas". Basically he (the developer) translated the most of the MIDI interface into GlovePIE

I personally think it's a little bit bloated esp. when you would use the GUI to create something because you have what feels like a 1km long scrollable dropdown list of MIDI inputs. Then again I know most what I know about MIDI from the GlovePIE documentation :)
http://glovepie.org/w/index.php?title=P ... v0.45#MIDI

EDIT: actually I found a "DataEntry" midi command in GlovePIE as well (it's undocumented though). I assume that's the more generic command you could use in GlovePIE instead of something specific and predefined like "Control".
Last edited by DrDim on Wed Jan 07, 2015 9:26 am, edited 2 times in total.
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

From a programmers perspective thats very ungeneric, and hard if you want todo some higly dynamic processing of the midi signal.. oh well
We will have to rewrite some of FreePIEs core functionally for this (code completion mainly) so it might take some time, but I could have a version workign without code completion very soon
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

I am trying to minimize the footprint of the Midi API can you please try that it is still working please
You do not have the required permissions to view the files attached to this post.
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

yep. still works on my end!
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Ok, first test version, for now its stricly event driven, like this

Code: Select all

def update():
	diagnostics.watch(midi[0].data.channel)
	diagnostics.watch(midi[0].data.status)
	diagnostics.watch(midi[0].data.buffer[0])
	diagnostics.watch(midi[0].data.buffer[1])
	
if starting: 
	midi[0].update += update
You do not have the required permissions to view the files attached to this post.
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

The code above works well with my device.

Image

This is almost working too well :D . Can't believe there hasn't been any problems yet. I can only dream of doing anything like this which works right of the bat!
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Cool that it works :D Let me know if you run into any problems using the code
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Since the midi plugin is purely event driven polling wont work that good (you might miss data that fires between script execution intevals) could you please try this script?

Code: Select all

def update():
	keyboard.setKey(Key.W, midi[0].data.buffer[1] < 64)
	keyboard.setKey(Key.S, midi[0].data.buffer[1] > 63)

if starting:
	midi[0].update += update
I'm not 100% sure the setkey command will work if you dont call it each script execution. Plase try it from a game because notepad wont catch more than one key.
values < 64 should make you character walk forward in game and values > 63 should make him walk backward
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

https://www.youtube.com/watch?v=8ISyzGMe7YU

:)

Code: Select all

from System import Int16

def update():

   vJoy[0].rz = filters.mapRange(midi[0].data.buffer[1], 0, 127, -Int16.MaxValue, Int16.MaxValue)   
   diagnostics.watch(vJoy[0].rz)

if starting:
   midi[0].update += update
I'll have to work a bit on the ranges. Int16 seems to leave big deadzones.
Other than that I'm very happy with how this worked out overall! Thank you very much CyberVillain!
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Strange with the ranges, is the slider really linear? If you slide the slider 1/4 of the way buffer[1] should be close to 32
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

I fixed it in a very analog way.
I measured the slider with a ruler. It has a lenth of ca. 11cm. Deadzones go from 0cm-2,5cm and 8,5cm-11cm
If you apply those values on the range of -32767 and 32767 with rule of three you get the approximate actual range of -17873 to 17873

When I use those values in the script it works like a charm :D

Code: Select all

def update():

   vJoy[0].rz = filters.mapRange(midi[0].data.buffer[1], 0, 127, -17873, 17873)
   
   diagnostics.watch(vJoy[0].rz)

if starting:
   midi[0].update += update
BTW: should I still test the setkey script?
CyberVillain
Petrif-Eyed
Posts: 2166
Joined: Mon Jun 22, 2009 8:36 am
Location: Stockholm, Sweden

Re: MIDI

Post by CyberVillain »

Strange that it has those deadzones, maybe has reason in the DJ world?

Yes, please try it, the keyboard plugin works different than vJoy
DrDim
One Eyed Hopeful
Posts: 24
Joined: Mon Jan 05, 2015 4:33 am

Re: MIDI

Post by DrDim »

I would rather assume that at least the rz axis of VJoy isn't using as much as -int16,int16. They were no deadzones when I used GlovePIE + PPJoy (actually I had to add deadzones).

The SetKey script seems to be rather accurate (I used A/D instead of W/S). No lag at all in Counter-Strike. You don't see it in the video, but I can do the tiniest sidesteps and it's still responsive, so I don't think anything gets eaten between intervals

https://www.youtube.com/watch?v=500BciVal5Y
Post Reply

Return to “FreePIE”