Login / Register  0 items | $0.00 NewWhat is KVR? Submit News Advertise
User avatar
aciddose
KVRAF
 
11316 posts since 7 Dec, 2004, from Vancouver, Canada

Postby aciddose; Fri Aug 18, 2017 6:51 pm Re: Hard-Sync with MinBlep / How to manage edge cases

Code: Select all
phase += delta;
while (phase >= next || sync) {
 overlap = phase - next;
 fraction = (phase > next ? overlap / delta : 0.0);
 // syncing, sync happened before next step
 if (sync && sync_fraction > fraction) {
  set_phase(sync_fraction, destination_phase);
 } else {
  set_phase(fraction, next < 1.0 ? next : 0.0);
 }
}


If you do things correctly there are no "edge cases".

Note that regardless of whether sync happens before the next step or after, you must always loop to handle both events or aliasing and error will result.

This is called "event handling with sub-sample precision."

If you want morphing conditions (variable pulse-width, morphing waveforms, ...) the code is a lot more complex in order to handle things as efficiently as possible. Still though you can generate any waveform with any set of conditions from one implementation. It isn't necessary to have multiple implementations one for each of pulse, ramp or other waveforms.

This is because ultimately any first-order changes in delta or other conditions (pulse-width modulation) are simply more of the same sort of events that you need to handle with sub-sample precision.
http://xhip.net/synth/ Xhip Synthesizer v8 released 21 May 2017
xhy3
KVRer
 
18 posts since 19 Jan, 2014

Postby xhy3; Sat Aug 19, 2017 12:53 am Re: Hard-Sync with MinBlep / How to manage edge cases

Ok, it worked. I have chosen the ordering solution. It's the simplest one for a saw with one master oscillator. I had a mistake in the if statement, because of this it took a bit longer than planned. The one with the bigger phase is the first one :dog:

Now the same for the pulse :)

Thanks again!
xhy3
KVRer
 
18 posts since 19 Jan, 2014

Postby xhy3; Mon Sep 11, 2017 2:03 am Re: Hard-Sync with MinBlep / How to manage edge cases

