Programming Challenges part VI

Part I : A computer-generated composition which respects the rules of Western music.


int duration = 700; //feel free to experiment with different values! notre duration
int pause = 500; //feel free to experiment with different values! time between notes
int speakerPin = 8; //piezo is connected between GND and pin 8 

                     // 36 notes; A3 220 - Gsharp6 1661 in semitones
int notes [] =      {220, 233, 247, 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988, 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661}; 

                     //The seven modes starting from I Ionian going to  VII Locrian
int scales [][15] = { 
                    {0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 17, 19, 21, 23, 24 },
                    {0, 2, 3, 5, 7, 9, 10, 12, 14, 15, 17, 19, 21, 22, 24 },
                    {0, 1, 3, 5, 7, 8, 10, 12, 13, 15, 17, 19, 20, 22, 24 },
                    {0, 2, 4, 6, 7, 9, 11, 12, 14, 16, 18, 19, 21, 23, 24 },
                    {0, 2, 4, 5, 7, 9, 10, 12, 14, 16, 17, 19, 21, 22, 24 },
                    {0, 2, 3, 5, 7, 8, 10, 12, 14, 15, 17, 19, 20, 22, 24 },
                    {0, 1, 3, 5, 6, 8, 10, 12, 13, 15, 17, 18, 20, 22, 24 },
};

                     // some standard chord progressions
int chordProgressions [][4] = { 

                    {0, 3, 4, 4 },
                    {0, 0, 3, 4 },
                    {0, 3, 4, 3 },                  
                    {0, 3, 1, 4 },
                    {0, 3, 4, 0 },
                    {0, 1, 4, 0 },                  
                    {0, 5, 3, 4 },
                    {0, 3, 5, 4 },
                    {0, 4, 5, 3 },                     

};

void setup() {

  Serial.begin(9600); 
  pinMode(speakerPin, OUTPUT);
  randomSeed(analogRead(0));
}

void loop() {

  int randomRootNote = random(11); // pick a random root note. Only chosing from the first 12 notes so that we don't go out of bounds if we take this note + 5 in the future for example...
  int randomScale [15];  // create array to take the random scale
  int randomChordProgression [4];   // create array to take the random chord progression

  int myNotes[15]; // create array to take the notes in our random scale with the random root note

  Serial.println("Random root frequency is: ");
  Serial.println(notes[randomRootNote]);



  Serial.println("All available notes: ");  


         for (int  i = 0; i < 36; i++) // There is no way in arduino to copy an entire array; doing it element by element here
   {     
     Serial.println(notes [i]); 
   }

   Serial.println("Random scale is: "); 
     int randomNumber = random(7); // random number for randomScale loop below
     for (int  i = 0; i < 15; i++) // There is no way in arduino to copy an entire array; doing it element by element here
   {     
     randomScale[i] = scales[randomNumber][i];
     Serial.println(randomScale[i]);
   }

/*
 *
 *
 * Step 1
 * Fill randomChordProgression with a random Chord Progression and print the results to the serial monitor
 *
 *
 *
 *
 */
    Serial.println("Random Chord Progression is: "); 
    int randomChordLine = random(9);
    for (int i = 0; i < 4; i++)
    {
      randomChordProgression[i] = chordProgressions[randomChordLine][i];
      Serial.println(randomChordProgression[i]);
    }


/*
 *
 *
 * Step 2
 * Fill myNotes with the notes in the randomly chosen scale starting at the randomly chosen root note and print the results to the serial monitor.
 *
 *
 *
 *
 */
  Serial.println("My notes are: "); 
  for (int i = 0; i < 15; i++)
  {
    myNotes[i] = notes[(randomRootNote + randomScale[i])%15];
    Serial.println(myNotes[i]);
  }
/*
 *
 *
 * Step 3
 * Create a loop which plays notes in the triad (root note, root note + 3 semitones, root notes + 5 semitones) randomly of each chord moving through in the randomly selected chord progression. (Reminder: all your triads will be notes from myNotes)
 * The duration of each note and the duration of each pause between notes should also be random within a range you select. It should also be possible to control how many times this entire process is repeated.
 * 
 * Hint: You could create an array called Triad to hold the notes from triads built from myNotes defined by the randomChordProgression.
 *
 */
  int Triad [3]; 

    for (int i = 0; i < 4; i++) 
    {
      tone(8, myNotes[randomChordProgression[i]], duration);
      delay(pause);
      tone(8, myNotes[randomChordProgression[(i+3)]], duration);
      delay(pause);
      tone(8, myNotes[randomChordProgression[(i+5)]], duration);
      delay(pause);
    }

  delay(10000000);

}

