Metadata-Version: 2.4
Name: ableton-device-creator
Version: 3.0.0
Summary: Professional toolkit for Ableton Live device creation and modification
Author: Ben Juodvalkis
License: MIT
Project-URL: Homepage, https://github.com/ben-juodvalkis/Ableton-Device-Creator
Project-URL: Repository, https://github.com/ben-juodvalkis/Ableton-Device-Creator
Project-URL: Documentation, https://github.com/ben-juodvalkis/Ableton-Device-Creator/blob/main/docs/CLI_GUIDE.md
Project-URL: Changelog, https://github.com/ben-juodvalkis/Ableton-Device-Creator/releases
Project-URL: Issues, https://github.com/ben-juodvalkis/Ableton-Device-Creator/issues
Keywords: ableton,audio,music-production,device-creation
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: cli
Requires-Dist: click>=8.0.0; extra == "cli"
Provides-Extra: dev
Requires-Dist: pytest>=7.4.0; extra == "dev"
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
Requires-Dist: black>=23.7.0; extra == "dev"
Requires-Dist: flake8>=6.1.0; extra == "dev"
Dynamic: license-file

# Ableton Device Creator V3.0

> **Professional Python toolkit for creating and modifying Ableton Live devices**

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)

## Overview

Modern Python library for programmatically creating and modifying Ableton Live devices (.adg) and presets (.adv). Born from 2+ years of production use in professional live performance systems.

### What's New in V3.0?

✨ **Modern Python Package** - Installable with pip, proper module structure
🎯 **Simple API** - High-level classes replace 100+ scripts
⚡ **CLI Tool** - Command-line interface for quick workflows
📚 **Zero Dependencies** - Core uses only Python stdlib
🎨 **Production-Ready** - Tested with real samples and DAW

---

## Quick Start

### Installation

```bash
# Install the package (Python API only, zero dependencies)
pip install ableton-device-creator

# Or with the `adc` command-line tool
pip install "ableton-device-creator[cli]"

# Or the latest unreleased code from GitHub
pip install "ableton-device-creator[cli] @ git+https://github.com/ben-juodvalkis/Ableton-Device-Creator.git"

# Or install from source (editable, for development)
git clone https://github.com/ben-juodvalkis/Ableton-Device-Creator.git
cd "Ableton-Device-Creator"
pip install -e ".[cli]"
```

The default drum rack, Sampler and Simpler templates ship inside the package,
so every example below works from any folder. Pass `template=` (or
`--template` on the CLI) to build from your own device instead.

### Basic Usage (Python API)

```python
from ableton_device_creator.drum_racks import DrumRackCreator
from ableton_device_creator.sampler import SamplerCreator

# Create drum rack from samples
creator = DrumRackCreator()
rack = creator.from_folder("samples/drums/", output="MyKit.adg")

# Create chromatic sampler
sampler = SamplerCreator()
instrument = sampler.from_folder("samples/", layout="chromatic")
```

### Basic Usage (CLI)

```bash
# Create drum rack
adc drum-rack create samples/drums/

# Apply color coding
adc drum-rack color MyKit.adg

# Create chromatic sampler
adc sampler create samples/ --layout chromatic

# Show device info
adc util info MyKit.adg
```

---

## Features

### 🥁 Drum Rack Creation

```python
from ableton_device_creator.drum_racks import DrumRackCreator, DrumRackModifier

# Create from folder with auto-categorization
creator = DrumRackCreator()
rack = creator.from_categorized_folders(
    "samples/drums/",
    layout="808",  # or "standard", "percussion"
    output="808_Kit.adg"
)

# Remap MIDI notes
modifier = DrumRackModifier("MyKit.adg")
modifier.remap_notes(shift=12).save("MyKit_High.adg")
```

**Features:**
- Auto-categorize samples (kicks, snares, hats, etc.)
- Multiple layouts (standard, 808, percussion)
- MIDI note remapping
- Batch processing

### 🎨 Macro Mapping

```python
from ableton_device_creator.macro_mapping import DrumPadColorMapper, TransposeMapper

# Apply color coding
colorizer = DrumPadColorMapper("MyKit.adg")
colorizer.apply_colors().save("MyKit_Colored.adg")

# Add transpose control
transpose = TransposeMapper("MySampler.adg")
transpose.add_transpose_mapping(macro_index=15).save("MySampler_Transpose.adg")
```

**Features:**
- Auto color pads by sample type
- Add transpose controls to samplers
- Preserve existing mappings
- Remove every macro mapping from a Drum Rack (see below)

### 🔓 Removing Macro Mappings

