// Sending messages with timing info attached
//
// To do this, we use the sendBundle command
// It is different to sendMsg in that you send a BUNDLE of messages at one time.
// You also specify a time for the bundle to occur.
// It looks like s.sendBundle(time, [message1], [message2], [message3]....);

// Create and start a server
s = Server.local;
s.boot;

// Use our variable sine synthdef from before - it should still be in the synthdefs folder
s.sendSynthDef("variablesine");

// Now use the sendBundle command
(
s.sendBundle(0.2,		// our time value is set to 0.2 seconds after the message arrives
	["/s_new", "variablesine", 1000, 1, 0, "freq", 200],
	["/s_new", "variablesine", 1001, 1, 0, "freq", 600],
	["/s_new", "variablesine", 1002, 1, 0, "freq", 900]);
s.sendBundle(1.2,		// this second bundle will get executed 1 second later
	["/n_free", 1000],
	["/n_free", 1001],
	["/n_free", 1002]);	
)

// Question - how do we create an ascending scale of C Major, starting at middle C and going up one // octave?
//
//
//
//
//
// Start by working out the frequencies involved (assuming equal temperament):
// The frequency of a note = 440 * 2^(m/12) where m=the number of semitones above or below Concert A
// So middle C = 9 semitones below concert A = 440 * 2^(-9/12) = 440 * 0.595 = 261.63
// D = 7 semitones below = 440 * 2^(-7/12) = 293.66
// E = 329.63
// F = 349.23
// G = 392.00
// A = 440.00
// B = 493.88
// C = 523.25
// Lets have each note play for 1 second, and have a gap of 1/2 second between each note
(
s.sendBundle(0.0, ["/s_new", "variablesine", 1000, 1, 0, "freq", 261.63]);
s.sendBundle(1.0, ["/n_free", 1000]);
s.sendBundle(1.5, ["/s_new", "variablesine", 1000, 1, 0, "freq", 293.66]);
s.sendBundle(2.5, ["/n_free", 1000]);
s.sendBundle(3.0, ["/s_new", "variablesine", 1000, 1, 0, "freq", 329.63]);
s.sendBundle(4.0, ["/n_free", 1000]);
s.sendBundle(4.5, ["/s_new", "variablesine", 1000, 1, 0, "freq", 349.23]);
s.sendBundle(5.5, ["/n_free", 1000]);
s.sendBundle(6.0, ["/s_new", "variablesine", 1000, 1, 0, "freq", 392.00]);
s.sendBundle(7.0, ["/n_free", 1000]);
s.sendBundle(7.5, ["/s_new", "variablesine", 1000, 1, 0, "freq", 440.00]);
s.sendBundle(8.5, ["/n_free", 1000]);
s.sendBundle(9.0, ["/s_new", "variablesine", 1000, 1, 0, "freq", 493.88]);
s.sendBundle(10.0, ["/n_free", 1000]);
s.sendBundle(10.5, ["/s_new", "variablesine", 1000, 1, 0, "freq", 523.25]);
s.sendBundle(11.5, ["/n_free", 1000]);
)
// Exciting or what!?!
// There is an easier way of working out the frequencies of the notes. Have a look at the octcps 
// operator - it converts from decimal octave to cycles per second (i.e. frequency)
// Decimal octave is a way of notating pitch - eg. 4.0 = C below A440, 5.0 = C above A440.
// Each semitone in between = 1/12. A440 is 9 semitones higher, = 4 + 9/12 = 4.75
// If we wanted to use decimal octave format to control the frequency of SinOsc, the amended code
// would look like this:
(
SynthDef("octcpssine", { arg freq;
	var osc;
	osc = SinOsc.ar(freq.octcps);
	Out.ar(0, osc);
}).writeDefFile;
s.sendSynthDef("octcpssine");
)

// and to play our scale we would send
(
s.sendBundle(0.0, ["/s_new", "octcpssine", 1000, 1, 0, "freq", 4.0]);
s.sendBundle(1.0, ["/n_free", 1000]);
s.sendBundle(1.5, ["/s_new", "octcpssine", 1000, 1, 0, "freq", 4.1667]);
s.sendBundle(2.5, ["/n_free", 1000]);
s.sendBundle(3.0, ["/s_new", "octcpssine", 1000, 1, 0, "freq", 4.3333]);
s.sendBundle(4.0, ["/n_free", 1000]);
s.sendBundle(4.5, ["/s_new", "octcpssine", 1000, 1, 0, "freq", 4.4167]);
s.sendBundle(5.5, ["/n_free", 1000]);
s.sendBundle(6.0, ["/s_new", "octcpssine", 1000, 1, 0, "freq", 4.5833]);
s.sendBundle(7.0, ["/n_free", 1000]);
s.sendBundle(7.5, ["/s_new", "octcpssine", 1000, 1, 0, "freq", 4.75]);
s.sendBundle(8.5, ["/n_free", 1000]);
s.sendBundle(9.0, ["/s_new", "octcpssine", 1000, 1, 0, "freq", 4.9167]);
s.sendBundle(10.0, ["/n_free", 1000]);
s.sendBundle(10.5, ["/s_new", "octcpssine", 1000, 1, 0, "freq", 5.0]);
s.sendBundle(11.5, ["/n_free", 1000]);
)

// When you're done, quit the server
s.quit;