Gaussian Blur 2D patch for Lich

You probably don’t need to boost the signal, because you get more or less the same result after compressor when you lower threshold and increase makeup gain.

I was thinking, another (a bit less common) approach for writing compressors is to use analytic signal from Hilbert transform to get signal magnitude. That means taking a real signal and sending it to 2 chains of allpass filters that produce complex signal in quadrature. The advantage here is that for a complex value we can get magnitude at any moment (at the cost of some fixed delay added during Hilbert transform).

This patch is already working with data in 2D, so maybe it could be possible to treat it as complex values and use magnitudes from the blurred texture? You might think that it’s similar to looking at RMS from a single axis, but instead of having to obtain average over multiple samples we would be able to use a momentary value.

Brilliant stuff once again @damikuy. You are really upping the game with your patches and videos.

Just a thought: instead of gain compensation, could the kernels be normalised? Or are you already doing that?

1 Like

Yeah that’s what I thought too and maybe I’m just not doing it right. I enabled AutoMakeup and heard no increase in loudness even when pulling the compression threshold all the way down to -80dB. I could hear compression taking some effect around -40dB, but without a significant boost in volume.

I’m not sure I follow what you are suggesting here. It sounds like it would introduce even more computation than the regular compression does.

Thanks for you kind words @mars!

The kernels are already normalized, have a look at setGauss in BlurKernel.h. I suppose I could add a signal boost here, not sure how that would change things.

Ok, so after spending a long time fussing with the gain compensation and getting to work kind of OK, I started looking at the zipping when changing texture size and finally implemented a fractional texture size scheme so that I don’t have to blur at two adjacent texture sizes and blend between the results. This freed up enough cycles to be able to lerp texture size across the block as well as update the kernel across the block with the delta approach you suggested. Once those were both implemented a magical thing happened: the gain compensation is no longer necessary because even at maximum blur, the signal strength is diminished only slightly. There is now only barely audible zipping when changing texture size with a simple waveform, but also the effect is now much more subtle, rather than the intense flanging and comb filter kinds of sounds that were happening before. I think the comb effect was actually just the weird discontinuities that happened while sweeping texture and blur size introducing related overtones in the high frequencies.

I’m going to spend a little more time with this tomorrow before pushing it to the public patch because it is 3am and maybe I messed something up. But at the moment, this feels a bit like a breakthrough.

1 Like

I finally have everything working nicely and have updated the public patch! Texture Size and Blur Amount can be modulate quite heavily without too many audible artifacts, thanks to fixing how I was offsetting how the samples are read relative to the write head of the circular buffer. Now it produces the kind of pitch warbling one expects from delays and flangers.

I removed my gain compensation code completely because now the signal loss from blurring is small enough that the Daisy Compressor works as one expects. I went ahead and exposed all of the compressors settings as MIDI parameters and gave them defaults that will make the compressor kick in only when the blur goes above 0 dB.

I also added a “brightness” parameter that can attenuate or boost the volume of the input signal as it is blurred, so you can either push a louder signal into the compressor or boost the signal level after the compressor with the make up gain.

All this and it performs better than the previous version. :smiley:

Two things I’m not entirely sure about:

  • compression is applied only to the blurred signal, not the final dry/wet mix. I did this so that fully dry will always be exactly what’s coming into the module, but I wonder if it might be nicer to compress the mixed output?
  • the compressed blurred signal is what’s put into the feedback path, but I wonder if it makes more sense to only feedback the uncompressed blur?

After all of this I now feel like I need to rerecord the demo video because the sound of the thing is so much better.

I would agree that it makes more sense not to compress dry signal. Also maybe there should be a control for amount of wet to compressed mix, i.e. to allow parallel compression on wet signal rather then fully compressing it.

This would make feedback level dependent on amount of blur in addition to feedback amount. I think that current approach makes feedback more controllable, but it should be easy enough to give the alternative a try too. Uncompressed feedback can have some advantages, i.e. you could try sending triggers to make the patch ping, compression could prevent this at it adds some lag and may prevent self-oscillation.

Ah, yes, I can add this. Although it is kind of funny to me that this patch basically has a fully-functional hidden compressor now.

I just tried pinging the patch as it stands and it seems to more or less work. It’s definitely the case that playing with high feedback and compression yields some interesting results, so I will probably leave the feedback in the compression path.

And since the thing that sent me back to working on the patch to eliminate the noise caused by my poor gain compensation was playing my Rhodes through the patch, I decided to try the Rhodes again and this patch makes for a nice stereo chorus effect, although I think I had gain up too high on my Instrument Interface so there is some distortion in the Rhodes from playing loudly. Might be even nicer if I dialed that back and boosted the signal going into the blur, which would then hit the compressor and hopefully not get so crunchy.

There are still some nasty audible artifacts, I would say that they mostly coincide with decay phase of bigger chords. Not sure if that’s compressor kicking in or something else.

Oooh, yes, I can hear those quite clearly in headphones. They were not noticeable to me listening on my monitor speakers. I didn’t really have the compressor engaged in this recording, but was using envelope followers to modulate some things, so it could be something to do with that. Although there are a few loud spots where I’m just playing single notes that don’t seen to cause the crackling. It feels like the crackling is mostly there with denser chords.

