@hraness/dawg 0.4.0 → 0.5.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 (116) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/DAWG.md +300 -35
  3. package/README.md +4 -4
  4. package/core/chords.ts +288 -7
  5. package/core/diff.ts +37 -12
  6. package/core/expression.ts +1241 -0
  7. package/core/loop.ts +23 -0
  8. package/core/master.ts +455 -0
  9. package/core/midi.ts +452 -0
  10. package/core/rhythm.ts +7 -2
  11. package/core/score.ts +536 -56
  12. package/core/sdk/eval-child.ts +38 -3
  13. package/core/sdk/print.ts +445 -14
  14. package/core/sdk/v1.ts +1709 -23
  15. package/core/sections.ts +2046 -0
  16. package/core/synth.ts +11 -1
  17. package/core/tempo.ts +1318 -0
  18. package/core/tuning.ts +1180 -0
  19. package/guides/audition.md +26 -0
  20. package/guides/automation.md +26 -0
  21. package/guides/chords.md +28 -0
  22. package/guides/effects.md +27 -0
  23. package/guides/faders.md +29 -0
  24. package/guides/files.md +28 -0
  25. package/guides/getting-started.md +26 -0
  26. package/guides/index.ts +75 -0
  27. package/guides/keys.md +27 -0
  28. package/guides/media.md +27 -0
  29. package/guides/mix.md +23 -0
  30. package/guides/music.md +14 -0
  31. package/guides/notes.md +26 -0
  32. package/guides/performance.md +26 -0
  33. package/guides/play.md +24 -0
  34. package/guides/project.md +13 -0
  35. package/guides/providers.md +25 -0
  36. package/guides/rhythm.md +26 -0
  37. package/guides/sessions.md +21 -0
  38. package/guides/sound.md +15 -0
  39. package/guides/sounds.md +25 -0
  40. package/guides/tempo.md +26 -0
  41. package/guides/tracks.md +25 -0
  42. package/guides/web-search.md +21 -0
  43. package/package.json +3 -1
  44. package/src/agent/agent.ts +2 -0
  45. package/src/agent/brief.ts +77 -3
  46. package/src/agent/chord-tools.ts +9 -1
  47. package/src/agent/expression-tools.ts +336 -0
  48. package/src/agent/master-tools.ts +299 -0
  49. package/src/agent/models.ts +4 -4
  50. package/src/agent/ops.ts +29 -4
  51. package/src/agent/planner.ts +45 -2
  52. package/src/agent/preview-tool.ts +21 -3
  53. package/src/agent/section-tools.ts +411 -0
  54. package/src/agent/time-tools.ts +290 -0
  55. package/src/agent/tools.ts +36 -2
  56. package/src/agent/tuning-tools.ts +301 -0
  57. package/src/agent/xcb-agent.ts +2 -0
  58. package/src/audio/arrange.ts +471 -0
  59. package/src/audio/audition.ts +16 -3
  60. package/src/audio/click.ts +113 -1
  61. package/src/audio/clock.ts +71 -5
  62. package/src/audio/effects/bus.ts +5 -4
  63. package/src/audio/effects/chain.ts +12 -2
  64. package/src/audio/effects/common.ts +30 -1
  65. package/src/audio/effects/convolution.ts +43 -5
  66. package/src/audio/effects/dynamics.ts +2 -1
  67. package/src/audio/effects/filter.ts +5 -3
  68. package/src/audio/effects/modulation.ts +5 -1
  69. package/src/audio/effects/space.ts +197 -50
  70. package/src/audio/engine.ts +175 -20
  71. package/src/audio/live.ts +33 -6
  72. package/src/audio/loudness.ts +551 -0
  73. package/src/audio/master.ts +660 -0
  74. package/src/audio/measure-worker.ts +45 -0
  75. package/src/audio/measure.ts +110 -0
  76. package/src/audio/player.ts +11 -6
  77. package/src/audio/preview.ts +87 -16
  78. package/src/audio/render-worker.ts +6 -1
  79. package/src/audio/renderer.ts +7 -1
  80. package/src/audio/sampler.ts +108 -19
  81. package/src/audio/synth/voice.ts +60 -13
  82. package/src/audio/synth/zzfx.ts +10 -4
  83. package/src/audio/warp.ts +86 -0
  84. package/src/audio/wav.ts +448 -59
  85. package/src/commands/arrange.ts +949 -0
  86. package/src/commands/expression.ts +934 -0
  87. package/src/commands/help.ts +281 -24
  88. package/src/commands/master.ts +361 -0
  89. package/src/commands/music.ts +6 -1
  90. package/src/commands/synth.ts +11 -1
  91. package/src/commands/time.ts +964 -0
  92. package/src/commands/tuning.ts +490 -0
  93. package/src/main.ts +826 -47
  94. package/src/render.ts +109 -7
  95. package/src/session/daemon.ts +18 -8
  96. package/src/session/naming.ts +8 -1
  97. package/src/session/rebase.ts +21 -0
  98. package/src/tui/arrange-menu.ts +390 -0
  99. package/src/tui/audition.ts +58 -5
  100. package/src/tui/euclid.ts +50 -6
  101. package/src/tui/fader.ts +409 -0
  102. package/src/tui/menu-time.ts +401 -0
  103. package/src/tui/menu.ts +656 -16
  104. package/src/tui/performance-menu.ts +235 -0
  105. package/src/tui/play-chords.ts +95 -1
  106. package/src/tui/play-mode.ts +150 -6
  107. package/src/tui/play-session.ts +414 -41
  108. package/tui/app.ts +262 -13
  109. package/tui/arrange-strip.ts +174 -0
  110. package/tui/drawer.ts +478 -0
  111. package/tui/grammar.ts +79 -12
  112. package/tui/guide.ts +351 -0
  113. package/tui/highway.ts +87 -4
  114. package/tui/hits.ts +68 -0
  115. package/tui/input.ts +7 -0
  116. package/tui/keys.ts +72 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,92 @@ All notable changes to dawg are recorded here. Versions follow [semantic version
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.5.0
8
+
9
+ 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.
10
+
11
+ ### Integration fixes
12
+
13
+ - **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.
14
+ - **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.
15
+ - **Forms keep tempo ramps** that cross a section boundary, and sections work in a compound meter held from bar 1 (6/8, 12/8).
16
+ - `/export name.wav` refuses and points to `dawg render` instead of writing loop JSON under a `.wav` name.
17
+ - 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.
18
+ - 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.
19
+ - 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.
20
+ - `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.
21
+
22
+ ### Guides
23
+
24
+ - **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.
25
+
26
+ ### Tempo and meter
27
+
28
+ - **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.
29
+ - **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.
30
+ - **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.
31
+ - **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_.
32
+ - **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.
33
+ - **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.
34
+ - **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.
35
+
36
+ ### Performance and expression
37
+
38
+ - **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.
39
+ - **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.
40
+ - **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.
41
+ - **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.
42
+ - **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.
43
+ - **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.
44
+
45
+ ### Tunings and scales
46
+
47
+ - **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.
48
+ - **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.
49
+ - **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.
50
+ - **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`).
51
+ - **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.
52
+ - **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.
53
+ - **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).
54
+ - **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.
55
+
56
+ ### Master and loudness
57
+
58
+ - **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.
59
+ - **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.
60
+ - **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.
61
+ - **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.
62
+ - **Glue auto make-up** (on by default) keeps glue on and off near level-matched; `master glue auto off` uses `makeup` alone.
63
+ - **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).
64
+
65
+ ### Arrange
66
+
67
+ - **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`).
68
+ - **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.
69
+ - **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.
70
+ - **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.
71
+ - **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.
72
+ - **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`.
73
+ - **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.
74
+ - **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.
75
+ - **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.
76
+
77
+ ## 0.4.1
78
+
79
+ 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.
80
+
81
+ ### Previewing changes
82
+
83
+ - **Edits crossfade instead of clicking.** When the loop (audition or song) swaps to a new render, the old and new buffers crossfade over 20 ms with equal-power gains at the same beat, so a change no longer steps the waveform. Playback only: renders and exports are byte-identical.
84
+ - **`/euclid` and the chord settings stage while the loop plays.** `Space` in the rhythm editor or the menu's Chords section (`/menu chords`) starts the audition loop; changes are then staged and heard (`●`, `B staged N`, `E(5,16) ← E(4,16)`, `Db ← C`), `a` flips A/B, `Enter` keeps them as one undo step and `Esc` reverts with nothing written. In the Chords section the loop plays the track's chord phrase under the current settings. With the loop off, both commit at once as before; their key footers and `?` panels use the shared audition keys.
85
+ - **Reverb changes are heard faster.** The stem cache keeps each track's reverb input and tail apart from its dry signal, so a reverb mix (or mix lane) change re-mixes the cached tail instead of re-rendering the voice and the room. Key to audio scheduled on a 4-track song: reverb mix on a wavetable pad in context 140 → 64 ms median (p90 151 → 68 ms); a filter change in context 100 → 74 ms. The bus mix loops also moved out of the large render function, which the JIT optimized late. Renders stay byte-identical (a new test checks cached re-mixes against cold renders and recorded digests).
86
+
87
+ ### Security
88
+
89
+ - **A security policy.** `SECURITY.md` and `https://dawg.sh/.well-known/security.txt` say how to report a vulnerability privately.
90
+ - **dawg.sh sends security headers** on every route: a Content Security Policy limited to the site's own origin and its analytics hosts, HSTS, `nosniff`, `DENY` framing, a strict referrer policy and a permissions policy that turns off camera, microphone and location.
91
+ - Dependabot also watches the site's dependencies (minor and patch updates, grouped).
92
+
7
93
  ## 0.4.0
8
94
 
9
95
  dawg now has a full sound engine with Strudel's synth, effect and sample parameters, Strudel sample packs, wavetables (including ones made from your own audio), Euclidean drum rows and a pattern library, Orchid-style chords, sound previews with A/B, and one consistent set of keys across every screen. Projects from 0.3.0 open and sound the same, and the `dawg` SDK is 1.13.0 (every step additive within v1).