Jupiter 8 CrossModulation combined with HardSync

DSP, Plug-in and Host development discussion.
xhy3
KVRist
63 posts since 19 Jan, 2014

Post Tue Jun 30, 2020 12:00 am

Hi,

i'm trying to implement a jupiter 8 style modulation. Hope someone can point mo to the right direction. We have following components:

vco1 --> cross modulation by vco2 (exponential FM (1V per octave))
vco2 --> can be hard synced by vco1

So, each one is related to the other one. I tried to do following (pseudocode):

Code: Select all

float out1 = 0;
float out2 = 0;
if (vco1.didPhaseReset()) // should i hard sync
  out2 = vco2.tickHardSync(vco2Frequency, vc1Phase, vc1Increment); 
else
  out2 = vco2.tick(vco2Frequency);
  
vco1Frequency = getFrequency(out2 * 96 + vco1MidiNote); // also some filtering happens here to avoid to much high frequencies

out1 = vco1.tick(vco1Frequency);
hard sync works in all cases without any cross modulation. But there are some issues when hard sync is enabled with cross modulation.

In some edge cases at some frequencies, it produces a lot of noise like it does when you have some sub sample issues in the hard sync algorithm. My guess is that it has to do with the introduced delay we have because both oscillators depend on each other.

Is there a way to reduce this issues at all with some introduced delays or something?

Any information and input is welcome!

juha_p
KVRian
587 posts since 21 Feb, 2006 from FI

Re: Jupiter 8 CrossModulation combined with HardSync

Post Tue Jun 30, 2020 12:46 am

IIRC, K Brown has utilized some of Jupiter 8 features in his Rolend synths which are free and includes SynthMaker/FlowStone sources ... maybe you could find some ideas from those ... ? If you dont have SM or FS available, FlowStone trial can be used for 7 days ....

xhy3
KVRist
63 posts since 19 Jan, 2014

Re: Jupiter 8 CrossModulation combined with HardSync

Post Tue Jun 30, 2020 12:51 am

juha_p wrote:
Tue Jun 30, 2020 12:46 am
IIRC, K Brown has utilized some of Jupiter 8 features in his Rolend synths which are free and includes SynthMaker/FlowStone sources ... maybe you could find some ideas from those ... ? If you dont have SM or FS available, FlowStone trial can be used for 7 days ....
Thanks for the tip. I take a look at it :tu:

User avatar
Urs
u-he
24539 posts since 8 Aug, 2002 from Berlin

Re: Jupiter 8 CrossModulation combined with HardSync

Post Tue Jun 30, 2020 1:11 am

xhy3 wrote:
Tue Jun 30, 2020 12:00 am
vco1 --> cross modulation by vco2 (exponential FM (1V per octave))
vco2 --> can be hard synced by vco1
Ah, the biggest missed opportunity in synth history. Jupiter 6 fixed it.

The best trick I know to reduce latency issues between the two oscillators is to use a "virtual replacement oscillator" for VCO2 which shares the same phase state, but different waveform generation. That oscillator would use a compromise between aliasing and latency, e.g. CZ-style phase distortion for waveform + polyBLEP for hard sync, and all it does is modulate VCO1.

mystran
KVRAF
5741 posts since 12 Feb, 2006 from Helsinki, Finland

Re: Jupiter 8 CrossModulation combined with HardSync

Post Tue Jun 30, 2020 3:28 am

xhy3 wrote:
Tue Jun 30, 2020 12:00 am
In some edge cases at some frequencies, it produces a lot of noise like it does when you have some sub sample issues in the hard sync algorithm. My guess is that it has to do with the introduced delay we have because both oscillators depend on each other.
Something that can cause issues like these if when your sub-sample solver assumes that some modulation signal is continuous, but it actually isn't.

For example, we typically assume that frequency is constant over a sample, hence the phase of the oscillator is a piece-wise linear function and we can just solve for a threshold crossing. If you violate the assumption that the frequency is constant, then your threshold crossing can end-up being garbage.

Another common case where this can happen is when you assume a PWM signal is piecewise constant (like the frequency), because now there is a discontinuity in the (phase-threshold) signal when the PWM input changes from one sample to another, again leading to non-sense linear solutions. In this case the simple fix is to treat such a modulated threshold as piecewise linear instead, so that you always have a consistent linear solution.

It might be that your cross-modulation introduces some similar situation where you end up with a condition that says a transition is required, yet when you try to solve for the transition time the timestamp comes out non-sensical because there was some discontinuity somewhere and the solver isn't able to figure the correct transition point anymore. Note that with these types of errors, the time-stamp that you end up with is often WAY off, by multiple samples or what not and if you don't explicitly check for bounds, you can even end up crashing the whole program.

I don't know if this type of issue is what you are experiencing, but I'd go through the logic extra carefully and make sure you can always draw continuous curves for anything you are trying to solve against.
Please just let me die.

xhy3
KVRist
63 posts since 19 Jan, 2014

Re: Jupiter 8 CrossModulation combined with HardSync

Post Tue Jun 30, 2020 4:02 am

Thanks for the answers. I will have a closer look at it and maybe a ghost oscillator could be a part of the solution.
I don't have any delay in the oscillator itself at the moment. That means, the oscillators are delayed, but both with the same amount. I'm using a symmetric blep. So the result should match again.

