2D array, read row in reverse without using a nested for loop?

Hi,

Still learning, but sometimes I come across a simple problem that becomes intractable, leading me to doubt my sanity.

I have the following arrays:

//Track Note data
boolean trackArray[4][16] = { 

  {
    1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0    }
  ,
  {
    0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0    }
  ,
  {
    0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0    }
  ,
  {
    0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0    }

};


//Track Assignment data

byte trackLength[] = { // Current Length of all tracks 
  16,16,16,16,16,16,16,16}; 
byte trackPosition[] = { // Current index of all tracks
  1,1,1,1,6,4,1,3}; 
byte trackNote[] = { // Current MIDI Note for all tracks
  36,38,40,58,60,42,44,46};
byte trackChan[] = { // Current MIDI Channel for all tracks
  10,10,10,10,10,10,10,10};
byte trackVelMax[] = { // Current maximum velocity for all tracks
  127,100,100,100,100,100,100,100};

What I do is iterate though the 4 tracks of the 2D array and select the current note on/off status per step.

I can do this no problem using a for loop to cycle through the tracks, something like…

for (int i = 0; i < 8; i++ ) { //Loop through the 8 Tracks 
    
      int notetoplay = trackArray[i][trackPosition[i]]; 	//Selects the note to play based on position in the track

      if (notetoplay == 1) {   					//indicates Note-on
        
        MIDI.sendNoteOn(trackNote[i],trackVelocity[i],trackChan[i]);
        MIDI.sendNoteOff(trackNote[i],0,trackChan[i]);

	trackPosition[i]++;					//Update Track Position
        if (trackPosition[i] >15) {trackPosition[i] = 0;} //Rotate the array


	 }
      }
   }

Which works fine.

However, what if I want to read the notes in reverse based on the trackPosition. For example, instead of reading the first row in this order…

1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0

I instead read it in reverse…

0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,1

I don’t want to alter the array - just read it. I’ve looked for an elegant way to do this but I’m stumped.

An ideas?

Many kind thanks in advance.
:slight_smile:

I'm not qoute sure about the structure but you could either count the index backwards

for(int i = 7; i >= 0; i--){}

or calculate the index when it is used

int notetoplay = trackArray[i][trackPosition[7-i]]

I'm also not sure, but I think you have create a new variable for going up or down.

Old code

  trackPosition[i]++;          //Update Track Position
  if (trackPosition[i] >15) {
    trackPosition[i] = 0;             //Rotate the array
  }

New code. This code can change the direction, so when the position is 3, you can go to 4 or 2. That is what the boolean variable is used for. If you want to start always at 15 and go downwards, the code needs to be different.

boolean trackForward = true;
...
  if (trackForward) {                  // test if forward
    if (trackPosition[i] >= 15)     
      trackPosition[i] = 0;           //Rotate the array
    else
      trackPosition[i]++;
    }
  }
  else {                                            // reverse
    if (trackPosition[i] == 0) 
      trackPosition[i] = 15;             //Rotate the array
    else
      trackPosition[i]--;            //Update Track Position
    }
  }

nilton61:

int notetoplay = trackArray[i][trackPosition[7-i]]

D’oh! So simple. Thanks.
:slight_smile: