Author |
Message |
Dr. Spankenstein
Joined: Mar 03, 2007 Posts: 136 Location: Cambridge
Audio files: 1
|
Posted: Sun Sep 23, 2007 9:29 am Post subject:
A simple ramping evelope that I can only ramp upwards? |
 |
|
I'm having problems when getting the Envelope STK to ramp from one point to another should the target be below the original value.
Code: |
SndBuf Buffer1 => Gain Gain => Envelope e => dac;
"YellowMello(80).wav" => Buffer1.read;
1 => Buffer1.gain;
1 => Buffer1.loop;
0.0 => e.value;
1.0 => e.target;
0.5 => e.time;
10000::ms => now;
|
This will ramp from 0.0 to 1.0 no problem but if I try going from 1.0 to 0.0 it doesnt work?!
Have I missed something?
Code: |
SndBuf Buffer1 => Gain Gain => Envelope e => dac;
"YellowMello(80).wav" => Buffer1.read;
1 => Buffer1.gain;
1 => Buffer1.loop;
1.0 => e.value;
0.0 => e.target;
0.5 => e.time;
10000::ms => now;
|
Thanks
Rhys |
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Sun Sep 23, 2007 3:47 pm Post subject:
|
 |
|
Oh wow yes!
I've just tested it and seen this same problem in the performance in Envelope also!
it makes me kinda confused about the way it performs..
is it working in Ratio rather than Value?
hmmm I'm not sure, let's look at this:
(tested on chuck 1.2.1.0)
here goes:
Code: | Envelope e => blackhole;
fun void check01()
{
for(int i; i < 10; i++)
{
<<< e.last() >>>;
.1::second => now;
}
}
<<< "stage 1: 0 -> 1" >>>;
0.0 => e.value;
samp => now; // reset envelope
1.0 => e.time;
1.0 => e.target;
check01();
<<< "stage 2: 1 -> 0" >>>;
1.0 => e.value;
samp => now; // reset envelope
1.0 => e.time;
0.0 => e.target;
check01();
<<< "stage 3: 0 -> 2" >>>;
0.0 => e.value;
samp => now; // reset envelope
1.0 => e.time;
2.0 => e.target;
check01();
<<< "stage 4: 1 -> 2" >>>;
1.0 => e.value;
samp => now; // reset envelope
1.0 => e.time;
2.0 => e.target;
check01();
<<< "stage 5: 2 -> 1" >>>;
2.0 => e.value;
samp => now; // reset envelope
1.0 => e.time;
1.0 => e.target;
check01(); |
result:
Code: | "stage 1: 0 -> 1" : (string)
0.000000 :(float)
0.100000 :(float)
0.200000 :(float)
0.300000 :(float)
0.400000 :(float)
0.500000 :(float)
0.600000 :(float)
0.700000 :(float)
0.800000 :(float)
0.900000 :(float)
"stage 2: 1 -> 0" : (string)
1.000000 :(float)
1.000000 :(float)
1.000000 :(float)
1.000000 :(float)
1.000000 :(float)
1.000000 :(float)
1.000000 :(float)
1.000000 :(float)
1.000000 :(float)
1.000000 :(float)
"stage 3: 0 -> 2" : (string)
0.000000 :(float)
0.200000 :(float)
0.400000 :(float)
0.600000 :(float)
0.800000 :(float)
1.000000 :(float)
1.200000 :(float)
1.400000 :(float)
1.600000 :(float)
1.800000 :(float)
"stage 4: 1 -> 2" : (string)
1.000000 :(float)
1.200000 :(float)
1.400000 :(float)
1.600000 :(float)
1.800000 :(float)
2.000000 :(float)
2.000000 :(float)
2.000000 :(float)
2.000000 :(float)
2.000000 :(float)
"stage 5: 2 -> 1" : (string)
2.000000 :(float)
1.900000 :(float)
1.800000 :(float)
1.700000 :(float)
1.600000 :(float)
1.500000 :(float)
1.400000 :(float)
1.300000 :(float)
1.200000 :(float)
1.100000 :(float) |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Sep 25, 2007 6:02 pm Post subject:
|
 |