I think that the assumption that the frequency is constant leads to that noisy output somehow. I report back if i know more about it.

xhy3
KVRist
63 posts since 19 Jan, 2014

Re: Jupiter 8 CrossModulation combined with HardSync

Post Tue Jun 30, 2020 4:35 am

Hopefully i was able to avoid the issue and the inconsistency when i take one sample from the future to modulate the vco2. It seems to work after the first tests:

Code: Select all

float out1 = 0;
float out2 = 0;
if (vco1.didPhaseReset()) // should i hard sync
  out2 = vco2.tickHardSync(vco2Frequency, vc1Phase, vc1Increment); 
else
  out2 = vco2.tick(vco2Frequency);
  
vco1Frequency = getFrequency(out2OneSampleInTheFuture * 96 + vco1MidiNote); // here take one sample from the future

out1 = vco1.tick(vco1Frequency);
This way i can make sure that the modulation exactly fits the sync. Otherwise the pitch modulation was still on max value when i rendered the first sample after the hard sync.

I get almost the same result like the roland cloud version with the saw waveform now. I will also compare to the hardware jupiter 8 asap :)

camsr
KVRAF
7000 posts since 17 Feb, 2005

Re: Jupiter 8 CrossModulation combined with HardSync

Post Tue Jun 30, 2020 12:16 pm

Oversampling, yes it's a kludge but not un-useful. Exponential FM, Hard Sync, these words are synonymous with oversampling. 32x oversampling can make aliasing almost mute on some extreme settings.

You should compare naive oversampling with any other alias reducing methods, weight the benefits.

xhy3
KVRist
63 posts since 19 Jan, 2014

Re: Jupiter 8 CrossModulation combined with HardSync

Post Wed Jul 01, 2020 5:44 am

camsr wrote:
Tue Jun 30, 2020 12:16 pm
Oversampling, yes it's a kludge but not un-useful. Exponential FM, Hard Sync, these words are synonymous with oversampling. 32x oversampling can make aliasing almost mute on some extreme settings.

You should compare naive oversampling with any other alias reducing methods, weight the benefits.
That's true. I'm thinking about 4x oversampling instead of 2x. I would not oversample 32 times with an already bandlimited infrastructure, but i also think that the quality would increase. I would do it if we had faster CPU's :)

Found another problem zone. My oscillators emulate the instability of the VCO's. This makes hard sync extreme difficult at edge cases (with normal pulse hard sync), because the pitch is not stable and modulates all the time. Luckily the Jupiter 8 pulse hard sync does only sync in one direction. At a first sight it looks like i could ignore the pitch instability.

mystran
KVRAF
5741 posts since 12 Feb, 2006 from Helsinki, Finland

Re: Jupiter 8 CrossModulation combined with HardSync

Post Fri Jul 03, 2020 12:59 am

camsr wrote:
Tue Jun 30, 2020 12:16 pm
Oversampling, yes it's a kludge but not un-useful. Exponential FM, Hard Sync, these words are synonymous with oversampling. 32x oversampling can make aliasing almost mute on some extreme settings.
Oversampling alone is really not particularly effective as an anti-aliasing strategy, because the amount of oversampling you need to do to push the aliasing down grows exponentially. For something like hard-sync with spectrum usually falling at 6dB/octave, with 32x oversampling you only get about 5 octaves or 30dB of aliasing rejection which is really not a whole lot. Even 1024x oversampling only gives you about 60dB.

A moderate amount (eg. 2x or 4x) of oversampling is great for relaxing the transition requirements for things like BLEPs and interpolation kernels, cleaning up low to moderate levels of distortion (where the distortion products higher up aren't too significant) and as a band-aid for things like BLT frequency warping when better solutions are impractical.
Please just let me die.

mystran
KVRAF
5741 posts since 12 Feb, 2006 from Helsinki, Finland

Re: Jupiter 8 CrossModulation combined with HardSync

Post Fri Jul 03, 2020 1:32 am

xhy3 wrote:
Wed Jul 01, 2020 5:44 am
Found another problem zone. My oscillators emulate the instability of the VCO's. This makes hard sync extreme difficult at edge cases (with normal pulse hard sync), because the pitch is not stable and modulates all the time. Luckily the Jupiter 8 pulse hard sync does only sync in one direction. At a first sight it looks like i could ignore the pitch instability.
Treat frequency as piece-wise contant, phase as piece-wise linear (integral of the frequency) and every comparator reference signal (eg. PWM level, reset level, whatever) as piece-wise linear (they must all be continuous or you'll end-up with some of the sub-sample time-stamps outside the sampling interval). When doing sync, simple solve as usual (and process transitions), until you see a sub-sample time-stamp that is later than hard-sync time-stamp, then perform the hard-sync and then continue to process as normal. When implemented correctly, you can add noise to all the inputs just fine without causing any glitches. If adding slight noise results in glitches, then there is almost always some rare situations where the glitches can happen even without noise, so it's not really a matter of making it more difficult, but rather just exposing corner cases more easily.

Note though that noisy PWM is "glitchy by design" (ie. also in an analog design) unless you either latch (ie. pulse goes high on threshold, but low only on cycle-reset) or add comparator hysteresis (ie. the level required to go high is somewhat higher than the level require to go back to low, so that slight noise doesn't cause the the comparator to rapidly switch between the two states).
Please just let me die.

Return to “DSP and Plug-in Development”