Quantizing cosine output to a scale

Gulshan Singh's icon

Hi, I'm new to Max/MSP. I'm a big fan of Andrew Sorensen, and I was watching one his videos here: https://www.youtube.com/watch?v=yY1FSsUV-8c. In his video, he uses the output of a cosine function and quantizes it to a scale to create an arpeggio.

How would I do this in Max/MSP? Should I use line to feed inputs into the cosine function or is there a better way to do it? And after that, how would I do the quantization? Would I have to make a bunch of < and > patches that check if the values are between certain ranges and then map them to notes? Is there an easier way?

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

Here's a start. I'd recommend using an MSP object to generate the cosine function at audio rate, and then sampling its values. The series of [if] objects is a good, modular way to go. Perhaps there's a better quantization method - I've found myself in want of one too.

Wetterberg's icon

I think I inadvertently made something really pretty-sounding.

Anyways, this goes beyond "line" use, since it'll sync to your global transport, meaning porting it into MaxForLive or something should be trivial.

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

And just to be at odds with the majority, I'd recommend not doing it at audio-rate, because I find I'm downsampling to 16th notes anyway. So that's my position on *that*, hehe.

brendan mccloskey's icon
Christopher Dobrian's icon
Max Patch
Copy patch and select New From Clipboard in Max.

I agree with @Wetterberg that MSP is overkill for such a task. In fact, to be even more efficient you can just calculate one cycle of a sine (or cosine or whatever) once, then use it as a lookup table. (Although buffer~ is ostensibly an MSP object, with peek~ you can treat it simply as an array of floats, and MSP doesn't even need to be on.) Here's an example where I fill an array with 512 samples of one cycle of a sine wave (that's sufficient resolution for MIDI note purposes), then read through it to get a value between -1 and 1. The increment through the array depends on the number of notes you want per cycle, and you can set the center pitch (offset), the amplitude of the sine (in semitones), the scale you want to map the results to, and a key transposition at the end.

Wetterberg's icon

aw yeah, using the fill sin message is nice and elegant, for sure!

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

Made me think of a glaring error in my own patch:

james holden's icon

in case anyone else really "NEEDS" to do scale quantizing at audio rate (i'm making a intellijel uscale clone today) and finds this with google, this thread gave me the idea for an efficient solution: a lookup buffer.

when a scale is selected you fill a half-second-long buffer (using poke~) with a quantized value for each input frequency (eg for 44.1khz this would be 0-22050Hz) integers will do fine. this only needs to be done when the scale changes and is trivial.

then for the audio rate quantize you feed your input frequency (as a signal) to index~ - look up the quant. version in the buffer - and on to your oscillator.