Comparing phase truncation and interpolation in wavetable synth

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

deleted2
Last edited by itoa on Fri Sep 25, 2020 12:55 pm, edited 1 time in total.
giq

Post

deleted (sorry my kid was here :)
giq

Post

Hi everyone,

thank you for all your precious advice.

I would like to summarize what I understood starting from the very basics of DDS. I think that the main problem when approaching for the first time wavetable synthesis and the associated aliasing issues is that we usually refer to aliasing when talking about Analog to Digital conversion and back. When applied for DDS there is a little mental adjustment required which is sometimes overlooked.

What I have understood is that if we have a generic wavetable and a base sampling frequency (eg 44kHz) the phase increment, let's say M, will basically define the real sampling frequency of the system. For M< 1 we are oversampling, for M>1 we are downsampling. We can consider our wavetable signal, which is periodic and "infinite", as an analog signal that we are sampling at a frequency given by the (base sampling frequency/M). If the original wavetable does not already contain harmonics below the Nyquist frequency, 22k in this case, for M=1 we do not have aliasing. If M>1, we will start downsampling the signal and aliasing will be produced depending on the frequency content of the signal.

Please tell me if this makes sense. :)

That being said, let's say that I have some existing wavetables from which I want to generate some bandlimited versions for the higher keys. My approach would be: if we consider the MIDI note number 83 (987.766Hz), the M will be equal to 128*987.766/44k = 2.866. This means that the actual sampling frequency becomes around 44k/2.866 = 15kHz. To avoid aliasing, in theory, the wavetable associated to this key should not contain frequency above 15kHz/2 = 7.5kHz. Is this somehow correct?

From a practical point of view, as far as I know, there are two methods to calculate the wavetables, either by FFT, zeroing and IFFT or by using a LP filter. For the latter method, maybe it would be necessary to first create multiple periods of the single-cycle wave and then apply the filter. What do you use for generating wavetables?

thank you again

Post

ACR_Crew wrote: Mon Sep 28, 2020 1:59 pm Please tell me if this makes sense. :)
Yes, it makes sense as far as I understood it, but for the purpose of implementing wavetable playback the "nominal sampling rate" of the table is not really that meaningful and usually it's easier to think in terms of normalized frequencies.

For example if you treat a 2048-sample wavetable as having a sampling rate of 2048 samples/cycle (rather than N samples/second), then if your phase increment (for a normalized accumulator that wraps at 1) is less than 1/2048 you are resampling to a lower frequency and if it's more than 1/2048 then you are resampling to a higher frequency.

We can also compute the maximum allowable number of harmonics from the phase increment directly: for a normalized (ie. wraps at 1) phase increment p, it takes 1/p samples to complete a cycle. Multiply by 0.5 (the Nyquist rate requirement) and round down to the next smaller integer and that's your number of valid harmonics. Now you just need to find the correct per-computed version of your waveform with at most that many harmonics.

The actual real-world frequencies (or the actual sampling rate used) never really come into play at all, except in terms of computing the desired phase-increment.
From a practical point of view, as far as I know, there are two methods to calculate the wavetables, either by FFT, zeroing and IFFT or by using a LP filter. For the latter method, maybe it would be necessary to first create multiple periods of the single-cycle wave and then apply the filter. What do you use for generating wavetables?
Given a FIR filter, you can just convolve periodically in time-domain as well, though this is less efficient than doing it with FFT, so there's really no point. For IIR filters your best bet is probably to sample the IR into a FIR, then apply periodic convolution, and the whole thing is even more pointless. Seriously just use FFT. As long as you are doing it as preprocessing there are literally no downsides whatsoever.

Post