```python
from ableton_device_creator.core import decode_adg, encode_adg
from ableton_device_creator.macro_mapping import classify_rack, unmap_drum_rack, verify_unmap

xml = decode_adg("MyKit.adg")
info = classify_rack(xml)          # root class, mapping counts, nested racks, macro names
if info.is_drum_rack:
    unmapped, report = unmap_drum_rack(xml)
    assert verify_unmap(xml, unmapped, report) == []
    encode_adg(unmapped, "MyKit-unmapped.adg")
```

`unmap_drum_rack` does what Live's own unmap does: it deletes every `KeyMidi` block
owned by the rack, writes the value the macro was driving into each freed parameter
(the stored value of a mapped parameter is ignored by Live and is often stale in
generated kits), and resets the rack's `MacroDefaults` to -1. Macro names and
positions stay. Mappings inside nested Instrument or Effect Racks belong to those
racks and are left alone unless `include_nested=True`. Edits are string-level; the
XML is never re-serialised, and the result is verified element by element against
the original.

Why remove mappings rather than re-point them: the Looping surface now owns every
whole-kit gesture as a *virtual macro* that fans out to each pad's parameters by
name (Looping ADR-428). A macro-held parameter is disabled in Live, so the kits must
carry no mappings at all for the surface to write the pads directly.

### 🙈 Hiding the Macro Panel

```python
from ableton_device_creator.core import decode_adg, encode_adg
from ableton_device_creator.macro_mapping import hide_macros, verify_hide

xml = decode_adg("MyKit.adg")
hidden, report = hide_macros(xml)   # no-op unless the root device is a Drum Rack
if report.changed:
    assert verify_hide(xml, hidden, report) == []
    encode_adg(hidden, "MyKit.adg")
```

The cosmetic counterpart to unmapping: on the *root* Drum Rack only, the macro
panel folds away (`AreMacroControlsVisible`) and the custom macro names go back to
`Macro 1`..`Macro 16`. Macro values, positions, mappings, pads and every rack
nested in a pad are untouched, and Instrument Rack presets are skipped entirely.
Use `hide_macros_tree(root, in_place=True)` to sweep a whole library.

### 🎹 Sampler & Simpler

```python
from ableton_device_creator.sampler import SamplerCreator, SimplerCreator

# Create chromatic sampler (maps samples to consecutive notes)
sampler = SamplerCreator()
sampler.from_folder("samples/", layout="chromatic")

# Create Simpler devices (one per sample)
simpler = SimplerCreator()
simpler.from_folder("samples/", output_folder="simplers/")
```

**Layouts:**
- **Chromatic** - Maps samples from C-2 upward
- **Drum** - 8 kicks, 8 snares, 8 hats, 8 perc
- **Percussion** - Maps from C1 upward

### 🛠️ Core Utilities

```python
from ableton_device_creator.core import decode_adg, encode_adg

# Decode ADG to XML for inspection
xml = decode_adg("MyRack.adg")
print(xml[:100])

# Modify XML and re-encode
encode_adg(modified_xml, "MyRack_Modified.adg")
```

---

## CLI Reference

