This should be an easy function to use, but i can't for the life of me figure the syntax out - i've tried 5 => Math.trunc(2); and Math.trunc(5,2); and 5.trunc(2); // this would be the nicest syntax and some other things, to no avail - the documentation isn't big on examples for stuff like this. thanks, jascha
Okay, i just figured out that Math.trunc(x) just truncates x to the nearest integer - it'd be nice to have something to round to arbitrary values, though. Is there, for instance, a nicer way to round the output of a low-frequency saw wave than this? This just seems laborious: ---- SinOsc sin => dac; SawOsc saw; 1 => saw1.freq; 0 => saw1.phase; saw1 => blackhole; while (true) { 400.00 * (Math.trunc(((saw1.last() * 2000.0) + 2000.0) / 400.0)) => sin.freq; // saw1 goes from 0 to 4000 at a speed of 1 Hz // and is rounded to the nearest 400 1::samp => now; }; --- thanks, jascha On Oct 7, 2007, at 10:44 PM, Jascha Narveson wrote:
This should be an easy function to use, but i can't for the life of me figure the syntax out - i've tried
5 => Math.trunc(2);
and
Math.trunc(5,2);
and
5.trunc(2); // this would be the nicest syntax
and some other things, to no avail - the documentation isn't big on examples for stuff like this.
thanks,
jascha _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Hi Jascha! Welcome (to ChucK and to Princeton)! There are several ways to approach this task at hand, and depends on the desired ultimate end result. It's certainly fine (though often cumbersome) to do things by hand/sample (your current example seems to be some kind of a direct mashup of a SuperCollider-like control approach with the ChucK timing mechanism). Here are some other approaches. First, the rounding can be simplified, for example: // patch SinOsc sin => dac; // Osc, also a 0 to 1 ramp Osc saw => blackhole; 1 => saw.freq; 0 => saw.phase; // time loop while( true ) { // ramp 0 to 4000, step size -> 400 400.00 * Math.trunc(saw.last() * 10) => sin.freq; // tick it 1::samp => now; } If it fits your task at hand, you can also directly compute the control frequencies yourself, and move along in time only as much as necessary: // patch SinOsc sin => dac; // initialize some values 4000 => float top; 400 => float multiple; top / multiple => float steps; 1::second / steps => dur T; // time loop while( true ) { 0 => int n; while( n < steps ) { n * multiple => sin.freq; n++; T => now; } } the loop can also look like... // time loop while( true ) { 0 => float f; while( f < top ) { f => sin.freq; multiple +=> f; T => now; } } These examples may seem more verbose compared to other languages, but they do delineate precisely what is happening, and of equal import: when. There are probably many other ways to accomplish this as well. Welcome again. Hope this helps! Best, Ge! On Sun, 7 Oct 2007, Jascha Narveson wrote:
Okay, i just figured out that Math.trunc(x) just truncates x to the nearest integer - it'd be nice to have something to round to arbitrary values, though. Is there, for instance, a nicer way to round the output of a low-frequency saw wave than this? This just seems laborious:
----
SinOsc sin => dac; SawOsc saw;
1 => saw1.freq; 0 => saw1.phase;
saw1 => blackhole;
while (true) { 400.00 * (Math.trunc(((saw1.last() * 2000.0) + 2000.0) / 400.0)) => sin.freq; // saw1 goes from 0 to 4000 at a speed of 1 Hz // and is rounded to the nearest 400 1::samp => now; }; --- thanks,
jascha
On Oct 7, 2007, at 10:44 PM, Jascha Narveson wrote:
This should be an easy function to use, but i can't for the life of me figure the syntax out - i've tried
5 => Math.trunc(2);
and
Math.trunc(5,2);
and
5.trunc(2); // this would be the nicest syntax
and some other things, to no avail - the documentation isn't big on examples for stuff like this.
thanks,
jascha _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Hi! That was a good question, I think sorting where to use "modular synth style" signal flow and where to us "plain code" is a important part of ChucKing. Many things can be done both ways but if you do it the "wrong" way you'll end up with ugly code and high cpu costs. If there is still a need to round to a multiple of some number in a "5.trunc(2);" style it could be done using something like this; fun float trunc(float input, float multiple) { return (input - input%multiple); } which will always round down. If we really need the closest value we can use something like; fun float trunc(float input, float multiple) { if ( input%multiple < ( .5 * multiple) ) return (input - input%multiple); else return (input - input%multiple + multiple); } This would be overkill if we just want a series of tones that hits every multiple of 400Hz (in that case we'd be much better off with simply generating that series directly like Ge said) but it's still a valid question in itself. Hope that helps. Kas.
Hello, Ge and Kassen - Thanks for the welcomes both of you, and thanks for the interesting software, Ge! And yes, you've accurately pegged me as a SC user learning ChucK - i've been 'translating' examples in both directions in an attempt to learn the language. It's been interesting to see how the languages differ - i love how intuitive signal flow is in ChucK. Both of your suggestions are useful. Is "Osc" in the documentation somewhere? I don't see it on the online UGen reference list... cheers, jascha On Oct 8, 2007, at 6:54 AM, Kassen wrote:
Hi!
That was a good question, I think sorting where to use "modular synth style" signal flow and where to us "plain code" is a important part of ChucKing. Many things can be done both ways but if you do it the "wrong" way you'll end up with ugly code and high cpu costs.
If there is still a need to round to a multiple of some number in a "5.trunc(2);" style it could be done using something like this;
fun float trunc(float input, float multiple) { return (input - input%multiple); }
which will always round down. If we really need the closest value we can use something like;
fun float trunc(float input, float multiple) { if ( input%multiple < ( .5 * multiple) ) return (input - input% multiple); else return (input - input%multiple + multiple); }
This would be overkill if we just want a series of tones that hits every multiple of 400Hz (in that case we'd be much better off with simply generating that series directly like Ge said) but it's still a valid question in itself.
Hope that helps. Kas. _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
participants (3)
-
Ge G. Wang
-
Jascha Narveson
-
Kassen