Good piano sound?

Hi,

is there a way to create good piano sounds with supercollider (no - I do not intend to create my own physical model) or would you rather use something like fluidsynth with a good soundfont that you control from supercollider via midi?

Many thanks.

1 Like

I’ve used this one on certain occasions.

https://doc.sccode.org/Classes/MdaPiano.html

For now, I’d use VSTPlugin with sfizz (lightweight Sforzando player) and either Headroom Piano (156 MB download, decent but not great sound) or Salamander Grand Piano (~400 MB download, better sound).

hjh

3 Likes

Pianoteq is great, too.

1 Like

BTW VSTPlugin’s setup is not that complicated in the end, but if you haven’t used it before, sorting out the commands you need can take some effort.

So here’s a quick example for sfizz.

s.boot;

// only once, before first use
// the search will be cached,
// don't need to repeat it unless you install more plug-ins
VSTPlugin.search;

// ... wait for scan (can take awhile...)

(
SynthDef(\vstInst, { |out = 0|
	Out.ar(0, VSTPlugin.ar(numOut: 2));
}).add;
)

a = Synth(\vstInst);

c = VSTPluginController(a);

c.open("sfizz.vst3", editor: true);

c.editor;

// GUI opens -- choose the sfz file for your piano

// save a preset so you can recover without GUI next time

c.writeProgram("~/piano.vstpreset".standardizePath);

c.close;
a.free;


// now, when you need to just play it
(
a = Synth(\vstInst);

c = VSTPluginController(a);
c.open("sfizz.vst3", action: { |vstctl, success|
	if(success) {
		c.readProgram("~/piano.vstpreset".standardizePath, { |vstctl, success|
			if(success) {
				"OK, ready!".postln
			} {
				"Couldn't read preset".warn;
			};
		})
	} {
		"Couldn't open VST plugin".warn;
	};
});
)

m = c.midi;

// fake Milton Babbitt
(
p = Pbind(
	\type, \midi,
	\midiout, m,
	\midinote, Pwhite(36, 84, inf),
	\dur, Pexprand(0.1, 0.4, inf),
	\legato, Pexprand(0.2, 6, inf),
	\amp, Pwhite(0.2, 0.8, inf)
).play;
)

p.stop;

a.free;

For the quick example, I just saved the preset file in the home directory. In practice, I would save it in the same location as the scd file, and specify the path as thisProcess.nowExecutingPath.dirname +/+ "piano.vstpreset". (Keeping all the resources together is simpler for project maintenance.)

hjh

3 Likes

Ha! I’ve just been looking for good free piano samples. “Salamander Grand Piano” sounds quite decent!

On subject of free piano samples, I had a lot of fun with this one, Chapters Piano – pianobook

1 Like

The event type should rather be vst_midi to ensure proper timing! Note that vst_midi has a \vst key (= the VSTPluginController instance) instead of \midiout. In your case the pattern would look like this:

(
p = Pbind(
	\type, \vst_midi,
	\vst, c,
	\midinote, Pwhite(36, 84, inf),
	\dur, Pexprand(0.1, 0.4, inf),
	\legato, Pexprand(0.2, 6, inf),
	\amp, Pwhite(0.2, 0.8, inf)
).play;
)

Fun fact: VSTPlugin +sfizz also allows for microtonal MIDI playback i.e. the \midinote parameter can be floating point number with a fractional part!

1 Like

Ah, I hadn’t realized that latency wasn’t implemented.

But, looking at the classes, it looks to me like it could be done:

	// MIDI / Sysex
	sendMidi { arg status, data1=0, data2=0, detune, latency;
		// LATER we might actually omit detune if nil
		this.sendBundle(latency, ['/midi_msg', Int8Array.with(status, data1, data2), detune ?? 0.0]);
	}

	// later...
	sendBundle { arg latency ... cmds;
		synth.server.listSendBundle(latency, cmds)
	}

… then VSTPluginMIDIProxy could have a latency member variable, and pass it to sendMidi.

There would be some benefit to this. For instance, my live coding framework plays pitched material through my Voicer class. Voicer can play synths, or can accept a MIDIOut-compatible object as the target. To support VSTPlugin, it would be nice if VSTPluginMIDIProxy could be that MIDIOut-compatible object. Otherwise, I would have to engineer my own Adapter layer (but that seems rather silly, since there already is one that does everything except handle latency).

