@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/core/sections.ts CHANGED
@@ -13,8 +13,12 @@
13
13
  */
14
14
  import { DRUM_VOICES, isDrumInstrument } from "./drums.ts";
15
15
  import { FX_LANES } from "./fx.ts";
16
+ import { resolveString } from "./strings.ts";
17
+ import { modalSettings, windSettings } from "./resonators.ts";
18
+ import { slicePedals } from "./expression.ts";
16
19
  import {
17
20
  SCORE_LIMITS,
21
+ withNoteCap,
18
22
  ScoreValidationError,
19
23
  TrackScore,
20
24
  isSamplerInstrument,
@@ -121,8 +125,12 @@ export function sliceSongTime(
121
125
  * Later repetitions get `~p2`, `~p3` ids. Without timed tracks, or without
122
126
  * sections, the score comes back unchanged.
123
127
  */
124
- export function bakeTrackTime(score: TrackScore): TrackScore {
125
- if (score.sections.length === 0 || !hasTrackTime(score)) return score;
128
+ export function bakeTrackTime(
129
+ score: TrackScore,
130
+ options: { always?: boolean } = {},
131
+ ): TrackScore {
132
+ if (!hasTrackTime(score)) return score;
133
+ if (score.sections.length === 0 && !options.always) return score;
126
134
  const seen = new Map<string, number>();
127
135
  const notes = performedNotes(score).map((note) => {
128
136
  const count = (seen.get(note.id) ?? 0) + 1;
@@ -134,13 +142,24 @@ export function bakeTrackTime(score: TrackScore): TrackScore {
134
142
  durationTicks: Math.max(1, Math.round(note.durationTicks)),
135
143
  };
136
144
  });
137
- return new TrackScore({
138
- ...score.toJSON(),
139
- tracks: score.tracks.map(({ time: _time, ...track }) => track),
140
- notes,
141
- });
145
+ return withNoteCap(
146
+ BAKED_NOTE_CAP,
147
+ () =>
148
+ new TrackScore({
149
+ ...score.toJSON(),
150
+ tracks: score.tracks.map(({ time: _time, ...track }) => track),
151
+ notes,
152
+ }),
153
+ );
142
154
  }
143
155
 
156
+ /**
157
+ * Most notes a baked or arranged score may hold while it renders: a cycled
158
+ * or phasing track repeats its notes across the song, past the stored
159
+ * score's limit.
160
+ */
161
+ export const BAKED_NOTE_CAP = SCORE_LIMITS.maxNotes * 64;
162
+
144
163
  /** Conventional section names, offered first by `nextSectionName`. */
145
164
  export const SECTION_KINDS = Object.freeze([
146
165
  "intro",
@@ -414,7 +433,10 @@ export function sectionScore(score: TrackScore, section: Section): TrackScore {
414
433
  time: timed.time ?? null,
415
434
  bars: section.bars,
416
435
  tracks: score.tracks.map((track) =>
417
- mapAutomation(track, (points) => cropPoints(points, from, to)),
436
+ slicePedals(
437
+ mapAutomation(track, (points) => cropPoints(points, from, to)),
438
+ [{ from, to, offset: 0 }],
439
+ ),
418
440
  ),
419
441
  notes,
420
442
  sections: [],
@@ -1233,7 +1255,9 @@ export function arrangedSlice(
1233
1255
  tempoBpm: timed.tempoBpm,
1234
1256
  time: timed.time ?? null,
1235
1257
  bars,
1236
- tracks: score.tracks.map((track) => sliceLanes(track, pieces)),
1258
+ tracks: score.tracks.map((track) =>
1259
+ slicePedals(sliceLanes(track, pieces), pieces),
1260
+ ),
1237
1261
  notes: arrangedNotes(score, fromBar, fromBar + noteBars).map((note) => ({
1238
1262
  ...note,
1239
1263
  startTick: note.startTick - shift,
@@ -1302,12 +1326,22 @@ function laneFallback(track: Track, lane: string): number | undefined {
1302
1326
  }
1303
1327
  const spec = FX_LANES.find((candidate) => candidate.lane === lane);
1304
1328
  if (!spec) return undefined;
1329
+ if (spec.effect === "string") {
1330
+ const value = resolveString(track.string)[spec.param];
1331
+ return typeof value === "number" ? value : spec.spec.default;
1332
+ }
1305
1333
  const source = (
1306
1334
  spec.effect === "reverb"
1307
1335
  ? track.reverb
1308
1336
  : spec.effect === "synth"
1309
1337
  ? track.synth
1310
- : (track.fx as Record<string, unknown> | undefined)?.[spec.effect]
1338
+ : spec.effect === "keys"
1339
+ ? track.keys
1340
+ : spec.effect === "modal"
1341
+ ? track.modal && modalSettings(track.modal)
1342
+ : spec.effect === "wind"
1343
+ ? track.wind && windSettings(track.wind)
1344
+ : (track.fx as Record<string, unknown> | undefined)?.[spec.effect]
1311
1345
  ) as Record<string, unknown> | undefined;
1312
1346
  const stored = source?.[spec.param];
1313
1347
  return typeof stored === "number" ? stored : spec.spec.default;