Old 03-16-2010, 06:39 PM   #1
fladd
Human being with feelings
 
fladd's Avatar
 
Join Date: May 2006
Posts: 937
Default Can anyone explain this code to me?

Hi there,

can anyone please explain this code from the Wiki to me? It just doesn't make any sense to me!

Code:
desc:Echo
slider1:120<0,1000,1>Length [ms]

@slider
echolength = slider1 / 1000 * srate ;

@sample
bufpos[0] = spl0 ;
bufpos = bufpos + 1 ;
bufpos > echolength ? bufpos = 0;
spl0 = spl0 + bufpos[0] ; 
spl1 = spl0 ;
So, as far as I understand, it takes each sample and puts it at the beginning of an array/buffer. So far, so good.
But now, it increments this array (how can you increment an array? What does that mean? Is this shifting all items in that array one further?).
It then checks if the length of the array (?) is already the same as the echo length. If so, it empties the array.
And then, it replaces the actual sample with the one that now is at the beginning of the array.
So how exactly would this echo a signal?

Regards,
fladd
__________________
www.fladd.de/sound
fladd is offline   Reply With Quote
Old 03-16-2010, 07:33 PM   #2
Mich
Human being with feelings
 
Join Date: May 2009
Posts: 1,265
Default

JesuSonic "arrays" work differently than normal arrays.

Quote:
Originally Posted by JesuSonic Documentation
[ ]
Example: z=x[y]; or x[y]=z;
Example: z=gmem[y]; or gmem[y]=z;
In the first form, you may use brackets to index into memory that is local to your effect. Your effect has approximately 8 million (8,388,608) slots of memory and you may access them either with fixed offsets (i.e. 16811[0]) or with variables (myBuffer[5]). If a value in the brackets is omitted then 0 is used instead.
[...]

Basically you have 8M memory slots that you can access the following ways:
0[0] which evaluates to the 0-th memory slot
m[0] evaluates to th m-th slot
0[m] also to the m-th
n[m] to the (n+m)-th
etc...

Code:
What this effect does is, insert the current sample value at memory location bufpos, so the memory locks like this:
1---------
^bufpos
         ^echolength
Then in the next step bufpos is incremented:
1---------
 ^bufpos
Then the memory slot at bufpos is read and added to the current sample.

The effect turns into an echo once that process is repeated.
Store next sample at bufpos and increment bufpos:
12--------
  ^bufpos
until bufpos reaches echolength:
1234567890
          ^bufpos
at which point you wrap around bufpos to the start (bufpos > echolength part):
1234567890
^bufpos
so you emulate a ringbuffer.

Hope that helps.
Mich is offline   Reply With Quote
Old 03-16-2010, 11:17 PM   #3
Analogy
Human being with feelings
 
Join Date: Sep 2009
Posts: 871
Default

Even though Jesusonic uses a syntax that looks like an array from most languages you would be used to, it is actually nothing like anything you would be used to.

Using the array syntax [] treats the variable that it is applied to as an index into the effect's local memory array. The number in the brackets is just an offset from the index defined by the value of the variable.

Here's a practical example

Code:
a=0;
b=2;

a[0]=.2;
a[1]=.4;
a[2]=.6;

spl0=a[0]; // .2

a=1;

spl1=a[0]; // .4, a is now 1, so [0] indexes into position 1 in the array
spl2=b[0]; // .6, b is 2, so [0] indexes into position 2. You can return values from anywhere in the array, even if they were set through a different variable.

spl3=b[-2]; // .2, you can use a negative offset to go backwards in the array

spl4=a[b]; //These two statements return the same value
spl5=b[a];

c=a+b; //c is now 3, you can still use your "array index" variables for math or comparison operations

Last edited by Analogy; 03-17-2010 at 01:05 AM.
Analogy is offline   Reply With Quote
Old 03-17-2010, 02:50 PM   #4
fladd
Human being with feelings
 
fladd's Avatar
 
Join Date: May 2006
Posts: 937
Default

Quote:
Originally Posted by Mich View Post
JesuSonic "arrays" work differently than normal arrays.




Basically you have 8M memory slots that you can access the following ways:
0[0] which evaluates to the 0-th memory slot
m[0] evaluates to th m-th slot
0[m] also to the m-th
n[m] to the (n+m)-th
etc...

Code:
What this effect does is, insert the current sample value at memory location bufpos, so the memory locks like this:
1---------
^bufpos
         ^echolength
Then in the next step bufpos is incremented:
1---------
 ^bufpos
Then the memory slot at bufpos is read and added to the current sample.

The effect turns into an echo once that process is repeated.
Store next sample at bufpos and increment bufpos:
12--------
  ^bufpos
until bufpos reaches echolength:
1234567890
          ^bufpos
