Array Opcodes
An array must be created (via init or fillarray) as kMyName plus ending brackets. The brackets determine the dimensions of the array. So,
kArr[] init 10
creates a one-dimensional array of length 10, whereas
kArr[][] init 10, 10
creates a two-dimensional array with 10 rows and 10 columns.
After the initalization of the array, referring to the array as a whole is done without any brackets. Brackets are only used if an element is indexed:
kArr[] init 10 ;with brackets because of initialization kLen = lenarray(kArr) ;without brackets kFirstEl = kArr[0] ;indexing with brackets
The same syntax is used for a simple copy via the '=' operator:
kArr1[] fillarray 1, 2, 3, 4, 5 kArr2[] = kArr1 ;creates kArr2 as copy of kArr1
Note that most array operations are currently k-rate only. So like any other k-rate opcode, an operation on arrays will be automatically repeated every k-cycle. For instance, this code will repeat re-writing the array with different random values every k-cycle, as long as the instrument runs:
kArr[] init 10 kIndx = 0 until kIndx == lenarray(kArr) do kArr[kIndx] rnd31 10, 0 kIndx += 1 od
If you want to avoid this, you must organize it in one of the usual ways, for instance by using a trigger:
kArr[] init 10 kTrig metro 1 if kTrig == 1 then ;do the following once a second kIndx = 0 until kIndx == lenarray(kArr) do kArr[kIndx] rnd31 10, 0 kIndx += 1 od endif
The usual way to create an array is with init:
kArr[] init 10 ;creates one-dimensional array with length 10 kArr[][] init 10, 10 ;creates two-dimensional array
A one-dimensional array can also be created and filled with distinct values by the opcode fillarray. This line creates a vector with length 4 and puts in the numbers [1, 2, 3, 4]:
kArr[] fillarray 1, 2, 3, 4
The function lenarray(kArr) reports the length of an array. See example for function lenarray.
copyf2array kArr, kfn
copies data from an ftable to a vector.
copya2ftab kArr, kfn
copies data from a vector to an function table.
See examples for opcodes copyf2array and copya2ftab.
If the four basic math operators are used between an array and a scalar (number), the operation is applied to each element. The safest way to do this is to store the result in a new array:
kArr1[] fillarray 1, 2, 3 kArr2[] = kArr1 + 10 ;(kArr2 is now [11, 12, 13])
Here is an example of array/scalar operations. It uses the file array_scalar_math.csd.
Example 3. Example of array operations
<CsoundSynthesizer> <CsOptions> -n -m128 </CsOptions> <CsInstruments> instr 1 ;create array and fill with numbers 1..10 kArr1[] fillarray 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ;print content printf "%s", 1, "\nInitial content:\n" kndx = 0 until kndx == lenarray(kArr1) do printf "kArr[%d] = %f\n", kndx+1, kndx, kArr1[kndx] kndx += 1 od ;add 10 kArr2[] = kArr1 + 10 ;print content printf "%s", 1, "\nAfter adding 10:\n" kndx = 0 until kndx == lenarray(kArr2) do printf "kArr[%d] = %f\n", kndx+1, kndx, kArr2[kndx] kndx += 1 od ;subtract 5 kArr3[] = kArr2 - 5 ;print content printf "%s", 1, "\nAfter subtracting 5:\n" kndx = 0 until kndx == lenarray(kArr3) do printf "kArr[%d] = %f\n", kndx+1, kndx, kArr3[kndx] kndx += 1 od ;multiply by -1.5 kArr4[] = kArr3 * -1.5 ;print content printf "%s", 1, "\nAfter multiplying by -1.5:\n" kndx = 0 until kndx == lenarray(kArr4) do printf "kArr[%d] = %f\n", kndx+1, kndx, kArr4[kndx] kndx += 1 od ;divide by -3/2 kArr5[] = kArr4 / -(3/2) ;print content printf "%s", 1, "\nAfter dividing by -3/2:\n" kndx = 0 until kndx == lenarray(kArr5) do printf "kArr[%d] = %f\n", kndx+1, kndx, kArr5[kndx] kndx += 1 od ;turnoff turnoff endin </CsInstruments> <CsScore> i 1 0 .1 </CsScore> </CsoundSynthesizer>
If the four basic math operators are used between two arrays, the operation is applied element by element. The result can be straightforward stored in a new array:
kArr1[] fillarray 1, 2, 3 kArr2[] fillarray 10, 20, 30 kArr3[] = kArr1 + kArr2 ;(kArr3 is now [11, 22, 33])
Here is an example of array operations. It uses the file array_array_math.csd.
Example 4. Example of array operations
<CsoundSynthesizer> <CsOptions> -n -m128 </CsOptions> <CsInstruments> instr 1 ;create array and fill with numbers 1..10 resp .1..1 kArr1[] fillarray 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 kArr2[] fillarray 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 ;print contents printf "%s", 1, "\nkArr1:\n" kndx = 0 until kndx == lenarray(kArr1) do printf "kArr1[%d] = %f\n", kndx+1, kndx, kArr1[kndx] kndx += 1 od printf "%s", 1, "\nkArr2:\n" kndx = 0 until kndx == lenarray(kArr2) do printf "kArr2[%d] = %f\n", kndx+1, kndx, kArr2[kndx] kndx += 1 od ;add arrays kArr3[] = kArr1 + kArr2 ;print content printf "%s", 1, "\nkArr1 + kArr2:\n" kndx = 0 until kndx == lenarray(kArr3) do printf "kArr3[%d] = %f\n", kndx+1, kndx, kArr3[kndx] kndx += 1 od ;subtract arrays kArr4[] = kArr1 - kArr2 ;print content printf "%s", 1, "\nkArr1 - kArr2:\n" kndx = 0 until kndx == lenarray(kArr4) do printf "kArr4[%d] = %f\n", kndx+1, kndx, kArr4[kndx] kndx += 1 od ;multiply arrays kArr5[] = kArr1 * kArr2 ;print content printf "%s", 1, "\nkArr1 * kArr2:\n" kndx = 0 until kndx == lenarray(kArr5) do printf "kArr5[%d] = %f\n", kndx+1, kndx, kArr5[kndx] kndx += 1 od ;divide arrays kArr6[] = kArr1 / kArr2 ;print content printf "%s", 1, "\nkArr1 / kArr2:\n" kndx = 0 until kndx == lenarray(kArr6) do printf "kArr5[%d] = %f\n", kndx+1, kndx, kArr6[kndx] kndx += 1 od ;turnoff turnoff endin </CsInstruments> <CsScore> i 1 0 .1 </CsScore> </CsoundSynthesizer>
kArrRes maparray kArrSrc, "fun"
maps the k-rate 1-arg function in the string to every element of the vector.
Possible functions are for instance abs, ceil, exp, floor, frac, int, log, log10, round, sqrt. This is a simple example:
kArrSrc[] fillarray 1, 2, 3, 4, 5 kArrRes[] init 5 kArrRes maparray kArrSrc, "sqrt"
See example for opcode maparray.
kMin [,kMinIndx] minarray kArr
returns the smallest value in an array, and optionally its index.
kMax [,kMaxIndx] maxarray kArr
returns the largest value in an array, and optionally its index. See examples for opcodes minarray and maxarray.
scalearray kArr, kMin, kMax
scales all values in kArr between kMin and kMax.
kArr[] fillarray 1, 3, 9, 5, 6 scalearray kArr, 1, 3
changes kArr to [1, 1.5, 3, 2, 2.25]. See example for opcode scalearray.
slicearray kArr, iStart, iEnd
returns a slice of kArr from index iStart to index iEnd (included).
The array for receiving the slice must have been created in advance:
kArr[] fillarray 1, 2, 3, 4, 5, 6, 7, 8, 9 kArr1[] init 5 kArr2[] init 4 kArr1 slicearray kArr, 0, 4 ;[1, 2, 3, 4, 5] kArr2 slicearray kArr, 5, 8 ;[6, 7, 8, 9]
See example for opcode slicearray.
The dimension of an input array must be declared in two places:
For instance :
opcode FirstEl, k, k[] ;returns the first element of vector kArr kArr[] xin xout kArr[0] endop
Here is an example of an array in an UDO. It uses the file array_udo.csd.
Example 5. Example of an array in an UDO
<CsoundSynthesizer> <CsOptions> -nm128 </CsOptions> <CsInstruments> opcode FirstEl, k, k[] ;returns the first element of vector kArr kArr[] xin xout kArr[0] endop instr 1 kArr[] fillarray 6, 3, 9, 5, 1 kFirst FirstEl kArr printf "kFirst = %d\n", 1, kFirst turnoff endin </CsInstruments> <CsScore> i 1 0 .1 </CsScore> </CsoundSynthesizer>