@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
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Ctrl-k menu rows for the wind engine (0.6.1): the "Winds and brass" group
3
+ * under Sound › browse sounds, and the WIND_PARAMS rows under Sound ›
4
+ * Parameters on a wind-engine track. Every row runs a `wind …` command.
5
+ */
6
+ import type { EnumParam, NumberParam } from "../../core/params.ts";
7
+ import type { Track } from "../../core/score.ts";
8
+ import {
9
+ DEFAULT_WIND_PRESET,
10
+ WIND_GROUPS,
11
+ WIND_INSTRUMENT,
12
+ WIND_PARAMS,
13
+ WIND_PRESETS,
14
+ WIND_PRESET_NAMES,
15
+ WIND_SIMPLE,
16
+ windSettings,
17
+ type WindPresetName,
18
+ } from "../../core/winds.ts";
19
+ import { num, specStep, type MenuNode } from "./menu.ts";
20
+
21
+ function presetRow(name: WindPresetName): MenuNode {
22
+ return {
23
+ kind: "action",
24
+ label: `${name.padEnd(13)} ${WIND_PRESETS[name].doc}`,
25
+ command: `wind ${name}`,
26
+ help: WIND_PRESETS[name].styles,
27
+ };
28
+ }
29
+
30
+ /** Sound › browse sounds › Winds and brass: flutes, reeds, brass. */
31
+ export function windsMenu(): MenuNode {
32
+ return {
33
+ kind: "menu",
34
+ id: "winds",
35
+ label: "Winds and brass",
36
+ detail: `${WIND_PRESET_NAMES.length} blown · flute, sax, trumpet …`,
37
+ help: "breath-driven waveguides: flutes, reeds and brass; wind players 4 for a section",
38
+ build: () =>
39
+ WIND_GROUPS.map((group): MenuNode => ({
40
+ kind: "menu",
41
+ id: `winds:${group.label.toLowerCase()}`,
42
+ label: group.label,
43
+ detail: group.presets.slice(0, 3).join(", ") + " …",
44
+ help: `${group.label.toLowerCase()} on the wind engine`,
45
+ build: () => group.presets.map(presetRow),
46
+ })),
47
+ };
48
+ }
49
+
50
+ function numberRow(
51
+ name: string,
52
+ spec: NumberParam,
53
+ value: number,
54
+ fallback: number,
55
+ ): MenuNode {
56
+ return {
57
+ kind: "number",
58
+ label: name,
59
+ value,
60
+ min: spec.min,
61
+ max: spec.max,
62
+ step: specStep(spec),
63
+ format: (v) => (spec.unit ? `${num(v)} ${spec.unit}` : num(v)),
64
+ command: (v) => `wind ${name} ${num(v)}`,
65
+ reset: `wind ${name} off`,
66
+ help: `${spec.doc} · preset ${num(fallback)} · x resets`,
67
+ };
68
+ }
69
+
70
+ /** Sound › Parameters rows on a wind-engine track. */
71
+ export function windParameterNodes(track: Track): MenuNode[] {
72
+ if (track.instrument !== WIND_INSTRUMENT || !track.wind) return [];
73
+ const wind = track.wind;
74
+ const preset = WIND_PRESETS[wind.preset ?? DEFAULT_WIND_PRESET].settings;
75
+ const resolved = windSettings(wind) as Readonly<
76
+ Record<string, number | string | boolean>
77
+ >;
78
+ const fallback = preset as Readonly<
79
+ Record<string, number | string | boolean>
80
+ >;
81
+ const row = (name: string): MenuNode | undefined => {
82
+ const spec = WIND_PARAMS[name]!;
83
+ const own = (wind as Record<string, unknown>)[name];
84
+ if (spec.kind === "enum")
85
+ return {
86
+ kind: "choice",
87
+ label: name,
88
+ value: own === undefined ? "preset" : String(own),
89
+ options: ["preset", ...(spec as EnumParam).values],
90
+ command: (option) =>
91
+ option === "preset" ? `wind ${name} unset` : `wind ${name} ${option}`,
92
+ help: `${spec.doc} · preset ${String(fallback[name])}`,
93
+ };
94
+ if (spec.kind === "boolean")
95
+ return {
96
+ kind: "choice",
97
+ label: name,
98
+ value: own === undefined ? "preset" : own ? "on" : "off",
99
+ options: ["preset", "on", "off"],
100
+ command: (option) =>
101
+ option === "preset" ? `wind ${name} unset` : `wind ${name} ${option}`,
102
+ help: `${spec.doc} · preset ${fallback[name] ? "on" : "off"}`,
103
+ };
104
+ return numberRow(
105
+ name,
106
+ spec,
107
+ Number(resolved[name]),
108
+ Number(fallback[name]),
109
+ );
110
+ };
111
+ const nodes: MenuNode[] = [
112
+ {
113
+ kind: "choice",
114
+ label: "preset",
115
+ value: wind.preset ?? DEFAULT_WIND_PRESET,
116
+ options: WIND_PRESET_NAMES,
117
+ command: (option) => `wind preset ${option}`,
118
+ help: "the instrument: bore, exciter, range and mute",
119
+ },
120
+ ];
121
+ for (const name of WIND_SIMPLE) {
122
+ const node = row(name);
123
+ if (node) nodes.push(node);
124
+ }
125
+ const rest = Object.keys(WIND_PARAMS).filter(
126
+ (name) => !(WIND_SIMPLE as readonly string[]).includes(name),
127
+ );
128
+ nodes.push({
129
+ kind: "menu",
130
+ id: "wind:advanced",
131
+ label: "advanced",
132
+ detail: rest.join(", "),
133
+ help: "every wind parameter",
134
+ build: () => rest.flatMap((name) => row(name) ?? []),
135
+ });
136
+ if (Object.keys(wind).some((key) => key !== "preset"))
137
+ nodes.push({
138
+ kind: "action",
139
+ label: "reset to preset",
140
+ command: "wind reset",
141
+ help: "clear overrides, keep the preset",
142
+ });
143
+ return nodes;
144
+ }