Edison, New Jersey, USA
an easier granulator in max
StoreTags: max msp, granular synthe, flies, stutter
Author: flies on July 28 2006
Viewed 5097 times. 7 people liked this blog. You can rate it below if you haven't already.
People who enjoyed reading this: Otterfan, jdg, p, PAWEL, daswesen, ejectorset, mapmap
--> i will soon have a computer on which to implement my max patch ideas, but while i wait here's another patch idea.

warning: this post is a bit verbose. so sue me. I explain this at length so as to flesh out the idea so that when I code it i'll have a good idea of what i'm doing (clear goals are key!), and also if you want to build this

the idea is to make a 'streaming' granulator (runs off of an audio input instead of a static buffer) letting the packaged object 'stutter~' to handle the buffer juggling. stutter~ takes in audio and records it to a record buffer of specified length. when you give it the say so, it will transfer the contents of the record buffer to a playback buffer, which you then read out like wave~ with a phase input (signal not message).

the simplest application of stutter~ is to take the audio in and play back one little portion of it. when you bang stutter~, it takes the last buffer, so you can get simple time-stretch-esque effects, akin to buffer override, gantz graf etc.

probably next simplest (which i have tried and i think it sounds cool), is to use stutter~ as a lofi pitch shifter/time stretcher. by sending stutter the output of an sfplay~, and coordinated control of the playback speed of sfplay and stutter, you can do pitch bend and time stretch. maintain sfplay speed and increase stutter speed and you can pitch up with no change in speed. decrease sfplay speed and increase stutter speed and you can stretch the sound without altering pitch. (getting the ratio between stutter speed and sfplay speed right was a little tricky when taking a variable grain length into account, but beyond that it's hardly different from the help file for stutter~)

plus stutter allows you to vary the per-grain amplitude randomly, and it allows you to give it a probability that the next grain will repeat the previous - stuttering, you might say. A third variable is a probability that the playback buffer will become silent. The fourth variable is grain length.
those four variables alone make an interesting effect. add the time stretching and it makes a decent instrument.

so that's what stutter does, but my most recent idea was to use stutter as the heart of a more refined granulator. the main refinement i offer is to remove the noise that arrises from uninterpolated loop points by windowing. so at the beginning of each grain, you have a fade in, and a fade out at the end. The other main addition is to add more simultaneous grains.

this idea uses three or more parallel stutter~ objects running at equally spaced phase (0, 0.33, 0.66) with trapezoidal crossfading so that at all times 1 fades in, 1 fades out and one runs at full volume. probably the best way to do the crossfading would be with buffer lookup triggered by the very same phasor that drives the stutter object. note that the trapezoid will also be split in 3 equal parts: _/ (flip that so the underscore is on top and it should be clear). It would be equally possible to use different window shapes, all one would need to do would be use a different buffer.

this makes a time-synchronous grain cloud, with per-grain randomness of amplitude and possible cutoff. it would be relatively straightforward to add a per-grain randomized filter as well by using the driving phasor -> xover~ -> sah~ to control the filter parameters. one could do likewise for per-grain panning.

this is a relatively simple form of granulation, but there are some cool aspects that wouldn't be found in other granulators. the main thing that i think would be cool would be the way the repeat probability would work with multiple parallel stutter~ objects. if you set the repeat probability pretty high, each stutter would have a good chance of repeating a single grain over and over, but since each would repeat a different grain, you'd get an unusual texture.

you could also vary the relative timing of the grain start to get an effect similar to the 'quantize' parameter of the DLGranulator in audiomulch. i don't know whether the relative timing would stay constant as the grain size changed, b/c that requires changing the frequency of the driving phasor. i'll have to test that.

anyway, it should work and i can see how it will work. i'll post it when i get my computer back and have time to build it.



Read flies's other blogs.flies's Recent Blogs
Comments

This method sounds interesting, I'm curious to see how it works (as I'm not great at visualizing from text descriptions).

I was actually going to post my audio rate granular engine (that I'm using as the guts to build my sequencer) today (I was packaging the components for ftp when I noticed this)...are 2 blogs about granular sound too many?

YES I AM FIRST YOU WAIT j/k

FYI I just tried...stutter~ is a little glitchy when the phasor~ rate changes. however I didn't try changing the number box to on mouse-up so maybe that would help.

also make use of poly~ for the grain generators, then you can make changes to the number of instances quickly as you're working (in case the number of streams is too cpu intensive) (You probably knew this, I've just notived that there aren't alot of poly~'s on granular stuff outside of the example in max)

and I won't worry about posting mine 'til I'm finished with the entire sequencer...I just got excited about figuring out totally audio rate asynchronous from a buffer~ (that is cool, right?)

