Smoothing for a rudimentary granular synth
I'm trying to learn Gen and granular synthesis by getting my hands dirty and building a synth from scratch in Gen. Most granular synths (at least that I see) use samples, but I wanted to follow Curtis Roads' example in his book Microsound and see if I could make a granular synth using a sine wave as its sound source. I've achieved that (I think) with this patch, but am getting some undesirable clicks and pops when I try to use longer grain durations with higher-density settings, as the envelope gets cut off. Maybe this is unavoidable for high grain-density/long-duration circumstances - I don't know - so I figured I'd ask about it here and see if anyone has any input for how to treat this scenario. I've pasted the patch. In order to duplicate the clicks I'm referencing, try setting 'GRAIN DENSITY' to 20. and GRAIN DURATION to 85.
Well, it's unavoidable if your synth is mono. You can use poly~ or mc.gen~ to make it polyphonic. However you'll need to implement your own voice allocation since the existing ones don't work in audio rate.
Thanks for the reply. That makes sense that it's unavoidable in this implementation - I figured that might be the case. Hmm..I did try implementing this in mc.gen~ to see if I could handle it that way, but to no effect. I find that I still get the same issue. Try this patch, with settings like a grain density of 400 and duration of 100 ms.
Yeah, 30 voices aren't enough for that. I think the following expression gives you the values that won't produce clicks
duration * density / mc_channelcount <= 1000
Maybe you could implement a retrigger function like the retrigger attribute of adsr~.
BTW you need to add an mc.mixdown~ before the live.gain~. In it's current form you can hear only two voices. Maybe that's why it seems that nothing has changed.
your second comment did indeed help reduce the clicks and pops. forgive me, but I'm confused about your first comment: are you saying that I need a greater number of @chans in the ~sig object? (greater than 30?). And where are you imagining implementing the expression you mentioned? It will return a 0 or 1, what is that value controlling?
I'm not suggesting you implement the expression in Max (although you could). It's for measuring whether you'll get clicks or not. As long as you don't violate the inequality (if it returns 1) you won't get clicks.
To get rid of clicks when taking over a voice, you need a 'predelay stage' begore attack during which the prior voice is rapidly released. Even a 5 msec predelay stage is enough to stop clicks.
That is helpful, @Ernest! I've never tried to implement a predelay stage, let alone in mc.gen~. Do you have any examples of that or resources on that in mind?
Yes, there are some examples in synthcore and the 32-voice synth at
awesome. if you can point me to a specific feature, that would be super helpful, but it's fun poking around in here nonetheless!
Here's a gen~ ADSR demo patch from when I designed in UI objects instead of wrote code. It contains a lot of notes. It's not as efficient as codebox, but it's a good way to understand how it works. It's got a lot of extra functionality such as shaping the ADSR stages which you'll probably want to strip out. I'm sorry the max UI does need improving, but at least it should start drawing an envelope right away when you open it.