// 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", 300], ["/s_new", "variablesine", 1002, 1, 0, "freq", 400]); 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;