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. WINDOWS USERS — this command doesn’t work yet so:
manual update instructions are also available (if you have trouble with the druid method).
ASL2
“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, amplitude, shape) -- optional: amplitude & shape
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
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. times). 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
sequins
This new library connects data to “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}} -- last note alternates between 3 and 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
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. This system is specifically setup for building remote user interfaces. We’ve updated bowery to use public variables for all the main performance controls.
bowering
This new norns script is a basic crow-script loader. When loading a new crow script, any public variables will have a UI element generated to control it. It comes populated with the updated bowery collection, which is open for contributions!
The script is also a demonstration of building a public-aware host. Bowering could be extended in many ways, or act as an example for building your own crow-interactive scripts. Norns support also introduces a few helper functions & conventions for uploading scripts to crow and “freezing” public variables so norns can act as a crow script configurator.
Note: norns: update 210630 / 210701 is required to work with crow 3.0
clock
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.
input and output
just intonation support
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. This supports a method for handling key-modulation while maintaining internal harmony.
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.scale quantizers):
input[1].mode('scale', {1/1, 9/8, 5/4}, 'ji') -- last arg (v/8 scaling) is optional
-- when omitted, defaults to 1V/octave
input frequency detection mode
The new input mode freq is short for frequency tracker. It functions the same as stream & volume modes, but streams values representing the frequency of an attached oscillator.
input[1].freq = function(hz)
-- called each interval defined in the .mode call below
end
input[1].mode("freq", 0.1) -- stream the frequency 10x per second
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).
misc
-
output.voltsquery now returns shaped and scaled value, as seen at the jack - output scale syntax now allows
output[n].scale = {note list}
calibrate
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
assorted improvements and fixes
- userscript storage increased to 16k (doubled!)
- massive RAM optimization (this means more clocks, tables, etc at runtime)
- ii follower mode on Teletype (requires TT v4.0)
druid
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
NOTE: windows connection is temporarily broken, so please don’t update yet if you’re running windows.
websocket commands
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>
Max + Max for Live
The Max objects & Max for Live devices have been updated to support the new crow 3.0 features thanks to @dan_derks. A few new changes too:
-
^^dualnow has dropdown to select pulse or ADSR for secondary output event – if ADSR is selected, device will horizontally expand to reveal ADSR stage controls -
^^outsno longer has anlfooption, sinceremoteduplicates the coverage – artists can load Live’s native LFO device and map it toremote's knob to run time-synced LFO’s through Live → crow
^^