|
kijjaz wrote: | is it working in Ratio rather than Value?
|
I think it is. I made some modifications to your test file (I also changed the function to report e.value() instead of e.last(), your way I only get 0's)
Look at this;
Quote: | "stage 2: 1 -> 0.0001" : (string)
1.000000 :(float)
0.999990 :(float)
0.999980 :(float)
0.999970 :(float)
0.999960 :(float)
0.999950 :(float)
0.999940 :(float)
0.999930 :(float)
0.999920 :(float)
0.999910 :(float)
|
I edited it that way to see if ramping to 0 was the problem as opposed to ramping down. This is just plainly wrong.
On a whim I looked at the source and I believe this function from ugen_stk.cpp to be the offending component;
Code: |
void Envelope :: setTime(MY_FLOAT aTime)
{
if (aTime < 0.0) {
printf("[chuck](via Envelope): negative times not allowed ... correcting!\n");
rate = m_target / (-aTime * Stk::sampleRate());
}
else if( aTime == 0.0 )
rate = FLT_MAX;
else
rate = m_target / (aTime * Stk::sampleRate());
m_time = aTime;
if( m_time < 0.0 ) m_time = -m_time;
} |
here "rate" is being calculated and as far as I can tell "rate" is being added to the envelope's value every sample. This, however doesn't seem to take the current value of the envelope into account.
Code: | rate = ( m_target - value ) / (aTime * Stk::sampleRate()); |
Or something along those lines would be better, at least as far as I understand what's going on (which is not at all far!). Basically what we are seeing is behaviour that pretends it starts at 0, then continues in a relative fashion. I tried tricking it by starting at 1, then making it ramp to -1 but it also seems to assume negative values to ramp to are wrong (and need correction) so this made it ramp to 2.
There is something very weird going on here, I don't see what would be so bad about "rate" being negative either yet there is a device in there speciffically aimed at "correcting" negative rates. _________________ Kassen |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Sep 25, 2007 6:43 pm Post subject:
|
 |
|
HA! I fixed something! I tried recompiling ChucK with the line I suggested above and this actually works! Now ramping from 1 to 2 works properly instead of going at a double rate, then stopping at 2 after half a second.
I'm sure this isn't so amazing to many but I never programmed in C before. Now let's see if I can get it to ramp down properly as well.... _________________ Kassen |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Sep 25, 2007 7:38 pm Post subject:
|
 |
|
Fixed!
In that file edit the function to read like this;
Code: |
void Envelope :: setTime(MY_FLOAT aTime)
{
if (aTime < 0.0) {
printf("[chuck](via Envelope): negative times not allowed ... correcting!\n");
rate = m_target / (-aTime * Stk::sampleRate());
}
else if( aTime == 0.0 )
rate = FLT_MAX;
else
rate = (m_target -value) / (aTime * Stk::sampleRate());
if (rate < 0.0 ) { rate = -rate; }
m_time = aTime;
if( m_time < 0.0 ) m_time = -m_time;
} |
and recompile.
This gives the correct behaviour when ramping up or down from non-zero starting points. The issue was that "rate" should indeed be positive and it's added or subtracted based on whether the target is below or above the current value. My solution resulted in a negative rate while ramping down, this resulted in ramping up and the old solution resulted in wrong amounts to ramp by.
Disclaimer; this is the first C code I ever wrote/edited. As such I wouldn't be at all surprised if it had side-effects, exploded or otherwise resulted in issues and neither should you. I compiled it successfully, then got decent results, no warranties, no refunds. _________________ Kassen |
|
Back to top
|
|
 |
Dr. Spankenstein
Joined: Mar 03, 2007 Posts: 136 Location: Cambridge
Audio files: 1
|
Posted: Wed Sep 26, 2007 6:22 am Post subject:
|
 |
|
Brilliant!! Kassen to the rescue (again).
I'm off to recompile it with your new code so I can carry on with what I started.
Many thanks
Rhys
...Just had a thought. I dont have Visual C++, can anyone recommend a free compiler that would work with this, or could Kassen attach the new .exe perhaps? |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Wed Sep 26, 2007 6:46 am Post subject:
|
 |
|
Thanks!
Looking at it again I see I missed something. If you would inadvertently use a negative amount of duration it won't be relative anymore like that. I also see I don't need those curly brackets so let's do yet another version;
Code: |
void Envelope :: setTime(MY_FLOAT aTime)
{
if (aTime < 0.0) {
printf("[chuck](via Envelope): negative times not allowed ... correcting!\n");
rate = (m_target -value) / (-aTime * Stk::sampleRate());
}
else if( aTime == 0.0 )
rate = FLT_MAX;
else
rate = (m_target -value) / (aTime * Stk::sampleRate());
if (rate < 0.0 ) rate = -rate;
m_time = aTime;
if( m_time < 0.0 ) m_time = -m_time;
} |
Looks better to me but it's kinda trivial, I don't think "negative time" is that common.
About a .exe; I did this using the GCC compiler on Linux. I did think of you (and my XP laptop) and tried to compile it for Windows but GCC refused. Maybe Philippe can help us as he's been making those wonderful ASIO versions too, otherwise we'll have to wait for Ge& Spencer and a official fix or perhaps some friendly passer by will help? _________________ Kassen |
|
Back to top
|
|
 |
Blue Hell
Site Admin

Joined: Apr 03, 2004 Posts: 24040 Location: The Netherlands, Enschede
Audio files: 276
G2 patch files: 320
|
|
Back to top
|
|
 |
moudi
Joined: Oct 07, 2006 Posts: 63 Location: Bern Switzerland
|
Posted: Wed Sep 26, 2007 3:32 pm Post subject:
|
 |
|
Dr. Spankenstein wrote: | ...Just had a thought. I dont have Visual C++, can anyone recommend a free compiler that would work with this, or could Kassen attach the new .exe perhaps? |
it should be possible with eclipse:
http://www.eclipse.org
jassas
/moudi |
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Wed Sep 26, 2007 9:17 pm Post subject:
|
 |
|
Kassen: Wow.. that's really cool of you.
I'll try that, thanks.
I was always confused about the result of Envelope hahahh
-_-" I've just noticed its result. |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Thu Sep 27, 2007 5:41 am Post subject:
|
 |
|
Well, it was your investigation that gave me a hunch, you deserve credit too. Open Source is pritty cool! :¬)
Right now I'm considering that maybe Envelope should be able to ramp to negative values too, for example when it's used to interpolate between values for LiSa or SndBuf rates. A gain set to -1 won't do when you are trying to slide from 2 to -2, at least not without a extra set of parameter changes halfway.
There's also cool stuff in the source that seems disabled, for example a modeled police whistle called "Whistle" that I can't seem to reach from ChucK syntax. Poking around is fun :¬) _________________ Kassen |
|
Back to top
|
|
 |
