//*!!Sensor,    S1,               button, sensorTouch,      ,                    !!*//
//*!!                                                                            !!*//
//*!!Start automatically generated configuration code.                           !!*//
const tSensors button               = (tSensors) S1;   //sensorTouch        //*!!!!*//
//*!!CLICK to edit 'wizard' created sensor & motor configuration.                !!*//

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//                                    Somg Playback Demonstration
//
// This program demonstrates the sound playback routines of RobotC.
//
// It contains three songs that are played sequentially.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

//
// An optional touch sensor can be used to start/stop the program. Following flag indicates whether
// it should be used. The touch sensor should be given the name "button" in the config wizard.
//
const bool bTouchSensorForStartStop = false;

void BeethovenFifth()
{
	//  Piano Player II
	//    rest);
	wait10Msec(75);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(622,38);	wait10Msec(38);
	//    rest);
	wait10Msec(38);
	PlayTone(698,15);	wait10Msec(19);
	PlayTone(698,15);	wait10Msec(19);
	PlayTone(698,15);	wait10Msec(19);
	PlayTone(587,38);	wait10Msec(38);
	//    rest);
	wait10Msec(75);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(622,15);	wait10Msec(19);
	PlayTone(831,15);	wait10Msec(19);
	PlayTone(831,15);	wait10Msec(19);
	PlayTone(831,15);	wait10Msec(19);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(1244,15);	wait10Msec(19);
	PlayTone(1244,15);	wait10Msec(19);
	PlayTone(1244,15);	wait10Msec(19);
	PlayTone(1047,38);	wait10Msec(38);
	//    rest);
	wait10Msec(19);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(587,15);	wait10Msec(19);
	PlayTone(831,15);	wait10Msec(19);
	PlayTone(831,15);	wait10Msec(19);
	PlayTone(831,15);	wait10Msec(19);
	PlayTone(784,15);	wait10Msec(19);
	PlayTone(1397,15);	wait10Msec(19);
	PlayTone(1397,15);	wait10Msec(19);
	PlayTone(1397,15);	wait10Msec(19);
	PlayTone(1175,38);	wait10Msec(38);
	//    rest);
	wait10Msec(19);
	PlayTone(1568,15);	wait10Msec(19);
	PlayTone(1568,15);	wait10Msec(19);
	PlayTone(1397,15);	wait10Msec(19);
	PlayTone(1244,19);	wait10Msec(19);
	//    rest);
	wait10Msec(19);
	PlayTone(1175,15);	wait10Msec(19);
	PlayTone(1568,15);	wait10Msec(19);
	PlayTone(1568,15);	wait10Msec(19);
	PlayTone(1397,15);	wait10Msec(19);
	PlayTone(1244,19);	wait10Msec(19);
	//    rest);
	wait10Msec(19);
	PlayTone(1175,15);	wait10Msec(19);
	PlayTone(1568,15);	wait10Msec(19);
	PlayTone(1568,15);	wait10Msec(19);
	PlayTone(1397,15);	wait10Msec(19);
	PlayTone(1244,19);	wait10Msec(19);
	//    rest);
	wait10Msec(38);
	PlayTone(1047,19);	wait10Msec(19);
	//    rest);
	wait10Msec(38);
	PlayTone(784,38);	wait10Msec(38);
	return;
}


