How polyphonic cables will work in Rack v1

I agree that A/B tests will help here. Over the weekend I’ll prepare some AB’s using the Oberheim modules in Diva and similarly with Repro 5. I think it’s also worth listening to AB’s involving Arturia SEM V/Matrix 12 and Sonic Projects OP-X PRO-II, as these aren’t so militant about emulating the complete signal path (resulting far more friendly processor overhead). I’ll include iSEM (iOS) within that last batch as its also very processor efficient but successfully emulates the impact of separate filter responses on a per voice basis.

The sonic signature that connects all of the above VA’a has nothing to do with zero delay filter modeling or suchlike (both the SEM V and OP-X were designed before ZDF became the ‘soup du jour’ of the VA emulation community). It’s simply that they follow that original Oberheim 4-Voice architecture and individual ‘rotating’ polyphonic voices spread across the stereo field, each with a slightly different filter response; results in a killer recipe for pads and drones that sound very different to the polyphonic voicing of the e.g. Roland synths of the early to mid eighties. The Juno’s and Jupiters had their own secret sauce (their killer chorus units) but this was still very different to the Oberheims and Prophets.

I can only imagine how great VCV will sound with Vult’s ace Vessek unit (hybrid FM/phase modulation oscillator) spread across the stereo field in a similar manner. I’d imagine it would sound pretty darn awesome! :slight_smile:

1 Like

about “should the setting of poly modules have slight variations per voices”
If I understand correctly, a poly vcf module will also have a poly cut off. mod cv in.
If it is so, then it’s up to the user to mux and demux the signal that control the cut off to introduce some small variations

Yes, if you want to have slight variations of VCF cutoff per-voice, you could demux the cutoff signal, patch the N cables into a monophonic module that applies a unique offset to each signal, patch the result into the muxer, and then patch the single poly cable into the FREQ CV input of the VCF.

But a better solution is for the developer of the monophonic offset module to add polyphonic support, so you only need 1 + 1 cables instead of 1 + 2N + 1.

3 Likes

Hi all, i try to give my contribution about the “drift” matter.
Excuse me if it won’t fit the discussion here.
A good idea would be to have a generic “drift” module.
A thing with a poly input, a poly output and 16 knobs with CV input for every knob where is possible to decide the range of drift for every poly voice. And maybe a mono “trigger” input to generate new drift values for every channell in the poly chain. Or maybe a trigger input for every channel.
This way the concept of analog drift could be applied to any parameter (VCF cutoff, VCO pulsewidth, ADSR times etc.)
Does it make any sense?

2 Likes

