Metadata-Version: 2.3
Name: buildable
Version: 0.1.1
Summary: Combine and edit Ableton Live sets (.als files).
Project-URL: Documentation, https://github.com/kmontag/buildable#readme
Project-URL: Issues, https://github.com/kmontag/buildable/issues
Project-URL: Source, https://github.com/kmontag/buildable
Author-email: Kevin Montag <kmontag@cs.stanford.edu>
License-Expression: MIT
License-File: LICENSE.txt
Keywords: ableton,live
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python
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 :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=3.8
Requires-Dist: lxml~=5.2.2
Description-Content-Type: text/markdown

# buildable

[![PyPI - Version](https://img.shields.io/pypi/v/buildable.svg)](https://pypi.org/project/buildable)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/buildable.svg)](https://pypi.org/project/buildable)
![Test & Release](https://github.com/kmontag/buildable/actions/workflows/test_and_release.yml/badge.svg?branch=main)
[![codecov](https://codecov.io/github/kmontag/alpax/graph/badge.svg?token=5C1JO6YTDL)](https://codecov.io/github/kmontag/buildable)

---

`buildable` allows you to edit and extend Ableton Live sets programmatically. For example, you could
have a single set that stores your common return tracks, and use `buildable` to add them to various
template sets.

Currently you can:

- copy tracks/returns from other sets.
- delete and re-order tracks/returns.
- add/edit key mappings for many set elements.

## Installation

```console
pip install buildable
```

## Usage

For example, you could create a project containing set components that you want to mix together, and
generate templates from them with something like:

```python
from buildable import LiveSet

# Template bases containing e.g. MIDI/audio tracks.
jam_session = LiveSet.from_file('jam-session-tracks.als')
composition = LiveSet.from_file('composition-tracks.als')

# Shared main track and return tracks to be copied to the templates.
shared_structure = LiveSet.from_file('shared-structure.als')

for template_set in (jam_session, composition):
    # Copy returns and main track from the shared set.
    template_set.insert_return_tracks(shared_returns.return_tracks)
    template_set.main_track = shared_main.main_track

    # Assign tap tempo to key "p".
    template_set.transport.tap_tempo_key_midi.persistent_key_string = "p"

# Assign crossfader to the mod wheel on MIDI channel 1.
jam_session.main_track.key_midi_crossfade_equal.channel = 0
jam_session.main_track.key_midi.crossfade_equal.note_or_controller = 1

jam_session.write_to_file("/path/to/user-library/Templates/JamSession.als")
composition.write_to_file("/path/to/user-library/Templates/Composition.als")
```

## Design

Live sets are represented as XML documents, and the `buildable` API mirrors the native document structure
as closely as possible. This helps with flexibility and robustness, but comes with some caveats:

- spelling mistakes and naming inconsistencies are carried over from the native format.
- some simple operations require using relatively complex accessors - for example, key/MIDI mappings
  for sends are accessed using
  e.g. `live_set.primary_tracks[0].device_chain.mixer.sends.track_send_holders[0].send.key_midi`.
- `buildable` won't stop you from setting values that are semantically valid, but invalid at
  runtime.

The best way to familiarize yourself with the native structure is to examine existing Live sets
(using e.g. `gunzip -c my-set.als`) and/or look through the `buildable` source code.
