[Share] Functions for Wave Terrain Synthesis

Noah's icon

Yesterday I spent a bit of time copy-pasting the terrain generation algorithms from this wave terrain synth's github page:

https://github.com/aaronaanderson/WaveTerrainSynth

This is not my own work. I feel obligated to emphasize that. Aaron Anderson did everything in the original project (which is excellent- I suggest downloading it and checking it out), and I just stuck part of it in Gen~.

The math here isn't very stressful on CPU, so I decided to just have the output calculated rather than written into a buffer (also because I'm lazy....). These could also be used as waveshaping functions, if you were to edit them a bit. The fact that there's inputs for both x and y "coordinates" also means that trajectories are completely open ended, and not at all limited to what's generated by two sawtooth waves like I have in this example patch, so I'd recommend trying different ideas of your own. Have fun!

wave terrain functions.maxpat
Max Patch

quat's icon

Great share. Thanks!

Aaron Anderson's icon

Hi Noah!

Thank you for doing this; I've had some fun playing with this in Max. One issue I really wish to solve is the aliasing. It becomes a super prominent issue with large/complex orbit sizes. (I'm working on an oversampling implementation in the C++ version)

I'll be stuck in a plane for 20 hours this week so I'll try to put all my orbits in the max patch and report back here.

For those that are interested, I discovered this synthesis method while reading 'The Computer Music Tutorial' and found a lot of deeper information through research done by Stuart James.

I'm happy to see this is getting some mileage, thanks again!

Aaron

Noah's icon

Yeah that's something I noticed too. Sadly, though I don't know a whole lot about things like bandlimiting or other AA methods outside of upsampling. It didn't cross my mind at the time, but it probably wouldn't be difficult to make a poly~ file for this, and just increase the samplerate there. Other than that though I don't have a whole lot of solutions :/

Aaron Anderson's icon

It would be very difficult to execute in Gen~, but oversampling and filtering is the only real solution to the issue in this case. If I recall correctly the DX7 had aliasing and it seemed to do alright. For now we can just call it a feature, not a bug. I've uploaded a new version of the patch with a drop down menu for orbit patterns and a few presets. Have fun!

waveterrain.maxpat
Max Patch
added orbits and presets

Andrew's icon

Thanks for sharing, this is really nice.

.quasar's icon

Very nice ! As for the oversampling in gen~ I have been quite interested in implementing it myself in gen~.

It is definitely doable, but indeed quite difficult depending on the technique. I think for Wave Terrain Synthesis, a good solution would be to use the upsampled phasor method. There is a good example of a X8 Upsampled Phasor macro in the following link (in Reaktor Core) which can be adapted quite easily :

The main difficulty (at least for me) is the X8 downsampling filter which should accompany this macro. I have a good macro for that in Reaktor Core, but I just haven't managed to adapt it to gen~ yet.

Otherwise, there is a simple X4 Upsampling example in the ClingWrap patch of the Owl package.

JBBollen's icon

Thanksalot, Noah. And a very good step-up, Aaron (long-haul, were we? I use my yearly flights from NL to NZ that way ;-). The whole thing has an FM-on-steroids-quality. Very interested in the gen~ implementation. I just received my OWL pedal and I am thinking about using it just as a sophisticated Fuzz on my ebass to get that contemporary DnB crunch. It would have to be pure gen~ , though. @.QUASAR, The ClingWrap patch is one of the more interesting ones - studying it very carefully ;-)