/* Fichier de musique - Aide pour ceux qui veulent faire jouer de la
musique a leur TamagoKit. Les routines sont tirées de fichiers propres au
RugWarrior (le petit robot montré au début du cours) et ne sont pas
nécessairement adaptées au TamagoKit. NOTEZ QU'AUCUNE DE CES FONCTIONS
N'ONT ÉTÉ TESTÉES AVEC LE TAMAGOKIT. Toutefois, elles peuvent vous aider
a composer une petite pièce */


/* MUSIQUE NIVEAU SIMPLE */
/* La fonction tone a comme prototype: void tone(float frequency, float
length)
Il suffit de remplacer cette fonction par buzzer et ça devrait
fonctionner */

void bicycle() /* Bicycle built for two */
{
tone(2093.0,0.769);
tone(1760.0,0.769);
tone(1396.9,0.769);
tone(1046.5,0.769);
tone(1174.7,0.192);
tone(1318.5,0.192);
tone(1396.9,0.192);
tone(1174.7,0.385);
tone(1396.9,0.192);
tone(1046.5,0.962);
sleep(0.385);
tone(1568.0,0.769);
tone(2093.0,0.769);
tone(1760.0,0.769);
tone(1396.9,0.769);
tone(1174.7,0.192);
tone(1318.5,0.192);
tone(1396.9,0.192);
tone(1568.0,0.385);
tone(1760.0,0.192);
tone(1568.0,0.962);
sleep(0.385);
tone(1760.0,0.192);
tone(1864.7,0.192);
tone(1760.0,0.192);
tone(1568.0,0.192);
tone(2093.0,0.385);
tone(1760.0,0.192);
tone(1568.0,0.192);
tone(1396.9,0.962);
tone(1568.0,0.192);
tone(1760.0,0.385);
tone(1396.9,0.192);
tone(1174.7,0.385);
tone(1396.9,0.192);
tone(1174.7,0.192);
tone(1046.5,0.962);
tone(1046.5,0.192);
tone(1396.9,0.385);
tone(1760.0,0.192);
tone(1568.0,0.385);
tone(1046.5,0.192);
tone(1396.9,0.385);
tone(1760.0,0.192);
tone(1568.0,0.192);
tone(1760.0,0.192);
tone(1864.7,0.192);
tone(2093.0,0.192);
tone(1760.0,0.192);
tone(1396.9,0.192);
tone(1568.0,0.385);
tone(1046.5,0.192);
tone(1396.9,0.962);
}

void alert_tune()
{
tone(1046.5,0.200);
tone(1396.9,0.200);
tone(1046.5,0.200);
tone(698.5,0.200);
}

/* MUSIQUE NIVEAU INTERMÉDIAIRE */

/* Well tempered scale:
a 1.000, a# 1.070, b 1.143, c 1.218, c# 1.295, d 1.375, d#
1.457,
e 1.542, f 1.628, f 1.718, g 1.810, g# 1.904, A 2.000
*/

/* Fundamental freq of this octave. Others: 220, 440, 880, 1760 */
float octave = 440.0;

float a0 = octave * 1.000;
float b0 = (octave * 1.143);
float c = (octave * 1.218);
float d = (octave * 1.375);
float e = (octave * 1.542);
float f = (octave * 1.628);
float g = (octave * 1.810);
float a = (octave * 2.000);
float b = (octave * 2.0 * 1.143);
float c2 = (octave * 2.0 * 1.218);

/* Note times: q - quarter, h - half, w - whole */

float tempo = 0.25; /* Duration of a quarter note */
float q = tempo; /* Quarter note */
float h = (2.0 * tempo); /* Half note */
float dh = (3.0 * tempo); /* Dotted half */

int note_display = 0; /* Global chooses whether to display note or not */

void note(float freq, float dur)
{ tone(freq,dur);
}

void cof()
{ note(c,q);
note(f,q); note(g,q); note(a,q);
note(g,dh);
note(e,5.0 * q);
note(c,q);
note(f,q); note(g,q); note(a,q);
note(g,8.0 * q);
note(c,q);
note(f,q); note(g,q); note(a,q);
note(g,dh);
note(e,5.0 * q);
note(g,q);
note(f,q); note(e,q); note(c,q);
note(c,5.0 * q);
note(c2,q);
note(b,q); note(a,q); note(g,q);
note(b,h); note(g,q);
note(a,h); note(f,q);
note(g,h); note(c2,q);
note(b,q); note(a,q); note(g,q);
note(b,8.0 * q);
note(c2,q);
note(b,q); note(a,q); note(g,q);
note(b,h); note(g,q);
note(a,h); note(f,q);
note(g,h); note(g,q);
note(f,q); note(e,q); note(c,q);
note(c,7.0 * q);
}


/* MUSIQUE NIVEAU EXPERT */

/* songs work like this: */
/* a note is <number><optional # or &><a-g> */
/* <number> how many "beats" the note gets. if you make 1 an eighth note,
then 2=quarter note, 4=half note, 8=whole note, 3=dotted quarter,
6=dotted half, etc. If you have a dotted eighth, you'd need to make
eighth
equal 2, etc. */
/* optional # or & means make the next note sharp or flat */
/* a-g means which note. the octave for the note is automatically chosen
to make the note as close as possible to the last note. you can
override
this with U or D in between notes to force a shift up or down. just
enter
all the notes without the U and D's, listen to the song, and it will
become
clear where the U's and D's need to go*/

