making my code more concise

I have this code but I'm trying to learn how to make it more concise. Each function does the same thing only with a different array of notes (numbers) Does anyone see a good way to go about making it more concise, while being easy to follow? It's one function that calls 1 of 4 others, but the 4 others are almost identical.
thanks.
ps.
SeventhMode() & MinorMode() simple return true or false...

void autoArpeggio(int i) {  //play arpeggio for the note (i) automatically
  if (SeventhMode())  { //play 7th mode
    if (MinorMode())  playMinorSeventh(i); //play the minor seventh scale
    else playSeventh(i);  //play the seventh scale
  }
  else if (MinorMode()) playMinor(i);  //play the minor scale
  else playNormal(i);  //play the normal scale
}

void playNormal(int theNote){
  byte autoScale[] = {
    0,4,7,12,16,19,24,28,31,36                                                                              };
  int s = sizeof(autoScale);
  for (int i = 0; i < s; i++) {
    int j = theNote + autoScale[i];
    midiOut(j);
    delay(autoDelay);
  }
}

void playMinor(int theNote){
  byte autoScale[] = {
    0,3,7,12,15,19,24,27,31,36                                                                              };
  int s = sizeof(autoScale);
  for (int i = 0; i < s; i++) {
    int j = theNote + autoScale[i];
    midiOut(j);
    delay(autoDelay);
  }
}

void playSeventh(int theNote){
  byte autoScale[] = {
    0,4,7,10,12,16,19,22,24,28,31,34,36                                                                              };
  int s = sizeof(autoScale);
  for (int i = 0; i < s; i++) {
    int j = theNote + autoScale[i];
    midiOut(j);
    delay(autoDelay);
  }
}

void playMinorSeventh(int theNote){
  byte autoScale[] = {
    0,3,7,10,12,15,19,22,24,27,31,34,36                                                                              };
  int s = sizeof(autoScale);
  for (int i = 0; i < s; i++) {
    int j = theNote + autoScale[i];
    midiOut(j);
    delay(autoDelay);
  }
}

You could have several global arrays containing the note values. Then, call one function, and pass it the name of the array containing the notes. No need to replicate the code to play the notes.

Agreed. You might have to pass it the size of the array too as that seems to change.

Something along the line of -

#define ARRAY_LENGTH(ARRAY)         (sizeof(ARRAY) / sizeof(ARRAY[0]))


void autoArpeggio(int i)            // play arpeggio for the note (i) automatically
{
    if ( SeventhMode() )            // play 7th mode
    {
        if ( MinorMode() )
            playMinorSeventh(i);    // play the minor seventh scale
        else
            playSeventh(i);         // play the seventh scale
    }
    else if ( MinorMode() )
        playMinor(i);               // play the minor scale
    else
        playNormal(i);              // play the normal scale
}

void processMidiEvents(const byte autoScale[], int const s, int const theNote)
{
    for ( int i = s; i--; )
    {
        midiOut(theNote + *autoScale++);
        delay(autoDelay);
    }
}

call examples -

{
    // playNormal
   const  byte autoScale[] = { 0, 4, 7, 12, 16, 19, 24, 28, 31, 36 };
    processMidiEvents(autoScale, ARRAY_LENGTH(autoScale), theNote);
}

{
    // playMinor
    const byte autoScale[] = { 0, 3, 7, 12, 15, 19, 24, 27, 31, 36 };
    processMidiEvents(autoScale, ARRAY_LENGTH(autoScale), theNote);
}

{
    // playSeventh
    const byte autoScale[] = { 0, 4, 7, 10, 12, 16, 19, 22, 24, 28, 31, 34, 36 };
    processMidiEvents(autoScale, ARRAY_LENGTH(autoScale), theNote);
}

{
    // playMinorSeventh
    const byte autoScale[] = { 0, 3, 7, 10, 12, 15, 19, 22, 24, 27, 31, 34, 36 };
    processMidiEvents(autoScale, ARRAY_LENGTH(autoScale), theNote);
}
0,4,7,12,16,19,24,28,31,36                                                                              };

??

I couldn't figure out how it would even compile with no closing brace, then I spotted it gone walkabout at the right of the page.


Rob