Iāve gathered some specific SysEx message examples for controlling Yamaha FB01. It has become a bit of a long post but I wanted to try and be thorough.
These examples are specific to Yamaha FB01 which seems to have a fairly weird MIDI implementation. Iāve imagined how some simple Pipes could potentially be implemented as well.
First, some easy examples, where a SysEx Command ID number and Parameter Value maps directly to a single Device Parameter.
Each message uses the following pattern (below). The symbol _ preceding a letter represents a number that needs to be configurable but can be static, * preceding a letter represents a number that is dynamic and would be mapped from a CC, for example but any incoming value as long as it has been filtered/translated accordingly first. Iāve made these bold in the examples because they are really the only thing that needs to change from one message to the next once the Pipe has been configured.
Numbers preceded by x are in hexadecimal and padded with a leading 0.
i.e. x0F == 15, xF0 == 240
xF0 [ Start ]
_M [ Manufacturer ID ]
x75 [ Sub Status ]
_S [ System Channel Number ]
_I [ Instrument ID ]
_C [ Command ID ]
*V [ Parameter Value ]
xF7 [ End ]
So for example the Command ID for setting Polyphony is x00. A message formed with the following bytes would change Instrument 1 Polyphony to 8:
xF0 x43 x75 x00 x18 x00 x08 xF7
The following would set Instrument 3 polyphony to 1:
xF0 x43 x75 x00 x1A x00 x01 xF7
The Parameter Value can be mapped directly from the CC number, assuming the CC number can be clamped to a certain range, 1 - 8 for example here. Range Filter looks like it would achieve that.
Something to note about the Instrument ID here is that it is actually calculated from Instrument Id + 23. Who knows why? In an ideal world we would be able to set Instrument ID as 1, 2, 3 for example have Midi Hub figure out what the numbers to be sent are (18, 19, 1A) combined number is but for now a single user configurable value would suffice. Of course it would be fun to be able to control at least Instrument ID as well even if that is within a predefined offset range.
So far so simple, here are some other easy examples.
LFO On/Off Command ID is x0A. For some reason On is 0 and Off is 1ā¦ Some way of mapping a CC to the appropriate value here would be good.
Set Instrument 1 LFO On:
xF0 x43 x75 x00 x18 x0A x00 xF7
Set Instrument 1 LFO Off:
xF0 x43 x75 x00 x18 x0A x01 xF7
Examples for Octave Transpose, which is Command ID x07.
The range is from -2 to +2, each of the values is sent as 0 to 4. Straight mapping of CC to value with the Range Filter seems fine here.
Set Instrument 1 Octave Transpose to -2 (minimum value):
xF0 x43 x75 x00 x18 x07 x00 xF7
Set Instrument 1 Octave Transpose to 0:
xF0 x43 x75 x00 x18 x07 x02 xF7
Set Instrument 1 Octave Transpose to +2 (maximum value):
xF0 x43 x75 x00 x18 x07 x04 xF7
Potential Pipe Idea
A simple Pipe implementation that would facilitate the above message style in is described below. I havenāt explored the Hub Editor very thoroughly but I think this would be achievable.
The Pipe would alow definition of the message structure and take a single incoming value. Start and End of SysEx messge will never change so they could be appended automatically. By having the message structure configurable it will support any given Manufacturer ID etc.
For example letās Name the Property in the Pipe āSysEx Bytesā and the Value would be a text box allowing entry of comma separated list.
The example of setting Instrument 1 Polyphony would look like this; 67, 117, 0, 24, 0
SysEx Bytes: 67, 117, 0, 24, 0
Those decimals are the same as the hex in the example (x43, x75, x00, x18, x00
), some syntax for optionally handling hex numbers in the Property Value field would be nice here.
The incoming value would be used to form the final byte before the SysEx end byte, so the same example would look like this (input -> [output array]
)
8 -> [240, 67, 117, 0, 24, 0, 7, 247]
Hopefully what Iāve written so far makes sense, Below Iāll describe some of the more difficult cases.
For the most part, a similar Pipe implementation as described above would work, with some additional configuration for the Paramater Value Bytes.
This time there are two Parameter Value bytes that are sent, the SysEx structure looks as follows.
xF0 [ Start ]
_M [ Manufacturer ID ]
x75 [ Sub Status ]
_S [ System Channel Number ]
_I [ Instrument ID ]
_C [ Command ID ]
*V [ Parameter Value Low ]
*V [ Parameter Value High ]
xF7 [ End ]
First, a simple example, all on Instrument 1, controlling LFO Speed which is Command ID x48. The actual Command ID as listed in the manual x0C but it needs to be offset when sending as SysEx, I think itās reasonable for the user to specify the offset value rather than require Midi Hub to work this out as things are likely complicated enough already.
Set LFO Speed to 1:
xF0 x43 x75 x00 x18 x48 x01 x00 xF7
Set LFO Speed to 5:
xF0 x43 x75 x00 x18 x48 x05 x00 xF7
Set LFO Speed to 16:
xF0 x43 x75 x00 x18 x48 x00 x01 xF7
Set LFO Speed to 32:
xF0 x43 x75 x00 x18 x48 x00 x02 xF7
Set LFO Speed to 123:
xF0 x43 x75 x00 x18 x48 x0B x07 xF7
Set LFO Speed to 128:
xF0 x43 x75 x00 x18 x48 x00 x08 xF7
Set LFO Speed to 255:
xF0 x43 x75 x00 x18 x48 x0F x0F xF7
For each of the above, the following bitwise operations are used, where parameterValue
is the LFO Speed
Parameter Value Low; parameterValue & 15
Parameter Value High; parameterValue >> 4
Potential Pipe Idea
The Pipe implementation for this could look similar to the previous implementation example with an additional two Properties āData Low Functionā and āData High Functionā where the Value would be a text box where the bitwise operations can be defined.
For the two Parameter Values above a Pipe would have the following Properties (values are in decimal);
SysEx Bytes: 67, 117, 0, 24, 72
Data High Function: & 15
Data High Function: >> 4
or as hexadecimal
SysEx Bytes: x43, x75, x00, x18, x48
Data High Function: & x0F
Data High Function: >> x04
Results for the examples as defined above (input -> [output array]
)
1 ā [240, 67, 117, 0, 24, 72, 1, 0, 247]
5 ā [240, 67, 117, 0, 24, 72, 5, 0, 247]
16 ā [240, 67, 117, 0, 24, 72, 0, 1, 247]
32 ā [240, 67, 117, 0, 24, 72, 0, 2, 247]
123 ā [240, 67, 117, 0, 24, 72, 11, 7, 247]
128 ā [240, 67, 117, 0, 24, 72, 0, 8, 247]
255 ā [240, 67, 117, 0, 24, 72, 15, 15, 247]
Iām wondering if some syntax in the āSysEx Bytesā property to express that the bytes refer to another Property in the Pipe might be useful. For example if in one of the above we wanted to change the Instrument ID byte the Properties in the Pipe might look like this. It would mean the Pipe needs to take multiple input values (referred to as arguments below).
SysEx Bytes: 67, 117, 0, 24, {Instrument ID}, {Data Low}, {Data High}
Data Low: {$argument1} & 15
Data High: {$argument1} >> 4
Instrument ID: {$argument2}
This would look something like this in practice
123, 72 ā [240, 67, 117, 0, 24, 72, 11, 7, 247]
OK probably not so difficult after allā¦ so far! The Command for controlling LFO Speed maps directly from a single Device Parameter so itās actually straightforward.
There are also what Iāll call a ācompoundā commands, which map a Command Parameter Value from two or more Device Parameters sent as a single message with one Command ID.
An example of a compound command is one relating to Feedback Level and Algorithm Number. In this case both parameter values are combined and then split again into the Value Low and Value High before being sent with the Command ID of the compound command.
There would need to be a way of keeping track of the ālast sent parameter valuesā because the Low and High bytes for changing the Feedback Level with Algorithm 1 set will be different to bytes for changing Feedback Level with Algorithm 5 set.
I will try to add some examples of this too. Perhaps youāre already familiar with the problem and something like the proposed DX7 interface pipe would already cover it at least the tracking of the values. Could you describe a bit more detail of what youāre thinking with the interface pipe? Iām not familiar with DX7 SysEx and would hope itās not as crazy as FB01 but I would not be too surprised if it was!
Potential Pipe Idea
Another Pipe that would be useful is one that just sends a pre defined SysEx message. For example you could store a list of the bytes that make up the message in the Pipe and have it after some Pipes that filter out channel, program message or CC number for example, the sent message need not have any dynamic content at all. This would be the most simple way of providing at least some basic SysEx control.