I’ve finally fixed the clicking when modulating texture size and added a blend parameter for the compressor so we can blend between uncompressed and compressed blur. It does change the sound pretty substantially from the previous version, but I think it is also the more correct implementation of the concept. There are definitely some sweet spots to be found where some subtle tilting of texture size and dialing in of feedback give a mono sound quite a nice stereo field.

I think tomorrow I will rerecord the segments for the demo video and maybe do another Rhodes improv to show the difference in sound there.

1 Like

Don’t have time to check it out myself right, so I’ll just ask here.

Does anything interesting comes out if you visualize output in 2D rather than as 2 mono channels? There are a few scopes with Lissajous mode in VCVrack you could use when recording video.

Oh, good question, I haven’t looked at the output in XY mode on ZeroScope. I’ve been visualizing it as square textures for left and right channels because the blur is two-dimensional within each channel, so doing that hints at the Y-Axis blurring that’s occurring. But the Lissajous mode might be interesting when skewing texture size or blur on a mono signal.

I tweaked a few things in the patch and improved the resampling I’m using so that it doesn’t introduce as much resonance to the signal. So I’ve finally recorded a new version of the demo video with the updated sound of the patch. It’s very different, it turns out, and much more of a low pass filter like one would expect. Oh and I use the XY mode on the ZeroScope for most of it, which is pretty interesting on a square wave.

1 Like

It took quite a while to finish this one, didn’t it? But the patch finally sounds right.

I have a small suggestion to try regarding feedback. You can use a complex number describing feedback when dealing with quadrature audio. The way I usually do it is by adding 2 parameters - FB magnitude and FB angle and storing current value in a ComplexFloat. Then you can use that number’s real/imaginary parts to set feedback for each channel.

With a scalar feedback you can see its effect that distorts waveshape diagonally, but using complex value you can rotate it by adjusting angle. It’s easier to see it on the scope than describe.

I’m not sure I understand what you are suggesting for feedback and I don’t think the audio in this patch is quadrature? Are you suggesting that it could be treated that way? If you can point me to a code example of what you are talking about, that might be easiest for me to grasp.

Although, yes, I did notice the diagonal waveshaping effect of feedback on a sine wave during testing at one point.

Well it’s an effect processor that takes 2 channels. So if you’re sending data in quadrature (or we should probably say complex audio signal), it would be processed as such. And you have 2 separate channels of feedback, so they can be applied in a fashion I’ve described.

The code is rather simple, here are relevant pieces as used in polygonal VCO:

1 Like

Either I’m still confused about how you see this being applied, or possibly you are confused by what I’m talking about when I talk about blurring along the X and Y axis. I’ve tested out an addition of feedback angle and realized that in the context of this patch, it just amounts to skewing the level of feedback applied to the left and right channels of audio, which is more interesting when processing a raw waveform like square or triangle because light feedback will waveshape them in subtle ways without producing a ringing tone. But for more complex material, like a drum loop, turning up feedback just produces a ringing sine wave, so adjusting the angle just pans this ringing to the left or right.

Here’s the change so you can see if I’m implementing this as you are suggesting:

The X and Y-axis blur passes are performed in series and both the left and right channels have XY blurs applied to them. So it’s not that I process the left channel of audio and wind up with a complex signal that this complex feedback could then be applied to. However, what might be interesting is to add feedback to the BlurProcessor implementation and then give the GaussianBlurSignalProcessor a setFeedback method like the one for your Polygonal Oscillator. This would allow setting feedback levels for the X and Y blur passes differently, with potential feedback signal inversion as a result. This makes more sense to me, since the X and Y blur passes are essentially delayed low-pass filters (although Y-axis is not quite this because it can lerp between non-adjacent samples when sampling the signal), to set the feedback amount for each delay-filter independently.

No confusion here, I just wanted to bring up the complex feedback topic as a possible addition to this patch. I understand that at this stage audio channels are treated as dual mono. Such modification to feedback obviously doesn’t change it considerably, but adds and extra dimension that can be modulated.

Or some kind of complex signal, like knoscillator’s output :wink: That said, I usually add a channel of feedback or two to any attempt of making complex VCO.

Ok, cool, glad we are on the same page! I did wind up implementing complex feedback internal to GaussianBlurSignalProcessor just to see how it would sound. It’s interesting and with light feedback provides a parameter that can be swept that subtly alters the timbre of the sound. With higher feedback it can result in two feedback tones: one bass tone from the X-axis and one higher tone from the Y-axis. These are a bit more interactive than the single tone produced in the public version of the patch, but I’m not sure how much I like it, so I’ll probably play around with it a bit more. It’s checked into my development branch if you want to try it out:

The version above where it’s just essentially skewing feedback amount feels like it fits a bit better with the Patch as it stands, since the notion of stereo skew is already present for texture size and blur size. One thing I’ve noticed is that feedback becomes more sensitive under lower blur size settings, so I wonder if it might make sense to use the amount that blur size is skewed as the feedback angle.

Oh good point, I think I will add this when revisiting Knoscillator for Genius.