Playing “Mission Impossible” Tune on a Arduino with 2 Voices

Dear Arduinoists,

Inspired by Dipto’s version of the Super Mario tune with two voice, I wanted to make my own tune. I had the notations of the MI-Theme for the easy piano lessons laying around, and I thought to myself, lets convert it. It was needed for a little game I was developing on Arduino.

Dipto’s approach was good, but it lacked the function to do other stuff while the melody was playing. It took me some time to figure it out, how to handle that. Maybe my approach is hacky, but it did the job.

I didn’t try to  copy and paste the notations into the other code, but it should work. Here I´ll provide  the whole code needed. I took out the functions needed, added a blinking LED for audio/visual experience, and compiled it on my Arduino mini.  Please make sure you use the piezo/buzzer/speaker on the PINS 7+8, and make sure you downloaded the right tone library (google: “rogue tone library”).  In order to make it compile, please change the #includes in the tone.cpp like stated in the code below and have the frequenzen.h // notes.h or whereever the frequencies are defined included in the project directory. The “frequenzen.h” is the very common file provided with the tone library demos.

If you´d like to download the code: http://www.xlr8.at/downloads/Mission_Impossible.zip

Inspired by these articles here:
https://www.linuxcircle.com/2013/03/31/playing-mario-bros-tune-with-arduino-and-piezo-buzzer/

and

https://www.linuxcircle.com/2013/04/03/play-mario-bros-harmonies-on-arduino-and-2-speakers/

Have fun, and happy compiling !

Cheers André

And here goes the code:

 

/*MISSION IMPOSSIBLE
 
Done by: André Thomas
24.01.2014
 
Taken out from a poker program I have written last year.
Idea for the 2-Tone same Speaker didn´t came from me.
 
"Mission Impossible" theme made for Arduino by me, note by note.
------------------------------------------------------------------
For compiling you need Tone() from here
http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation
 
Go into the Tone Directory and change tone.cpp header (includes) to this:
 
#include <avr/interrupt.h>
//#include <avr/pgmspace.h>
//#include <wiring.h>
#include <Arduino.h>
 
so it will compile.
------------------------------------------------------------------
 
*/
 
#include <Tone.h>
#include "frequenzen.h"
#include <avr/pgmspace.h>
 
#define OUT1 7
#define OUT2 8
 
//Sound Vars
Tone notePlayer[2];
unsigned int Counts[] = { 0, 0};
unsigned long stopTimeNote1 = 0;
unsigned long stopTimeNote2 = 0;
int value;
int value2;
int dur;
int dur2;
 
//Mission Impossible // Game Finale Melodie
int mimp[]  PROGMEM = {
NOTE_DS5,
NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,
NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,
NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,
NOTE_D5,NOTE_DS5,NOTE_D5,NOTE_DS5,
NOTE_D5,NOTE_DS5,NOTE_F5,NOTE_FS5,NOTE_G5, // Upswing 5
 
NOTE_G2,0,NOTE_G2,0,NOTE_AS2,0,NOTE_C3,0,
NOTE_G2,0,NOTE_G2,0,NOTE_F2,0,NOTE_FS2,0,
 
NOTE_G2,0,NOTE_G2,0,NOTE_AS2,0,NOTE_C3,0,
NOTE_G2,0,NOTE_G2,0,NOTE_F2,0,NOTE_FS2,0,
 
NOTE_G2,0,NOTE_G2,0,NOTE_AS2,0,NOTE_C3,0,
NOTE_G2,0,NOTE_G2,0,NOTE_F2,0,NOTE_FS2,0,
 
NOTE_G2,0,NOTE_G2,0,NOTE_AS2,0,NOTE_C3,0,
NOTE_G2,0,NOTE_G2,0,NOTE_F2,0,NOTE_FS2,0,
 
NOTE_G2,0,NOTE_G2,0,NOTE_AS2,0,NOTE_C3,0,
NOTE_G2,0,NOTE_G2,0,NOTE_F2,0,NOTE_FS2,0,
 
NOTE_G2,0,NOTE_G2,0,NOTE_AS2,0,NOTE_C3,0,
NOTE_G2,0,NOTE_G2,0,NOTE_F2,0,NOTE_FS2,0,
 
NOTE_G2,0,NOTE_G2,0,NOTE_AS2,0,NOTE_C3,0,
NOTE_G2,0,NOTE_G2,0,NOTE_F2,0,NOTE_FS2,0,
 
NOTE_G2,0,NOTE_G2,0,NOTE_AS2,0,NOTE_C3,0,
NOTE_G2,0,NOTE_G2,0,NOTE_F2,0,NOTE_FS2,0,
 
NOTE_G2,0,NOTE_G2,0,NOTE_AS2,0,NOTE_C3,0,
NOTE_G2,0,NOTE_G2,0,NOTE_F2,0,NOTE_FS2,0,
 
NOTE_G2,0,NOTE_G2,0,NOTE_AS2,0,NOTE_C3,0,
NOTE_G2,0,NOTE_G2,0,NOTE_F2,0,NOTE_FS2,0,
 
NOTE_G2,0
 
,-1
};
 
