A WebMIDI editor for XG MIDI devices
The idea here is to build a single page web app that lets you edit all the hidden parameters of Yamahas XG standard. On most devices, you can change a handful of parameters like filter cutoff frequency and attack and release, but you can't edit LFO, or reverb details, for example.
BTW, this screen was sent to my by todays sponsor, Elecrow. This is a 1280 by 400 pixel IPS touch screen that registers as a USB mouse. It solidly built, sharp and bright, can mount a Raspberry PI on its back, or can be mounted on a tripo, and its the perfect fit for DIY projects and I'll certainly find good use for it on this channel. Please take a look at their web page as they have plenty of different panels in all sizes, resolution and price ranges, and look, they recently celebrated their tenth birthday! Hooray!
Single Page Web App means this is one HTML file you can load into your browser and all the designs, UI elements and scripts are in that one file, there's nothing else that needs to be loaded.
Webmidi has been around for some years, and with the exception of Safari, all the major browsers support it.
Ok, so here I'm in Visual Studio Code, and I've installed an HTML preview plugin so I can see my work in real time.
My idea here is to create a form that is divided into multiple fieldsets. Each fieldset contains a group of range sliders that belong to a certain set of related parameters.
First, I'll create some select boxes for the MIDI input and output devices connected to your computer.
Now, let's format these elements. It's always a good idea to define a set of colours, so you can change them easily later.
I've arranged my input sliders as lists, so lets format these accordingly.
Add some color gradients to the fieldsets to make them more distinct.
Now, let's do some copy and paste coding. Head over to MDN and lookup webmidi. Copy all the example scripts there into a script tag at the very bottom of the page.
Let's qickly load the page into a browser and we can see it's asking for MIDI permission now.
Right! Now let's add our MIDI devices to the select menu. Again, copy the example code from MDN and modify it so it doesn't print them to the console, but creates options in our select boxes. The options will display the name of the MIDI interface and contain their ID as a value.
Let's add a new fieldset now. This will contain two range sliders for changing filter cutoff frequency and resonance.
The ranger slider can have a value and a maximum value, which will be 127, according to the MIDI standard. I'll also name all my sliders cc _ cc number, which will come in handy later.
Now let's add some CSS to make the sliders stand vertical and touch-friendly.
Next, I'll add and eventhandler to all sliders. The event handler will be attached on midi success and will listen to slider movements. Due to my naming convention, it's easy to determine the kind of midi command and its number by looking up the sliders name. For example, the first slider for cutoff frequency is named cc_74, so my script knows that it's a CC command and it's number is 74.
Now, all we need to do is to send the CC value to our synthesizer. So once again, copy and paste the note send command from the MDN page to our script, but we'll need to tweak it a bit. We need to add the midi port id, cc number and value as parameters, and then change the message number from hexadecimal 90 to b0.
Now replace the console log command with that command.
Also add some lines that determine the active midi port and the cc number and value, and then replace the console log command with the midi send command, and we have a working filter control. Nice!
Now, we can easily add more CC sliders. Luckily, I found this web page which has all the information needed.
I encountered a small roadblock when working on the amp envelope controls. Attack and release have their own cc numbers, but decay is handled by so called NRPNs or "non-registered paramter numbers".
These allowed companies to include controls outside of the XG standard if they wanted to.
This works by sending 3 consecutive CC commands, the so called most signigicant bit or MSB, on CC 99, first, then the so called least significant bit, or LSB, on CC 98 next, and after that, you send the actual value of CC 6.
Let's take a look at how this works on decay time.
The documentation tells us that the MSB is 1 and the LSB is 64 here.
The range of possible values is from 0 to 127.
Now I'll add a new slider with a range from 0 to 127 and name it nprn_decay.
In my code, I can now set up a switch that reacts to the nprn names I specified, and then create an array containing the MSB and LSB: 1 and 64.
I then need to issue three consecutive CC commands: CC 99 with a value of 1, CC 98 with a value of 64 and CC6 with the value specified by the user operating the slider.
Nice!
Lastly, let's take a look at how to handle SysEx commands. These are mostly used for setting up the effects.
A sysex command is a couple of bytes you transfer to your synth. It always begins with hexadecimal F0 and always ends with F7. The second byte is always the vendor id, in this case 43 for Yamaha.
Here you can see that we can set up our reverb algorithm using the seventh and eighth byte in a sysex command. The 7th byte specifies what we're changing and the 8th byte specifies the value.
Knowing that, we can add some more range sliders to our app. As I'm lazy, I'll name each slider exactly like the sysex command it's going to issue, and just search for the XX string and replace it with the slider value.
Then just split the name into an array and send it to the synth.
And that's all we need to know to finish the editor. In the time I had for making this video, I managed to create this editor for reverb parameters.
All that's left to do is to make sure the document doesn't move when operating the sliders, which is easily done with some CSS instructions.
And here it is, my yet unfinished, but functional webmidi based, touch screen operated MIDI controller.
I've put this onto GitHub and if you feel so inclined, please add more functionality to it.