Old 12-12-2011, 12:14 PM   #1
Erriez
Human being with feelings
 
Join Date: Jun 2010
Location: The Netherlands
Posts: 104
Default How to define a multidimension array

Hi all,

I'd like to define a multidimension array as well as normal arrays in one single JS script. The syntax in C is:

Code:
int array1[50][64];
int array2[16];
I can't find it in the documentation how to do this. Any suggestions? Thanks!
Erriez is offline   Reply With Quote
Old 12-12-2011, 02:57 PM   #2
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: Holland
Posts: 1,653
Default

I just did a quick forum search for "array" in the JS subforum, and this topic seems relevant:
http://forum.cockos.com/showthread.php?t=79621
Tale is offline   Reply With Quote
Old 12-12-2011, 03:09 PM   #3
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: location, location
Posts: 7,680
Default

What Mich suggests in the other thread is the right way to do it. If you want a 64*16 array, then write arr[i*16+j] instead of arr[i][j].
schwa is offline   Reply With Quote
Old 12-13-2011, 12:14 PM   #4
Erriez
Human being with feelings
 
Join Date: Jun 2010
Location: The Netherlands
Posts: 104
Default

I saw the other thread, but I had a different question: I'd like to define multiple normal arrays mixed with multidimension arrays. After spending a lot of time to reinvent the wheel about this undocumented stuff, I found a solution.

My problem was located in the definition of the arrays which is completely different than I expected. Please find below a full working example with a memory verification:

Code:
errorsArray1 = 0;
errorsArray2 = 0;
errorsArray3 = 0;

// C style: int array1[3];
array1 = 3;
// C style: int array2[2][3];
array2 = (array1 + (2*3));
// C style: int array3[4];
array3 = (array1 + array2 + 4);

// Initialize arrays
array1[0] = 11;
array1[1] = 12;
array1[2] = 13;

array2[(0*3)+0] = 14;
array2[(0*3)+1] = 15;
array2[(0*3)+2] = 16;
array2[(1*3)+0] = 17;
array2[(1*3)+1] = 18;
array2[(1*3)+2] = 19;

array3[0] = 20;
array3[1] = 21;
array3[2] = 22;
array3[3] = 23;

// Verify arrays
(array1[0] != 11) ? errorsArray1 += 1;
(array1[1] != 12) ? errorsArray1 += 1;
(array1[2] != 13) ? errorsArray1 += 1;

(array2[(0*3)+0] != 14) ? errorsArray2 += 1;
(array2[(0*3)+1] != 15) ? errorsArray2 += 1;
(array2[(0*3)+2] != 16) ? errorsArray2 += 1;
(array2[(1*3)+0] != 17) ? errorsArray2 += 1;
(array2[(1*3)+1] != 18) ? errorsArray2 += 1;
(array2[(1*3)+2] != 19) ? errorsArray2 += 1;

(array3[0] != 20) ? errorsArray3 += 1;
(array3[1] != 21) ? errorsArray3 += 1;
(array3[2] != 22) ? errorsArray3 += 1;
(array3[3] != 23) ? errorsArray3 += 1;
Output: Variables errorsArray1, errorsArray2 and errorsArray3 are 0 which is OK.

Can someone please update the outdated page below?
http://www.reaper.fm/sdk/js/js.php
Arrays are the basics of programming! (Sorry for my frustration about this)

Thanks for your help!

Last edited by Erriez; 12-13-2011 at 12:55 PM.
Erriez is offline   Reply With Quote
Old 12-13-2011, 04:23 PM   #5
Mich
Human being with feelings
 
Join Date: May 2009
Posts: 1,265
Default

Quote:
Originally Posted by Erriez View Post
Can someone please update the outdated page below?
http://www.reaper.fm/sdk/js/js.php
Arrays are the basics of programming! (Sorry for my frustration about this)
What's outdated about the documentation?

Also grep for "array" in the documentation you will not find it. Because [] in JS designates a memory access and no array access. How the memory access works is clearly outlined in the documentation, no?

Just because JS uses squared brackets doesn't mean their semantic should be the same as in some other language! Squared brackets in JS access the memory at the position calculated from the value before the [] (the offset) plus the value within the [] (the index).

So in conclusion their is no array syntax in JS, hence no arrays.
__________________
Quote:
Originally Posted by vBulletin Message
Sorry pipelineaudio is a moderator/admin and you are not allowed to ignore him or her.
Mich is offline   Reply With Quote
Old 12-14-2011, 12:18 PM   #6
Erriez
Human being with feelings
 