int mimpDur [] PROGMEM = {
 
50,50,50,50,50,50,50,50,50,50,
50,50,50,50,50,50,50,50,50,50,
50,50,50,50,50,50,50,50,50,50,
50,50,50,50,
50,50,50,50,50,50,
 
200,400,200,400,200,200,200,200,              //2000
200,400,200,400,200,200,200,200,
 
200,400,200,400,200,200,200,200,              //2000
200,400,200,400,200,200,200,200,
 
200,400,200,400,200,200,200,200,
200,400,200,400,200,200,200,200,
 
200,400,200,400,200,200,200,200,
200,400,200,400,200,200,200,200,
 
200,400,200,400,200,200,200,200,
200,400,200,400,200,200,200,200,
 
200,400,200,400,200,200,200,200,
200,400,200,400,200,200,200,200,
 
200,400,200,400,200,200,200,200,
200,400,200,400,200,200,200,200,
 
200,400,200,400,200,200,200,200,
200,400,200,400,200,200,200,200,
 
400,-1
};
 
int mimp2 [] PROGMEM  = {
NOTE_G3,
 
NOTE_G3,0,NOTE_G3,0,NOTE_AS3,0,NOTE_C4,0,
NOTE_G3,0,NOTE_G3,0,NOTE_F3,0,NOTE_FS3,0,
 
NOTE_G3,0,NOTE_G3,0,NOTE_AS3,0,NOTE_C4,0,
NOTE_G3,0,NOTE_G3,0,NOTE_F3,0,NOTE_FS3,0,
 
NOTE_AS5,0,NOTE_G5,0,NOTE_D5,0,
NOTE_AS5,0,NOTE_G5,0,NOTE_CS5,0,
NOTE_AS5,0,NOTE_G5,0,NOTE_C5,0,
NOTE_AS4,0,NOTE_C5,0,
 
NOTE_AS4,NOTE_G4,NOTE_FS5,0,
NOTE_AS4,NOTE_G4,NOTE_F5,0,
NOTE_AS4,NOTE_G4,NOTE_E5,0,
NOTE_DS5,NOTE_D5,0,
 
NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,0,
NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,0    ,
NOTE_CS5,NOTE_F5,NOTE_AS5,NOTE_CS5,NOTE_F5,NOTE_AS5,NOTE_CS5,NOTE_F5,0    ,
NOTE_DS5,NOTE_G5,NOTE_C6,NOTE_DS5,NOTE_G5,NOTE_C6,NOTE_DS5,NOTE_G5,0,
NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,0    ,
NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,0    ,
NOTE_GS4,NOTE_C5,NOTE_F5,NOTE_GS4,NOTE_C5,NOTE_F5,NOTE_GS4,NOTE_C5,0     ,
NOTE_A4,NOTE_CS5,NOTE_FS5,NOTE_A4,NOTE_CS5,NOTE_FS5,NOTE_A4,NOTE_CS5,0,
 
NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,0    ,
NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,0    ,
NOTE_CS5,NOTE_F5,NOTE_AS5,NOTE_CS5,NOTE_F5,NOTE_AS5,NOTE_CS5,NOTE_F5,0    ,
NOTE_DS5,NOTE_G5,NOTE_C6,NOTE_DS5,NOTE_G5,NOTE_C6,NOTE_DS5,NOTE_G5,0,
NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,0    ,
NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,0    ,
NOTE_GS4,NOTE_C5,NOTE_F5,NOTE_GS4,NOTE_C5,NOTE_F5,NOTE_GS4,NOTE_C5,0     ,
NOTE_A4,NOTE_CS5,NOTE_FS5,NOTE_A4,NOTE_CS5,NOTE_FS5,NOTE_A4,NOTE_CS5,0,
 
NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,NOTE_G5,NOTE_AS4,NOTE_D5,0,-1
 
};
 
