W3C home > Mailing lists > Public > public-audio-dev@w3.org > December 2015

Re: Web MIDI Synths

From: James Ingram <j.ingram@netcologne.de>
Date: Tue, 1 Dec 2015 12:32:51 +0100
To: Chris Wilson <cwilso@google.com>
Cc: "public-audio-dev@w3.org" <public-audio-dev@w3.org>
Message-ID: <565D8563.90402@netcologne.de>

> I'd like to just encourage people to discuss it here (or, preferably, 
> in the GH issue on virtual synths)
Shall we move there? I think it might be better to stay here until my 
software has stabilised a bit more. Then we'll have ironed out the 
teething troubles.
> I think it's a fantastically bad idea to redo a standardized albeit 
> slightly goofy mechanism just to make it simpler
I knew that I was doing something risky in defining a separate layer for 
custom controls, and now see that it was indeed a mistake. A clear case 
of brain overload... It would be better if software synths always react 
to ordinary MIDI control messages (so that they can always be controlled 
easily by standard MIDI hardware). In my defence, I should say that the 
host is a layer between the hardware and the synth, so the host could 
adapt incoming messages. But that means that hosts would always have to 
do unnecessary work. Fortunately, the correction isn't very difficult to 
make. I'll do it as soon as I've finished this mail.
> Granted, I remap some [CCs]:
> CC1 ("mod wheel"): controls filter modulation amount
> CC2 ("breath controller"): controls filter cutoff
> CC7 ("volume") and CC11 ("expression"): controls filter Q
> CC5 ("portamento time"), CC15 ("undefined") and CC73 ("sound attack 
> time"): controls overdrive
> ... and so on.  (Full list visible at 
> https://github.com/cwilso/midi-synth/blob/master/js/synth.js#L150-L204.)
> In short, I set up CCs based on what my available keyboards that I 
> would likely demo on (e.g. my Alesis Vortex), rather than have a whole 
> separate mapping layer. I'm not personally convinced you CAN come up 
> with an exhaustive list of "standard" CCs, since many of the MIDI ones 
> don't even apply for a lot of synthesizers (e.g. the aforementioned 
> "portamento time").
Agreed. I'm not convinced either.

But I still think that a controls declaration is a MUST.
Think of it like this: The synth can't have a GUI because the GUI is the 
responsibility of the host app. Different host applications have 
different GUIs. One of the possible GUIs looks like your original one, 
with control labels, knobs and buttons, keyboard etc., and the synth's 
API has to enable the host to re-create a GUI like that. The synth's API 
is a non-graphical version of a GUI, that the host app can use as it 
thinks fit.

I think that means that the controls declaration has to contain objects 
like those I defined for custom controls:
(e.g. { name: "osc1 detune", index: 6, defaultValue: 64 } ). Obviously, 
synth programmers would do well to map their controls as closely as 
possible to the standard MIDI ones (as you did), but I see no way to 
legislate on what "close" means.
There are (at least) two types of control in your original GUI: 
continuous controllers (knobs) and pop-up menus (for controlling 
waveforms). I can't think of anything really equivalent to a pop-up menu 
in standard MIDI, but the problem could be solved by defining a control 
like this:
{ name: "osc1 waveform", index: 19, defaultValue: "sawtooth", items: 
"sine, square, triangle, sawtooth" }
That would define CC19 to be a control that accepts values 0, 1, 2 and 
3, with default value 3. Attempting to set a value greater than 3 would 
be an error.
I think we need to define a standard form for each GUI control type. 
There aren't very many of them, so that shouldn't be too difficult.

Note that default values are those that are set when the synth gets an 
"all controllers off" message:
{ name: "all controllers off", index: 121 }  or { name: "reset", index: 
Should all synths *always* implement standard MIDI CC121 to mean "reset 
all controllers to their default values"? I currently think this comes 
under the heading of recommending that programmers map their controls as 
closely as possible to the standard MIDI ones. One can recommend that 
programmers implement this control, but not insist.

Since we are now allowing standard MIDI CCs to be overridden, I think 
its quite legitimate to do the following:
{ name: "pitchwheel deviation", index 42, defaultValue: 2 }
(42 being arbitrarily chosen here).

> Throwing exceptions is a nuclear option.
Error handling is a bit of a red herring. Its an implementation detail, 
not part of the API we are trying to define. Again, I think its a 
question of who is responsible for the GUI, and I think the GUI is the 
host's responsibility, not the synth's. If the synth throws an 
exception, the host can decide what to do with it, depending on the 
host's requirements. The host can choose to ignore the exception, put up 
an alert, send the synth an alternative message etc. If the synth 
decides to handle the error itself (e.g. by ignoring it), then the host 
has no choice. The synth has no way of knowing what the host might want 
to do, so it should throw an exception.

Issue #110 <https://github.com/WebAudio/web-midi-api/issues/110>
> Note that supporting GM instruments does not mean that the whole MIDI 
> standard is implemented.
> The whole MIDI standard meaning CC list, or the whole GM standard 
> (defined set of CCs, sounds, etc)?  Because if you say you "support 
> GM", I'm pretty sure you need to support all of GM.
In *software* synths, I think its important to keep load times down, and 
only to load the presets (and preset samples) that one actually needs. 
Of course, one can load a soundfont containing a complete GM sound set, 
but its going to take a long time. I think the question could be 
rephrased to make the answer more informative. Maybe "Can this software 
synth play GM presets?" and if the answer is yes "Can it play preset 
17?" etc. The situation is very different for hardware synths.


I think we are getting somewhere. Many thanks! :-)
As I said, I'm now going to get rid of the custom controls layer.

Received on Tuesday, 1 December 2015 11:33:31 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 19:03:55 UTC