/* music.c */

/* hacked up by randy sargent 1/91 */
/* randy apologizes for the annoying syntax of the music as he tries to
   re-read the earlier songs 6/94 */
  
/* 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 */

/* use start_process to play your favorite song while your robot robots :) */






    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";

/* randy.  "pink panther" */

void pp() {
    play(pp_song);
}

/* added to by karsten ulland 10/92 */

void wate() {
  play(w_song);
}

void classics() {
  play(classics_song);
}


/* more from karsten 1/93 */

void charge() {
  play(charge_song);
}

/* randy 4/94 */

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;
	}
/*	printf("dur %d a %d i %d\n", duration, accidental, i);*/
/*	wait();*/
	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);
}

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);
}

