BLIT headache

elena2
 KVRer
 19 posts since 7 Jun, 2018
Hi, I am trying to code a bandlimited impulse train (blit) oscillator module for Synthedit but I am encountering some problems. Be patient with me, who knows me also knows that I am a skilled C and DSP coder but when maths get too complex I give priority to intuition (I am not a maths guru so try to avoid using a too complex math jargon if you can...)
Ok, I kind of understood that the perfect solution for blit is summing sinc pulses with proper phase (possibly windowed); however to save computation and avoid tabulations I tried another approach (my invention or kind of)... but it does not work and I would like to understand why...
I am pretty using a fractional delay filter (all pass) to position the pulses in a buffer with proper offset basing on their fractional sample position. Inspection of the generated audio (here the period is 20.25 samples) reveals that I made no mistakes and the pulses are positioned and fractionallyshifted as expected. Unfortunately the spectrum of the generated pulse train is still plagued by aliasing and it is not the perfect comb which I need to obtain! Increasing the length of the fractional delay or even windowing does not help minimally. What is there conceptually wrong with this approach ?
The strange thing is, if I instead use a digital waveguide (one I have written) with an all pass interpolator and I initialize the buffer with an unity pulse, the resulting spectrum IS a perfect comb
(but the time domain signal is really messy). Here is a comparison of a same impulse train with period of 50.5 samples generated by the method described above (top) and by the dwg (bottom). Unfortunately I cannot use a digital waveguide as oscillator, because it tends to lose stability when heavily modulating the pitch, or the peaks tend to lose their original flat level over time (indeed the dwg is a recursive thing)...
Which other approach can I use to write a blit oscillator giving a perfect comb as spectrum? Thanks
Ok, I kind of understood that the perfect solution for blit is summing sinc pulses with proper phase (possibly windowed); however to save computation and avoid tabulations I tried another approach (my invention or kind of)... but it does not work and I would like to understand why...
I am pretty using a fractional delay filter (all pass) to position the pulses in a buffer with proper offset basing on their fractional sample position. Inspection of the generated audio (here the period is 20.25 samples) reveals that I made no mistakes and the pulses are positioned and fractionallyshifted as expected. Unfortunately the spectrum of the generated pulse train is still plagued by aliasing and it is not the perfect comb which I need to obtain! Increasing the length of the fractional delay or even windowing does not help minimally. What is there conceptually wrong with this approach ?
The strange thing is, if I instead use a digital waveguide (one I have written) with an all pass interpolator and I initialize the buffer with an unity pulse, the resulting spectrum IS a perfect comb
(but the time domain signal is really messy). Here is a comparison of a same impulse train with period of 50.5 samples generated by the method described above (top) and by the dwg (bottom). Unfortunately I cannot use a digital waveguide as oscillator, because it tends to lose stability when heavily modulating the pitch, or the peaks tend to lose their original flat level over time (indeed the dwg is a recursive thing)...
Which other approach can I use to write a blit oscillator giving a perfect comb as spectrum? Thanks
You do not have the required permissions to view the files attached to this post.

matt42
 KVRian
 1207 posts since 9 Jan, 2006
Are you using the allpass filter to fractionally offset a single sample impulse? If so a single sample impulse is not band limited and will alias like crazy.

Z1202
 KVRian
 1196 posts since 12 Apr, 2002
