@hraness/dawg 0.6.0 → 0.7.0
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 +126 -0
- package/DAWG.md +655 -141
- package/README.md +27 -25
- package/core/autotune.ts +1119 -0
- package/core/chords.ts +759 -23
- package/core/clips.ts +499 -0
- package/core/diff.ts +182 -99
- package/core/expression.ts +158 -6
- package/core/fx.ts +354 -32
- package/core/granular.ts +91 -0
- package/core/instruments.ts +180 -0
- package/core/keys.ts +573 -4
- package/core/loop.ts +5 -0
- package/core/lyrics.ts +297 -0
- package/core/master.ts +3 -3
- package/core/resonators.ts +306 -4
- package/core/routing.ts +165 -0
- package/core/score.ts +1181 -16
- package/core/sdk/eval-child.ts +7 -2
- package/core/sdk/eval.ts +35 -6
- package/core/sdk/print.ts +354 -6
- package/core/sdk/sync-lyrics.ts +49 -0
- package/core/sdk/v1.ts +3160 -69
- package/core/sections.ts +298 -24
- package/core/sing.ts +815 -0
- package/core/strings.ts +237 -2
- package/core/style-provenance.ts +80 -0
- package/core/styles/africa-mena-southasia.ts +2893 -0
- package/core/styles/americas.ts +3810 -0
- package/core/styles/art.ts +4993 -0
- package/core/styles/base.ts +123 -0
- package/core/styles/cycles.ts +106 -0
- package/core/styles/electronic.ts +2723 -0
- package/core/styles/europe-asia-pacific.ts +2838 -0
- package/core/styles/excerpt.ts +29 -0
- package/core/styles/gamelan.ts +283 -0
- package/core/styles/generate.ts +2199 -0
- package/core/styles/index.ts +515 -0
- package/core/styles/parts.ts +106 -0
- package/core/styles/pop.ts +3189 -0
- package/core/styles/rock.ts +2993 -0
- package/core/styles/roots.ts +4175 -0
- package/core/styles/schema.ts +429 -0
- package/core/styles/taxonomy.ts +940 -0
- package/core/styles/validate.ts +528 -0
- package/core/tempo.ts +32 -2
- package/core/tuning.ts +19 -3
- package/core/vocoder.ts +524 -0
- package/core/winds.ts +652 -0
- package/guides/agent.md +29 -0
- package/guides/arrange.md +30 -0
- package/guides/audition.md +20 -14
- package/guides/automation.md +12 -6
- package/guides/chords.md +16 -14
- package/guides/effects.md +17 -15
- package/guides/faders.md +20 -16
- package/guides/files.md +13 -9
- package/guides/getting-started.md +15 -11
- package/guides/keys.md +19 -15
- package/guides/media.md +17 -12
- package/guides/mix.md +12 -6
- package/guides/music.md +23 -8
- package/guides/notes.md +15 -9
- package/guides/performance.md +15 -10
- package/guides/play.md +21 -13
- package/guides/project.md +25 -8
- package/guides/providers.md +20 -14
- package/guides/resample.md +32 -0
- package/guides/rhythm.md +17 -13
- package/guides/sessions.md +17 -7
- package/guides/show-me.md +31 -0
- package/guides/sound.md +25 -9
- package/guides/sounds.md +15 -12
- package/guides/styles.md +31 -0
- package/guides/tempo.md +15 -10
- package/guides/tracks.md +15 -10
- package/guides/tuning.md +32 -0
- package/guides/voice.md +31 -0
- package/guides/web-search.md +18 -8
- package/native/prebuilt/darwin-arm64/libdawg_sink.dylib +0 -0
- package/native/prebuilt/darwin-x64/libdawg_sink.dylib +0 -0
- package/native/prebuilt/linux-arm64/libdawg_sink.so +0 -0
- package/native/prebuilt/linux-x64/libdawg_sink.so +0 -0
- package/native/prebuilt/manifest.json +21 -0
- package/package.json +5 -2
- package/src/agent/agent.ts +131 -13
- package/src/agent/calibration-tools.ts +53 -0
- package/src/agent/chord-tools.ts +153 -1
- package/src/agent/clip-tools.ts +453 -0
- package/src/agent/command-agent.ts +369 -0
- package/src/agent/drum-tools.ts +2 -2
- package/src/agent/expression-tools.ts +91 -0
- package/src/agent/gateway.ts +246 -60
- package/src/agent/models.ts +53 -12
- package/src/agent/ops.ts +15 -1
- package/src/agent/pack-tools.ts +1 -1
- package/src/agent/planner.ts +13 -0
- package/src/agent/portable-schema.ts +80 -0
- package/src/agent/preview-tool.ts +5 -1
- package/src/agent/provider.ts +22 -8
- package/src/agent/resample-tool.ts +131 -0
- package/src/agent/rhythm-tools.ts +1 -1
- package/src/agent/section-tools.ts +1 -1
- package/src/agent/show-me.ts +497 -0
- package/src/agent/steer.ts +15 -0
- package/src/agent/style-tools.ts +217 -0
- package/src/agent/tool-error.ts +12 -0
- package/src/agent/tools.ts +307 -37
- package/src/agent/usage.ts +2 -2
- package/src/agent/voice-tools.ts +925 -0
- package/src/agent/xcb-agent.ts +16 -6
- package/src/argv.ts +38 -0
- package/src/audio/analysis.ts +253 -0
- package/src/audio/arrange.ts +58 -3
- package/src/audio/autotune-engine.ts +101 -0
- package/src/audio/autotune.ts +640 -0
- package/src/audio/clips.ts +240 -0
- package/src/audio/doctor.ts +86 -0
- package/src/audio/dsp/bandbank.ts +138 -0
- package/src/audio/dsp/envelope.ts +171 -0
- package/src/audio/dsp/follow.ts +120 -0
- package/src/audio/dsp/formant.ts +427 -0
- package/src/audio/dsp/glottal.ts +243 -0
- package/src/audio/dsp/interp.ts +7 -2
- package/src/audio/dsp/lpc.ts +50 -0
- package/src/audio/dsp/periodicity.ts +59 -0
- package/src/audio/dsp/pitch.ts +995 -0
- package/src/audio/dsp/psola.ts +199 -0
- package/src/audio/dsp/shift.ts +256 -0
- package/src/audio/effects/chain.ts +21 -4
- package/src/audio/effects/common.ts +57 -0
- package/src/audio/effects/convolution.ts +113 -5
- package/src/audio/effects/filter.ts +48 -69
- package/src/audio/effects/formant.ts +263 -0
- package/src/audio/effects/gaze.ts +354 -0
- package/src/audio/engine.ts +206 -33
- package/src/audio/fit.ts +80 -3
- package/src/audio/granular.ts +352 -21
- package/src/audio/instrument-check.ts +67 -47
- package/src/audio/instruments.ts +36 -3
- package/src/audio/keys/calibration.ts +56 -0
- package/src/audio/keys/electric.ts +427 -0
- package/src/audio/keys/engine.ts +156 -20
- package/src/audio/keys/organ.ts +1335 -0
- package/src/audio/keys/piano.ts +72 -8
- package/src/audio/keys/sympathetic.ts +127 -0
- package/src/audio/kits.ts +135 -6
- package/src/audio/live-worker.ts +3 -1
- package/src/audio/live.ts +247 -26
- package/src/audio/native.ts +615 -0
- package/src/audio/preview.ts +45 -3
- package/src/audio/render-worker.ts +2 -0
- package/src/audio/renderer.ts +2 -0
- package/src/audio/resample.ts +286 -0
- package/src/audio/resonators.ts +10 -2
- package/src/audio/sampler.ts +252 -24
- package/src/audio/samples.ts +46 -3
- package/src/audio/sing/analysis.ts +193 -0
- package/src/audio/sing/engine.ts +949 -0
- package/src/audio/strings/body.ts +29 -16
- package/src/audio/strings/bow.ts +699 -0
- package/src/audio/strings/engine.ts +274 -22
- package/src/audio/strings/measure.test-helpers.ts +2 -0
- package/src/audio/synth/oscillators.ts +31 -21
- package/src/audio/synth/voice.ts +34 -1
- package/src/audio/vocoder/bank.ts +314 -0
- package/src/audio/vocoder/carrier.ts +165 -0
- package/src/audio/vocoder/control.ts +68 -0
- package/src/audio/vocoder/detect.ts +50 -0
- package/src/audio/vocoder/index.ts +304 -0
- package/src/audio/vocoder/talkbox.ts +143 -0
- package/src/audio/wav.ts +608 -85
- package/src/audio/winds/engine.ts +306 -0
- package/src/audio/winds/filters.ts +153 -0
- package/src/audio/winds/pitch.ts +104 -0
- package/src/audio/winds/trim.ts +104 -0
- package/src/audio/winds/trims.ts +917 -0
- package/src/audio/winds/trims1.ts +297 -0
- package/src/audio/winds/voice.ts +492 -0
- package/src/auth/cli.ts +38 -36
- package/src/auth/credentials.ts +30 -1
- package/src/auth/login.ts +15 -9
- package/src/auth/tui.ts +19 -10
- package/src/commands/arrange.ts +44 -29
- package/src/commands/autotune.ts +421 -0
- package/src/commands/calibration.ts +74 -0
- package/src/commands/clips.ts +887 -0
- package/src/commands/drums.ts +3 -2
- package/src/commands/edit.ts +11 -4
- package/src/commands/expression.ts +104 -23
- package/src/commands/formant.ts +221 -0
- package/src/commands/fx.ts +105 -33
- package/src/commands/grammar.ts +558 -0
- package/src/commands/granular.ts +7 -2
- package/src/commands/help.ts +652 -339
- package/src/commands/history.ts +18 -0
- package/src/commands/keys.ts +293 -17
- package/src/commands/modal.ts +67 -4
- package/src/commands/music.ts +1 -1
- package/src/commands/nearest.ts +53 -0
- package/src/commands/pack.ts +9 -2
- package/src/commands/param-range.ts +56 -0
- package/src/commands/parses.ts +130 -0
- package/src/commands/progression.ts +170 -0
- package/src/commands/resample.ts +281 -0
- package/src/commands/rhythm.ts +3 -0
- package/src/commands/rig.ts +8 -25
- package/src/commands/sample.ts +49 -2
- package/src/commands/shift.ts +119 -0
- package/src/commands/sing.ts +478 -0
- package/src/commands/string.ts +28 -2
- package/src/commands/strum.ts +485 -0
- package/src/commands/style.ts +415 -0
- package/src/commands/time.ts +6 -3
- package/src/commands/tuning.ts +3 -3
- package/src/commands/vocal-pitch.ts +616 -0
- package/src/commands/vocal.ts +147 -0
- package/src/commands/vocoder.ts +627 -0
- package/src/commands/wind.ts +244 -0
- package/src/fs/durable.ts +50 -0
- package/src/lang/glossary.ts +493 -0
- package/src/launch-args.ts +163 -0
- package/src/main.ts +1521 -255
- package/src/media/cli.ts +20 -3
- package/src/media/import.ts +3 -1
- package/src/project/check.ts +26 -3
- package/src/project/clip-pins.ts +72 -0
- package/src/project/init.ts +23 -8
- package/src/project/sync.ts +418 -86
- package/src/render.ts +36 -1
- package/src/session/daemon.ts +3 -0
- package/src/session/meta.ts +14 -0
- package/src/session/origin.ts +154 -0
- package/src/session/port.ts +22 -4
- package/src/session/presence.ts +50 -7
- package/src/session/protocol.ts +5 -1
- package/src/session/rebase.ts +18 -5
- package/src/session/receipt.ts +258 -0
- package/src/session/store.ts +65 -43
- package/src/tui/arrange-menu.ts +65 -31
- package/src/tui/audition.ts +1 -1
- package/src/tui/euclid.ts +18 -13
- package/src/tui/fader.ts +228 -41
- package/src/tui/granular-menu.ts +2 -4
- package/src/tui/menu-clips.ts +297 -0
- package/src/tui/menu-time.ts +20 -13
- package/src/tui/menu-voice.ts +405 -0
- package/src/tui/menu.ts +1377 -193
- package/src/tui/modal-menu.ts +38 -11
- package/src/tui/performance-menu.ts +46 -1
- package/src/tui/play-chords.ts +108 -5
- package/src/tui/play-mode.ts +16 -1
- package/src/tui/play-session.ts +81 -16
- package/src/tui/sing-menu.ts +278 -0
- package/src/tui/style-menu.ts +104 -0
- package/src/tui/vocoder-menu.ts +244 -0
- package/src/tui/wind-menu.ts +144 -0
- package/src/version.ts +8 -0
- package/src/web/fetch.ts +115 -29
- package/tui/activity.ts +180 -9
- package/tui/app.ts +274 -40
- package/tui/clip-row.ts +132 -0
- package/tui/delight.ts +144 -0
- package/tui/drawer.ts +70 -22
- package/tui/frame-gate.ts +76 -0
- package/tui/grammar.ts +112 -63
- package/tui/guide.ts +42 -4
- package/tui/highway.ts +269 -25
- package/tui/hints.ts +192 -0
- package/tui/input.ts +60 -9
- package/tui/keys.ts +1 -1
- package/tui/play-strip.ts +68 -14
- package/tui/prompt.ts +1 -1
- package/tui/screen.ts +144 -14
- package/tui/theme.ts +27 -0
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
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
* on/off/true/false; enums take one of their values. Each command is one
|
|
19
20
|
* `updateTrack` revision and one undo step.
|
|
20
21
|
*/
|
|
21
|
-
import {
|
|
22
|
+
import { nearest } from "./nearest.ts";
|
|
22
23
|
import {
|
|
23
24
|
EFFECT_NAMES,
|
|
24
25
|
FX_PRESETS,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
isEffectName,
|
|
29
30
|
normalizeParam,
|
|
30
31
|
FxValidationError,
|
|
32
|
+
VOWEL_VALUES,
|
|
31
33
|
type EffectName,
|
|
32
34
|
type FxName,
|
|
33
35
|
type FxValues,
|
|
@@ -56,37 +58,69 @@ export type FxCommand =
|
|
|
56
58
|
type: "fx-set";
|
|
57
59
|
effect: EffectName;
|
|
58
60
|
values: Readonly<Record<string, number | string | boolean>>;
|
|
61
|
+
}
|
|
62
|
+
/** Store exactly these values (`/vowel a` drops a previous morph). */
|
|
63
|
+
| {
|
|
64
|
+
type: "fx-replace";
|
|
65
|
+
effect: EffectName;
|
|
66
|
+
values: Readonly<Record<string, number | string | boolean>>;
|
|
59
67
|
};
|
|
60
68
|
|
|
61
|
-
const EFFECT_ALIASES: Readonly<Record<string, EffectName>> =
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
});
|
|
69
|
+
export const EFFECT_ALIASES: Readonly<Record<string, EffectName>> =
|
|
70
|
+
Object.freeze({
|
|
71
|
+
lpf: "filter",
|
|
72
|
+
hpf: "filter",
|
|
73
|
+
bpf: "filter",
|
|
74
|
+
dj: "djf",
|
|
75
|
+
"dj-filter": "djf",
|
|
76
|
+
"auto-filter": "autofilter",
|
|
77
|
+
autof: "autofilter",
|
|
78
|
+
bitcrush: "crush",
|
|
79
|
+
bitcrusher: "crush",
|
|
80
|
+
coarse: "crush",
|
|
81
|
+
distortion: "distort",
|
|
82
|
+
dist: "distort",
|
|
83
|
+
drive: "distort",
|
|
84
|
+
shape: "distort",
|
|
85
|
+
trem: "tremolo",
|
|
86
|
+
comp: "compressor",
|
|
87
|
+
compress: "compressor",
|
|
88
|
+
rotary: "leslie",
|
|
89
|
+
gain: "postgain",
|
|
90
|
+
echo: "delay",
|
|
91
|
+
bus: "orbit",
|
|
92
|
+
o: "orbit",
|
|
93
|
+
sidechain: "duck",
|
|
94
|
+
duckorbit: "duck",
|
|
95
|
+
room: "reverb",
|
|
96
|
+
verb: "reverb",
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 0.7: `formant` was an alias of the vowel filter; it now shifts formants.
|
|
101
|
+
* A vowel given to it gets this answer instead of a silent change.
|
|
102
|
+
*/
|
|
103
|
+
export const FORMANT_FX_USAGE =
|
|
104
|
+
"formant · shift -12..12 st, mix 0..1 · presets deep giant bright tiny";
|
|
105
|
+
|
|
106
|
+
/** `/vowel morph`, `fx vowel morph` and set_fx all refuse a morph with no target. */
|
|
107
|
+
export const VOWEL_MORPH_NEEDS_TO =
|
|
108
|
+
"set a target first: /vowel a o 0.5 or /vowel to o";
|
|
109
|
+
|
|
110
|
+
export const FORMANT_VOWEL_HINT =
|
|
111
|
+
"formant now shifts formants at constant pitch; the vowel filter is `vowel`";
|
|
112
|
+
|
|
113
|
+
/** Whether `fx formant …` words or set_fx params name a vowel. */
|
|
114
|
+
export function formantGotVowel(
|
|
115
|
+
words: readonly (string | number | boolean)[],
|
|
116
|
+
): boolean {
|
|
117
|
+
return words.some(
|
|
118
|
+
(word) =>
|
|
119
|
+
typeof word === "string" &&
|
|
120
|
+
(word.toLowerCase() === "vowel" ||
|
|
121
|
+
(VOWEL_VALUES as readonly string[]).includes(word.toLowerCase())),
|
|
122
|
+
);
|
|
123
|
+
}
|
|
90
124
|
|
|
91
125
|
export function parseEffectName(name: string): EffectName | undefined {
|
|
92
126
|
const lower = name.toLowerCase();
|
|
@@ -133,10 +167,25 @@ export function parseParamValue(
|
|
|
133
167
|
}
|
|
134
168
|
}
|
|
135
169
|
|
|
170
|
+
/** The effects people reach for first, for the empty `fx` read. */
|
|
171
|
+
const COMMON_FIRST: readonly string[] = [
|
|
172
|
+
"reverb",
|
|
173
|
+
"delay",
|
|
174
|
+
"filter",
|
|
175
|
+
"distort",
|
|
176
|
+
"chorus",
|
|
177
|
+
"compressor",
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
const FX_LIST_WORDS: readonly string[] = ["list", "ls", "presets"];
|
|
181
|
+
|
|
136
182
|
export function parseFxCommand(prompt: string): FxCommand | undefined {
|
|
137
183
|
const words = prompt.trim().split(/\s+/);
|
|
138
184
|
if (words[0]?.toLowerCase() !== "fx") return undefined;
|
|
139
185
|
if (words.length === 1) return { type: "fx-list" };
|
|
186
|
+
// `fx list`, `fx ls`, `fx presets`: the same read as bare `fx`.
|
|
187
|
+
if (words.length === 2 && FX_LIST_WORDS.includes(words[1]!.toLowerCase()))
|
|
188
|
+
return { type: "fx-list" };
|
|
140
189
|
if (prompt.length > 1_024) return undefined;
|
|
141
190
|
const irWord = (word: string | undefined) =>
|
|
142
191
|
word !== undefined && ["ir", "iresponse"].includes(word.toLowerCase());
|
|
@@ -147,6 +196,8 @@ export function parseFxCommand(prompt: string): FxCommand | undefined {
|
|
|
147
196
|
if (effect === "reverb" && irWord(words[2]) && words.length === 4)
|
|
148
197
|
return irCommand(words[3]!);
|
|
149
198
|
const rest = words.slice(2).map((word) => word.toLowerCase());
|
|
199
|
+
// `fx wobble`, `fx double`: a bare effect name turns it on.
|
|
200
|
+
if (rest.length === 0) return { type: "fx-on", effect };
|
|
150
201
|
if (rest.length === 1 && (rest[0] === "on" || rest[0] === "off"))
|
|
151
202
|
return { type: rest[0] === "on" ? "fx-on" : "fx-off", effect };
|
|
152
203
|
if (rest.length === 1 && rest[0] === "reset")
|
|
@@ -200,9 +251,16 @@ export function unknownFxMessage(prompt: string): string | undefined {
|
|
|
200
251
|
const words = prompt.trim().split(/\s+/);
|
|
201
252
|
if (words[0]?.toLowerCase() !== "fx" || words.length < 2) return undefined;
|
|
202
253
|
const name = words[1]!.toLowerCase();
|
|
254
|
+
if (name === "formant" && formantGotVowel(words.slice(2)))
|
|
255
|
+
return FORMANT_VOWEL_HINT;
|
|
256
|
+
// A new numeric-first effect: out-of-range values and preset typos get its
|
|
257
|
+
// ranges and presets instead of the generic unknown-command path.
|
|
258
|
+
if (name === "formant" && words.length <= 6 && !parseFxCommand(prompt))
|
|
259
|
+
return FORMANT_FX_USAGE;
|
|
203
260
|
if (parseEffectName(name) || ["ir", "iresponse", "amp"].includes(name))
|
|
204
261
|
return undefined;
|
|
205
|
-
|
|
262
|
+
if (words.length === 2 && FX_LIST_WORDS.includes(name)) return undefined;
|
|
263
|
+
const near = nearest(name, [
|
|
206
264
|
...EFFECT_NAMES,
|
|
207
265
|
...Object.keys(EFFECT_ALIASES),
|
|
208
266
|
"reverb",
|
|
@@ -239,6 +297,11 @@ export function effectDefaults(effect: EffectName): FxValues {
|
|
|
239
297
|
delete out.sag;
|
|
240
298
|
delete out.gate;
|
|
241
299
|
}
|
|
300
|
+
// The vowel morph stays absent until set: `fx vowel on` stores 0.6 data.
|
|
301
|
+
if (effect === "vowel") {
|
|
302
|
+
delete out.to;
|
|
303
|
+
delete out.morph;
|
|
304
|
+
}
|
|
242
305
|
return out;
|
|
243
306
|
}
|
|
244
307
|
|
|
@@ -301,7 +364,7 @@ export function applyFxCommand(
|
|
|
301
364
|
ok: true,
|
|
302
365
|
message: on.length
|
|
303
366
|
? `fx · ${on.map((effect) => `${effect} (${describe(effect, effectValues(track, effect)!)})`).join(" → ")}`
|
|
304
|
-
: `fx · none ·
|
|
367
|
+
: `fx · none · ${COMMON_FIRST.join(" ")} … · fx list`,
|
|
305
368
|
};
|
|
306
369
|
}
|
|
307
370
|
if (command.type === "fx-ir")
|
|
@@ -321,7 +384,16 @@ export function applyFxCommand(
|
|
|
321
384
|
...effectDefaults(effect),
|
|
322
385
|
...FX_PRESETS[effect]![command.preset],
|
|
323
386
|
};
|
|
387
|
+
else if (command.type === "fx-replace") values = { ...command.values };
|
|
324
388
|
else values = { ...(current ?? effectDefaults(effect)), ...command.values };
|
|
389
|
+
if (
|
|
390
|
+
values &&
|
|
391
|
+
effect === "vowel" &&
|
|
392
|
+
command.type === "fx-set" &&
|
|
393
|
+
command.values.morph !== undefined &&
|
|
394
|
+
values.to === undefined
|
|
395
|
+
)
|
|
396
|
+
return { ok: false, message: `vowel · ${VOWEL_MORPH_NEEDS_TO}` };
|
|
325
397
|
if (values && effect === "delay" && values.time === 0) {
|
|
326
398
|
const { time: _time, ...rest } = values;
|
|
327
399
|
values = rest;
|