No description
  • Python 76.7%
  • Jinja 23.3%
Find a file
Daniel Díaz 835de339ff Add AGENTS.md
Signed-off-by: Daniel Díaz <yosoy@danieldiaz.org>
2026-06-27 18:31:09 -06:00
templates Add --minimal option to skip /headamp/ and /ch/xx/mix 2026-05-25 17:41:35 -06:00
tests Add edit-names command 2026-06-27 18:27:43 -06:00
.gitignore Initial version 2026-05-02 18:39:30 -06:00
AGENTS.md Add AGENTS.md 2026-06-27 18:31:09 -06:00
engine.py tests: Fix some and improve coverage 2026-05-03 10:32:04 -06:00
metadata.py Fix colors for X18, honor channel ordering 2026-05-02 18:53:35 -06:00
mixerconf.py Add edit-names command 2026-06-27 18:27:43 -06:00
models.py Initial version 2026-05-02 18:39:30 -06:00
presets.py Initial version 2026-05-02 18:39:30 -06:00
profiles.py Fix channel index on different versions of Python 2026-06-27 15:20:54 -06:00
README.md Add edit-names command 2026-06-27 18:27:43 -06:00

Digital Mixer Scene Configuration Generator

A Python-based utility to generate scene configuration files (.scn) for digital mixers (specifically Behringer X18/XR18 and X32). It maps human-readable stage layouts (JSON/YAML) to optimized mixer channel assignments and processing presets.

Features

  • Logical Grouping: Automatically assigns channels based on professional mixing standards:
    • Voices (Soprano, Mezzosoprano, Tenor, Baritone)
    • Plugged Instruments (Guitar, Piano, Bass)
    • Strings (Violin, Viola, Cello)
    • Percussion (Cajon, Bongos, Chimes)
  • Multi-Mixer Support: Profiles for Behringer X18 and X32.
  • EQ Presets: Automatic frequency adjustments based on instrument type and microphone model (e.g., SM58 optimization for voices).
  • Validation: Strict input validation using Pydantic.
  • Dual-Use: Use it as a standalone CLI tool or integrate it as a Python library.

Installation

pip install pydantic typer jinja2 pyyaml

Usage

Simplified Nested Format (Auto-mapped)

You can also use a simplified, grouped layout which automatically maps keys to their respective types:

- sopranos:
  - Alejandra
  - Saidee
- tenors:
  - Abraham
- instruments:
  - Guitar (Panano)
  - Piano (Leonor)

In this format, voices are mapped based on the key (sopranos, tenors, etc.), and instruments are inferred from the string prefix (e.g., "Guitar", "Piano").

- source_type: soprano
  player_name: Patsy
  microphone: SM58
- source_type: guitar (plug)
  player_name: Daniel
- source_type: cajon (whole)
  player_name: Chuy

Generate a scene:

python mixerconf.py create --input layout.yaml --mixer x18 --output sunday_service.scn

Skip /headamp/ and /ch/xx/mix ON lines for a lighter scene file:

python mixerconf.py create --input layout.yaml --mixer x32 --minimal --output minimal.scn

Or with the short flag:

python mixerconf.py create -i layout.yaml -m x32 -M -o minimal.scn

Validate a layout without rendering:

python mixerconf.py validate layout.yaml

Interactive Name Editing

Edit names in an existing .scn file without touching the rest of the configuration. Use the --quick flag to specify voice type counts (Soprano, Mezzosoprano, Tenor, Baritone) — the tool will prompt for each channel's new name:

python mixerconf.py edit-names service.scn --quick "2,1,1,0"

The interactive editor supports:

  • Enter to keep the current default name
  • Type a new name to rename
  • , to go back to the previous channel
  • T,Charlie to change the type to Tenor and set the name (type characters: S, M, T, B)

The mixer type is auto-detected from the file header (#4.0# = X32, no header = X18). Override with --mixer:

python mixerconf.py edit-names service.scn --quick "2,0,1,0" --mixer x18

Save to a new file instead of overwriting:

python mixerconf.py edit-names service.scn --quick "3,1,2,1" --output renamed.scn

Python Library

from models import ChannelInput, VoiceType, SceneMapping
from engine import assign_channels
from profiles import BehringerX18Profile

inputs = [
    ChannelInput(source_type=VoiceType.SOPRANO, player_name="Patsy")
]

assigned = assign_channels(inputs)
scene = SceneMapping(name="My Scene", inputs=assigned)

profile = BehringerX18Profile()
output_text = profile.render(scene)
print(output_text)

Development

Running Tests

The project maintains high test coverage (~99%) across core logic and CLI commands.

python3 -m pytest --cov=. tests/

Adding New Profiles

  1. Create a new Jinja2 template in templates/.
  2. Define a new MixerProfile subclass in profiles.py.
  3. Add icon/color mappings in metadata.py.