FM Synth anti aliasing.

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

The speculation in the above post is now verified. If you use the definite integral, either for sin or sinc to calculate the actual modulation amount the distortion/noise is eliminated completely.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

It is exactly as I've been saying for years. You can 100% anti-alias phase modulation using a thru-zero band-limited oscillator. Replace the continuous waveform with a sample, replace the sample by band-limited impulses.
aciddose: could you please explain to newcomers like me what you mean by thru-zero band limited oscillator? and what does it mean to reaplace the sample by band limited impulses?
Could you explain it in more detail please as I'm kind of lost.

Post

iliar1987 wrote:
It is exactly as I've been saying for years. You can 100% anti-alias phase modulation using a thru-zero band-limited oscillator. Replace the continuous waveform with a sample, replace the sample by band-limited impulses.
aciddose: could you please explain to newcomers like me what you mean by thru-zero band limited oscillator? and what does it mean to reaplace the sample by band limited impulses?
Could you explain it in more detail please as I'm kind of lost.
"Thru-zero" means that you can sweep the frequency "through zero" to the negative frequencies (so it can run backwards) which generally involves some extra logic in both digital and analog oscillators.

Band-limited means the signal has a finite bandwidth, which in this case generally refers to an oscillator that doesn't generate partials above the Nyquist rate (half the sampling rate), which would show up as aliasing.

Post

[seriously KVR? double posts? in 2014?]

Post

"Thru-zero" means that you can sweep the frequency "through zero" to the negative frequencies (so it can run backwards) which generally involves some extra logic in both digital and analog oscillators.

Band-limited means the signal has a finite bandwidth, which in this case generally refers to an oscillator that doesn't generate partials above the Nyquist rate (half the sampling rate), which would show up as aliasing.
I know what through zero means and what bad-limited means.
aciddose recommended the use of a "band-limited through zero oscillator" to overcome fm synthesis aliasing. However he didn't say exactly how would such an oscillator be implemented, is it BLIT of some sort? and the cryptic "turn the samples into band limited impulses" doesn't explain that either.
I was asking, how exactly to implement such a thing?

Post

Samples _are_ band limited impulses. Those impulses are the sinc function centered on the sample.

You can calculate the modulation depth you apply to a carrier by summing the integral (∫) of the sinc function (lets call this ∫sinc) for each sample of your modulator.

You need to apply a window and so on to get this right as sinc and ∫sinc are both continuous functions that go on infinitely in either direction.

The key to this is that we only need to know the sum of integrals at specific points to implement the modulation, and that ∫sinc is easy to calculate, and that a complex waveform (sine, saw, whatever) can be built up of samples (dirac / sinc impulses) and likewise the modulation is built up of the integral or sum of ∫sinc impulses.

You should try computing the naive implementation using sin and ∫sin first, then see if you can wrap your head around building sin out of samples. If you can get through that, you should immediately realize you are not limited to sin but may use literally any waveform to get a fully band-limited result with exact modulation sums calculated at any point from the integral functions.

Just for clarity let me try to define what I mean:

output = sum of your carrier waveforms for this sample (summed from a band-limited function like sin or sinc)

modulation sum = the total integral of the modulation input to your carrier from all modulators at this point in time (this sample). Normally we would just add everything up naively, but we ignore the continuous part of the function between samples and this is where the noise/error comes from. The integral of a function gives you the total application of modulation (the velocity, not acceleration) at this point in time while normally we'd just sum the acceleration at that single point and ignore all the other points along the continuous contour.

http://www.wolframalpha.com/input/?i=in ... inc%28x%29

I guess I should also answer your question... Thinking of the oscillator in terms of accumulating phase and then calculating the value of a sample is wrong. You need to think instead of inserting sinc impulses at various positions in time.

How exactly you compute the output is up to you, but one idea is that you can maintain a list of impulses that still exist within your window. As you move through your waveform (phase accumulation) you don't use phase to calculate the output, but rather simply to keep track of how far you've gone. You add all the impulses (samples from your "virtual waveform sample") that occurred before this point and then use those to compute all the outputs.

Using minimum phase versions of these functions is very useful as it means you do not need to look "forward in time" to sum the influence of impulses you haven't yet inserted. For reasons of practicality you really need to use tables anyway.

So, the whole thing is related, sort of, to a minblit oscillator... just not really.

Also drawing any lines between these at this point would be making a huge number of assumptions for you ahead of time, and really how you implement this is all up to you. I suspect there are far more efficient ways to compute this using SSE or parallel threads for example that become possible once you stop looking at it like a typical oscillator implementation.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

Also, I've been meaning to implement a very simple 4-op fm synthesizer like the OPL3 starting with only sine, then looking at various ways to implement complex waveforms.

I've only tested this so far using my existing implementation (stuff from Xhip mostly, not writing a lot of new code) with a simple two op modulator -> carrier configuration.

