Files
recipes/PRIMITIVES.md
gilesb 2560190e06 Update recipes to use IPFS CIDs
- Change :hash to :cid throughout
- Update cat asset: QmXrj6tSSn1vQXxxEY2Tyoudvt4CeeqR9gGQwSt7WFrhMZ
- Update dog effect: QmT99H4MC5p18MGuxAeKGeXD71cGCzMNRxFfvt4FuCwpn6
- Update invert effect: QmPWaW5E5WFrmDjT6w8enqvtJhM8c5jvQu7XN1doHA3Z7J

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 08:39:38 +00:00

150 lines
4.9 KiB
Markdown

# Art DAG Primitive Language
## Overview
Primitives enable declarative composition of audio-reactive video. The key insight: **data flows alongside media**.
```
audio → ANALYZE → data → BIND/MAP/COMPUTE → parameters → TRANSFORM → video
```
## Two Types of Flow
| Flow | Examples | Description |
|------|----------|-------------|
| **Media** | video, audio files | Actual content that gets transformed |
| **Data** | beat times, tempo, energy envelope | Analysis results that drive parameters |
## Primitives
### Source Primitives
| Primitive | Status | Description |
|-----------|--------|-------------|
| `SOURCE` | ✅ Implemented | Load single media file |
| `SOURCE_LIST` | ❌ Not implemented | Collect multiple inputs into a list |
| `PARAM` | ❌ Not implemented | Recipe parameter (data, not media) |
### Analysis Primitives
| Primitive | Status | Description |
|-----------|--------|-------------|
| `ANALYZE` | ❌ Not implemented | Extract features from media |
**ANALYZE features:**
| Feature | Output | Description |
|---------|--------|-------------|
| `beats` | `{beat_times: [], tempo: float}` | Beat positions |
| `downbeats` | `{downbeat_times: []}` | First beat of each bar |
| `tempo` | `{bpm: float, confidence: float}` | Tempo detection |
| `energy` | `{envelope: [{time, value}...]}` | Loudness over time |
| `spectrum` | `{bass: [], mid: [], high: []}` | Frequency bands over time |
| `onsets` | `{onset_times: []}` | Note/sound starts |
| `motion_tempo` | `{motion_bpm: float}` | Video motion periodicity |
### Data Processing Primitives
| Primitive | Status | Description |
|-----------|--------|-------------|
| `GROUP` | ❌ Not implemented | Chunk data (e.g., beats → measures) |
| `COMPUTE` | ❌ Not implemented | Arithmetic/expressions on data |
| `SELECT` | ❌ Not implemented | Conditional data selection |
| `BIND` | ❌ Not implemented | Map data ranges to parameter ranges |
**BIND example:**
```yaml
- source: energy.envelope # 0.0 → 1.0
target: saturation # mapped to 1.0 → 2.0
range: [1.0, 2.0]
attack_ms: 10 # response shaping
release_ms: 100
```
### Iteration Primitives
| Primitive | Status | Description |
|-----------|--------|-------------|
| `MAP` | ❌ Not implemented | Apply operation to each item in list |
| `RANDOM_SLICE` | ❌ Not implemented | Extract random segment from random pool item |
| `SEGMENT_AT` | ❌ Not implemented | Cut media at specified times |
**MAP operations:**
- `ANALYZE` - analyze each item
- `TRANSFORM` - apply effects to each item
- `COMPUTE` - calculate value for each item
- `RANDOM_SLICE` - extract random segment for each item
### Transform Primitives
| Primitive | Status | Description |
|-----------|--------|-------------|
| `SEGMENT` | ✅ Implemented | Extract time range |
| `RESIZE` | ✅ Implemented | Scale/crop/pad |
| `TRANSFORM` | ✅ Implemented | Static effects (color, blur, speed) |
| `TRANSFORM_DYNAMIC` | ❌ Not implemented | Time-varying effects from BIND |
### Compose Primitives
| Primitive | Status | Description |
|-----------|--------|-------------|
| `SEQUENCE` | ✅ Implemented | Concatenate in time |
| `LAYER` | ✅ Implemented | Stack spatially |
| `MUX` | ✅ Implemented | Combine video + audio |
| `BLEND` | ✅ Implemented | Blend two inputs |
## Patterns
### Pattern 1: Beat-Synced Cuts
```
music → ANALYZE(beats) → GROUP(4) → MAP(RANDOM_SLICE, videos) → SEQUENCE → MUX(music)
```
Audio drives cut timing, videos provide content.
### Pattern 2: Energy-Reactive Effects
```
music → ANALYZE(energy) → BIND(saturation, brightness) → TRANSFORM_DYNAMIC(video) → MUX
```
Audio amplitude drives visual intensity.
### Pattern 3: Tempo Matching
```
music → ANALYZE(tempo) ─┐
├→ COMPUTE(speed_factor) → TRANSFORM(speed) → SEQUENCE
videos → MAP(ANALYZE(motion_tempo)) ─┘
```
Video speed adjusted to match audio tempo.
### Pattern 4: Spectrum-Driven Layers
```
music → ANALYZE(spectrum) → BIND(bass→layer1_opacity, high→layer2_opacity)
video1 ────────────────────→ LAYER ← video2
```
Different frequency bands control different visual layers.
## Design Principles
1. **Separation of concerns**: ANALYZE extracts data, BIND maps it, TRANSFORM applies it
2. **Composability**: Small primitives combine into complex behaviors
3. **Declarative**: Describe *what* you want, not *how* to compute it
4. **Reproducibility**: Seeds and deterministic operations ensure same inputs → same output
5. **Data as first-class**: Analysis results flow through the DAG like media
## Implementation Priority
1. `ANALYZE` (beats, energy, tempo) - foundation for audio-reactive
2. `BIND` - connects analysis to effects
3. `TRANSFORM_DYNAMIC` - applies time-varying effects
4. `MAP` - enables iteration over lists
5. `SOURCE_LIST` - multiple input handling
6. `GROUP`, `COMPUTE`, `SELECT` - data manipulation