Join Date: Jun 2010
Location: The Netherlands
Posts: 104
Default

The only documentation I found is this link, or do I miss something?

Quote:
Just because JS uses squared brackets doesn't mean their semantic should be the same as in some other language!
I agree, but it should be clearly documented and it's not.

Quote:
How the memory access works is clearly outlined in the documentation, no?
No. The memory access usage doc is maybe clear for you, but not for me:

Quote:
Chapter [ ]
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.

If 'gmem' is specified (the second form), then instead of local effect memory, the buffer is the global storage buffer, which is approximately 1 million (1,048,576) slots that are shared across all effects.
A simple real practical example is missing in this chapter. I discussed this theoretical text with two independent senior C programmers, but we don't understand it. I've wasted lots of hours debugging to find the right answer, but its still undefined behaviour for me.

Quote:
Squared brackets in JS access the memory at the position calculated from the value before the [] (the offset) plus the value within the [] (the index).
Sorry, we can't follow you: "at the position calculated from the value before the [] (the offset)" What do you mean?

Reaper developers, can you please change this chapter to human readable/practical documentation and spend a few words about 'arrays'? Reaper is made for musicians... not only for advanced programmers of a self-invented script language.
Erriez is offline   Reply With Quote
Old 12-14-2011, 03:31 PM   #7
IXix
Human being with feelings
 
Join Date: Jan 2007
Location: mcr:uk
Posts: 2,475
Default

It seems pretty well documented to me. I struggled with it at first but only because I hadn't read it properly.
IXix is online now   Reply With Quote
Old 12-14-2011, 10:55 PM   #8
Mich
Human being with feelings
 
Join Date: May 2009
Posts: 1,265
Default

Quote:
Originally Posted by Erriez View Post
Sorry, we can't follow you: "at the position calculated from the value before the [] (the offset)" What do you mean?

Reaper developers, can you please change this chapter to human readable/practical documentation and spend a few words about 'arrays'? Reaper is made for musicians... not only for advanced programmers of a self-invented script language.
snip -------------------------------------

Section MEMORY
==============
JesuSonic has 8,388,608 local memory slots per effect.
They can be accessed via square brackets.

The memory slot access syntax is as follows:
Code:
expr1[expr2]
This accesses the memory slot with offset 'expr1+expr2'.
A memory access is an expression itself.

<optional for non-programmers>

The syntax for write access is:
Code:
expr1[expr2] = expr3;
This will write the value of expr3 into the memory slot at offset 'expr1+expr2'.

The syntax for read access is:
Code:
var = expr1[expr2];
This will read the value of the memory slot at offset 'expr1+expr2'. Then write the value into variable 'var'.

</optional for non-programmers>

JesuSonic also provides 1,048,576 global memory slots shared across all effects [on a track(?)].
Global memory can be accessed with the reserved keyword 'gmem' followed by square brackets, the enclosed content of which indicates the offset into the global memory slots.
The global memory access syntax is as follows:
Code:
gmem[expr1]
This will access the global memory slot at offset 'expr1'.

---------------------------------- /snip

You want a documentation like that?
__________________
Quote:
Originally Posted by vBulletin Message
Sorry pipelineaudio is a moderator/admin and you are not allowed to ignore him or her.
Mich is offline   Reply With Quote
Old 12-15-2011, 04:12 AM   #9
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 12,288
Default

How about this approach? Thinking of a chessboard:

Code:
startofboard = 1024;                                            // start address  
noofcols = 8;                                                      // length of each dimension
noofrows = 8;
square = startofboard;                                         // name of the element in the array
endofboard = startofboard + (noofcols * noofrows);  // end address, 
                                                                       // for reference by the next array

// to access a square for column col_no and row row_no:
    current_sq = square[(col_no -1) * noofcols + (row_no -1));

// or
  sq_index = (col_no -1) * noofcols + (row_no -1);
  current_sq = square[sq_index];

--------------
or for a 3D chessboard

startofboard = 1024;
noofcols = 8;
noofrows = 8;
nooflayers = 8;
cube = startofboard;
endofboard = startofboard + (noofcols * noofrows * nooflayers);

// to access a particular square:
    current_cube = cube[((layer_no -1) * nooflayers + (col_no -1)) * noofcols + (row_no -1));

// or
  cube_index = ((layer_no -1) * nooflayers + (col_no -1)) * noofcols + (row_no -1);
  current_cube = cube[cube_index];
