musikinformatik / SuperDirt

Tidal Audio Engine
GNU General Public License v2.0
520 stars 74 forks source link

Multiple midi commands in one message #157

Closed yaxu closed 4 years ago

yaxu commented 4 years ago

There is logic to infer midi command from the values in a message. I think this could be used to allow more than one midi command in one message.

telephon commented 4 years ago

Yes, possible in principle.

yaxu commented 4 years ago

I've had a look and see one problem - how to tell whether a noteon should be sent? Currently one is sent if nothing else is done, but it would be nice to be able to e.g. send a control message and a noteon at once, or just send a control message.

The midinote comes from freq which I think is set to middle c by default. I can't see a way of telling if that's been set from tidal. If it hasn't, I think no note should be played.

telephon commented 4 years ago

Ok, so the default should be nil. I'll take a look.

yaxu commented 4 years ago

Yes although I think synths / samples should still default to 0 at some point, if there is a (non-midi) sound set.

telephon commented 4 years ago

yes, it is using the same event hierarchy, so you can use note, freq or whatever:

            ~n = 0; // sample number or note
            ~octave = 5;
            ~midinote = #{ ~note ? ~n + (~octave * 12) };
            ~freq = #{ ~midinote.value.midicps };

we'd have to check for each of these keys for notNil:

midinote, freq, n, octave

and remember in the future if we add any other kind of logic.

I'm not so familiar with the MIDI-world, if there are any other frequency related commands.

yaxu commented 4 years ago

Here's a go: https://github.com/musikinformatik/SuperDirt/pull/159

However, hasNote is always true:

hasNote = (not (~midinote.isNil && ~freq.isNil && ~n.isNil && ~octave.isNil));
yaxu commented 4 years ago

Indeed with no parameters set, [~midinote, ~freq, ~n, ~octave].postln gives [ a Function, 261.6255653006, 0, 5 ]

telephon commented 4 years ago

Yes, there are defaults in the event (see Classes/DirtOrbit.sc). Hm, we'll have to try and find a solution that is not just a band-aid.

telephon commented 4 years ago

Just one possibility: maybe send something from tidal that signals that no note is intended?

yaxu commented 4 years ago

I could get tidal to send something if midinote, freq, n or octave is missing, but that would be a bit of a band-aid too.

This issue about tidal sending cps changes without a sound seems related: https://github.com/tidalcycles/Tidal/issues/489

It's another case of a message arriving that is not for triggering sound..

I guess the underlying issue is that the parent class of all superdirt events represents a sound trigger, but a message might not contain one.

yaxu commented 4 years ago

I think it'd be nice to have the option to remove a bit of latency from midi commands other than noteon / aftertouch. Midi can have low throughput, so I think it's normal to send commands a little bit ahead of time so that noteons aren't delayed.

telephon commented 4 years ago

I've just made a commit that lets you distinguish if a note was set externally or not. You can check for if(~n == \none) { ... })

let me know if this helps …

telephon commented 4 years ago

I think it'd be nice to have the option to remove a bit of latency from midi commands other than noteon / aftertouch. Midi can have low throughput, so I think it's normal to send commands a little bit ahead of time so that noteons aren't delayed.

that would be a good extra issue

yaxu commented 4 years ago

Thanks @telephon, these all work now:

once $ cc "30:20" # s "midi"

once $ cc "30:20" # nrpn "40:3000" # s "midi"

once $ cc "30:20" # nrpn "40:3000" # n 3 # s "midi"

once $ n 3 # s "midi"
yaxu commented 4 years ago

However I notice that this:

once $ s "superpiano"

Gives the freq default which is currently 440 (a), not c and

once $ s "supermandolin"

doesn't sound at all, because there is no default frequency set for that synth.

yaxu commented 4 years ago

Do we need to explicitly set freq=261.626 on all synths?

telephon commented 4 years ago

Do we need to explicitly set freq=261.626 on all synths?

I'd set them all to 440 Hz. Or do we need c?

yaxu commented 4 years ago

I don't know much about notes but I'd expect the default note to be 0.

telephon commented 4 years ago

yes and no. From now on, we should expect the note be the note the synth is defined with. Could be useful, for synths that sound best at higher octaves, e.g.

telephon commented 4 years ago

But we could also write something like:

SynthDef(\imp, { |out, sustain = 1, freq = (60.midicps), …