Full CLI documentation: [docs/CLI_GUIDE.md](https://github.com/ben-juodvalkis/Ableton-Device-Creator/blob/main/docs/CLI_GUIDE.md)

### Drum Rack Commands

```bash
# Create drum rack
adc drum-rack create samples/ -o MyKit.adg --layout 808

# Apply colors
adc drum-rack color MyKit.adg

# Remap notes (shift up 1 octave)
adc drum-rack remap MyKit.adg --shift 12

# Remove every macro mapping from every Drum Rack under a folder (writes a parallel tree)
adc drum-rack unmap "Looping Presets/Instruments/Ableton" --dry-run
adc drum-rack unmap "Looping Presets/Instruments/Ableton" \
    --out "Looping Presets/Instruments/Ableton-unmapped" --report unmap.json
```

### Sampler Commands

```bash
# Create chromatic sampler
adc sampler create samples/ --layout chromatic

# Create drum-style sampler
adc sampler create samples/ --layout drum --max-samples 32
```

### Simpler Commands

```bash
# Create Simpler devices (one per sample)
adc simpler create samples/ -o simplers/

# Process recursively
adc simpler create samples/ --recursive
```

### Utility Commands

```bash
# Decode to XML
adc util decode MyRack.adg -o MyRack.xml

# Encode from XML
adc util encode MyRack.xml -o MyRack.adg

# Show device info
adc util info MyRack.adg
```

---

## Project Structure

```
Ableton-Device-Creator/
├── src/ableton_device_creator/    # Python package
│   ├── core/                       # ADG encoder/decoder
│   ├── drum_racks/                 # Drum rack creation
│   ├── sampler/                    # Sampler creation
│   ├── macro_mapping/              # Color, transpose
│   └── cli.py                      # Command-line interface
│
├── examples/                       # Usage examples
│   ├── drum_rack_example.py
│   ├── sampler_example.py
│   └── macro_mapping_example.py
│
├── scripts/                        # Per-library conversion scripts
│   ├── multisample_utils.py        # Shared sampler/velocity helpers
│   └── create_*.py                 # One script per sample library
│
├── templates/                      # Device templates
│   ├── input_rack.adg              # Drum rack template
│   ├── sampler-rack.adg            # Sampler template
│   ├── simpler-template.adv        # Simpler template
│   └── *_donor.adg                 # Donor racks for sample-swap workflows
│
├── docs/                           # Documentation
│   ├── CLI_GUIDE.md                # CLI reference
│   └── current-plan/               # Development docs
│
└── archive-v2-scripts/             # V2 reference code
```

---

## Library Conversion Scripts

`scripts/` holds one script per sample library — the working end of this repo.
Each turns a specific vendor export (SonicCouture, Soundiron, Spitfire, …) into
finished Ableton devices, and encodes what that library's export actually looks
like: its filename convention, its velocity-layer scheme, and its export
glitches.

```bash
# Each script is standalone; most support --plan to preview without writing
python3 scripts/create_electro_acoustic_racks.py --plan
python3 scripts/create_boroughs_racks.py
```

Two conventions matter when adding one:

- **Import flat.** `multisample_utils.py` (shared velocity/pitch-zone helpers)
  is imported bare — `from multisample_utils import ...` — by most scripts, and
  several scripts import each other by module name. The directory is flat on
  purpose; subfolders would break those imports.
- **Report, don't repair.** Vendor exports have gaps (empty folders, zero-frame
  files, missing slots). Surface them as warnings so they can be re-exported —
  never silently drop or interpolate them.

