diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-14 18:06:24 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-14 18:06:24 +0100 |
| commit | e9dde3cea39e69d6188a7f49034f6d95e4c8b6b4 (patch) | |
| tree | b3b383eff5f0d1d18bdbb781c331e6a31fcb25a7 /doc | |
| parent | b4c901700de0d9e867b9fd0c0c6a6586578f8480 (diff) | |
feat(tracker): add sample offset and humanization
Implements two tracker realism features:
1. Sample Offset (compile-time):
- Add offset_sec field to NoteParams and Sample structs
- Parse OFFSET parameter in SAMPLE directive
- Apply timing shift during compilation (zero runtime cost)
- Use for attack-heavy samples to align perceived beat
2. Humanization (runtime, deterministic):
- Add humanize_seed, timing_variation_pct, volume_variation_pct to TrackerScore
- Parse HUMANIZE directive with SEED/TIMING/VOLUME params
- Apply per-event RNG jitter using std::minstd_rand
- Deterministic: same seed produces identical output
Both features work in real-time playback and WAV export.
Test file: data/test_humanize.track
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/TRACKER.md | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/doc/TRACKER.md b/doc/TRACKER.md index 5cb59de..dc77976 100644 --- a/doc/TRACKER.md +++ b/doc/TRACKER.md @@ -18,16 +18,22 @@ Patterns are BPM-independent. Changing BPM only affects playback speed. ``` # Comments start with # -BPM <tempo> # Optional, defaults to 120 BPM +BPM <tempo> # Optional, defaults to 120 BPM +HUMANIZE SEED <int> TIMING <pct> VOLUME <pct> # Optional humanization -SAMPLE <name> [OFFSET <sec>] [VOL <volume>] # Define sample with optional offset/volume +# Generated samples: +SAMPLE <name>, <freq>, <dur>, <amp>, <attack>, <harmonics>, <decay> [OFFSET <sec>] -PATTERN <name> LENGTH <duration> # Define pattern with unit-less duration - <unit_time>, <sample>, <volume>, <pan> # Pattern events +# Asset samples: +SAMPLE <asset_id> [OFFSET <sec>] # ASSET_* from assets.txt -HUMANIZE SEED <int> TIMING <pct> VOLUME <pct> # Optional humanization params +# Auto-generated notes (no SAMPLE declaration needed): +# NOTE_C4, NOTE_A#3, NOTE_Eb2, etc. -SCORE # Score section (pattern triggers) +PATTERN <name> [LENGTH <duration>] # Defaults to LENGTH 1.0 + <unit_time>, <sample>, <volume>, <pan> + +SCORE <unit_time>, <pattern_name> ``` @@ -74,26 +80,27 @@ PATTERN short_fill LENGTH 0.5 # 2 beats = 1 second at 120 BPM ### Sample Offset -Samples can specify an intrinsic offset (time-shift left): +Intrinsic timing offset per sample (compile-time): ``` -SAMPLE ASSET_KICK_1 OFFSET 0.05 VOL 1.2 +SAMPLE ASSET_KICK_1 OFFSET 0.01 # Trigger 10ms earlier (attack compensation) +SAMPLE bass, 80, 0.5, 1.0, 0.02, 3, 0.6 OFFSET 0.005 ``` -- **OFFSET**: Seconds to shift trigger earlier (preserves beat sync) -- **VOL**: Default volume multiplier for this sample +- Shifts sample trigger earlier while preserving beat sync +- Applied at compile-time (zero runtime cost) +- Use for attack-heavy samples to align perceived beat ### Humanization -Add per-note timing/volume variation for realistic playback: +Per-note timing/volume variation (runtime, deterministic): ``` -HUMANIZE SEED 42 TIMING 2.0 VOLUME 5.0 +HUMANIZE SEED 42 TIMING 5.0 VOLUME 10.0 ``` -- **SEED**: Random seed for reproducibility -- **TIMING**: Timing variation (% of beat duration) -- **VOLUME**: Volume variation (% of event volume) - -Applied per-note, baked into WAV export. +- **SEED**: Deterministic RNG seed (reproducible across runs) +- **TIMING**: ±% jitter of beat duration +- **VOLUME**: ±% variation of event volume +- Identical in real-time playback and WAV export --- |
