@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
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* glide <ms>|off <target> portamento into each note
|
|
9
9
|
* glide <ms>|0|off [legato|mono|poly] the track's glide (`glide mono`)
|
|
10
10
|
* pedal <beat>-<beat>…|bars [<bar>-<bar>]|down|half|up <beat>|off
|
|
11
|
+
* pedal soft|sost <same forms> una corda and sostenuto (0.6.1)
|
|
11
12
|
* velcurve linear|soft|hard|fixed [<v>]
|
|
12
13
|
* humanize <ms> [<vel%> [<len%>]] [seed <n>]|on|off|reseed|seed <n>
|
|
13
14
|
* humanize <ms> [<vel%> [<len%>]]|exact|off <target> per-note amounts
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
normalizeBend,
|
|
33
34
|
normalizeHumanize,
|
|
34
35
|
normalizePedal,
|
|
36
|
+
SOSTENUTO_STATES,
|
|
35
37
|
normalizeTrackGlide,
|
|
36
38
|
normalizeVelocityCurve,
|
|
37
39
|
normalizeVibrato,
|
|
@@ -53,6 +55,7 @@ import {
|
|
|
53
55
|
type Note,
|
|
54
56
|
type Track,
|
|
55
57
|
} from "../../core/score.ts";
|
|
58
|
+
import { softPedalNote } from "../../core/keys.ts";
|
|
56
59
|
import { barStartTick, loopTicksOf } from "../../core/tempo.ts";
|
|
57
60
|
|
|
58
61
|
export type NoteTarget =
|
|
@@ -73,11 +76,15 @@ export type ExpressionCommand =
|
|
|
73
76
|
| { type: "vibrato"; vibrato: NoteVibrato | null; target: NoteTarget }
|
|
74
77
|
| { type: "note-glide"; glide: number | null; target: NoteTarget }
|
|
75
78
|
| { type: "track-glide"; time?: number | null; mode?: GlideMode }
|
|
76
|
-
| {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
| {
|
|
80
|
+
type: "pedal-spans";
|
|
81
|
+
spans: readonly { from: number; to: number }[];
|
|
82
|
+
lane?: PedalLane;
|
|
83
|
+
}
|
|
84
|
+
| { type: "pedal-bars"; from?: number; to?: number; lane?: PedalLane }
|
|
85
|
+
| { type: "pedal-list"; lane?: PedalLane }
|
|
86
|
+
| { type: "pedal-event"; state: PedalState; beat: number; lane?: PedalLane }
|
|
87
|
+
| { type: "pedal-off"; lane?: PedalLane }
|
|
81
88
|
| { type: "velcurve"; curve: VelocityCurveName; fixed?: number }
|
|
82
89
|
| {
|
|
83
90
|
type: "humanize";
|
|
@@ -299,7 +306,31 @@ function nearWord(text: string, word: string): boolean {
|
|
|
299
306
|
return previous[word.length]! <= 2;
|
|
300
307
|
}
|
|
301
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Which pedal a `pedal` command edits (0.6.1): absent is the sustain
|
|
311
|
+
* pedal, `soft` the una corda (Track.softPedal), `sost` the sostenuto.
|
|
312
|
+
*/
|
|
313
|
+
export type PedalLane = "soft" | "sost";
|
|
314
|
+
|
|
315
|
+
const PEDAL_LANES: Readonly<Record<string, PedalLane>> = {
|
|
316
|
+
soft: "soft",
|
|
317
|
+
unacorda: "soft",
|
|
318
|
+
sost: "sost",
|
|
319
|
+
sostenuto: "sost",
|
|
320
|
+
};
|
|
321
|
+
|
|
302
322
|
function parsePedal(words: string[]): ExpressionCommand | undefined {
|
|
323
|
+
const lane = words[0] ? PEDAL_LANES[words[0]] : undefined;
|
|
324
|
+
if (lane) {
|
|
325
|
+
const command = parsePedalLane(words.slice(1));
|
|
326
|
+
return command && command.type.startsWith("pedal-")
|
|
327
|
+
? ({ ...command, lane } as ExpressionCommand)
|
|
328
|
+
: undefined;
|
|
329
|
+
}
|
|
330
|
+
return parsePedalLane(words);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function parsePedalLane(words: string[]): ExpressionCommand | undefined {
|
|
303
334
|
const [first, ...rest] = words;
|
|
304
335
|
if (!first) return { type: "pedal-list" };
|
|
305
336
|
if (OFF.test(first) && rest.length === 0) return { type: "pedal-off" };
|
|
@@ -564,6 +595,16 @@ export function describePerformance(score: TrackScore, track: Track): string {
|
|
|
564
595
|
const parts = [
|
|
565
596
|
`glide ${track.glide ? `${ms(track.glide.time)} ${track.glide.mode}` : "off"}`,
|
|
566
597
|
`pedal ${track.pedal ? `${track.pedal.length} event${track.pedal.length === 1 ? "" : "s"}` : "off"}`,
|
|
598
|
+
...(track.softPedal
|
|
599
|
+
? [
|
|
600
|
+
`soft ${track.softPedal.length} event${track.softPedal.length === 1 ? "" : "s"}`,
|
|
601
|
+
]
|
|
602
|
+
: []),
|
|
603
|
+
...(track.sostenuto
|
|
604
|
+
? [
|
|
605
|
+
`sost ${track.sostenuto.length} event${track.sostenuto.length === 1 ? "" : "s"}`,
|
|
606
|
+
]
|
|
607
|
+
: []),
|
|
567
608
|
`velcurve ${track.velocityCurve ? `${track.velocityCurve.curve}${track.velocityCurve.fixed !== undefined ? ` ${track.velocityCurve.fixed}` : ""}` : "linear"}`,
|
|
568
609
|
`humanize ${describeHumanize(track.humanize)}`,
|
|
569
610
|
];
|
|
@@ -680,10 +721,24 @@ function mergePedal(
|
|
|
680
721
|
current: readonly PedalEvent[] | undefined,
|
|
681
722
|
added: readonly PedalEvent[],
|
|
682
723
|
maxTick: number,
|
|
724
|
+
label?: string,
|
|
725
|
+
states?: readonly PedalState[],
|
|
683
726
|
): readonly PedalEvent[] | undefined {
|
|
684
727
|
const byTick = new Map((current ?? []).map((event) => [event.tick, event]));
|
|
685
728
|
for (const event of added) byTick.set(event.tick, event);
|
|
686
|
-
return normalizePedal([...byTick.values()], maxTick);
|
|
729
|
+
return normalizePedal([...byTick.values()], maxTick, label, states);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/** The Track field, message label and allowed states of a pedal lane. */
|
|
733
|
+
function pedalLaneOf(lane: PedalLane | undefined): {
|
|
734
|
+
field: "pedal" | "softPedal" | "sostenuto";
|
|
735
|
+
label: string;
|
|
736
|
+
states?: readonly PedalState[];
|
|
737
|
+
} {
|
|
738
|
+
if (lane === "soft") return { field: "softPedal", label: "soft pedal" };
|
|
739
|
+
if (lane === "sost")
|
|
740
|
+
return { field: "sostenuto", label: "sostenuto", states: SOSTENUTO_STATES };
|
|
741
|
+
return { field: "pedal", label: "pedal" };
|
|
687
742
|
}
|
|
688
743
|
|
|
689
744
|
/** Apply `command` to the focused track `trackId`. */
|
|
@@ -771,11 +826,12 @@ export function applyExpressionCommand(
|
|
|
771
826
|
);
|
|
772
827
|
}
|
|
773
828
|
case "pedal-list": {
|
|
774
|
-
const
|
|
829
|
+
const { field, label } = pedalLaneOf(command.lane);
|
|
830
|
+
const events = track[field] ?? [];
|
|
775
831
|
if (events.length === 0)
|
|
776
832
|
return {
|
|
777
833
|
ok: true,
|
|
778
|
-
message:
|
|
834
|
+
message: `${label} · none on ${trackId} · ${command.lane ? `pedal ${command.lane} 0-4` : "pedal bars"} to add`,
|
|
779
835
|
};
|
|
780
836
|
const shown = events
|
|
781
837
|
.slice(0, 12)
|
|
@@ -784,24 +840,45 @@ export function applyExpressionCommand(
|
|
|
784
840
|
`${Math.round((event.tick / score.ticksPerBeat) * 1000) / 1000} ${event.state}`,
|
|
785
841
|
);
|
|
786
842
|
if (events.length > 12) shown.push(`+${events.length - 12} more`);
|
|
787
|
-
return {
|
|
843
|
+
return {
|
|
844
|
+
ok: true,
|
|
845
|
+
message: `${label} · ${shown.join(" · ")} · ${trackId}`,
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
case "pedal-off": {
|
|
849
|
+
const { field, label } = pedalLaneOf(command.lane);
|
|
850
|
+
return track[field]
|
|
851
|
+
? trackResult(
|
|
852
|
+
score,
|
|
853
|
+
track,
|
|
854
|
+
{ [field]: null },
|
|
855
|
+
`${label} · off · ${trackId}`,
|
|
856
|
+
)
|
|
857
|
+
: { ok: true, message: `${label} · already off · ${trackId}` };
|
|
788
858
|
}
|
|
789
|
-
case "pedal-off":
|
|
790
|
-
return track.pedal
|
|
791
|
-
? trackResult(score, track, { pedal: null }, `pedal · off · ${trackId}`)
|
|
792
|
-
: { ok: true, message: `pedal · already off · ${trackId}` };
|
|
793
859
|
case "pedal-spans":
|
|
794
860
|
case "pedal-bars":
|
|
795
861
|
case "pedal-event": {
|
|
862
|
+
const { field, label, states } = pedalLaneOf(command.lane);
|
|
796
863
|
let added: PedalEvent[];
|
|
797
864
|
if (command.type === "pedal-bars") {
|
|
798
865
|
const from = command.from ?? 1;
|
|
799
866
|
if (from > score.bars)
|
|
800
867
|
return {
|
|
801
868
|
ok: false,
|
|
802
|
-
message:
|
|
869
|
+
message: `${label} · the loop has ${score.bars} bar${score.bars === 1 ? "" : "s"}`,
|
|
803
870
|
};
|
|
804
|
-
|
|
871
|
+
const to = Math.min(command.to ?? score.bars, score.bars);
|
|
872
|
+
// Soft and sostenuto hold through the bars (no re-pedalling).
|
|
873
|
+
added = command.lane
|
|
874
|
+
? [
|
|
875
|
+
{ tick: barStartTick(score, from - 1), state: "down" },
|
|
876
|
+
{
|
|
877
|
+
tick: Math.min(barStartTick(score, to), maxTick),
|
|
878
|
+
state: "up",
|
|
879
|
+
},
|
|
880
|
+
]
|
|
881
|
+
: barPedal(score, from, to);
|
|
805
882
|
} else if (command.type === "pedal-event") {
|
|
806
883
|
added = [
|
|
807
884
|
{ tick: Math.round(command.beat * tpb), state: command.state },
|
|
@@ -815,7 +892,7 @@ export function applyExpressionCommand(
|
|
|
815
892
|
if (added.some((event) => event.tick > maxTick))
|
|
816
893
|
return {
|
|
817
894
|
ok: false,
|
|
818
|
-
message:
|
|
895
|
+
message: `${label} · beats run 0..${maxTick / tpb} in this loop`,
|
|
819
896
|
};
|
|
820
897
|
let pedal: readonly PedalEvent[] | undefined;
|
|
821
898
|
try {
|
|
@@ -825,11 +902,11 @@ export function applyExpressionCommand(
|
|
|
825
902
|
command.type === "pedal-bars" &&
|
|
826
903
|
command.from === undefined &&
|
|
827
904
|
command.to === undefined
|
|
828
|
-
? normalizePedal(added, maxTick)
|
|
829
|
-
: mergePedal(track
|
|
905
|
+
? normalizePedal(added, maxTick, field, states)
|
|
906
|
+
: mergePedal(track[field], added, maxTick, field, states);
|
|
830
907
|
} catch (error) {
|
|
831
908
|
if (error instanceof ExpressionValidationError)
|
|
832
|
-
return { ok: false, message:
|
|
909
|
+
return { ok: false, message: `${label} · ${error.message}` };
|
|
833
910
|
throw error;
|
|
834
911
|
}
|
|
835
912
|
const downs = (pedal ?? []).filter((event) => event.state === "down");
|
|
@@ -840,11 +917,15 @@ export function applyExpressionCommand(
|
|
|
840
917
|
: []),
|
|
841
918
|
...(halves.length > 0 ? [`${halves.length} half`] : []),
|
|
842
919
|
].join(", ");
|
|
920
|
+
// Una corda is stored anyway (an instrument change may follow), but
|
|
921
|
+
// say when nothing will sound different.
|
|
922
|
+
const silent =
|
|
923
|
+
field === "softPedal" && pedal ? softPedalNote(track) : undefined;
|
|
843
924
|
return trackResult(
|
|
844
925
|
score,
|
|
845
926
|
track,
|
|
846
|
-
{
|
|
847
|
-
|
|
927
|
+
{ [field]: pedal ?? null },
|
|
928
|
+
`${label} · ${pedal?.length ?? 0} event${pedal?.length === 1 ? "" : "s"} (${held}) · ${trackId}${silent ? ` · no effect: ${silent}` : ""}`,
|
|
848
929
|
);
|
|
849
930
|
}
|
|
850
931
|
case "velcurve": {
|
|
@@ -933,7 +1014,7 @@ export const EXPRESSION_USAGE = Object.freeze({
|
|
|
933
1014
|
glide:
|
|
934
1015
|
"glide <ms>|<s>s|off [legato|mono|poly] (track) · glide <ms>|off <target> (notes) · glide 60 mono · SDK glide: 0.06 (s)",
|
|
935
1016
|
pedal:
|
|
936
|
-
"pedal <beat>-<beat>…|bars [<bar>-<bar>]|down|half|up <beat>|off · pedal 0-3.5 4-7.5 · pedal bars",
|
|
1017
|
+
"pedal [soft|sost] <beat>-<beat>…|bars [<bar>-<bar>]|down|half|up <beat>|off · pedal 0-3.5 4-7.5 · pedal bars · pedal soft 0-8 (una corda) · pedal sost 0-4 (holds keys down at 0)",
|
|
937
1018
|
velcurve:
|
|
938
1019
|
"velcurve linear|soft|hard|fixed [<v 0..1>] · velcurve soft · velcurve fixed 0.8",
|
|
939
1020
|
humanize:
|
package/src/commands/fx.ts
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
* fx list the focused track's effects
|
|
5
5
|
* fx <effect> on|off|reset enable with defaults, remove, reset
|
|
6
6
|
* fx <effect> preset <name> load a named preset (FX_PRESETS)
|
|
7
|
+
* fx <effect> turn it on (same as `on`)
|
|
7
8
|
* fx <effect> <param> <value> set one parameter (enables it)
|
|
8
9
|
* fx <effect> <number> set its first parameter (`fx orbit 2`)
|
|
9
10
|
* fx <effect> <param> <value> <param> <value>… several at once
|
|
10
11
|
* fx reverb ir <impulse>|off convolution reverb (Strudel `ir`):
|
|
11
|
-
* room|hall|plate, a pack sound or a
|
|
12
|
+
* room|hall|plate|reverse|gate|spring, a pack sound or a
|
|
12
13
|
* project file; `fx ir hall` too
|
|
13
14
|
*
|
|
14
15
|
* Effects are every `FX_CHAIN` stage except pan (see core/fx.ts), plus
|
|
@@ -147,6 +148,8 @@ export function parseFxCommand(prompt: string): FxCommand | undefined {
|
|
|
147
148
|
if (effect === "reverb" && irWord(words[2]) && words.length === 4)
|
|
148
149
|
return irCommand(words[3]!);
|
|
149
150
|
const rest = words.slice(2).map((word) => word.toLowerCase());
|
|
151
|
+
// `fx wobble`, `fx double`: a bare effect name turns it on.
|
|
152
|
+
if (rest.length === 0) return { type: "fx-on", effect };
|
|
150
153
|
if (rest.length === 1 && (rest[0] === "on" || rest[0] === "off"))
|
|
151
154
|
return { type: rest[0] === "on" ? "fx-on" : "fx-off", effect };
|
|
152
155
|
if (rest.length === 1 && rest[0] === "reset")
|
package/src/commands/granular.ts
CHANGED
|
@@ -160,7 +160,9 @@ export function parseGranularCommand(
|
|
|
160
160
|
const name = rest[index]!;
|
|
161
161
|
const spec = GRANULAR_PARAMS[name];
|
|
162
162
|
if (!spec) return undefined;
|
|
163
|
-
|
|
163
|
+
// Dotted note values as the rest of dawg writes them: `1/8.` is `1/8d`.
|
|
164
|
+
const word =
|
|
165
|
+
name === "sync" ? rest[index + 1]!.replace(/\.$/, "d") : rest[index + 1]!;
|
|
164
166
|
if ((word === "off" || word === "unset") && spec.kind !== "boolean") {
|
|
165
167
|
values[name] = null;
|
|
166
168
|
continue;
|
|
@@ -170,7 +172,10 @@ export function parseGranularCommand(
|
|
|
170
172
|
? noteNumber(word)
|
|
171
173
|
: parseParamValue(spec, word);
|
|
172
174
|
if (value === undefined) return undefined;
|
|
173
|
-
|
|
175
|
+
// 0.6.1 switches: off removes the field, so on-then-off leaves the
|
|
176
|
+
// score (and its sha256) as it was.
|
|
177
|
+
values[name] =
|
|
178
|
+
value === false && (name === "mono" || name === "pedal") ? null : value;
|
|
174
179
|
}
|
|
175
180
|
return { type: "grain-set", values };
|
|
176
181
|
}
|
package/src/commands/help.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* app commands take a slash (bare aliases keep working but are listed once,
|
|
5
5
|
* in their canonical form).
|
|
6
6
|
*/
|
|
7
|
+
import { GUITAR_TUNING_NAMES } from "../../core/chords.ts";
|
|
7
8
|
import { EXPRESSION_USAGE } from "./expression.ts";
|
|
8
9
|
|
|
9
10
|
export type HelpGroup = "music" | "session" | "window" | "keys";
|
|
@@ -72,10 +73,30 @@ export const HELP_SECTIONS: readonly HelpSection[] = [
|
|
|
72
73
|
summary:
|
|
73
74
|
"plucked strings · string sitar · string buzz 0.8 · string ring 6",
|
|
74
75
|
},
|
|
76
|
+
{
|
|
77
|
+
command: "bowed [<preset>] | <param> <value> | presets",
|
|
78
|
+
summary:
|
|
79
|
+
"bowed strings · bowed violin · bowed cellos · bowed pressure 0.7 · bowed sord 1",
|
|
80
|
+
},
|
|
75
81
|
{
|
|
76
82
|
command: "rig <preset> | reset",
|
|
77
83
|
summary:
|
|
78
|
-
"guitar rig · rig crunch · rig metal · rig
|
|
84
|
+
"guitar rig · rig crunch · rig metal · rig shoegaze · rig lists them",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
command:
|
|
88
|
+
"guitar tune <name|notes> | capo | hand | ring | position | reset",
|
|
89
|
+
summary: "guitar fretting · guitar tune dadgad · guitar capo 2",
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
command: "strum [chords] [pattern] [strokes D-DU-UDU] [speed 22ms]",
|
|
93
|
+
summary:
|
|
94
|
+
"strummed guitar chords · strum G D Em C folk · strum I V vi IV · strum alone strums the track's chords",
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
command: "fx wobble|bloom|swell|double [param value]",
|
|
98
|
+
summary:
|
|
99
|
+
"shoegaze · fx wobble depth 30 · fx double · fx reverb ir builtin:reverse",
|
|
79
100
|
},
|
|
80
101
|
{
|
|
81
102
|
command: "track jangle|punk|funk|ragged|gtr-lead|gtr-metal|bachata",
|
|
@@ -94,12 +115,33 @@ export const HELP_SECTIONS: readonly HelpSection[] = [
|
|
|
94
115
|
command: "keys <param> <value> | preset <name> | reset",
|
|
95
116
|
summary: "piano params · keys hardness 0.3 decay 1.5 · keys lists them",
|
|
96
117
|
},
|
|
118
|
+
{
|
|
119
|
+
command: "epiano|wurli|clav [preset <name>] | <param> <value>",
|
|
120
|
+
summary:
|
|
121
|
+
"electric keys · suitcase dyno funkclav · epiano vibe 0.6 · clav pickup bridge",
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
command:
|
|
125
|
+
"tonewheel [<drawbars>] | combo [<registers>] [<voice>] | pipe [<stops>] [<row> <value> …]",
|
|
126
|
+
summary:
|
|
127
|
+
"organs · tonewheel 888800008 perc 3rd · gospel · combo 08880 flute · pipe plenum · keys perc 3rd",
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
command: "rotary slow|fast|stop [at <beat>]",
|
|
131
|
+
summary:
|
|
132
|
+
"organ rotary speaker speed · rotary fast at 16 writes the keys-rotary lane",
|
|
133
|
+
},
|
|
97
134
|
{
|
|
98
135
|
command:
|
|
99
136
|
"modal <preset> | <param> <value> | mallet <name> | reset | off",
|
|
100
137
|
summary:
|
|
101
138
|
"mallets and bells · modal vibes · modal hardness 0.8 · modal presets",
|
|
102
139
|
},
|
|
140
|
+
{
|
|
141
|
+
command: "wind <preset> | <param> <value> | mute <name> | reset | off",
|
|
142
|
+
summary:
|
|
143
|
+
"winds and brass · wind flute · wind sax · wind players 4 · wind presets",
|
|
144
|
+
},
|
|
103
145
|
{
|
|
104
146
|
command: "art <articulation>|off [target]",
|
|
105
147
|
summary:
|
|
@@ -122,6 +164,11 @@ export const HELP_SECTIONS: readonly HelpSection[] = [
|
|
|
122
164
|
command: "pedal <beat>-<beat>... | bars | down|half|up <beat> | off",
|
|
123
165
|
summary: "sustain pedal · pedal 0-3.5 4-7.5 · pedal bars",
|
|
124
166
|
},
|
|
167
|
+
{
|
|
168
|
+
command: "pedal soft|sost <beat>-<beat>... | bars | off",
|
|
169
|
+
summary:
|
|
170
|
+
"piano una corda and sostenuto · pedal soft 0-8 · pedal sost 0-4",
|
|
171
|
+
},
|
|
125
172
|
{
|
|
126
173
|
command: "velcurve linear|soft|hard|fixed [<v>]",
|
|
127
174
|
summary: "how velocity maps to level · velcurve fixed 0.6 (0..1)",
|
|
@@ -242,6 +289,20 @@ export const HELP_SECTIONS: readonly HelpSection[] = [
|
|
|
242
289
|
summary: "repeats pace accent prob swing …",
|
|
243
290
|
},
|
|
244
291
|
{ command: "grid <voice> <x.X.>", summary: "explicit steps · X accent" },
|
|
292
|
+
{
|
|
293
|
+
command: "shift <semitones> [formant keep|follow|<n>] [<voice>]",
|
|
294
|
+
summary:
|
|
295
|
+
"a sample's pitch without changing its length · shift 0 clears",
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
command: "fade [in|out] <seconds> [<voice>]",
|
|
299
|
+
summary: "a sample's fade in and out (Strudel fadeInTime/fadeTime)",
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
command:
|
|
303
|
+
"resample <track>|orbit <n>|master [section <name>|bars a-b] [grain]",
|
|
304
|
+
summary: "render to a pinned WAV on a new sampler (or granular) track",
|
|
305
|
+
},
|
|
245
306
|
{ command: "undo", summary: "step back · Ctrl-Z" },
|
|
246
307
|
{ command: "redo", summary: "step forward · Ctrl-Y" },
|
|
247
308
|
],
|
|
@@ -603,7 +664,7 @@ export const USAGE: Readonly<Record<string, string>> = {
|
|
|
603
664
|
click: "/click on|off|<volume> · /click 50%",
|
|
604
665
|
"count-in": "/count-in 0|1|2",
|
|
605
666
|
chords:
|
|
606
|
-
"/chords auto|manual|off · voicing <n> · spread · bass · perform · rate · octaves · sevenths · preset · style",
|
|
667
|
+
"/chords auto|manual|off · voicing <n> · spread · bass · perform · rate · octaves · sevenths · preset · style · strokes · speed",
|
|
607
668
|
key: "key <tonic> <mode> | none · key A minor",
|
|
608
669
|
scale: "scale [<tonic>] <name> | list · scale D hijaz",
|
|
609
670
|
tuning:
|
|
@@ -635,14 +696,14 @@ export const USAGE: Readonly<Record<string, string>> = {
|
|
|
635
696
|
bars: "bars takes 1…256 · bars 8",
|
|
636
697
|
extend: "extend <count> bars · extend 4 bars",
|
|
637
698
|
instrument:
|
|
638
|
-
"instrument <name> · sine piano pluck bass saw square triangle wavetable kit · pianos: grand upright felt honkytonk prepared · synth: sawtooth supersaw pulse white pink z_square…",
|
|
699
|
+
"instrument <name> · sine piano pluck bass saw square triangle wavetable kit · pianos: grand upright felt honkytonk prepared · electric: epiano suitcase dyno wurli clav funkclav · synth: sawtooth supersaw pulse white pink z_square…",
|
|
639
700
|
volume: "volume takes 0…1 · volume 0.8",
|
|
640
701
|
vol: "volume takes 0…1 · volume 0.8",
|
|
641
702
|
pan: "pan takes -1…1 · pan -0.5",
|
|
642
703
|
wt: "wt <table> | wt <0..1> | wt list · wt basic · wt wt_digital:2",
|
|
643
704
|
wavetable: "wt <table> | wt <0..1> | wt list · wt basic · wt wt_digital:2",
|
|
644
705
|
grain:
|
|
645
|
-
"grain <preset> | <param> <value> | on [voice V] | src synth:<name>|voice V | reset | off | presets · grain cloud · grain pitch 12",
|
|
706
|
+
"grain <preset> | <param> <value> | on [voice V] | src synth:<name>|voice V | reset | off | presets · sync 1/64…1/1 (t triplet, d or . dotted) · grain cloud · grain pitch 12 · grain sync 1/8.",
|
|
646
707
|
granular:
|
|
647
708
|
"grain <preset> | <param> <value> | on [voice V] | src synth:<name>|voice V | reset | off | presets · grain cloud",
|
|
648
709
|
warpmode: "warpmode none|asym|bendp|bendm|bendmp|sync|quant",
|
|
@@ -665,11 +726,17 @@ export const USAGE: Readonly<Record<string, string>> = {
|
|
|
665
726
|
export: "/export <file> · /export loop.track.json",
|
|
666
727
|
import: "/import <file> · /import loop.track.json",
|
|
667
728
|
sample:
|
|
668
|
-
"/sample <path> [as <voice>] · /sample set <voice> <control> <value>… · /sample set brk fit on clip 1",
|
|
729
|
+
"/sample <path> [as <voice>] · /sample set <voice> <control> <value>… · /sample set brk fit on clip 1 · /sample set soft vel 0-63 rr a",
|
|
669
730
|
samples: "/sample · lists the focused track's voices",
|
|
670
731
|
fitmode:
|
|
671
732
|
"/fitmode [repitch|beats|tones|auto|off] [<voice>] · /fitmode beats · /fitmode auto brk",
|
|
672
733
|
len: "/len <beats> [<voice>] · /len 16 · /len off",
|
|
734
|
+
shift:
|
|
735
|
+
"shift <semitones> [formant keep|follow|<n>] [<voice>] · shift 7 formant keep · shift 0",
|
|
736
|
+
fade: "fade [in|out] <seconds> [<voice>] · fade out 0.5 · fade in 0.05 · fade off",
|
|
737
|
+
resample:
|
|
738
|
+
"resample <track>|orbit <n>|master [section <name>|bars a-b] [post] [grain] [as <id>] · resample lead · resample drums bars 1-2 grain · resample master section chorus",
|
|
739
|
+
bounce: "resample <track>|orbit <n>|master [section <name>|bars a-b] [grain]",
|
|
673
740
|
view: "/view focus | all",
|
|
674
741
|
transcript: "/transcript",
|
|
675
742
|
log: "/transcript",
|
|
@@ -685,16 +752,32 @@ export const USAGE: Readonly<Record<string, string>> = {
|
|
|
685
752
|
synth: "synth <param> <value> | preset <name> · synth lpf 1200",
|
|
686
753
|
string:
|
|
687
754
|
"string <preset> | preset <name> | <param> <value> | presets | reset | off · string koto",
|
|
688
|
-
|
|
755
|
+
bowed:
|
|
756
|
+
"bowed [violin|viola|cello|contrabass|fiddle|erhu|kamancheh|violins|violas|cellos|contrabasses|pizz|trem] | <param> <value> | presets · bowed violin · bowed pressure 0.7",
|
|
757
|
+
rig: "rig clean|crunch|punk|ragged|lead|metal|fuzz|octave|funk|wah|bachata|spring|bassdrive|reese|jangle|alt|shoegaze|glide|dreampop|swell|ebow | reset",
|
|
758
|
+
guitar: `guitar tune ${GUITAR_TUNING_NAMES.join("|")} | E A D G B E · capo 0..12 · hand 3..6 · ring 0..1 · position · reset`,
|
|
759
|
+
strum:
|
|
760
|
+
"strum G D Em C [folk|pop|punk|…] [strokes D-DU-UDU] [speed 22ms] [each 4] [at 0] · strum alone strums the track's chords",
|
|
689
761
|
stomp:
|
|
690
762
|
"stomp fuzz|face|od|rat|octave | gain <0-10> tone <0-1> level <dB> | off",
|
|
691
763
|
head: "head clean|chime|crunch|lead|high|solid|bass | gain bass mid treble presence master <0-10> | gate <dB> | off",
|
|
692
764
|
cab: "cab 1x12|2x12|4x12|1x10|open|8x10|1x15|di | mic <0-1> | off",
|
|
693
|
-
keys: "keys <param> <value> | preset <name> | reset | presets · keys hardness 0.3 · keys stretch 0",
|
|
765
|
+
keys: "keys <param> <value> | preset <name> | reset | presets · keys hardness 0.3 · keys stretch 0 · keys sym 0.5 (sympathetic bloom under the sustain pedal)",
|
|
694
766
|
piano:
|
|
695
767
|
"piano [grand|ballad|upright|felt|lofi|honkytonk|prepared] · piano ballad",
|
|
768
|
+
epiano:
|
|
769
|
+
"epiano [preset epiano|suitcase|dyno] | bark bell tone vibe vibehz decay release <value> · epiano vibe 0.6 · rhodes",
|
|
770
|
+
wurli:
|
|
771
|
+
"wurli [preset wurli] | bark bell tone trem decay release <value> · wurli trem 0.5",
|
|
772
|
+
clav: "clav [preset clav|funkclav] | pickup neck|bridge|both|out | mute tone decay release <value> · clav pickup bridge",
|
|
773
|
+
tonewheel:
|
|
774
|
+
"tonewheel [<9 drawbar digits>] | hammond | b3 | gospel | jazzorgan · tonewheel 888800008",
|
|
775
|
+
combo: "combo [<5 register digits>] | farfisa | vox · combo 08880",
|
|
776
|
+
pipe: "pipe [plenum|flutes|cornet|reeds|strings|full | <stop> …] | church · pipe principal8,octave4",
|
|
777
|
+
rotary: "rotary slow|fast|stop [at <beat>] · rotary fast · rotary fast at 16",
|
|
696
778
|
modal:
|
|
697
|
-
"modal <preset> | <body> | <param> <value> | mallet <name> | reset | off | presets · modal vibes · modal
|
|
779
|
+
"modal <preset> | <body> | <param> <value> | mallet <name> | pair <track> | gamelan | reset | off | presets · modal vibes · modal gangsa · modal ring 3",
|
|
780
|
+
wind: "wind <preset> | <param> <value> | mute <name> | reset | off | presets · wind flute · wind trumpet mute harmon · wind players 4",
|
|
698
781
|
pack: "/pack list | info <name> | use <pack>/<sound> | add <url>",
|
|
699
782
|
kit: "/kit [name] · /kit syn909",
|
|
700
783
|
euclid: "/euclid [voice] · euclid hat 7 16",
|