Oscillators - train and triangle? - or something else?

rsweeten's icon

Hi,

I'm working on writing a multi-mode oscillator configuration in gen/codebox, and would love some advice on the triangle and train sections, since these aren't oscillators per se.

I'm using Train and Triangle , but I'm pretty sure that's not the right way to do it.. I've included what I have so far.

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

Ray

geddonn's icon

Hmm, when I load your patch the Gen subpatcher appears to revert to default (ie. in1 + in2).

Andrew Benson's icon

It's because we don't have the gen file.

rsweeten's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Oops.. (it's copy compressed in the gen file, right?)

rsweeten's icon

nope. how bout this..

3611.oscCore.gendsp
gendsp
Graham Wakefield's icon

Train is a pulse generator, so it is 'sort of' an oscillator. It's not driven by frequency, but rather pulse period, which is specified in samples. So [train 44100] pulses once per second (1Hz) for example, and [train 22050] pulses at 2Hz etc. It's basically inspired by the MSP [train~] object, but measures time in samples rather than milliseconds.

Triangle is also inspired by the MSP [triangle~] object. It is more like a wave shaper. The name comes from the fact that if you send a phasor ramp in, you get a triangle wave out. The result is not band-limited, so it's more useful for LFOs.

Hope that helps!

Peter McCulloch's icon

There's been a lot written about band-limited (or alias-reducing, more accurately...) oscillators. Unfortunately, for most of them the math is not easy to follow.

This article in CMJ was pretty good: "New Perspectives on Distortion Synthesis for Virtual Analog Oscillators". Here's something based on it that I've extended to include PWM, and can handle FM!

If you don't mind the darker sound, you can just skip the postfilter. This is not production-ready (probably need to move filters inside of gen...), but it sounds pretty nasty.

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

`

LiamCormacGould's icon

man that is sick!!!

rsweeten's icon

Thanks Peter for the great reference! That's really awesome. And thank you for the code.

I actually recently acquired the Audio Programming Book, and Lazzarini looms large there as you probably know. It was the first place I looked for information on band-limiting.

I rolled the FM (with the exception of the line~ objects, I don't think there's an equivalent in gen~) and PWM into gen and introduced some AM as well (after the tanh). As a sort of personal challenge I also I translated the object style to GenExpr code boxes.

I noticed that for cycle in GenExpr, you can't set the index to phase. In the docs it says "In GenExpr, only the built-in sinusoid wavetable can be used", I have to think that means you can't set the index attribute, but the language is not entirely clear, or I'm doing it wrong.

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

Still haven't gotten my head around history in gen for the filter section.. maybe that'll be my next undertaking.

pid's icon
Max Patch
Copy patch and select New From Clipboard in Max.

i think cycle not being able to be set to phase index in GenExpr is a bug. i do not see why it should not work.

pid's icon
Max Patch
Copy patch and select New From Clipboard in Max.

and here is peter's "post filter" in gen~ for fun:

Peter McCulloch's icon

Re: cycle not being able to set via phase: I wonder if this has to do with table lookups not working inside genexpr. That's my best guess.

Thanks for posting. I'm working on an optimized version now.

Graham Wakefield's icon

Confirmed the indexed cycle in GenExpr is a bug; and the fix is going to be in the next Gen update. Also the buffer/data limitation is going to be lifted too :-)

stkr's icon

Great news Graham. Gen just keeps on giving.

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

Here is a resonant twopole Highpass that might be interesting in this situation:

Peter McCulloch's icon

Here's my tweaked version. Most of the calculations are replaced with lookup tables. The pulsewidth can go as narrow as 1% now (was previously 10%)

After a little evaluation, I found that a fixed highshelf filter gave a better result, so that's in there in place of the moving shelf. (highpass + original)

Also, the FM is much cleaner in this version since I've got it connected to the PWM, so there's less stepping as you sweep the modulation index. One thing to note, because the FM is interacting with the scaling factor, the sound is not as bright, because the spectral tilt becomes that of a modulated sine rather than a modulated square. I think this is a more useful sound.

It's more expensive as an oscillator than rect~ and slightly brighter, but you do get FM. The tradeoff, for the time being at least, is the lack of hard sync. Need to brush up on maths before that one gets dealt with...

3637.PM.PWM.maxhelp
maxhelp
rsweeten's icon

Good to know about the indexed cycle.

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

So I thought I'd try to tackle equation 22 (Moog-like Sawtooth) on Page 34 of that CMJ article PM cited above, and maybe this isn't the place for this, but here's what I have after blindly swinging at the thing.

3643.ScreenShot20120403at1.35.44PM.png
png
FP's icon

hello, where is [PM.PMW~] please ?

jayrope's icon

Train and triangle derived from phasor wave below. Self-explaining, i guess.

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