@hraness/dawg 0.5.0 → 0.6.1

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 (124) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/DAWG.md +592 -49
  3. package/README.md +4 -4
  4. package/core/chords.ts +492 -4
  5. package/core/diff.ts +9 -0
  6. package/core/expression.ts +143 -6
  7. package/core/fx.ts +689 -2
  8. package/core/granular.ts +619 -0
  9. package/core/instruments.ts +442 -0
  10. package/core/keys.ts +955 -0
  11. package/core/resonators.ts +862 -0
  12. package/core/score.ts +529 -8
  13. package/core/sdk/eval-child.ts +2 -0
  14. package/core/sdk/print.ts +247 -16
  15. package/core/sdk/sync-instruments.ts +58 -0
  16. package/core/sdk/v1.ts +2417 -40
  17. package/core/sections.ts +44 -10
  18. package/core/strings.ts +1080 -0
  19. package/core/winds.ts +652 -0
  20. package/guides/automation.md +1 -0
  21. package/guides/chords.md +3 -1
  22. package/guides/effects.md +5 -2
  23. package/guides/media.md +1 -1
  24. package/guides/performance.md +3 -0
  25. package/guides/resample.md +26 -0
  26. package/guides/sounds.md +7 -2
  27. package/guides/tempo.md +1 -0
  28. package/package.json +1 -1
  29. package/src/agent/agent.ts +13 -0
  30. package/src/agent/chord-tools.ts +153 -1
  31. package/src/agent/expression-tools.ts +91 -0
  32. package/src/agent/granular-tools.ts +138 -0
  33. package/src/agent/models.ts +4 -4
  34. package/src/agent/ops.ts +42 -2
  35. package/src/agent/preview-tool.ts +7 -1
  36. package/src/agent/resample-tool.ts +131 -0
  37. package/src/agent/tools.ts +726 -17
  38. package/src/agent/xcb-agent.ts +13 -0
  39. package/src/audio/arrange.ts +42 -3
  40. package/src/audio/dsp/bank.ts +233 -0
  41. package/src/audio/dsp/envelope.ts +161 -0
  42. package/src/audio/dsp/fft.ts +6 -0
  43. package/src/audio/dsp/filters.ts +57 -0
  44. package/src/audio/dsp/interp.ts +112 -0
  45. package/src/audio/dsp/modal.ts +684 -0
  46. package/src/audio/dsp/onset.ts +197 -0
  47. package/src/audio/dsp/oversample.ts +202 -0
  48. package/src/audio/dsp/rng.ts +37 -0
  49. package/src/audio/dsp/shape.ts +81 -0
  50. package/src/audio/dsp/shift.ts +256 -0
  51. package/src/audio/dsp/stft.ts +73 -0
  52. package/src/audio/dsp/window.ts +77 -0
  53. package/src/audio/effects/chain.ts +23 -3
  54. package/src/audio/effects/common.ts +14 -0
  55. package/src/audio/effects/convolution.ts +106 -1
  56. package/src/audio/effects/gaze.ts +354 -0
  57. package/src/audio/effects/rig/cab.ts +99 -0
  58. package/src/audio/effects/rig/filters.ts +152 -0
  59. package/src/audio/effects/rig/gate.ts +39 -0
  60. package/src/audio/effects/rig/head.ts +487 -0
  61. package/src/audio/effects/rig/index.ts +170 -0
  62. package/src/audio/effects/rig/section.ts +78 -0
  63. package/src/audio/effects/rig/stomp.ts +238 -0
  64. package/src/audio/engine.ts +56 -6
  65. package/src/audio/fit.ts +447 -0
  66. package/src/audio/granular.ts +995 -0
  67. package/src/audio/instrument-check.ts +137 -0
  68. package/src/audio/instruments.ts +140 -0
  69. package/src/audio/keys/dsp.ts +323 -0
  70. package/src/audio/keys/electric.ts +420 -0
  71. package/src/audio/keys/engine.ts +485 -0
  72. package/src/audio/keys/organ.ts +1335 -0
  73. package/src/audio/keys/piano.ts +476 -0
  74. package/src/audio/keys/sympathetic.ts +127 -0
  75. package/src/audio/live-worker.ts +56 -0
  76. package/src/audio/live.ts +361 -15
  77. package/src/audio/loudness.ts +65 -20
  78. package/src/audio/preview.ts +17 -1
  79. package/src/audio/resample.ts +285 -0
  80. package/src/audio/resonators.ts +295 -0
  81. package/src/audio/sampler.ts +328 -35
  82. package/src/audio/samples.ts +56 -8
  83. package/src/audio/strings/body.ts +263 -0
  84. package/src/audio/strings/bow.ts +656 -0
  85. package/src/audio/strings/engine.ts +615 -0
  86. package/src/audio/strings/loop.ts +119 -0
  87. package/src/audio/strings/measure.test-helpers.ts +200 -0
  88. package/src/audio/strings/pluck.ts +354 -0
  89. package/src/audio/warp.ts +61 -0
  90. package/src/audio/wav.ts +191 -19
  91. package/src/audio/winds/engine.ts +302 -0
  92. package/src/audio/winds/filters.ts +153 -0
  93. package/src/audio/winds/pitch.ts +104 -0
  94. package/src/audio/winds/trim.ts +80 -0
  95. package/src/audio/winds/trims.ts +917 -0
  96. package/src/audio/winds/voice.ts +479 -0
  97. package/src/commands/expression.ts +111 -23
  98. package/src/commands/fit.ts +135 -0
  99. package/src/commands/fx.ts +35 -1
  100. package/src/commands/granular.ts +432 -0
  101. package/src/commands/help.ts +159 -5
  102. package/src/commands/keys.ts +629 -0
  103. package/src/commands/modal.ts +310 -0
  104. package/src/commands/resample.ts +281 -0
  105. package/src/commands/rig.ts +264 -0
  106. package/src/commands/sample.ts +52 -2
  107. package/src/commands/shift.ts +119 -0
  108. package/src/commands/string.ts +201 -0
  109. package/src/commands/strum.ts +473 -0
  110. package/src/commands/time.ts +4 -1
  111. package/src/commands/wind.ts +244 -0
  112. package/src/main.ts +339 -15
  113. package/src/project/check.ts +17 -0
  114. package/src/render.ts +49 -4
  115. package/src/session/presence.ts +16 -3
  116. package/src/tui/audition.ts +2 -2
  117. package/src/tui/granular-menu.ts +278 -0
  118. package/src/tui/menu.ts +934 -9
  119. package/src/tui/modal-menu.ts +145 -0
  120. package/src/tui/performance-menu.ts +42 -0
  121. package/src/tui/play-chords.ts +104 -3
  122. package/src/tui/play-mode.ts +1 -0
  123. package/src/tui/play-session.ts +70 -2
  124. package/src/tui/wind-menu.ts +144 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,69 @@ All notable changes to dawg are recorded here. Versions follow [semantic version
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.6.1
8
+
9
+ Instruments wave 2: bowed strings and sampler velocity layers, gamelan presets and a wind engine, electric keys with soft and sostenuto pedals, tonewheel, combo and pipe organs, shoegaze effects and guitar strumming, and granular resample with formant-keeping shift. Every new field is optional, so 0.4, 0.5 and 0.6.0 projects load, print and render byte-identically.
10
+
11
+ ### Added
12
+
13
+ - **Electric keys.** Three new keys families on the modelled-piano `keys` field: `epiano` (a tine piano with a nonlinear pickup at 2x oversampling, `bark` and `bell`, and the `vibe` suitcase stereo vibrato), `wurli` (a reed piano with a capacitive pickup and a `trem` tremolo) and `clav` (neck and bridge pickups with `pickup neck|bridge|both|out` and a `mute` slider, seeded per track, with a release plunk). Presets `epiano suitcase dyno wurli clav funkclav`, aliases `rhodes wurlitzer clavinet`. `epiano preset suitcase`, `clav pickup bridge`, Sound › browse sounds › Keys › Electric and the electric rows in the Sound page, `set_instrument` and `set_keys`, and `track({ instrument: "suitcase" })` in the SDK. The legacy word `keys` is unchanged.
14
+ - **Soft pedal and sostenuto.** The modelled pianos take `softPedal` (una corda: fewer unison strings, a softer hammer and a darker, quieter note, read at each onset) and `sostenuto` (holds only the keys already down when it presses). `pedal soft 0-8`, `pedal sost 0-4`, the Soft pedal and Sostenuto rows in Sound › performance, the `set_piano_pedals` agent tool and `track({ softPedal, sostenuto })` in the SDK (1.26.0). The piano parameter `keys sym` adds sympathetic string resonance while the sustain pedal is down. Tracks without them render byte-identically.
15
+ - **Shoegaze effects.** Four new track effects after the guitar cab: `wobble` (a held tremolo arm: seeded pitch wow and flutter, `depth` in cents), `bloom` (amp feedback: the top held note grows a singing harmonic, seeded per note), `swell` (a volume-pedal fade-in on every strum) and `double` (automatic double tracking: a seeded second take spread left and right). `fx wobble`, Effects › Shoegaze, `set_fx`, and `fx: { wobble: { depth: 30 } }` in the SDK; lanes `wobble-depth` and `swell-mix`. Rigs `shoegaze glide dreampop swell ebow` (`rig shoegaze`, `track shoegaze`), and `jangle` gains a light double when applied again (stored jangle rigs render unchanged). Reverb `ir builtin:reverse` is a reverse-gate swell (it rises after the attack; not a pre-verb), with `builtin:gate` and `builtin:spring` beside it, all generated from seeded noise. A full shoegaze rig costs under 25 ms per track-second. SDK 1.27.0 (additive).
16
+ - **Guitar strumming.** `guitar tune dadgad`, `guitar capo 2` (also `hand`, `ring`, `position`) set a track's fretboard, stored as an optional `guitar` field. `strum G D Em C folk` writes strummed chords voiced on that fretboard (no barre over an open string; a fifth, then an 11th, then a 9th are dropped when a chord has too many notes; chord symbols now also take `11 m11 maj11 add11 madd11 13 m13 maj13 7b9 7#11 maj7#11 7b13 13b9`), with stroke grids (`D U d u x - .` or `down folk pop punk funk reggae waltz jangle island`) and a strum `speed` in milliseconds (22 ms by default; the spread equals it within 1 ms). `/chords perform guitar` strums play-mode chords, with `/chords strokes` and `/chords speed` and `[` `]` to change speed while playing; Chords › strokes and speed, Sound › guitar; agent tools `set_guitar` and `strum_chords`, and `write_chords` takes `perform: "guitar"`; SDK `track({ guitar })` and `strum()`.
17
+ - **Organs.** Tonewheel, combo and pipe organs on the keys engine: 91 free-running tonewheels phase-locked to song time with nine drawbars, single-trigger percussion that mutes the 1' bar, key click, scanner vibrato/chorus V1-C3, drive and a two-rotor rotary speaker with inertia (`rotary slow|fast|stop`, lanes `keys-rotary` and `keys-drive`); a five-register combo organ; band-limited additive pipe ranks with stops, registrations, chiff, wind and tremulant, on any tuning. Presets tonewheel gospel jazzorgan combo vox pipe flutes cornet reeds celeste (aliases hammond b3 farfisa church pipeorgan). Reach them with `tonewheel`, `combo`, `pipe` and `rotary`, the menu's Sound › browse sounds › Keys › Organs and the Drawbars, Registers and Stops sub-menus, the agent's `set_keys` (`drawbars`, `registers`, `stops`, `rotary`), or `keys({ drawbars, stops, registers })` in the SDK (1.26.0). `organ` keeps its old tone. Percussion is one envelope per track (chords all sound it; `percvol soft` for the soft setting), mutations are tuned pure, footages follow non-12 tunings by octave, drive keeps loudness, presets sit within a few dB, `rotary fast at <beat>` writes the lane, a row the family does not read is refused, and long exports keep the wheels and rotor phase-locked across windows.
18
+ - Resample (SDK 1.29.0): `resample <track>|orbit <n>|master [section <name>|bars a-b] [post] [grain] [as <id>]` renders a track, an orbit or the mix through the offline renderer to a WAV pinned by sha256 under the track's `samples/`, records where it came from on the voice (`from`), and adds a sampler track, or with `grain` a granular track, that plays it. Project › Resample in the ctrl-k menu and the agent's `resample` tool do the same.
19
+ - Grain play: granular `sync` (grain onsets on a note-value grid that follows the tempo map), `quant` (`scale` or `chord`: grain pitches snap to the key or to what the other tracks sound), `mono` (legato notes retarget one voice and its cloud) and `pedal` (the sustain pedal freezes the head), plus `grain-<param>` automation lanes for every movable granular parameter, in Mix & automation's picker.
20
+ - Sample shift and fades: `shift <st> [formant keep|<n>]` pitches a sampler voice without changing its length (phase vocoder with formant keeping from 110 to 330 Hz voices, within 1 cent), and `fade in|out <s>` sets Strudel's `fadeInTime`/`fadeTime`. Sound › Sample rows Shift, Formant, Fade in and Fade out, and `set_sample` arguments.
21
+ - **Gamelan.** Fifteen presets appended to the modal engine: the bronzes `saron` `demung` `slenthem` `gangsa` `gender` `bonang` `kenong` `kethuk` `kempul`, the bells `crotales` `musicbox` `toypiano` and the frame drums `daf` `bodhran` `tabla`. `modal gamelan` lists them, with a hint to use `tuning slendro` or `pelog`. `modal pair <track>` makes an ombak pair: the pengisep sounds `ombak` Hz above its pengumbang partner, so the two beat at exactly that rate (gangsa 7 Hz). `modal ombak 6` on a track that is not modal yet starts a gangsa. Saron, demung, gangsa and bonang damp the key at note-off, as a player's hand does before the next stroke (tutupan). In the SDK a gangsa partner without its own `ombak` plays one straight voice, and `dawg check` warns when `pair` names a missing or non-modal track. Menu Sound › browse sounds › Mallets and bells › Gamelan, `set_modal` takes `pair`, SDK `modal("gangsa", { pair })` (1.30.0). `RESONATOR_TABLE_VERSION` is 2 (rows appended, existing presets unchanged), so cached stems re-render once.
22
+ - **Ring-out in play mode.** Undamped modal voices (gongs, kempul, bowls) keep ringing after note-off in play mode and the audition loop, capped at 32 with a 250 ms fade for the oldest; the loop fold fades a tail that would outlast it.
23
+ - **Winds and brass.** A new wind engine of breath-driven waveguides (jet, reed, conical reed and lip models; Thiran-tuned bores; reed and jet at 2x with ADAA) with 21 presets: `flute` `recorder` `whistle` `ney` `shakuhachi` `panpipe` `suling` `bansuri` `clarinet` `bassclarinet` `oboe` `bassoon` `sax` `altosax` `barisax` `trumpet` `harmon` `plunger` `trombone` `tuba` `horn`. Per-rate trims from `scripts/calibrate-winds.ts` keep every preset within 3 cents. `bright` opens the tone of every model, and presets are level-matched on loudness (sustain RMS) rather than peak. Lines slur by default, back-to-back notes included, `players` spreads a section over chord tones, mutes, growl, flutter and a plunger wah, `wind-<param>` lanes. `wind <preset>`, `wind trumpet mute harmon`, `wind breath 0.8` (`vibrato` is an alias of `vib`), staged A/B in the audition loop, `presets wind`, `instrument flute`, menu Sound › browse sounds › Winds and brass and the Sound page, agent `set_wind`, SDK `wind()` (1.30.0). The legacy `wind` word keeps its old tone byte-identically.
24
+ - **Bowed strings.** The string engine gains a bow (`exciter: "bow"`): a bowed waveguide after the STK model with a Schelleng guard, so every pressure, speed and position setting stays in Helmholtz motion (0 of 1296 unstable), a pitch lock (within 1 cent to C7 at 22.05 and 48 kHz) and 2x oversampling for short strings. 13 presets are appended: violin, viola, cello, contrabass, fiddle, erhu, kamancheh, the sections violins, violas, cellos and contrabasses, pizz and trem, with a `violin` body. Bow parameters `pressure speed attack tremhz sord dyn` (alias `expression`) join `vib vibmod vibdelay`; `string-pressure`, `string-speed`, `string-sord` and `string-dyn` automate. True legato (the held note lets go within a 64th note or 150 ms) or `legato` notes slur in one bow stroke, up to two octaves, and a note held under a moving line keeps sounding. Section players get seeded vibrato and onsets up to 25 ms apart; staccato is a detache stroke and accents bite. `bowed violin`, `bowed pressure 0.7`, Sound › browse sounds › Strings › Bowed and the bow rows in the Sound page, `set_string` and `stringed({ preset: "cello" })` (SDK 1.31.0). The bare words `cello`, `contrabass` and `strings` keep their old voices byte-identically; `bowed-cello`, `violin`, `viola`, `fiddle`, `erhu`, `kamancheh`, `violins`, `violas`, `cellos` and `contrabasses` pick the bowed presets. The string preset table hash changes because rows were appended; the 22 earlier rows are unchanged.
25
+ - **Sampler velocity layers and round robin.** Sampler voices take `vel: [lo, hi]` (SFZ `lovel`/`hivel`) and `rr: "<group>"`: keyed voices with the same root become velocity layers, and voices in a group take turns A B A B, deterministically. `/sample set sn1 vel 0-63 rr sn`, the Velocity layer and Round robin rows on each sample voice, `set_sample` and `sample(path, { vel, rr })`. Voices without them play as before.
26
+
27
+ ### Fixed
28
+
29
+ - Switching tracks could fail at random with a "no such file" error when the presence heartbeat and the focus change wrote at the same moment, leaving play mode recording onto the old track. Presence writes are now serialised with unique temp names, and a presence error never fails a focus change.
30
+ - Guitar strumming kept a slash bass only when it was a chord tone: `B/E` now has E as its lowest note in every tuning, like `A/E`.
31
+ - `dreampop` and `ebow` work as instrument words (`track ebow`, `instrument: "dreampop"`), giving the rig and its reverb wash like `shoegaze`. `glide` and `swell` stay rig-only (`rig glide`), because `glide` is already the portamento command and `swell` an effect.
32
+ - The `shoegaze` rig sat 4-9 dB under clean on strummed parts; its trim is raised so strummed and held parts both land within 2.5 dB of clean (a new strummed test). `ebow` and `swell` are documented as held-note rigs.
33
+ - `fx <effect>` alone (`fx wobble`) turns the effect on instead of printing usage. /help and DAWG.md show `fx reverb ir builtin:reverse` (the bare `reverb ir …` went to the agent).
34
+ - `dawg render` warns on stderr when samples hit 16-bit full scale, with the fix (lower volumes, or a master with a limiter).
35
+ - `resample` refuses a source that is silent over the range instead of writing a silent file and track, and trims the file's silent tail (20 ms after the last sound) rather than a fixed 4 s.
36
+ - Keeping formants (`shift 7 formant 0`) no longer drops the level by about 7 dB on an upward shift: each frame keeps its energy through the correction.
37
+ - `dawg --import` of a file that is not loop JSON (such as an exported .mid) prints one line instead of a stack trace.
38
+ - Changing a keys track to another instrument (`wind sax`, `bowed violins`) drops its stale `keys` block.
39
+ - Sound › browse sounds › Winds and brass lists Saxophones (`sax`, `altosax`, `barisax`) as their own group. DAWG.md names the Sound page for instrument rows (there is no Parameters page).
40
+
41
+ ## 0.6.0
42
+
43
+ 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.
44
+
45
+ ### Added
46
+
47
+ - **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).
48
+ - **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.
49
+ - **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.
50
+ - **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`).
51
+ - **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).
52
+ - **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.
53
+
54
+ ### Fixed
55
+
56
+ - **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.
57
+ - **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.
58
+ - **Quieter voice steals.** A stolen modal voice fades over 80 ms with a raised cosine, so long gong and kempul tails no longer click.
59
+ - **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.
60
+ - **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.
61
+ - **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.
62
+ - **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.
63
+ - **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.
64
+ - **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.
65
+
66
+ ### Internal
67
+
68
+ - **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.
69
+
7
70
  ## 0.5.0
8
71
 
9
72
  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.