I'm not sure if there is enough information to identify the source of problem (or could be simply an implementation bug).
One thing is what kind of allpass you are using. Is it an interpolated delay? In that case the interpolation quality will affect the aliasing. Also theoretically you need a dedicated delay per impluse, otherwise you must be cutting the samples, effectively performing rectangular windowing (which is probably one of the worst options, aliasingwise). I doubt that a delaybased allpass is a good alternative to a properly done windowing. The math is pretty much the same, but it's way more inconvenient and difficult to properly reason about the setup. If you use an IIR allpass, the issue is similar (you need a separate filter per impulse, or your cutoff modulation is likely to produce lots of aliasing).
As for single impulse being not bandlimited, actually it is. So in principle your approach is correct, but it doesn't look to me like a simpler one compared to standard approaches.
One thing you might consider is using Dirichlet kernels instead of windowed sinc. They give zero inharmonic aliasing.
Edit: actually they are perfect, but the integration used in BLIT is imperfect and can be seen as producing "harmonic aliasing"
One thing is what kind of allpass you are using. Is it an interpolated delay? In that case the interpolation quality will affect the aliasing. Also theoretically you need a dedicated delay per impluse, otherwise you must be cutting the samples, effectively performing rectangular windowing (which is probably one of the worst options, aliasingwise). I doubt that a delaybased allpass is a good alternative to a properly done windowing. The math is pretty much the same, but it's way more inconvenient and difficult to properly reason about the setup. If you use an IIR allpass, the issue is similar (you need a separate filter per impulse, or your cutoff modulation is likely to produce lots of aliasing).
As for single impulse being not bandlimited, actually it is. So in principle your approach is correct, but it doesn't look to me like a simpler one compared to standard approaches.
One thing you might consider is using Dirichlet kernels instead of windowed sinc. They give zero inharmonic aliasing.
Edit: actually they are perfect, but the integration used in BLIT is imperfect and can be seen as producing "harmonic aliasing"

mystran
 KVRAF
 5893 posts since 12 Feb, 2006 from Helsinki, Finland
The first plot looks approximately like you would expect with a simple (onepole?) allpass interpolator. Such an interpolator gives the correct delay at lowfrequencies only and if you look at the plot, there isn't much aliasing at lowfrequencies. This means it's actually working just fine. Unfortunately, at higher frequencies you need a much better interpolator to get decent results. I'm pretty sure this specific method can be found in some academic papers, but as you've observed the quality isn't great (even though at low frequencies it's way better than naive).
So why does a DWG not result in aliasing then? Because the feedback system is LTI and therefore has a finite number of resonant frequencies. Rather than causing aliasing, what an allpass interpolator does in this case is "move" the lowest resonant frequencies to the correct positions. The error is still there, but rather than manifesting as aliasing, it manifests as the higher partials being slightly out of tune (although it's slight enough that it's usually hard to see in a typical FFT plot with typical small allpass delay values; try larger delays in the allpass part if you want to see more clearly what is going on), which you see in the timedomain plot as "dispersion" where the spike progressively spreads on every roundtrip.
Long story short, you simply need (much) better interpolation and FIR interpolation (windowed sinc or otherwise) is probably going to be easier in the end (because either way you kinda need to be prepared to overlap the responses of multiple interpolators and this is a lot easier with FIRs), assuming Dirichlet kernels don't do what you need. Those are basically nice closedform solutions to a periodic bandlimited impulse; see Wikipedia for a formula, they are probably the easiest way to implement BLITs. FIR interpolators might work better than Dirichlet when it comes to modulation (specifically if you want to build something like PWM out of your BLITs; with Dirichlet you also need to crossfade two versions when changing the number of harmonics when modulating pitch, otherwise you get clicks), but cannot ever be truly perfect (though you can always make them better with the cost of extra latency and CPU use).
Also I want to note that if you plan on integrating the BLIT into classic analog waveforms, then you might want to also consider BLEPs instead, because generally writing a BLEP oscillator is a lot easier than trying to get the integration to work acceptably (at least if you care about low frequencies). Downside is that you don't get to use Dirichlet kernels.
[edit: random sidenote: if you want smooth modulation with a delay line, then "bucketbrigade" style fixed delay with a varying sampling rate, with resampling on both input and output can work wonders, at the cost of being ridiculously tricky to implement correctly and "somewhat" expensive on CPU if you want a large modulation range; great for stuff like a chorus though]
So why does a DWG not result in aliasing then? Because the feedback system is LTI and therefore has a finite number of resonant frequencies. Rather than causing aliasing, what an allpass interpolator does in this case is "move" the lowest resonant frequencies to the correct positions. The error is still there, but rather than manifesting as aliasing, it manifests as the higher partials being slightly out of tune (although it's slight enough that it's usually hard to see in a typical FFT plot with typical small allpass delay values; try larger delays in the allpass part if you want to see more clearly what is going on), which you see in the timedomain plot as "dispersion" where the spike progressively spreads on every roundtrip.
Long story short, you simply need (much) better interpolation and FIR interpolation (windowed sinc or otherwise) is probably going to be easier in the end (because either way you kinda need to be prepared to overlap the responses of multiple interpolators and this is a lot easier with FIRs), assuming Dirichlet kernels don't do what you need. Those are basically nice closedform solutions to a periodic bandlimited impulse; see Wikipedia for a formula, they are probably the easiest way to implement BLITs. FIR interpolators might work better than Dirichlet when it comes to modulation (specifically if you want to build something like PWM out of your BLITs; with Dirichlet you also need to crossfade two versions when changing the number of harmonics when modulating pitch, otherwise you get clicks), but cannot ever be truly perfect (though you can always make them better with the cost of extra latency and CPU use).
Also I want to note that if you plan on integrating the BLIT into classic analog waveforms, then you might want to also consider BLEPs instead, because generally writing a BLEP oscillator is a lot easier than trying to get the integration to work acceptably (at least if you care about low frequencies). Downside is that you don't get to use Dirichlet kernels.
[edit: random sidenote: if you want smooth modulation with a delay line, then "bucketbrigade" style fixed delay with a varying sampling rate, with resampling on both input and output can work wonders, at the cost of being ridiculously tricky to implement correctly and "somewhat" expensive on CPU if you want a large modulation range; great for stuff like a chorus though]
Preferred pronouns would be "it/it" because according to this country, I'm a piece of human trash.