Blue Hell
Site Admin

Joined: Apr 03, 2004 Posts: 24040 Location: The Netherlands, Enschede
Audio files: 276
G2 patch files: 320
|
Posted: Fri Sep 28, 2007 4:50 pm Post subject:
|
 |
|
I split off a bunch of posts re. setting up visual c++ express to : http://electro-music.com/forum/topic-20796.html - it seemed a bit off topic here. _________________ Jan
also .. could someone please turn down the thermostat a bit.
 |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Fri Sep 28, 2007 5:49 pm Post subject:
|
 |
|
Sounds fine to me. _________________ Kassen |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Sun Sep 30, 2007 8:29 am Post subject:
|
 |
|
Philippe brought to my attention that the fix STILL wasn't right. For one thing after using "target" a few times keyOff and keyOn didn't work properly anymore. I poked around quite a bit and as far as I can tell this was likely caused by those functions not re-scaling "rate" if you don't re-define the duration. Also odd was that the scaling functions operate on "m_target" instead of "target" while keyOff didn't set m_target at all.
I sorta kinda hacked it up, using a sharp stone, some runes and a rain-dance. The good news is that now everything I threw at it worked properly. The bad news is that Envelope gets re-used by many other Ugens and I didn't test how/if this affects those. If you use this "fix" in any important or mission-critical application you are crazy and I can't be held responcible for the outcome (but it seems to work for me).
Code: | /***************************************************/
/*! \class Envelope
\brief STK envelope base class.
This class implements a simple envelope
generator which is capable of ramping to
a target value by a specified \e rate.
It also responds to simple \e keyOn and
\e keyOff messages, ramping to 1.0 on
keyOn and to 0.0 on keyOff.
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
----------------
This is a experimental "fixed" version by Kassen who doesn't speak C++.
Don't use this for anything important untill the official devs
have had a look at it, Don't say I didn't warn you.
this is a modification on ugen_stk.cpp for chuck 1.2.1.0,
which is covered by the GPL (and so so is this).
*/
/***************************************************/
#include <stdio.h>
Envelope :: Envelope(void) : Stk()
{
target = (MY_FLOAT) 0.0;
value = (MY_FLOAT) 0.0;
rate = (MY_FLOAT) 0.001;
m_target = 1.0;
m_time = rate * Stk::sampleRate();
state = 0;
}
Envelope :: ~Envelope(void)
{
}
void Envelope :: keyOn(void)
{
target = (MY_FLOAT) m_target;
if (value != target) state = 1;
setTime( m_time );
}
void Envelope :: keyOff(void)
{
target = (MY_FLOAT) 0.0;
if (value != target) state = 1;
setTime( m_time );
}
void Envelope :: setRate(MY_FLOAT aRate)
{
if (aRate < 0.0) {
printf("[chuck](via Envelope): negative rates not allowed ... correcting!\n");
rate = -aRate;
}
else
rate = aRate;
m_time = (target - value) / (rate * Stk::sampleRate());
if( m_time < 0.0 ) m_time = -m_time;
}
void Envelope :: setTime(MY_FLOAT aTime)
{
if (aTime < 0.0) {
printf("[chuck](via Envelope): negative times not allowed ... correcting!\n");
rate = (target -value) / (-aTime * Stk::sampleRate());
}
else if( aTime == 0.0 )
rate = FLT_MAX;
else
rate = (target - value) / (aTime * Stk::sampleRate());
if (rate < 0.0 ) rate = -rate;
m_time = aTime;
if( m_time < 0.0 ) m_time = -m_time;
}
void Envelope :: setTarget(MY_FLOAT aTarget)
{
target = m_target = aTarget;
if (value != target) state = 1;
// set time
setTime( m_time );
}
void Envelope :: setValue(MY_FLOAT aValue)
{
state = 0;
target = aValue;
value = aValue;
}
int Envelope :: getState(void) const
{
return state;
}
MY_FLOAT Envelope :: tick(void)
{
if (state) {
if (target > value) {
value += rate;
if (value >= target) {
value = target;
state = 0;
}
}
else {
value -= rate;
if (value <= target) {
value = target;
state = 0;
}
}
}
return value;
}
MY_FLOAT *Envelope :: tick(MY_FLOAT *vec, unsigned int vectorSize)
{
for (unsigned int i=0; i<vectorSize; i++)
vec[i] = tick();
return vec;
}
MY_FLOAT Envelope :: lastOut(void) const
{
return value;
}
|
_________________ Kassen |
|
Back to top
|
|
 |