Per-library specifics — source paths, note layouts, known export glitches — are
documented in [CLAUDE.md](https://github.com/ben-juodvalkis/Ableton-Device-Creator/blob/main/CLAUDE.md).

---

## Common Workflows

### Workflow 1: Complete Drum Kit Setup

```bash
# 1. Create drum rack
adc drum-rack create samples/drums/ -o MyKit.adg

# 2. Apply color coding
adc drum-rack color MyKit.adg

# 3. Remap to higher octave (optional)
adc drum-rack remap MyKit.adg --shift 12 -o MyKit_High.adg
```

### Workflow 2: Sampler Library

```python
from ableton_device_creator.sampler import SamplerCreator

creator = SamplerCreator()

# Create samplers for different categories
creator.from_folder("samples/kicks/", output="Kicks_Chromatic.adg")
creator.from_folder("samples/snares/", output="Snares_Chromatic.adg")
creator.from_folder("samples/hats/", output="Hats_Chromatic.adg")
```

### Workflow 3: Batch Processing

```python
from pathlib import Path
from ableton_device_creator.drum_racks import DrumRackCreator

creator = DrumRackCreator()

# Process all subfolders
for folder in Path("samples").iterdir():
    if folder.is_dir():
        creator.from_folder(folder, output=f"output/{folder.name}.adg")
```

---

## API Documentation

### DrumRackCreator

```python
from ableton_device_creator.drum_racks import DrumRackCreator

# Uses the bundled template; pass template="MyTemplate.adg" to use your own
creator = DrumRackCreator()

# Simple mode - fill pads sequentially
rack = creator.from_folder(
    samples_dir="samples/",
    output="MyRack.adg",
    categorize=False
)

# Categorized mode - organize by sample type
rack = creator.from_categorized_folders(
    samples_dir="samples/",
    layout="808",  # or "standard", "percussion"
    output="Categorized.adg"
)
```

### SamplerCreator

```python
from ableton_device_creator.sampler import SamplerCreator

# Uses the bundled template; pass template="MySampler.adg" to use your own
creator = SamplerCreator()

# Chromatic layout (C-2 upward)
sampler = creator.from_folder(
    samples_dir="samples/",
    layout="chromatic",
    samples_per_instrument=32
)

# Drum layout (8 kicks, 8 snares, etc.)
sampler = creator.from_folder(
    samples_dir="samples/",
    layout="drum"
)
```

### SimplerCreator

```python
from ableton_device_creator.sampler import SimplerCreator

# Uses the bundled template; pass template="MySimpler.adv" to use your own
creator = SimplerCreator()

# Batch create (one .adv per sample)
devices = creator.from_folder(
    samples_dir="samples/",
    output_folder="simplers/"
)

# Single device
device = creator.from_sample(
    sample_path="kick.wav",
    output="kick.adv"
)
```

---

## Requirements

- **Python 3.8+**
- **Core:** Zero dependencies (stdlib only)
- **CLI:** `click>=8.0.0` (optional, install with `pip install "ableton-device-creator[cli]"`)
- **Ableton Live 12.1 or later** to open the generated devices (the bundled templates
  were saved in Live 12; the Simpler template needs 12.2 or later)

---

## How It Works

### ADG/ADV File Format

Ableton device files (.adg) and presets (.adv) are **gzipped XML files**:

```
MyRack.adg (55 KB gzipped)
    ↓ decode
MyRack.xml (1.1 MB uncompressed)
    ↓ modify
MyRack_Modified.xml
    ↓ encode
MyRack_Modified.adg (56 KB gzipped)
```

This toolkit:
1. Decompresses .adg/.adv to XML
2. Modifies the XML structure
3. Recompresses to .adg/.adv

---

## Version History

### V3.0.0 (2026-09-27) - first public release

Added since the November 2025 alpha:
- `adc drum-rack unmap`, `hide-macros`, `ungroup`, `auto-select` - batch
  edits to existing kits, each verified against the original file
- `adc sampler thin` and `adc sampler set-env` - lighter multisample racks and
  batch envelope edits
- The default templates ship inside the package, so it works from any folder
- `drum-rack create` deletes the pads it doesn't fill, and categorizes a flat
  folder by filename

**Complete rewrite as modern Python package** (3.0.0-alpha.1, 2025-11-29)

**New:**
- ✅ Installable Python package with pip
- ✅ Clean API with high-level classes
- ✅ CLI tool with 14 commands
- ✅ Comprehensive documentation
- ✅ Production-tested with real samples
- ✅ Type hints throughout
- ✅ Zero core dependencies

**Migrated:**
- 111 V2 scripts → 15 Python classes
- Ad-hoc scripts → Organized modules
- Manual workflows → CLI commands

**Breaking Changes:**
- New import paths (`from ableton_device_creator.drum_racks import ...`)
- Different API (class-based instead of scripts)
- V2 scripts preserved in `archive-v2-scripts/`

### V2.0.0 (2025-11-28)

Production-ready scripts from live performance system (111 scripts).

### V1.0.0

Original proof-of-concept (preserved in `archive-v1/`).

---

## Development

### Running Examples

```bash
# Set PYTHONPATH
export PYTHONPATH=src

# Run examples
python3 examples/drum_rack_example.py
python3 examples/sampler_example.py
python3 examples/cli_demo.py
```

### Testing Philosophy

This project prioritizes **production-proven code** over extensive test coverage:

- **Primary validation:** Manual testing in Ableton Live
- **Production use:** 2+ years in professional live performance
- **Immediate feedback:** Invalid ADG files fail to load in DAW
- **Focus:** Real-world usage over synthetic tests

---

## Documentation

- **[CLI Guide](https://github.com/ben-juodvalkis/Ableton-Device-Creator/blob/main/docs/CLI_GUIDE.md)** - Complete CLI reference
- **[CLAUDE.md](https://github.com/ben-juodvalkis/Ableton-Device-Creator/blob/main/CLAUDE.md)** - Project context for AI assistants
- **[Examples](https://github.com/ben-juodvalkis/Ableton-Device-Creator/tree/main/examples)** - Python API examples
- **[V3 Implementation Plan](https://github.com/ben-juodvalkis/Ableton-Device-Creator/blob/main/docs/current-plan/V3_IMPLEMENTATION_PLAN.md)** - Development roadmap

---

## Contributing

Contributions welcome! Please:

1. Test in Ableton Live (the ultimate validation)
2. Add examples for new features
3. Update documentation
4. Keep zero-dependency policy for core

---

## License

MIT License - see LICENSE file for details.

---

## Acknowledgments

Built for the Ableton Live community with 2+ years of production use.

**Special thanks:**
- Native Instruments for sample libraries that inspired this toolkit
- Ableton community for feedback and use cases
- Claude AI for V3.0 refactoring assistance

---

## Support

- **Issues:** [GitHub Issues](https://github.com/ben-juodvalkis/Ableton-Device-Creator/issues)
- **Discussions:** [GitHub Discussions](https://github.com/ben-juodvalkis/Ableton-Device-Creator/discussions)
- **Documentation:** [docs/](https://github.com/ben-juodvalkis/Ableton-Device-Creator/tree/main/docs)

---

**V3.0 - Built with Python & Claude Code**