int mimp2Dur [] PROGMEM  = {
 
2025,    //+25 for the delayed melody
 
200,400,200,400,200,200,200,200,
200,400,200,400,200,200,200,200,
 
200,400,200,400,200,200,200,200,
200,400,200,400,200,200,200,200,
 
150,50,150,50,800,800,
150,50,150,50,800,800,
150,50,150,50,800,800,
150,50,400,1400,
 
200,200,600,1000,
200,200,600,1000,
200,200,600,1000,
200,400,1400,
 
25,25,25,25,25,25,25,25,391,
25,25,25,25,25,25,25,25,391,
25,25,25,25,25,25,25,25,191,
25,25,25,25,25,25,25,25,191,
25,25,25,25,25,25,25,25,391,
25,25,25,25,25,25,25,25,391,
25,25,25,25,25,25,25,25,191,
25,25,25,25,25,25,25,25,191,
 
25,25,25,25,25,25,25,25,391,
25,25,25,25,25,25,25,25,391,
25,25,25,25,25,25,25,25,191,
25,25,25,25,25,25,25,25,191,
25,25,25,25,25,25,25,25,391,
25,25,25,25,25,25,25,25,391,
25,25,25,25,25,25,25,25,191,
25,25,25,25,25,25,25,25,191,
 
25,25,25,25,25,25,25,25,300, 0
};
 
int led = 13;   //Just a LED
 
void setup()
{
pinMode(led, OUTPUT);                         // Set pinmode
notePlayer[0].begin(OUT1);                    // Voice 1
notePlayer[1].begin(OUT2);                    // Voice 2
digitalWrite(led, LOW);                       // Turn off LED
}
 
void loop() {
 
playTune(mimp, mimpDur, mimp2 , mimp2Dur ,0);  //Play the tune
 
}
 
void playTune(int melody[],  int melDurations[], int harmony[],  int harmDurations[], boolean repeat )
{
value    = pgm_read_word(&melody[Counts[0]]);
value2   = pgm_read_word(&harmony[Counts[1]]);
dur      = pgm_read_word(&melDurations[Counts[0]]);
dur2     = pgm_read_word(&harmDurations[Counts[1]]);
 
if(value == -1 || value2 == -1) {
notePlayer[0].stop();
notePlayer[1].stop();
digitalWrite(led, LOW); // Just a visual check if it´s doin something
if(repeat == 1) {
value=0;value2=0;dur=0;dur2=0;Counts[0]=0;Counts[1]=0;
}
return;
}
 
if ( millis()>stopTimeNote1 ) {
if(value==0) {
if(notePlayer[0].isPlaying()) notePlayer[0].stop();
digitalWrite(led, LOW); // Just a visual check if it´s doin something
}
else{
notePlayer[0].play(value);
digitalWrite(led, HIGH); // Just a visual check if it´s doin something
}
stopTimeNote1 = millis() + dur;
if(value != -1 ) {Counts[0]++;}
 
}
 
if ( millis()>stopTimeNote2 ) {
if(value2==0) { if(notePlayer[1].isPlaying()) notePlayer[1].stop();    }
else{
notePlayer[1].play(value2);
}
stopTimeNote2 = millis() + dur2;
if(value2 != -1 ) {Counts[1]++;}
 
}
return;
}
 
void resetTone() {
Counts[0] = 0;
Counts[1] = 0;
stopTimeNote1 = 0;
stopTimeNote2 = 0;
notePlayer[0].stop();
notePlayer[1].stop();
value=0;
value2=0;
dur=0;
dur2=0;
}

 

 

 

(Visited 6,807 times, 1 visits today)