I like alias-noise and 8bit
Hi I'd like to resample a 44100 signal to something like 10K *and* hear the alias noise. Also I'd like to resample to lower bitdepth, something like 8 or 6 bit. 1) How it that most efficiently done with chuck? 2) I event thought it might be possible for me to implement this as a real UGen. My plan would be to start from one of the simple UGens (gain), and expand/modify from there, but before even looking into the chuck source, is there any documentation about doing this? Should I expect this to be more effective in implenenting in chuck-code, and if so about how much? Also. supposed I actually succed in making something that works, could it be included in future chuck-releases? -- peace, love & harmony Atte http://atte.dk | http://myspace.com/attejensen http://anagrammer.dk | http://modlys.dk
2008/5/18 Atte André Jensen
Hi
Hey, Atte!
I'd like to resample a 44100 signal to something like 10K *and* hear the alias noise. Also I'd like to resample to lower bitdepth, something like 8 or 6 bit.
Cool, me too. Morning coffee is a bit late today but it's a Sunday and there's a nice ChucK puzzle to go with it. Oh, and it's nice coffee :¬)
1) How it that most efficiently done with chuck?
Well, quantising in time (sample rate) is without any doubt done most easily by writing the .last() of some signal to the .next of a Step at the required period. Quantising in amplitude (bit depth) means rounding. I think my proposal below might be quite efficient but I'm not 100% sure there. It does work fine though and Std has several other rounding schemes you may wish to try for CPU performance and/or sound quality. Here you go; This example should be quite clear and suitable for extending for your own purposes, I think, but if I'm wrong please do shout. ============================= //replace with more interesting signal. SinOsc my_signal => blackhole; Step resampled => dac; resample(); //remove shred to quit.... fun void resample() { //8 KHz ms / 8 => dur re_samp_rate; //set bits here 8 => int bits; //calculate the maximum integer value of the signal's amplitude at this bitdepth Math.pow(2, bits) * .5 => float scale; //division is expensive and we only need to do it once 1/scale => float downscale; while(true) { //digital clipping if (my_signal.last() > 1) 1 => resampled.next; else if (my_signal.last() < -1) -1 => resampled.next; else { //cast to int for cheep&cheerful rounding //then multiply back into the range //write result to output downscale * ( (my_signal.last() * scale) $ int) => resampled.next; } //samplerate is implicid in controll-rate re_samp_rate => now; } } ===================
2) I event thought it might be possible for me to implement this as a real UGen. My plan would be to start from one of the simple UGens (gain), and expand/modify from there, but before even looking into the chuck source, is there any documentation about doing this? Should I expect this to be more effective in implenenting in chuck-code, and if so about how much? Also. supposed I actually succed in making something that works, could it be included in future chuck-releases?
Me too! I'd also like the following to work but it seems like I can extend Step but the result will -for some strange reason- not be a Ugen. I'm not the greatest OOP wizard but I really feel that if I extend Ugen the result should be a Ugen as well. Right now we can extend it but not actually do anything with the result. ======================== //example code, doesn't actually work //this is the offending line LowRezNoise n => dac; minute => now; class LowRezNoise extends Step { ms => dur rate; spork ~ fakeTick(); fun void freq( float input) { second / input => rate; } fun void fakeTick() { while(1) { Std.rand2f(-1,1) => this.next; rate => now; } } } ==================== Hope that helps? Yours, Kas.
Kassen wrote:
Here you go; This example should be quite clear and suitable for extending for your own purposes, I think, but if I'm wrong please do shout.
Thanks alot. I feel embarrased that I didn't know about last being available for all ugens. I (believe it or not) did look in the documentation, but for ugens and no last is listed there, however I should have looked at http://chuck.cs.princeton.edu/doc/language/ugen.html I'll have a look at your examples, and modify for my needs.
I'd also like the following to work but it seems like I can extend Step but the result will -for some strange reason- not be a Ugen. I'm not the greatest OOP wizard but I really feel that if I extend Ugen the result should be a Ugen as well. Right now we can extend it but not actually do anything with the result.
Ok, so you're in chuck, I was thinking about going c++... Anyways, I had the impression that defining our own ugens in chuck-code wasn't supported, but I sure hope I was wrong. Obviously this would make the LoFi example sooo smooth: SndBuf s => LoFi l => dac; s.read("something.wav"); 22100 => l.rate; 8 => l.bits; 1::week => now; The second last section on http://chuck.cs.princeton.edu/doc/language/ugen.html says "creating [ugens], comming soon". It seems this (missing) info is exactly what I'm looking for. Could any of the coders fill us in? -- peace, love & harmony Atte http://atte.dk | http://myspace.com/attejensen http://anagrammer.dk | http://modlys.dk
Atte : Thanks alot. I feel embarrased that I didn't know about last being available
for all ugens. I (believe it or not) did look in the documentation, but for ugens and no last is listed there, however I should have looked at http://chuck.cs.princeton.edu/doc/language/ugen.html
Yes, it is. Back when I was a young little ChucKer I -for a while- had the impression ChucK was a bit like a Buchla modular; Buchla uses/used different types of plugs for control and audio signals. It's not at all but the key is .last() on the one end and Step (or Impulse) on the other. This might be a good candidate for a small section in the manual because you (and me) weren't tthe only ones that were confused by it for a while. I would, BTW, be in favour of allowing Envelope to ramp to negative values. I think we could do this by removing a single check from Envelope's C++ code and as far as I could tell when I looked at that there wouldn't be any real repercussions but I might be wrong there. (Perry? Ge?). This would allow for linear interpolation when we go from code to Ugens if we don't like (too much) aliassing (at the moment).
I'll have a look at your examples, and modify for my needs.
Great. I think the aliassing one is correct (but no waranties!), this should be fairly easy to work with. Ok, so you're in chuck, I was thinking about going c++...
Me too, that's why I used the word "also". I think the two would both be nice on their own but I also think that prototyping in ChucK could help in developing the C++. ChucK is after all faster and easier to write.
Anyways, I had the impression that defining our own ugens in chuck-code wasn't supported, but I sure hope I was wrong.
Well, the example I just send (extending Step) was my best shot. I don't think we can and considdering how much stuff I tried I'd be very surprised indeed if this was possible. Frankly I think that bit of code demonstrates a issue. I feel that either we should be able to extend a Ugen (and have the result be a Ugen) or it should throw a warning like trying to extend a primitive does. ================== //example of this //this doesn't work which is documented and correct behaviour class value extends int { //stupid example function fun void increment() { this++; } } ==================
Obviously this would make the LoFi example sooo smooth:
SndBuf s => LoFi l => dac; s.read("something.wav");
22100 => l.rate; 8 => l.bits;
1::week => now;
Yes, I agree. Developing our own Ugens in C++ is possible already but the lack of documentation on exactly what this would mean makes it a rather daunting project if you're not already fluent in C++. extending/making Ugens in ChucK on the other hand would could help maintain readable code in larger projects, etc. I think both would be worthwhile aditions.
The second last section on http://chuck.cs.princeton.edu/doc/language/ugen.html says "creating [ugens], comming soon". It seems this (missing) info is exactly what I'm looking for.
Yeah.... I suspect that's simply one of the bits that has been on The List for a long time due to other stuff getting more priority. We need it, but we also need garabage collection, fileIO and (I feel) updating the code of just a part of a shred, etc, etc, etc. At least we can be confident that our esteemed DEV's aren't in any danger of feeling bored and having nothing at hand any time soon, that's at least something :¬). Cheers, Kas.
Kassen wrote:
Here you go; This example should be quite clear and suitable for extending for your own purposes, I think, but if I'm wrong please do shout.
Thanks, I tried your code and it works just great! -- peace, love & harmony Atte http://atte.dk | http://myspace.com/attejensen http://anagrammer.dk | http://modlys.dk
participants (2)
-
Atte André Jensen
-
Kassen