API Reference
Synthesizer
- class dexed.DexedSynth(sample_rate=44100.0)
Bases:
objectDX7 synthesizer.
Example:
synth = DexedSynth(sample_rate=44100) # From a Patch (DX7 sysex interface) patch = Patch.load_bank("rom1a.syx")[0] synth.load_patch(patch) audio = synth.render(midi_note=60, velocity=100) # From a Preset (ML interface) from dexed import Preset preset = Preset(algorithm=15, feedback=0.5) synth.load_preset(preset) audio = synth.render(midi_note=60)
- Parameters:
sample_rate (float)
- render(midi_note=60, velocity=100, note_duration=3.0, render_duration=4.0)
Render audio with current parameters.
- Parameters:
- Return type:
- Returns:
numpy array of shape [T] with audio samples (float32)
- render_all_ops(midi_note=60, velocity=100, note_duration=3.0, render_duration=4.0)
Render individual operator outputs.
Preset
- class dexed.Preset(feedback=0.0, transpose=0.5, pitch_mod_sensitivity=0.0, lfo_speed=0.35353535353535354, lfo_delay=0.0, lfo_pitch_mod_depth=0.0, lfo_amp_mod_depth=0.0, osc_key_sync=1, lfo_sync=0, pitch_env_rates=<factory>, pitch_env_levels=<factory>, op_env_rates=<factory>, op_env_levels=<factory>, op_output_level=<factory>, op_frequency_coarse=<factory>, op_frequency_fine=<factory>, op_detune=<factory>, op_velocity_sensitivity=<factory>, op_amp_mod_sensitivity=<factory>, op_rate_scaling=<factory>, op_breakpoint=<factory>, op_left_depth=<factory>, op_right_depth=<factory>, algorithm=0, lfo_wave=4, op_frequency_mode=<factory>, op_left_curve=<factory>, op_right_curve=<factory>)
Bases:
objectPyTree-compatible DX7 preset with all synth state.
All fields are JAX PyTree data leaves – changing any value never triggers JIT recompilation. This makes Preset ideal for use as the argument to
jax.pure_callback.algorithmis 0-indexed (0–31), matching the DX7 sysex byte.Because there are no meta fields, all Presets share the same treedef:
_, treedef = jax.tree.flatten(Preset()) # works for any Preset
Flat vector to Preset inside JIT:
_, treedef = jax.tree.flatten(Preset()) @jax.jit def make_preset(flat_params): # flat_params is (145,) leaves = Preset.array_to_leaves(flat_params) return jax.tree.unflatten(treedef, leaves)
Bulk serialization:
arr = np.stack([p.to_array() for p in presets]) # (N, 145) float32 np.save('presets.npy', arr) presets = [Preset.from_array(row) for row in np.load('presets.npy')]
- Parameters:
feedback (float)
transpose (float)
pitch_mod_sensitivity (float)
lfo_speed (float)
lfo_delay (float)
lfo_pitch_mod_depth (float)
lfo_amp_mod_depth (float)
osc_key_sync (int)
lfo_sync (int)
pitch_env_rates (ndarray)
pitch_env_levels (ndarray)
op_env_rates (ndarray)
op_env_levels (ndarray)
op_output_level (ndarray)
op_frequency_coarse (ndarray)
op_frequency_fine (ndarray)
op_detune (ndarray)
op_velocity_sensitivity (ndarray)
op_amp_mod_sensitivity (ndarray)
op_rate_scaling (ndarray)
op_breakpoint (ndarray)
op_left_depth (ndarray)
op_right_depth (ndarray)
algorithm (int)
lfo_wave (int)
op_frequency_mode (ndarray)
op_left_curve (ndarray)
op_right_curve (ndarray)
- SCALES: ClassVar[Dict[str, int]] = {'feedback': 7, 'lfo_amp_mod_depth': 99, 'lfo_delay': 99, 'lfo_pitch_mod_depth': 99, 'lfo_speed': 99, 'op_amp_mod_sensitivity': 3, 'op_breakpoint': 99, 'op_detune': 14, 'op_env_levels': 99, 'op_env_rates': 99, 'op_frequency_coarse': 31, 'op_frequency_fine': 99, 'op_left_depth': 99, 'op_output_level': 99, 'op_rate_scaling': 7, 'op_right_depth': 99, 'op_velocity_sensitivity': 7, 'pitch_env_levels': 99, 'pitch_env_rates': 99, 'pitch_mod_sensitivity': 7, 'transpose': 48}
- DATA_FIELDS: ClassVar[List[str]] = ['feedback', 'transpose', 'pitch_mod_sensitivity', 'lfo_speed', 'lfo_delay', 'lfo_pitch_mod_depth', 'lfo_amp_mod_depth', 'pitch_env_rates', 'pitch_env_levels', 'op_env_rates', 'op_env_levels', 'op_output_level', 'op_frequency_coarse', 'op_frequency_fine', 'op_detune', 'op_velocity_sensitivity', 'op_amp_mod_sensitivity', 'op_rate_scaling', 'op_breakpoint', 'op_left_depth', 'op_right_depth', 'osc_key_sync', 'lfo_sync', 'algorithm', 'lfo_wave', 'op_frequency_mode', 'op_left_curve', 'op_right_curve']
- to_array()
Pack all parameters into a (145,) float32 array.
Order matches
DATA_FIELDS. Integer fields are cast to float32.- Return type:
- classmethod from_array(arr)
Unpack a (145,) float32 array into a Preset.
Integer fields are recovered by rounding.
- Parameters:
arr (
ndarray) – (145,) float32 array as produced byto_array().- Return type:
- global_continuous()
Global continuous params as a (15,) float32 array.
Order: feedback, transpose, pitch_mod_sensitivity, lfo_speed, lfo_delay, lfo_pitch_mod_depth, lfo_amp_mod_depth, pitch_env_rates[0..3], pitch_env_levels[0..3].
- Return type:
- global_ints()
Global integer params as a (4,) int32 array.
Order matches
GLOBAL_INT_MAXES: osc_key_sync, lfo_sync, algorithm, lfo_wave.- Return type:
- op_continuous()
Per-operator continuous params as a (6, 18) float32 array.
Row
iholds operatori’s 18 continuous params. Order matchesOP_CONTINUOUS_SIZE: env_rates[4], env_levels[4], output_level, frequency_coarse, frequency_fine, detune, velocity_sensitivity, amp_mod_sensitivity, rate_scaling, breakpoint, left_depth, right_depth.- Return type:
- op_ints()
Per-operator integer params as a (6, 3) int32 array.
Row
iholds operatori’s 3 ints. Order matchesOP_INT_MAXES: frequency_mode, left_curve, right_curve.- Return type:
- classmethod from_operator_bundles(global_cont, global_int, op_cont, op_int)
Construct a Preset from operator-bundle arrays.
- Parameters:
global_cont (
ndarray) – (15,) float32 — global continuous params.global_int (
ndarray) – (4,) int — [osc_key_sync, lfo_sync, algorithm, lfo_wave].op_cont (
ndarray) – (6, 18) float32 — per-operator continuous params.op_int (
ndarray) – (6, 3) int — per-operator ints [freq_mode, left_curve, right_curve].
- Return type:
This is the inverse of calling
global_continuous(),global_ints(),op_continuous(),op_ints().
- static array_to_leaves(arr)
Split a (145,) flat array into a list of PyTree leaves.
Works with both NumPy and JAX arrays. JIT-traceable.
All Presets share the same treedef (no meta fields), so one treedef works universally:
_, treedef = jax.tree.flatten(Preset()) @jax.jit def make_preset(flat_params): return jax.tree.unflatten(treedef, Preset.array_to_leaves(flat_params))
- Parameters:
arr – flat array with
len(arr) == 145.- Returns:
List of 28 arrays/scalars matching the PyTree leaf order.
- classmethod from_patch(patch)
Create a Preset from a
Patch.Delegates to
to_preset().- Return type:
Patch
- class dexed.Patch(name='INIT VOICE')
Bases:
objectComplete DX7 patch with all parameters.
Provides named access to all DX7 parameters and conversion methods for various formats (sysex, packed, normalized arrays).
Operators are 0-indexed (op[0] through op[5]). Algorithm is 0-indexed (0-31).
- Parameters:
name (str)
- property op: _OperatorAccessor
patch.op[0] through patch.op[5].
- Type:
Access operators by 0-based index
- classmethod from_sysex(data)
Create Patch from 156-byte unpacked DX7 voice data.
This is the “VCED” format used in single-voice dumps.
- classmethod from_packed(data)
Create Patch from 128-byte packed format (used in bulk dumps).
- classmethod load_bank(filename)
Load a DX7 bank file (32 voices).
Supports both raw 4096-byte dumps and standard sysex format.
- save_to_bank(filename, patches=None)
Save patches to a bank file. If patches is None, saves just this patch as slot 0.
- to_raw()
Export to 155-element array of raw DX7 parameter values.
Values are in their native DX7 ranges (0-99, 0-31, etc.).
- Return type:
- classmethod from_raw(params)
Create Patch from 155-element raw parameter array.
Custom Operator Graphs
- class dexed.OperatorGraph(num_ops=6)
Bases:
objectCustom FM synthesis graph with arbitrary operator routing.
Provides DX7-accurate synthesis with the flexibility to create custom topologies beyond the 32 standard algorithms.
- Parameters:
num_ops (int)
- connect(source, target, amount=1.0)
Connect source operator to modulate target operator.
- Parameters:
- Return type:
- Returns:
self for method chaining
- disconnect(source, target)
Remove modulation connection between operators.
- Return type:
- Parameters:
- set_carriers(carriers)
Set which operators output to audio.
- Parameters:
- Return type:
- Returns:
self for method chaining
- set_feedback(op, level=7)
Set self-feedback level for an operator (DX7 style).
- Parameters:
- Return type:
- Returns:
self for method chaining
- get_connections()
Get all connections as (source, target, amount) tuples.
- get_sources(target)
Get all operators that modulate a given target.
- get_targets(source)
Get all operators that a given source modulates.
- is_connected(source, target)
Check if source modulates target.
- connection_amount(source, target)
Get modulation amount (0.0 if not connected).
- get_feedback(op)
Get feedback level for an operator (0 if none).
- disconnect_all()
Remove all connections (reset to isolated operators).
- Return type:
- summary()
Get a human-readable summary of the graph configuration.
- Return type:
- Returns:
Multi-line summary string.
- to_mermaid()
Generate Mermaid diagram syntax for visualization.
- Return type:
- Returns:
Mermaid flowchart syntax string.
- to_ascii()
Generate ASCII art representation of the graph.
- Return type:
- Returns:
Multi-line string showing operators, connections, and carriers.
- render(sample_rate=44100.0, midi_note=60, velocity=100, note_duration=1.0, render_duration=1.5)
Render audio from the operator graph with DX7-accurate synthesis.
- Parameters:
- Return type:
- Returns:
Audio samples as float32 numpy array
- render_all_ops(sample_rate=44100.0, midi_note=60, velocity=100, note_duration=1.0, render_duration=1.5)
Render individual operator outputs with DX7-accurate synthesis.
- classmethod from_matrix(mod_matrix, carriers, feedback=None)
Create an operator graph from a modulation matrix.
- Parameters:
- Return type:
- Returns:
OperatorGraph instance
- class dexed.GraphOperator(output_level=99, frequency_coarse=1, frequency_fine=0, frequency_mode=0, detune=7, velocity_sensitivity=0, rate_scaling=0, amp_mod_sensitivity=0, breakpoint=39, left_depth=0, right_depth=0, left_curve=0, right_curve=0, envelope=<factory>)
Bases:
objectOperator in a custom FM synthesis graph.
Parameters match DX7 operators for familiarity and accuracy.
- Parameters:
- envelope: GraphEnvelope
Algorithm Utilities
- dexed.get_carriers(algorithm)
Get list of carrier operator numbers for an algorithm.
- dexed.get_modulators(algorithm)
Get list of modulator operator numbers for an algorithm.
- dexed.get_mod_matrix(algorithm)
Get 6x6 modulation matrix for an algorithm.
- dexed.algorithms = <dexed.algorithms._AlgorithmDict object>
Dictionary-like access to algorithms by number (0-31).