Z1202
 KVRian
 1196 posts since 12 Apr, 2002
Oh, actually you're probably right, although I think the reasoning has to be more complicated. A naive 0subsample pulse is bandlimited and so is any result of its delaying by an LTI system, such as 1pole allpass. However, when those start to get mixed with other impulses you don't get the harmonic behavior, since delays are different at different frequencies. And one still needs to use different allpass instances for different impulses, otherwise cutoff needs to be modulated and that's a potential source of aliasing.mystran wrote: ↑Mon Aug 10, 2020 11:36 amThe first plot looks approximately like you would expect with a simple (onepole?) allpass interpolator. Such an interpolator gives the correct delay at lowfrequencies only and if you look at the plot, there isn't much aliasing at lowfrequencies. This means it's actually working just fine. Unfortunately, at higher frequencies you need a much better interpolator to get decent results. I'm pretty sure this specific method can be found in some academic papers, but as you've observed the quality isn't great (even though at low frequencies it's way better than naive).
thismystran wrote: ↑Mon Aug 10, 2020 11:36 am[edit: random sidenote: if you want smooth modulation with a delay line, then "bucketbrigade" style fixed delay with a varying sampling rate, with resampling on both input and output can work wonders, at the cost of being ridiculously tricky to implement correctly and "somewhat" expensive on CPU if you want a large modulation range; great for stuff like a chorus though]

mystran
 KVRAF
 5893 posts since 12 Feb, 2006 from Helsinki, Finland
Wrong. If you center an infinite cardinal sine (with bandwidth exactly up to Nyquist) at exactly one sampling instant, then there will be exactly one nonzero sample. In continuoustime, the cardinal sine then has a zerocrossing exactly at every other sampling instant and is nonzero everywhere else. This is the whole fundamental basis of NyquistShannon sampling theorem and if a singlesample impulse wasn't bandlimited, then you could not possibly have any bandlimited signals at all (where as the opposite is true: sampled signals are always bandlimited; whenever you see aliasing, it happens because you are essentially resampling something without necessarily realizing it).
Instead the aliasing happens because no practically realisable fractional delay filter can possibly have exactly the same response (modulo the desired delay) for different offsets, except at frequencies approaching DC (in the limit sense). When you then build an impulsetrain by using different offsets, the responses of the different impulses don't quite match (or equivalently, the interpolator as a whole isn't bandlimited in continuous time; this is easier to analyze, but the "not quite matching response" is probably easier to understand intuitively) and hence the result isn't quite what a combfilter would produce in response to a singlesample impulse.
But there is really nothing wrong with a single impulse. It's just a single cardinal sine, sampled exactly at the center point and perfectly bandlimited by definition of NyquistShannon.
edit: The classic paper is actually pretty easy to read: https://web.archive.org/web/20100208112 ... npaper.pdf
Preferred pronouns would be "it/it" because according to this country, I'm a piece of human trash.

