@onjmin/dtm 0.1.14 → 0.1.16

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.js CHANGED
@@ -1627,8 +1627,8 @@ function parseKoeHeader(headerBytes) {
1627
1627
  }
1628
1628
  var pcmBase = (jsonLength) => 8 + jsonLength;
1629
1629
  var BlobVoiceSource = class {
1630
- constructor(blob, base) {
1631
- this.blob = blob;
1630
+ constructor(blob2, base) {
1631
+ this.blob = blob2;
1632
1632
  this.base = base;
1633
1633
  }
1634
1634
  blob;
@@ -1639,8 +1639,8 @@ var BlobVoiceSource = class {
1639
1639
  }
1640
1640
  };
1641
1641
  var RangeVoiceSource = class {
1642
- constructor(url, base) {
1643
- this.url = url;
1642
+ constructor(url2, base) {
1643
+ this.url = url2;
1644
1644
  this.base = base;
1645
1645
  }
1646
1646
  url;
@@ -1656,8 +1656,8 @@ var RangeVoiceSource = class {
1656
1656
  return res.arrayBuffer();
1657
1657
  }
1658
1658
  };
1659
- async function rangeFetch(url, start, length) {
1660
- const res = await fetch(url, {
1659
+ async function rangeFetch(url2, start, length) {
1660
+ const res = await fetch(url2, {
1661
1661
  headers: { Range: `bytes=${start}-${start + length - 1}` }
1662
1662
  });
1663
1663
  if (!res.ok && res.status !== 206)
@@ -2428,22 +2428,22 @@ var createLocalBackend = async (options) => {
2428
2428
  }
2429
2429
  };
2430
2430
  };
2431
- var spawnVoiceWorker = async (url) => {
2432
- const sameOrigin = new URL(url, location.href).origin === location.origin;
2433
- if (sameOrigin) return new Worker(url);
2434
- const text = await fetch(url).then((r) => r.text());
2431
+ var spawnVoiceWorker = async (url2) => {
2432
+ const sameOrigin = new URL(url2, location.href).origin === location.origin;
2433
+ if (sameOrigin) return new Worker(url2);
2434
+ const text = await fetch(url2).then((r) => r.text());
2435
2435
  return new Worker(
2436
2436
  URL.createObjectURL(new Blob([text], { type: "text/javascript" }))
2437
2437
  );
2438
2438
  };
2439
2439
  var createWorkerBackend = async (workerUrl, options) => {
2440
- const worker = await spawnVoiceWorker(workerUrl);
2440
+ const worker2 = await spawnVoiceWorker(workerUrl);
2441
2441
  const aliasSet = /* @__PURE__ */ new Set();
2442
2442
  const pending = /* @__PURE__ */ new Map();
2443
2443
  let reqId = 0;
2444
2444
  let onReady = null;
2445
2445
  let onFail = null;
2446
- worker.onmessage = (ev) => {
2446
+ worker2.onmessage = (ev) => {
2447
2447
  const m = ev.data;
2448
2448
  if (m.type === "ready") {
2449
2449
  for (const a of m.aliases) aliasSet.add(a);
@@ -2458,14 +2458,14 @@ var createWorkerBackend = async (workerUrl, options) => {
2458
2458
  }
2459
2459
  }
2460
2460
  };
2461
- worker.onerror = (e) => {
2461
+ worker2.onerror = (e) => {
2462
2462
  const ev = e;
2463
2463
  onFail?.(new Error(ev.message || ev.error || `Event: ${ev.type}`));
2464
2464
  };
2465
2465
  await new Promise((resolve, reject) => {
2466
2466
  onReady = resolve;
2467
2467
  onFail = reject;
2468
- worker.postMessage({
2468
+ worker2.postMessage({
2469
2469
  type: "init",
2470
2470
  koe: options.koe,
2471
2471
  worldlineScriptUrl: options.worldlineScriptUrl ?? DEFAULT_WORLDLINE_SCRIPT,
@@ -2482,7 +2482,7 @@ var createWorkerBackend = async (workerUrl, options) => {
2482
2482
  m.pcm ? { pcm: m.pcm, preSec: m.preSec ?? 0, rate: m.rate ?? 1 } : null
2483
2483
  )
2484
2484
  );
2485
- worker.postMessage({
2485
+ worker2.postMessage({
2486
2486
  type: "render",
2487
2487
  id,
2488
2488
  alias,
@@ -2494,7 +2494,7 @@ var createWorkerBackend = async (workerUrl, options) => {
2494
2494
  hasAlias: (a) => aliasSet.has(a),
2495
2495
  pitchTokens: collectPitchTokens(aliasSet),
2496
2496
  renderAlias,
2497
- dispose: () => worker.terminate()
2497
+ dispose: () => worker2.terminate()
2498
2498
  };
2499
2499
  };
2500
2500
  var createKoeVoice = async (ctx, destination, options) => {
@@ -2629,7 +2629,7 @@ var createSingingVoices = (ctx, destination, options = {}) => {
2629
2629
  [FALLBACK_MODEL, createKlattVoice(ctx, destination)]
2630
2630
  ]);
2631
2631
  const loading = /* @__PURE__ */ new Map();
2632
- const load = (model) => {
2632
+ const load2 = (model) => {
2633
2633
  const m = model.toLowerCase();
2634
2634
  const ready = loaded.get(m);
2635
2635
  if (ready) return Promise.resolve(ready);
@@ -2661,7 +2661,7 @@ var createSingingVoices = (ctx, destination, options = {}) => {
2661
2661
  const loadModels = async (models) => {
2662
2662
  const set = /* @__PURE__ */ new Set();
2663
2663
  for (const m of models) if (m) set.add(m.toLowerCase());
2664
- await Promise.all([...set].map((m) => load(m)));
2664
+ await Promise.all([...set].map((m) => load2(m)));
2665
2665
  };
2666
2666
  const forEachSungNote = (track, fn) => {
2667
2667
  let prevVowel = "";
@@ -2883,21 +2883,26 @@ var shiftNotes = (cores, shiftSteps) => {
2883
2883
  // src/midi-io.ts
2884
2884
  var STEPS_PER_BEAT = 48;
2885
2885
  var analyzeMidiTracks = (midi) => {
2886
- const { track } = midi;
2886
+ const { tracks } = midi;
2887
2887
  const result = [];
2888
- for (let i = 0; i < track.length; i++) {
2888
+ for (let i = 0; i < tracks.length; i++) {
2889
2889
  const notes = [];
2890
2890
  let currentTime = 0;
2891
- for (const event of track[i].event) {
2892
- currentTime += event.deltaTime;
2893
- const data = event.data;
2894
- if (event.type === 9 && data && data[1]) {
2895
- notes.push({ pitch: data[0], channel: event.channel ?? 0 });
2896
- } else if (event.type === 8) {
2897
- for (let k = notes.length - 1; k >= 0; k--) {
2898
- if (notes[k].pitch === data[0] && notes[k].end === void 0) {
2899
- notes[k].end = currentTime;
2900
- break;
2891
+ for (const event of tracks[i]) {
2892
+ currentTime += event.delta;
2893
+ if (event.noteOn && event.noteOn.velocity > 0) {
2894
+ notes.push({
2895
+ pitch: event.noteOn.noteNumber,
2896
+ channel: event.channel ?? 0
2897
+ });
2898
+ } else if (event.noteOff || event.noteOn && event.noteOn.velocity === 0) {
2899
+ const noteOff = event.noteOff || event.noteOn;
2900
+ if (noteOff) {
2901
+ for (let k = notes.length - 1; k >= 0; k--) {
2902
+ if (notes[k].pitch === noteOff.noteNumber && notes[k].end === void 0) {
2903
+ notes[k].end = currentTime;
2904
+ break;
2905
+ }
2901
2906
  }
2902
2907
  }
2903
2908
  }
@@ -2915,51 +2920,54 @@ var analyzeMidiTracks = (midi) => {
2915
2920
  return result;
2916
2921
  };
2917
2922
  var getMidiBPM = (midi) => {
2918
- const { track } = midi;
2919
- for (const { event } of track) {
2920
- for (const { type, metaType, data } of event) {
2921
- if (type !== 255 || metaType !== 81) continue;
2922
- if (typeof data === "number") {
2923
- return 6e7 / data;
2923
+ const { tracks } = midi;
2924
+ for (const track of tracks) {
2925
+ for (const event of track) {
2926
+ if (event.setTempo && typeof event.setTempo.microsecondsPerQuarter === "number") {
2927
+ return 6e7 / event.setTempo.microsecondsPerQuarter;
2924
2928
  }
2925
- const [b1, b2, b3] = data;
2926
- return 6e7 / (b1 << 16 | b2 << 8 | b3);
2927
2929
  }
2928
2930
  }
2929
2931
  return 120;
2930
2932
  };
2931
2933
  var extractMidiPlacements = (midi, selectedTrackIndices) => {
2932
- const { track, timeDivision } = midi;
2933
- const ticksPerBeat = timeDivision;
2934
+ const { tracks, division } = midi;
2935
+ const ticksPerBeat = division;
2934
2936
  const bpm = getMidiBPM(midi);
2935
2937
  const channelNotes = {};
2936
2938
  for (const trackIdx of selectedTrackIndices) {
2937
- const trackData = track[trackIdx];
2939
+ const trackData = tracks[trackIdx];
2938
2940
  if (!trackData) continue;
2939
2941
  let currentTime = 0;
2940
- for (const event of trackData.event) {
2941
- currentTime += event.deltaTime;
2942
+ for (const event of trackData) {
2943
+ currentTime += event.delta;
2942
2944
  if (event.channel === 9) continue;
2943
- if (event.type !== 8 && event.type !== 9) continue;
2944
- const [pitch, velocity] = event.data;
2945
- const isNoteOff = event.type === 8 || !velocity;
2946
- const channel = event.channel ?? 0;
2947
- if (!channelNotes[channel]) channelNotes[channel] = [];
2948
- if (isNoteOff) {
2949
- for (let i = channelNotes[channel].length - 1; i >= 0; i--) {
2950
- const note = channelNotes[channel][i];
2951
- if (note.pitch === pitch && note.end === null) {
2952
- note.end = currentTime;
2953
- break;
2954
- }
2955
- }
2956
- } else {
2945
+ if (event.noteOn && event.noteOn.velocity > 0) {
2946
+ const pitch = event.noteOn.noteNumber;
2947
+ const velocity = event.noteOn.velocity;
2948
+ const channel = event.channel ?? 0;
2949
+ if (!channelNotes[channel]) channelNotes[channel] = [];
2957
2950
  channelNotes[channel].push({
2958
2951
  pitch,
2959
2952
  velocity,
2960
2953
  start: currentTime,
2961
2954
  end: null
2962
2955
  });
2956
+ } else if (event.noteOff || event.noteOn && event.noteOn.velocity === 0) {
2957
+ const noteOff = event.noteOff || event.noteOn;
2958
+ if (noteOff) {
2959
+ const pitch = noteOff.noteNumber;
2960
+ const channel = event.channel ?? 0;
2961
+ if (channelNotes[channel]) {
2962
+ for (let i = channelNotes[channel].length - 1; i >= 0; i--) {
2963
+ const note = channelNotes[channel][i];
2964
+ if (note.pitch === pitch && note.end === null) {
2965
+ note.end = currentTime;
2966
+ break;
2967
+ }
2968
+ }
2969
+ }
2970
+ }
2963
2971
  }
2964
2972
  }
2965
2973
  }
@@ -3072,33 +3080,36 @@ var extractMidiPlacements = (midi, selectedTrackIndices) => {
3072
3080
  return { placements, bpm };
3073
3081
  };
3074
3082
  var extractMidiPlacementsByTrack = (midi, selectedIndices, trackIds) => {
3075
- const { track, timeDivision } = midi;
3076
- const ticksPerBeat = timeDivision;
3083
+ const { tracks, division } = midi;
3084
+ const ticksPerBeat = division;
3077
3085
  const bpm = getMidiBPM(midi);
3078
3086
  const ticksPerStep = ticksPerBeat / STEPS_PER_BEAT;
3079
3087
  const placements = [];
3080
3088
  selectedIndices.forEach((midiIdx, lane) => {
3081
3089
  if (lane >= trackIds.length) return;
3082
- const trackData = track[midiIdx];
3090
+ const trackData = tracks[midiIdx];
3083
3091
  if (!trackData) return;
3084
3092
  const trackId = trackIds[lane];
3085
3093
  const active = [];
3086
3094
  let currentTime = 0;
3087
- for (const event of trackData.event) {
3088
- currentTime += event.deltaTime;
3095
+ for (const event of trackData) {
3096
+ currentTime += event.delta;
3089
3097
  if (event.channel === 9) continue;
3090
- if (event.type !== 8 && event.type !== 9) continue;
3091
- const [pitch, velocity] = event.data;
3092
- const isOff = event.type === 8 || !velocity;
3093
- if (isOff) {
3094
- for (let i = active.length - 1; i >= 0; i--) {
3095
- if (active[i].pitch === pitch && active[i].end === null) {
3096
- active[i].end = currentTime;
3097
- break;
3098
+ if (event.noteOn && event.noteOn.velocity > 0) {
3099
+ const pitch = event.noteOn.noteNumber;
3100
+ const velocity = event.noteOn.velocity;
3101
+ active.push({ pitch, velocity, start: currentTime, end: null });
3102
+ } else if (event.noteOff || event.noteOn && event.noteOn.velocity === 0) {
3103
+ const noteOff = event.noteOff || event.noteOn;
3104
+ if (noteOff) {
3105
+ const pitch = noteOff.noteNumber;
3106
+ for (let i = active.length - 1; i >= 0; i--) {
3107
+ if (active[i].pitch === pitch && active[i].end === null) {
3108
+ active[i].end = currentTime;
3109
+ break;
3110
+ }
3098
3111
  }
3099
3112
  }
3100
- } else {
3101
- active.push({ pitch, velocity, start: currentTime, end: null });
3102
3113
  }
3103
3114
  }
3104
3115
  for (const note of active) {
@@ -5529,13 +5540,6 @@ var TRACKS_ADVANCED = [
5529
5540
  color: [100, 255, 160],
5530
5541
  instrument: 14,
5531
5542
  volume: 100
5532
- },
5533
- {
5534
- id: "t15",
5535
- name: "TRACK 16",
5536
- color: [255, 150, 200],
5537
- instrument: 15,
5538
- volume: 100
5539
5543
  }
5540
5544
  ];
5541
5545
  var DEFAULT_TRACKS = TRACKS_SIMPLE;
@@ -6437,11 +6441,11 @@ var mountDAW = (target, options = {}) => {
6437
6441
  lyricCount.textContent = active.lyricModel && n > 0 ? `${n}\u97F3\u7BC0` : "";
6438
6442
  };
6439
6443
  const syncLyricTerms = () => {
6440
- const url = active.lyricModel ? KOE_VOICEBANK_TERMS[active.lyricModel] : void 0;
6441
- if (url) {
6444
+ const url2 = active.lyricModel ? KOE_VOICEBANK_TERMS[active.lyricModel] : void 0;
6445
+ if (url2) {
6442
6446
  const label = lyricModelLabel(active.lyricModel);
6443
6447
  lyricTermsLink.textContent = `${label}UTAU\u97F3\u6E90`;
6444
- lyricTermsLink.href = url;
6448
+ lyricTermsLink.href = url2;
6445
6449
  lyricTerms.classList.remove("dtm-hidden");
6446
6450
  } else {
6447
6451
  lyricTerms.classList.add("dtm-hidden");
@@ -6779,9 +6783,9 @@ var mountDAW = (target, options = {}) => {
6779
6783
  chordTrack.core.addHistoryOnce();
6780
6784
  redrawAll();
6781
6785
  };
6782
- const loadMIDI = (bytes) => {
6786
+ const loadMIDI = async (bytes) => {
6783
6787
  if (!options.parseMidi) return;
6784
- const midi = options.parseMidi(bytes);
6788
+ const midi = await options.parseMidi(bytes);
6785
6789
  const analysis = analyzeMidiTracks(midi);
6786
6790
  const selected = analysis.filter((a) => a.selected).map((a) => a.index);
6787
6791
  applyMidiSelection(midi, selected);
@@ -6945,13 +6949,13 @@ var mountDAW = (target, options = {}) => {
6945
6949
  });
6946
6950
  refs.generateMmlBtn.addEventListener("click", showMML);
6947
6951
  refs.exportMidiBtn.addEventListener("click", () => {
6948
- const blob = exportMIDI2();
6949
- const url = URL.createObjectURL(blob);
6952
+ const blob2 = exportMIDI2();
6953
+ const url2 = URL.createObjectURL(blob2);
6950
6954
  const a = document.createElement("a");
6951
- a.href = url;
6955
+ a.href = url2;
6952
6956
  a.download = "dtm.mid";
6953
6957
  a.click();
6954
- URL.revokeObjectURL(url);
6958
+ URL.revokeObjectURL(url2);
6955
6959
  });
6956
6960
  const copy = (text, btn) => {
6957
6961
  navigator.clipboard?.writeText(text);
@@ -7018,7 +7022,7 @@ var mountDAW = (target, options = {}) => {
7018
7022
  refs.overlay.hidden = false;
7019
7023
  setLoading(true);
7020
7024
  const buffer = new Uint8Array(await file.arrayBuffer());
7021
- pendingMidi = options.parseMidi(buffer);
7025
+ pendingMidi = await options.parseMidi(buffer);
7022
7026
  detectedTracks = analyzeMidiTracks(pendingMidi);
7023
7027
  refs.midiTrackSelection.innerHTML = `<span class="dtm-label">\u30C8\u30E9\u30C3\u30AF</span>`;
7024
7028
  detectedTracks.forEach((t, i) => {
@@ -7647,12 +7651,12 @@ var mountMmlPlayer = (target, mml, options = {}) => {
7647
7651
  termsRow.style.gap = "4px";
7648
7652
  termsRow.style.flexWrap = "wrap";
7649
7653
  const label = KOE_VOICEBANK_LABELS[model] ?? model;
7650
- const url = KOE_VOICEBANK_TERMS[model];
7654
+ const url2 = KOE_VOICEBANK_TERMS[model];
7651
7655
  const span1 = doc.createElement("span");
7652
7656
  span1.textContent = "\u4F7F\u7528\u6642\u306B\u306F";
7653
7657
  const a = doc.createElement("a");
7654
7658
  a.textContent = `${label}UTAU\u97F3\u6E90`;
7655
- a.href = url;
7659
+ a.href = url2;
7656
7660
  a.target = "_blank";
7657
7661
  a.rel = "noopener";
7658
7662
  a.style.color = "var(--dtm-primary)";
@@ -8121,13 +8125,173 @@ var createPianoRoll = (options, handlers) => {
8121
8125
  };
8122
8126
  };
8123
8127
 
8128
+ // node_modules/.pnpm/fast-unique-numbers@9.0.27/node_modules/fast-unique-numbers/build/es2019/factories/add-unique-number.js
8129
+ var createAddUniqueNumber = (generateUniqueNumber2) => {
8130
+ return (set) => {
8131
+ const number = generateUniqueNumber2(set);
8132
+ set.add(number);
8133
+ return number;
8134
+ };
8135
+ };
8136
+
8137
+ // node_modules/.pnpm/fast-unique-numbers@9.0.27/node_modules/fast-unique-numbers/build/es2019/factories/cache.js
8138
+ var createCache = (lastNumberWeakMap) => {
8139
+ return (collection, nextNumber) => {
8140
+ lastNumberWeakMap.set(collection, nextNumber);
8141
+ return nextNumber;
8142
+ };
8143
+ };
8144
+
8145
+ // node_modules/.pnpm/fast-unique-numbers@9.0.27/node_modules/fast-unique-numbers/build/es2019/factories/generate-unique-number.js
8146
+ var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER === void 0 ? 9007199254740991 : Number.MAX_SAFE_INTEGER;
8147
+ var TWO_TO_THE_POWER_OF_TWENTY_NINE = 536870912;
8148
+ var TWO_TO_THE_POWER_OF_THIRTY = TWO_TO_THE_POWER_OF_TWENTY_NINE * 2;
8149
+ var createGenerateUniqueNumber = (cache2, lastNumberWeakMap) => {
8150
+ return (collection) => {
8151
+ const lastNumber = lastNumberWeakMap.get(collection);
8152
+ let nextNumber = lastNumber === void 0 ? collection.size : lastNumber < TWO_TO_THE_POWER_OF_THIRTY ? lastNumber + 1 : 0;
8153
+ if (!collection.has(nextNumber)) {
8154
+ return cache2(collection, nextNumber);
8155
+ }
8156
+ if (collection.size < TWO_TO_THE_POWER_OF_TWENTY_NINE) {
8157
+ while (collection.has(nextNumber)) {
8158
+ nextNumber = Math.floor(Math.random() * TWO_TO_THE_POWER_OF_THIRTY);
8159
+ }
8160
+ return cache2(collection, nextNumber);
8161
+ }
8162
+ if (collection.size > MAX_SAFE_INTEGER) {
8163
+ throw new Error("Congratulations, you created a collection of unique numbers which uses all available integers!");
8164
+ }
8165
+ while (collection.has(nextNumber)) {
8166
+ nextNumber = Math.floor(Math.random() * MAX_SAFE_INTEGER);
8167
+ }
8168
+ return cache2(collection, nextNumber);
8169
+ };
8170
+ };
8171
+
8172
+ // node_modules/.pnpm/fast-unique-numbers@9.0.27/node_modules/fast-unique-numbers/build/es2019/module.js
8173
+ var LAST_NUMBER_WEAK_MAP = /* @__PURE__ */ new WeakMap();
8174
+ var cache = createCache(LAST_NUMBER_WEAK_MAP);
8175
+ var generateUniqueNumber = createGenerateUniqueNumber(cache, LAST_NUMBER_WEAK_MAP);
8176
+ var addUniqueNumber = createAddUniqueNumber(generateUniqueNumber);
8177
+
8178
+ // node_modules/.pnpm/broker-factory@3.1.15/node_modules/broker-factory/build/es2019/factories/create-broker.js
8179
+ var createBrokerFactory = (createOrGetOngoingRequests, extendBrokerImplementation, generateUniqueNumber2, isMessagePort2) => (brokerImplementation) => {
8180
+ const fullBrokerImplementation = extendBrokerImplementation(brokerImplementation);
8181
+ return (sender) => {
8182
+ const ongoingRequests = createOrGetOngoingRequests(sender);
8183
+ sender.addEventListener("message", (({ data: message }) => {
8184
+ const { id } = message;
8185
+ if (id !== null && ongoingRequests.has(id)) {
8186
+ const { reject, resolve } = ongoingRequests.get(id);
8187
+ ongoingRequests.delete(id);
8188
+ if (message.error === void 0) {
8189
+ resolve(message.result);
8190
+ } else {
8191
+ reject(new Error(message.error.message));
8192
+ }
8193
+ }
8194
+ }));
8195
+ if (isMessagePort2(sender)) {
8196
+ sender.start();
8197
+ }
8198
+ const call = (method, params = null, transferables = []) => {
8199
+ return new Promise((resolve, reject) => {
8200
+ const id = generateUniqueNumber2(ongoingRequests);
8201
+ ongoingRequests.set(id, { reject, resolve });
8202
+ if (params === null) {
8203
+ sender.postMessage({ id, method }, transferables);
8204
+ } else {
8205
+ sender.postMessage({ id, method, params }, transferables);
8206
+ }
8207
+ });
8208
+ };
8209
+ const notify = (method, params, transferables = []) => {
8210
+ sender.postMessage({ id: null, method, params }, transferables);
8211
+ };
8212
+ let functions = {};
8213
+ for (const [key, handler] of Object.entries(fullBrokerImplementation)) {
8214
+ functions = { ...functions, [key]: handler({ call, notify }) };
8215
+ }
8216
+ return { ...functions };
8217
+ };
8218
+ };
8219
+
8220
+ // node_modules/.pnpm/broker-factory@3.1.15/node_modules/broker-factory/build/es2019/factories/create-or-get-ongoing-requests.js
8221
+ var createCreateOrGetOngoingRequests = (ongoingRequestsMap) => (sender) => {
8222
+ if (ongoingRequestsMap.has(sender)) {
8223
+ return ongoingRequestsMap.get(sender);
8224
+ }
8225
+ const ongoingRequests = /* @__PURE__ */ new Map();
8226
+ ongoingRequestsMap.set(sender, ongoingRequests);
8227
+ return ongoingRequests;
8228
+ };
8229
+
8230
+ // node_modules/.pnpm/broker-factory@3.1.15/node_modules/broker-factory/build/es2019/factories/extend-broker-implementation.js
8231
+ var createExtendBrokerImplementation = (portMap) => (partialBrokerImplementation) => ({
8232
+ ...partialBrokerImplementation,
8233
+ connect: ({ call }) => {
8234
+ return async () => {
8235
+ const { port1, port2 } = new MessageChannel();
8236
+ const portId = await call("connect", { port: port1 }, [port1]);
8237
+ portMap.set(port2, portId);
8238
+ return port2;
8239
+ };
8240
+ },
8241
+ disconnect: ({ call }) => {
8242
+ return async (port) => {
8243
+ const portId = portMap.get(port);
8244
+ if (portId === void 0) {
8245
+ throw new Error("The given port is not connected.");
8246
+ }
8247
+ await call("disconnect", { portId });
8248
+ };
8249
+ },
8250
+ isSupported: ({ call }) => {
8251
+ return () => call("isSupported");
8252
+ }
8253
+ });
8254
+
8255
+ // node_modules/.pnpm/broker-factory@3.1.15/node_modules/broker-factory/build/es2019/guards/message-port.js
8256
+ var isMessagePort = (sender) => {
8257
+ return typeof sender.start === "function";
8258
+ };
8259
+
8260
+ // node_modules/.pnpm/broker-factory@3.1.15/node_modules/broker-factory/build/es2019/module.js
8261
+ var createBroker = createBrokerFactory(createCreateOrGetOngoingRequests(/* @__PURE__ */ new WeakMap()), createExtendBrokerImplementation(/* @__PURE__ */ new WeakMap()), generateUniqueNumber, isMessagePort);
8262
+
8263
+ // node_modules/.pnpm/midi-json-parser-broker@4.0.132/node_modules/midi-json-parser-broker/build/es2019/module.js
8264
+ var wrap = createBroker({
8265
+ parseArrayBuffer: ({ call }) => {
8266
+ return async (arrayBuffer) => {
8267
+ return call("parse", { arrayBuffer }, [arrayBuffer]);
8268
+ };
8269
+ }
8270
+ });
8271
+ var load = (url2) => {
8272
+ const worker2 = new Worker(url2);
8273
+ return wrap(worker2);
8274
+ };
8275
+
8276
+ // node_modules/.pnpm/midi-json-parser@8.1.74/node_modules/midi-json-parser/build/es2019/worker/worker.js
8277
+ var worker = `(()=>{var e={455(e,t){!function(e){"use strict";var t=function(e){return function(t){var n=e(t);return t.add(n),n}},n=function(e){return function(t,n){return e.set(t,n),n}},r=void 0===Number.MAX_SAFE_INTEGER?9007199254740991:Number.MAX_SAFE_INTEGER,o=536870912,s=2*o,i=function(e,t){return function(n){var i=t.get(n),a=void 0===i?n.size:i<s?i+1:0;if(!n.has(a))return e(n,a);if(n.size<o){for(;n.has(a);)a=Math.floor(Math.random()*s);return e(n,a)}if(n.size>r)throw new Error("Congratulations, you created a collection of unique numbers which uses all available integers!");for(;n.has(a);)a=Math.floor(Math.random()*r);return e(n,a)}},a=new WeakMap,f=n(a),c=i(f,a),u=t(c);e.addUniqueNumber=u,e.generateUniqueNumber=c}(t)}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var s=t[r]={exports:{}};return e[r].call(s.exports,s,s.exports,n),s.exports}(()=>{"use strict";const e=-32603,t=-32602,r=-32601,o=(e,t)=>Object.assign(new Error(e),{status:t}),s=t=>o('The handler of the method called "'.concat(t,'" returned an unexpected result.'),e),i=(t,n)=>async({data:{id:i,method:a,params:f}})=>{const c=n[a];try{if(void 0===c)throw(e=>o('The requested method called "'.concat(e,'" is not supported.'),r))(a);const n=void 0===f?c():c(f);if(void 0===n)throw(t=>o('The handler of the method called "'.concat(t,'" returned no required result.'),e))(a);const u=n instanceof Promise?await n:n;if(null===i){if(void 0!==u.result)throw s(a)}else{if(void 0===u.result)throw s(a);const{result:e,transferables:n=[]}=u;t.postMessage({id:i,result:e},n)}}catch(e){const{message:n,status:r=-32603}=e;t.postMessage({error:{code:r,message:n},id:i})}};var a=n(455);const f=new Map,c=(e,n,r)=>({...n,connect:({port:t})=>{t.start();const r=e(t,n),o=(0,a.generateUniqueNumber)(f);return f.set(o,()=>{r(),t.close(),f.delete(o)}),{result:o}},disconnect:({portId:e})=>{const n=f.get(e);if(void 0===n)throw(e=>o('The specified parameter called "portId" with the given value "'.concat(e,'" does not identify a port connected to this worker.'),t))(e);return n(),{result:null}},isSupported:async()=>{if(await new Promise(e=>{const t=new ArrayBuffer(0),{port1:n,port2:r}=new MessageChannel;n.onmessage=({data:t})=>e(null!==t),r.postMessage(t,[t])})){const e=r();return{result:e instanceof Promise?await e:e}}return{result:!1}}}),u=(e,t,n=()=>!0)=>{const r=c(u,t,n),o=i(e,r);return e.addEventListener("message",o),()=>e.removeEventListener("message",o)},l=e=>void 0!==e.channel,d=e=>e.toString(16).toUpperCase().padStart(2,"0"),g=(e,t=0,n=e.byteLength-(t-e.byteOffset))=>{const r=t+e.byteOffset,o=[],s=new Uint8Array(e.buffer,r,n);for(let e=0;e<n;e+=1)o[e]=d(s[e]);return o.join("")},h=(e,t=0,n=e.byteLength-(t-e.byteOffset))=>{const r=t+e.byteOffset,o=new Uint8Array(e.buffer,r,n);return String.fromCharCode.apply(null,o)},m=e=>{const t=new DataView(e),n=v(t);let r=14;const o=[];for(let e=0,s=n.numberOfTracks;e<s;e+=1){let e;({offset:r,track:e}=b(t,r)),o.push(e)}return{division:n.division,format:n.format,tracks:o}},p=(e,t,n)=>{let r;const{offset:o,value:s}=T(e,t),i=e.getUint8(o);return r=240===i?y(e,o+1):255===i?U(e,o+1):w(i,e,o+1,n),{...r,event:{...r.event,delta:s},eventTypeByte:i}},v=e=>{if(e.byteLength<14)throw new Error("Expected at least 14 bytes instead of ".concat(e.byteLength));if("MThd"!==h(e,0,4))throw new Error('Unexpected characters "'.concat(h(e,0,4),'" found instead of "MThd"'));if(6!==e.getUint32(4))throw new Error("The header has an unexpected length of ".concat(e.getUint32(4)," instead of 6"));const t=e.getUint16(8),n=e.getUint16(10);return{division:e.getUint16(12),format:t,numberOfTracks:n}},U=(e,t)=>{let n;const r=e.getUint8(t),{offset:o,value:s}=T(e,t+1);if(1===r)n={text:h(e,o,s)};else if(2===r)n={copyrightNotice:h(e,o,s)};else if(3===r)n={trackName:h(e,o,s)};else if(4===r)n={instrumentName:h(e,o,s)};else if(5===r)n={lyric:h(e,o,s)};else if(6===r)n={marker:h(e,o,s)};else if(7===r)n={cuePoint:h(e,o,s)};else if(8===r)n={programName:h(e,o,s)};else if(9===r)n={deviceName:h(e,o,s)};else if(10===r||11===r||12===r||13===r||14===r||15===r)n={metaTypeByte:d(r),text:h(e,o,s)};else if(32===r)n={channelPrefix:e.getUint8(o)};else if(33===r)n={midiPort:e.getUint8(o)};else if(47===r)n={endOfTrack:!0};else if(81===r)n={setTempo:{microsecondsPerQuarter:(e.getUint8(o)<<16)+(e.getUint8(o+1)<<8)+e.getUint8(o+2)}};else if(84===r){let t;const r=e.getUint8(o);96&r?32==(96&r)?t=25:64==(96&r)?t=29:96&~r||(t=30):t=24,n={smpteOffset:{frame:e.getUint8(o+3),frameRate:t,hour:31&r,minutes:e.getUint8(o+1),seconds:e.getUint8(o+2),subFrame:e.getUint8(o+4)}}}else if(88===r)n={timeSignature:{denominator:Math.pow(2,e.getUint8(o+1)),metronome:e.getUint8(o+2),numerator:e.getUint8(o),thirtyseconds:e.getUint8(o+3)}};else if(89===r)n={keySignature:{key:e.getInt8(o),scale:e.getInt8(o+1)}};else{if(127!==r)throw new Error('Cannot parse a meta event with a type of "'.concat(d(r),'"'));n={sequencerSpecificData:g(e,o,s)}}return{event:n,offset:o+s}},w=(e,t,n,r)=>{const o=128&e?null:r,s=(null===o?e:o)>>4;let i,a=null===o?n:n-1;if(8===s)i={noteOff:{noteNumber:t.getUint8(a),velocity:t.getUint8(a+1)}},a+=2;else if(9===s){const e=t.getUint8(a),n=t.getUint8(a+1);i=0===n?{noteOff:{noteNumber:e,velocity:n}}:{noteOn:{noteNumber:e,velocity:n}},a+=2}else if(10===s)i={keyPressure:{noteNumber:t.getUint8(a),pressure:t.getUint8(a+1)}},a+=2;else if(11===s)i={controlChange:{type:t.getUint8(a),value:t.getUint8(a+1)}},a+=2;else if(12===s)i={programChange:{programNumber:t.getUint8(a)}},a+=1;else if(13===s)i={channelPressure:{pressure:t.getUint8(a)}},a+=1;else{if(14!==s)throw new Error('Cannot parse a midi event with a type of "'.concat(d(s),'"'));i={pitchBend:t.getUint8(a)|t.getUint8(a+1)<<7},a+=2}return i.channel=15&(null===o?e:o),{event:i,offset:a}},y=(e,t)=>{const{offset:n,value:r}=T(e,t);return{event:{sysex:g(e,n,r)},offset:n+r}},b=(e,t)=>{if("MTrk"!==h(e,t,4))throw new Error('Unexpected characters "'.concat(h(e,t,4),'" found instead of "MTrk"'));const n=[],r=e.getUint32(t+4)+t+8;let o=null,s=t+8;for(;s<r;){const t=p(e,s,o),{event:r,eventTypeByte:i}=t;n.push(r),s=t.offset,l(r)&&(128&i)>0&&(o=i)}return{offset:s,track:n}},T=(e,t)=>{let n=t,r=0;for(;;){const t=e.getUint8(n);if(n+=1,!(t>127))return r+=t,{offset:n,value:r};r+=127&t,r<<=7}};u(self,{parse:({arrayBuffer:e})=>({result:m(e)})})})()})();`;
8278
+
8279
+ // node_modules/.pnpm/midi-json-parser@8.1.74/node_modules/midi-json-parser/build/es2019/module.js
8280
+ var blob = new Blob([worker], { type: "application/javascript; charset=utf-8" });
8281
+ var url = URL.createObjectURL(blob);
8282
+ var midiJsonParser = load(url);
8283
+ var connect = midiJsonParser.connect;
8284
+ var disconnect = midiJsonParser.disconnect;
8285
+ var isSupported = midiJsonParser.isSupported;
8286
+ var parseArrayBuffer = midiJsonParser.parseArrayBuffer;
8287
+ URL.revokeObjectURL(url);
8288
+
8124
8289
  // src/studio.ts
8125
8290
  var import_meta = {};
8126
8291
  var DEFAULT_CDN = {
8127
8292
  soundFont: "https://rpgen3.github.io/soundfont/mjs/surikov/SoundFont.mjs",
8128
8293
  soundFontDrum: "https://rpgen3.github.io/soundfont/mjs/surikov/SoundFont_drum.mjs",
8129
- soundFontList: "https://rpgen3.github.io/soundfont/mjs/surikov/SoundFont_list.mjs",
8130
- midiParser: "https://cdn.jsdelivr.net/npm/midi-parser-js@4.0.4/+esm"
8294
+ soundFontList: "https://rpgen3.github.io/soundfont/mjs/surikov/SoundFont_list.mjs"
8131
8295
  };
8132
8296
  var SOUNDFONT_NAME = "FluidR3_GM_sf2_file";
8133
8297
  var TRACK_ROLES = ["melody", "submelody", "bass", "chord"];
@@ -8138,10 +8302,10 @@ var resolveDefaultVoiceWorkerUrl = () => {
8138
8302
  return void 0;
8139
8303
  }
8140
8304
  };
8141
- var importFrom = async (url, name) => {
8305
+ var importFrom = async (url2, name) => {
8142
8306
  const mod = await import(
8143
8307
  /* @vite-ignore */
8144
- url
8308
+ url2
8145
8309
  );
8146
8310
  return mod[name] ?? mod.default;
8147
8311
  };
@@ -8170,23 +8334,17 @@ var createDtmStudio = async (options = {}) => {
8170
8334
  eng.SoundFont_drum ?? importFrom(cdn.soundFontDrum, "SoundFont_drum"),
8171
8335
  eng.SoundFont_list ?? importFrom(cdn.soundFontList, "SoundFont_list")
8172
8336
  ]);
8173
- let midiParser = null;
8174
8337
  let parseMidi;
8175
8338
  if (features.midi) {
8176
- parseMidi = eng.parseMidi;
8177
- if (!parseMidi) {
8178
- const midiPromise = importFrom(
8179
- cdn.midiParser,
8180
- "default"
8181
- ).then((m) => {
8182
- midiParser = m;
8183
- }).catch((e) => console.warn("[dtm] midi-parser \u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557", e));
8184
- void midiPromise;
8185
- parseMidi = (bytes) => {
8186
- if (!midiParser) throw new Error("midi-parser not ready");
8187
- return midiParser.parse(bytes);
8188
- };
8189
- }
8339
+ parseMidi = eng.parseMidi || ((bytes) => {
8340
+ const buffer = bytes.buffer;
8341
+ if (buffer instanceof ArrayBuffer) {
8342
+ return parseArrayBuffer(
8343
+ buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength)
8344
+ );
8345
+ }
8346
+ throw new Error("SharedArrayBuffer is not supported for MIDI parsing");
8347
+ });
8190
8348
  }
8191
8349
  const voiceWorkerUrl = options.voiceWorkerUrl === null ? void 0 : options.voiceWorkerUrl ?? resolveDefaultVoiceWorkerUrl();
8192
8350
  const singingVoices = createSingingVoices(audioCtx, masterGain, {
@@ -8237,13 +8395,13 @@ var createDtmStudio = async (options = {}) => {
8237
8395
  clamp4(Math.round(wave[i] * 32768), -32768, 32767),
8238
8396
  true
8239
8397
  );
8240
- const blob = new Blob([view], { type: "audio/wav" });
8241
- const url = URL.createObjectURL(blob);
8398
+ const blob2 = new Blob([view], { type: "audio/wav" });
8399
+ const url2 = URL.createObjectURL(blob2);
8242
8400
  const a = document.createElement("a");
8243
- a.href = url;
8401
+ a.href = url2;
8244
8402
  a.download = "record.wav";
8245
8403
  a.click();
8246
- URL.revokeObjectURL(url);
8404
+ URL.revokeObjectURL(url2);
8247
8405
  };
8248
8406
  const onToggleRecord = recorder ? () => {
8249
8407
  if (recorder.isRecording()) {