greetings! first off..... i am thoroughly enjoying ChucK; thanks a lot! my question is whether anybody has an elegant way of attacking the problem of zipper noise when using external MIDI controllers which send only integer values. it's great that ChucK uses float MIDI values, but we need a way of smoothing incoming controller data -- perhaps something like pd's "line" operator. i'll have to give some thought to how it could be built from scratch, using native primitive operators, but an optimized higher-level function to take care of this would certainly be useful. thanks again! .pltk.
On 5/5/06, plutek
my question is whether anybody has an elegant way of attacking the problem of zipper noise when using external MIDI controllers which send only integer values. it's great that ChucK uses float MIDI values, but we need a way of smoothing incoming controller data -- perhaps something like pd's "line" operator.
Very expensive but it should work; Chuck the CC's value to a "step" ugen, lowpass filter that with a very low (sub sonic) cutoff and chuck the .last value of that at some high rate (ideally sample rate) to wherever you need the parameter to go. This is probably quite expensive on the cpu but I don't see any other options. Yours, Kas.
On Fri, 5 May 2006 05:18:37 +0200
Kassen
On 5/5/06, plutek
wrote: my question is whether anybody has an elegant way of attacking the problem of zipper noise when using external MIDI controllers which send only integer values. it's great that ChucK uses float MIDI values, but we need a way of smoothing incoming controller data -- perhaps something like pd's "line" operator.
Very expensive but it should work;
Chuck the CC's value to a "step" ugen, lowpass filter that with a very low (sub sonic) cutoff and chuck the .last value of that at some high rate (ideally sample rate) to wherever you need the parameter to go.
This is probably quite expensive on the cpu but I don't see any other options.
hmmm.... yeah, i thought of going that sort of route, and was hoping to avoid it because of, as you say, the "expense". well, maybe i'll give it a shot. .pltk.
Hi Plutek!
my question is whether anybody has an elegant way of attacking the problem of zipper noise when using external MIDI controllers which send only integer values. it's great that ChucK uses float MIDI values, but we need a way of smoothing incoming controller data -- perhaps something like pd's "line" operator.
There are several ways of addressing this. In addition to the Kassen's suggestion, one can also write a simple interpolator shred that 1) shares the variable of interest 2) operates at a zipper-friendly rate (perhaps less than 10::ms to 1::ms, depending on the sound). This way works well (I've seen it used in several case, and have used it myself), and can be much less CPU intensive. Given this works, it's conceivable that we can write a class to encapsulate this functionality. I am a bit swamped with PLOrk at the moment (we just had a concert Tuesday in Princeton, and there will be one Saturday at Dartmouth). If needed, I can post some code (and chime in on benchmarking chuck thread) after this weekend. Happy ChucKing! Ge!
If needed, I can post some code (and chime in on benchmarking chuck thread) after this weekend.
"need" is a big word but if you would have a moment to spare I would very much apreceate your thoughts on some of the issues around those asignments of ugen's to array members. For routing that's looking extremely good but I'm hesitant to actively use it untill I find out how it works exactly. In due time, of cource. Yours, kas.
Hi Kassen and all!
"need" is a big word but if you would have a moment to spare I would very much apreceate your thoughts on some of the issues around those asignments of ugen's to array members.
The current specification for arrays of Objects is that each element is a reference, like a non-array Object variable, can be treated as such. For example, as you know: Object foo; Object @ bar; At this point, both foo and bar is a reference variable to an Object, the only different being foo is referencing an instance of Object, whereas bar is referencing NULL at this point. assignment: // assign foo to bar: both now point to the same instance foo @=> bar; Going to arrays isn't really any different: Object fooray[10]; Object @ barray[10]; fooray simply contains 10 references (each referencing at this point to newly allocated Object instances), barray also contains 10 references, but due to the @ declaration all elements are NULL. Except for this difference, fooray and barray are the same: they both contain references to Objects. If we want, we can assign references to the elements of fooray and barray: // assuming fooray.cap() == barray.cap() for( int i; i < fooray.cap(); i++ ) fooray[i] @=> barray[i]; This above fills barray's elements with corresponding elements of fooray. We can also assign new instances to fooray's elements and to barray's elements: // make a new Object (reference variable obj) Object obj; obj @=> fooray[0]; obj @=> barray[2]; // make a new Object new Object @=> fooray[4]; new Object @=> barray[5]; The objects, in theory, are reference counted and garbage collected as appropriate. In practice, the garbage collection system is not finished (completing it is actually the main goal, along with string manipulations, of the 1.2.0.6 release). In the cases above, it actually works, I think. In the case of UGens, it's no different really, except the @=> and => operators do completely different things. As Perry explained: UGen foo; UGen bar; foo => bar; // connects foo to bar, as we all know foo @=> bar; // assigns foo to bar In the 'foo @=> bar;' case, bar now references the same UGen as foo. What bar was previously referencing should have it's reference count decremented and be potentially garbaged collected. Things get potentially kind of wacky is when we combine @=> and => into a single statement, like: // make an array (all elements == NULL, due to @) sinosc @ bank[N]; // make new sinosc, assign it to bank[0], connect it to dac sinosc s @=> bank[0] => dac; Like Perry wrote, this decomposes into the following lines: // make new sinosc sinosc s; // assign it s @=> bank[0]; // connect bank[0] to dac bank[0] => dac; The thing to remember is @=> always signifies assignment, => depends on the context. And that's pretty much it. I am actually still not sure if I answered the right question - please let me know... Doh. If this part of the language seems confusing, we can certainly try to improve it. Best wishes, Kassen and all. Ge!
Ge;
And that's pretty much it. I am actually still not sure if I answered the right question - please let me know... Doh. If this part of the language seems confusing, we can certainly try to improve it.
Thanks for taking the time to clarify all that. It's not all that confusing anymore. It's dawning on me that ChucK as a language is quite a bit more elborate or at least generalised then our documentation and examples so far would lead one to believe. That's a Good Thing, much preferable to other instruments. This asigning of objects to array locations sounds like a very good idea to me, it should facilitate building little patch-bays and so on. I take it that if you write; // make new sinosc sinosc s; // assign it s @=> bank[0]; // connect bank[0] to dac bank[0] => dac; Then I would be free to do such things as; .3 => bank[0].gain; Right? That would be quite convenient. It wouldn't result in anything fundamentally new but for larger patches that need routing and mixing it would certainly make it all a lot easier and more readable to deal with. Thanks again, Kas.
participants (3)
-
Ge Wang
-
Kassen
-
plutek