@hraness/dawg 0.6.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.
- package/CHANGELOG.md +34 -0
- package/DAWG.md +338 -51
- package/README.md +4 -4
- package/core/chords.ts +492 -4
- package/core/diff.ts +5 -0
- package/core/expression.ts +143 -6
- package/core/fx.ts +258 -6
- package/core/granular.ts +91 -0
- package/core/instruments.ts +161 -0
- package/core/keys.ts +573 -4
- package/core/resonators.ts +291 -3
- package/core/score.ts +349 -3
- package/core/sdk/print.ts +78 -3
- package/core/sdk/v1.ts +1320 -36
- package/core/sections.ts +12 -4
- package/core/strings.ts +237 -2
- package/core/winds.ts +652 -0
- package/guides/automation.md +1 -0
- package/guides/chords.md +3 -1
- package/guides/effects.md +3 -2
- package/guides/media.md +1 -1
- package/guides/performance.md +3 -0
- package/guides/resample.md +26 -0
- package/guides/sounds.md +7 -6
- package/package.json +1 -1
- package/src/agent/agent.ts +8 -2
- package/src/agent/chord-tools.ts +153 -1
- package/src/agent/expression-tools.ts +91 -0
- package/src/agent/ops.ts +4 -1
- package/src/agent/preview-tool.ts +2 -1
- package/src/agent/resample-tool.ts +131 -0
- package/src/agent/tools.ts +200 -15
- package/src/agent/xcb-agent.ts +8 -2
- package/src/audio/arrange.ts +21 -0
- package/src/audio/dsp/envelope.ts +161 -0
- package/src/audio/dsp/shift.ts +256 -0
- package/src/audio/effects/chain.ts +18 -3
- package/src/audio/effects/common.ts +14 -0
- package/src/audio/effects/convolution.ts +106 -1
- package/src/audio/effects/gaze.ts +354 -0
- package/src/audio/engine.ts +46 -5
- package/src/audio/fit.ts +45 -0
- package/src/audio/granular.ts +352 -21
- package/src/audio/instrument-check.ts +9 -5
- package/src/audio/instruments.ts +32 -3
- package/src/audio/keys/electric.ts +420 -0
- package/src/audio/keys/engine.ts +143 -19
- package/src/audio/keys/organ.ts +1335 -0
- package/src/audio/keys/piano.ts +50 -6
- package/src/audio/keys/sympathetic.ts +127 -0
- package/src/audio/live-worker.ts +3 -1
- package/src/audio/live.ts +136 -9
- package/src/audio/preview.ts +15 -1
- package/src/audio/resample.ts +285 -0
- package/src/audio/resonators.ts +10 -2
- package/src/audio/sampler.ts +168 -21
- package/src/audio/samples.ts +26 -1
- package/src/audio/strings/body.ts +29 -16
- package/src/audio/strings/bow.ts +656 -0
- package/src/audio/strings/engine.ts +266 -20
- package/src/audio/strings/measure.test-helpers.ts +2 -0
- package/src/audio/wav.ts +119 -19
- package/src/audio/winds/engine.ts +302 -0
- package/src/audio/winds/filters.ts +153 -0
- package/src/audio/winds/pitch.ts +104 -0
- package/src/audio/winds/trim.ts +80 -0
- package/src/audio/winds/trims.ts +917 -0
- package/src/audio/winds/voice.ts +479 -0
- package/src/commands/expression.ts +103 -22
- package/src/commands/fx.ts +4 -1
- package/src/commands/granular.ts +7 -2
- package/src/commands/help.ts +91 -8
- package/src/commands/keys.ts +287 -11
- package/src/commands/modal.ts +67 -4
- package/src/commands/resample.ts +281 -0
- package/src/commands/rig.ts +5 -1
- package/src/commands/sample.ts +49 -2
- package/src/commands/shift.ts +119 -0
- package/src/commands/string.ts +28 -2
- package/src/commands/strum.ts +473 -0
- package/src/commands/wind.ts +244 -0
- package/src/main.ts +129 -7
- package/src/project/check.ts +5 -1
- package/src/render.ts +16 -0
- package/src/session/presence.ts +16 -3
- package/src/tui/audition.ts +1 -1
- package/src/tui/menu.ts +637 -35
- package/src/tui/modal-menu.ts +34 -7
- package/src/tui/performance-menu.ts +42 -0
- package/src/tui/play-chords.ts +104 -3
- package/src/tui/play-mode.ts +1 -0
- package/src/tui/play-session.ts +34 -9
- package/src/tui/wind-menu.ts +144 -0
package/core/sections.ts
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
import { DRUM_VOICES, isDrumInstrument } from "./drums.ts";
|
|
15
15
|
import { FX_LANES } from "./fx.ts";
|
|
16
16
|
import { resolveString } from "./strings.ts";
|
|
17
|
-
import { modalSettings } from "./resonators.ts";
|
|
17
|
+
import { modalSettings, windSettings } from "./resonators.ts";
|
|
18
|
+
import { slicePedals } from "./expression.ts";
|
|
18
19
|
import {
|
|
19
20
|
SCORE_LIMITS,
|
|
20
21
|
withNoteCap,
|
|
@@ -432,7 +433,10 @@ export function sectionScore(score: TrackScore, section: Section): TrackScore {
|
|
|
432
433
|
time: timed.time ?? null,
|
|
433
434
|
bars: section.bars,
|
|
434
435
|
tracks: score.tracks.map((track) =>
|
|
435
|
-
|
|
436
|
+
slicePedals(
|
|
437
|
+
mapAutomation(track, (points) => cropPoints(points, from, to)),
|
|
438
|
+
[{ from, to, offset: 0 }],
|
|
439
|
+
),
|
|
436
440
|
),
|
|
437
441
|
notes,
|
|
438
442
|
sections: [],
|
|
@@ -1251,7 +1255,9 @@ export function arrangedSlice(
|
|
|
1251
1255
|
tempoBpm: timed.tempoBpm,
|
|
1252
1256
|
time: timed.time ?? null,
|
|
1253
1257
|
bars,
|
|
1254
|
-
tracks: score.tracks.map((track) =>
|
|
1258
|
+
tracks: score.tracks.map((track) =>
|
|
1259
|
+
slicePedals(sliceLanes(track, pieces), pieces),
|
|
1260
|
+
),
|
|
1255
1261
|
notes: arrangedNotes(score, fromBar, fromBar + noteBars).map((note) => ({
|
|
1256
1262
|
...note,
|
|
1257
1263
|
startTick: note.startTick - shift,
|
|
@@ -1333,7 +1339,9 @@ function laneFallback(track: Track, lane: string): number | undefined {
|
|
|
1333
1339
|
? track.keys
|
|
1334
1340
|
: spec.effect === "modal"
|
|
1335
1341
|
? track.modal && modalSettings(track.modal)
|
|
1336
|
-
:
|
|
1342
|
+
: spec.effect === "wind"
|
|
1343
|
+
? track.wind && windSettings(track.wind)
|
|
1344
|
+
: (track.fx as Record<string, unknown> | undefined)?.[spec.effect]
|
|
1337
1345
|
) as Record<string, unknown> | undefined;
|
|
1338
1346
|
const stored = source?.[spec.param];
|
|
1339
1347
|
return typeof stored === "number" ? stored : spec.spec.default;
|
package/core/strings.ts
CHANGED
|
@@ -31,9 +31,9 @@ export const STRING_PARAMS: Readonly<Record<string, ParamSpec>> = Object.freeze(
|
|
|
31
31
|
{
|
|
32
32
|
exciter: {
|
|
33
33
|
kind: "enum",
|
|
34
|
-
values: ["pick", "finger", "hammer", "noise"],
|
|
34
|
+
values: ["pick", "finger", "hammer", "noise", "bow"],
|
|
35
35
|
default: "pick",
|
|
36
|
-
doc: "how the string is set in motion",
|
|
36
|
+
doc: "how the string is set in motion (bow: the bowed voice)",
|
|
37
37
|
},
|
|
38
38
|
ring: {
|
|
39
39
|
kind: "number",
|
|
@@ -276,6 +276,63 @@ export const STRING_PARAMS: Readonly<Record<string, ParamSpec>> = Object.freeze(
|
|
|
276
276
|
doc: "output level (presets carry a calibrated trim)",
|
|
277
277
|
strudel: ["gain"],
|
|
278
278
|
},
|
|
279
|
+
// ---- bowed (f061-bowed): read only when exciter is bow ----
|
|
280
|
+
pressure: {
|
|
281
|
+
kind: "number",
|
|
282
|
+
min: 0,
|
|
283
|
+
max: 1,
|
|
284
|
+
default: 0.5,
|
|
285
|
+
step: 0.05,
|
|
286
|
+
automate: true,
|
|
287
|
+
doc: "bow force within the playable range: flautando at 0, gritty at 1",
|
|
288
|
+
},
|
|
289
|
+
speed: {
|
|
290
|
+
kind: "number",
|
|
291
|
+
min: 0,
|
|
292
|
+
max: 1,
|
|
293
|
+
default: 0.6,
|
|
294
|
+
step: 0.05,
|
|
295
|
+
automate: true,
|
|
296
|
+
doc: "bow speed at full dynamics (loudness)",
|
|
297
|
+
},
|
|
298
|
+
attack: {
|
|
299
|
+
kind: "number",
|
|
300
|
+
min: 0.005,
|
|
301
|
+
max: 4,
|
|
302
|
+
default: 0.08,
|
|
303
|
+
step: log,
|
|
304
|
+
unit: "s",
|
|
305
|
+
doc: "bow-speed ramp at the start of a stroke (swells)",
|
|
306
|
+
strudel: ["attack"],
|
|
307
|
+
},
|
|
308
|
+
tremhz: {
|
|
309
|
+
kind: "number",
|
|
310
|
+
min: 0,
|
|
311
|
+
max: 16,
|
|
312
|
+
default: 0,
|
|
313
|
+
step: 0.5,
|
|
314
|
+
unit: "Hz",
|
|
315
|
+
doc: "tremolo bowing: rapid up and down strokes per second (0 off)",
|
|
316
|
+
},
|
|
317
|
+
sord: {
|
|
318
|
+
kind: "number",
|
|
319
|
+
min: 0,
|
|
320
|
+
max: 1,
|
|
321
|
+
default: 0,
|
|
322
|
+
step: 0.05,
|
|
323
|
+
automate: true,
|
|
324
|
+
doc: "con sordino: the practice mute, darker and softer",
|
|
325
|
+
},
|
|
326
|
+
dyn: {
|
|
327
|
+
kind: "number",
|
|
328
|
+
min: 0,
|
|
329
|
+
max: 1,
|
|
330
|
+
default: 1,
|
|
331
|
+
step: 0.05,
|
|
332
|
+
automate: true,
|
|
333
|
+
doc: "dynamics on top of velocity, drives bow speed and pressure (swells)",
|
|
334
|
+
strudel: ["expression"],
|
|
335
|
+
},
|
|
279
336
|
},
|
|
280
337
|
);
|
|
281
338
|
|
|
@@ -291,6 +348,21 @@ export const STRING_SIMPLE_PARAMS: readonly string[] = Object.freeze([
|
|
|
291
348
|
"sym",
|
|
292
349
|
]);
|
|
293
350
|
|
|
351
|
+
/** Simple menu rows of a bowed track (exciter bow, 0.6.1). */
|
|
352
|
+
export const BOW_SIMPLE_PARAMS: readonly string[] = Object.freeze([
|
|
353
|
+
"pressure",
|
|
354
|
+
"speed",
|
|
355
|
+
"attack",
|
|
356
|
+
"pos",
|
|
357
|
+
"vib",
|
|
358
|
+
"tremhz",
|
|
359
|
+
"sord",
|
|
360
|
+
"dyn",
|
|
361
|
+
"bright",
|
|
362
|
+
"ring",
|
|
363
|
+
"body",
|
|
364
|
+
]);
|
|
365
|
+
|
|
294
366
|
/** Parameter name for a Strudel alias (`decay` -> `ring`), or the name. */
|
|
295
367
|
export function stringParamName(word: string): string | undefined {
|
|
296
368
|
if (STRING_PARAMS[word]) return word;
|
|
@@ -358,6 +430,37 @@ function preset(
|
|
|
358
430
|
});
|
|
359
431
|
}
|
|
360
432
|
|
|
433
|
+
// Bowed base (proto/strings/presets.ts `B`, 0.6.1): the bowed rows start
|
|
434
|
+
// here, so BASE and every plucked row stay byte-identical.
|
|
435
|
+
const BOW_BASE: StringValues = {
|
|
436
|
+
...BASE,
|
|
437
|
+
exciter: "bow",
|
|
438
|
+
ring: 0.6,
|
|
439
|
+
damp: 0.5,
|
|
440
|
+
pos: 0.12,
|
|
441
|
+
release: 0.15,
|
|
442
|
+
pressure: 0.5,
|
|
443
|
+
speed: 0.6,
|
|
444
|
+
attack: 0.08,
|
|
445
|
+
vib: 5.5,
|
|
446
|
+
vibmod: 0.18,
|
|
447
|
+
vibdelay: 0.25,
|
|
448
|
+
body: "violin",
|
|
449
|
+
voices: 4,
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
function bowed(
|
|
453
|
+
doc: string,
|
|
454
|
+
styles: string,
|
|
455
|
+
values: StringValues,
|
|
456
|
+
): StringPreset {
|
|
457
|
+
return Object.freeze({
|
|
458
|
+
doc,
|
|
459
|
+
styles,
|
|
460
|
+
values: Object.freeze({ ...BOW_BASE, ...values }),
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
|
|
361
464
|
/**
|
|
362
465
|
* The plucked presets, ported from the prototype (stiffness rewritten from
|
|
363
466
|
* B = 0.002 s^2 to the 1e-6 x 400^stiff scale, `gain` is the per-preset
|
|
@@ -738,6 +841,122 @@ export const STRING_PRESETS: Readonly<Record<string, StringPreset>> =
|
|
|
738
841
|
gain: 0.36,
|
|
739
842
|
},
|
|
740
843
|
),
|
|
844
|
+
// ---- bowed (0.6.1, f061-bowed): appended, earlier rows unchanged ----
|
|
845
|
+
violin: bowed("solo violin", "Bach, Brahms, Shostakovich, cantatas", {
|
|
846
|
+
gain: 0.393,
|
|
847
|
+
}),
|
|
848
|
+
viola: bowed("solo viola", "orchestral, chamber", {
|
|
849
|
+
vib: 5.2,
|
|
850
|
+
size: 1.22,
|
|
851
|
+
gain: 0.537,
|
|
852
|
+
}),
|
|
853
|
+
cello: bowed(
|
|
854
|
+
"solo cello",
|
|
855
|
+
"Bach suites, Brahms, Shostakovich, Mitski ballads",
|
|
856
|
+
{ ring: 0.9, pos: 0.1, vib: 5, vibmod: 0.2, size: 2.4, gain: 0.415 },
|
|
857
|
+
),
|
|
858
|
+
contrabass: bowed("arco double bass", "orchestral bass", {
|
|
859
|
+
ring: 1.2,
|
|
860
|
+
pos: 0.1,
|
|
861
|
+
vib: 4.5,
|
|
862
|
+
vibmod: 0.12,
|
|
863
|
+
body: "bass",
|
|
864
|
+
size: 1.2,
|
|
865
|
+
voices: 2,
|
|
866
|
+
gain: 0.316,
|
|
867
|
+
}),
|
|
868
|
+
fiddle: bowed("folk fiddle, straight tone, firm bow", "celtic, bluegrass", {
|
|
869
|
+
pressure: 0.65,
|
|
870
|
+
pos: 0.1,
|
|
871
|
+
attack: 0.03,
|
|
872
|
+
vib: 0,
|
|
873
|
+
gain: 0.504,
|
|
874
|
+
}),
|
|
875
|
+
erhu: bowed("erhu, skin body, wide vibrato", "Chinese, film", {
|
|
876
|
+
pressure: 0.45,
|
|
877
|
+
pos: 0.1,
|
|
878
|
+
vib: 6,
|
|
879
|
+
vibmod: 0.35,
|
|
880
|
+
vibdelay: 0.15,
|
|
881
|
+
body: "skin",
|
|
882
|
+
size: 0.77,
|
|
883
|
+
voices: 2,
|
|
884
|
+
gain: 0.347,
|
|
885
|
+
}),
|
|
886
|
+
kamancheh: bowed("kamancheh spike fiddle", "Persian", {
|
|
887
|
+
pressure: 0.55,
|
|
888
|
+
pos: 0.1,
|
|
889
|
+
vib: 6.5,
|
|
890
|
+
vibmod: 0.25,
|
|
891
|
+
vibdelay: 0.1,
|
|
892
|
+
body: "skin",
|
|
893
|
+
voices: 2,
|
|
894
|
+
gain: 0.43,
|
|
895
|
+
}),
|
|
896
|
+
violins: bowed(
|
|
897
|
+
"violin section",
|
|
898
|
+
"orchestral, Shostakovich, Beethoven, Brahms",
|
|
899
|
+
{ vibmod: 0.15, unison: 6, detune: 0.12, spread: 0.7, gain: 0.399 },
|
|
900
|
+
),
|
|
901
|
+
violas: bowed("viola section", "orchestral", {
|
|
902
|
+
vib: 5.2,
|
|
903
|
+
vibmod: 0.15,
|
|
904
|
+
size: 1.22,
|
|
905
|
+
unison: 4,
|
|
906
|
+
detune: 0.12,
|
|
907
|
+
spread: 0.6,
|
|
908
|
+
gain: 0.57,
|
|
909
|
+
}),
|
|
910
|
+
cellos: bowed("cello section", "orchestral, cantatas", {
|
|
911
|
+
ring: 0.9,
|
|
912
|
+
pos: 0.1,
|
|
913
|
+
vib: 5,
|
|
914
|
+
vibmod: 0.17,
|
|
915
|
+
size: 2.4,
|
|
916
|
+
unison: 4,
|
|
917
|
+
detune: 0.1,
|
|
918
|
+
spread: 0.6,
|
|
919
|
+
gain: 0.46,
|
|
920
|
+
}),
|
|
921
|
+
contrabasses: bowed("double bass section", "orchestral", {
|
|
922
|
+
ring: 1.2,
|
|
923
|
+
pos: 0.1,
|
|
924
|
+
vib: 4.5,
|
|
925
|
+
vibmod: 0.1,
|
|
926
|
+
body: "bass",
|
|
927
|
+
size: 1.2,
|
|
928
|
+
unison: 3,
|
|
929
|
+
detune: 0.08,
|
|
930
|
+
spread: 0.4,
|
|
931
|
+
voices: 2,
|
|
932
|
+
gain: 0.315,
|
|
933
|
+
}),
|
|
934
|
+
pizz: preset(
|
|
935
|
+
"pizzicato string section, plucked with the finger",
|
|
936
|
+
"orchestral, Motown strings, film",
|
|
937
|
+
{
|
|
938
|
+
exciter: "finger",
|
|
939
|
+
ring: 0.6,
|
|
940
|
+
damp: 0.5,
|
|
941
|
+
pos: 0.2,
|
|
942
|
+
bright: 0.45,
|
|
943
|
+
release: 0.08,
|
|
944
|
+
body: "violin",
|
|
945
|
+
unison: 4,
|
|
946
|
+
detune: 0.1,
|
|
947
|
+
spread: 0.6,
|
|
948
|
+
voices: 6,
|
|
949
|
+
gain: 0.497,
|
|
950
|
+
},
|
|
951
|
+
),
|
|
952
|
+
trem: bowed("tremolo string section, rapid bowing", "film, orchestral", {
|
|
953
|
+
tremhz: 13,
|
|
954
|
+
vibmod: 0.1,
|
|
955
|
+
unison: 4,
|
|
956
|
+
detune: 0.12,
|
|
957
|
+
spread: 0.6,
|
|
958
|
+
gain: 0.507,
|
|
959
|
+
}),
|
|
741
960
|
});
|
|
742
961
|
|
|
743
962
|
/** Preset names in table order. */
|
|
@@ -745,6 +964,17 @@ export const STRING_PRESET_NAMES: readonly string[] = Object.freeze(
|
|
|
745
964
|
Object.keys(STRING_PRESETS),
|
|
746
965
|
);
|
|
747
966
|
|
|
967
|
+
/**
|
|
968
|
+
* The bowed-family presets (0.6.1): the rows appended from `violin` on,
|
|
969
|
+
* `pizz` included (a plucked violin section, listed with its family).
|
|
970
|
+
*/
|
|
971
|
+
export const BOWED_PRESET_NAMES: readonly string[] = Object.freeze(
|
|
972
|
+
STRING_PRESET_NAMES.slice(STRING_PRESET_NAMES.indexOf("violin")),
|
|
973
|
+
);
|
|
974
|
+
|
|
975
|
+
/** The preset `bowed` with no name plays. */
|
|
976
|
+
export const DEFAULT_BOWED_PRESET = "cello";
|
|
977
|
+
|
|
748
978
|
/** The preset a bare `string: {}` plays. */
|
|
749
979
|
export const DEFAULT_STRING_PRESET = "nylon";
|
|
750
980
|
|
|
@@ -760,6 +990,11 @@ export const STRING_ALIASES: Readonly<Record<string, string>> = Object.freeze({
|
|
|
760
990
|
cembalo: "harpsichord",
|
|
761
991
|
hammered: "dulcimer",
|
|
762
992
|
sehtar: "setar",
|
|
993
|
+
// bowed (0.6.1); `strings`, `cello` and `contrabass` stay legacy words
|
|
994
|
+
kemence: "kamancheh",
|
|
995
|
+
pizzicato: "pizz",
|
|
996
|
+
tremolo: "trem",
|
|
997
|
+
"bowed-cello": "cello",
|
|
763
998
|
});
|
|
764
999
|
|
|
765
1000
|
/** A preset name for a word or alias, or undefined. */
|