mystran wrote: Mon Sep 28, 2020 2:59 pmFor example if you treat a 2048-sample wavetable as having a sampling rate of 2048 samples/cycle (rather than N samples/second), then if your phase increment (for a normalized accumulator that wraps at 1) is less than 1/2048 you are resampling to a lower frequency and if it's more than 1/2048 then you are resampling to a higher frequency.
This way of thinking works well, assuming your WTs are limited to "their own Nyquist". However once you start bandlimiting them stronger (for the purposes of improving interpolation quality), it gets a bit awkward. This is why I advised another approach in an earlier post: think in terms of real playback frequencies of the harmonics. If you wish to stay agnostic from the actual SR, you can work in terms of normalized playback (WT oscillator output) sampling rate (T=1). Now, as soon as the playback frequency of your harmonic exceeds the output Nyquist, it will alias, which is a very natural way of thinking. YMMV.

Post

Hello again everyone,

I have played with creating my band limited wavetables (at the moment only two for two sets of octaves) and I noticed a reduction of the aliasing as expected.

However, while continuing my studies about resampling I came across the famous paper from Laurent de Soras Quest For The Perfect Resampler. It describes a method based on creating mipmapped versions of the original wavetables and using an FIR filter whose coefficients depend on the phase fractional position with the impulse response of the filter increasingly shifting. The main point here is that polynomial interpolation such as linear, lagrange etc becomes quickly inefficient when compared to the same order FIRs.

Question 1) The mipmapped waves are obtained by filtering to half the sampling frequency and decimating to half their size. Except for the decimation process, this looks like the same approach as with bandlimited wavetables. Is decimation a required process for the described method itself?
Question 2) Did anyone compare the standard bandlimited + polynomial interpolation with the above method?

Post

ACR_Crew wrote: Sat Oct 03, 2020 6:24 pm However, while continuing my studies about resampling I came across the famous paper from Laurent de Soras Quest For The Perfect Resampler. It describes a method based on creating mipmapped versions of the original wavetables and using an FIR filter whose coefficients depend on the phase fractional position with the impulse response of the filter increasingly shifting. The main point here is that polynomial interpolation such as linear, lagrange etc becomes quickly inefficient when compared to the same order FIRs.
As far as I can see, it discusses the method that we generally refer to as "sinc-interpolation" (which has probably been mentioned in this thread already). Normally this is implemented by approximating a continuous-time brickwall low-pass filter (ideally sinc) with a highly oversampled kernel stored into a lookup table, then this table is interpolated (usually with linear interpolation) to approximate the desired continous kernel between the known points, although mathematically you can arrive at the same design from other directions as well.

See https://ccrma.stanford.edu/~jos/resample/ for some more discussion on the subject.

Polynomial interpolation is really just a special case of FIR interpolation where we approximate the continuous-time low-pass filter with a piece-wise polynomial kernel. For example, in linear interpolation the "low-pass kernel" is the triangular function. For very low orders (eg. linear, cubic) we can compute the coefficient (or the response) directly and if this is all we need, it's usually the fastest approach.

For longer and higher order piece-wise polynomial kernels though the cost of such computation grows quickly though and it becomes more efficient to build a table-based approximation for these as well. At that point though, if you're using a LUT anyway, there's usually no good reason to constrain yourself to polynomials in particular and you might just as well optimize the response directly. The point I'm trying to get across here though is that polynomial interpolation really is not fundamentally different at all, rather it's just about a choice of kernel for which one can efficiently compute the coefficients on the fly.
Question 1) The mipmapped waves are obtained by filtering to half the sampling frequency and decimating to half their size. Except for the decimation process, this looks like the same approach as with bandlimited wavetables. Is decimation a required process for the described method itself?
Assuming that you are asking whether you need to decimate in order to perform sinc-interpolation, the answer is no. Decimation for all intents and purposes is nothing but a memory optimization, at the cost of greater demand on the interpolator.

The observation made earlier is that when you skip the decimation and just store the whole table for each mip, then given large enough table size the quality required from the interpolator can be low enough that you can get away with something like linear or cubic, because it gets to work with "oversampled" data.

The important thing to understand is that this not really a "different method" at all, but rather just a different choice of design parameters and implementation optimizations.

Post Reply

Return to “DSP and Plugin Development”