Leipzig still sees occasional breaking changes, though every effort will be made to document them here.
- Addition -
phrase
marks rests with:rest?
andplay
ignores them. - Addition -
cut
truncates or pads melodies to fit. - Bug fix -
with
is properly variadic, including one or zero arguments. - Bug fix -
just
has a properly consonant major sixth.
- Addition - Clojurescript is supported on all namespaces other than
live
. - Addition -
augment
adds to an element of a chord. - Bug fix - The example works again.
- Addition -
phrase
accepts vector durations, representing repeated notes. - Addition -
phrase
accepts an optional third argument for velocities. - Addition -
but
replaces part of a melody. - Addition -
tempo
applies a transformation to both time and duration. - Addition - Experimental
accelerando
linearly interpolates between two relatively different rates. - Addition -
play
allows for lead-in notes with negative times. - Breaking change -
where
ignores missing keys. - Bug fix -
play
no longer throws aNullPointerException
for finite sequences of notes.
- Breaking change - In
phrase
, rests are reified as notes of nil pitch. - Breaking change -
then
andtimes
do not allow padding. - Breaking change -
bpm
returns a fn that converts beats to seconds, to match Supercollider. - Addition -
mapthen
provides a temporal equivalent to mapcat.
- Breaking change - The
help
macro has been removed because it wasn't helpful. - Addition -
stop
kills all running melodies. - Addition -
with
is variadic.
- Addition -
nil
s represent rests inphrase
. Note, ensure you userhythm
instead of(phrase ... (repeat nil))
orphrase
will never return. - Addition -
Sequential
s (lists, vectors and lazy-seqs) represent clusters inphrase
. - Addition - Maps represent chords in
phrase
. - Addition -
then
andtimes
accept an optional parameter controlling when the subsequent melody starts.
- Breaking change -
jam
is not a macro, so it expects a ref as an argument. - Breaking change -
crab
translates the result to avoid playing it before the original. - Bug fix -
crab
reflects melodies according to the end of each note (see issue #2) and sorts the resulting notes by time to ensure order is preserved. - Addition -
having
zips arbitrary atributes onto melodies. - Addition -
just
translates from midi to frequency using just intonation. - Addition -
rhythm
builds sequences of notes without pitch. - Addition - Codox documentation.
- Breaking change -
play
andplay-note
are in the newleipzig.live
namespace. - Breaking change -
high
andlow
operate on midi, not degrees. - Bug fix - Fractional degrees are linearly interpolated by
scale
. - Addition -
inversion
transforms chords. - Addition -
raise
andlower
are like high and low, but for degrees. - Addition -
from
is public inleipzig.scale
. - Addition -
wherever
is likewhere
, but selectively transforms notes. - Experimental - Alternatives to equal temperament are provided in
leipzig.temperament
. - Experimental - The
jam
macro inleipzig.live
affords redef-aware looping.
- Breaking change -
play
returns a future instead of blocking. - Bug fix -
then
useswith
instead ofconcat
to ensure order is preserved.
- Bug fix -
phrase
is lazy both on its inputs and output. - Addition - Leipzig is available under the MIT license.
- Addition - Melodies are modelled as sequences of maps, ordered by :time.
- Addition -
play
lazily sends notes to SuperCollider as they are required. - Addition - The
play-note
multimethod arranges notes to instrument on the :part key. - Addition - Scales are modelled as functions that translate degrees to midi.
- Addition - Canons are modelled as functions that transform one melody into another.
- Addition - Chords are modelled as maps.