User:Fabien Labeyrie/Clapping Arduino Modulo
Clapping Arduino
The following exercise puts Steve Reich into an italian chip, using its tone functionality. As a result, it should be able to play the clapping music by itself.
Version I : two speakers and two loops
How does it work ?
The Clapping music consists in one pattern being played and shifted by two people. We will use two speakers to differentiate the two musical lines and to produce a stereo effect. The Arduino board will dispatch the tone information to the speakers thanks to two nested for loops and two if conditions. [1]
Technologies involved
The Arduino program is very close to C.
Steps
- We are defining the pattern
- Each speaker will act as a different channel
- The pattern is being repeated and shifted
- Because the tone function in Arduino cannot play several notes simultaneously, we are tricking human sound perception : two sounds played one after the other very quickly (10 milliseconds in this example) will be interpreted by our brain as simultaneous.
Source code
// This is telling the board which pin to use as an output
int speakerHigh = 8;
int speakerLow = 7;
// This will be the frequency of the notes
int noteValue = 3000;
// This will be the duration of the notes and the pause between them
int theDelay = 10;
// This is the pattern
char pat[] = "xxx xx x xx ";
// This is the pattern lenght
int patlen = strlen(pat);
void setup(){}
void loop (){
// This tells the program to begin a new measure after twelve notes have been played
for (int iLine=0; iLine<patlen; iLine++){
// The following loop will be completed first, then launched again by the previous one.
for (int iNote1=0; iNote1<patlen; iNote1++){
// iNote2, which represents the notes of the second channel, will be assigned a number value resulting from the addition of the two nested loops
int iNote2 = iNote1+iLine;
// When the number value of iNote2 is bigger than 11, it's been resetted to 0, so that all the number values will correspond to a position in the pattern
if (iNote2 > (patlen-1)){
iNote2 = iNote1-patlen+iLine;
}
// Channel one
// The if condition will match each note number value with a position in the pattern, checking if it refers to an "x" or a blank space
if (pat[iNote1] == 'x') {
// We have to shut the other speaker in order to make this one play
noTone(speakerHigh);
// The note is finally played
tone(speakerLow, noteValue, theDelay);
delay(theDelay);
}
// Channel two
// The second channel is played 10 milliseconds after the first, simulating a simultaneous playing.
if (pat[iNote2] == 'x') {
noTone(speakerLow);
tone(speakerHigh, noteValue, theDelay);
}
delay(theDelay*theDelay);
}
}
}
Version II : C code and the modulo
How does it work ?
Because the previous code is not as efficient as it can get, we will see how it can be optimised in C. Instead of sending it to the Arduino board, we will create a visual output in the linux shell. The result will show a list of X and blank spaces.
Technologies involved
C.
Steps
Source code
#include "stdio.h"
#include "string.h"
char pat[] = "xxx xx x xx ";
int patlen;
int i = 0;
int shift = 0;
int i2 = 0;
int main(){
patlen = strlen(pat);
while (shift < patlen) {
while (i < patlen) {
// The modulo won't change anything about values under 12, but after that, it gives the remainder, meaning it will go through 1 to 12 once again.
printf("%c%c\n", pat[i], pat[(i+shift)%12]);
i++;
}
shift++;
i = 0;
}
}