Issues I met during this Challenges

  Serial.println("My notes are: "); 
  for (int i = 0; i < 15; i++)
  {
    myNotes[i] = notes[i] + randomScale[i])%15];
    Serial.println(myNotes[i]);
  }

The error in Step 2 was to add the randomScale out of the notes array, without calling randomRootNote.

  Serial.println("My notes are: "); 
  for (int i = 0; i < 15; i++)
  {
    myNotes[i] = notes[(randomRootNote + randomScale[i])%15];
    Serial.println(myNotes[i]);
  }

Step 3 remain unsolved until now :

int Triad [3]; 

    for (int i = 0; i < 15; i++) 
    {
      tone(8, myNotes[i], duration);
      delay(pause);
      tone(8, myNotes[(i+3)%15], duration);
      delay(pause);
      tone(8, myNotes[(i+5)%15], duration);
      delay(pause);
    }

The randomChordProgression[] was not used in my step 3 whereas it should have. I tried this way, but the result does not seem accurate.

int Triad [3]; 

    for (int i = 0; i < 4; i++) 
    {
      tone(8, myNotes[randomChordProgression[i]], duration);
      delay(pause);
      tone(8, myNotes[randomChordProgression[(i+3)]], duration);
      delay(pause);
      tone(8, myNotes[randomChordProgression[(i+5)]], duration);
      delay(pause);
    }

Correction of this part by Jonah : During the use of myNotes[randomChordProgression[(i+3)]], the (i-3) part is adding 3 to the randomly choosen note, and therefore it is modifying the notes. "+3" should be added after the indice brackets to increment the choosen notes by 3, or 5 right after in the code.

int Triad [3]; 

    for (int i = 0; i < 4; i++) 
    {
      tone(8, myNotes[randomChordProgression[i]], duration);
      delay(pause);
      tone(8, myNotes[randomChordProgression[i]+2], duration);
      delay(pause);
      tone(8, myNotes[randomChordProgression[i]+4], duration);
      delay(pause);
    }

Random duration and random pause

I first tried to modify the duration and pause values at the beginning of the sketch by "randomising" them at their initialization. The result is not satisfying, the value is random, but the value remain the same while the sketch is running :

What it sounds like :

So i initialized three randomDuration(700) and randomPause(500) to get different values at each occurences duration and pause are used in the loop.

What the serial monitor prints :

The part of code achieving this :

  Serial.println("My notes are (in order of use): ");
  int randomDuration1 = random(700);
  int randomDuration2 = random(700);
  int randomDuration3 = random(700);
  int randomPause1 = random(500);
  int randomPause2 = random(500);
  int randomPause3 = random(500);
  int Triad [3]; 

    for (int i = 0; i < 4; i++) 
    {
      tone(8, myNotes[randomChordProgression[i]], randomDuration1);
      delay(randomPause1);
      tone(8, myNotes[randomChordProgression[i]+2], randomDuration2);
      delay(randomPause2);
      tone(8, myNotes[randomChordProgression[i]+4], randomDuration3);
      delay(randomPause3);
      Serial.println(myNotes[randomChordProgression[i]]);
      Serial.println(myNotes[randomChordProgression[i]+2]);
      Serial.println(myNotes[randomChordProgression[i]+4]);
      Serial.println("duration is :");
      Serial.println(randomDuration1);
      Serial.println(randomDuration2);
      Serial.println(randomDuration3);
      Serial.println("pause is :");
      Serial.println(randomPause1);
      Serial.println(randomPause2);
      Serial.println(randomPause3);
    }

What it sounds like :

results matching ""

    No results matching ""