@hraness/dawg 0.3.0 → 0.4.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 (81) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/DAWG.md +608 -39
  3. package/README.md +4 -4
  4. package/core/chords.ts +1724 -0
  5. package/core/diff.ts +13 -1
  6. package/core/euclid.ts +670 -0
  7. package/core/fx.ts +1065 -0
  8. package/core/kits.ts +320 -0
  9. package/core/params.ts +111 -0
  10. package/core/rhythm.ts +287 -0
  11. package/core/score.ts +735 -18
  12. package/core/sdk/eval-child.ts +34 -22
  13. package/core/sdk/eval.ts +4 -1
  14. package/core/sdk/print.ts +304 -22
  15. package/core/sdk/sync-chords.ts +54 -0
  16. package/core/sdk/v1.ts +3226 -21
  17. package/core/synth.ts +1001 -0
  18. package/package.json +1 -1
  19. package/src/agent/agent.ts +38 -3
  20. package/src/agent/brief.ts +29 -4
  21. package/src/agent/chord-tools.ts +357 -0
  22. package/src/agent/drum-tools.ts +135 -0
  23. package/src/agent/models.ts +4 -4
  24. package/src/agent/pack-tools.ts +369 -0
  25. package/src/agent/planner.ts +17 -2
  26. package/src/agent/preview-tool.ts +270 -0
  27. package/src/agent/rhythm-tools.ts +145 -0
  28. package/src/agent/tools.ts +308 -14
  29. package/src/agent/xcb-agent.ts +8 -2
  30. package/src/audio/audition.ts +93 -0
  31. package/src/audio/cache.ts +160 -0
  32. package/src/audio/effects/bus.ts +147 -0
  33. package/src/audio/effects/chain.ts +109 -0
  34. package/src/audio/effects/common.ts +251 -0
  35. package/src/audio/effects/convolution.ts +339 -0
  36. package/src/audio/effects/drive.ts +142 -0
  37. package/src/audio/effects/duck.ts +122 -0
  38. package/src/audio/effects/dynamics.ts +121 -0
  39. package/src/audio/effects/filter.ts +319 -0
  40. package/src/audio/effects/modulation.ts +174 -0
  41. package/src/audio/effects/space.ts +394 -0
  42. package/src/audio/engine.ts +112 -4
  43. package/src/audio/kits.ts +200 -0
  44. package/src/audio/packs.ts +1787 -0
  45. package/src/audio/preview.ts +481 -0
  46. package/src/audio/random.ts +15 -0
  47. package/src/audio/sampler.ts +157 -29
  48. package/src/audio/samples.ts +386 -44
  49. package/src/audio/synth/oscillators.ts +268 -0
  50. package/src/audio/synth/voice.ts +555 -0
  51. package/src/audio/synth/zzfx.ts +137 -0
  52. package/src/audio/wav.ts +411 -295
  53. package/src/audio/wavetable-maker.ts +717 -0
  54. package/src/audio/wavetable.ts +624 -0
  55. package/src/commands/drums.ts +299 -0
  56. package/src/commands/edit.ts +26 -4
  57. package/src/commands/fx.ts +360 -0
  58. package/src/commands/help.ts +298 -10
  59. package/src/commands/music.ts +10 -8
  60. package/src/commands/pack.ts +423 -0
  61. package/src/commands/rhythm.ts +230 -0
  62. package/src/commands/sample.ts +162 -2
  63. package/src/commands/synth.ts +229 -0
  64. package/src/commands/wavetable.ts +370 -0
  65. package/src/main.ts +1222 -30
  66. package/src/media/cli.ts +15 -2
  67. package/src/media/tools.ts +106 -1
  68. package/src/media/wavetable.ts +202 -0
  69. package/src/render.ts +22 -1
  70. package/src/session/naming.ts +3 -1
  71. package/src/tui/audition.ts +521 -0
  72. package/src/tui/euclid.ts +516 -0
  73. package/src/tui/menu.ts +1305 -244
  74. package/src/tui/play-chords.ts +630 -0
  75. package/src/tui/play-session.ts +364 -16
  76. package/src/tui/sketch.ts +108 -0
  77. package/src/web/search.ts +4 -1
  78. package/tui/app.ts +161 -39
  79. package/tui/grammar.ts +286 -0
  80. package/tui/highway.ts +7 -1
  81. package/tui/play-strip.ts +59 -14
package/tui/play-strip.ts CHANGED
@@ -32,9 +32,20 @@ export type PlayHeaderView = Readonly<{
32
32
  beat?: Readonly<{ index: number; of: number; flash: boolean }> | undefined;
33
33
  /** `grid 1/16`. */
34
34
  grid: string;
35
+ /** Chord mode: `AUTO C major · Dm (ii) → G · arp-up`, empty when off. */
36
+ chords?: string | undefined;
35
37
  /** Short status (`octave C2`, `no audio`). */
36
38
  status?: string | undefined;
37
39
  keys: readonly PlayStripKey[];
40
+ /** Chord mode's number-row legend; latched entries are `on`. */
41
+ legend?: readonly ChordLegendCell[] | undefined;
42
+ }>;
43
+
44
+ /** One chord-mode key on the legend row: `1 dim`, `9 strum-up`. */
45
+ export type ChordLegendCell = Readonly<{
46
+ key: string;
47
+ label: string;
48
+ on: boolean;
38
49
  }>;
