// externalMethodFiles/


// float.sc

// string.sc

// array.sc


[["1", "2"], ["3"]].cat_entries([["3"], ["4", "5"]])



// tools/



/* Parser

 *

 * Parses command strings of the format

 *

 *  time [frequency] [switch] [public message] [private message]

 *

 * All arguments are optional except for `time', which indicates

 * when to trigger the following values, and should be between the clock's

 * current time and the end of the piece.  E.g. if the current time is

 * 04:15 and the piece lasts until 15:00, the `time' argument can be 8:13.015,

 * but not 2:01 or 20:50.  The format of each argument is as follows:

 *

 *   time       a time string with at least one minute value and two second values,

 *              and an optional fraction of a second, e.g.

 *

 *                0:00.0001

 *                01:23.3521

 *

 *   frequency  a floating-point number to set the synth frequency: e.g.

 *

 *                4410

 *                4454.1

 *

 *   switch     either the plus sign, +, to switch the synth on, or the minus sign, -,

 *              to switch it off

 *

 *   public     a capital M followed by space and then a string in double quotes, like

 *   message    

 *                M "This is a PLOrk message the audience will see."

 *                M   "Who knew rhythmic typing would be so exhilarating?"

 *

 *   private    same as for public message, but with a lower-case M:

 *   message

 *                m "This is a message only the players will see." 

 *

 * More examples: 

 * 

 * A command that turns the synth on a minute into the piece, sets it to 4411.1 Hz, and

 * lets the audience know what to expect after that:

 *

 */

 

p = Parser("1:00 4411.1 + M \"In another minute, I'm going to tune the synth up 0.1 Hz.\"");


// The parser stores whatever information it can find in a dictionary.

p.dict;




/*  Timing

 *  Facilitates event timing by storing a start time and duration.

 *

 */


t = Timing.new(duration: 900);


t.start;             // start timing

t.stop;

t.start(15);         // start timing at 15 seconds

t.now;               // current time

t.remaining;         // seconds until t.duration

t.valid_time(20);    // true if the argument is between t.now and t.duration

t.stop;


/*  FreqTables

 *  Creates tables of frequencies, corresponding amplitudes, and glitches.

 *  The frequency and glitch tables shows the difference between each pair of frequencies;

 *  The amplitude table shows the product of each pair of amplitudes.

 */

 

f = FreqTables.new([4410, 4411, 4412], [1, 0, 1])


f.freqs;

f.glitches;

f.amps;

f.freqTable;

f.glitchTable;

f.ampTable;

f.set_freq(0, 4409);

f.freqTable;

f.glitchTable;

f.set_amp(1, 1);

f.ampTable;


/*

 *  Key, KeyboardView

 *  A Key is a visual representation of a key on the (typing) keyboard.

 *  A KeyboardView use Keys to create a visual representation of most of the keyboard.

 *  A KeyboardView can be added to a Window as follows:

 */ 


w = Window.new("KeyboardView Test", Rect(0, 0, 400, 300)).front;


// Note that the keyboard scale is 14.5 units x 5 units, so scale the KeyboardView appropriately

k = KeyboardView(parent: w, bounds: Rect(0, 0, w.bounds.width, w.bounds.width / 14.5 * 5));


k.key_down($q);

k.key_up($q);



/*

 *  SynthDisplay

 *

 *  A SynthDisplay is a visualization of an impulse frequency synth.

 *

 */

 


w = Window.new("SynthView Test", Rect(0, 0, 400, 300)).front;

v = SynthDisplay(parent: w, bounds: w.view.bounds.insetBy(10));

v.set_amp(1);

v.set_freq(4411);