I would not have predicted this … hm, next live set with microtonally f…ouled up harp :smiling_imp:

hjh

I think the OteyPiano supercollider extension sounds great. It’s a physical model.
https://doc.sccode.org/Classes/OteyPiano.html

I had considered this before. First off, I don’t really like the idea that the user would have to manually set a latency member. After all, it is just a hack for MIDIOut to (somewhat) synchronize a MIDI device with the Server. VSTPlugin does not need it.

Also, I don’t think that a method called sendMidi should ever schedule a bundle under the hood. My idea was that the VSTPluginMIDIProxy methods would behave the same way as other (synchronous) Server commands, such as VSTPluginController.set or Node.set.

Finally, there are some more subtle issues with the \midi Event type: when you have an array of MIDI events, it would send each Event individually. Now, if \strum is used, it would delay events accordingly on the SystemClock, but what you really want is to schedule all events as bundles with appropriate timetags (latency + offset).

Long story short: the \midi Event type is just not suitable for controlling Server objects. That’s why I have added the \vst_midi Event type, which behaves more like other Server events.

Otherwise, I would have to engineer my own Adapter layer (but that seems rather silly, since there already is one that does everything except handle latency).

I mean, the only thing you have to do is replace \midi with \vst_midi and \midiout with \vst. And since we’re talking about a framework, you would only have to do it once and be done. I think it’s a reasonable tradeoff :slight_smile:

1 Like

Yeah! I’ve just finished a piece that features a detuned virtual piano and vstplugin~ + sfizz + “Salamander Grand Piano” works really nicely for my purposes.

Voicer doesn’t use events to send its messages, so this will not work in my case.

I guess documentation should be changed, then, to make it clear that VSTPluginMIDIProxy is not a drop-in replacement for MIDIOut, and never will be. With that, I’d understand that I need to write a new adapter for it anyway.

IMO, frankly, it would be more useful for VSTPluginMIDIProxy to be a drop-in replacement for MIDIOut (I’m willing to bet that most users won’t care about conceptual purity here if it gets in the way – or maybe it’s just me), but you disagree and it’s your codebase, so I have to live with that.

hjh

I guess documentation should be changed, then, to make it clear that VSTPluginMIDIProxy is not a drop-in replacement for MIDIOut, and never will be. With that, I’d understand that I need to write a new adapter for it anyway.

In the documentation for \vst_midi it says:

NOTE: Always prefer \vst_midi over \midi because the latter doesn’t schedule OSC bundles!

But I should probably also make it clear in the VSTPluginMIDIProxy help file. Noted! clarify VSTPluginMIDIProxy documentation (#146) · Issues · Pure Data libraries / vstplugin · GitLab

@jamshark70 Bad news: it seems like sfizz does not support MIDI note detuning (yet). Turns out I’ve been only using sforzando by Plogue and somehow thought it would also work with sfizz… Unfortunately, sforzando is only available for Windows and macOS (but you should be able to run it on Linux with the built-in Wine bridge, or external wine bridges, such as yabridge).

Anyway, I’ve made a feature request on GitHub: Feature request: support MIDI detune parameter · Issue #1085 · sfztools/sfizz · GitHub

1 Like

Another plug for Pianoteq - automating the model parameters in SC is pretty amazing…

2 Likes

Uhhh, I haven’t tried that yet.

BTW, the VST3 version of “Pianoteq 6” - but not “Pianoteq 6 STAGE” - also supports MIDI note detuning, i.e. fractional MIDI notes with VSTPlugin.

2 Likes

I probably should have mentioned that I am a total noob…

I managed to install the VSTPlugin and I’ve downloaded a sfizz-1.2.0.tar.gz file - so could you please explain how to install sfizz and where to put the Salamander file?

I am running Debian testing, the VSTPlugin is at ~/.local/share/SuperCollider/Extensions/VSTPlugin.

Many thanks!

Apropos this topic I actually messed around with exactly this today. I’ve used sfizz/salamander for a bit but recently switched to the mind blowing pianoteq instead. Made a little pattern test today

8 Likes

On Linux, VST2 plugins usually go to ~/.vst and VST3 plugins go to ~/.vst3. Then you just have to boot the Server and call VSTPlugin.search to scan for new plugins.

The Salamander piano samples can be anywhere. Maybe create a ~/sfz folder where you keep all your SFZ instruments. Then you only have to drag the SalamanderGrandPianoV3.sfz file into the sfizz plugin editor window.