void HallOfMountainKing()
{
	wait10Msec(8);  // Rest
	PlayTone(220,12);  wait10Msec(15);
	PlayTone(247,12);  wait10Msec(15);
	PlayTone(262,12);  wait10Msec(15);
	PlayTone(294,12);  wait10Msec(15);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(262,12);  wait10Msec(15);
	PlayTone(330,24);  wait10Msec(30);
	PlayTone(311,12);  wait10Msec(15);
	PlayTone(247,12);  wait10Msec(15);
	PlayTone(311,24);  wait10Msec(30);
	PlayTone(294,12);  wait10Msec(15);
	PlayTone(233,12);  wait10Msec(15);
	PlayTone(294,24);  wait10Msec(30);
	PlayTone(220,12);  wait10Msec(15);
	PlayTone(247,12);  wait10Msec(15);
	PlayTone(262,12);  wait10Msec(15);
	PlayTone(294,12);  wait10Msec(15);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(262,12);  wait10Msec(15);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(440,12);  wait10Msec(15);
	PlayTone(392,12);  wait10Msec(15);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(262,12);  wait10Msec(15);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(392,48);  wait10Msec(60);
	wait10Msec(8);  // Rest
	PlayTone(220,12);  wait10Msec(15);
	PlayTone(247,12);  wait10Msec(15);
	PlayTone(262,12);  wait10Msec(15);
	PlayTone(294,12);  wait10Msec(15);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(262,12);  wait10Msec(15);
	PlayTone(330,24);  wait10Msec(30);
	PlayTone(311,12);  wait10Msec(15);
	PlayTone(247,12);  wait10Msec(15);
	PlayTone(311,24);  wait10Msec(30);
	PlayTone(294,12);  wait10Msec(15);
	PlayTone(233,12);  wait10Msec(15);
	PlayTone(294,24);  wait10Msec(30);
	PlayTone(220,12);  wait10Msec(15);
	PlayTone(247,12);  wait10Msec(15);
	PlayTone(262,12);  wait10Msec(15);
	PlayTone(294,12);  wait10Msec(15);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(262,12);  wait10Msec(15);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(440,12);  wait10Msec(15);
	PlayTone(392,12);  wait10Msec(15);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(262,12);  wait10Msec(15);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(392,48);  wait10Msec(60);
	wait10Msec(8);  // Rest
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(370,12);  wait10Msec(15);
	PlayTone(415,12);  wait10Msec(15);
	PlayTone(440,12);  wait10Msec(15);
	PlayTone(494,12);  wait10Msec(15);
	PlayTone(415,12);  wait10Msec(15);
	PlayTone(494,24);  wait10Msec(30);
	PlayTone(523,12);  wait10Msec(15);
	PlayTone(440,12);  wait10Msec(15);
	PlayTone(523,24);  wait10Msec(30);
	PlayTone(494,12);  wait10Msec(15);
	PlayTone(415,12);  wait10Msec(15);
	PlayTone(494,24);  wait10Msec(30);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(370,12);  wait10Msec(15);
	PlayTone(415,12);  wait10Msec(15);
	PlayTone(440,12);  wait10Msec(15);
	PlayTone(494,12);  wait10Msec(15);
	PlayTone(415,12);  wait10Msec(15);
	PlayTone(494,24);  wait10Msec(30);
	PlayTone(523,12);  wait10Msec(15);
	PlayTone(440,12);  wait10Msec(15);
	PlayTone(523,24);  wait10Msec(30);
	PlayTone(494,48);  wait10Msec(60);
	wait10Msec(8);  // Rest
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(370,12);  wait10Msec(15);
	PlayTone(415,12);  wait10Msec(15);
	PlayTone(440,12);  wait10Msec(15);
	PlayTone(494,12);  wait10Msec(15);
	PlayTone(415,12);  wait10Msec(15);
	PlayTone(494,24);  wait10Msec(30);
	PlayTone(523,12);  wait10Msec(15);
	PlayTone(440,12);  wait10Msec(15);
	PlayTone(523,24);  wait10Msec(30);
	PlayTone(494,12);  wait10Msec(15);
	PlayTone(415,12);  wait10Msec(15);
	PlayTone(494,24);  wait10Msec(30);
	PlayTone(330,12);  wait10Msec(15);
	PlayTone(370,12);  wait10Msec(15);
	PlayTone(415,12);  wait10Msec(15);
	PlayTone(440,12);  wait10Msec(15);
	PlayTone(494,12);  wait10Msec(15);
	PlayTone(415,12);  wait10Msec(15);
	PlayTone(494,24);  wait10Msec(30);
	PlayTone(523,12);  wait10Msec(15);
	PlayTone(440,12);  wait10Msec(15);
	PlayTone(523,24);  wait10Msec(30);
	PlayTone(494,48);  wait10Msec(60);
	wait10Msec(8);  // Rest
	wait10Msec(8);  // Rest
	PlayTone(440,8);  wait10Msec(15);
	PlayTone(494,8);  wait10Msec(15);
	PlayTone(523,8);  wait10Msec(15);
	PlayTone(587,8);  wait10Msec(15);
	PlayTone(659,8);  wait10Msec(15);
	PlayTone(523,8);  wait10Msec(15);
	PlayTone(659,24);  wait10Msec(30);
	PlayTone(622,8);  wait10Msec(15);
	PlayTone(494,8);  wait10Msec(15);
	PlayTone(622,24);  wait10Msec(30);
	PlayTone(587,8);  wait10Msec(15);
	PlayTone(466,8);  wait10Msec(15);
	PlayTone(587,24);  wait10Msec(30);
	PlayTone(440,8);  wait10Msec(15);
	PlayTone(494,8);  wait10Msec(15);
	PlayTone(523,8);  wait10Msec(15);
	PlayTone(587,8);  wait10Msec(15);
	PlayTone(659,8);  wait10Msec(15);
	PlayTone(523,8);  wait10Msec(15);
	PlayTone(659,8);  wait10Msec(15);
	PlayTone(880,8);  wait10Msec(15);
	PlayTone(784,8);  wait10Msec(15);
	PlayTone(659,8);  wait10Msec(15);
	PlayTone(523,8);  wait10Msec(15);
	PlayTone(659,8);  wait10Msec(15);
	PlayTone(784,48);  wait10Msec(60);
	wait10Msec(8);  // Rest
	PlayTone(440,8);  wait10Msec(15);
	PlayTone(494,8);  wait10Msec(15);
	PlayTone(523,8);  wait10Msec(15);
	PlayTone(587,8);  wait10Msec(15);
	PlayTone(659,8);  wait10Msec(15);
	PlayTone(523,8);  wait10Msec(15);
	PlayTone(659,24);  wait10Msec(30);
	PlayTone(622,8);  wait10Msec(15);
	PlayTone(494,8);  wait10Msec(15);
	PlayTone(622,24);  wait10Msec(30);
	PlayTone(587,8);  wait10Msec(15);
	PlayTone(466,8);  wait10Msec(15);
	PlayTone(587,24);  wait10Msec(30);
	PlayTone(440,8);  wait10Msec(15);
	PlayTone(494,8);  wait10Msec(15);
	PlayTone(523,8);  wait10Msec(15);
	PlayTone(587,8);  wait10Msec(15);
	PlayTone(659,8);  wait10Msec(15);
	PlayTone(523,8);  wait10Msec(15);
	PlayTone(659,8);  wait10Msec(15);
	PlayTone(880,8);  wait10Msec(15);
	PlayTone(831,8);  wait10Msec(15);
	PlayTone(659,8);  wait10Msec(15);
	PlayTone(831,8);  wait10Msec(15);
	PlayTone(988,8);  wait10Msec(15);
	PlayTone(880,48); wait10Msec(60);
	return;
}