Blue Hell
Site Admin

Joined: Apr 03, 2004 Posts: 24040 Location: The Netherlands, Enschede
Audio files: 276
G2 patch files: 320
|
|
Back to top
|
|
 |
Dr. Spankenstein
Joined: Mar 03, 2007 Posts: 136 Location: Cambridge
Audio files: 1
|
Posted: Tue Oct 02, 2007 5:50 am Post subject:
|
 |
|
Thanks very much Blue!
Here's an non ASIO flavoured windows version but with Kassen's new env code and is a non debug version. (Taken down)
Rhys
....after that it seems that the new env code works but as soon as I try to do anything more complex outside that then ChucK crashes...back to the drawing board methinks.
PS. Unfortunately it does the same thing with Blue's code returning an error of:
Run-Time Check Failure 3: The variable 'dword' is being used without being defined
I think damn is the only d word that springs to mind right now  |
|
Back to top
|
|
 |
Blue Hell
Site Admin

Joined: Apr 03, 2004 Posts: 24040 Location: The Netherlands, Enschede
Audio files: 276
G2 patch files: 320
|
Posted: Tue Oct 02, 2007 6:27 am Post subject:
|
 |
|
Interesting error message
Do you have a piece of chuck code that reproduces the error? _________________ Jan
also .. could someone please turn down the thermostat a bit.
 |
|
Back to top
|
|
 |
Dr. Spankenstein
Joined: Mar 03, 2007 Posts: 136 Location: Cambridge
Audio files: 1
|
Posted: Tue Oct 02, 2007 7:53 am Post subject:
|
 |
|
I do, however you're not gonna like what I say.....
...its my project code, which has been likened to the size of a phone book!
I wouldnt know where to begin.
Rhys
EDIT: Looking thru the source code reveals that the dword is something to do with sound files and buffers. |
|
Back to top
|
|
 |
Blue Hell
Site Admin

Joined: Apr 03, 2004 Posts: 24040 Location: The Netherlands, Enschede
Audio files: 276
G2 patch files: 320
|
Posted: Tue Oct 02, 2007 8:07 am Post subject:
|
 |
|
Dr. Spankenstein wrote: | I do, however you're not gonna like what I say..... |
I thought you might have something simple, phone books are not too interesting for me indeed  _________________ Jan
also .. could someone please turn down the thermostat a bit.
 |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Oct 02, 2007 9:49 am Post subject:
|
 |
