pink.live-code

Functions for live coding music using pink.simple engine.

bars

(bars b)(bars b beats-per-bar)
Returns time in seconds for num bars given. Useful for converting times
appropriate for audio functions.

beat-advance

(beat-advance subdiv)(beat-advance subdiv units)
Calculates start time for x number of beats ahead in time.  Uses next-beat
with subdiv time to get the adjusted time for one subdivision, then adds
remaining number of units to subdiv. Units should be a whole number.

For example, to calculate 7 16th notes ahead in time, use (beat-advance 1/4
7).

beat-mod

(beat-mod mod-val)(beat-mod beat-time mod-val)
Returns modulus division of given beat-time and mod-val. Rounds to whole
number beats. Defaults to using (now) if only mod-val is given. 2-arity
version useful with multiplied versions of (now) to get sub-divisions of
beat.

beat-phase

(beat-phase sub-div total)
Returns current phase (0.0,1.0] of *beat* within total number of sub-beats. For example,
using a sub-beat of 4 (i.e., 16th notes), 16 total would equal one measure at 
4/4 time signature. Useful when paired with cosr.

beat-printer

(beat-printer & args)
Temporally recursive function to print out beat-mod
times.  Useful for seeing where one is within the current
beat/bar structure.

beats

(beats b)
Returns time in seconds for num beats given. Useful for converting times
appropriate for audio functions.

cause

(cause func start & args)
Implementation of Canon-style cause function. Will create and schedule an
event that calls the given function at given start time (in beats) and with
given arguments.

cosr

(cosr phs low high)
Cosine that scales/shifts value into range given by low/high.
Useful when generating events. Phase can be calculated using beat-phase.
(Based on cosr by Andrew Sorensen).

end-recur!

macro

(end-recur! a)
Macro to redefine given function name to a var-arg function that
short-circuits current operation.  Useful to end temporal recursion of an
event function that may be already queued up in the event list. 

end-recur! operates by swapping out the function value held in 'a' with one
that will restore the value of 'a' to its previous value. This ends the
temporal recursion of the function as well as allows the user start a new
temporal recursion without first re-evaluating the 'a' function from the
editor. This is in contrast to kill-recur! which will leave the function
value as a no-op function. 

end-recur! is best used when a single instance of a function is used in
temporal recursion. If multiple recursions are in operation, end-recur! may
not end all instances. 

User may schedule a call to end-recur! by using wrapper function, such as:

(cause #(end-recur! my-perf-func) (next-beat 4)) 

Note: Implemented as macro to work with var special-form.

kill-recur!

macro

(kill-recur! a)
Macro to redefine given function name to a var-arg, no-op function. Useful
to end temporal recursion of an event function that may be already queued up
in the event list. 

When using kill-recur!, be aware that the function def in memory no longer
represents what is on screen. User will need to re-evaluate the function
definition before using again in temporal recursion.

When multiple instances of a function are in temporal recursion, kill-recur!
may be used to stop all instances.

User may schedule a call to kill-recur! by using wrapper function, such as:

(cause #(kill-recur! my-perf-func) (next-beat 4)) 

Note: Implemented as macro to work with var special-form.

next-beat

(next-beat)(next-beat b)(next-beat cur-beat-time b)
Calculates forward time for the next beat boundary.  Useful for scheduling
of temporally recursive event function so that it will fire in sync with
other beat-oriented functions.Adjusts for fractional part of current beat
time that arises due to block-based processing. 

For example, if an engine has a current beat time of 81.2, if (next-beat 4)
is used, it will provide a value of 3.8, so that the event function will fire
at beat 84.

next-in-atom

(next-in-atom atm)
Retrieves head of sequence held in atom and resets atom to rest of sequence.
Not thread safe in that outside mutator may write a value that gets
overwritten by the reset! call, but largely okay for the kinds of operations
done in live-coding.

redef!

macro

(redef! a new-func)
Macro to redefine given function 'a' to function value held in new-func.
Useful in conjunction with cause to schedule when a function will be
redefined. For example, when modifying a temporally recursive function, one
can use (cause #(redef! a b) (next-beat 16)) to schedule that the function 'a'
be redefined with value of 'b' at the next 4-bar boundary. Users may then
edit body of function separately from its use in performance.

reset!!

(reset!! a b)
Same as reset! but returns nil. Useful for live coding so that value from
reset! does not try to get printed by editor's clojure plugin. For example,
when using an atom to store an infinite sequence used by a recursive process,
reset!! might cause an OutOfMemoryException as the editor would try to print
the results of the reset!.

sample-duration

(sample-duration wave)
Return duration of audio sample

sample-one-shot

(sample-one-shot sample)
Returns audio function that plays a stereo sample without looping until
completion.

sub-beat

(sub-beat n)
Returns current sub-beat time.