electro-music.com   Dedicated to experimental electro-acoustic
and electronic music
 
    Front Page  |  Radio
 |  Media  |  Forum  |  Wiki  |  Links
Forum with support of Syndicator RSS
 FAQFAQ   CalendarCalendar   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   LinksLinks
 RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in  Chat RoomChat Room 
 Forum index » DIY Hardware and Software » ChucK programming language
Help with LiSa
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [12 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
Author Message
Antimon



Joined: Jan 18, 2005
Posts: 4145
Location: Sweden
Audio files: 371
G2 patch files: 100

PostPosted: Sun Nov 01, 2009 10:54 am    Post subject: Help with LiSa Reply with quote  Mark this post and the followings unread

I feel there's something obvious I'm doing wrong here, but I can't for the life of me figure out what it is...

Code below. As I see it, it should just play back the sine tone with a one second delay. I'm repeatedly setting the playPos to where it's supposed to be. This is a scaled down version of a live sample cutter I'm working on.

The thing is, the playback jumps around and mixes with previous audio in a weird way that I don't understand. I'm anyone can run it and verify that it sounds weird I'd be happy - if you comment out the spork ~ playLisa() line, you get the result that I'm expecting even when playLisa is running.

What's going on? Aren't you supposed to move the playPos around without disturbing recording? Am I doing some mindnumbingly stupid thing with the value that I put in playPos (I've stared at it and rewritten it a couple of times with the same result)?

Any suggestions would be gratefully accepted.

Code:
SinOsc osc => LiSa lisa => dac;
0.5 => osc.gain;
1.0 => lisa.gain;

1::second => lisa.duration;
0::second => lisa.recPos;
1 => lisa.loopRec;
1::second => lisa.loopEndRec;
1 => lisa.record;
1 => lisa.play;
0 => lisa.sync;

fun void playLisa() {
   while (true) {
      for (0 => int i; i < 8; i++) {
         i*1::second/8 => lisa.playPos;
         1::second/8 => now;
      }
   }
}
spork ~ playLisa();


while(1) {
   for (300 => float freq; freq < 2000.0; 0.001 +=> freq) {
      freq => osc.freq;
      1::samp => now;
   }
   for (2000 => float freq; freq > 300.0; 0.001 -=> freq) {
      freq => osc.freq;
      1::samp => now;
   }
}


/Stefan

_________________
Antimon's Window
@soundcloud @Flattr home - you can't explain music
Back to top
View user's profile Send private message Visit poster's website
Hillaby



Joined: Oct 28, 2009
Posts: 11
Location: Hungary

PostPosted: Sun Nov 01, 2009 3:59 pm    Post subject: Reply with quote  Mark this post and the followings unread

I played around with LiSa, a Mandolin and feedback. It sounded like an echo effect.

However, I don't know if this is of much help for you Surprised.

Code:
Mandolin m => LiSa lisa => dac;
fun void play() {
   while(1) {
      Std.rand2(26, 40)*2 => Std.mtof => m.freq;
      1 => m.pluck;
      317::ms => now;
   }
}

fun void sweepFeedback() {
   while(1) {
      for (0. => float fb; fb < .6; .01 +=> fb) {
         <<<"feedback: ", fb>>>;
         fb => lisa.feedback;
         70::ms => now;
      }
      for (.6 => float fb; fb > 0.; .01 -=> fb) {
         <<<"feedback: ", fb>>>;
         fb => lisa.feedback;
         70::ms => now;
      }
   }
}

.4 => m.gain;

1::second => lisa.duration;
1 => lisa.record;
1 => lisa.play;
1 => lisa.loopRec;
.3 => lisa.feedback;

spork ~ play();
spork ~ sweepFeedback();


day => now;

_________________
Hillaby
(Szilveszter)
More music at ReverbNation
... at MySpace
A humble blog
Back to top
View user's profile Send private message Visit poster's website
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Sun Nov 01, 2009 9:33 pm    Post subject: Reply with quote  Mark this post and the followings unread

Something odd is going on here. consider this version;
Code:


fun void playLisa() {
   while (true) {
      for (0 => int i; i < 8; i++) {
         //i * 0.125::second => lisa.playPos;
         <<<((i * 0.125::second) - lisa.playPos()) / samp, "playPos difference" >>>;
         <<<((i * 0.125::second) - lisa.recPos()) / samp, "recPos difference" >>>;
         0.125::second => now;
      }
   }
}


Uncomment that line to hear and see the difference. It seems like the looplength for playback is off by one samp. This seems like a bug to me.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Sun Nov 01, 2009 10:04 pm    Post subject: Reply with quote  Mark this post and the followings unread

Reported to the list.

It turns out this only happens when the loopEnd is also the .duration(). For now I'd set a more generous duration and a explicit loopEnd(); that seems to fix the issue.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Hillaby



Joined: Oct 28, 2009
Posts: 11
Location: Hungary

PostPosted: Sun Nov 01, 2009 11:49 pm    Post subject: Reply with quote  Mark this post and the followings unread

Oh well, as I see, I didn't quite understand the issue; my take on the problem was erroneous... Still, it sounds good Very HappyVery Happy.
_________________
Hillaby
(Szilveszter)
More music at ReverbNation
... at MySpace
A humble blog
Back to top
View user's profile Send private message Visit poster's website
Antimon



Joined: Jan 18, 2005
Posts: 4145
Location: Sweden
Audio files: 371
G2 patch files: 100

PostPosted: Mon Nov 02, 2009 4:32 am    Post subject: Reply with quote  Mark this post and the followings unread

@Kassen, I'm not sure what you mean. I tried doubling the duration and setting loopEnd, but I still get the same result.

Changed to your implementation of playLisa below:

Code:
SinOsc osc => LiSa lisa => dac;
0.5 => osc.gain;
1.0 => lisa.gain;

1.5::second => lisa.duration;
0::second => lisa.loopStart;
1::second => lisa.loopEnd;
0 => lisa.loop;
0::samp => lisa.recPos;
1 => lisa.loopRec;
1::second => lisa.loopEndRec;
1 => lisa.record;
1 => lisa.play;
0 => lisa.sync;

fun void playLisa() {
   while (true) {
      for (0 => int i; i < 8; i++) {
         i * 1::second/8 => lisa.playPos;
         <<<((i * 1::second/8) - lisa.playPos()) / samp, "playPos difference" >>>;
         <<<((i * 1::second/8) - lisa.recPos()) / samp, "recPos difference" >>>;
         0.125::second => now;
      }
   }
}
spork ~ playLisa();


while(1) {
   for (300 => float freq; freq < 2000.0; 0.001 +=> freq) {
      freq => osc.freq;
      1::samp => now;
   }
   for (2000 => float freq; freq > 300.0; 0.001 -=> freq) {
      freq => osc.freq;
      1::samp => now;
   }
}


Good idea with those printouts. I get the impression that recPos and playPos advance one after the other in some way, and when we set playPos the order shifts. I tried changing the line that sets recPos to this:

Code:
1::samp => lisa.recPos;


This changed the app to make a sound that is less chaotic, but still not perfect as there is a tiny click every time I set playPos, and the printouts show that there is this small discrepancy between playPos and recPos that shifts by 0.5 every second time.

I have the feeling that if I change my code to use multiple voices and rampUp/rampDown I'll be able to realise what I want to do. That doesn't change the fact that there is something fishy going on though.

/Stefan

_________________
Antimon's Window
@soundcloud @Flattr home - you can't explain music

Last edited by Antimon on Mon Nov 02, 2009 8:52 am; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
Antimon



Joined: Jan 18, 2005
Posts: 4145
Location: Sweden
Audio files: 371
G2 patch files: 100

PostPosted: Mon Nov 02, 2009 4:40 am    Post subject: Reply with quote  Mark this post and the followings unread

BTW, this behaviour is the same in ChucK 1.2.1.3 and 1.2.1.2 - I first discovered the problem on the old version and then updated to see if it was something that had been fixed.

/Stefan

_________________
Antimon's Window
@soundcloud @Flattr home - you can't explain music
Back to top
View user's profile Send private message Visit poster's website
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Mon Nov 02, 2009 8:42 am    Post subject: Reply with quote  Mark this post and the followings unread

Antimon wrote:
@Kassen, I'm not sure what you mean. I tried doubling the duration and setting loopEnd, but I still get the same result.


That's strange! In my version with the printed lines I see the read pointer start to lag by 1 cumulative samp per 8 printed lines, so one samp per loop iteration. When I set .duration() larger they behave the same, aside from some floatingpoint rounding errors (nothing larger than a millionth of a samp) and those don't seem to carry.

Quote:

Good idea with those printouts. I get the impression that recPos and playPos advance one after the other in some way, and when we set playPos the order shifts.


I find that a bit hard to believe; those will most likely be moved in LiSa's "tick" function and I don't see why that would ever change. This order will only matter if your read and write pointers are on the same spot. As far as I can see they actually are in your example; both start at 0::ms and start looping at a rate of 1 to the right. I'm not sure why you are doing that.


Quote:
This changed the app to make a sound that is less chaotic, but still not perfect as there is a tiny click every time I set playPos, and the printouts show that there is this small discrepancy between playPos and recPos that shifts by 0.5 every second time.


That's strange. Your new version won't run for me; looks like you had html set in your post? I think we have at least one bug in LiSa but I also think you are putting LiSa on a very hard spot by having your read and write pointer at the same place. I feel LiSa should be able to deal with that by writing before reading every tick (and likely she does as all UGens deal with input before reporting output)... but then you are right on the edge and any rounding errors will put you firmly on either side in a way that the read interpolation won't be able to deal with.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Antimon



Joined: Jan 18, 2005
Posts: 4145
Location: Sweden
Audio files: 371
G2 patch files: 100

PostPosted: Mon Nov 02, 2009 8:59 am    Post subject: Reply with quote  Mark this post and the followings unread

Aw crap, I never learn. Embarassed I edited the post with the correct code.

Also, here is what it prints out:

Code:
$ bin/chuck test.ck
0.000000 playPos difference
0.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference
0.000000 playPos difference
0.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference
0.000000 playPos difference
0.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference
0.000000 playPos difference
0.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference
0.000000 playPos difference
-44100.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference
0.000000 playPos difference
0.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference
0.000000 playPos difference
0.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference
0.000000 playPos difference
0.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference
0.000000 playPos difference
-44100.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference


You see that recPos difference changes between two values, so that every second time it's 0.000000 and the other times it's 0.500000 (this is too large a difference to be caused by printing roundoff errors). When I set playPos it's momentarily -44100.000000.

I'm thinking that we may be having some kind of roundoff problem, but that it happens in LiSa.playPos(dur time). Every second time the new playPos falls on one side of the currect recPos, and the other times it falls on the other side, if you catch my meaning.

Hmm... I just tried adding a small amount to the value I send to playPos, but it didn't help.

/Stefan

_________________
Antimon's Window
@soundcloud @Flattr home - you can't explain music
Back to top
View user's profile Send private message Visit poster's website
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Mon Nov 02, 2009 9:24 am    Post subject: Reply with quote  Mark this post and the followings unread

The -44100 thing is the amount of samples in your second. As the buffer loops -44100, 0 and +44100 should all refer to the same point. i'm not worried about that one; that one *is* a rounding error and it's at least 7 digits after the decimal point so off by less than a tick of your cpu. That should be fine Smile

Seems that now playPos is fine, that's good, but apparently now rePos drifts. I have no idea why it would do that but this seems awfully regular. It should be noted what we are actually measuring, BTW.

We are measuring the difference between the actual time (which has a very high resolution indeed) and the place where recPos() was at the last tick LiSa calculated. RecPos() only has a resolution of a samp with regard to the moments at which we can measure as UGens don't do any work in-between ticks. We are *not* measuring where recPos() would be if the UGen would have a infinitely high resolution.

I'd still expect a constant offset if any, btw. At least we are no longer seeing a drift that carries, more like a highly predictable jitter.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Antimon



Joined: Jan 18, 2005
Posts: 4145
Location: Sweden
Audio files: 371
G2 patch files: 100

PostPosted: Mon Nov 02, 2009 10:33 am    Post subject: Reply with quote  Mark this post and the followings unread

Erm, well I've been seeing exactly the same thing all the time. :)

Anyway, I tried changing the second printout to this:


Code:
         <<<(lisa.playPos() - lisa.recPos()), "recPos difference" >>>;


I still get the same result:

Code:
0.000000 playPos difference
0.500000 recPos difference
0.000000 playPos difference
-44100.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference
0.000000 playPos difference
0.000000 recPos difference
0.000000 playPos difference
0.500000 recPos difference


I interpret this as there a resolution inside Lisa of at least 0.5::samp, as I'm subtracting to internal values and getting a 0.5 result (BTW, I removed the division by samp, as it doesn't seem to do anything).

Anyway, I think that this rounding is the problem. If I change the loop to divide by 4 (and count to 4 in the loop), the problem disappears. A quarter second is 11025 samples. Divide this by two and you lose precision. This means that every second time I set the playPos to somthing that is one sample off.

Here's the solution!

Code:
SinOsc osc => LiSa lisa => dac;
0.5 => osc.gain;
1.0 => lisa.gain;

2::second => lisa.duration;
1::second => lisa.loopEnd;
0::second => lisa.recPos;
1 => lisa.loopRec;
1::second => lisa.loopEndRec;
1 => lisa.record;
1 => lisa.play;
0 => lisa.sync;

1::second/8 => dur beatDur;
8*beatDur => lisa.loopEndRec;

fun void playLisa() {
   while (true) {
      for (0 => int i; i < 8; i++) {
         Math.floor(i * beatDur/samp)*samp=> lisa.playPos;
         <<<(beatDur - lisa.playPos()), "playPos difference" >>>;
         <<<(lisa.playPos() - lisa.recPos()), "recPos difference" >>>;
         beatDur => now;
      }
   }
}
spork ~ playLisa();


while(1) {
   for (300 => float freq; freq < 2000.0; 0.001 +=> freq) {
      freq => osc.freq;
      1::samp => now;
   }
   for (2000 => float freq; freq > 300.0; 0.001 -=> freq) {
      freq => osc.freq;
      1::samp => now;
   }
}


I need to compensate for the roundoff. A bit surprisingly, I need to throw the decimals away using Math.floor()! Usually, when converting floats to integers, the systems rounds downwards to the closest integer, but it seems LiSa.playPos() rounds upwards - or maybe it just does it wrong somehow.

Anyway, I don't think this is any obvious bug in LiSa, just a tricky feature to get round. It might be worth highlighting somewhere that UGens don't deal with partial sample durations, that's something I've missed (though it seems perfectly reasonable when I think about it more).

Thanks for your help Kassen! You provided good alternative angles at the problem.

/Stefan

_________________
Antimon's Window
@soundcloud @Flattr home - you can't explain music
Back to top
View user's profile Send private message Visit poster's website
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Mon Nov 02, 2009 11:24 am    Post subject: Reply with quote  Mark this post and the followings unread

I think this is actually a issue of LiSa not dealing with partial samples in recPos posittion, not so much a issue of partial sample durations as such. We actually knew this already in that it's known that LiSa only interpolates at reading and not at writing. Maybe that does mean the recording loop must be a integer length as well; not sure.

The thing with loopEnd being off when loopEnd is also the max duration is still a bug, IMHO.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [12 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
 Forum index » DIY Hardware and Software » ChucK programming language
Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Forum with support of Syndicator RSS
Powered by phpBB © 2001, 2005 phpBB Group
Copyright © 2003 through 2009 by electro-music.com - Conditions Of Use