at which point you wrap around bufpos to the start (bufpos > echolength part):
1234567890
^bufpos
so you emulate a ringbuffer.

Hope that helps.
Thanks a lot for that explanation, it is clear to me now. The missing parts where indeed the extreme strange syntax of addressing the buffer as well as the fact that I am not playing anything back until the buffer reaches the length of the echo.

fladd
__________________
www.fladd.de/sound
fladd is offline   Reply With Quote
Old 03-17-2010, 02:52 PM   #5
fladd
Human being with feelings
 
fladd's Avatar
 
Join Date: May 2006
Posts: 937
Default

Quote:
Originally Posted by Analogy View Post
Even though Jesusonic uses a syntax that looks like an array from most languages you would be used to, it is actually nothing like anything you would be used to.

Using the array syntax [] treats the variable that it is applied to as an index into the effect's local memory array. The number in the brackets is just an offset from the index defined by the value of the variable.

Here's a practical example

Code:
a=0;
b=2;

a[0]=.2;
a[1]=.4;
a[2]=.6;

spl0=a[0]; // .2

a=1;

spl1=a[0]; // .4, a is now 1, so [0] indexes into position 1 in the array
spl2=b[0]; // .6, b is 2, so [0] indexes into position 2. You can return values from anywhere in the array, even if they were set through a different variable.

spl3=b[-2]; // .2, you can use a negative offset to go backwards in the array

spl4=a[b]; //These two statements return the same value
spl5=b[a];

c=a+b; //c is now 3, you can still use your "array index" variables for math or comparison operations
Thanks for this explanation, too. It clarifies the weird syntax of incrementing the buffer.

fladd
__________________
www.fladd.de/sound
fladd is offline   Reply With Quote
Old 03-18-2010, 02:22 AM   #6
Fabian
Human being with feelings
 
Fabian's Avatar
 
Join Date: Sep 2008
Location: Sweden
Posts: 5,263
Default

Follow-up question...

Is there any efficiency benefit to either of the two identical codes below?

Code:
@sample
bufpos[0] = spl0 ;
bufpos = bufpos + 1 ;
bufpos > echolength ? bufpos = 0;
Code:
@init
n = 0;
bufpos = 128; // this is to make sure the buffer does not overwrite n

@sample
bufpos[n] = spl0 ;
n = n + 1 ;
n > echolength ? n = 0;
If the first one is not more efficient than the second one, then I consider it needlessly obfuscated (as the OP indicates).

And, BTW, this is not much different from C/C++, you can do a similar thing, bufpos being a pointer to the buffer, a pointer can be redirected in two ways, either *bufpos or bufpos[0]. And in C/C++ there's no difference, the compiler turns one into the other...
__________________
// MVHMF
I never always did the right thing, but all I did wasn't wrong...
Fabian is offline   Reply With Quote
Old 03-20-2010, 04:38 PM   #7
Analogy
Human being with feelings
 
Join Date: Sep 2009
Posts: 871
Default

Quote:
@init
n = 0;
bufpos = 128; // this is to make sure the buffer does not overwrite n

@sample
bufpos[n] = spl0 ;
n = n + 1 ;
n > echolength ? n = 0;
I don't see why you would do this. As far as I know, regular variables don't live in the buffer, so you would never overwrite them by writing to the buffer. You would only really do this if you want to keep two chunks of audio in the buffer, one from 0 to 127, and one from 128 to (echolength+128)

From an efficiency standpoint, the first example should take a very very slight edge, depending on how much overhead is introduced by having to fetch n and add it to bufpos before diving into the array. I'm assuming that in the compiler, bufpos[0] turns into a simple pointer into the array, while bufpos[n] has to add a few operations that fetch n, add it to bufpos and use the resulting number as the pointer. Honestly, nitpicky stuff.
Analogy is offline   Reply With Quote
Old 03-25-2010, 06:31 AM   #8
Mich
Human being with feelings
 
Join Date: May 2009
Posts: 1,265
Default

Quote:
Originally Posted by Fabian View Post
If the first one is not more efficient than the second one, then I consider it needlessly obfuscated (as the OP indicates).
Well it depends, regarding efficiency I don't know how JS internally handles it, but like Analogy already said, the 'n' is not needed in JS, so if you don't consider what this code should look like in C or any other programming language but JS then it is IMO not obfuscated at all since it is essentially reduced to the essentials.
Mich is offline   Reply With Quote
Old 03-25-2010, 07:12 AM   #9
dub3000
Human being with feelings
 
dub3000's Avatar
 
Join Date: Mar 2008
Location: Sydney, Australia
Posts: 3,813
Default

might also be worth investigating something like

n = (n + 1) % echolength;

instead of the last two lines.

might be slower or faster, depends on the implementation (mod is expensive, but so are branches).
dub3000 is online now   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 07:21 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.