@onjmin/dtm 0.1.63 → 0.1.65

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.
Files changed (3) hide show
  1. package/dist/index.js +145 -68
  2. package/dist/index.mjs +145 -68
  3. package/package.json +1 -2
package/dist/index.js CHANGED
@@ -6641,7 +6641,7 @@ var isDecayInstrument = (fontName) => {
6641
6641
  if (!match) return false;
6642
6642
  const program = Math.floor(Number(match[1]) / 10);
6643
6643
  if (0 <= program && program <= 15) return true;
6644
- if (24 <= program && program <= 39) return true;
6644
+ if (24 <= program && program <= 37) return true;
6645
6645
  if (program === 46) return true;
6646
6646
  if (104 <= program && program <= 119) return true;
6647
6647
  return false;
@@ -6750,7 +6750,7 @@ var adjustZone = async (ctx, fontName, zone) => {
6750
6750
  }
6751
6751
  }
6752
6752
  zone.buffer = newBuf;
6753
- zone.loopEnd = zone.loopStart + (zone.loopEnd - zone.loopStart) * repeatCount;
6753
+ zone.loopEnd = zone.loopStart + loopLengthFrame / rateRatio * repeatCount;
6754
6754
  } catch (e) {
6755
6755
  console.warn(
6756
6756
  "[SoundFont.loopExtension] Failed to extend loop buffer:",
@@ -8136,6 +8136,11 @@ var buildUI = (target, options) => {
8136
8136
  <button class="dtm-btn dtm-btn--primary" data-dtm="midi-search-open">MML\u691C\u7D22</button>
8137
8137
  </div>
8138
8138
  <p class="dtm-load-note dtm-hidden" data-dtm="mml-load-note"></p>
8139
+ <div class="dtm-row" style="margin-top:8px;">
8140
+ <label class="dtm-checkbox-label" title="\u6709\u52B9\u306B\u3059\u308B\u3068\u3001\u73FE\u5728\u9078\u629E\u4E2D\u306E\u30C8\u30E9\u30C3\u30AF\u306E\u307F\u5909\u66F4\u3057\u307E\u3059">
8141
+ <input type="checkbox" class="dtm-checkbox" data-dtm="apply-active-only"> \u73FE\u5728\u306E\u30C8\u30E9\u30C3\u30AF\u306E\u307F\u5BFE\u8C61\u3068\u3059\u308B
8142
+ </label>
8143
+ </div>
8139
8144
  </div>
8140
8145
  </details>
8141
8146
 
@@ -8272,6 +8277,7 @@ var buildUI = (target, options) => {
8272
8277
  mmlInput: sel("mml-input"),
8273
8278
  mmlLoadBtn: sel("mml-load"),
8274
8279
  mmlLoadNote: sel("mml-load-note"),
8280
+ applyActiveOnly: sel("apply-active-only"),
8275
8281
  shiftSelect: sel("shift-select"),
8276
8282
  shiftApplyBtn: sel("shift-apply"),
8277
8283
  macroClear: sel("macro-clear"),
@@ -11642,10 +11648,22 @@ var mountDAW = (target, options = {}) => {
11642
11648
  const loadMML = (mml) => {
11643
11649
  if (!mml) return;
11644
11650
  stop();
11645
- clearAll();
11646
- for (const t of trackStates) t.core.setLoadMode(true);
11647
- resetCustomVocals();
11648
- for (const def of parseCustomVocals(mml)) registerCustomVocal(def);
11651
+ const applyActiveOnly = refs.applyActiveOnly?.checked ?? false;
11652
+ const activeTrackIndex = trackStates.findIndex(
11653
+ (t) => t.config.id === activeTrackId
11654
+ );
11655
+ if (applyActiveOnly) {
11656
+ const active = getActive();
11657
+ active.core.clearNotesWithoutHistory();
11658
+ active.core.setLoadMode(true);
11659
+ } else {
11660
+ clearAll();
11661
+ for (const t of trackStates) t.core.setLoadMode(true);
11662
+ }
11663
+ if (!applyActiveOnly) {
11664
+ resetCustomVocals();
11665
+ for (const def of parseCustomVocals(mml)) registerCustomVocal(def);
11666
+ }
11649
11667
  const {
11650
11668
  placements,
11651
11669
  bpm: parsedBpm,
@@ -11659,26 +11677,29 @@ var mountDAW = (target, options = {}) => {
11659
11677
  // このDAWのトラック数を超えるチャンネルはベースへ畳み込む(従来挙動)
11660
11678
  clampTrackCount: trackStates.length
11661
11679
  });
11662
- if (meta.instrument && INSTRUMENT_PRESETS[meta.instrument]) {
11663
- currentInstrument = meta.instrument;
11664
- options.onInstrumentChange?.(meta.instrument);
11665
- }
11666
- if (meta.drum && drumPatterns[meta.drum]) {
11667
- currentDrumPattern = meta.drum;
11668
- refs.drumSelect.value = meta.drum;
11669
- options.onDrumChange?.(meta.drum);
11670
- }
11671
- if (meta.volume !== void 0) {
11672
- masterVolume = meta.volume;
11673
- refs.masterVolume.value = String(meta.volume);
11674
- refs.masterVolumeLabel.textContent = `${meta.volume}%`;
11675
- }
11676
- if (meta.drumVolume !== void 0) {
11677
- drumVolume = meta.drumVolume;
11678
- refs.drumVolume.value = String(meta.drumVolume);
11679
- refs.drumVolumeLabel.textContent = `${meta.drumVolume}%`;
11680
+ if (!applyActiveOnly) {
11681
+ if (meta.instrument && INSTRUMENT_PRESETS[meta.instrument]) {
11682
+ currentInstrument = meta.instrument;
11683
+ options.onInstrumentChange?.(meta.instrument);
11684
+ }
11685
+ if (meta.drum && drumPatterns[meta.drum]) {
11686
+ currentDrumPattern = meta.drum;
11687
+ refs.drumSelect.value = meta.drum;
11688
+ options.onDrumChange?.(meta.drum);
11689
+ }
11690
+ if (meta.volume !== void 0) {
11691
+ masterVolume = meta.volume;
11692
+ refs.masterVolume.value = String(meta.volume);
11693
+ refs.masterVolumeLabel.textContent = `${meta.volume}%`;
11694
+ }
11695
+ if (meta.drumVolume !== void 0) {
11696
+ drumVolume = meta.drumVolume;
11697
+ refs.drumVolume.value = String(meta.drumVolume);
11698
+ refs.drumVolumeLabel.textContent = `${meta.drumVolume}%`;
11699
+ }
11680
11700
  }
11681
11701
  trackStates.forEach((t, i) => {
11702
+ if (applyActiveOnly && i !== activeTrackIndex) return;
11682
11703
  const name = normalizeInstrumentName(meta.trackInstruments?.[i] ?? "");
11683
11704
  if (t.trackInstrument !== name) {
11684
11705
  t.trackInstrument = name;
@@ -11686,21 +11707,33 @@ var mountDAW = (target, options = {}) => {
11686
11707
  }
11687
11708
  });
11688
11709
  trackStates.forEach((t, i) => {
11710
+ if (applyActiveOnly && i !== activeTrackIndex) return;
11689
11711
  const v = trackVelocity.get(i);
11690
11712
  if (v !== void 0 && v !== t.volume) {
11691
11713
  t.volume = v;
11692
11714
  t.core.setVolume(v);
11693
11715
  }
11694
11716
  });
11695
- for (const t of trackStates) {
11696
- t.lyrics = "";
11697
- t.lyricModel = "";
11698
- t.vocalVolume = DEFAULT_VOCAL_VOLUME;
11699
- t.vocalGate = 100;
11700
- t.vocalPan = 64;
11701
- t.vocalOctave = 0;
11717
+ if (applyActiveOnly) {
11718
+ const active = getActive();
11719
+ active.lyrics = "";
11720
+ active.lyricModel = "";
11721
+ active.vocalVolume = DEFAULT_VOCAL_VOLUME;
11722
+ active.vocalGate = 100;
11723
+ active.vocalPan = 64;
11724
+ active.vocalOctave = 0;
11725
+ } else {
11726
+ for (const t of trackStates) {
11727
+ t.lyrics = "";
11728
+ t.lyricModel = "";
11729
+ t.vocalVolume = DEFAULT_VOCAL_VOLUME;
11730
+ t.vocalGate = 100;
11731
+ t.vocalPan = 64;
11732
+ t.vocalOctave = 0;
11733
+ }
11702
11734
  }
11703
11735
  lyrics?.forEach((lt) => {
11736
+ if (applyActiveOnly && lt.trackId !== activeTrackIndex) return;
11704
11737
  const t = trackStates[lt.trackId];
11705
11738
  if (!t) return;
11706
11739
  t.lyrics = lt.syllables.map((s) => s.kana).join("");
@@ -11711,6 +11744,7 @@ var mountDAW = (target, options = {}) => {
11711
11744
  t.vocalOctave = lt.octave ?? 0;
11712
11745
  });
11713
11746
  for (const p of placements) {
11747
+ if (applyActiveOnly && p.trackIndex !== activeTrackIndex) continue;
11714
11748
  const t = trackStates[p.trackIndex];
11715
11749
  if (!t) continue;
11716
11750
  t.core.addNote(p.startStep, p.pitch, {
@@ -11718,8 +11752,9 @@ var mountDAW = (target, options = {}) => {
11718
11752
  velocity: DEFAULT_VELOCITY
11719
11753
  });
11720
11754
  }
11721
- if (parsedBpm) setBpm(parsedBpm);
11722
- for (const t of trackStates) {
11755
+ if (!applyActiveOnly && parsedBpm) setBpm(parsedBpm);
11756
+ const targets = applyActiveOnly ? [getActive()] : trackStates;
11757
+ for (const t of targets) {
11723
11758
  t.core.setLoadMode(false);
11724
11759
  t.core.addHistoryOnce();
11725
11760
  }
@@ -11774,15 +11809,28 @@ var mountDAW = (target, options = {}) => {
11774
11809
  };
11775
11810
  const applyMidiSelection = (midi, selectedIndices) => {
11776
11811
  stop();
11777
- clearAll();
11778
- for (const t of trackStates) t.core.setLoadMode(true);
11779
- for (const t of trackStates) {
11780
- t.lyrics = "";
11781
- t.lyricModel = "";
11782
- t.vocalVolume = DEFAULT_VOCAL_VOLUME;
11783
- t.vocalGate = 100;
11784
- t.vocalPan = 64;
11785
- t.vocalOctave = 0;
11812
+ const applyActiveOnly = refs.applyActiveOnly?.checked ?? false;
11813
+ if (applyActiveOnly) {
11814
+ const active = getActive();
11815
+ active.core.clearNotesWithoutHistory();
11816
+ active.core.setLoadMode(true);
11817
+ active.lyrics = "";
11818
+ active.lyricModel = "";
11819
+ active.vocalVolume = DEFAULT_VOCAL_VOLUME;
11820
+ active.vocalGate = 100;
11821
+ active.vocalPan = 64;
11822
+ active.vocalOctave = 0;
11823
+ } else {
11824
+ clearAll();
11825
+ for (const t of trackStates) t.core.setLoadMode(true);
11826
+ for (const t of trackStates) {
11827
+ t.lyrics = "";
11828
+ t.lyricModel = "";
11829
+ t.vocalVolume = DEFAULT_VOCAL_VOLUME;
11830
+ t.vocalGate = 100;
11831
+ t.vocalPan = 64;
11832
+ t.vocalOctave = 0;
11833
+ }
11786
11834
  }
11787
11835
  const { placements, bpm: parsedBpm } = isAdvanced ? extractMidiPlacementsByTrack(
11788
11836
  midi,
@@ -11790,6 +11838,7 @@ var mountDAW = (target, options = {}) => {
11790
11838
  trackStates.map((t) => t.config.id)
11791
11839
  ) : extractMidiPlacements(midi, selectedIndices);
11792
11840
  for (const p of placements) {
11841
+ if (applyActiveOnly && p.trackId !== activeTrackId) continue;
11793
11842
  const t = trackStates.find((ts) => ts.config.id === p.trackId);
11794
11843
  if (!t) continue;
11795
11844
  t.core.addNote(p.startStep, p.pitch, {
@@ -11797,8 +11846,9 @@ var mountDAW = (target, options = {}) => {
11797
11846
  velocity: p.velocity
11798
11847
  });
11799
11848
  }
11800
- setBpm(Math.round(parsedBpm));
11801
- for (const t of trackStates) {
11849
+ if (!applyActiveOnly) setBpm(Math.round(parsedBpm));
11850
+ const targets = applyActiveOnly ? [getActive()] : trackStates;
11851
+ for (const t of targets) {
11802
11852
  t.core.setLoadMode(false);
11803
11853
  t.core.addHistoryOnce();
11804
11854
  }
@@ -11846,10 +11896,29 @@ var mountDAW = (target, options = {}) => {
11846
11896
  const overlayDuring = (fn) => {
11847
11897
  refs.overlay.hidden = false;
11848
11898
  setLoading(true);
11899
+ const globalOverlay = document.createElement("div");
11900
+ globalOverlay.className = "dtm-overlay";
11901
+ globalOverlay.style.position = "fixed";
11902
+ globalOverlay.style.zIndex = "99999";
11903
+ const spinner = document.createElement("div");
11904
+ spinner.className = "dtm-spinner";
11905
+ const fill = document.createElement("i");
11906
+ fill.className = "dtm-spinner-fill";
11907
+ spinner.appendChild(fill);
11908
+ globalOverlay.appendChild(spinner);
11909
+ const label = document.createElement("div");
11910
+ label.className = "dtm-loading-label";
11911
+ label.textContent = "\u51E6\u7406\u4E2D...";
11912
+ globalOverlay.appendChild(label);
11913
+ document.body.appendChild(globalOverlay);
11849
11914
  setTimeout(() => {
11850
- fn();
11851
- refs.overlay.hidden = true;
11852
- setLoading(false);
11915
+ try {
11916
+ fn();
11917
+ } finally {
11918
+ refs.overlay.hidden = true;
11919
+ setLoading(false);
11920
+ globalOverlay.remove();
11921
+ }
11853
11922
  }, 30);
11854
11923
  };
11855
11924
  const showConfirmModal = (message) => new Promise((resolve) => {
@@ -11979,36 +12048,44 @@ var mountDAW = (target, options = {}) => {
11979
12048
  refs.drumVolumeLabel.textContent = `${drumVolume}%`;
11980
12049
  });
11981
12050
  refs.macroClear.addEventListener("click", () => {
11982
- const active = getActive();
11983
- active.core.beginBatch();
11984
- active.core.clearNotesWithoutHistory();
11985
- active.core.endBatch();
11986
- active.core.saveHistory();
11987
- redrawAll();
12051
+ overlayDuring(() => {
12052
+ const active = getActive();
12053
+ active.core.beginBatch();
12054
+ active.core.clearNotesWithoutHistory();
12055
+ active.core.endBatch();
12056
+ active.core.saveHistory();
12057
+ redrawAll();
12058
+ });
11988
12059
  });
11989
12060
  refs.macroRandom.addEventListener("click", () => {
11990
- generateRandomPattern(getActive().core, {
11991
- stepsPerBar: renderConfig.stepsPerBar,
11992
- startStep: playStartStep,
11993
- pitchRangeStart: renderConfig.pitchRangeStart
12061
+ overlayDuring(() => {
12062
+ generateRandomPattern(getActive().core, {
12063
+ stepsPerBar: renderConfig.stepsPerBar,
12064
+ startStep: playStartStep,
12065
+ pitchRangeStart: renderConfig.pitchRangeStart
12066
+ });
12067
+ redrawAll();
11994
12068
  });
11995
- redrawAll();
11996
12069
  });
11997
12070
  refs.macroHarmonic.addEventListener("click", () => {
11998
- const chord = trackStates.find((t) => t.config.id === "chord");
11999
- if (!chord || activeTrackId === "chord") return;
12000
- applyHarmonicFilter(getActive().core, chord.core, {
12001
- stepsPerBar: renderConfig.stepsPerBar
12071
+ overlayDuring(() => {
12072
+ const chord = trackStates.find((t) => t.config.id === "chord");
12073
+ if (!chord || activeTrackId === "chord") return;
12074
+ applyHarmonicFilter(getActive().core, chord.core, {
12075
+ stepsPerBar: renderConfig.stepsPerBar
12076
+ });
12077
+ redrawAll();
12002
12078
  });
12003
- redrawAll();
12004
12079
  });
12005
12080
  refs.macroMono.addEventListener("click", () => {
12006
- const chord = trackStates.find((t) => t.config.id === "chord");
12007
- if (!chord || activeTrackId === "chord") return;
12008
- applyMonophonic(getActive().core, chord.core, {
12009
- stepsPerBar: renderConfig.stepsPerBar
12081
+ overlayDuring(() => {
12082
+ const chord = trackStates.find((t) => t.config.id === "chord");
12083
+ if (!chord || activeTrackId === "chord") return;
12084
+ applyMonophonic(getActive().core, chord.core, {
12085
+ stepsPerBar: renderConfig.stepsPerBar
12086
+ });
12087
+ redrawAll();
12010
12088
  });
12011
- redrawAll();
12012
12089
  });
12013
12090
  refs.generateMmlBtn.addEventListener("click", showMML);
12014
12091
  refs.exportMidiBtn.addEventListener("click", () => {
package/dist/index.mjs CHANGED
@@ -6519,7 +6519,7 @@ var isDecayInstrument = (fontName) => {
6519
6519
  if (!match) return false;
6520
6520
  const program = Math.floor(Number(match[1]) / 10);
6521
6521
  if (0 <= program && program <= 15) return true;
6522
- if (24 <= program && program <= 39) return true;
6522
+ if (24 <= program && program <= 37) return true;
6523
6523
  if (program === 46) return true;
6524
6524
  if (104 <= program && program <= 119) return true;
6525
6525
  return false;
@@ -6628,7 +6628,7 @@ var adjustZone = async (ctx, fontName, zone) => {
6628
6628
  }
6629
6629
  }
6630
6630
  zone.buffer = newBuf;
6631
- zone.loopEnd = zone.loopStart + (zone.loopEnd - zone.loopStart) * repeatCount;
6631
+ zone.loopEnd = zone.loopStart + loopLengthFrame / rateRatio * repeatCount;
6632
6632
  } catch (e) {
6633
6633
  console.warn(
6634
6634
  "[SoundFont.loopExtension] Failed to extend loop buffer:",
@@ -8014,6 +8014,11 @@ var buildUI = (target, options) => {
8014
8014
  <button class="dtm-btn dtm-btn--primary" data-dtm="midi-search-open">MML\u691C\u7D22</button>
8015
8015
  </div>
8016
8016
  <p class="dtm-load-note dtm-hidden" data-dtm="mml-load-note"></p>
8017
+ <div class="dtm-row" style="margin-top:8px;">
8018
+ <label class="dtm-checkbox-label" title="\u6709\u52B9\u306B\u3059\u308B\u3068\u3001\u73FE\u5728\u9078\u629E\u4E2D\u306E\u30C8\u30E9\u30C3\u30AF\u306E\u307F\u5909\u66F4\u3057\u307E\u3059">
8019
+ <input type="checkbox" class="dtm-checkbox" data-dtm="apply-active-only"> \u73FE\u5728\u306E\u30C8\u30E9\u30C3\u30AF\u306E\u307F\u5BFE\u8C61\u3068\u3059\u308B
8020
+ </label>
8021
+ </div>
8017
8022
  </div>
8018
8023
  </details>
8019
8024
 
@@ -8150,6 +8155,7 @@ var buildUI = (target, options) => {
8150
8155
  mmlInput: sel("mml-input"),
8151
8156
  mmlLoadBtn: sel("mml-load"),
8152
8157
  mmlLoadNote: sel("mml-load-note"),
8158
+ applyActiveOnly: sel("apply-active-only"),
8153
8159
  shiftSelect: sel("shift-select"),
8154
8160
  shiftApplyBtn: sel("shift-apply"),
8155
8161
  macroClear: sel("macro-clear"),
@@ -11520,10 +11526,22 @@ var mountDAW = (target, options = {}) => {
11520
11526
  const loadMML = (mml) => {
11521
11527
  if (!mml) return;
11522
11528
  stop();
11523
- clearAll();
11524
- for (const t of trackStates) t.core.setLoadMode(true);
11525
- resetCustomVocals();
11526
- for (const def of parseCustomVocals(mml)) registerCustomVocal(def);
11529
+ const applyActiveOnly = refs.applyActiveOnly?.checked ?? false;
11530
+ const activeTrackIndex = trackStates.findIndex(
11531
+ (t) => t.config.id === activeTrackId
11532
+ );
11533
+ if (applyActiveOnly) {
11534
+ const active = getActive();
11535
+ active.core.clearNotesWithoutHistory();
11536
+ active.core.setLoadMode(true);
11537
+ } else {
11538
+ clearAll();
11539
+ for (const t of trackStates) t.core.setLoadMode(true);
11540
+ }
11541
+ if (!applyActiveOnly) {
11542
+ resetCustomVocals();
11543
+ for (const def of parseCustomVocals(mml)) registerCustomVocal(def);
11544
+ }
11527
11545
  const {
11528
11546
  placements,
11529
11547
  bpm: parsedBpm,
@@ -11537,26 +11555,29 @@ var mountDAW = (target, options = {}) => {
11537
11555
  // このDAWのトラック数を超えるチャンネルはベースへ畳み込む(従来挙動)
11538
11556
  clampTrackCount: trackStates.length
11539
11557
  });
11540
- if (meta.instrument && INSTRUMENT_PRESETS[meta.instrument]) {
11541
- currentInstrument = meta.instrument;
11542
- options.onInstrumentChange?.(meta.instrument);
11543
- }
11544
- if (meta.drum && drumPatterns[meta.drum]) {
11545
- currentDrumPattern = meta.drum;
11546
- refs.drumSelect.value = meta.drum;
11547
- options.onDrumChange?.(meta.drum);
11548
- }
11549
- if (meta.volume !== void 0) {
11550
- masterVolume = meta.volume;
11551
- refs.masterVolume.value = String(meta.volume);
11552
- refs.masterVolumeLabel.textContent = `${meta.volume}%`;
11553
- }
11554
- if (meta.drumVolume !== void 0) {
11555
- drumVolume = meta.drumVolume;
11556
- refs.drumVolume.value = String(meta.drumVolume);
11557
- refs.drumVolumeLabel.textContent = `${meta.drumVolume}%`;
11558
+ if (!applyActiveOnly) {
11559
+ if (meta.instrument && INSTRUMENT_PRESETS[meta.instrument]) {
11560
+ currentInstrument = meta.instrument;
11561
+ options.onInstrumentChange?.(meta.instrument);
11562
+ }
11563
+ if (meta.drum && drumPatterns[meta.drum]) {
11564
+ currentDrumPattern = meta.drum;
11565
+ refs.drumSelect.value = meta.drum;
11566
+ options.onDrumChange?.(meta.drum);
11567
+ }
11568
+ if (meta.volume !== void 0) {
11569
+ masterVolume = meta.volume;
11570
+ refs.masterVolume.value = String(meta.volume);
11571
+ refs.masterVolumeLabel.textContent = `${meta.volume}%`;
11572
+ }
11573
+ if (meta.drumVolume !== void 0) {
11574
+ drumVolume = meta.drumVolume;
11575
+ refs.drumVolume.value = String(meta.drumVolume);
11576
+ refs.drumVolumeLabel.textContent = `${meta.drumVolume}%`;
11577
+ }
11558
11578
  }
11559
11579
  trackStates.forEach((t, i) => {
11580
+ if (applyActiveOnly && i !== activeTrackIndex) return;
11560
11581
  const name = normalizeInstrumentName(meta.trackInstruments?.[i] ?? "");
11561
11582
  if (t.trackInstrument !== name) {
11562
11583
  t.trackInstrument = name;
@@ -11564,21 +11585,33 @@ var mountDAW = (target, options = {}) => {
11564
11585
  }
11565
11586
  });
11566
11587
  trackStates.forEach((t, i) => {
11588
+ if (applyActiveOnly && i !== activeTrackIndex) return;
11567
11589
  const v = trackVelocity.get(i);
11568
11590
  if (v !== void 0 && v !== t.volume) {
11569
11591
  t.volume = v;
11570
11592
  t.core.setVolume(v);
11571
11593
  }
11572
11594
  });
11573
- for (const t of trackStates) {
11574
- t.lyrics = "";
11575
- t.lyricModel = "";
11576
- t.vocalVolume = DEFAULT_VOCAL_VOLUME;
11577
- t.vocalGate = 100;
11578
- t.vocalPan = 64;
11579
- t.vocalOctave = 0;
11595
+ if (applyActiveOnly) {
11596
+ const active = getActive();
11597
+ active.lyrics = "";
11598
+ active.lyricModel = "";
11599
+ active.vocalVolume = DEFAULT_VOCAL_VOLUME;
11600
+ active.vocalGate = 100;
11601
+ active.vocalPan = 64;
11602
+ active.vocalOctave = 0;
11603
+ } else {
11604
+ for (const t of trackStates) {
11605
+ t.lyrics = "";
11606
+ t.lyricModel = "";
11607
+ t.vocalVolume = DEFAULT_VOCAL_VOLUME;
11608
+ t.vocalGate = 100;
11609
+ t.vocalPan = 64;
11610
+ t.vocalOctave = 0;
11611
+ }
11580
11612
  }
11581
11613
  lyrics?.forEach((lt) => {
11614
+ if (applyActiveOnly && lt.trackId !== activeTrackIndex) return;
11582
11615
  const t = trackStates[lt.trackId];
11583
11616
  if (!t) return;
11584
11617
  t.lyrics = lt.syllables.map((s) => s.kana).join("");
@@ -11589,6 +11622,7 @@ var mountDAW = (target, options = {}) => {
11589
11622
  t.vocalOctave = lt.octave ?? 0;
11590
11623
  });
11591
11624
  for (const p of placements) {
11625
+ if (applyActiveOnly && p.trackIndex !== activeTrackIndex) continue;
11592
11626
  const t = trackStates[p.trackIndex];
11593
11627
  if (!t) continue;
11594
11628
  t.core.addNote(p.startStep, p.pitch, {
@@ -11596,8 +11630,9 @@ var mountDAW = (target, options = {}) => {
11596
11630
  velocity: DEFAULT_VELOCITY
11597
11631
  });
11598
11632
  }
11599
- if (parsedBpm) setBpm(parsedBpm);
11600
- for (const t of trackStates) {
11633
+ if (!applyActiveOnly && parsedBpm) setBpm(parsedBpm);
11634
+ const targets = applyActiveOnly ? [getActive()] : trackStates;
11635
+ for (const t of targets) {
11601
11636
  t.core.setLoadMode(false);
11602
11637
  t.core.addHistoryOnce();
11603
11638
  }
@@ -11652,15 +11687,28 @@ var mountDAW = (target, options = {}) => {
11652
11687
  };
11653
11688
  const applyMidiSelection = (midi, selectedIndices) => {
11654
11689
  stop();
11655
- clearAll();
11656
- for (const t of trackStates) t.core.setLoadMode(true);
11657
- for (const t of trackStates) {
11658
- t.lyrics = "";
11659
- t.lyricModel = "";
11660
- t.vocalVolume = DEFAULT_VOCAL_VOLUME;
11661
- t.vocalGate = 100;
11662
- t.vocalPan = 64;
11663
- t.vocalOctave = 0;
11690
+ const applyActiveOnly = refs.applyActiveOnly?.checked ?? false;
11691
+ if (applyActiveOnly) {
11692
+ const active = getActive();
11693
+ active.core.clearNotesWithoutHistory();
11694
+ active.core.setLoadMode(true);
11695
+ active.lyrics = "";
11696
+ active.lyricModel = "";
11697
+ active.vocalVolume = DEFAULT_VOCAL_VOLUME;
11698
+ active.vocalGate = 100;
11699
+ active.vocalPan = 64;
11700
+ active.vocalOctave = 0;
11701
+ } else {
11702
+ clearAll();
11703
+ for (const t of trackStates) t.core.setLoadMode(true);
11704
+ for (const t of trackStates) {
11705
+ t.lyrics = "";
11706
+ t.lyricModel = "";
11707
+ t.vocalVolume = DEFAULT_VOCAL_VOLUME;
11708
+ t.vocalGate = 100;
11709
+ t.vocalPan = 64;
11710
+ t.vocalOctave = 0;
11711
+ }
11664
11712
  }
11665
11713
  const { placements, bpm: parsedBpm } = isAdvanced ? extractMidiPlacementsByTrack(
11666
11714
  midi,
@@ -11668,6 +11716,7 @@ var mountDAW = (target, options = {}) => {
11668
11716
  trackStates.map((t) => t.config.id)
11669
11717
  ) : extractMidiPlacements(midi, selectedIndices);
11670
11718
  for (const p of placements) {
11719
+ if (applyActiveOnly && p.trackId !== activeTrackId) continue;
11671
11720
  const t = trackStates.find((ts) => ts.config.id === p.trackId);
11672
11721
  if (!t) continue;
11673
11722
  t.core.addNote(p.startStep, p.pitch, {
@@ -11675,8 +11724,9 @@ var mountDAW = (target, options = {}) => {
11675
11724
  velocity: p.velocity
11676
11725
  });
11677
11726
  }
11678
- setBpm(Math.round(parsedBpm));
11679
- for (const t of trackStates) {
11727
+ if (!applyActiveOnly) setBpm(Math.round(parsedBpm));
11728
+ const targets = applyActiveOnly ? [getActive()] : trackStates;
11729
+ for (const t of targets) {
11680
11730
  t.core.setLoadMode(false);
11681
11731
  t.core.addHistoryOnce();
11682
11732
  }
@@ -11724,10 +11774,29 @@ var mountDAW = (target, options = {}) => {
11724
11774
  const overlayDuring = (fn) => {
11725
11775
  refs.overlay.hidden = false;
11726
11776
  setLoading(true);
11777
+ const globalOverlay = document.createElement("div");
11778
+ globalOverlay.className = "dtm-overlay";
11779
+ globalOverlay.style.position = "fixed";
11780
+ globalOverlay.style.zIndex = "99999";
11781
+ const spinner = document.createElement("div");
11782
+ spinner.className = "dtm-spinner";
11783
+ const fill = document.createElement("i");
11784
+ fill.className = "dtm-spinner-fill";
11785
+ spinner.appendChild(fill);
11786
+ globalOverlay.appendChild(spinner);
11787
+ const label = document.createElement("div");
11788
+ label.className = "dtm-loading-label";
11789
+ label.textContent = "\u51E6\u7406\u4E2D...";
11790
+ globalOverlay.appendChild(label);
11791
+ document.body.appendChild(globalOverlay);
11727
11792
  setTimeout(() => {
11728
- fn();
11729
- refs.overlay.hidden = true;
11730
- setLoading(false);
11793
+ try {
11794
+ fn();
11795
+ } finally {
11796
+ refs.overlay.hidden = true;
11797
+ setLoading(false);
11798
+ globalOverlay.remove();
11799
+ }
11731
11800
  }, 30);
11732
11801
  };
11733
11802
  const showConfirmModal = (message) => new Promise((resolve) => {
@@ -11857,36 +11926,44 @@ var mountDAW = (target, options = {}) => {
11857
11926
  refs.drumVolumeLabel.textContent = `${drumVolume}%`;
11858
11927
  });
11859
11928
  refs.macroClear.addEventListener("click", () => {
11860
- const active = getActive();
11861
- active.core.beginBatch();
11862
- active.core.clearNotesWithoutHistory();
11863
- active.core.endBatch();
11864
- active.core.saveHistory();
11865
- redrawAll();
11929
+ overlayDuring(() => {
11930
+ const active = getActive();
11931
+ active.core.beginBatch();
11932
+ active.core.clearNotesWithoutHistory();
11933
+ active.core.endBatch();
11934
+ active.core.saveHistory();
11935
+ redrawAll();
11936
+ });
11866
11937
  });
11867
11938
  refs.macroRandom.addEventListener("click", () => {
11868
- generateRandomPattern(getActive().core, {
11869
- stepsPerBar: renderConfig.stepsPerBar,
11870
- startStep: playStartStep,
11871
- pitchRangeStart: renderConfig.pitchRangeStart
11939
+ overlayDuring(() => {
11940
+ generateRandomPattern(getActive().core, {
11941
+ stepsPerBar: renderConfig.stepsPerBar,
11942
+ startStep: playStartStep,
11943
+ pitchRangeStart: renderConfig.pitchRangeStart
11944
+ });
11945
+ redrawAll();
11872
11946
  });
11873
- redrawAll();
11874
11947
  });
11875
11948
  refs.macroHarmonic.addEventListener("click", () => {
11876
- const chord = trackStates.find((t) => t.config.id === "chord");
11877
- if (!chord || activeTrackId === "chord") return;
11878
- applyHarmonicFilter(getActive().core, chord.core, {
11879
- stepsPerBar: renderConfig.stepsPerBar
11949
+ overlayDuring(() => {
11950
+ const chord = trackStates.find((t) => t.config.id === "chord");
11951
+ if (!chord || activeTrackId === "chord") return;
11952
+ applyHarmonicFilter(getActive().core, chord.core, {
11953
+ stepsPerBar: renderConfig.stepsPerBar
11954
+ });
11955
+ redrawAll();
11880
11956
  });
11881
- redrawAll();
11882
11957
  });
11883
11958
  refs.macroMono.addEventListener("click", () => {
11884
- const chord = trackStates.find((t) => t.config.id === "chord");
11885
- if (!chord || activeTrackId === "chord") return;
11886
- applyMonophonic(getActive().core, chord.core, {
11887
- stepsPerBar: renderConfig.stepsPerBar
11959
+ overlayDuring(() => {
11960
+ const chord = trackStates.find((t) => t.config.id === "chord");
11961
+ if (!chord || activeTrackId === "chord") return;
11962
+ applyMonophonic(getActive().core, chord.core, {
11963
+ stepsPerBar: renderConfig.stepsPerBar
11964
+ });
11965
+ redrawAll();
11888
11966
  });
11889
- redrawAll();
11890
11967
  });
11891
11968
  refs.generateMmlBtn.addEventListener("click", showMML);
11892
11969
  refs.exportMidiBtn.addEventListener("click", () => {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "author": "onjmin",
3
3
  "license": "MIT",
4
4
  "name": "@onjmin/dtm",
5
- "version": "0.1.63",
5
+ "version": "0.1.65",
6
6
  "description": "MMLを中間言語に用いた、モバイルファーストなDAW / ピアノロール打ち込みコンポーネント",
7
7
  "homepage": "https://onjmin.github.io/dtm",
8
8
  "repository": {
@@ -55,7 +55,6 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@onjmin/chord-parser": "1.0.2",
58
- "@onjmin/dtm": "0.1.14",
59
58
  "@onjmin/koe": "1.0.4",
60
59
  "midi-json-parser": "8.1.74"
61
60
  },