How to program split points for a MIDI keyboard?

Hi

So I would like to use multiple SynthDefs on one MIDI keyboard and was thinking of making split points. (https://doc.sccode.org/Guides/UsingMIDI.html)
I guess it has to be something how one configures this Array:
notes = Array.newClear(128); // array has one slot per possible MIDI note

I tried something like “Array.series(50,0,1)” and was hoping to limit the sounds of one SynthDef up to MIDI number 49. But in fact I am still able to play sounds which are higher than 49 on my MIDI keyboard. I just receive an error message from SuperCollider that it’s out of range and the sound isn’t released when I release a key.

Thanks!

1 Like

See msgNum under here: http://doc.sccode.org/Classes/MIDIFunc.html#*new

msgNum, chan and src ID are filters: if nil, they pass everything; if a specific value, only that value passes through; collections and functions are also allowed for richer decision making. (See matchItem help.)

So you could write:

var notes = Array.newClear(128);

MIDIdef(\lowNotes, { |vel, note|
    ... your note stuff here...
}, msgNum: { |note| note <= 49 });

MIDIdef(\highNotes, { |vel, note|
    ... your note stuff here...
}, msgNum: { |note| note > 49 });

Still just using one array, which is fine as long as the keyboard splits don’t overlap.

hjh

Cool, that sounds great.

The problem is I receive an error: ERROR: Message ‘<=’ not understood.

(
SynthDef(\string, {

	arg freq=500, out=0;
	
	var snd;
	
	snd = Saw.ar(freq,0.2);
	
	Out.ar(out, snd);
	
}).add
)

MIDIClient.init;
MIDIIn.connectAll;

(
var notes = Array.newClear(128); // array has one slot per possible MIDI note


MIDIdef(\lowNotes, { |vel, note, num|
		notes[num] = Synth(\string, [\freq, num.midicps]);	
}, msgNum: { |note| note <= 49 });
)

Probably missing something obvious…

It’s a bug, and more complex than I can fix at the moment.

Try this maybe?

MIDIdef(\lowNotes, { |vel, note, num|
	// btw DO NOT USE 'NUM' HERE
	// the third argument is the channel number, NOT the note number
	notes[note] = Synth(\string, [\freq, note.midicps]);	
}, msgNum: (0..49));

So when I was using the code you suggested in your last post SuperCollider didn’t complain. But I wasn’t able to produce any sound.

I tried it with MIDIFunc instead:

(
var notes, on, off;


notes = Array.newClear(128); //

on = MIDIFunc.noteOn({ |vel, note|
              notes[note] = Synth(\string, [\freq, note.midicps]);
}, noteNum: (0..49));

off = MIDIFunc.noteOff({|vel, note|
	notes[note].release;
});
)

That works in fact. Do you have an idea what’s different now?
I am using VMPK at the moment, because I don’t have my Hardware MIDI keyboard here. Don’t know whether that would make any difference.

But thanks a lot for your immediate help!

I see – I was too hasty to reply.

First, I forgot that it should be MIDIdef.noteOn. That led me to get the argument name for noteNum wrong. And the note-filtering function was an incorrect analogy to OSCFunc.

Nothing wrong with using MIDIFunc btw; I was trying to use MIDIdef because its built-in storage is more convenient.

hjh