/* note that you can add spaces anywhere you want, to make your song
(somewhat)
more legible. for debugging you might want to put spaces at each
measure, for example */

/* randy. "pink panther" */
char pp_song[]= "1#d 4e3r1#f4g3r1#d 3e1#f3g1c3bD1e3g1b 8&b2b2a2g2e2d10e
7r1#d 4e3r1#f4g3r1#d 3e1#f3g1c3b1g3b1e 28&e D3r1#d 4e3r1#f4g3r1#d
3e1#f3g1c3bD1e3g1b 8&b2b2a2g2e2d10e 12r U3e1d3b1a3g1#f
1&b3a1&b3a1&b3a1&b3a 2g2e2d20e";

char w_song[]="1c2f1f2f1g2a1a2a1f2g1g2g1e4f1r
1f2a1a2a1&b2c1c2c1c2d1c2&b1a4g1r 1gU2d1d2d1c2d1e2f1d2c1d2c1&b4a1r
D1c2f1f2f1g2a1a2a1f2g1g2f1e5f";

char classics_song[]="4g2c2d4c4g4a2g2f2e2c2d2e2f2g2a2b10c2r
4c4b4c2d2b2c2d2e2#f4g2#f2e4d2g2#f4g4d4e2d2c2b2g2a2b2c2b2c2d2e2d2e2#f12g";

char charge_song[]="1c1e1g2c1r1g4c";

char looney_tune_song[]= "U3e1d2c2d2e2d2e2c2d2d2d6d2r
3d1c2b2c2d2#c2d2b2c2c2c6c";


void pp() {
play(pp_song);
}

void wate() {
play(w_song);
}

void classics() {
play(classics_song);
}

void charge() {
play(charge_song);
}

void looney_tune() {
tempo=8;
play(looney_tune_song);
tempo=12;
}

/**********************************************************************/
/* music player Randy Sargent */

/* # of milliseconds per 16th note, divided by 8 */
int tempo= 12;
long time, newtime;

/* command letter to motor control */
int music_current_command= 'o';

/*
Example using play:

Songs should be GLOBALS so they can be longer - MD 7/93

char song[]= "1#d 4e3r1#f4g3r1#d 3e1#f3g1c3bD1e3g1b 8&b2b2a2g2e2d10e
7r1#d 4e3r1#f4g3r1#d 3e1#f3g1c3b1g3b1e 28&e D3r1#d 4e3r1#f4g3r1#d
3e1#f3g1c3bD1e3g1b 8&b2b2a2g2e2d10e 12r U3e1d3b1a3g1#f
1&b3a1&b3a1&b3a1&b3a 2g2e2d2e18e 8r 2g2e2d2e18e 8r 2g2e2d2e18e";

void pp() {
play(song);
}

Also see tequila.c for an example of music interspersed with commands
Also see tunes.c for other fun tunes.

*/

int music_next_command= 0;

void play(char song[])
{
int i, duration, accidental, delta, note, rest;
int notes[]= {0,2,3,5,7,8,10};
int old_note= 30;
play_reset();

i= 0;
while (song[i]) {

while (1) {
while (song[i] == ' ') ++i;
if (song[i] == 'X') {++i; music_next_command= song[i]; ++i;}
else break;
}

if (!song[i]) break;

while (song[i] == 'D') {
old_note -= 12;
++i;
}
while (song[i] == 'U') {
old_note += 12;
++i;
}
if ('0' <= song[i] && song[i] <= '9') {
duration= 0;
while ('0' <= song[i] && song[i] <= '9') {
duration = duration * 10 + song[i]-'0';
++i;
}
}
if (song[i] == '#') {
accidental= 1;
++i;
} else if (song[i] == '&') {
accidental= -1;
++i;
} else {
accidental= 0;
}
if (song[i] == 'r') rest= 1;
else {
if (song[i] < 'a' || song[i] > 'g') {
printf("\nBad note:%c\n", song[i]);
beep();
beep();
beep();
sleep(5.0);
return;
}
note= notes[song[i]-'a'] + accidental;
rest= 0;
}
i++;

if (rest) {
play_note(0, duration);
} else {
delta= note - (old_note % 12);
old_note += delta;
if (delta > 5) old_note -= 12;
if (delta < -5) old_note += 12;

play_note(old_note, duration);
}
}
play_note(0, 1);
music_command('o');
}

void music_command(int c)
{
music_current_command= c;
}

void play_reset()
{
time= mseconds();
newtime= time+100L;
}

void play_note(int note, int duration)
{
play_note_2(note, duration*7);
play_note_2(0, duration);
}


/* Ici, je crois qu'il faut adapter la fonction pour utiliser plutot
buzzer() sur le TamagoKit */

void play_note_2(int note, int duration)
{
float freq;
int period;

if (note) {
freq= 55.0 * (2. ^ (((float) note) / 12.));
}

while (mseconds() < newtime);
if (note) {
set_beeper_pitch(freq);
beeper_on();
}
else {
beeper_off();
}
if (music_next_command &&
music_current_command != music_next_command){
music_command(music_next_command);
music_next_command= 0;
}

newtime += (long)(duration * tempo);
}