I suspect that implementing this with highly complex operator layouts including feedbacks and complex waveforms is very difficult to say the least, if even possible.

The fact that this isn't already a commodity thing says it all really.

CPU is definitely an issue. Extreme exponential growth of computational complexity as the modulation is increased is probably an issue.

The point is only, mathematically it seems theoretically possible. Not that it is practical for something like a DX-7 to implement.

https://soundcloud.com/aciddose/fmjunk

I've used a ridiculous amount of unison and so on here, but you still get to see that the naive blep-based sine sample playback with thru-zero eliminates the aliasing almost entirely on the sample itself.

However, due to the slight aliasing allowed on the modulator followed by the naive point-sampling of the modulation sum, that aliasing builds up significantly by the time the carrier brings it to the output.

Even then, the aliasing is minor compared to a naive implementation. The error due to nearest sampling of the modulation is far more significant. The signal is driven out of tune and then to noise as the frequency increases to the point where the nearest samples no longer approximate even remotely the modulation sums that would be generated if utilizing the integral functions.

If I ever get around to coding it, I will post example clips of sounds generated using the integral functions to eliminate this issue with noise bursts common to naive "FM" implementations. It is of note however that even then the result is similar to oversampling the anti-aliased naive modulated version. What you get is as modulation depth increases to ridiculous amounts + pitch is very high, the resulting signal is either sum+difference like or mostly out of band and so inaudible.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

let's see if i understand aciddose's proposal right and may fill in some details. so, we start with a simple FM signal in the continuous time domain:

f(t) = sin(wc*t + b*sin(wm*t))

where "wc" and "wm" are carrier and modulator radian frequencies and "b" is the modulation index. naively sampling this function at discrete time indices will produce aliasing. so, still in the continuous time domain, we bandlimit our f(t) by performing a convolution with a lowpass impulse response h(t) and obtain (in a kind of pseudo latex):

g(t) = integral_{-inf}^{inf} f(u) * h(t-u) du

where our lowpass impulse response h(t) is the sinc function: h(t) = sin(t)/t. sampling g(t) at discrete times will not produce aliasing, because g(t) is bandlimited. being unable to solve the integral analytically (supposedly, i didn't try), we approximate the integral by applying a window function to the sinc and calculate a riemann sum for the convolution integral (or trapezoidal sum or whatever other numerical integration technique). am i getting the idea right, so far? due to the informal explanations, it was a bit of guesswork for me.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

I'm not sure what would be the most practical concrete implementation.

In fact I'm not really certain this could ever be practical on current hardware. Once you involve feedback "delay-free loops" it becomes very complex.

For the straightforward case without feedback it is arguable that simple band-limiting of the carriers (and therefore modulators) combined with naive sampling at a high frequency (over-sampling) should do the trick.

With feedback it is possible to ignore what is correct and use naive sampling (a non-zero group delay) instead, putting up with the consequences such as noise.

I think you've understood correctly though, I'm sure anyone could write a simple proof that the resulting signal is band-limited regardless of the wave-shapes involved if they are ultimately built up from a combination of continuous band-limited signals like sinc().

That is all I wanted to provide evidence for.

In my tests I have never gone as far as to attempt to solve for feedback and I'm not even sure it would be possible. That said without massive optimizations like mipmapping for the underlying waveforms this method (the incomplete method) is already impossible to run on ordinary modern hardware.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

it should work for any waveforms because we do not have to make any assumptions about the bandwidth of f(t), the continuous-time signal before applying the convolution integral. and after applying the convolution integral, it will be bandlimited by virtue of having been convolved with an ideal lowpass impulse response, so it won't alias.

i wonder however, if this technique could actually be entirely equivalent to oversampling plus downsampling using a windowed-sinc FIR filter before decimation. because, inside the numerical evaluation of the integral, we have to evaluate the function f(t) at various time-instants (supposedly spaced more densely than the final samplerate). so, assuming that we take an equidistant integration stepsize, we are actually evaluating the function at an oversampled grid, multiply these function values with our weights from the windowed sinc and sum them up. which is essentially oversampling plus FIR filtering, unless i'm missing something.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

The fact you can look at these things as equivalent in that sense doesn't really change how they're defined.

We can also look at any continuous signal as always containing out of band components, so creating a discrete-time sampled signal to represent any true continuous signal is impossible.

That doesn't stop us from applying shannon-nyquist to the problem.

What makes sampling the continuous signal different from filtering a discrete (over-sampled) signal is that we've moved the order of the filtering and sampling around.

So, to say that one is equal to the other is the same as to say naive over-sampling combined with a FIR interpolation filter is equivalent to BLIT synthesis. At an abstract level they are the same thing, yes. The only difference is the point at which we start from.

Top down, or bottom up.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post Reply

Return to “DSP and Plugin Development”