[Csnd] question concerning array shuffle

Dear community,
I tried to figure out the ArrShuffle-Udo, that I’ve found at https://flossmanual.csound.com/csound-language/arrays.
Unfortunately, this opcode does not behave as I’ve expected.
In the below quoted example I’ve expected sequences of four different pitches, but I can clearly hear repetitions of the same pitch.
I can’t find out the reason.
It would be great, if someone could give me a hint!

Here’s my code:

-odac -m0d ; ==============================================

sr = 44100
;ksmps = 100
nchnls = 2
0dbfs = 1
seed 0
giPchNumsA[] fillarray 60,64,67,72
gidurs[ ] fillarray 1,1,1,3

;;; JOACHIMS CODE
opcode RndInt, i, ii
iStart, iEnd xin
iRnd random iStart, iEnd+.999
iRndInt = int(iRnd)
xout iRndInt
endop

opcode gArrShuffle, i[], i[]
iInArr[] xin
iLen = lenarray(iInArr)
iOutArr[] init iLen
iIndx = 0
iEnd = iLen-1
while iIndx < iLen do
;get one random element and put it in iOutArr
iRndIndx RndInt 0, iEnd
iOutArr[iIndx] = iInArr[iRndIndx]
;shift the elements after this one to the left
while iRndIndx < iEnd do
iInArr[iRndIndx] = iInArr[iRndIndx+1]
iRndIndx += 1
od
;reset end and increase counter
iIndx += 1
iEnd -= 1
od
xout iOutArr
endop
;;;;;;;;;;;;;;;;;; END JOACHIMS CODE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

instr SwitchOnSine
iwhen = 0
iEnd = p3
idur = 1
iamp = -24
iArrIndx = 0
icounter = 0
loop:
iPchNumsShuffled[] gArrShuffle giPchNumsA
iPchNum = iPchNumsShuffled[iArrIndx]
idur = gidurs[iArrIndx]
schedule “playSine”, iwhen, idur,iPchNum,iamp
iArrIndx = iArrIndx+1
if iArrIndx =lenarray(iPchNumsShuffled) then
iArrIndx = 0
endif
;loop_le iArrIndx,1,lenarray(iPchNumsShuffled)-1,loop
loop_le iwhen,idur,iEnd,loop
endin
instr playSine
idur = p3
iPchNum = p4
icps mtof iPchNum
iamp = ampdb(p5)
iein = 0.03
iaus = idur-iein
aenv expsegr 0.00001,iein,1,iaus,0.000001
asine poscil aenv*iamp,icps
outs asine,asine
endin

; ==============================================

i"SwitchOnSine" 0 26

Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here

hi stefan -

if you put the udo inside the loop, it will create a new shuffle all the time, and this will most probably lead to repetitions. but the shuffle must be done only once. this works:

instr SwitchOnSine
iwhen = 0
iEnd = p3
idur = 1
iamp = -24
iArrIndx = 0
icounter = 0
iPchNumsShuffled[] gArrShuffle giPchNumsA
loop:
iPchNum = iPchNumsShuffled[iArrIndx]
idur = gidurs[iArrIndx]
schedule "playSine", iwhen, idur,iPchNum,iamp
   iArrIndx = iArrIndx+1
if iArrIndx =lenarray(iPchNumsShuffled) then
iArrIndx = 0
endif
;loop_le iArrIndx,1,lenarray(iPchNumsShuffled)-1,loop
loop_le iwhen,idur,iEnd,loop
endin

best -
  joachim

Dear Joachim,
thanks for Your reply!
Now I don’t hear repetitions, but I would like to hear always a new version of the four pitches!
What do You mean by

if you put the udo inside the loop, it will create a new shuffle all the time

?

Is it possible that all the time is at k-rate?
All the best,
Stefan

hi stefan -

if you want to hear always a new version of the four pitches, you must create a new "shuffle" version exactly after four pitches. using your code i think this does what you want to achieve:

instr SwitchOnSine
iwhen = 0
iEnd = p3
idur = 1
iamp = -24
iArrIndx = 0
loop:
if iArrIndx == 0 then
  iPchNumsShuffled[] gArrShuffle giPchNumsA
endif
iPchNum = iPchNumsShuffled[iArrIndx]
idur = gidurs[iArrIndx]
schedule "playSine", iwhen, idur,iPchNum,iamp
   iArrIndx = iArrIndx+1
if iArrIndx =lenarray(iPchNumsShuffled) then
iArrIndx = 0
endif
loop_le iwhen,idur,iEnd,loop
endin

i personally would prefer this:

instr SwitchOnSine
  iStart = 0
  iEnd = p3
  iAmp = -24
  iArrIndx = 0
  while iStart < iEnd do
   if iArrIndx == 0 then
    iPchNumsShuffled[] gArrShuffle giPchNumsA
   endif
   iPchNum = iPchNumsShuffled[iArrIndx]
   iDur = gidurs[iArrIndx]
   schedule "playSine", iStart, iDur, iPchNum, iAmp
   iArrIndx = (iArrIndx+1) % lenarray(giPchNumsA)
   iStart += iDur
  od
endin

best -
  joachim

Dear Joachim,
thanks very much for Your help! Both versions work fine for me.

The solution with the modulo operator is very clever!
All the best,
Stefan