Author |
Message |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Jan 15, 2008 8:02 am Post subject:
LiSa zero crossing detection. |
 |
|
I posted the following to the list last night, might be usefull to pleople here as well?
Quote: | Dear ChucKists.
(particularly Dan who asked me for examples of LiSa usage a while back)
Below you'll find a example of how to make LiSa's loop points snap to the next positive zero crossing in her buffer, provided the buffer was loaded from a recorded file using SndBuf.
This has many uses, particularly to glitch-free loop a sample that's not noisy enough to hide clicks and/or particularly bass heavy in situations where the overall structure of the program loops at a different rate then the sample loop length and crossfading would mean adding shreds..This is a polite way of saying it's especially good for cheap & easy stuttering kick-drums.
Mind that this will change the loop's length and thus pitch and/or timing, it's much cleaner sound-wise though.
In some situations this may be cleaner or lead to cleaner code than the methods in the examples/docs but it would be a bad idea to think this is the best way to avoid clicks in all cases as it isn't. It's a interesting option though and one I found to work well compared to it's complexity.
With lots of comments, I hope others will find this as usefull as I'm finding it now.
Yours,
Kas.
|
Code: | //Zero crossing detection and snapping for LiSa by Kassen
//Permision granted for redistribution, modification, etc.
//no waranties, no refunds, please mind your speakers.
//Remixing strongly encouraged.
SndBuf buf => LiSa l => dac;
//your sample goes here
//this patch is primarily meant for low drum beats or notes
//clicks aren't as objectionable for claps and the like
//may be impractical for lengthy soundscapes.....
buf.read("kick.wav");
int n, m;
float last;
int crossings;
2::second => l.duration;
//detect the number of positive zero crossings in the file
//we do this faster than realtime
//if you try this for long samples while other stuff is running
//there may be glitches as this likely maxes out the cpu
//due to not advancing time
for (0=> n; n<buf.samples(); n++)
{
if ((last < 0) && ( buf.valueAt(n) >= 0))
{
crossings++;
}
buf.valueAt(n) => last;
}
<<<crossings, "positive zero crossings in sample">>>;
//make a array of this length
int zerocrossings[crossings];
//create a index of their locations
0 => crossings;
0 => last;
for (0=> n; n<buf.samples(); n++)
{
if ((last < 0) && ( buf.valueAt(n) >= 0))
{
n => zerocrossings[crossings];
crossings++;
}
buf.valueAt(n) => last;
}
//go LiSa!
l.record(1);
buf.samples()::samp => now;
l.record(0);
//save cpu
buf =< l;
//loop forever to demo
//here we only snap loopEnd() to the crossings,
//loopStart() may be treated in the same way,
//at which point only using positive crossings becomes usefull.
while(1)
{
//start at the beginning
0::ms => l.playPos;
l.play(1);
//modulate loop length
for (1 => m; m < 8; m++)
{
m* (2::second /16) => l.loopEnd;
//don't bother trying to detect crossings if we already passed the last one
if ( (l.loopEnd()/samp)$ int < zerocrossings[zerocrossings.cap()-1])
{
//find the next positive zero crossing...
0 => n;
while( (((l.loopEnd()/samp) $ int ) > zerocrossings[n]) &&n< zerocrossings.cap()-1 ) n++;
//snap to it
zerocrossings[n +1]::samp => l.loopEnd;
}
second => now;
}
//get rid of clicks at the end, pause and start over
l.rampDown(50::ms);
second => now;
} |
_________________ Kassen |
|
Back to top
|
|
 |
Frostburn

Joined: Dec 12, 2007 Posts: 255 Location: Finland
Audio files: 9
|
Posted: Fri Jan 18, 2008 6:16 am Post subject:
|
 |
|
Nice Kassen.
I played around with LiSa too but couldn't yet hit anything of quality.
Any ideas how do I do zero crossing detection when recording from adc live? LiSa's .valueAt(dur) is broken. Is the wiki the right place to post bugs like this? _________________ To boldly go where no man has bothered to go before. |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Fri Jan 18, 2008 6:39 am Post subject:
|
 |
|
Frostburn wrote: | Nice Kassen.
I played around with LiSa too but couldn't yet hit anything of quality.
Any ideas how do I do zero crossing detection when recording from adc live? LiSa's .valueAt(dur) is broken. Is the wiki the right place to post bugs like this? |
That's not a bug but a feature Dan is working on which isn't finished yet, he talked about it on the list. It should be in the next version. This valueAt should be both read&write for LiSa, quite exciting, I think.
What you can do, but it's not as fast, is play the contents of your LiSa, track them using .last() instead of valueAt and advance time by one samp every time. This is of course slower. I working on a different solution but itś hard to explain and I have yet to test it. _________________ Kassen |
|
Back to top
|
|
 |
Frostburn

Joined: Dec 12, 2007 Posts: 255 Location: Finland
Audio files: 9
|
Posted: Fri Jan 18, 2008 6:57 am Post subject:
|
 |
|
Oh. ok. I was assuming that it was implemented as it was listed on LiSa's description.
It would be a cool feature. I hope Dan finds the time to work on it. :)
I'm working on an auto-correlator so advancing time while reading (insane amounts of) data from LiSa's buffer isn't an option.
I'll see what I can do with a float array to store the samples and an Impulse generator to play it back. (Ah the smell of roasted CPU in the morning). _________________ To boldly go where no man has bothered to go before. |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Fri Jan 18, 2008 7:03 am Post subject:
|
 |
|
Oh! I didn't think valueAt() was in the doc, in that case it's a bug. No harm in reporting it. No idea how I missed that, I thought I looked for it. Weird.
A array of floats will work, yes, what you could also do is use a Step instead of a Impulse and thus gain the ability to turn the rate down for lower playback rates. _________________ Kassen |
|
Back to top
|
|
 |
|