Yes, it definitely does. Something like that we have in Diva(there are “tune” option for every voice and general “drift”, but in modular system I prefer acces to a drift of every voice, plus to have an ablity to use some kind of “smart randomization” of drift(and maybe tune’s), which gives that “analog/full/lush vibe”. You know, there are threads on Gearslutz, where Synapse Audio’s developers exmplain it in details(they’re working on a new synth and, as I got it from their words, they’re paying a lot of attention to this thing).
Also, you can watch these kind of video explanations:

1 Like

Go for it. The only thing I should mention is that it would be more straightforward to have just one “drift” knob. Polyphonic channels (when used for their recommended purpose, polyphonic voices) should be treated roughly identically, so all channels should have the same amount of drift variation. Users shouldn’t really need to request that channel 7 has more drift than channel 2. They should just turn a knob (with CV), and all N voices should go out of tune in statistically similar amounts.

I suppose that my recommendation is an exact disagreement with @Samir.

1 Like

aP Modules has a detuner that adds configurable noise to an input; something like that might work if applied to filters instead of V/oct?

I guess it should be in poliphonic form.
When i use similar strategies with different mono voices my Rack become so much cluttered and CPU stressing …

using Reaktor i did a similar thing that gives random drift (in a user defined range) to the polyphonic signal. Instead of an always running noise would be better to have a random value (in user defined range) triggered just when a gate/trigger arrives. This kind of thing can simulate analog drift in CV

Maybe I should get around to making that multi sample and hold module. It’s come up a few times now :thinking:

1 Like

Hi Andrew.

Thank you for all your hard work in creating VCV Rack. It’s the most fun I’ve had since my first acid trip. I’m 64 now and haven’t tripped for years. Getting to the point though, I really don’t see the big deal with a polyphonic modular synth. The modular synth is what I consider a classic art form and instrument. Just because it’s technically possible does not mean it should be the new future. Consider me being old fashioned, but I haven’t seen any polyphonic saxophones lately.

Just a thought.

Jay Goodman

2 Likes

If you don’t see the point, let others enjoy it then. I’m not forcing you to make polyphonic patches.

4 Likes

If there were polyphonic saxophones, people would play them and love them.

Not to derail this thread completely, but I thought this was relevant:

2 Likes

Not really special since there are dozens of multi-channel modules like that.

I’ve only heard of one real polyphonic hardware module, the P3000, which never existed. It was designed to use Mini-DIN-8 connectors. You could also use HDMI or mini-HDMI, 8P8C (ethernet), USB-C, D-sub, or any other type of multi-core cable for carrying polyphonic signals.

Agreed. This was mainly in response to jay.goodman00’s comment on monophony and polyphony in modular synths. Apparently, it IS a relevant topic.

The P3000 looks interesting. Hadn’t see that interface with the Mini-DIN-8 connectors.

I sure will. I probably would have been skeptical of the horseless carriage back then. :wink:

Hi all and @Vortico.
How far we are from testing VCV 1.0 polyphony features?
As far as i know there are still some Fundamental stuff to be made polyphonic.
Am i right?
thanks!

Making your monophonic module polyphonic

Here’s an example of how one would add polyphony to your Module class, say an oscillator.

Monophonic:

VcoEngine vcoEngine;

void process(const ProcessArgs &args) override {
	float pitch = inputs[PITCH_INPUT].getVoltage();
	pitch += params[PITCH_PARAM].getValue();
	vcoEngine.setPitch(pitch);
	vcoEngine.process(args.sampleTime);
	outputs[SINE_OUTPUT].setVoltage(vcoEngine.getSine());
}

Polyphonic:

VcoEngine vcoEngine[16];

void process(const ProcessArgs &args) override {
	int channels = inputs[PITCH_INPUT].getChannels();
	for (int c = 0; c < channels; c++) {
		float pitch = inputs[PITCH_INPUT].getVoltage(c);
		pitch += params[PITCH_PARAM].getValue();
		vcoEngine[c].setPitch(pitch);
		vcoEngine[c].process(args.sampleTime);
		outputs[SINE_OUTPUT].setVoltage(vcoEngine[c].getSine(), c);
	}
	// Don't forget to set the number of output channels
	outputs[SINE_OUTPUT].setChannels(channels);
}

This is all you need to get polyphony working.

Advanced: using SIMD

But using 16 voices would take roughly 16x the CPU compared to the monophonic version for the 16 calls to the expensive VcoEngine::process() method. What if I told you it was possible to use only a bit more than 4x the CPU? (And ~1x for using 4 voices.) Enter 128-bit SIMD, using Rack’s simd/vector.hpp header.

using namespace simd;
// 4 engines processing 4 floats simultaneously
VcoEngine<float_4> vcoEngine[4];

void process(const ProcessArgs &args) override {
	int channels = inputs[PITCH_INPUT].getChannels();
	// Advance by 4 channels each time
	for (int c = 0; c < channels; c += 4) {
		float_4 pitch = float_4::load(inputs[PITCH_INPUT].getVoltages(c));
		// The simd API allows you to add single floats to vectors
		pitch += params[PITCH_PARAM].getValue();
		vcoEngine[c / 4].setPitch(pitch);
		vcoEngine[c / 4].process(args.sampleTime);
		float_4 sine = vcoEngine[c / 4].getSine();
		sine.store(outputs[SINE_OUTPUT].getVoltages(c));
	}
	outputs[SINE_OUTPUT].setChannels(channels);
}

Note that this requires the hypothetical VcoEngine code to be written to support simd::float_4. Here I’ve used a template (template <typename T> struct VcoEngine {...), but you can use the type directly if you want.

5 Likes

Do you plan to eventually make dsp::RCFilter and company SIMD also? Just wondering since some mixing consoles have many filters (mscHack comes to mind), and those could be imrproved also if they used SIMD filter code. I may also want an SIMD RCFilter for a Geodesics module, and I will probably parallelize your RCFilter, but I would ideally like to avoid the code duplication if possible (I could even send you my parallel version of your RCFilter if ever you don’t plan on making it and are interested).