mystran wrote:
kryptonaut wrote:In the past I've used a tabulated BLEP derived from an IIR filter response - that way it's always causal (so you don't have to anticipate a step N samples ahead) and by adjusting the filter parameters you can experiment with different roll-offs, cutoff frequency, etc. for various effects and/or trading off BLEP length vs antialiasing.


The problem is that a minimum-phase BLEP is not zero-phase and trying to pretend so leads to all kinds of funky DC offset issues and other crap that BLEPs are specifically supposed to avoid. Since you can have arbitrary overlaps of any number of BLEPs anyway, your best strategy is to mix them into a buffer right-away when you find the relevant transition point, at which point moving the "naive" output around in the buffer to compensate for linear-phase BLEP latency is trivial.

edit: in short, if you think MinBLEPs make something easier in terms of implementation, then your implementation is almost certain broken in the first place!


Yes, the DC offset can be big. Up to 5 times the amplitude for saws at high frequencies when they overlap and hard sync, but it's easy to remove the offset. Just add a one pole high pass filter with the cutoff of the oscillator increment value for the current frequency.

How does FM work when you have the normal bleps? i can imagine that you can't change the frequency (phase increment) anymore for 1/2 the blep size once you have mixed the blep. Otherwise the blep misses the corner. Is there a solution for this issue?
User avatar
aciddose
KVRAF
 
11316 posts since 7 Dec, 2004, from Vancouver, Canada

Postby aciddose; Mon Sep 11, 2017 3:35 am Re: Hard-Sync with MinBlep / How to manage edge cases

Impulses are being inserted. That is all you need to think about. Impulses do not have "frequency". They have an amplitude and an infinitesimal position in time, period.

The "frequency" of a set of impulses is merely an abstract determined by the distance between any two impulses. If this distance is always different it can't be said that the collection of impulses has a defined frequency. There are various ways to calculate averages and other statistical methods which have a wide variety of applications. None of them are related to frequency in Hertz.

The DC offset is constant with a linear relationship to the density of impulses. What variable refers directly to the impulse density? The "frequency". This is where the average comes in handy: over a period of time (one sample) the "average" density can be used to determine the exact offset with only very small error due to the window. If you're using impulses for an oscillator a good approximation to the density on a particular sample is equal to the sampled frequency on that same sample (delayed by latency of your impulses.)

So: dc free output = impulse buffer + naive waveform + frequency * c;

Computing the constant "DC of impulse at 100% density" is the only important part. (Each waveform has a different sum of impulses: a pulse is +1 -1 = 0, ramp is +1 = 1, a 75% duty ramp/triangle will have a sum of 1st and 2nd order impulses. You just need to sum the impulses on each discontinuity throughout the waveform. Waveform constant DC = impulse constant DC * waveform discontinuity sum for this impulse.)

That is all.

Xhip's oscillator:
  1. Uses minimum phase impulses
  2. Uses 0th, 1st, 2nd and 3rd order impulses (blit, blep, blamp, splamp, ++)
  3. Has DC offset at nyquist or any frequency of -112 dB
  4. Handles thru-zero "FM" (negative frequencies)
  5. Handles sync
  6. Can do morphing waveforms (from tables) and sub-sample precision "width" (morph) but this is disabled in Xhip itself

Try it if you want to see the lowest possible quality you can get from such an implementation.
http://xhip.net/synth/ Xhip Synthesizer v8 released 21 May 2017
xhy3
KVRer
 
18 posts since 19 Jan, 2014

Postby xhy3; Mon Sep 11, 2017 1:41 pm Re: Hard-Sync with MinBlep / How to manage edge cases

aciddose wrote:Impulses are being inserted. That is all you need to think about. Impulses do not have "frequency". They have an amplitude and an infinitesimal position in time, period.


I wonder how a good implementation for an integrated symmetrical blep would look like (without minBleps). You always have something like this:

output = impulse buffer + naive waveform

The impulse jump in the buffer needs to fit the jump in the naive waveform. Thats the point where i see some problems when the frequency modulates while you already have mixed the impulse into the buffer.

aciddose wrote:So: dc free output = impulse buffer + naive waveform + frequency * c;


Isn't it easier and more stable to just add a one pole high pass with the cutoff around the fundamental frequency? It does all the things with one subtraction, addition and multiplication.
User avatar
aciddose
KVRAF
 
11316 posts since 7 Dec, 2004, from Vancouver, Canada

Postby aciddose; Mon Sep 11, 2017 2:15 pm Re: Hard-Sync with MinBlep / How to manage edge cases

No, for the same reason you just talked about regarding integration.

The high-pass filter will always remove more than you want because it approximates the removal of DC over time. By computing the exact DC value per sample you can remove the exact value of the offset rather than approximating it. You can take impulse density into account exactly and get a better result (-112 dB vs. -60 dB with a naive high-pass filter.)

Test it yourself. The consequence of the error is in minor side-bands vs. DC offset and is ultimately a trade-off.

For frequency modulation it turns out that using the nth order (integrated) vs. low-pass filtered (which has a frequency coefficient) is actually a better approximation rather than worse. You have to remember that any integration is only approximate to begin with since we're attempting to produce a geometrical shape. Integrating impulses is only an approximation of that geometry and it is far more easy to exactly generate the geometry instead.

Can the difference be measured? Yes, it is trivial. It comes down to very minor (<1 dB) differences in the spectral result which decrease as the sample rate increases.

So we're only looking at approximating the same thing from different directions with numerous trade-offs and never a perfect result.
http://xhip.net/synth/ Xhip Synthesizer v8 released 21 May 2017
xhy3
KVRer
 
18 posts since 19 Jan, 2014

Postby xhy3; Mon Sep 11, 2017 10:57 pm Re: Hard-Sync with MinBlep / How to manage edge cases

aciddose wrote:No, for the same reason you just talked about regarding integration.

The high-pass filter will always remove more than you want because it approximates the removal of DC over time. By computing the exact DC value per sample you can remove the exact value of the offset rather than approximating it. You can take impulse density into account exactly and get a better result (-112 dB vs. -60 dB with a naive high-pass filter.)

Test it yourself. The consequence of the error is in minor side-bands vs. DC offset and is ultimately a trade-off.


Thanks for the detailed explanation. I didn't notice that the side bands also have the source in DC offsets. I will try it.

aciddose wrote:over a period of time (one sample) the "average" density can be used to determine the exact offset with only very small error due to the window.


I just wonder how you calculate the average density. Do you use a circular buffer with a defined size (number of samples) where the most values are zero and some of them are +1 or -1 (the impulses), window it and calculate the average or is there a more effizient way to do this?
User avatar
aciddose
KVRAF
 
11316 posts since 7 Dec, 2004, from Vancouver, Canada

Postby aciddose; Tue Sep 12, 2017 7:25 am Re: Hard-Sync with MinBlep / How to manage edge cases

The buffer contains variable impulses (blit, blep, blamp, ...) at various amplitudes and positions. The density at any one position is approximately equal to the current sampled frequency (in 1/Hz) multiplied by the sum of impulses scaled by the DC of each impulse for a complete cycle.

If you use Xhip to test the frequency modulation (X-Mod) feature you should notice that if any DC leakage were allowed it would result in feed-through of the modulator frequency. You can try it with -36 st for the modulator and you'll find the level of feed-through is extremely low with this technique. (Actually you can use several octaves if you disable KBT and use detune mod sources, although it has an ultimately limited range.)

If you were integrating pulses with a lossy integrator (or otherwise) the feed-through is massive. It makes X-Mod impossible. The biggest issue is a variable amount of error. It is easy to over-look the fact that all digital filters are highly inaccurate because they are discrete (remember not LTI). If the approximation has a continuous error it means as the frequency is modulated the DC offset does not change.

This is what allows the minimal (-60 dB peak) modulator feed-through in Xhip. This is nearly inaudible and is reduced with increased oversampling.

http://xhip.net/temp/xmod.mp3
http://xhip.net/temp/xmod.7z (.wav)
http://xhip.net/synth/ Xhip Synthesizer v8 released 21 May 2017
Previous

Moderator: Moderators (Main)

Return to DSP and Plug-in Development

Who is online

Users browsing this forum: Architeuthis, CCBot (commoncrawl), Google Feedfetcher