@dawcore/components 0.0.18 → 0.0.20
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/dist/index.d.mts +171 -114
- package/dist/index.d.ts +171 -114
- package/dist/index.js +201 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +181 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -5
package/dist/index.js
CHANGED
|
@@ -230,7 +230,7 @@ var DawTrackElement = class extends import_lit2.LitElement {
|
|
|
230
230
|
this.pan = 0;
|
|
231
231
|
this.muted = false;
|
|
232
232
|
this.soloed = false;
|
|
233
|
-
this.
|
|
233
|
+
this._renderMode = "waveform";
|
|
234
234
|
this.spectrogramConfig = null;
|
|
235
235
|
this.trackId = crypto.randomUUID();
|
|
236
236
|
// Track removal is detected by the editor's MutationObserver,
|
|
@@ -238,6 +238,21 @@ var DawTrackElement = class extends import_lit2.LitElement {
|
|
|
238
238
|
// cannot bubble events to ancestors).
|
|
239
239
|
this._hasRendered = false;
|
|
240
240
|
}
|
|
241
|
+
get renderMode() {
|
|
242
|
+
return this._renderMode;
|
|
243
|
+
}
|
|
244
|
+
set renderMode(value) {
|
|
245
|
+
const old = this._renderMode;
|
|
246
|
+
let next = value;
|
|
247
|
+
if (next === "both") {
|
|
248
|
+
console.warn(
|
|
249
|
+
`[dawcore] <daw-track render-mode="both"> is not yet supported; falling back to 'spectrogram'`
|
|
250
|
+
);
|
|
251
|
+
next = "spectrogram";
|
|
252
|
+
}
|
|
253
|
+
this._renderMode = next;
|
|
254
|
+
this.requestUpdate("renderMode", old);
|
|
255
|
+
}
|
|
241
256
|
// Light DOM so <daw-clip> children are queryable.
|
|
242
257
|
createRenderRoot() {
|
|
243
258
|
return this;
|
|
@@ -300,8 +315,8 @@ __decorateClass([
|
|
|
300
315
|
(0, import_decorators2.property)({ type: Boolean })
|
|
301
316
|
], DawTrackElement.prototype, "soloed", 2);
|
|
302
317
|
__decorateClass([
|
|
303
|
-
(0, import_decorators2.property)({ attribute: "render-mode" })
|
|
304
|
-
], DawTrackElement.prototype, "renderMode",
|
|
318
|
+
(0, import_decorators2.property)({ attribute: "render-mode", noAccessor: true })
|
|
319
|
+
], DawTrackElement.prototype, "renderMode", 1);
|
|
305
320
|
__decorateClass([
|
|
306
321
|
(0, import_decorators2.property)({ attribute: false })
|
|
307
322
|
], DawTrackElement.prototype, "spectrogramConfig", 2);
|
|
@@ -1246,7 +1261,7 @@ function isDomClip(desc) {
|
|
|
1246
1261
|
}
|
|
1247
1262
|
|
|
1248
1263
|
// src/elements/daw-editor.ts
|
|
1249
|
-
var
|
|
1264
|
+
var import_core9 = require("@waveform-playlist/core");
|
|
1250
1265
|
|
|
1251
1266
|
// src/workers/peaksWorker.ts
|
|
1252
1267
|
var import_waveform_data = __toESM(require("waveform-data"));
|
|
@@ -2774,15 +2789,7 @@ var RecordingController = class {
|
|
|
2774
2789
|
|
|
2775
2790
|
// src/controllers/spectrogram-controller.ts
|
|
2776
2791
|
var import_spectrogram = require("@dawcore/spectrogram");
|
|
2777
|
-
var
|
|
2778
|
-
fftSize: 2048,
|
|
2779
|
-
windowFunction: "hann",
|
|
2780
|
-
frequencyScale: "mel",
|
|
2781
|
-
minFrequency: 0,
|
|
2782
|
-
gainDb: 20,
|
|
2783
|
-
rangeDb: 80
|
|
2784
|
-
};
|
|
2785
|
-
var LIBRARY_DEFAULT_COLOR_MAP = "viridis";
|
|
2792
|
+
var import_core4 = require("@waveform-playlist/core");
|
|
2786
2793
|
var SpectrogramController = class {
|
|
2787
2794
|
constructor(host, workerFactory) {
|
|
2788
2795
|
this.orchestrator = null;
|
|
@@ -2856,7 +2863,21 @@ var SpectrogramController = class {
|
|
|
2856
2863
|
const detail = e.detail;
|
|
2857
2864
|
this.host.dispatchEvent(
|
|
2858
2865
|
new CustomEvent("daw-spectrogram-ready", {
|
|
2859
|
-
detail,
|
|
2866
|
+
detail: { trackId: detail.trackId, generation: detail.generation },
|
|
2867
|
+
bubbles: true,
|
|
2868
|
+
composed: true
|
|
2869
|
+
})
|
|
2870
|
+
);
|
|
2871
|
+
});
|
|
2872
|
+
this.orchestrator.addEventListener("viewport-error", (e) => {
|
|
2873
|
+
const detail = e.detail;
|
|
2874
|
+
this.host.dispatchEvent(
|
|
2875
|
+
new CustomEvent("daw-spectrogram-error", {
|
|
2876
|
+
detail: {
|
|
2877
|
+
trackId: detail.trackId,
|
|
2878
|
+
generation: detail.generation,
|
|
2879
|
+
error: detail.error
|
|
2880
|
+
},
|
|
2860
2881
|
bubbles: true,
|
|
2861
2882
|
composed: true
|
|
2862
2883
|
})
|
|
@@ -2877,18 +2898,18 @@ var SpectrogramController = class {
|
|
|
2877
2898
|
track = c;
|
|
2878
2899
|
break;
|
|
2879
2900
|
}
|
|
2880
|
-
return { ...
|
|
2901
|
+
return { ...import_core4.SPECTROGRAM_DEFAULTS, ...this.editorConfig ?? {}, ...track ?? {} };
|
|
2881
2902
|
}
|
|
2882
2903
|
mergedColorMap() {
|
|
2883
2904
|
for (const c of this.trackColorMaps.values()) {
|
|
2884
|
-
return c ??
|
|
2905
|
+
return c ?? import_core4.DEFAULT_SPECTROGRAM_COLOR_MAP;
|
|
2885
2906
|
}
|
|
2886
|
-
return this.editorColorMap ??
|
|
2907
|
+
return this.editorColorMap ?? import_core4.DEFAULT_SPECTROGRAM_COLOR_MAP;
|
|
2887
2908
|
}
|
|
2888
2909
|
};
|
|
2889
2910
|
|
|
2890
2911
|
// src/interactions/pointer-handler.ts
|
|
2891
|
-
var
|
|
2912
|
+
var import_core5 = require("@waveform-playlist/core");
|
|
2892
2913
|
|
|
2893
2914
|
// src/interactions/constants.ts
|
|
2894
2915
|
var DRAG_THRESHOLD = 3;
|
|
@@ -2998,10 +3019,10 @@ var PointerHandler = class {
|
|
|
2998
3019
|
const h = this._host;
|
|
2999
3020
|
if (h.scaleMode === "beats") {
|
|
3000
3021
|
let tick = px * h.ticksPerPixel;
|
|
3001
|
-
tick = (0,
|
|
3022
|
+
tick = (0, import_core5.snapTickToGrid)(tick, h.snapTo, h._meterEntries, h.ppqn);
|
|
3002
3023
|
return h._ticksToSeconds(tick);
|
|
3003
3024
|
}
|
|
3004
|
-
return (0,
|
|
3025
|
+
return (0, import_core5.pixelsToSeconds)(px, h.samplesPerPixel, h.effectiveSampleRate);
|
|
3005
3026
|
}
|
|
3006
3027
|
_timeToPx(time) {
|
|
3007
3028
|
const h = this._host;
|
|
@@ -3093,7 +3114,7 @@ var PointerHandler = class {
|
|
|
3093
3114
|
};
|
|
3094
3115
|
|
|
3095
3116
|
// src/interactions/clip-pointer-handler.ts
|
|
3096
|
-
var
|
|
3117
|
+
var import_core6 = require("@waveform-playlist/core");
|
|
3097
3118
|
var ClipPointerHandler = class {
|
|
3098
3119
|
constructor(host) {
|
|
3099
3120
|
this._mode = null;
|
|
@@ -3127,7 +3148,7 @@ var ClipPointerHandler = class {
|
|
|
3127
3148
|
const anchorTick = h._secondsToTicks(anchorSeconds);
|
|
3128
3149
|
const deltaTicks = totalDeltaPx * h.ticksPerPixel;
|
|
3129
3150
|
const targetTick = anchorTick + deltaTicks;
|
|
3130
|
-
const snappedTick = h.snapTo !== "off" ? (0,
|
|
3151
|
+
const snappedTick = h.snapTo !== "off" ? (0, import_core6.snapTickToGrid)(targetTick, h.snapTo, h._meterEntries, h.ppqn) : targetTick;
|
|
3131
3152
|
const snappedSeconds = h._ticksToSeconds(snappedTick);
|
|
3132
3153
|
const snappedSample = Math.round(snappedSeconds * h.effectiveSampleRate);
|
|
3133
3154
|
return snappedSample - anchorSample;
|
|
@@ -3390,7 +3411,7 @@ var ClipPointerHandler = class {
|
|
|
3390
3411
|
};
|
|
3391
3412
|
|
|
3392
3413
|
// src/interactions/file-loader.ts
|
|
3393
|
-
var
|
|
3414
|
+
var import_core7 = require("@waveform-playlist/core");
|
|
3394
3415
|
async function loadFiles(host, files) {
|
|
3395
3416
|
if (!files) {
|
|
3396
3417
|
console.warn("[dawcore] loadFiles called with null/undefined");
|
|
@@ -3412,7 +3433,7 @@ async function loadFiles(host, files) {
|
|
|
3412
3433
|
host._audioCache.delete(blobUrl);
|
|
3413
3434
|
host._resolvedSampleRate = audioBuffer.sampleRate;
|
|
3414
3435
|
const name = file.name.replace(/\.\w+$/, "");
|
|
3415
|
-
const clip = (0,
|
|
3436
|
+
const clip = (0, import_core7.createClip)({
|
|
3416
3437
|
audioBuffer,
|
|
3417
3438
|
startSample: 0,
|
|
3418
3439
|
durationSamples: audioBuffer.length,
|
|
@@ -3436,7 +3457,7 @@ async function loadFiles(host, files) {
|
|
|
3436
3457
|
);
|
|
3437
3458
|
host._peaksData = new Map(host._peaksData).set(clip.id, peakData);
|
|
3438
3459
|
const trackId = crypto.randomUUID();
|
|
3439
|
-
const track = (0,
|
|
3460
|
+
const track = (0, import_core7.createTrack)({ name, clips: [clip] });
|
|
3440
3461
|
track.id = trackId;
|
|
3441
3462
|
host._tracks = new Map(host._tracks).set(trackId, {
|
|
3442
3463
|
name,
|
|
@@ -3495,8 +3516,110 @@ async function loadFiles(host, files) {
|
|
|
3495
3516
|
return { loaded, failed };
|
|
3496
3517
|
}
|
|
3497
3518
|
|
|
3519
|
+
// src/interactions/midi-loader.ts
|
|
3520
|
+
var INSTALL_HINT = "@dawcore/midi is required for loadMidi(). Install with: npm install @dawcore/midi";
|
|
3521
|
+
async function loadMidiImpl(host, source, options = {}) {
|
|
3522
|
+
const startTime = options.startTime ?? 0;
|
|
3523
|
+
if (!Number.isFinite(startTime) || startTime < 0) {
|
|
3524
|
+
throw new RangeError(
|
|
3525
|
+
"loadMidi: startTime must be a non-negative finite number (got " + String(options.startTime) + ")"
|
|
3526
|
+
);
|
|
3527
|
+
}
|
|
3528
|
+
let midiModule;
|
|
3529
|
+
try {
|
|
3530
|
+
midiModule = await import("@dawcore/midi");
|
|
3531
|
+
} catch (originalErr) {
|
|
3532
|
+
console.warn("[dawcore] @dawcore/midi dynamic import failed: " + String(originalErr));
|
|
3533
|
+
throw new Error(INSTALL_HINT);
|
|
3534
|
+
}
|
|
3535
|
+
const { parseMidiUrl, parseMidiFile } = midiModule;
|
|
3536
|
+
let parsed;
|
|
3537
|
+
if (typeof source === "string") {
|
|
3538
|
+
parsed = await parseMidiUrl(source, void 0, options.signal);
|
|
3539
|
+
} else {
|
|
3540
|
+
let buffer;
|
|
3541
|
+
try {
|
|
3542
|
+
buffer = await source.arrayBuffer();
|
|
3543
|
+
} catch (err) {
|
|
3544
|
+
throw new Error(
|
|
3545
|
+
'loadMidi: failed to read File "' + source.name + '" (' + source.size + " bytes): " + String(err)
|
|
3546
|
+
);
|
|
3547
|
+
}
|
|
3548
|
+
parsed = parseMidiFile(buffer);
|
|
3549
|
+
}
|
|
3550
|
+
const childrenBefore = new Set(host.querySelectorAll("daw-track"));
|
|
3551
|
+
const settlements = await Promise.allSettled(
|
|
3552
|
+
parsed.tracks.map(
|
|
3553
|
+
(t) => host.addTrack({
|
|
3554
|
+
name: t.name,
|
|
3555
|
+
renderMode: "piano-roll",
|
|
3556
|
+
clips: [
|
|
3557
|
+
{
|
|
3558
|
+
midiNotes: t.notes,
|
|
3559
|
+
midiChannel: t.channel,
|
|
3560
|
+
midiProgram: t.programNumber,
|
|
3561
|
+
start: startTime
|
|
3562
|
+
}
|
|
3563
|
+
]
|
|
3564
|
+
})
|
|
3565
|
+
)
|
|
3566
|
+
);
|
|
3567
|
+
const succeeded = [];
|
|
3568
|
+
const rejections = [];
|
|
3569
|
+
for (const s of settlements) {
|
|
3570
|
+
if (s.status === "fulfilled") {
|
|
3571
|
+
succeeded.push(s.value);
|
|
3572
|
+
} else {
|
|
3573
|
+
rejections.push(s.reason);
|
|
3574
|
+
}
|
|
3575
|
+
}
|
|
3576
|
+
if (rejections.length > 0) {
|
|
3577
|
+
const appendedTracks = Array.from(host.querySelectorAll("daw-track")).filter(
|
|
3578
|
+
(el) => !childrenBefore.has(el)
|
|
3579
|
+
);
|
|
3580
|
+
for (const el of appendedTracks) {
|
|
3581
|
+
try {
|
|
3582
|
+
el.remove();
|
|
3583
|
+
} catch (cleanupErr) {
|
|
3584
|
+
console.warn("[dawcore] loadMidi cleanup failed for a track: " + String(cleanupErr));
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
await Promise.resolve();
|
|
3588
|
+
for (let i = 1; i < rejections.length; i++) {
|
|
3589
|
+
console.warn(
|
|
3590
|
+
"[dawcore] loadMidi: additional track failure (" + i + "): " + stringifyReason(rejections[i])
|
|
3591
|
+
);
|
|
3592
|
+
}
|
|
3593
|
+
const first = rejections[0];
|
|
3594
|
+
if (rejections.length > 1) {
|
|
3595
|
+
const message = "loadMidi: " + rejections.length + " of " + settlements.length + " tracks failed; first: " + (first instanceof Error ? first.message : stringifyReason(first));
|
|
3596
|
+
throw new Error(message);
|
|
3597
|
+
}
|
|
3598
|
+
throw first instanceof Error ? first : new Error(stringifyReason(first));
|
|
3599
|
+
}
|
|
3600
|
+
return {
|
|
3601
|
+
trackIds: succeeded.map((el) => el.trackId),
|
|
3602
|
+
bpm: parsed.bpm,
|
|
3603
|
+
timeSignature: parsed.timeSignature,
|
|
3604
|
+
duration: parsed.duration,
|
|
3605
|
+
name: parsed.name
|
|
3606
|
+
};
|
|
3607
|
+
}
|
|
3608
|
+
function stringifyReason(reason) {
|
|
3609
|
+
if (reason === null) return "null";
|
|
3610
|
+
if (reason === void 0) return "undefined";
|
|
3611
|
+
if (typeof reason === "object") {
|
|
3612
|
+
try {
|
|
3613
|
+
return JSON.stringify(reason);
|
|
3614
|
+
} catch {
|
|
3615
|
+
return Object.prototype.toString.call(reason);
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
return String(reason);
|
|
3619
|
+
}
|
|
3620
|
+
|
|
3498
3621
|
// src/interactions/recording-clip.ts
|
|
3499
|
-
var
|
|
3622
|
+
var import_core8 = require("@waveform-playlist/core");
|
|
3500
3623
|
function addRecordedClip(host, trackId, buf, startSample, durSamples, offsetSamples = 0) {
|
|
3501
3624
|
let trimmedBuf = buf;
|
|
3502
3625
|
if (offsetSamples > 0 && offsetSamples < buf.length) {
|
|
@@ -3511,7 +3634,7 @@ function addRecordedClip(host, trackId, buf, startSample, durSamples, offsetSamp
|
|
|
3511
3634
|
}
|
|
3512
3635
|
trimmedBuf = trimmed;
|
|
3513
3636
|
}
|
|
3514
|
-
const clip = (0,
|
|
3637
|
+
const clip = (0, import_core8.createClip)({
|
|
3515
3638
|
audioBuffer: trimmedBuf,
|
|
3516
3639
|
startSample,
|
|
3517
3640
|
durationSamples: durSamples,
|
|
@@ -3834,7 +3957,10 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
3834
3957
|
* `_selectedTrackId`, etc.) — most of which don't affect the spectrogram
|
|
3835
3958
|
* viewport. Skip the cross-controller call when nothing changed.
|
|
3836
3959
|
*
|
|
3837
|
-
* The orchestrator dedupes too,
|
|
3960
|
+
* The orchestrator dedupes identical viewports too, so removing this cache
|
|
3961
|
+
* wouldn't change observable behavior — but it would push a fresh
|
|
3962
|
+
* `setViewport` call (with object allocation) into every Lit reactive
|
|
3963
|
+
* update for properties unrelated to the viewport.
|
|
3838
3964
|
*/
|
|
3839
3965
|
this._lastSpectrogramViewport = null;
|
|
3840
3966
|
// --- Track Events ---
|
|
@@ -4077,9 +4203,10 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
4077
4203
|
this._spectrogramController?.unregisterCanvas(canvasId);
|
|
4078
4204
|
}
|
|
4079
4205
|
/**
|
|
4080
|
-
*
|
|
4081
|
-
*
|
|
4082
|
-
*
|
|
4206
|
+
* Forward a clip's AudioBuffer to the spectrogram controller if the parent
|
|
4207
|
+
* track is in spectrogram render-mode. Eagerly creates the controller via
|
|
4208
|
+
* `_ensureSpectrogramController` so the audio data is queued for the first
|
|
4209
|
+
* render — even if no canvases have been registered yet.
|
|
4083
4210
|
*/
|
|
4084
4211
|
_maybeRegisterSpectrogramClipAudio(trackId, clip) {
|
|
4085
4212
|
const descriptor = this._tracks.get(trackId);
|
|
@@ -4530,7 +4657,7 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
4530
4657
|
let clip;
|
|
4531
4658
|
if (waveformData) {
|
|
4532
4659
|
const wdRate = waveformData.sample_rate;
|
|
4533
|
-
clip = (0,
|
|
4660
|
+
clip = (0, import_core9.createClip)({
|
|
4534
4661
|
audioBuffer,
|
|
4535
4662
|
waveformData,
|
|
4536
4663
|
startSample: Math.round(clipDesc.start * wdRate),
|
|
@@ -4543,7 +4670,7 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
4543
4670
|
});
|
|
4544
4671
|
this._peakPipeline.cacheWaveformData(audioBuffer, waveformData);
|
|
4545
4672
|
} else {
|
|
4546
|
-
clip = (0,
|
|
4673
|
+
clip = (0, import_core9.createClipFromSeconds)({
|
|
4547
4674
|
audioBuffer,
|
|
4548
4675
|
startTime: clipDesc.start,
|
|
4549
4676
|
duration: clipDesc.duration || audioBuffer.duration,
|
|
@@ -4623,7 +4750,7 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
4623
4750
|
const noteSpanSeconds = notes.length ? notes.reduce((max, n) => Math.max(max, n.time + n.duration), 0) : 0;
|
|
4624
4751
|
const sourceDurationSamples = Math.ceil(Math.max(noteSpanSeconds, clipDesc.duration, 1) * sr);
|
|
4625
4752
|
const requestedDurationSamples = clipDesc.duration > 0 ? Math.round(clipDesc.duration * sr) : sourceDurationSamples;
|
|
4626
|
-
const clip = (0,
|
|
4753
|
+
const clip = (0, import_core9.createClip)({
|
|
4627
4754
|
startSample: Math.round(clipDesc.start * sr),
|
|
4628
4755
|
durationSamples: requestedDurationSamples,
|
|
4629
4756
|
offsetSamples: Math.round(clipDesc.offset * sr),
|
|
@@ -4832,7 +4959,7 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
4832
4959
|
const waveformData = await waveformDataPromise;
|
|
4833
4960
|
if (waveformData) {
|
|
4834
4961
|
const wdRate = waveformData.sample_rate;
|
|
4835
|
-
const clip2 = (0,
|
|
4962
|
+
const clip2 = (0, import_core9.createClip)({
|
|
4836
4963
|
waveformData,
|
|
4837
4964
|
startSample: Math.round(clipDesc.start * wdRate),
|
|
4838
4965
|
durationSamples: Math.round((clipDesc.duration || waveformData.duration) * wdRate),
|
|
@@ -4857,7 +4984,7 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
4857
4984
|
});
|
|
4858
4985
|
this._peaksData = new Map(this._peaksData).set(clip2.id, peakData);
|
|
4859
4986
|
this._minSamplesPerPixel = Math.max(this._minSamplesPerPixel, waveformData.scale);
|
|
4860
|
-
const previewTrack = (0,
|
|
4987
|
+
const previewTrack = (0, import_core9.createTrack)({
|
|
4861
4988
|
name: descriptor.name,
|
|
4862
4989
|
clips: [clip2],
|
|
4863
4990
|
volume: descriptor.volume,
|
|
@@ -4913,7 +5040,7 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
4913
5040
|
}
|
|
4914
5041
|
}
|
|
4915
5042
|
}
|
|
4916
|
-
const track = (0,
|
|
5043
|
+
const track = (0, import_core9.createTrack)({
|
|
4917
5044
|
name: descriptor.name,
|
|
4918
5045
|
clips,
|
|
4919
5046
|
volume: descriptor.volume,
|
|
@@ -5067,6 +5194,22 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
5067
5194
|
async loadFiles(files) {
|
|
5068
5195
|
return loadFiles(this, files);
|
|
5069
5196
|
}
|
|
5197
|
+
/**
|
|
5198
|
+
* Imperatively load a `.mid` file (URL or File) and create N `<daw-track>`
|
|
5199
|
+
* elements — one per note-bearing MIDI track. On any per-track failure,
|
|
5200
|
+
* every `<daw-track>` appended during the call is removed (both successful
|
|
5201
|
+
* and failed) so the editor returns to its pre-call state.
|
|
5202
|
+
*
|
|
5203
|
+
* `options.signal` is forwarded to `fetch()` only for URL sources; aborting
|
|
5204
|
+
* after parsing does not cancel in-flight `addTrack` calls.
|
|
5205
|
+
*
|
|
5206
|
+
* Requires the optional `@dawcore/midi` peer dep — throws with an install
|
|
5207
|
+
* hint (and `console.warn`s the original error) when the dynamic import
|
|
5208
|
+
* fails for any reason.
|
|
5209
|
+
*/
|
|
5210
|
+
async loadMidi(source, options) {
|
|
5211
|
+
return loadMidiImpl(this, source, options);
|
|
5212
|
+
}
|
|
5070
5213
|
// --- Programmatic Track API ---
|
|
5071
5214
|
/**
|
|
5072
5215
|
* Build the engine if it hasn't been built yet. Lets consumers obtain a
|
|
@@ -5180,6 +5323,13 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
5180
5323
|
}
|
|
5181
5324
|
const oldDesc = this._tracks.get(trackId);
|
|
5182
5325
|
if (!oldDesc) return;
|
|
5326
|
+
let normalizedRenderMode = partial.renderMode;
|
|
5327
|
+
if (normalizedRenderMode === "both") {
|
|
5328
|
+
console.warn(
|
|
5329
|
+
`[dawcore] render-mode="both" is not yet supported; falling back to 'spectrogram'`
|
|
5330
|
+
);
|
|
5331
|
+
normalizedRenderMode = "spectrogram";
|
|
5332
|
+
}
|
|
5183
5333
|
const newDesc = {
|
|
5184
5334
|
...oldDesc,
|
|
5185
5335
|
...partial.name !== void 0 && { name: partial.name },
|
|
@@ -5187,7 +5337,7 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
5187
5337
|
...partial.pan !== void 0 && { pan: partial.pan },
|
|
5188
5338
|
...partial.muted !== void 0 && { muted: partial.muted },
|
|
5189
5339
|
...partial.soloed !== void 0 && { soloed: partial.soloed },
|
|
5190
|
-
...
|
|
5340
|
+
...normalizedRenderMode !== void 0 && { renderMode: normalizedRenderMode }
|
|
5191
5341
|
};
|
|
5192
5342
|
this._tracks = new Map(this._tracks).set(trackId, newDesc);
|
|
5193
5343
|
if (this._engine) {
|
|
@@ -5675,7 +5825,7 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
5675
5825
|
width = Math.round(endTick / this.ticksPerPixel) - clipLeft;
|
|
5676
5826
|
} else {
|
|
5677
5827
|
clipLeft = Math.floor(clip.startSample / spp);
|
|
5678
|
-
width = (0,
|
|
5828
|
+
width = (0, import_core9.clipPixelWidth)(clip.startSample, clip.durationSamples, spp);
|
|
5679
5829
|
}
|
|
5680
5830
|
let clipSegments;
|
|
5681
5831
|
let segmentChannels;
|
|
@@ -6297,7 +6447,7 @@ DawRecordButtonElement = __decorateClass([
|
|
|
6297
6447
|
// src/elements/daw-keyboard-shortcuts.ts
|
|
6298
6448
|
var import_lit18 = require("lit");
|
|
6299
6449
|
var import_decorators16 = require("lit/decorators.js");
|
|
6300
|
-
var
|
|
6450
|
+
var import_core10 = require("@waveform-playlist/core");
|
|
6301
6451
|
var DawKeyboardShortcutsElement = class extends import_lit18.LitElement {
|
|
6302
6452
|
constructor() {
|
|
6303
6453
|
super(...arguments);
|
|
@@ -6317,7 +6467,7 @@ var DawKeyboardShortcutsElement = class extends import_lit18.LitElement {
|
|
|
6317
6467
|
const shortcuts = this.shortcuts;
|
|
6318
6468
|
if (shortcuts.length === 0) return;
|
|
6319
6469
|
try {
|
|
6320
|
-
(0,
|
|
6470
|
+
(0, import_core10.handleKeyboardEvent)(e, shortcuts, true);
|
|
6321
6471
|
} catch (err) {
|
|
6322
6472
|
console.warn("[dawcore] Keyboard shortcut failed (key=" + e.key + "): " + String(err));
|
|
6323
6473
|
const target = this._editor ?? this;
|
|
@@ -6484,6 +6634,7 @@ var DawSpectrogramElement = class extends import_lit19.LitElement {
|
|
|
6484
6634
|
this.originX = 0;
|
|
6485
6635
|
this._canvases = [];
|
|
6486
6636
|
this._registeredCanvasIds = [];
|
|
6637
|
+
this._warnedNoHost = false;
|
|
6487
6638
|
}
|
|
6488
6639
|
get samplesPerPixel() {
|
|
6489
6640
|
return this._samplesPerPixel;
|
|
@@ -6550,7 +6701,15 @@ var DawSpectrogramElement = class extends import_lit19.LitElement {
|
|
|
6550
6701
|
}
|
|
6551
6702
|
_registerCanvases() {
|
|
6552
6703
|
const editor = this._findHostEditor();
|
|
6553
|
-
if (!editor || typeof editor._spectrogramRegisterCanvas !== "function")
|
|
6704
|
+
if (!editor || typeof editor._spectrogramRegisterCanvas !== "function") {
|
|
6705
|
+
if (!this._warnedNoHost) {
|
|
6706
|
+
this._warnedNoHost = true;
|
|
6707
|
+
console.warn(
|
|
6708
|
+
"[dawcore] <daw-spectrogram> (clip " + this.clipId + ") could not find host <daw-editor>. Canvases will not render. Ensure the element is mounted inside a <daw-editor>."
|
|
6709
|
+
);
|
|
6710
|
+
}
|
|
6711
|
+
return;
|
|
6712
|
+
}
|
|
6554
6713
|
for (let i = 0; i < this._canvases.length; i++) {
|
|
6555
6714
|
const canvas = this._canvases[i];
|
|
6556
6715
|
const canvasId = this.clipId + "-ch" + this.channelIndex + "-chunk" + i;
|