|
Dr. Spankenstein wrote: | Thanks very much Blue!
....after that it seems that the new env code works but as soon as I try to do anything more complex outside that then ChucK crashes...back to the drawing board methinks.
|
OUCH!
I just tried running the otf_0n.ck examples and those seem fine to me here.
I can't rule it out but my fix doesn't define any new variables, doesn't perform any sort of operation that's not already there in a very similar form and the only functions that I'm calling are also called by similar things right next to them. I'm most definitely not defining any "dword's", whatever those are. Defining things in C++ is well beyond me at this point.
How about renaming this version to "chuck_asio", then seeing whether the plain one from the official site does this as well? Oh, and perhaps also compare it to Philippe's version of the official one?
IMHO phonebooks suck, BTW. Size is fine but the larger it gets the more you need structure. Clean names for everything, moving all similar passages to function calls, using classes where they make sense (and nowhere else!). Any passage that looks monotonous can likely be moved to a table or function.
I had a cleanup-spree again of my own sequencer code a few days ago and got it to be yet smaller (28k last time I looked) and a lot cleaner. With small& clean code bugs drift to the surface naturally. Another advantage of small&clean code is that it forces you to be precise about what you mean.
While I'm lecturing, which feels quite silly to me, I might as well make it yet sillier. The following link about writing English is by a game-designer who's mainly famous for being one of the best Street Fighter players in the world;
http://www.sirlin.net/archive/writing-well-part-2-clear-thinking-clear-writing/ I enjoyed that a lot and if you have a phonebook that's hard to manage you may get something out of it. You may also want to look up "refactoring" in the context of object oriented programing.
Apologies if this was out of line and perhaps my "fix" *is* to blame but by the time you experience your code as a phonebook you need a cleanup-spree or ther will be trouble in the near future which would be a waste of all your work but what do I know? Perhaps a MB of ChucK code is the bare minimum for your cutter :¬). _________________ Kassen |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Oct 02, 2007 9:53 am Post subject:
|
 |
|
Dr. Spankenstein wrote: |
EDIT: Looking thru the source code reveals that the dword is something to do with sound files and buffers. |
That's likely caused by rtAudio getting used in some inappropriate way then. Perhaps somewhere in your phonebook is something that brings yet another chuck-bug to light... that can't be ruled out (I would even call it likely), we already saw two bugs in Envelope alone. _________________ Kassen |
|
Back to top
|
|
 |
Dr. Spankenstein
Joined: Mar 03, 2007 Posts: 136 Location: Cambridge
Audio files: 1
|
Posted: Tue Oct 02, 2007 10:43 am Post subject:
|
 |
|
The "back to the drawing board" comment was referring to myself and and the way I had compiled the code, after a long time of trying different methods, adding libraries, bits of code in header files and downloading SDKs I felt a lot out of my depth and figured I had done something wrong when compiling your code.
As for the shortening of mycode, its an ongoing process and I'm one of these people who just keeps adding things to the code before later refining it but I shall have a look at the linked page as it will come in handy.
Rhys |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Oct 02, 2007 10:56 am Post subject:
|
 |
|
Yeah, I do that too, I add things is a fairly impulsive way, it gets much larger and messier and at some point it all gets refined back down.
Before you take that link as accusation of unclear thinking; what I mean is that I myself enjoy the process of refining my musical thoughts until they compact and precise code. It's a interesting process that taught me a lot and so I recommend it. _________________ Kassen |
|
Back to top
|
|
 |
Blue Hell
Site Admin

Joined: Apr 03, 2004 Posts: 24040 Location: The Netherlands, Enschede
Audio files: 276
G2 patch files: 320
|
Posted: Tue Oct 02, 2007 4:48 pm Post subject:
|
 |
|
Kassen wrote: | http://www.sirlin.net/archive/writing-well-part-2-clear-thinking-clear-writing/ |
The link doesn't work ... firefox insists that there is no www server at www.sirlin.net ... anyway, it got cached somewhere (if we're all still talking about the same things), and the text would good for some fine quotes
Sorry to have no progress on the topic, got distracted by some issues re. the G2 patch archive. _________________ Jan
also .. could someone please turn down the thermostat a bit.
 |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Oct 02, 2007 5:24 pm Post subject:
|
 |
|
That's quite odd.
It could've come from my cashe. I don't always agree with David but he makes some very good points there that I found quite relevant with regard to coding for expressive systems like music. I found -to my disturbance- that a lot of the time when I sit down with what looks like a solid plan it turns out that I really don't know what I want.
At that point it's either a "phone book" or retiring to the couch or bed with a piece of paper and a pipe. _________________ Kassen |
|
Back to top
|
|
 |
|