How to Use Nallely’s Random Preset and Patch Generators
Nallely provides two distinct randomization facilities: random_preset() randomizes every controllable parameter on a single MIDI or virtual device, while RandomPatcher generates random signal routings (patches) across an entire system of devices.
The dr-schlange/nallely-midi library includes stateless generators for exploring sound design and creating test data. Both tools respect parameter ranges and can operate locally or remotely via the Trevor API.
Random Preset Generator
Architectural Overview
The random preset generator iterates over every controllable parameter of a device and assigns a random value within its defined range or accepted_values. This facility is implemented in the base device classes and is available for both physical MIDI hardware and virtual devices.
-
In
nallely/core/virtual_device.py(lines 73‑85),VirtualDevice.random_preset()loops throughself.all_parameters(), skipping theset_pauseparameter used by LFOs (see the guard on line 78). -
For concrete MIDI hardware,
nallely/core/midi_device.py(lines 16‑24) providesMidiDevice.random_preset(), which applies the same logic to physical synthesizers and controllers.
Both implementations are stateless; they modify the device’s current parameter values but do not alter the underlying class definition.
Randomizing a Single Device
From an interactive Python session, instantiate any device class and call random_preset():
from nallely import MidiDevice
from nallely.devices import NTS1
# Connect to a Korg NTS-1 (or any supported device)
synth = NTS1()
# Randomize every parameter respecting min/max ranges
synth.random_preset()
# Persist the generated configuration to disk
synth.save_preset("experimental_nts1.json")
The method call executes the logic defined in MidiDevice.random_preset(), filling parameters with statistically random values suitable for exploratory sound design.
Using the CLI Demo Script
The repository includes a ready-made experiment script at experiments/random_device_config.py that automates the randomization workflow:
python experiments/random_device_config.py
This script:
- Imports a default device (typically
NTS1) - Calls
device.random_preset()(line 17 of the script) - Prompts for user input: press s to save the preset, q to quit, or any other key to generate another random configuration
Random Patch Generator
How RandomPatcher Works
The random patch generator is implemented as a virtual device named RandomPatcher in the experimental sub-package. Unlike the preset generator which targets a single device, RandomPatcher orchestrates connections across an entire system.
When the trigger CV (control voltage) goes high, the device executes its main() method (lines 68‑84 of nallely/experimental/random_patchers.py):
- Gathers all devices via
all_system_parameters()(helper method at lines 86‑94) - Randomizes each discovered device by invoking
device.random_preset() - Selects random source→destination pairs using
random.choiceover the Cartesian product of all device outputs and inputs - Clears existing connections via
TrevorAPI.delete_all_connections() - Creates new associations with
TrevorAPI.associate_parameters(src, dst)for each selected pair - Pushes updates to the Trevor backend via
self.trevor_bus.send_update()
Adding RandomPatch to a Session
To generate random routings within a Nallely session, instantiate RandomPatcher alongside a TrevorBus:
from nallely import Session, RandomPatcher, TrevorBus
# Bridge to the external Trevor server
trevor = TrevorBus(host="localhost", port=8000)
# Create the patch generator
patcher = RandomPatcher()
patcher.trigger = 1 # Fire the patch generation immediately
# Assemble session
session = Session(devices=[trevor, patcher])
session.run() # Invokes RandomPatcher.main()
When triggered, the patcher deletes previous connections and establishes 10 new random routings between available CV outputs and inputs.
Remote Control via Trevor API
Both generators integrate with the Trevor remote API. You can trigger a random preset on a specific device without direct local instantiation:
from nallely.trevor import TrevorAPI
api = TrevorAPI(host="localhost", port=8000)
api.random_preset(device_id="NTS1")
This call forwards to the device’s native random_preset() implementation (see nallely/trevor/trevor_api.py, lines 33‑35). The API wrapper allows headless servers or external scripts to leverage Nallely’s randomization engine across network boundaries.
Summary
random_preset()is available on allMidiDeviceandVirtualDeviceinstances vianallely/core/midi_device.pyandnallely/core/virtual_device.py; it respects parameter ranges and skips LFO timing controls.RandomPatcherlives innallely/experimental/random_patchers.pyand generates system-wide random routings when triggered.- Both facilities are stateless and can be invoked locally or remotely through the
TrevorAPIinterface. - The
experiments/random_device_config.pyscript provides an immediate CLI for single-device exploration.
Frequently Asked Questions
Does the random preset generator respect parameter limits?
Yes. According to the source code in nallely/core/virtual_device.py (lines 73‑85), the generator reads each parameter’s range tuple or accepted_values list and uses Python’s random module to select values strictly within those bounds. It will not send out-of-range MIDI data to hardware devices.
Can I exclude specific parameters from randomization?
The base implementation deliberately excludes the set_pause parameter (used by internal LFOs) as shown on line 78 of virtual_device.py. For other exclusions, you would subclass the device and override all_parameters() to filter the returned dictionary before calling super().random_preset().
How many connections does RandomPatcher create?
The current implementation in nallely/experimental/random_patchers.py (lines 68‑84) creates 10 random connections per trigger event. This is hardcoded in the main() method where it iterates over a range and calls random.choice on the Cartesian product of system outputs and inputs.
Is the RandomPatcher suitable for production use?
RandomPatcher resides in the experimental sub-package because it performs high-level orchestration across multiple devices. While functional, it is designed for exploration and testing rather than deterministic live performance, as it deletes all existing connections before creating new random ones.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →