@hraness/dawg 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/DAWG.md +551 -33
  3. package/README.md +4 -4
  4. package/core/chords.ts +288 -7
  5. package/core/diff.ts +41 -12
  6. package/core/expression.ts +1241 -0
  7. package/core/fx.ts +437 -2
  8. package/core/granular.ts +528 -0
  9. package/core/instruments.ts +281 -0
  10. package/core/keys.ts +386 -0
  11. package/core/loop.ts +23 -0
  12. package/core/master.ts +455 -0
  13. package/core/midi.ts +452 -0
  14. package/core/resonators.ts +574 -0
  15. package/core/rhythm.ts +7 -2
  16. package/core/score.ts +717 -62
  17. package/core/sdk/eval-child.ts +40 -3
  18. package/core/sdk/print.ts +614 -27
  19. package/core/sdk/sync-instruments.ts +58 -0
  20. package/core/sdk/v1.ts +2824 -45
  21. package/core/sections.ts +2072 -0
  22. package/core/strings.ts +845 -0
  23. package/core/synth.ts +11 -1
  24. package/core/tempo.ts +1318 -0
  25. package/core/tuning.ts +1180 -0
  26. package/guides/audition.md +26 -0
  27. package/guides/automation.md +26 -0
  28. package/guides/chords.md +28 -0
  29. package/guides/effects.md +29 -0
  30. package/guides/faders.md +29 -0
  31. package/guides/files.md +28 -0
  32. package/guides/getting-started.md +26 -0
  33. package/guides/index.ts +75 -0
  34. package/guides/keys.md +27 -0
  35. package/guides/media.md +27 -0
  36. package/guides/mix.md +23 -0
  37. package/guides/music.md +14 -0
  38. package/guides/notes.md +26 -0
  39. package/guides/performance.md +26 -0
  40. package/guides/play.md +24 -0
  41. package/guides/project.md +13 -0
  42. package/guides/providers.md +25 -0
  43. package/guides/rhythm.md +26 -0
  44. package/guides/sessions.md +21 -0
  45. package/guides/sound.md +15 -0
  46. package/guides/sounds.md +29 -0
  47. package/guides/tempo.md +27 -0
  48. package/guides/tracks.md +25 -0
  49. package/guides/web-search.md +21 -0
  50. package/package.json +3 -1
  51. package/src/agent/agent.ts +9 -0
  52. package/src/agent/brief.ts +77 -3
  53. package/src/agent/chord-tools.ts +9 -1
  54. package/src/agent/expression-tools.ts +336 -0
  55. package/src/agent/granular-tools.ts +138 -0
  56. package/src/agent/master-tools.ts +299 -0
  57. package/src/agent/models.ts +4 -4
  58. package/src/agent/ops.ts +68 -6
  59. package/src/agent/planner.ts +45 -2
  60. package/src/agent/preview-tool.ts +27 -4
  61. package/src/agent/section-tools.ts +411 -0
  62. package/src/agent/time-tools.ts +290 -0
  63. package/src/agent/tools.ts +574 -16
  64. package/src/agent/tuning-tools.ts +301 -0
  65. package/src/agent/xcb-agent.ts +9 -0
  66. package/src/audio/arrange.ts +489 -0
  67. package/src/audio/audition.ts +16 -3
  68. package/src/audio/click.ts +113 -1
  69. package/src/audio/clock.ts +71 -5
  70. package/src/audio/dsp/bank.ts +233 -0
  71. package/src/audio/dsp/fft.ts +6 -0
  72. package/src/audio/dsp/filters.ts +57 -0
  73. package/src/audio/dsp/interp.ts +112 -0
  74. package/src/audio/dsp/modal.ts +684 -0
  75. package/src/audio/dsp/onset.ts +197 -0
  76. package/src/audio/dsp/oversample.ts +202 -0
  77. package/src/audio/dsp/rng.ts +37 -0
  78. package/src/audio/dsp/shape.ts +81 -0
  79. package/src/audio/dsp/stft.ts +73 -0
  80. package/src/audio/dsp/window.ts +77 -0
  81. package/src/audio/effects/bus.ts +5 -4
  82. package/src/audio/effects/chain.ts +6 -1
  83. package/src/audio/effects/common.ts +30 -1
  84. package/src/audio/effects/dynamics.ts +2 -1
  85. package/src/audio/effects/filter.ts +5 -3
  86. package/src/audio/effects/modulation.ts +5 -1
  87. package/src/audio/effects/rig/cab.ts +99 -0
  88. package/src/audio/effects/rig/filters.ts +152 -0
  89. package/src/audio/effects/rig/gate.ts +39 -0
  90. package/src/audio/effects/rig/head.ts +487 -0
  91. package/src/audio/effects/rig/index.ts +170 -0
  92. package/src/audio/effects/rig/section.ts +78 -0
  93. package/src/audio/effects/rig/stomp.ts +238 -0
  94. package/src/audio/effects/space.ts +92 -2
  95. package/src/audio/engine.ts +100 -21
  96. package/src/audio/fit.ts +402 -0
  97. package/src/audio/granular.ts +664 -0
  98. package/src/audio/instrument-check.ts +133 -0
  99. package/src/audio/instruments.ts +111 -0
  100. package/src/audio/keys/dsp.ts +323 -0
  101. package/src/audio/keys/engine.ts +361 -0
  102. package/src/audio/keys/piano.ts +432 -0
  103. package/src/audio/live-worker.ts +54 -0
  104. package/src/audio/live.ts +263 -17
  105. package/src/audio/loudness.ts +596 -0
  106. package/src/audio/master.ts +660 -0
  107. package/src/audio/measure-worker.ts +45 -0
  108. package/src/audio/measure.ts +110 -0
  109. package/src/audio/player.ts +11 -6
  110. package/src/audio/preview.ts +76 -14
  111. package/src/audio/render-worker.ts +6 -1
  112. package/src/audio/renderer.ts +7 -1
  113. package/src/audio/resonators.ts +287 -0
  114. package/src/audio/sampler.ts +269 -34
  115. package/src/audio/samples.ts +30 -7
  116. package/src/audio/strings/body.ts +250 -0
  117. package/src/audio/strings/engine.ts +369 -0
  118. package/src/audio/strings/loop.ts +119 -0
  119. package/src/audio/strings/measure.test-helpers.ts +198 -0
  120. package/src/audio/strings/pluck.ts +354 -0
  121. package/src/audio/synth/voice.ts +60 -13
  122. package/src/audio/synth/zzfx.ts +10 -4
  123. package/src/audio/warp.ts +147 -0
  124. package/src/audio/wav.ts +377 -30
  125. package/src/commands/arrange.ts +949 -0
  126. package/src/commands/expression.ts +941 -0
  127. package/src/commands/fit.ts +135 -0
  128. package/src/commands/fx.ts +31 -0
  129. package/src/commands/granular.ts +427 -0
  130. package/src/commands/help.ts +355 -27
  131. package/src/commands/keys.ts +353 -0
  132. package/src/commands/master.ts +361 -0
  133. package/src/commands/modal.ts +247 -0
  134. package/src/commands/music.ts +6 -1
  135. package/src/commands/rig.ts +260 -0
  136. package/src/commands/sample.ts +3 -0
  137. package/src/commands/string.ts +175 -0
  138. package/src/commands/synth.ts +11 -1
  139. package/src/commands/time.ts +967 -0
  140. package/src/commands/tuning.ts +490 -0
  141. package/src/main.ts +919 -41
  142. package/src/project/check.ts +13 -0
  143. package/src/render.ts +139 -8
  144. package/src/session/daemon.ts +18 -8
  145. package/src/session/naming.ts +8 -1
  146. package/src/session/rebase.ts +21 -0
  147. package/src/tui/arrange-menu.ts +390 -0
  148. package/src/tui/audition.ts +38 -5
  149. package/src/tui/fader.ts +409 -0
  150. package/src/tui/granular-menu.ts +278 -0
  151. package/src/tui/menu-time.ts +401 -0
  152. package/src/tui/menu.ts +967 -23
  153. package/src/tui/modal-menu.ts +118 -0
  154. package/src/tui/performance-menu.ts +235 -0
  155. package/src/tui/play-chords.ts +3 -1
  156. package/src/tui/play-mode.ts +150 -6
  157. package/src/tui/play-session.ts +459 -43
  158. package/tui/app.ts +262 -13
  159. package/tui/arrange-strip.ts +174 -0
  160. package/tui/drawer.ts +478 -0
  161. package/tui/grammar.ts +63 -1
  162. package/tui/guide.ts +351 -0
  163. package/tui/highway.ts +87 -4
  164. package/tui/hits.ts +68 -0
  165. package/tui/input.ts +7 -0
  166. package/tui/keys.ts +72 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,105 @@ All notable changes to dawg are recorded here. Versions follow [semantic version
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.6.0
8
+
9
+ Instruments: plucked strings, mallets and bells, a modelled piano, granular clouds, fitting samples to the tempo map, and a guitar rig, all built on the 0.5 foundations. Every new field is optional, so 0.4 and 0.5 projects load, print and render byte-identically.
10
+
11
+ ### Added
12
+
13
+ - **Fitting samples to the song.** Sampler voices take `bpm` (their own tempo) or `len` (beats), and follow the song's tempo map, ramps included. `fitmode` picks how: `repitch` (tape, the default), `beats` (onset slices placed on time, hits stay sharp) or `tones` (phase-vocoder stretch, pitch kept). `/bpm 174`, `/len 16`, `/fitmode beats` (or `/fitmode auto`, which listens and suggests), the Sound menu's sample rows, the agent's `fit_sample` tool, and `sample(path, { bpm, fitmode, len })` in the SDK. Only the frames a note can reach are fitted. In play mode a fit up to 8 s (source or output) is computed at once; longer ones say "fitting" until ready, then "fit ready". A bare `bpm <n>` stays the song tempo. SDK 1.20.0 (additive).
14
+ - **Plucked strings.** A physical string model with 22 presets: nylon, steel, electric and 12-string (`jangle`) guitars, electric, slap, upright and Motown bass, sitar and tanpura with jawari buzz and sympathetic strings, harpsichord, lute, oud, setar, tar, santur, hammered dulcimer, koto, harp, banjo, tres and requinto. Strings follow tunings, bends and articulations; `string sitar`, `string buzz 0.8`, Sound › browse sounds › Strings, the `set_string` agent tool and `stringed()` in the SDK (1.21.0). Legacy instrument words keep their tone.
15
+ - **Guitar rig.** Three new effects after `distort`: a `stomp` box (fuzz, face, od, rat, octave), an amp `head` (clean, chime, crunch, lead, high, solid, bass) with Yeh–Smith tone stacks, power-amp sag, calibrated makeup gain and an optional noise `gate`, and a speaker `cab` (1x12, 2x12, 4x12, 1x10, open, 8x10, 1x15, di). Oversampled and antialiased: aliases of a 1 kHz fuzz stay at or below -60 dB. `rig <preset>` loads a whole rig (clean crunch punk ragged lead metal fuzz octave funk wah bachata spring bassdrive reese jangle alt); `stomp`, `head` and `cab` edit one stage; `fx amp` points to `head` (amp stays Strudel gain). Menu Effects › Guitar rig, agent tool `set_rig`, SDK `rig()` (1.22.0). Stomps are level-matched to bypass, so switching rigs keeps the level; a rig's companion effects (funk's envelope filter, jangle's compressor) leave with it. Track words `jangle punk funk ragged gtr-lead gtr-metal bachata` make a guitar track (the strings `electric` voice, `12string` for jangle) with that rig from the prompt, the agent and the SDK. Play mode sounds the first 0.75 s of a rig note at once and renders the rest in the background. Projects without a rig render byte-identically.
16
+ - **Granular instrument.** `grain cloud` turns any pitched track into a seeded, deterministic grain cloud of its own sound (a synth or a sampler voice; `synth:pad` with nothing loaded), with eight presets (`cloud hold sparkle swarm stutter microloop backwards dust`) and short parameters (`pos scan grain overlap jitter spray pitch detune shimmer spread window reverse freeze drift`…). Grains read a shared band-limited semitone bank (`src/audio/dsp/bank.ts`, 64 MB cap) with window tables in `src/audio/dsp/window.ts`: within 1 cent, alias-free upward, under 10 ms cold note-on and 7 ms per voice-second. Reachable as `grain …` and `track cloud`, Sound › granular and Sound › browse sounds › Granular, the `set_granular` agent tool and `granular()` in the SDK (1.23.0). Notes keep sounding through `release` after note-off, the built-in synth sources are held seamless loops of the track's own synth sound, and `grain off` restores the voice the track had (`granular.from`).
17
+ - **A modelled piano.** `piano` (or `grand`, `upright`, `felt`, `honkytonk`, `prepared`, and the presets `ballad` and `lofi`) puts a built-in physical piano on the focused track: felt hammers, stretched inharmonic three-string unisons with a two-stage decay, a soundboard knock, dampers and the sustain pedal, in any tuning. `keys hardness 0.3`, `keys decay 1.5`, `keys preset lofi` and `keys reset` shape it, `keys-<param>` lanes automate it, the menu has it under Sound > browse sounds > Keys and Sound > Keys, the agent has `set_keys`, and the SDK takes `track({ instrument: "grand", keys: { ... } })` (SDK 1.24.0). A project stored with `instrument: "piano"` keeps its old tone; only new writes of the word choose the modelled grand. A preset's effects (the lofi filter and crush, the ballad and felt rooms) come with the word on every surface, including `song.ts`, and leave again when you switch presets or `keys reset`. In play mode a released key damps as the real damper would (a short tail low down, none from F6 up).
18
+ - **Mallets and bells.** A modal resonator engine with 12 presets: marimba, vibes, xylophone, glock, celesta, chimes, kalimba, mbira, steelpan, bowl, gong and timpani (aliases vibraphone, glockenspiel, tubular, thumbpiano, gongageng, steeldrum, singingbowl, kettledrum, tubularbells). Mallet, hardness, strike position, ring, tilt, damping, vibraphone motor, ombak beating, buzz, click and a strike glide; `modal-<param>` automation lanes; tunings, cents, bends, articulation, pedal, velocity curves, humanize and the tempo map apply. Reach it with `modal <preset>`, `modal <param> <value>`, the menu's Sound › browse sounds › Mallets and bells, the agent's `set_modal` tool, or `modal()` in the SDK (1.25.0). Plain `marimba` keeps its old tone and `dawg check` points to the new one.
19
+
20
+ ### Fixed
21
+
22
+ - **Long songs keep sounding.** A song without sections whose tracks use `time` (cycle or rate) now renders all of its windows instead of going silent after 20 s, and a long phasing arrangement with sections no longer fails at the 4096-note score limit while baking; `dawg check` warns when an arrangement bakes more notes than that, and a render error is one line.
23
+ - **Unknown instrument words are caught.** `dawg check` warns about an instrument word that names no voice (`violin`, `clav`) with the nearest real one, and the `instrument` command refuses it with a suggestion instead of playing a sine.
24
+ - **Quieter voice steals.** A stolen modal voice fades over 80 ms with a raised cosine, so long gong and kempul tails no longer click.
25
+ - **Beat fitting on the grid.** `fitmode beats` places each slice start at the hit's transient, within 2 ms of the grid after a 174 to 128 BPM fit.
26
+ - **True peak.** The meter and the master limiter check seven inter-sample phases evenly, so a peak between samples is no longer under-read by about 0.2 dB.
27
+ - **Missing samples fail the render.** A sample that cannot load (a pin mismatch, an offline pack) makes `dawg render` exit with an error instead of writing a song with the voice missing.
28
+ - **Strings in tune.** Harpsichord and other unison courses centre their seeded detune on the tuning table, per key, so the course sits on pitch and level is flat across velocity.
29
+ - **Granular cost.** The grain bank looks chunks up without string keys; a 16-voice swarm costs about 4 ms per voice-second at 48 kHz.
30
+ - **Smaller fixes.** `pedal half` receipts count half pedals, `modal saron` (or any body word) sets the body, `fx wobble` and `grain src bus:…` answer locally instead of going to the agent, and a tempo point past the song end says `bars <n>` extends it. DAWG.md says when exports run at 48 kHz.
31
+
32
+ ### Internal
33
+
34
+ - **0.6 instrument plumbing.** Shared DSP primitives under `src/audio/dsp/` (counter-based seeded randomness, Hermite reads and a Thiran fractional delay, half-band 2x/4x oversampling, antiderivative-antialiased shapers, DC blocker and one-pole), an instrument engine registry (`src/audio/instruments.ts`) consulted by renders, the stem cache and live play, and one instrument word resolver (`core/instruments.ts`, copied into the SDK) used by the `instrument` prompt, `set_instrument` and `track()`. Nothing is registered yet, so every project sounds and prints exactly as before.
35
+
36
+ ## 0.5.0
37
+
38
+ Foundations: tunings and microtones, expressive performance, tempo maps and phasing, song sections, and a master bus with loudness metering. Every new field is optional, so 0.4 projects load, print and render byte-identically.
39
+
40
+ ### Integration fixes
41
+
42
+ - **Renders cover the whole song.** `dawg render` no longer stops at 30 s for a song without a form or for `--section`; long songs render in windows up to 15 minutes, and a note held across a window seam is crossfaded so long drones stay smooth.
43
+ - **Exports keep more of the song.** WAV renders carry a `cue ` point and `LIST adtl` label at each section start; MIDI exports write FF 06 section markers, the tuning as MIDI Tuning Standard SysEx, and glides, bends, vibrato and cents as pitch bend on lone notes.
44
+ - **Forms keep tempo ramps** that cross a section boundary, and sections work in a compound meter held from bar 1 (6/8, 12/8).
45
+ - `/export name.wav` refuses and points to `dawg render` instead of writing loop JSON under a `.wav` name.
46
+ - Play mode starts in single notes on tracks in a non-12 tuning and on mono glide tracks, instead of auto chords in an assumed C major.
47
+ - True peak uses a 32-tap windowed-sinc interpolator instead of the BS.1770-4 example filter, which read dense, bright masters up to half a dB low; the limiter now holds its ceiling on supersaws and distortion.
48
+ - The `acid` preset slides (60 ms legato glide); expression commands take a `last` target; `tuning root C` takes a bare pitch class; `/track piano b` accepts a name with spaces; a song in a named tuning is auto-named after it instead of a guessed 12-TET key.
49
+ - `fermata at end` holds the last felt beat in compound meters; a meter change that pushes notes or fermatas past the song end says so; the menu's song length names the written end tempo; the SDK accepts a `rit()` that ends where `aTempo()` starts or at the final barline.
50
+
51
+ ### Guides
52
+
53
+ - **Short guides for every feature, in the app and on dawg.sh.** `/guide` (or F1) opens a tree of one-page guides (getting started, tracks, notes, play mode, chords, rhythm, sounds, effects, automation, mix, the menu and audition loop, media tools, project files, sessions, providers, web search, keys, tempo and meter). Each fits one pane at 80 columns and shows both what to ask the agent and the command, key or menu path that does it by hand. ↑↓ move, → expand or open, ← back, `/` filter, Esc close. The same Markdown files (`guides/*.md`, shipped in the package) are the docs on dawg.sh.
54
+
55
+ ### Tempo and meter
56
+
57
+ - **Tempo maps.** `tempo 90 at bar 9` steps the tempo; `ramp` or `exp` glides into it (linear or equal-ratio per beat). `rit 4 bars to 80` and `accel 8 bars to 174 at bar 9` write a ritardando or accelerando (75% / 133% over the last 2 bars by default). `a tempo` and `tempo primo` step back. `tempo map` lists the changes. Stored as the optional song `time.tempo`; `tempoBpm` stays the start tempo.
58
+ - **Fermatas.** `fermata at 31 2` holds a beat (the dotted quarter in 6/8) for 2 extra beats: that beat slows evenly to three times its length, in the WAV and the MIDI export alike. A held beat lasts at most 16.777 s, the slowest tempo a MIDI file can write.
59
+ - **Meter changes.** `meter 7/8 at bar 5` changes the meter on a bar line. The click, count-in, highway bar lines and numbers, and play-mode bar erase follow it.
60
+ - **Polytempo, polymeter and phasing.** `track rate 3/2`, `track phase 0.5`, `track cycle 3` and `track phasing 4 [over 16]` give a track its own tempo ratio, offset and loop length, so two identical loops drift apart and realign, as in Reich's _Come Out_. `track phasing 3 hold 8` steps instead: hold in step, move a sixteenth ahead, hold again, as in _Piano Phase_.
61
+ - **One time map everywhere.** Ticks stay score time; the offline renderer, live engine and audition loop, transport clock, click and count-in, recording and the highway convert through the same map.
62
+ - **MIDI export.** `/export song.mid` and `dawg render song.mid` write a Standard MIDI File with tempo and time-signature meta events; ramps become sixteenth-note tempo steps that land on the same seconds as the WAV.
63
+ - **Menu, agent and SDK.** Project › Tempo & meter (`/menu tempo`), the agent's `set_time` tool, and SDK 1.14.0 `tempo`, `ramp`, `rit`, `accel`, `fermata`, `meter` and `phasing`, plus SDK 1.19.0 `aTempo`, `tempoPrimo` and `stepPhasing`; `song()` refuses marks past the song end and checks rit/accel direction and fermata length. Projects without these fields load, print and render byte-identically.
64
+
65
+ ### Performance and expression
66
+
67
+ - **Articulations.** `art staccato|legato|accent|tenuto|marcato|ghost [target]` sets how notes are played: staccato half length, legato held into the next note, accent and marcato louder, tenuto full length, ghost quiet and short. Targets are `all`, `bar 3`, `bars 2-4` or note ids.
68
+ - **Glide and portamento.** `glide 60ms` on a track slides like a TB-303 (`legato`: one voice, slides only between overlapping notes, no envelope retrigger), or always (`mono`), or per voice (`poly`); `glide 60ms bar 2` sets it per note (a bare number is ms; the SDK's `glide` is seconds). A glide cut off by the next note continues from the pitch it reached, and on a legato track a note with its own glide slides from a note that ends at most a 16th step earlier (the TB-303 slide, set on the destination note); a slide never bridges a longer rest. Mono and legato glides approach the pitch exponentially, like an analog portamento; poly glides stay linear. `glide 0` turns glide off, and a bare decimal below 1 (`glide 0.06`) is rejected with a hint (`60ms` or `0.06s`). A chain is accented when any of its notes is.
69
+ - **Pitch bends and vibrato per note.** `bend scoop|fall|doit|-200|0:-200 0.25:0` draws a pitch curve in cents over the note; `vibrato 5.5 30 0.2` adds rate, depth and delay. A note's settings override the track's synth `vib`, `penv` and `slide`. Bends follow the note's articulated length, not the pedal or humanize. New synth param `faccent` (0..4 octaves) opens the low-pass envelope on accent and marcato notes and shortens its decay, the TB-303 accent; the `acid` preset sets 1.5.
70
+ - **Sustain pedal.** `pedal 0-3.5 4-7.5` (beats), `pedal bars` (re-pedals each downbeat on the meter map, replacing the lane; `pedal bars 2-3` adds bars) or `pedal down|half|up <beat>` hold synth, wavetable and sampler notes until the pedal lifts; `half` lets them fade. In play mode, `Tab` and Shift sustain now record as pedal events, and notes keep the length the key was held; a pedal held across the loop seam stays down at the loop start, a take whose bar fails to record is kept, and bare `pedal` lists the track's pedal events.
71
+ - **Velocity curves and humanize.** `velcurve soft|hard|fixed [v]` shapes velocity per track; `humanize 8 5 10 seed 3` adds seeded timing (ms), velocity and length (%) variation at render, so the score stays as written and every render of a take is identical (`humanize reseed` for a new take). Humanize never turns a chord into a glide: chords, the mono line and glides are decided on written positions. A note can carry its own humanize amounts, so the agent's `set_expression` and the SDK's `note(..., { humanize: { timing: 10 } })` humanize just a range (`{}` keeps a note exact), and so does `humanize 20 8 bars 2-3` (`humanize exact <target>` keeps notes exact, `humanize off <target>` clears them). `velcurve fixed` takes 0..1.
72
+ - **Everywhere.** The menu has **Sound › performance** (staged with A/B in the audition loop) and `/guide` has a performance guide; the agent has `set_expression` and `set_performance` over note ids or beat ranges; the SDK (1.15.0) takes `note(..., { art, glide, bend, vibrato, humanize })`, `expr(notes, {...})` and `track({ glide, pedal, velocityCurve, humanize })`. Bar targets follow the meter map. MIDI export writes the performed notes (articulation, humanize, velocity curve, mono voicing) and the pedal as CC64; glide, bend and vibrato are not exported. Projects without these fields load, print and render byte-identically.
73
+
74
+ ### Tunings and scales
75
+
76
+ - **Song and track tunings.** `tuning 19-edo`, `tuning just`, `tuning pelog`, `tuning edo 31`, `tuning ratios 9/8 5/4 3/2 2/1` or `tuning cents …` retune the song; `tuning track …` retunes one track. Set the reference pitch (`ref 432`, the 12-TET A4 that fixes the root key), the root key and the key mapping (`linear`, one key per step as in Scala and Surge, or `nearest`, which keeps the piano layout). The library has 12-, 19-, 24- and 31-EDO, Pythagorean, 5- and 7-limit just intonation, a La Monte Young Well-Tuned Piano key map, gamelan pelog and slendro, an mbira nyamaropa tuning, Hindustani svaras and the 22 shrutis, and maqam, dastgah and raga tables (approximate where the tradition varies). `tuning list` shows them all.
77
+ - **Cents on the highway.** Detuned notes carry a compact tag; in 19-EDO and other linear tunings the tag names the 12-TET pitch it is measured from (`D#−47`) and lane labels mark the tuning's periods.
78
+ - **Scala import.** `tuning scl file.scl [kbm file.kbm]` copies Scala scale and keyboard-mapping files into the project's `tunings/` and validates them per the Scala specification.
79
+ - **Microtonal notes.** Any note can carry a static cents offset: `note("E4-14c", 0)` in the SDK, `add E4-14c at 0` or `cents n3 -14` at the prompt. The highway shows deviations from 12-TET as compact tags (`+14`, `−32`).
80
+ - **A scale and mode library.** The song key now reads any of the church modes, harmonic and melodic minor, phrygian dominant, pentatonics, blues, the maqamat Hijaz, Bayati, Rast, Saba, Kurd, Nahawand, Nikriz, Sikah and Huzam, Persian dastgahs (Shur, Homayoun, Chahargah, Segah, Nava), common Hindustani ragas (Yaman, Bhairav, Kafi, Bhairavi, Todi, Marwa and more) and Messiaen's seven modes of limited transposition (`scale D hijaz`, `scale list`). Every existing key string reads as before.
81
+ - **Everything honours the tuning.** Synth, wavetable and keyed-sampler tracks (by repitching), live playback, audition and export. Chords keep their keys in twelve-key tunings (pure in just intonation) and move to the nearest step in other equal tunings.
82
+ - **Scale-degree keyboard.** In play mode, `i` (or `/play degrees`) maps the home row to consecutive scale degrees, or to every step of a 19- or 31-note tuning (`Z`/`X` page through the steps eleven at a time).
83
+ - **Every way in.** The menu has Project › tuning & scale (`/menu tuning`) and Sound › tuning; the agent has `set_tuning` and `set_scale`, `add_notes` and `update_notes` take cents and the agent brief shows tunings; the SDK is 1.16.0 with `song({ tuning })` and `track({ tuning })`. Projects without a tuning open, print and render byte-identically.
84
+
85
+ ### Master and loudness
86
+
87
+ - **A song master.** `master glue on`, `master eq preset air`, `master limiter ceiling -1`: an optional chain after the track and orbit-bus sum with EQ (low and high shelves, two bells), a glue bus compressor, tape saturation, mid/side width with mono bass, and a true-peak brickwall limiter with lookahead. No master means byte-identical renders.
88
+ - **Loudness targets.** `master streaming` (-14 LUFS), `apple`, `podcast`, `broadcast` (-23), `classical`, `ambient`, `club` (-8) and `loud` (-6, hyperpop and gabber) at a -2 dBTP ceiling, or `master target -12` (`master -12`, `master on`, `master spotify` are shorthands). The target search is deterministic: the same mix always gets the same gain.
89
+ - **Loudness measurement** per ITU-R BS.1770-4 and EBU R 128: integrated, short-term and momentary LUFS, loudness range and true peak, checked against EBU Tech 3341 and 3342 test cases. `master measure` prints it, the header shows LUFS, the target and true peak while the loop plays (at the export rate once measured), with or without a master.
90
+ - **Export normalization.** `dawg render out.wav --normalize streaming` (or a LUFS number) and `--measure`. A song with a master exports at 48 kHz with TPDF dither (`--rate` overrides); `master measure` and `measure_mix` measure at that same rate, off the UI thread.
91
+ - **Glue auto make-up** (on by default) keeps glue on and off near level-matched; `master glue auto off` uses `makeup` alone.
92
+ - **Menu, agent and SDK.** Mix & automation › master (`/menu master`) with staged A/B; agent tools `set_master` and `measure_mix` (loudness, true peak, spectral balance, stereo correlation); `song({ master })` in the SDK (1.17.0).
93
+
94
+ ### Arrange
95
+
96
+ - **Song sections.** Name bar ranges (`section chorus 9-16`, `section add bridge 4 bars`) as intro, verse, chorus, build, drop or any name. Sections are markers, like a DAW's arranger track: marking never moves notes, while `section dup`, `move` and `delete` take the section's bars with them and ripple the rest. Each section can mute tracks (`section mute verse drums`) and vary them (`section vary chorus lead +12 gain 0.9`).
97
+ - **Song form.** `form intro verse*2 chorus outro` sets the order sections play in, with repeats; playback and `dawg render` follow it and `form bake` writes it out as a linear score. Without a form the song plays straight through as before.
98
+ - **Section loop and jump.** `section loop chorus` loops one section (with its mutes and variations) in playback, play mode and auditions; `section jump verse` moves the playhead. `dawg render out.wav --section chorus` renders one section.
99
+ - **Builds, drops and fills.** `build` adds a filtered noise riser, an accelerating snare roll, a filter sweep on the playing tracks and a tempo-synced supersaw uplifter over a section; `drop` cuts the beat before the downbeat and lands an impact; `fill` writes a tom, snare or kick fill with a crash at section boundaries. `build into chorus` puts the build on the bars before the chorus; filter sweeps follow an octave curve. Forms longer than 256 bars render in full, window by window. They write ordinary notes, tracks and automation, one undo step each.
100
+ - **Sections with tempo maps, phasing and the master.** A looped section, a form pass and `dawg render --section` play at the tempo sounding in those bars, and the transport clock follows the arranged tempo; phased tracks are cut by what they actually play; the master limits and normalizes a long form once over the whole song; `/export song.mid` follows the form like `dawg render`. Sections and meter changes cannot be combined.
101
+ - **Arranged renders sound like one pass.** Forms and songs with section mutes or variations that run past 45 s render in bar-aligned windows with a pre-roll, so held pads and drones, release and effect tails, sidechain ducking and seeded drum and noise voices continue across window seams exactly as in a single render. A form that plays sections in their own order keeps notes tied over a section boundary at full length, in playback and in `form bake`.
102
+ - **Arranging from the prompt is forgiving.** `section loop chrous` answers `no section named chrous (sections: …) · did you mean chorus?` locally instead of going to the agent; `build` then a bare `drop` lands on the bar after the build; `/help` has a song structure group and `/help arrange` lists every arranging command.
103
+ - **Arrangement strip and Arrange menu.** When a song has sections, a strip under the header shows them over the timeline with the playhead and the looped section. `/menu arrange` (the menu's seventh section) lists sections and opens loop, jump, a mute toggle per track, transpose and gain, build (into or over the section, custom length and layers), drop, fill, duplicate (as), move (to a bar), rename, unmark and delete.
104
+ - **Agent tools** `list_sections`, `edit_section`, `set_form` and `add_transition`, and in `song.ts` `song({ sections, form, loopSection })` (SDK 1.18.0). Projects without sections load, print and render byte-identically.
105
+
7
106
  ## 0.4.1
8
107
 
9
108
  Sound previews now crossfade instead of clicking, reverb changes are heard in under 100 ms, and the rhythm editor and chord settings hold changes until you keep them. dawg.sh gains a security policy and security headers.