Implementing scanned synthesis

Noah's icon

Would it be possible? I'm really fascinated by this synthesis method lately, but I've been uncertain what it actually means in this context to have the wavetable "constantly updating" at a certain frequency.

There's two interpretations of I've thought of: 1. To have whatever physical modelling or chaos function be excited or calculated that many times per second, and written into the buffer via the counter and poke operators. In my tests though, this had pretty terrible results in terms of sound. The second idea was to have a for loop write the chose function into the buffer at the chosen frequency. The problem with that though is that having a complex mathematical function calculated at least 128 times in the period of a single sample is incredibly computationally expensive.

The only other idea I have (but haven't tried yet) would be to have the for loop calculate 1 iteration of my function, then have the buffer write a straight line between that and the previous iteration. I'm have a suspicion that that would only give me strange saw waves though, and given the timbral complexity in the examples of scanned synthesis I've heard, I doubt that's what's done in a proper implementation.

Anyone have any definite knowledge on this? Detailed info about how to actually do this technique seems to be very scarce on the internet.

Max Gardener's icon

Searching the Forum is always a good idea. For example, you might find something like this:

https://cycling74.com/forums/scanned-synthesis-in-max-msp

Noah's icon

I am well aware of that thread, but it doesn't answer my question. I'm curious what the ideal process of updating the wavetable is, and if it's possible to implement in Gen~ efficiently; not if there is an external to do it for me.

.quasar's icon

The Qubit Scanned definitely reignited my interest in this synthesis technique. Most of the max externals are starting to be quite old and I couldn't find any Win64 version of the msd package so I'm wondering if jit.gen could do the trick. I do think so but I'm nowhere near the level required to do such things yet .

Has anyone tried to animate a wavetable with jitter or jit.gen ?

Noah's icon

Oh hey look someone else was curious. Good news, I did it, a while ago in fact. I just never got around to posting it till now. Mirrored info from a post I commented on in the facebook group:

Things to note: 1. "scanned synth beta" is a standalone patch to just futz around in without adding any extra filters or distortion or whatever. "scanned synth beta module" is sort of like a BEAP module, but without the whole "signal multiplied by 5" thing going on. In both versions, you have a little xy pad you can click and drag on to control force and offset. The "scanned synth beta" version has an oscilloscope behind it which gives some visually pleasing feedback, but I wasn't able to get it to work in the module version for whatever reason. Either way I think it's pretty fun and intuitive personally.

2. This is *not* very computationally cheap. This is a gen~ patch (and it seems to be pushing gen~ to its limits), though I've been intending for a long time to make an external version, but never got around to it. I tried to do it with the new API, but I don't think that that was designed for anything like this.

3. This does not sound anything at all like Qu-Bit's "Scanned" module, I'm aware. But in my research I stumbled upon a few videos from the original research done by Verplank, Shaw, and Matthews, and I can say with confidence that mine does sound much closer to that (not that Qu-Bit's is *bad*, I just don't have any idea how they got it to sound like that)

Scanned Synth.zip
application/x-zip-compressed 112.36 KB

Noah's icon

Oh also, put it in presentation mode, I forgot to make that the default. Sorry!

.quasar's icon

Oh great thanks !! Looking forward to trying your patch ;)

.quasar's icon

Really awesome, thanks for this ! Started playing with the "scanned synth beta" patch and I'm really liking the tones.

Quite weird how this synthesis technique appeared 20 years ago but less than a handful of papers have been published about it besides Mathews' original paper. That's why I was actually pleased about the Qu-bit's recent hardware implementation.

.quasar's icon

Still loving it ! One remark I have to make is that scanned synthesis is an especially difficult synthesis technique to pick if you want to manage the aliased components of the spectrum (true for all implementations of scanned synthesis I tried - Csound, Pure Data and now Max). I wonder how one could go about implementing an alias-suppressing strategy with scanned synthesis. I guess oversampling via poly would be the easiest option but it's just so CPU expensive...

I recently fiddled with Geiger's integrated wavetable antialiasing strategy (like dpw but applies to all wavetables). I wonder if that might work, although the integration is supposed to be non-realtime.

Otherwise there is polyblep and polyblamp but I would need to be able to figure out where and when exactly are the discontinuities happening.

.quasar's icon

I did a few tests and Geiger's alias-suppressing scheme for wavetables does work with your implementation of scanned synthesis.

I think the aliasing is noticeably suppressed as you increase the frequency. You could go even further by oversampling by a factor 4.

Here is the patch (which requires Noah's wavesets and javascript function included in the link previously posted.)

@NOAH : I'be interested to know what you think ;) I believe there's a lot of potential in your patches

Max Patch
Copy patch and select New From Clipboard in Max.

Teo Lowstein's icon

Hello,

I have two questions on @NOAH 's Scanned Synth Beta patch: How can I change it to make it usable in a poly~? I'm a real newbie when it comes to Gen~, but it seems that, since the code uses buffers to calculate the "wave scanning", I cannot interact with one instance of the poly without messing with the others (the only thing I can make is change the frequency, but all other things are shared).

The other thing is: is it possible to use the wavetables created by the patch in a CSound code using the scanu opcode? I can see a lot of similarities between the patch and the opcode, but since there is no matrix in the patch, I couldn't figure out for myself