-
Notifications
You must be signed in to change notification settings - Fork 35
v3 announce
A massive update of quality & quantity! Version 3 brings a great deal of new functionality, while solving some bugs & making the ecosystem more robust.
Updating your firmware is now easier than ever, but first you need to update druid (hint: pip3 install --upgrade monome-druid
).
Once druid is updated, with your crow connected simply type druid firmware
and you'll witness your crow's evolution.
/// VIDEO
"a slope language" now runs at audio rate, allowing for sample-accurate timings and oscillation up to 24k.
A new asllib action oscillate
is available: output[n].action = oscillate(freq)
Note: n2v
, negate
and clamp
are removed (as they can be replaced with native math operations, or asl constructs. This may break some rare scripts (notably n2v
was used frequently in non-asl code. It can be replaced with a divide-by-12).
dyn
, short for Dynamic, is useful for naming ASL arguments so that they can be updated by a script, without restarting the ASL.
-- create an lfo with a dynamic height, starting at 3V
output[1]( loop{ to( dyn{height=3}, 1)
, to( 0, 1)
}
)
output[1].dyn.height = 1 -- update height of LFO to 1V
-- note: this will take effect at the next repetition
Dynamic vars can be used anywhere in the ASL, either in a to()
call, or as a predicate value (eg. asl._if
). Furthermore, asllib functions may take dyn
values as variables. For example:
-- an lfo whose speed can be changed at runtime
output[2]( lfo( dyn{speed=0.1} ) )
Mutations can be attached to any dyn
which are executed each time the asl accesses the value, for example:
-- ramp lfo, decelerating from 0.1 seconds to infinity
output[1].action =
loop{ to(5, dyn{time=0.1}:step(0.1)) -- step performs addition / subtraction
, to(0, 0)
}
-- the lfo will slow down by 0.1 seconds each time it repeats
output[1].dyn.time = 0.1 -- reset the variable like a normal dyn
Available mutations are step
, mul
, and wrap
. wrap
is additionally useful for being able to keep a dyn
within bounds when it is modified from other functions or the REPL. See the reference
//// VIDEO
This new class connects data with "behaviors" which facilitate rapid building of sequencers and arpeggiators.
notes = sequins{0,2,4,6,7,9,11}
print( notes() ) -- each time notes() is called it returns the next value
-- 0 then 2 then 4 etc...
Sequins can be nested (effective for creating melodies):
s = sequins -- save yourself some typing
seq = s{1, 2, s{3, 4}}
print( seq() ) -- 1, 2, 3, 1, 2, 4 ...
Step size can be set on initialization or on the fly:
seq = s{1,2,3,4,5}:step(2) -- seq() --> 1,3,5,2,4,1,...
seq:step(1) -- seq() --> 1,2,3,4...
Any datatype is allowed, ie functionseq = s{lfo, ar, pulse}
or stringseq = s{"hello","goodbye"}
.
See the reference for the full range of capabilities.
Public variables are the automatic method for exposing crow variables to a connected USB host device. Public variables are kept synchronized across both devices and may be modified by either device.
TODO
A new clock
system has been implemented which parallels the norns system. This means crow now can have a ton of additional time-based functionality beyond metro
using the norns-familiar sync
and sleep
methods. See the clock reference for the full syntax.
Two new global functions justvolts
and just12
for converting from fractions (ie floats) to their volts, or 12TET representation.
They have the same signature justX( notex, offset)
. notex
can be a single fraction which returns a converted value, or it can be a table of fractions which will return a new table with each element converted. offset is an optional argument which expects a single fraction acting as a just-transposition to notex
. From my reading this seems like the way to handle key-modulation (open to other ideas here).
justvolts(1/1) -> 0.0
justvolts(3/2) -> 0.5849625
justvolts(1/4) -> -2.0 -- notes can be outside the 1/1 .. 2/1 range
just12(1/1) -> 0.0
just12(3/2) -> 7.019549
just12(3/2, 9/8) -> 9.058649 is 3/2 offset by 9/8
just12{1/1,3/2,7/4} -> {0.0, 7.019549, 9.688259} -- table call returns a new table
Output scale is used like so:
output[1].scale({1/1,3/2,11/8}, 'ji') -- a third optional arg sets volts/octave, so you can still use 1v2/octave if you want
Note the use of ji
where you normally put the temperament. This calls just12
under the hood, but is slightly better than doing it manually because it enforces some default behavior.
Input scale is similar to output, but uses the mode function call (like normal input quantizers):
input[1].mode('scale', {3/2, 9/8, 5/4}, 'ji') -- again last arg (v/8 scaling) is optional & omitted in this example
The new input mode freq
is short for frequency tracker. It functions the same as stream
& volume
modes, but returns values representing the frequency of an attached oscillation. ie: input[b].mode("freq")
Also available is a new function hztovolts
which is based on the same absolute freq range as just-friends, w/syn, etc. This is especially handy if you want to track a frequency input and control a module over ii
, or even to take an input frequency and send it to an output as a voltage (so it can be doubled by another oscillator). This would be especially interesting if the output had a .scale
applied, and in volts space, adding an offset becomes a direct transposition.
- output voltage query now returns shaped and scaled value, as seen at the jack
- output scale syntax now allows
output[n].scale = {note list}
The calibration system has been overhauled, giving direct access to the scale and offset values per input and output channel along with the ability to save the current configuration to flash.
While recalibration isn't something you should need to do, if you're interested check out the reference
- userscript storage increased to 16k (doubled!)
- massive RAM optimization (this means more clocks, tables, etc at runtime)
- ii follower mode on TT (requires TT v4.0)
Alongside this new firmware release we have some new features in druid:
- pydfu-based crow firmware updater, auto-fetches from git release @tehn
- websocket server at port 6666 for sending commands directly to crow (ie, line execution from editor) @csboling
- command autocomplete + input captures @csboling
- filename autocompletion @csboling
You can now send commands to crow via druid remotely, such as through your text editor with some additional configuration. Check out the reference, but here's a snippet for attaching a hotkey to vim
(requires you first install websocat
):
map <C-\> :silent .w !websocat ws://localhost:6666 -1<CR>