Metadata-Version: 2.4
Name: segan-gen
Version: 0.17.1
Summary: SEGAN (Sound Effect Grammar And Notation): write game sound effects and music as text, build them into WAVs and game-ready assets.
Author: Lukas Golino
License-Expression: Apache-2.0
Project-URL: Homepage, https://segan.top/
Project-URL: Source, https://github.com/lukasgolino/segan
Project-URL: Issues, https://github.com/lukasgolino/segan/issues
Project-URL: Changelog, https://github.com/lukasgolino/segan/blob/main/CHANGELOG.md
Keywords: sound-effects,music,audio,godot,game-assets,mcp,procedural
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Games/Entertainment
Classifier: Topic :: Multimedia :: Sound/Audio
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: numpy>=1.26
Requires-Dist: scipy>=1.11
Requires-Dist: Pillow>=10.1
Requires-Dist: PyYAML>=6
Requires-Dist: mcp<3,>=2.3
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Requires-Dist: ruff>=0.15; extra == "dev"
Requires-Dist: types-PyYAML; extra == "dev"
Requires-Dist: soundfile>=0.12; extra == "dev"
Provides-Extra: mcp
Provides-Extra: ogg
Requires-Dist: soundfile>=0.12; extra == "ogg"
Dynamic: license-file

# SEGAN — Sound Effect Grammar And Notation

SEGAN translates between AI and game audio. It defines a small text notation for sound effects and music —
instrument kits, step-grid songs and layered synth SFX, all YAML — that an AI agent can write fluently, and a
Python tool that lints it, renders **listen sheets** (pictures of the sound an agent can look at), and builds
engine-ready WAVs, `manifest.json` and Godot resources. It is the sister library of
[PAGAN](https://github.com/lukasgolino/pagan) (Pixel Art Grammar And Notation): same design, sound instead of pixels.

```yaml
patterns:
  a:
    length: 16
    lead: |
      ....|....|..p-|....  F5
      ....|..p-|....|p---  E5
      p-..|....|....|....  A4
    drums: |
      x...|....|x.x.|....  k
      ....|X...|....|X..o  s
```

- **Kits are the palette**: songs write one-character instrument keys; roll rows are the notes of the song's
  key, so an off-key note can't be written. Row labels are checked, so a missing row can't shift the grid.
- **SFX are synth layers** with pitch/gain/filter keyframes, 11 presets (coin, jump, laser, explosion, hit, hurt,
  powerup, blip, select, door, step), variations, phases and seamless loops.
- **Recorded SFX** for real-world sounds: `segan sounds search` finds recordings on Freesound (CC0 and CC BY
  only), `segan sounds add` records them in `sounds.lock` (fetched into a user cache, checked by sha256, nothing
  copied into the repo), and an SFX layer plays them (`sample: freesound:<id>` or a file) trimmed, reversed,
  faded, pitch-shifted and time-stretched independently, layered with synth sounds. `segan sounds credits`
  writes the attribution CC BY requires. See [examples/demo/sfx/boss_gong.sfx.yaml](https://github.com/lukasgolino/segan/blob/main/examples/demo/sfx/boss_gong.sfx.yaml).
- **A wide palette**: band-limited oscillators, instrument models (plucked and bowed strings, sung vowels and choirs,
  struck mallets, bells and metal, additive organs, wavetables, supersaws, 3-4 operator FM), hard sync, sub
  oscillators, brass mutes, 13 drum macros and per-instrument effects (chorus, ensemble, phaser, flanger,
  tempo-synced delay, reverb, drive, comb, ring, autopan...).
- **Sampled instruments** in any kit: `sample:` plays WAVs, SFZ maps and SoundFonts (`.sf2`), and four CC0
  libraries download on demand with `segan samples fetch`: `vsco2` (orchestra), `vcsl` (grand piano, electric
  piano, organs, mallets, winds, world and hand percussion), `karoryfer` (guitars, basses, erhu, a drum kit with a
  brush), `neosound` (voice, steel guitar, bamboo flute). See [examples/orchestra](https://github.com/lukasgolino/segan/blob/main/examples/orchestra).
- **Variety by design**: a random project seed, `segan kit roll` (a kit from style words, with a shared `identity`
  group), `segan suggest song` (key, mode, tempo, meter, texture and opening away from the project's songs), and
  sameness checks: lint warns when songs open alike or share their first bars, and `segan similarity` scores every
  pair.
- **One shared mix** (`[mix]`: room, tone, crush, oversampling, loudness targets, true-peak limiter) for every
  asset, so a game's sounds belong together; change it once and everything re-renders.
- **Deterministic**: same sources, byte-identical WAVs (band-limited oscillators, table-based maths, no RNG
  drift). Every command takes `--json` and exits non-zero on errors; lint findings carry rule id, file, line
  and a fix hint.

> **Status:** v0.17: the full pipeline works (kits, SFX, songs, lint, listen sheets, build, Godot 4, MIDI
> import, MCP server, Claude skill), with synth and sampled instruments. See [PLAN.md](https://github.com/lukasgolino/segan/blob/main/PLAN.md) and
> [CHANGELOG.md](https://github.com/lukasgolino/segan/blob/main/CHANGELOG.md).

## Install

Requires Python 3.11+. The package is `segan-gen` on PyPI; the command and the import are `segan`:

```sh
pip install segan-gen              # the CLI, the library and the MCP server
pip install "segan-gen[ogg]"       # + Ogg Vorbis music export, .ogg/.flac/.mp3 recordings
segan --version
```

Development:

```sh
git clone https://github.com/lukasgolino/segan.git && cd segan
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
mypy && pytest
```

## Quick start

```sh
segan init audio --style "cold ship, warm crew"   # segan.toml (with a project seed), BRIEF.md, SOUND.md, kits/core.kit.yaml
cd audio
segan kit show                      # every instrument playing a test phrase: previews/kits/core.listen.png + WAVs
segan new sfx coin --preset coin --description "bright two-note pickup"
segan suggest song theme --mood "exploration"   # key, tempo, meter, texture, opening, progression, instruments
segan new song theme --description "exploration loop"   # takes the suggestion (or --key/--tempo/--meter)
segan lint                          # format errors + warnings from the source and the rendered audio
segan preview coin theme            # WAV + listen sheet (+ loop seam view) per output; numbers with --json
segan gallery                       # every asset side by side + loudness by category
segan build                         # WAVs + manifest.json (+ Godot resources) into output_dir
```

The demo project in [`examples/demo/`](https://github.com/lukasgolino/segan/blob/main/examples/demo) has three kits (`nes`, `fm_soft`, `arcade_synth`), the
preset SFX and looping songs with variants; [`examples/godot/`](https://github.com/lukasgolino/segan/blob/main/examples/godot) is the Godot 4.7 project it
builds into (run `segan build` in `examples/demo` first, then open it in Godot and press Play).

## Listen sheets: how an agent "hears"

An agent can't hear, so `segan preview` draws the sound: a header with the numbers (length, peak, true peak,
LUFS vs. target, limiter, lead-in, loop seam click), the arrangement and a piano roll per track (from the
source), the waveform (clipping in red), a log-frequency spectrogram with octave lines, the intended pitch
(white) and the detected pitch (cyan), and the loudness over time. `--json` adds onsets, per-note pitch checks
in cents, spectral centroid and more. What it can't judge is taste: every asset stays `status: draft` until a
human listens and runs `segan mark <asset> --status approved`.

## Using the output in a game

`segan build` writes WAVs (16-bit, loop points in a `smpl` chunk, markers as cues) and `manifest.json`: per
asset its files, lengths and loop points in samples; songs also their tempo, sections, arrangement and markers
in samples, seconds and bars, variants and stems; SFX their variations and phases. With `export = ["wav",
"godot"]` and an `output_dir` inside a Godot 4 project, SEGAN also writes each WAV's loop points and compression
into its `.import`, an `AudioStreamRandomizer` per SFX with variations and an `AudioStreamSynchronized` per song
with stems (`export` + `"stems"`):

```gdscript
$Music.stream = load("res://assets/generated/audio/music/overworld.wav")   # loops seamlessly by itself
$Music.play()
$Coin.stream = load("res://assets/generated/audio/sfx/coin.tres")          # a different variation each time
$Coin.play()
```

The files are plain WAV (Ogg for music with `"ogg"`), so any engine plays them; `manifest.json` is the
engine-neutral contract (variations, loop points, buses, playback hints). With `"web"` in `export`, the build also
writes `segan_audio.js`, a Web Audio player for the manifest. Unity, Unreal and Defold: see "Other engines" in the
[engines topic](https://github.com/lukasgolino/segan/blob/main/src/segan/skill/topics/engines.md) (`segan docs engines`) for their import settings and what to read from the manifest.

## Using SEGAN with Claude

SEGAN ships a Claude skill that teaches an agent the whole workflow (setting up a game's audio, writing kits,
SFX and songs, reading listen sheets honestly, changing the sound over time):

```sh
segan skill install          # copies it to <repo>/.claude/skills/segan/
```

## Using SEGAN from any agent (MCP)

```sh
claude mcp add segan -- uvx segan-gen mcp --project /path/to/audio    # no install needed (uv); or `segan mcp` after pip install
```

A stdio MCP server: 26 tools, listen sheets as images, WAVs as audio. Other clients take the same command in their
config:

```json
{ "mcpServers": { "segan": { "command": "uvx", "args": ["segan-gen", "mcp", "--project", "/path/to/audio"] } } }
```

SEGAN is listed in the [MCP Registry](https://registry.modelcontextprotocol.io/) as `io.github.lukasgolino/segan`.

## Generator scripts and MIDI

`segan.api` (keys, chords, progressions, Euclidean rhythms, arpeggios, a pattern builder and YAML writers) is a
stable API for scripts that generate many sounds or procedural music. `segan import midi song.mid --kit nes`
converts a MIDI file into a song: quantized to the grid, snapped to the key, parts mapped to kit instruments,
with a report of every change.

<!-- mcp-name: io.github.lukasgolino/segan -->

## License

Apache 2.0. See [LICENSE](https://github.com/lukasgolino/segan/blob/main/LICENSE).
