notator / WebMIDISynthHost

Hosts software Web MIDI Synths that implement a superset of the Web MIDI API Output Device interface.
Other
18 stars 3 forks source link

Setting pitchWheel deviation #9

Closed notator closed 7 years ago

notator commented 8 years ago

Unless I'm mistaken, setting the pitchwheel deviation requires manipulation of REGISTERED_PARAMETER controls on hardware synths. It would be much simpler, especially on software synths, simply to define a new controller for the purpose. This was the approach adopted by gree for their synthesizer, and I have adopted it here. I have provided a utility function (in WebMIDI/utilities.js) that could be used when both hard- and software synths are in use. There is also an extended comment on the subject in that file. Is this okay?

notator commented 8 years ago

I've added PITCHWHEEL_DEVIATION constants to WebMIDI.constants.CONTROL and WebMIDI.constants.DEFAULT. WebMIDI.constants apply only to (software) WebMIDISynths, many of which will want to define function setPitchWheelDeviation(deviation) I think this control should have a standard CC value for all WebMIDISynths, and have assigned it to CC9, which is not used in the MIDI standard for hardware devices. The utility function, mentioned above, is still there for interoperability with hardware devices.

notator commented 7 years ago

While programming the solution to https://github.com/notator/Moritz/issues/2, I have decided to make the API for my WebMIDISynths exactly the same as for hardware MIDI devices. This means that setting the pitchWheel (semitone and cent) deviation should be done by sending a sequence of four MIDI messages:

<msg status="0xB0", data1="0x65", data2="0" /> // data1 is CTL_REGISTERED_PARAMETER_COARSE
<msg status="0xB0", data1="0x64", data2="0" /> // data1 is CTL_REGISTERED_PARAMETER_FINE
<msg status="0xB0", data1="0x06", data2="2" /> // data1 is CTL_DATA_ENTRY_COARSE, data2 is semitones
<msg status="0xB0", data1="0x26", data2="0" /> // data1 is CTL_DATA_ENTRY_FINE, data2 is cents

These messages all have: a) identical status bytes (0xB0 + channel) b) data1 values identical to those given here, The first two messages have data2 set to 0 (to select CTL_DATA_ENTRY_COARSE and CTL_DATA_ENTRY_FINE). The data2 byte in the third message sets the semitones component of the deviation. The data2 byte in the fourth message sets the cents component of the deviation.

The above messages set the pitchWheel deviation to its default value: 2 semitones, 0 cents.

WebMIDISynths, whose pitchWheel (semitone and cent) deviation can be set, must therefore implement the four controls: CTL_REGISTERED_PARAMETER_COARSE (=0x65, =101) CTL_REGISTERED_PARAMETER_FINE (=0x64, =100) CTL_DATA_ENTRY_COARSE (=0x06, =6) CTL_DATA_ENTRY_FINE (=0x26, =38)

Moritz only sets the deviation in semitones, so will (I think) only send two messages:

<msg status="0xB0", data1="0x65", data2="0" /> // data1 is CTL_REGISTERED_PARAMETER_COARSE
<msg status="0xB0", data1="0x06", data2="2" /> // data1 is CTL_DATA_ENTRY_COARSE, data2 is semitones

This issue must be addressed when https://github.com/notator/Moritz/issues/2 has been solved.

notator commented 7 years ago

This issue has now been resolved. If a WebMIDISynth can change its pitchWheelDeviation, then the control sequence for doing that is the same as for standard hardware MIDI synthesizers.

As with other synths, setting the FINE (cents) deviation is not really necessary here, and my WebMIDISynths don't use CTL_REGISTERED_PARAMETERs for anything else, so they ignore the FINE settings (CTL_REGISTERED_PARAMETER_FINE and CTL_DATA_ENTRY_FINE) altogether. Note that setting a WebMIDISynth's CTL_REGISTERED_PARAMETER_COARSE value to something other than 0 will stop the CTL_DATA_ENTRY_COARSE value from being used correctly to set the pitchWheelDeviation. This ensures that WebMIDISynths react correctly to arbitrary MIDI input.