void FrereJacque()
{
	PlayTone(523,40);	wait10Msec(50);
	PlayTone(587,40);	wait10Msec(50);
	PlayTone(659,40);	wait10Msec(50);
	PlayTone(523,40);	wait10Msec(50);
	PlayTone(523,40);	wait10Msec(50);
	PlayTone(587,40);	wait10Msec(50);
	PlayTone(659,40);	wait10Msec(50);
	PlayTone(523,40);	wait10Msec(50);
	PlayTone(659,40);	wait10Msec(50);
	PlayTone(698,40);	wait10Msec(50);
	PlayTone(784,80);	wait10Msec(90);
	PlayTone(659,40);	wait10Msec(50);
	PlayTone(698,40);	wait10Msec(50);
	PlayTone(784,80);	wait10Msec(90);
	PlayTone(784,20);	wait10Msec(30);
	PlayTone(880,20);	wait10Msec(30);
	PlayTone(784,20);	wait10Msec(30);
	PlayTone(698,20);	wait10Msec(30);
	PlayTone(659,40);	wait10Msec(50);
	PlayTone(523,40);	wait10Msec(50);
	PlayTone(784,20);	wait10Msec(30);
	PlayTone(880,20);	wait10Msec(30);
	PlayTone(784,20);	wait10Msec(30);
	PlayTone(698,20);	wait10Msec(30);
	PlayTone(659,40);	wait10Msec(50);
	PlayTone(523,40);	wait10Msec(50);
	PlayTone(523,40);	wait10Msec(50);
	PlayTone(392,40);	wait10Msec(50);
	PlayTone(523,80);	wait10Msec(90);
	PlayTone(523,40);	wait10Msec(50);
	PlayTone(392,40);	wait10Msec(50);
	PlayTone(523,80);	wait10Msec(90);
	return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Separate task to actually play the three songs
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

task playSongs()
{
	//
	// Set the task to high priority so that there is no jitter in the playback of sounds
	//
	nSchedulePriority = kHighPriority;

	//
	// Play the three songs in sequential order
	//
	HallOfMountainKing();
	wait10Msec(50);

	BeethovenFifth();
	wait10Msec(50);

	FrereJacque();
	wait10Msec(50);

	StopAllTasks(); // we're finished.
	return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//                                        The main Task
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

task main()
{
	int nLastButton;

	//
	// If we're using a touch sensor to start/stop the playback, then wait for button pressed, with debounce
	//
	if (bTouchSensorForStartStop)
	{
		//
		// Wait for button to be pressed. Debounce the button to avoid glitches.
		//
		while (bTouchSensorForStartStop)
		{
			//
			// debounce is find button in same state with 5-msec wait in-between.
			//
			// NOTE: don't need to debounce on the NXT. I think this is done either in the hardware or low-level s/w
			//
			nLastButton = SensorBoolean[button];
			wait10Msec(5);
			if (nLastButton != SensorBoolean[button])
				continue;
			if (SensorBoolean[button])
				break;
		}
		//
		// Wait for button release, with debounce
		//
		while (bTouchSensorForStartStop)
		{
			nLastButton = SensorBoolean[button];
			wait10Msec(5);
			if (nLastButton != SensorBoolean[button])
				continue;
			if (!SensorBoolean[button])
				break;
		}
	}

	//
	// Play the songs in a separate task. We don't need to do this, but it's a useful way
	// to demonstrate the multi-tasking capabilities of RobotC.
	//
	start(playSongs);

	//
	// Look for button to be pressed to stop program
	//
	while (true)
	{
		//
		//
		//
		if (!bTouchSensorForStartStop)
		{
			//
			// We're not using a touch sensor for start/stop. So simply repeat the loop
			//
			continue;
		}
		if (SensorBoolean[button])
		{
			// Touch Sensor is pushed. Time to finish up

			StopTask(playSongs);
			break;
		}
	}
	return;
}