I’ve pushed a number of major updates to some of my quarks, and published a new one. Please take a chance to try them out and let me know if you have any issues!
Here’s a quick run-down:
IconSet quark (new)
Quarks.install("https://github.com/scztt/IconSet.quark");
A quark wrapping two common open-source icon sets - Material (https://material.io/resources/icons/?style=baseline) and Linea (https://linea.io/).
It provides a simple interface to add svg icons to your UI from either of these two sets (including colorizing and scaling).:
ToolBar(
MenuAction("Louder").icon_(Linea("music_volume_up")),
MenuAction("Quieter").icon_(Linea("music_volume_down")),
MenuAction("Or nothing at all").icon_(Linea("music_mute"))
)
.toolButtonStyle_(QToolButtonStyle.textBesideIcon)
.bounds_(400@60)
.front;
NodeSnapshot
Quarks.install("https://github.com/scztt/NodeSnapshot.quark");
-
IO display overlay (visible when clicking on an IO triangle) now shows metadata about the bus, including rate, channels, and an average/min/max value.

-
Input/output display now shows IO’s for buses that are mapped to Synth arguments via
.asMap. -
IO display is now updated if it changes on the Synth (e.g. a mapped control is changed)
*Dots are shown next to IO display to indicate channels -
IO scope displays now show the bus values as the node in question will see them: this means, if a node is reading a bus that is only written to LATER in the graph, the scope will show silence (what the node sees), not an active signal. This can help when debugging node order problems.
-
Added
TreeValidator, which can walk aTreeSnapshotand produce warnings of invalid states (e.g. faulty node ordering). It is available in the UI as a button + drop-down at the top of the snapshot view. New validation passes can be added using TreeValidator.addValidation. The default validator will warn in cases where a node is reading from a bus that is written to by a later node, and when a node overwrites bus data already written to by another node before it was read (this bus data would be lost).

-
Bug fixes
OSequence
Quarks.install("https://github.com/scztt/OSequence.quark");
- OSequence is still highly undocumented! Sorry! But it now has a barebones help file with examples and a short tutorial.
- Introduced
OSequence:plotto visually plot a sequence. The x-axis of the plot is always time - the y-axis is a property of the events in yourOSequence, specified in the first argument - e.g.oseq.plot(\midinote)would plot themidinotevalues fromEvents in the sequence. - When creating an
OSequenceviaOSequence:*fromStream,Restevents are handled correctly (e.g. no event is stored, but time is incremented) - FIX: An issue with
OSequence:copywhere the same event would remain in two OSequences at once. - Implemented common
Collectioniterators likedo,collect, etc., as well as someOSequencespecific operations:doTimes,doReplaceTimes,filter(an in-place version ofselect),collectKeyandsetKey(collects/setse[key]for all itemsein the sequence). -
OSequencenow prefers to track the duration of individual events using thesustainkey where possible, since this reflects better how Pbind’s behave.
Connection
Quarks.install("https://github.com/scztt/Connection.quark");
- Added
ControlValueEnvir:asPbind, which creates a stream of events representing all the values in aControlValueEnvir. This can be composed with another event stream to easily modulate parameters. -
OSCReplyUpdater,SignalStateUpdater,BusStateUpdaternow support being placed at a specific location in the synth graph, viatargetandaddActionarguments.
BandSplitter
Quarks.install("https://github.com/scztt/BandSplitter.quark");
-
BandSplitternow supportskrandarrates.
Singleton
Quarks.install("https://github.com/scztt/Singleton.quark");
- FIX: Singleton’s passed a string name, e.g.
MySingleton("foo")will work as expected (the string will be converted to a symbol and match an existing Singleton). Before this, using a string as aSingletonname would never match, becauseSingletons are stored in anIdentityDictionary.
Require
Quarks.install("https://github.com/scztt/Require.quark");
-
If Require cannot find any files to include, it posts warnings specifying it’s search paths for debugging purposes.
-
Require:resolvePathsnow takes arguments for both a list of extensions and relative root paths. This does not affect the behavior ofRequireper se, but makes this useful for complex automatic resolution scenarios, e.g.:
Require.resolvePaths(
identifier: "Roland TR-66/*Conga*",
relativeTo: ["/Users/fsc/Documents/_sounds/drums/Drum Machines/"],
extensions:["wav", "aif"]
);
-> [ /Users/fsc/Documents/_sounds/drums/Drum Machines/Roland TR-66/MaxV - Conga Hi.wav, /Users/fsc/Documents/_sounds/drums/Drum Machines/Roland TR-66/MaxV - Conga Mi.wav ]
-
Require:rootsis a list of root search paths to use when resolving files. The previous example could also work with:Require.roots.add("/Users/fsc/Documents/_sounds/drums/Drum Machines/")




That part doesn’t include the validator though, which is at the end of the file.