mystran
 KVRAF
 5893 posts since 12 Feb, 2006 from Helsinki, Finland
..
Last edited by mystran on Mon Aug 10, 2020 1:46 pm, edited 1 time in total.
Preferred pronouns would be "it/it" because according to this country, I'm a piece of human trash.

mystran
 KVRAF
 5893 posts since 12 Feb, 2006 from Helsinki, Finland
The scheme I described can be found in this plugin: https://www.kvraudio.com/product/dustb ... signaldustZ1202 wrote: ↑Mon Aug 10, 2020 12:46 pmthismystran wrote: ↑Mon Aug 10, 2020 11:36 am[edit: random sidenote: if you want smooth modulation with a delay line, then "bucketbrigade" style fixed delay with a varying sampling rate, with resampling on both input and output can work wonders, at the cost of being ridiculously tricky to implement correctly and "somewhat" expensive on CPU if you want a large modulation range; great for stuff like a chorus though]
Last edited by mystran on Mon Aug 10, 2020 2:09 pm, edited 3 times in total.
Preferred pronouns would be "it/it" because according to this country, I'm a piece of human trash.

mystran
 KVRAF
 5893 posts since 12 Feb, 2006 from Helsinki, Finland
Anyone else feel like the forum buttons (eg. reply, edit) are really hard to tell from one another ever since they made them icons instead of text...?
Preferred pronouns would be "it/it" because according to this country, I'm a piece of human trash.

juha_p
 KVRian
 620 posts since 21 Feb, 2006 from FI
This is little out of subject question but, regarding Dirichlet kernels, bumped to this paper "The good, the bad and the ugly of kernels: why the Dirichlet kernel is not a good kernel" by Peter Haggstrom who mentions there Fejér kernel being a good kernel. If it's better then, isn't it suitable kernel for this type implementation in discussions? (yes, math newbie here )
EDIT: The boxcar function and Gibbs phenomenon, compared .......with the smoothed version based on Fejer’s summation:
Closeup:
You do not have the required permissions to view the files attached to this post.
Last edited by juha_p on Fri Aug 14, 2020 2:18 am, edited 1 time in total.

Z1202
 KVRian
 1196 posts since 12 Apr, 2002
I didn't read the paper, nor am I really familiar with Fejer kernel, but I'm pretty sure it's about the convergence analysis of Fourier series, not about being better for antialiased impulse train. Dirichlet kernel is a perfect BLIT.juha_p wrote: ↑Thu Aug 13, 2020 12:57 amThis is little out of subject question but, regarding Dirichlet kernels, bumped to this paper "The good, the bad and the ugly of kernels: why the Dirichlet kernel is not a good kernel" by Peter Haggstrom who mentions there Fejér kernel being a good kernel. If it's better then, isn't it suitable kernel for this type implementation in discussions? (yes, math newbie here )

Z1202
 KVRian
 1196 posts since 12 Apr, 2002
Just the definition itself. It's a sum of impulse train's partials up to a freelychosen boundary.
A related fact is that the partial sums of Fourier series can be seen as convolutions with Dirichlet kernel, which in frequency domain simply cuts off the partials above the same boundary by multiplying their amplitudes with zeros (while the others are multiplied with 1's). See the Fourier series convolution property. It's pretty much like sinc convolution in the sampling theorem, just for periodic signals instead. Dirichlet kernels are "periodic sincs"