39
50
 
40
51
  /** Text of the header row, for tests and narrow terminals. */
@@ -42,14 +53,14 @@ export function playHeaderText(view: PlayHeaderView, unicode = true): string {
42
53
  const parts = [
43
54
  "PLAY",
44
55
  view.range,
45
- `vel ${view.velocity}`,
46
56
  view.armed
47
57
  ? `${unicode ? "●" : "*"} ${view.recording ? "REC" : "rec armed"}${view.replace ? " replace" : ""}`
48
58
  : "",
49
- `click ${view.click ? (unicode ? "✓" : "on") : "off"}`,
59
+ view.click ? "click" : "",
50
60
  view.sustain ? "SUSTAIN" : "",
51
- view.grid,
61
+ view.chords ?? "",
52
62
  view.countIn ?? "",
63
+ view.status ?? "",
53
64
  ].filter(Boolean);
54
65
  return parts.join(" ");
55
66
  }
@@ -78,17 +89,15 @@ export function paintPlayHeader(
78
89
  };
79
90
  put(" PLAY ", roles.pillSteer);
80
91
  put(view.range, { ...roles.text, bold: true });
81
- put(`vel ${view.velocity}`);
82
92
  if (view.armed)
83
93
  put(
84
94
  `${unicode ? "●" : "*"} ${view.recording ? "REC" : "rec armed"}${view.replace ? " replace" : ""}`,
85
95
  view.recording ? roles.error : roles.warning,
86
96
  );
87
- put(
88
- `click ${view.click ? (unicode ? "✓" : "on") : "off"}`,
89
- view.click ? roles.success : roles.muted,
90
- );
97
+ // Velocity, grid and click details live in the `?` panel.
98
+ if (view.click) put("click", roles.success);
91
99
  if (view.sustain) put("SUSTAIN", roles.pillQueue);
100
+ if (view.chords) put(view.chords, roles.hit);
92
101
  if (view.countIn) put(view.countIn, roles.warning);
93
102
  if (view.beat) {
94
103
  const cells = Array.from({ length: view.beat.of }, (_, index) =>
@@ -109,12 +118,48 @@ export function paintPlayHeader(
109
118
  : roles.muted,
110
119
  );
111
120
  }
112
- put(view.grid, roles.muted);
113
- if (view.status) put(view.status, roles.muted);
114
- // Mode keys at the right edge while there is room.
115
- const hint = "z/x oct · c/v vel · r rec · m click · esc exit";
116
- const room = width - 1 - displayWidth(hint);
117
- if (room > x) buffer.text(room, y, hint, onBackground(roles.faint, panel));
121
+ // The way out and the way to learn more, always at the right edge.
122
+ const hint = "? keys · esc leave";
123
+ const right = width - 1 - displayWidth(hint);
124
+ // Status shows whole or by its first clause, never cut mid-word.
125
+ if (view.status) {
126
+ const room = right - 2 - x;
127
+ const first = view.status.split(" · ")[0]!;
128
+ const text =
129
+ displayWidth(view.status) <= room
130
+ ? view.status
131
+ : displayWidth(first) <= room
132
+ ? first
133
+ : "";
134
+ if (text) x += buffer.text(x, y, text, onBackground(roles.muted, panel));
135
+ }
136
+ if (right > x) buffer.text(right, y, hint, onBackground(roles.faint, panel));
137
+ }
138
+
139
+ /** Chord mode's number row: `1 dim 2 min … 9 block b bass off n next`. */
140
+ export function paintChordLegend(
141
+ buffer: CellBuffer,
142
+ y: number,
143
+ width: number,
144
+ cells: readonly ChordLegendCell[],
145
+ theme: Theme,
146
+ ): void {
147
+ const roles = theme.roles;
148
+ buffer.fill(0, y, width, 1, roles.canvas);
149
+ let x = 1;
150
+ for (const cell of cells) {
151
+ const keyWidth = displayWidth(cell.key);
152
+ const cellWidth = keyWidth + 1 + displayWidth(cell.label) + 2;
153
+ if (x + cellWidth > width) break;
154
+ buffer.text(x, y, cell.key, { ...roles.text, bold: true });
155
+ buffer.text(
156
+ x + keyWidth + 1,
157
+ y,
158
+ cell.label,
159
+ cell.on ? { ...roles.hit, reverse: true } : roles.muted,
160
+ );
161
+ x += cellWidth;
162
+ }
118
163
  }
119
164
 
120
165
  /** `a C3 │ w C#3 …`: each key with its note; lit keys reversed. */