# How to Use Nallely’s Random Preset and Patch Generators

> Learn to use Nallely's random preset and patch generators to randomize MIDI devices and signal routings. Explore the dr-schlange/nallely-midi repository for quick setup and creative sound design.

- Repository: [dr-schlange/nallely-midi](https://github.com/dr-schlange/nallely-midi)
- Tags: how-to-guide
- Published: 2026-02-28

---

**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`](https://github.com/dr-schlange/nallely-midi/blob/main/nallely/core/virtual_device.py) (lines 73‑85), `VirtualDevice.random_preset()` loops through `self.all_parameters()`, skipping the `set_pause` parameter used by LFOs (see the guard on line 78).

- For concrete MIDI hardware, [`nallely/core/midi_device.py`](https://github.com/dr-schlange/nallely-midi/blob/main/nallely/core/midi_device.py) (lines 16‑24) provides `MidiDevice.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()`:

```python
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`](https://github.com/dr-schlange/nallely-midi/blob/main/experiments/random_device_config.py) that automates the randomization workflow:

```bash
python experiments/random_device_config.py

```

This script:
1. Imports a default device (typically `NTS1`)
2. Calls `device.random_preset()` (line 17 of the script)
3. 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`](https://github.com/dr-schlange/nallely-midi/blob/main/nallely/experimental/random_patchers.py)):

1. Gathers all devices via `all_system_parameters()` (helper method at lines 86‑94)
2. Randomizes each discovered device by invoking `device.random_preset()`
3. Selects random source→destination pairs using `random.choice` over the Cartesian product of all device outputs and inputs
4. Clears existing connections via `TrevorAPI.delete_all_connections()`
5. Creates new associations with `TrevorAPI.associate_parameters(src, dst)` for each selected pair
6. 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`:

```python
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:

```python
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`](https://github.com/dr-schlange/nallely-midi/blob/main/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 all `MidiDevice` and `VirtualDevice` instances via [`nallely/core/midi_device.py`](https://github.com/dr-schlange/nallely-midi/blob/main/nallely/core/midi_device.py) and [`nallely/core/virtual_device.py`](https://github.com/dr-schlange/nallely-midi/blob/main/nallely/core/virtual_device.py); it respects parameter ranges and skips LFO timing controls.
- **`RandomPatcher`** lives in [`nallely/experimental/random_patchers.py`](https://github.com/dr-schlange/nallely-midi/blob/main/nallely/experimental/random_patchers.py) and generates system-wide random routings when triggered.
- Both facilities are **stateless** and can be invoked locally or remotely through the `TrevorAPI` interface.
- The [`experiments/random_device_config.py`](https://github.com/dr-schlange/nallely-midi/blob/main/experiments/random_device_config.py) script 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`](https://github.com/dr-schlange/nallely-midi/blob/main/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`](https://github.com/dr-schlange/nallely-midi/blob/main/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`](https://github.com/dr-schlange/nallely-midi/blob/main/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.