__________________
DarkStar ... interesting, if true.
My top 40 FRs, as voted by you
DarkStar is online now   Reply With Quote
Old 12-16-2011, 11:15 AM   #10
Erriez
Human being with feelings
 
Join Date: Jun 2010
Location: The Netherlands
Posts: 104
Default

Can you explain why the code below does not work?

Code:
array1 = 3;
array2 = (array1 + 6);
array3 = (array2 + 4);
Erriez is offline   Reply With Quote
Old 12-16-2011, 11:39 AM   #11
IXix
Human being with feelings
 
Join Date: Jan 2007
Location: mcr:uk
Posts: 2,475
Default

What you asked for...
Code:
array1 = 3;
array2 = (array1 + 6); // array2 = 3 + 6 == 9
array3 = (array2 + 4); // array3 = 9 + 4 == 13
All you did there was declare some variables and assign some values. If you want to access the memory buffer, you've got to use the square braces. It's not clear what you were expecting.
IXix is online now   Reply With Quote
Old 12-16-2011, 12:22 PM   #12
Erriez
Human being with feelings
 
Join Date: Jun 2010
Location: The Netherlands
Posts: 104
Default

Run the example and watch the error variables:

Code:
@init

errors1 = 0;
errors2 = 0;
errors3 = 0;

memtest1 = 3;
memtest2 = (memtest1 + 6);
memtest3 = (memtest2 + 4); // <- I expect that this is correct, but its not. Why???

// Initialize memtests
memtest1[0] = 11;
memtest1[1] = 12;
memtest1[2] = 13;

memtest2[0] = 14;
memtest2[1] = 15;
memtest2[2] = 16;
memtest2[3] = 17;
memtest2[4] = 18;
memtest2[5] = 19;

// This code corrupts memtest2
memtest3[0] = 20;
memtest3[1] = 21;
memtest3[2] = 22;
memtest3[3] = 23;

// Verify memtests
(memtest1[0] != 11) ? errors1 += 1;
(memtest1[1] != 12) ? errors1 += 1;
(memtest1[2] != 13) ? errors1 += 1;

// Failures detected in memtest2:
(memtest2[0] != 14) ? errors2 += 1;
(memtest2[1] != 15) ? errors2 += 1;
(memtest2[2] != 16) ? errors2 += 1;
(memtest2[3] != 17) ? errors2 += 1;
(memtest2[4] != 18) ? errors2 += 1;
(memtest2[5] != 19) ? errors2 += 1;

(memtest3[0] != 20) ? errors3 += 1;
(memtest3[1] != 21) ? errors3 += 1;
(memtest3[2] != 22) ? errors3 += 1;
(memtest3[3] != 23) ? errors3 += 1;
The example results in errors2 = 2, because the init is incorrect:
memtest1 = 3;
memtest2 = (memtest1 + 6);
memtest3 = (memtest2 + 4); // <- This line must be (memtest1 + memtest2 + 4)!

Everybody refers to this doc: z=x[y]; or x[y]=z;
But this seems not to work for memtest3, because it overwrites memtest2.

Anyone else?
Erriez is offline   Reply With Quote
Old 12-16-2011, 12:37 PM   #13
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 12,288
Default

Code:
memtest1 = 3;
memtest2 = (memtest1 + 6);
memtest3 = (memtest2 + 4); // <- I expect that this is correct, but its not. Why???
==>>
Code:
memtest1 = 3; // could be anything
memtest2 = (memtest1 + 3);
memtest3 = (memtest2 + 6); // <- I expect that this is correct, but its not. Why???
memtest2 must be 3 slots later than memtest1
memtest3 must be 6 slots later than memtest2

With the line memtest3 = (memtest2 + 4)
memtest3[0] is using the fourth slot after memtest2[0].
__________________
DarkStar ... interesting, if true.
My top 40 FRs, as voted by you
DarkStar is online now   Reply With Quote
Old 12-16-2011, 12:48 PM   #14
IXix
Human being with feelings
 
Join Date: Jan 2007
Location: mcr:uk
Posts: 2,475
Default

Looks to me like your offsets are, well, off. The start offset of each 'array' should be the base address of previous 'array' plus it's size...

Code:
memtest1 = 0;
memtest2 = memtest1 + 3;
memtest3 = memtest2 + 6;
Does that do what you're expecting?

edit: DarkStar types faster than I do
IXix is online now   Reply With Quote
Old 12-16-2011, 12:51 PM   #15
Erriez
Human being with feelings
 
Join Date: Jun 2010
Location: The Netherlands
Posts: 104
Default

Thank you very much, Darstar! That's the answer!

This works perfect and now I understand how the init works:

Code:
memtest1 = 0; // could be anything
memtest2 = (memtest1 + 3);
memtest3 = (memtest2 + 6);
Hmm, now I have to fix all my scripts... :-)

edit: Thanks IXix, I was 3 minutes later...
Erriez is offline   Reply With Quote
Old 12-16-2011, 12:52 PM   #16
IXix
Human being with feelings
 
Join Date: Jan 2007
Location: mcr:uk
Posts: 2,475
Default

Also, you might be interested in something which I posted to the useful snippets thread a long time ago. Very handy for working with memory blocks .
IXix is online now   Reply With Quote
Old 12-16-2011, 01:00 PM   #17
Erriez
Human being with feelings
 
Join Date: Jun 2010
Location: The Netherlands
Posts: 104
Default

That's a great tool, IXix! Very useful. Thanks!
Erriez is offline   Reply With Quote
Old 12-25-2011, 01:35 AM   #18
Zoab
Human being with feelings
 
Join Date: Dec 2011
Posts: 3
Default

I've been struggling with arrays, and though I managed to figure out my problem. I find this thread very strange:

Quote:
Originally Posted by IXix View Post
Looks to me like your offsets are, well, off. The start offset of each 'array' should be the base address of previous 'array' plus it's size...

Code:
memtest1 = 0;
memtest2 = memtest1 + 3;
memtest3 = memtest2 + 6;
Does that do what you're expecting?

edit: DarkStar types faster than I do
It seems to me that by coding:
Code:
memtest = 0;
memtest2 = memtest1+3;
etc...
you are suggesting that memtest1 will start from memory 0, and memtest2 will start from memory memtest1+3 = (in this case) 3.
However, as far as I understand you are just storing the number 0 in memtest1 and then storing the number 0+3 = 4 in memtest2.

Am I wrong or are you actually defining an array in memory?

Confused,
Zoab

Edit: I've added an image to show my confusion.
Attached Images
File Type: jpg Capture2.jpg (7.2 KB, 39 views)

Last edited by Zoab; 12-25-2011 at 01:46 AM. Reason: I've added an image that explains my confusion :)
Zoab is offline   Reply With Quote
Old 12-25-2011, 02:20 AM   #19
Erriez
Human being with feelings
 
Join Date: Jun 2010
Location: The Netherlands
Posts: 104
Default

Hello Zoab,

I understand your confusion, because the debugger (your screenshot) does not display the contents of the memory (array). Your code is correct to define arrays:

Code:
memtest1 = 0; // Any
memtest2 = memtest1 + 3; // memtest1 size = 3
memtest3 = memtest2 + 6; // memtest2 size = 2
// memtest3 size = (undefined?)

// Memtest1 size is 3:
memtest1[0] = 7; // First
...
memtest1[2] = 8; // Last

// Memtest2 size is 6:
memtest2[0] = 9; // First
...
memtest2[5] = 10; // Last

memtest3[0] = 11; // First
...
See also IXix post which contains a nice memory debugger:
Quote:
Also, you might be interested in something which I posted to the useful snippets thread a long time ago. Very handy for working with memory blocks .
Erriez is offline   Reply With Quote
Old 12-26-2011, 02:18 AM   #20
Mich
Human being with feelings
 
Join Date: May 2009
Posts: 1,265
Default

Quote:
Originally Posted by Zoab View Post
Am I wrong or are you actually defining an array in memory?
You don't define arrays in JS. There are no arrays in JS. Search the documentation no single mention of array in their.
What you have is 8M memory slots per effect and a[b] accesses the memory slot with offset a+b. Simple as that.

So in case a=0; b=3; a[0]=1; b[0]=2; a[1]=3; b[3]; you'd get your effects memory slots like: {1, 3, 0, 2, 0, 0, 6, ...}
Then doing 0[0] == 1; 0[1] == 3; 0[3] == 2; or even 2[3] == 6; will all evaluate to true.

EDIT: Just to reiterate you don't define arrays in JS. The memory region you access is just there from the very beginning and you just use it.
__________________
Quote:
Originally Posted by vBulletin Message
Sorry pipelineaudio is a moderator/admin and you are not allowed to ignore him or her.
Mich is offline   Reply With Quote
Reply

Tags
array, c style, js script, multidimension

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 02:53 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.