hope you don't mind the comments...But, I figured since I've been working on granular for the last couple of weeks in max..perhaps I should pass on what I've found.

sounds cool

i've already done a little bit of work to get stutter~ to work reasonably well with changing rates, although you're right it is anything but smooth. poly would be a good addition when i get around to making a 'time-asynchronous' granulator, with randomized inter-offset times (ahh jargon...i perhaps should say 'stochasticaly variable inter-offset time'), but the way i intend to implement the idea has each grain constantly playing, so poly~ wouldn't help except in terms of visual clarity.

asynchronous grain scheduling sounds better, but it'd be a little bit harder to implement.

actually, i didn't know that you could use poly~ without involving messages to turn 'notes' on and off, so that's news to me

anyway, it'd be rather annoying of me to put this idea out there and then get snotty about what people have to say about it (within reason), besides which i can only benefit from your experience.

pwl: stutter seems to have been added in 4.0. the rest is version independant.

I'm using reaktor for my grain processing in the audio core dsp thing and I have used max/msp.. so I am going to put my two cents in.
If you want to stop the noise or clicks in you grain windows the best way to do this is to use to sin wavs that are inverted to each other. the time or freq of the sin would be directly related to grain size in ms. Though if you wanted to have cutoff filters on each grain this would probably lead to an extremely amount of noise since the values would jumping around super quickly... you could avoid this using a env that was set to ms of the grain but this might not be the effect you are looking for. I'm wondering want kind of grain size are you looking to use?? Quantizing the grains seems very odd to me because, if you want to have a sample timestrech out to fit over a certain bar length in seconds, you will probably want the grain to be flexable in size to remove the artifacts that happen in grain sampling.
For live grain sampling I would say that all you need to do it get a decent grain algothrim going for a normal sample buffer and then use it to reference the buffer that is recording the input.. you will want to have the recording and the aloogthrim running at the same size ... and also make sure that the play head is running behind the recording head because, most of these gui based programming languages neeed a few seconds to read the array.

the idea is to avoid the click by using an amplitude envelope. the way stutter works is that you read from the playback buffer using a ramp wave that goes from 0 to 1 - like a play head, as you say. by using this same ramp wave to read out the buffer of the envelope, things ought to work out, since you'd switch the filter frequency while the grain was at 0 volume.

as for grain size, the stutter~ object takes a grain length argument in samples, so it could theoretically make grains as small as 3 samples, although this would of course be pointless. preferable would be grains as small as a few ms up to say 1/3 of a second.

the buffer juggling is definitely a tricky beast to handle, but the stutter~ object does all that for me, thankfully.

i'm not sure if env or sin is better... I would guess that the sin wav might be i little easier to mange to keep in sync but that is my guess. i could be wrong.... I would say try it out. I looked at the stutter object and i'm not sure if it wouldn't be easier to design you own grain sampler from the ground up. imo. I have been debating about going on this whole rant about using sample rate counts and array indexs but, I think I'll hold back on that.
; )
But if you want to know just ask.. The stuff I did in reaktor can pretty much be used in any audio language because, it's all just numbers.
heart
evan

hope I didn't come off like a complete wanker in my earlier posts. your idea was actually something I wanted to create for my last live show but couldn't figure out how to do it.

how did you get a smoother output out of stutter~ ?

for the patch I'm working on I used a sah~ method you mentioned (for panning) but used a >~ on the output and multiplied that by the envelope. a simple way to reject grains from a source like stutter~. useful for realtime pseudo random grain spacing.

that's what i thought too.. have no idea what you guys are on about but it sounds dope.

i'll post my old stutter patch as soon as i can. (it won't be too soon, b/c it's on the hard drive of a broken computer...)

i didn't manage to get stutter to be smooth per se. as i call the main tricky thing was a bit of algebra to make the grain length stay constant when changing pitch. when you change certain of the parametes, the active grains get a little messed up, and then the system 'recovers'; so it's not very smooth, and if you intend to constantly modify the grain length/pitch paremeters, as with an lfo or s/t, then this method would sound very glitchy. which isn't necessarily a bad thing...

another smoothness will come from using an envelope of some kind, and, as em978 points out, it may be simplest just to put phasor into cycle~ (sine wave) for the envelope. (re-scaling the phasor so that it only reads out one half of the period of the cycle~...)

and btw there's no wankishness problems
i guess at a certain point the technical details become harder to express as plain english and start making better sense in a patch format, but i enjoy trying to put these ideas into words. hopefully i'm not alone in that.

I agree, with such focus on the visual, speaking about max can get difficult as the ideas become a little more abstract/involved. However, it seems better for comprehension to be presented with ideas and not finished product.


Register / login
You must be a member to reply or post. signup or login