|
Post by Ben G on Sept 24, 2018 1:48:40 GMT
I have a Behringer X-Touch Mini (XTM) MIDI Controller. They don't have an editor for this that works on Mac (in 2018 — weird). So I'm trying to use MidiFire to really bring out the power in this controller for controlling soft synths on my iPad (many of which don't have MIDI Learn feature and all the CC are hardcoded).
So far I figured out how to remap the encoder knobs on the XTM to various parameters on the Arp Odyssei on my iPad in StreamByter, like so:
BX 03 = XX 52
remaps encoder #3 (which is CC3) to CC82 which is "VCO1 Coarse" adjustment on the Odyssei. Great!
ISSUE 1:
However, I am running into an issue where if I adjust this parameter on the iPad screen, and then with the hardware encoder, it "jumps" to the encoder value instead of starting where the Odyssei control is already set on screen and incrementing from there (I got a MIDI controller with encoders instead of pots specifically to avoid this issue).
I'm not sure if this is a limitation with Odyssei that can't be fixed or if I can can use StreamByter to fix it?
Basically, I think I need to send some sort of MIDI message that is equivalent to "increase/decrease the current value by N" instead of "change the current value to X".
ISSUE 2:
There are lots of buttons on the XTM which are factory set to send Note On and Note Off messages. For example, when I hit the button directly below encoder #1, the Event Monitor shows:
CH:11 Note On A♭-2 Vel:127 CH:11 Note On A♭-2 Vel:127 CH:11 Note Off A♭-2 Rel:000 CH:11 Note Off A♭-2 Rel:000
(I have no idea why it's doubled since I only hit the button once).
I would like to remap these to send messages to turn various synth parameters On/Off. For example, "VCO1 FM1 Source" is CC35 and has two values of LFO Sine and LFO Square. If I could hit the aforementioned button to toggle between LFO Sine and LFO Square that would be awesome!
ISSUE 3:
This is really obscure (and possibly a wild dream)...
(let's hypothetically ignore the use case presented in Issue #2 for a moment...)
Could I use the button below encoder #1 as a SHIFT button, so that when I hold it down and turn encoder #1, the encoder sends a totally different MIDI message?
So I suppose it would be something like (in pseudo code)
WHILE "CH:11 Note On A ♭-2 Vel:127" IF RECEIVE "CH:11 Ctl Num:1 Val:X" THEN SEND "CH:11 Ctl Num:24 Val:X"
UNTIL "CH:11 Note Off A ♭-2 Rel:000"
(so it would remap CC1 received with SHIFT pressed to CC36)
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Sept 24, 2018 9:06:40 GMT
Hi Ben,
ISSUE 1
Is a little bit tricky and depends upon Odyssei's MIDI implementation. If Odyssei *transmits* the value of a control as you change it on the iPad (it's probably unlikely, but worth checking with an Event Monitor), then you can just feed that event into the XTM. Essentially you need bi-directional communication. Alternatively, if Odyssei's MIDI implementation includes a parameter increment/decrement control, then you could indeed change the Stream Byter to send inc/dec messages as you rotate the XTM encoder. Suggest you investigate whether Odyssei has either of these in its MIDI implementation and then get back to me if either are supported.
ISSUE 2
So, we can indeed make the note event a toggle but if the XTM is really sending double then we have to add extra logic to detect this or it will toggle twice on each press.
Here is how it is done:
IF LOAD # L0 = note on count, L1 = current toggle ASS L0 = 0 0 END 9X XX 00 = 8X # remap note on/vel0 to note off IF M1 == 08 # possibly our Ab-2 note IF MT == 90 # Ab-2 note ON MAT L0 = L0 + 1 # inc instance count END IF MT == 80 # Ab-2 note OFF MAT L0 = L0 - 1 # dec instance count
IF L0 == 0 # toggle on final note off only # example code, toggle CC64 on channel 0 MAT L1 = L1 ^ 7F SND B0 40 L1 END END END
ISSUE 3
Yes, you can setup a SHIFT function as follows:
IF LOAD ASS L0 = 0 # shift flag END
# shift on/off with CC 08 IF M0 == B0 08 7F ASS L0 = 1 # mark shift as on END IF M0 == B0 08 00 ASS L0 = 0 # mark shift as off END
# remap CCs if shift is on IF L0 == 1 # example remap CC64 to 66 if shifted B0 40 = XX 42 # ... other logic for when shift is on END
Regards, Nic.
|
|
beng
Converser
Posts: 11
|
Post by beng on Sept 24, 2018 23:38:37 GMT
Thanks Nic! This looks awesome. I'll give it a shot over the next few days and let you know how it goes.
Regarding Issue #1, after I looked into it more, this type of MIDI control does seem to be somewhat non-standard. Apparently the receiving app has to be specifically coded to increment/decrement from the current position based on detecting rising or falling control messages (0-127 -- I could have the terminology all wrong here, but I hope you understand) and from what I've read, this type of feature is basically only found in Desktop DAWs. I certainly haven't found this type of feature in any of my many iPad soft synths yet.
It also would seem like a second option would be to set the encoder values to a certain starting position via MIDI Receive, but the XTM doesn't support this. I'm a totally newbie to MIDI, but it seems that having no MIDI Receive capability to set the values of the encoders in the XTM basically negates the entire reason for using encoders (vs fixed pots) in the first place? I'm still trying to figure out what the advantage of encoders is on the XTM, since it appears that the encoders basically still have "fixed" positions, it's just that the knobs are able to rotate a lot more than a fixed pot (so I guess I get more fine-grained control).
But again, I could just be screwing this all up because I don't know what I'm doing :-)
|
|
beng
Converser
Posts: 11
|
Post by beng on Sept 24, 2018 23:47:34 GMT
|
|
beng
Converser
Posts: 11
|
Post by beng on Sept 25, 2018 2:12:15 GMT
Well after further investigation it seems like what I want to do is theoretically totally possible (and desired by many), just not with the XTM (because there's no MIDI RX to set the initial encoder values) or for the other option, not with any iPad softsynths because to my knowledge none of them support a "relative" MIDI mode for controling the knobs and sliders. So no matter what I do, there seems to be no way to tweak iPad softsynths with a hardware controller without having the values jump when the hardware knob is initially turned.
I would love to be proved wrong! I'm kind of in disbelief that something so obvious would be impossible -- It seems like absolutely zero people would want the software values to jump out of place when using a hardware controller.
I'm hoping I can eventually build my own MIDI hardware controller using Teensy or Arduino, and that it could be designed to accept MIDI RX (from MidiFire) to set the initial encoder values to whatever is saved on my softsynths presets... even if I have to hard code the CC for various synth settings in MidiFire and load/initialize it from there (since many softsynths don't even have MIDI OUT).
Any idea if this is doable, or a pipe dream?
|
|
beng
Converser
Posts: 11
|
Post by beng on Sept 25, 2018 2:14:23 GMT
Oops I meant "there seems to be no way to tweak iPad softsynths with THIS hardware controller without"...
|
|
beng
Converser
Posts: 11
|
Post by beng on Sept 25, 2018 2:43:26 GMT
Further thoughts: maybe this is possible in MidiFire with the XTM now? I'm thinking: I could map the softsynths preset values in MidiFire somehow, for the various CC's. Using my previous example for the Odyssei, for example: CC82 = VCO1 Coarse Adjust CC83 = VCO1 Fine Adjust CC36 = VCO1 FM1 Depth1 CC39 = VCO1 FM2 Depth2 CC40 = VCO1 PW CC42 = VCO1 PW Mod (let’s just use these 6 CCs to get started — if this idea is legit, and you give me some example code, I think I can expand it further on my own) So let’s say I come up with a nice preset on the iOdyssei where these parameters have the following values: CC82=5 CC83=67 CC36=127 CC39=40 CC40=71 CC42=39 Is there some way to set this up in MidiFire? So instead of loading the preset inside iOdyssei itself, I could “load” it via MidiFire by just sending the initial CC values to iOdyssei? (in reality I would probably have to load the preset it in both places, since a few of the parameters in iOdyssei aren’t mapped to any CC like “Detune”). Then, MidiFire could be set so that incoming MIDI from the XTM in Relative mode would translate the relative values into absolute values that correspond to the “loaded” preset (which it seems Relative1 sends values of 1-7 when turned clockwise, and values of 123-127 when turned counter-clockwise, depending on the speed of the encoder turn -- 1 is a slow turn, 4 is moderate speed, 7 is super quick). For example, let’s say I have the XTM encoder #1 set up to send CC82. Since MidiFire has already loaded the preset and “knows” that CC82 is set to 5, when it receives a “slow clockwise” relative value of 1, it could send an absolute CC message of 6? and if it receives "super quick clockwise" 7, it could translate to 12 (5+7), etc? Then MidiFire could keep track of these changes, so that when CC82 is changed to value 12 with one super quick clockwise knob turn, it would re-save the value as 12. Then on the next slow clockwise turn it would increment it +1 to 13? Man if this could work, I will be HIGHLY impressed! If this is just wishful thinking... sorry to bug ya with my fantasies
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Sept 25, 2018 13:34:13 GMT
Hi beng , Yeah, you could configure Stream Byter to initialise the softsynth to certain values (so it knows what the current values are) and then add a bit of logic so that turning the CC has no effect until it goes past the current value in which case it would then spring into action - essentially a positive 'pick up' affair. Here's some example code that could do this for CC's 82 and 83. IF LOAD # initialise/retain CC 82 and 83 # we use array 'L' as a lookup # table of current CC values ASS L52 = 20 30 +P END
# 'pick up' CC's passing thru IF M0 == B0 # block CC if current preserved # value is less than CC value IF LM1 < M2 XX = XX +B END
# if CC value is > than preserved # do not block and update the value IF LM1 > M2 ASS LM1 M2 END ENDThis is a bit basic in that you need to make sure the encoder starts with a value below the currently preserved value. It could be possible to adjust the logic to detect whether you are sweeping the encoder up or down and reverse the logic. I will leave that as an exercise. :-) However, maybe a better approach would be to forego the 'pick up' logic entirely and connect the Stream Byter output to the XTM input so that the CC values when initialized get sent to the XTM and it should adjust the encoders to the correct value (same value as sent to the soft synth) Regards, Nic.
|
|
beng
Converser
Posts: 11
|
Post by beng on Sept 27, 2018 0:33:43 GMT
Thanks again! I will try all of this later today. One comment:
"However, maybe a better approach would be to forego the 'pick up' logic entirely and connect the Stream Byter output to the XTM input so that the CC values when initialized get sent to the XTM and it should adjust the encoders to the correct value (same value as sent to the soft synth)"
Do you mean the XTM input within MidiFire? Or the actual hardware XTM? Because the hardware can't receive any MIDI except to set the status of the LED lights on the encoders (which is dumb, and seems like a huge oversight to not be able to initialize the starting values of the encoders... basically makes it useless).
|
|
beng
Converser
Posts: 11
|
Post by beng on Sept 27, 2018 1:31:14 GMT
Also, do you have any particular MIDI programming tutorials that you recommend? I've read the "Understanding the MidiBridge Stream Byter" page, but this still all looks like Greek to me... I would like to understand it better, and I know I need to learn MIDI programming anyway if I'm going to eventually build my own hardware. I learn best by looking at example code and generous explanations of what's going on, rather than by dry technical specs, if that helps. Much thanks!
Ben
|
|
beng
Converser
Posts: 11
|
Post by beng on Sept 27, 2018 4:24:07 GMT
I've been messing around with this for over an hour and can't get the SHIFT code to work. Here's what I changed it to:
# BX 01 = XX 52
IF LOAD ASS L0 = 0 # shift flag END
# shift on/off with CC 08 IF M0 == BX 08 7F ASS L0 = 1 # mark shift as on END IF M0 == BX 08 00 ASS L0 = 0 # mark shift as off END
# remap CCs if shift is on IF L0 == 1 BX 01 = XX 52 END
I changed one of the buttons on the XTM to CC 08 (borrowed my gf's PC to use the XTM hardware editor). When I press and hold the button, I see "CH:11 Ctl Num:8 Val:127" in StreamByter. When I release the button I see "CH:11 Ctl Num:8 Val:0" (FYI, it's no longer sending double messages as I noted in my first post) — it seems to me that the line IF M0 == BX 08 7F should capture this because it's basically saying "if the message byte 0 is CC08, Value 127, on any incoming channel, then assign the variable L0 a value of 1". Right? Then towards the end of the code, IF L0 == 1, then map CC 01 to CC 82. But I'm not seeing any change when I hold down the shift button and tweak Encoder #1 which is sending out CC 01 (in SB "CH:11 Ctl Num:1 Val:42" for example). However, if I uncomment the very first line of the code, I do see a change... so I'm not sure where it's failing.
|
|
beng
Converser
Posts: 11
|
Post by beng on Sept 27, 2018 4:38:45 GMT
Got it!
I had to change all of the BX to BA since the XTM is sending on CH 11. I thought BX would capture incoming data from any channel, but I guess not?
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Sept 27, 2018 8:52:13 GMT
Hi beng , > Do you mean the XTM input within MidiFire? Or the actual hardware XTM? Because the hardware can't receive any MIDI except to set the status of the LED lights on the encoders (which is dumb, and seems like a huge oversight to not be able to initialize the starting values of the encoders... basically makes it useless). I mean the actual hardware XTM via the MIDI destination/output on MidiFire. If that only sets the LED and not the encoder position then that is pretty useless. Are you sure about this? > Also, do you have any particular MIDI programming tutorials that you recommend? I've read the "Understanding the MidiBridge Stream Byter" page, but this still all looks like Greek to me... I would like to understand it better, and I know I need to learn MIDI programming anyway if I'm going to eventually build my own hardware. I learn best by looking at example code and generous explanations of what's going on, rather than by dry technical specs, if that helps. Much thanks! If even the basic tutorial is all greek, maybe you might need to brush up a little on the MIDI messages themselves. If you understand how these work, then all that Stream Byter stuff makes much more sense. The Stream Byter language is designed around working with MIDI events. The best spec. I have found for MIDI that I use all the time is somascape - yes, it is a reference but really well presented. > I had to change all of the BX to BA since the XTM is sending on CH 11. I thought BX would capture incoming data from any channel, but I guess not? That *should* have given you an error as you cannot use wildcards in an IF statement; X wildcards are only relevant to a pattern/rewrite rule - <pattern> = <rewrite>, also referred to as Stream Byter I rules. Regards, Nic.
|
|
beng
Converser
Posts: 11
|
Post by beng on Sept 27, 2018 9:05:46 GMT
|
|
nic
Soapbox Supremo
Troublemaker
Press any key to continue
Posts: 2,011
|
Post by nic on Sept 27, 2018 9:26:44 GMT
Ouch! Seems like a very basic feature to me if they are encoder type knobs.
|
|