Event pattern for both synthesis and MIDI output

I would like to be able to have an event pattern that is capable of outputting note events and MIDI events simultaneously so that I can record both the sound result and the originating MIDI data on an external DAW.

To do this, after starting the server and instantiating a MidiOut:

s.boot;
MIDIClient.init;
MIDIIn.connectAll;
~midi_out = MIDIOut(0);

I tried the first thing that came to mind, which was to use the \type key and assign it a symbols list containing \note (for note events) and \midi (for midi events):

(
Pbindef(\test,
	\type, [\note, \midi],

    // MIDI stuff
	\midicmd, \noteOn,
	\midiout, ~midi_out,
    \chan, 0,

    // "sound synthesis" stuff
	\instrument, \default,
	\octave, 5,
	\degree, 0,
	\dur, 1,
	\amp, 1.0,
	\out, 0,
).quant_([4]).play;
);

But while this causes SC to output sound, as I expect, it does not produce any MIDI data output.

  • why?
  • How can I achieve the desired result?

In order to better understand the inner workings of SC, I ask a further question: why does it work and produce two independent sounds?

(
Pbindef(\test2,
	\instrument, \default,
	\octave, 5,
	\degree, [0,4],
	\dur, 1,
	\amp, 1.0,
	\out, 0,
).quant_([4]).play;
);
  • Is it actually two note events, or is it rather a single note event?
  • It occurs to me that when a list is passed as an argument, the event pattern behaves differently depending on whether the key is \type or something else (e.g. \degree).

Hi,

to the first part of the question see these old threads:

for the seconds part, see this recent one:

Thank you so much @dkmayer,
reading the refs you sent me, I was eventually able to get what I wanted the following way:

s.boot;
MIDIClient.init;
MIDIIn.connectAll;
~midi_out = MIDIOut(0);

(
Event.addEventType(\myEventType, { |server|
	currentEnvironment.copy.use {
		Event.eventTypes[\note].value(server);
	};
	Event.eventTypes[\midi].value(server);
});
);

(
Pbindef(\test,
	\type, \myEventType,
	\midicmd, \noteOn,
	\midiout, ~midi_out,
    \chan, 0,

	\instrument, \default,
	\octave, 5,
	\degree, Pseq((0..7),inf),
	\dur, 0.5,
	\amp, 1.0,
	\out, 0,

	\callback, Pfunc({ |e|
		e.postln;
		e.use{
			~type.postln;
		};
	})

).quant_([4]).play;
);

This way i both get the audio out from the server and the MIDI sent to my DAW.
I had to adjust the latency of the server a little in relation to that of the midiOut so as to synchronise the two outputs

~midi_out.latency_(0.1);
s.latency_(0.14);

but apart from that, it works great!

Glad to hear that it works for you !

Yes, that’s the “real world tweak” likely to be necessary. I remember that I had to experiment with latency as well the few times I had a similar setup.