@onjmin/dtm 0.1.95 → 0.1.96

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
@@ -1549,13 +1549,21 @@ var createChannelStrip = (ctx, destination, options = {}) => {
1549
1549
  );
1550
1550
  };
1551
1551
  setWidth(options.width ?? 100);
1552
+ const panner = typeof ctx.createStereoPanner === "function" ? ctx.createStereoPanner() : null;
1553
+ if (panner) panner.pan.value = clamp(options.pan ?? 0, -1, 1);
1554
+ const panOut = panner ?? merger;
1552
1555
  eqHigh.connect(compressor);
1553
1556
  compressor.connect(splitter);
1554
- merger.connect(destination);
1557
+ if (panner) merger.connect(panner);
1558
+ panOut.connect(destination);
1555
1559
  const reverbSendGain = ctx.createGain();
1556
1560
  reverbSendGain.gain.value = clamp(options.reverbSend ?? 0, 0, 100) / 100;
1557
- merger.connect(reverbSendGain);
1561
+ panOut.connect(reverbSendGain);
1558
1562
  if (options.reverbBus) reverbSendGain.connect(options.reverbBus);
1563
+ const delaySendGain = ctx.createGain();
1564
+ delaySendGain.gain.value = clamp(options.delaySend ?? 0, 0, 100) / 100;
1565
+ panOut.connect(delaySendGain);
1566
+ if (options.delayBus) delaySendGain.connect(options.delayBus);
1559
1567
  return {
1560
1568
  input,
1561
1569
  setEqLow: (db) => {
@@ -1588,6 +1596,17 @@ var createChannelStrip = (ctx, destination, options = {}) => {
1588
1596
  0.02
1589
1597
  );
1590
1598
  },
1599
+ setDelaySend: (amount) => {
1600
+ delaySendGain.gain.setTargetAtTime(
1601
+ clamp(amount, 0, 100) / 100,
1602
+ ctx.currentTime,
1603
+ 0.02
1604
+ );
1605
+ },
1606
+ setPan: (pan) => {
1607
+ if (!panner) return;
1608
+ panner.pan.setTargetAtTime(clamp(pan, -1, 1), ctx.currentTime, 0.02);
1609
+ },
1591
1610
  dispose: () => {
1592
1611
  input.disconnect();
1593
1612
  eqLow.disconnect();
@@ -1604,7 +1623,9 @@ var createChannelStrip = (ctx, destination, options = {}) => {
1604
1623
  outL.disconnect();
1605
1624
  outR.disconnect();
1606
1625
  merger.disconnect();
1626
+ panner?.disconnect();
1607
1627
  reverbSendGain.disconnect();
1628
+ delaySendGain.disconnect();
1608
1629
  }
1609
1630
  };
1610
1631
  };
@@ -3536,7 +3557,7 @@ var PITCH_MAP = {
3536
3557
  b: 11
3537
3558
  };
3538
3559
  var clamp3 = (value, lo, hi) => Math.min(hi, Math.max(lo, value));
3539
- var META_DIRECTIVE = /#(inst|drum|drumfont|volume|drumvolume|reverb|reverbdecay|reverbpredelay|delay|delaydiv|fadein|fadeout|mode)=([\w-]+)/gi;
3560
+ var META_DIRECTIVE = /#(inst|drum|drumfont|volume|drumvolume|reverb|reverbdecay|reverbpredelay|delay|delaydiv|mastercomp|fadein|fadeout|mode)=([\w-]+)/gi;
3540
3561
  var TRACK_INST_DIRECTIVE = /#t(\d+)inst=([^#;\r\n]+)/gi;
3541
3562
  var TRACK_COMP_DIRECTIVE = /#t(\d+)comp=(\d+)/gi;
3542
3563
  var TRACK_WIDTH_DIRECTIVE = /#t(\d+)width=(\d+)/gi;
@@ -3544,6 +3565,8 @@ var TRACK_REVERBSEND_DIRECTIVE = /#t(\d+)rev=(\d+)/gi;
3544
3565
  var TRACK_EQLOW_DIRECTIVE = /#t(\d+)eqlo=(-?\d+)/gi;
3545
3566
  var TRACK_EQMID_DIRECTIVE = /#t(\d+)eqmid=(-?\d+)/gi;
3546
3567
  var TRACK_EQHIGH_DIRECTIVE = /#t(\d+)eqhi=(-?\d+)/gi;
3568
+ var TRACK_PAN_DIRECTIVE = /#t(\d+)pan=(\d+)/gi;
3569
+ var TRACK_DELAYSEND_DIRECTIVE = /#t(\d+)dly=(\d+)/gi;
3547
3570
  var parseMmlMeta = (mml) => {
3548
3571
  const meta = {};
3549
3572
  for (const m of mml.matchAll(META_DIRECTIVE)) {
@@ -3571,6 +3594,9 @@ var parseMmlMeta = (mml) => {
3571
3594
  if (!Number.isNaN(dv)) meta.delay = clamp3(dv, 0, 100);
3572
3595
  } else if (key === "delaydiv") {
3573
3596
  if (["4", "8", "8d", "16"].includes(m[2])) meta.delayDivision = m[2];
3597
+ } else if (key === "mastercomp") {
3598
+ const mc = Number.parseInt(m[2], 10);
3599
+ if (!Number.isNaN(mc)) meta.masterCompression = clamp3(mc, 0, 100);
3574
3600
  } else if (key === "fadein") {
3575
3601
  const fi = Number.parseInt(m[2], 10);
3576
3602
  if (!Number.isNaN(fi)) meta.fadeIn = clamp3(fi, 0, 100);
@@ -3639,9 +3665,25 @@ var parseMmlMeta = (mml) => {
3639
3665
  meta.trackEqHigh[idx] = val;
3640
3666
  }
3641
3667
  }
3668
+ for (const m of mml.matchAll(TRACK_PAN_DIRECTIVE)) {
3669
+ const idx = Number.parseInt(m[1], 10);
3670
+ const val = clamp3(Number.parseInt(m[2], 10), 0, 127);
3671
+ if (!Number.isNaN(idx) && !Number.isNaN(val)) {
3672
+ meta.trackPan ??= {};
3673
+ meta.trackPan[idx] = val;
3674
+ }
3675
+ }
3676
+ for (const m of mml.matchAll(TRACK_DELAYSEND_DIRECTIVE)) {
3677
+ const idx = Number.parseInt(m[1], 10);
3678
+ const val = clamp3(Number.parseInt(m[2], 10), 0, 100);
3679
+ if (!Number.isNaN(idx) && !Number.isNaN(val)) {
3680
+ meta.trackDelaySend ??= {};
3681
+ meta.trackDelaySend[idx] = val;
3682
+ }
3683
+ }
3642
3684
  return meta;
3643
3685
  };
3644
- var stripMmlMeta = (mml) => mml.replace(META_DIRECTIVE, "").replace(TRACK_INST_DIRECTIVE, "").replace(TRACK_COMP_DIRECTIVE, "").replace(TRACK_WIDTH_DIRECTIVE, "").replace(TRACK_REVERBSEND_DIRECTIVE, "").replace(TRACK_EQLOW_DIRECTIVE, "").replace(TRACK_EQMID_DIRECTIVE, "").replace(TRACK_EQHIGH_DIRECTIVE, "");
3686
+ var stripMmlMeta = (mml) => mml.replace(META_DIRECTIVE, "").replace(TRACK_INST_DIRECTIVE, "").replace(TRACK_COMP_DIRECTIVE, "").replace(TRACK_WIDTH_DIRECTIVE, "").replace(TRACK_REVERBSEND_DIRECTIVE, "").replace(TRACK_EQLOW_DIRECTIVE, "").replace(TRACK_EQMID_DIRECTIVE, "").replace(TRACK_EQHIGH_DIRECTIVE, "").replace(TRACK_PAN_DIRECTIVE, "").replace(TRACK_DELAYSEND_DIRECTIVE, "");
3645
3687
  var formatMmlMeta = (meta, space = "") => {
3646
3688
  const parts = [];
3647
3689
  if (meta.instrument) parts.push(`#inst=${meta.instrument}`);
@@ -3660,6 +3702,8 @@ var formatMmlMeta = (meta, space = "") => {
3660
3702
  parts.push(`#delay=${meta.delay}`);
3661
3703
  if (meta.delayDivision && meta.delayDivision !== "8")
3662
3704
  parts.push(`#delaydiv=${meta.delayDivision}`);
3705
+ if (meta.masterCompression !== void 0 && meta.masterCompression !== 0)
3706
+ parts.push(`#mastercomp=${meta.masterCompression}`);
3663
3707
  if (meta.fadeIn !== void 0 && meta.fadeIn !== 0)
3664
3708
  parts.push(`#fadein=${meta.fadeIn}`);
3665
3709
  if (meta.fadeOut !== void 0 && meta.fadeOut !== 0)
@@ -3700,6 +3744,16 @@ var formatMmlMeta = (meta, space = "") => {
3700
3744
  if (val !== 0) parts.push(`#t${idx}eqhi=${val}`);
3701
3745
  }
3702
3746
  }
3747
+ if (meta.trackPan) {
3748
+ for (const [idx, val] of Object.entries(meta.trackPan)) {
3749
+ if (val !== 64) parts.push(`#t${idx}pan=${val}`);
3750
+ }
3751
+ }
3752
+ if (meta.trackDelaySend) {
3753
+ for (const [idx, val] of Object.entries(meta.trackDelaySend)) {
3754
+ if (val !== 0) parts.push(`#t${idx}dly=${val}`);
3755
+ }
3756
+ }
3703
3757
  return parts.join(space);
3704
3758
  };
3705
3759
  var parseMML = (mml, options = {}) => {
@@ -11533,6 +11587,12 @@ var buildUI = (target, options) => {
11533
11587
  <input type="range" class="dtm-range dtm-grow" data-dtm="master-volume" value="50" min="0" max="100">
11534
11588
  <span class="dtm-label" data-dtm="master-volume-label">50%</span>
11535
11589
  </div>
11590
+ <div class="dtm-row">
11591
+ <span class="dtm-label">\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7</span>
11592
+ <input type="range" class="dtm-range dtm-grow" data-dtm="master-comp" value="0" min="0" max="100" aria-label="\u30DE\u30B9\u30BF\u30D0\u30B9\u306E\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u30EC\u30C3\u30B5\u30FC\uFF08\u5168\u30C8\u30E9\u30C3\u30AF\u3092\u307E\u3068\u3081\u3066\u8EFD\u304F\u5727\u7E2E\u3057\u3001\u4E00\u4F53\u611F\u3092\u51FA\u3059\uFF09">
11593
+ <span class="dtm-label" data-dtm="master-comp-label">0%</span>
11594
+ <button class="dtm-infobtn" data-dtm="master-comp-info" title="\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
11595
+ </div>
11536
11596
  <div class="dtm-row">
11537
11597
  <button class="dtm-btn dtm-btn--ghost dtm-btn--xs" data-dtm="auto-master" title="\u97F3\u5727\u30FB\u30B9\u30C6\u30EC\u30AA\u5E45\u30FB\u30EA\u30D0\u30FC\u30D6\u306B\u52A0\u3048\u3001\u5404\u30C8\u30E9\u30C3\u30AF\u306E\u697D\u5668\u30FB\u97F3\u91CF\u3082\u81EA\u52D5\u63A8\u5B9A\u3057\u3066\u4E00\u62EC\u8A2D\u5B9A\u3057\u307E\u3059">\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0</button>
11538
11598
  <button class="dtm-infobtn" data-dtm="auto-master-info" title="\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
@@ -11788,6 +11848,9 @@ var buildUI = (target, options) => {
11788
11848
  hScrollThumb: sel("hscroll-thumb"),
11789
11849
  masterVolume: sel("master-volume"),
11790
11850
  masterVolumeLabel: sel("master-volume-label"),
11851
+ masterComp: sel("master-comp"),
11852
+ masterCompLabel: sel("master-comp-label"),
11853
+ masterCompInfoBtn: sel("master-comp-info"),
11791
11854
  reverbAmount: sel("reverb-amount"),
11792
11855
  reverbAmountLabel: sel("reverb-amount-label"),
11793
11856
  reverbAmountInfoBtn: sel("reverb-amount-info"),
@@ -13633,6 +13696,16 @@ var TRACK_WIDTH_INFO_HTML = `
13633
13696
  <p>\u30B9\u30DE\u30DB\u306E\u30B9\u30D4\u30FC\u30AB\u30FC1\u500B\u306A\u3069\u3001\u30E2\u30CE\u30E9\u30EB\u306B\u8FD1\u3044\u74B0\u5883\u3067\u518D\u751F\u3059\u308B\u3068\u97F3\u304C\u8584\u304F/\u4F4D\u76F8\u304C\u4E71\u308C\u3066\u805E\u3053\u3048\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\uFF08\u5DE6\u53F3\u306E\u5DEE\u5206\u3092\u8A87\u5F35\u3057\u3066\u3044\u308B\u305F\u3081\u3001\u8DB3\u3057\u5408\u308F\u305B\u308B\u3068\u6253\u3061\u6D88\u3057\u5408\u3046\u6210\u5206\u304C\u5897\u3048\u308B\uFF09\u3002\u4E3B\u65CB\u5F8B\u3084\u30DC\u30FC\u30AB\u30EB\u306F\u4E2D\u592E\u4ED8\u8FD1\u3067\u72ED\u3081\u3001\u30D1\u30C3\u30C9\u3084\u30B7\u30F3\u30BB\u306E\u88C5\u98FE\u30D1\u30FC\u30C8\u306F\u5E83\u3052\u308B\u3001\u3068\u3044\u3046\u306E\u304C\u30DF\u30C3\u30AF\u30B9\u306E\u5B9A\u77F3\u3067\u3059\u3002</p>
13634
13697
  </div>
13635
13698
  `;
13699
+ var TRACK_PAN_INFO_HTML = `
13700
+ <div class="dtm-modal-body-content">
13701
+ <h4>\u4F55\u3092\u3059\u308B\u8A2D\u5B9A\u304B</h4>
13702
+ <p>\u3053\u306E\u30C8\u30E9\u30C3\u30AF\u3092\u5DE6\u53F3\u306E\u3069\u3053\u306B\u7F6E\u304F\u304B\u3092\u6C7A\u3081\u307E\u3059\u300264\u304C\u4E2D\u592E\u30010\u3067\u5DE6\u3044\u3063\u3071\u3044\u3001127\u3067\u53F3\u3044\u3063\u3071\u3044\u3067\u3059\u3002\u6B4C\u8A5E\u30C8\u30E9\u30C3\u30AF\u306E\u5834\u5408\u3001\u3053\u3053\u306F\u697D\u5668\u3068\u3057\u3066\u306E\u30C8\u30E9\u30C3\u30AF\u5168\u4F53\u306E\u5B9A\u4F4D\u3067\u3001\u6B4C\u5531\u305D\u306E\u3082\u306E\u306E\u5B9A\u4F4D\uFF08\u4E0B\u306E\u300C\u5B9A\u4F4D\u300D\u6B04\u30FBvocalPan\uFF09\u3068\u306F\u5225\u306B\u50CD\u304D\u3001\u4E21\u65B9\u304C\u91CD\u306A\u3063\u3066\u6700\u7D42\u7684\u306A\u4F4D\u7F6E\u306B\u306A\u308A\u307E\u3059\u3002</p>
13703
+ <h4>\u300C\u30B9\u30C6\u30EC\u30AA\u5E45\u300D\u3068\u306E\u9055\u3044</h4>
13704
+ <p>\u5B9A\u4F4D\u306F\u300C\u97F3\u3092\u3069\u3053\u306B\u7F6E\u304F\u304B\u300D\uFF08\u5DE6\u5BC4\u308A/\u4E2D\u592E/\u53F3\u5BC4\u308A\uFF09\u3001\u30B9\u30C6\u30EC\u30AA\u5E45\u306F\u300C\u305D\u306E\u97F3\u81EA\u4F53\u304C\u3069\u308C\u3060\u3051\u5E83\u304C\u3063\u3066\u805E\u3053\u3048\u308B\u304B\u300D\u3067\u3001\u5F79\u5272\u304C\u7570\u306A\u308A\u307E\u3059\u3002\u4E21\u65B9\u3092\u5F37\u304F\u4F7F\u3046\u3068\u5B9A\u4F4D\u304C\u307C\u3084\u3051\u3066\u66D6\u6627\u306B\u306A\u308A\u304C\u3061\u3067\u3059\u3002</p>
13705
+ <h4>\u30DF\u30C3\u30AF\u30B9\u306E\u5B9A\u77F3</h4>
13706
+ <p>\u4E3B\u65CB\u5F8B\u30FB\u30DC\u30FC\u30AB\u30EB\u30FB\u30D9\u30FC\u30B9\u306A\u3069\u66F2\u306E\u8EF8\u306B\u306A\u308B\u30D1\u30FC\u30C8\u306F\u4E2D\u592E\u4ED8\u8FD1\u306B\u7F6E\u304D\u3001\u30CF\u30E2\u30EA\u30FB\u30AB\u30A6\u30F3\u30BF\u30FC\u30E1\u30ED\u30C7\u30A3\u30FB\u4F34\u594F\uFF08\u30B3\u30FC\u30C9/\u30D1\u30C3\u30C9\uFF09\u306A\u3069\u5F69\u308A\u306E\u30D1\u30FC\u30C8\u3092\u5DE6\u53F3\u3078\u632F\u308A\u5206\u3051\u308B\u3068\u3001\u5404\u30D1\u30FC\u30C8\u306E\u5C45\u5834\u6240\u304C\u5206\u304B\u308C\u3066\u805E\u304D\u53D6\u308A\u3084\u3059\u304F\u306A\u308A\u307E\u3059\uFF08\u7279\u306B\u4F4E\u57DF\u306F\u4E2D\u592E\u306B\u96C6\u3081\u308B\u306E\u304C\u5B9A\u77F3\u3067\u3059 \u2014 \u5DE6\u53F3\u306B\u632F\u308B\u3068\u4F4D\u76F8\u5E72\u6E09\u3067\u30E2\u30CE\u30E9\u30EB\u518D\u751F\u6642\u306B\u4F4E\u97F3\u304C\u75E9\u305B\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\uFF09\u3002</p>
13707
+ </div>
13708
+ `;
13636
13709
  var TRACK_REVERBSEND_INFO_HTML = `
13637
13710
  <div class="dtm-modal-body-content">
13638
13711
  <h4>\u4F55\u3092\u3059\u308B\u8A2D\u5B9A\u304B</h4>
@@ -13643,34 +13716,58 @@ var TRACK_REVERBSEND_INFO_HTML = `
13643
13716
  <p>Mix\u306F\u300C\u9001\u3089\u308C\u3066\u304D\u305F\u97F3\u3092\u3069\u308C\u3060\u3051\u8FD4\u3059\u304B\u300D\u3068\u3044\u3046\u5168\u4F53\u306E\u8FD4\u308A\u91CF\u3067\u3059\u3002\u5404\u30C8\u30E9\u30C3\u30AF\u306E\u9001\u308A\u91CF\u304C0\u306A\u3089\u3001Mix\u3092\u4E0A\u3052\u3066\u3082\u4F55\u3082\u8FD4\u3063\u3066\u304D\u307E\u305B\u3093\u3002\u307E\u305A\u3053\u306E\u30C8\u30E9\u30C3\u30AF\u306E\u9001\u308A\u91CF\u3092\u6C7A\u3081\u3066\u304B\u3089\u3001Mix\u3067\u5168\u4F53\u306E\u639B\u304B\u308A\u5177\u5408\u3092\u5FAE\u8ABF\u6574\u3057\u3066\u304F\u3060\u3055\u3044\u3002</p>
13644
13717
  </div>
13645
13718
  `;
13719
+ var TRACK_DELAYSEND_INFO_HTML = `
13720
+ <div class="dtm-modal-body-content">
13721
+ <h4>\u4F55\u3092\u3059\u308B\u8A2D\u5B9A\u304B</h4>
13722
+ <p>\u3053\u306E\u30C8\u30E9\u30C3\u30AF\u306E\u97F3\u3092\u3001\u30DE\u30B9\u30BF\u30C7\u30A3\u30EC\u30A4\uFF08[delay]\u30D1\u30CD\u30EB\uFF09\u3078\u3069\u308C\u3060\u3051\u9001\u308B\u304B\u3092 0-100% \u3067\u6C7A\u3081\u307E\u3059\u30020\u306A\u3089\u9001\u3089\u306A\u3044\uFF1D\u3053\u306E\u30C8\u30E9\u30C3\u30AF\u306B\u306F\u30C7\u30A3\u30EC\u30A4\u304C\u639B\u304B\u308A\u307E\u305B\u3093\u3002</p>
13723
+ <h4>\u300C\u4F4E\u57DF\u306B\u306F\u639B\u3051\u306A\u3044\u300D\u304C\u5B9A\u77F3</h4>
13724
+ <p>\u30C7\u30A3\u30EC\u30A4\uFF08\u3084\u307E\u3073\u3053\u306E\u3088\u3046\u306A\u7E70\u308A\u8FD4\u3057\uFF09\u3092\u4F4E\u57DF\u306B\u639B\u3051\u308B\u3068\u3001\u7E70\u308A\u8FD4\u3057\u304C\u91CD\u306A\u3063\u3066\u30EA\u30BA\u30E0\u304C\u6FC1\u308A\u3084\u3059\u3044\u305F\u3081\u3001\u30D9\u30FC\u30B9\u306A\u3069\u4F4E\u97F3\u30D1\u30FC\u30C8\u306F\u9001\u3089\u306A\u3044\uFF080\u306E\u307E\u307E\uFF09\u306E\u304C\u5B9A\u77F3\u3067\u3059\u3002\u30EA\u30FC\u30C9\u697D\u5668\u30FB\u30DC\u30FC\u30AB\u30EB\u306E\u8A9E\u5C3E\u306A\u3069\u3001\u805E\u304B\u305B\u305F\u3044\u30EF\u30F3\u30DD\u30A4\u30F3\u30C8\u3060\u3051\u306B\u9001\u308B\u306E\u304C\u52B9\u679C\u7684\u3067\u3059\u3002</p>
13725
+ <h4>[delay]\u30D1\u30CD\u30EB\u306EMix\u3068\u306E\u95A2\u4FC2</h4>
13726
+ <p>[delay]\u30D1\u30CD\u30EB\u306E\u639B\u304B\u308A\u5177\u5408\u304C0%\u3060\u3068\u3001\u3053\u3053\u3092\u3044\u304F\u3089\u4E0A\u3052\u3066\u3082\u7121\u97F3\u306E\u307E\u307E\u3067\u3059\u3002\u300C\u9001\u308A\u91CF\uFF08\u3053\u306E\u30C8\u30E9\u30C3\u30AF\u304C\u3069\u308C\u3060\u3051\u63D0\u4F9B\u3059\u308B\u304B\uFF09\u300D\u3068\u300C\u30DE\u30B9\u30BF\u306E\u30C7\u30A3\u30EC\u30A4\u8A2D\u5B9A\uFF08\u5B9F\u969B\u306B\u3069\u3093\u306A\u7E70\u308A\u8FD4\u3057\u304C\u639B\u304B\u308B\u304B\uFF09\u300D\u306E\u4E8C\u6BB5\u69CB\u3048\u306B\u306A\u3063\u3066\u3044\u308B\u305F\u3081\u3067\u3059\u3002\u4E21\u65B9\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002</p>
13727
+ </div>
13728
+ `;
13729
+ var MASTER_COMP_INFO_HTML = `
13730
+ <div class="dtm-modal-body-content">
13731
+ <h4>\u4F55\u3092\u3059\u308B\u8A2D\u5B9A\u304B</h4>
13732
+ <p>\u5168\u30C8\u30E9\u30C3\u30AF\u304C\u5408\u6D41\u3057\u305F\u5F8C\uFF08\u30DE\u30B9\u30BF\u30EA\u30D0\u30FC\u30D6\u30FB\u30DE\u30B9\u30BF\u30C7\u30A3\u30EC\u30A4\u306E\u623B\u308A\u3082\u542B\u3080\uFF09\u306B\u307E\u3068\u3081\u3066\u8EFD\u304F\u639B\u3051\u308B\u3001\u30DE\u30B9\u30BF\u30D0\u30B9\u306E\u300C\u30B0\u30EB\u30FC\uFF08\u63A5\u7740\u5264\uFF09\u30B3\u30F3\u30D7\u30EC\u30C3\u30B5\u30FC\u300D\u3067\u3059\u30020%\u3067\u7121\u52B9\u3001\u4E0A\u3052\u308B\u307B\u3069\u5404\u30C8\u30E9\u30C3\u30AF\u306E\u97F3\u91CF\u5DEE\u304C\u5747\u3055\u308C\u3001\u30D0\u30E9\u30D0\u30E9\u306B\u9CF4\u3063\u3066\u3044\u305F\u30D1\u30FC\u30C8\u304C\u3072\u3068\u307E\u3068\u307E\u308A\u306E\u300C\u30D0\u30F3\u30C9\u611F\u300D\u300C\u4E00\u4F53\u611F\u300D\u3092\u6301\u3063\u3066\u805E\u3053\u3048\u308B\u3088\u3046\u306B\u306A\u308A\u307E\u3059\u3002</p>
13733
+ <h4>\u5E38\u6642ON\u306E\u300C\u5B89\u5168\u30EA\u30DF\u30C3\u30BF\u30FC\u300D\u3068\u306E\u9055\u3044</h4>
13734
+ <p>\u97F3\u5272\u308C\u691C\u77E5\u30D0\u30C3\u30B8\u3068\u9023\u52D5\u3059\u308B\u5B89\u5168\u30EA\u30DF\u30C3\u30BF\u30FC\u306F\u3001\u5E38\u306BON\u3067\u97F3\u5272\u308C\u3092\u9632\u3050\u305F\u3081\u306E\u4FDD\u967A\u3067\u3059\u3002\u3053\u3061\u3089\u306E\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u306F\u65E2\u5B9A0\uFF08\u30AA\u30D5\uFF09\u3067\u3001\u97F3\u3092\u826F\u304F\u3059\u308B\u305F\u3081\u306E\u8868\u73FE\u76EE\u7684\u306E\u51E6\u7406\u3067\u3059\u3002\u639B\u304B\u308B\u9806\u5E8F\u306F\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u2192\u5B89\u5168\u30EA\u30DF\u30C3\u30BF\u30FC\u3067\u3001\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u901A\u904E\u5F8C\u306E\u4FE1\u53F7\u3092\u5B89\u5168\u30EA\u30DF\u30C3\u30BF\u30FC\u30FB\u97F3\u5272\u308C\u691C\u77E5\u30E1\u30FC\u30BF\u30FC\u304C\u76E3\u8996\u3057\u307E\u3059\u3002</p>
13735
+ <h4>\u30C8\u30E9\u30C3\u30AF\u5358\u4F4D\u306E\u300C\u97F3\u5727\u5F37\u5316\u300D\u3068\u306E\u9055\u3044</h4>
13736
+ <p>\u5404\u30C8\u30E9\u30C3\u30AF\u306E\u300C\u97F3\u5727\u5F37\u5316\u300D\uFF08\u30C1\u30E3\u30F3\u30CD\u30EB\u30B9\u30C8\u30EA\u30C3\u30D7\u306E\u30B3\u30F3\u30D7\u30EC\u30C3\u30B5\u30FC\uFF09\u306F\u3001\u305D\u306E\u30C8\u30E9\u30C3\u30AF\u5358\u4F53\u306E\u7C92\u7ACB\u3061\u3092\u63C3\u3048\u308B\u305F\u3081\u306E\u3082\u306E\u3067\u3059\u3002\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u306F\u305D\u308C\u3068\u306F\u5225\u306B\u3001\u5168\u30C8\u30E9\u30C3\u30AF\u304C\u6DF7\u3056\u3063\u305F\u5F8C\u306E\u300C\u5408\u594F\u300D\u5168\u4F53\u306B\u5BFE\u3057\u3066\u639B\u304B\u308A\u307E\u3059\u3002\u4E21\u65B9\u3092\u5F37\u304F\u639B\u3051\u3059\u304E\u308B\u3068\u30C0\u30A4\u30CA\u30DF\u30AF\u30B9\uFF08\u5F37\u5F31\u306E\u8868\u60C5\uFF09\u304C\u5931\u308F\u308C\u3066\u5358\u8ABF\u306B\u306A\u308A\u3084\u3059\u3044\u305F\u3081\u3001\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u306F\u63A7\u3048\u3081\uFF0820\u301C40%\u7A0B\u5EA6\uFF09\u304C\u51FA\u767A\u70B9\u306E\u76EE\u5B89\u3067\u3059\u3002</p>
13737
+ </div>
13738
+ `;
13646
13739
  var AUTO_MASTER_INFO_HTML = `
13647
13740
  <div class="dtm-modal-body-content">
13648
13741
  <h4>\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0\u3068\u306F</h4>
13649
13742
  <p>\u5E02\u8CA9\u66F2\u3067\u3088\u304F\u4F7F\u308F\u308C\u308B\u5024\u3092\u76EE\u5B89\u306B\u3001\u4EE5\u4E0B\u3092\u307E\u3068\u3081\u3066\u8A2D\u5B9A\u3059\u308B\u30DC\u30BF\u30F3\u3067\u3059\u3002\u66F2\u306EBPM\u3092\u898B\u3066\u4E00\u90E8\u306E\u5024\u3092\u81EA\u52D5\u8ABF\u6574\u3057\u307E\u3059\u3002</p>
13743
+ <h4>\u30B2\u30A4\u30F3\u30B9\u30C6\u30FC\u30B8\u30F3\u30B0\uFF08\u5B9F\u6E2C\u30D9\u30FC\u30B9\u306E\u97F3\u91CF\u8ABF\u6574\uFF09</h4>
13744
+ <p>\u518D\u751F\u3057\u3066\u3044\u308B\u9593\u3001\u88CF\u3067\u30DE\u30B9\u30BF\u306E\u30D4\u30FC\u30AF\u30EC\u30D9\u30EB\uFF08\u97F3\u5272\u308C\u691C\u77E5\u30D0\u30C3\u30B8\u3068\u540C\u3058\u5B9F\u6E2C\u5024\uFF09\u3092\u7D99\u7D9A\u7684\u306B\u53CE\u96C6\u3057\u3066\u3044\u307E\u3059\u3002\u5408\u8A082\u79D2\u4EE5\u4E0A\u306E\u518D\u751F\u5B9F\u7E3E\u304C\u6E9C\u307E\u3063\u3066\u3044\u308C\u3070\u3001\u300C\u304A\u307E\u304B\u305B\u300D\u5B9F\u884C\u6642\u306B\u305D\u306E\u5B9F\u6E2C\u30D4\u30FC\u30AF\u3092\u76EE\u6A19\u30D8\u30C3\u30C9\u30EB\u30FC\u30E0\uFF08-6dBFS\u4ED8\u8FD1\uFF09\u306B\u53CE\u307E\u308B\u3088\u3046\u9006\u7B97\u3057\u3066\u3001\u30DE\u30B9\u30BF\u97F3\u91CF\u3092\u81EA\u52D5\u8ABF\u6574\u3057\u307E\u3059\u3002</p>
13745
+ <p style="margin-top:4px;"><small>\u30CE\u30FC\u30C8\u306E\u30D9\u30ED\u30B7\u30C6\u30A3\u306A\u3069\u9759\u7684\u306A\u60C5\u5831\u3060\u3051\u3067\u306F\u3001\u8907\u6570\u30C8\u30E9\u30C3\u30AF\u304C\u91CD\u306A\u3063\u3066\u5B9F\u969B\u306B\u3069\u308C\u3060\u3051\u97F3\u5727\u304C\u7A4D\u307F\u4E0A\u304C\u308B\u304B\uFF08\u30C8\u30E9\u30C3\u30AF\u5358\u4F4D\u306E\u5727\u7E2E\u30FBEQ\u5F8C\u306E\u5024\u3082\u542B\u3080\uFF09\u306F\u5206\u304B\u308A\u307E\u305B\u3093\u3002\u5B9F\u969B\u306B\u9CF4\u3089\u3057\u305F\u97F3\u3092\u6E2C\u308B\u306E\u304C\u6700\u3082\u78BA\u5B9F\u306A\u305F\u3081\u3001\u3053\u306E\u30DC\u30BF\u30F3\u3092\u62BC\u3059\u305F\u3073\u306B\u4F7F\u3046\u306E\u3067\u306F\u306A\u304F\u3001\u3042\u308B\u7A0B\u5EA6\u7DE8\u96C6\u3057\u3066\u4E00\u5EA6\u3067\u3082\u518D\u751F\u3057\u305F\u5F8C\u306B\u62BC\u3059\u3068\u52B9\u679C\u3092\u767A\u63EE\u3057\u307E\u3059\u3002\u4E00\u5EA6\u3082\u518D\u751F\u3057\u3066\u3044\u306A\u3044\u30FB\u518D\u751F\u6642\u9593\u304C\u77ED\u3059\u304E\u308B\u5834\u5408\u306F\u5224\u65AD\u6750\u6599\u304C\u7121\u3044\u305F\u3081\u3001\u3053\u306E\u9805\u76EE\u306F\u30B9\u30AD\u30C3\u30D7\u3055\u308C\u4ED6\u306E\u5024\u3060\u3051\u304C\u9069\u7528\u3055\u308C\u307E\u3059\u3002</small></p>
13650
13746
  <ul>
13651
- <li>\u30DE\u30B9\u30BF\u30EA\u30D0\u30FC\u30D6 Mix: 20%</li>
13747
+ <li>\u30DE\u30B9\u30BF\u30D0\u30B9 \u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u30EC\u30C3\u30B5\u30FC: 25%\uFF08\u5404\u30C8\u30E9\u30C3\u30AF\u306E\u982D\u3092\u8EFD\u304F\u5747\u3057\u3066\u4E00\u4F53\u611F\u3092\u51FA\u3059\u3001\u63A7\u3048\u3081\u306A\u91CF\uFF09</li>
13748
+ <li>\u30DE\u30B9\u30BF\u30EA\u30D0\u30FC\u30D6 Mix: <strong>\u30A2\u30EC\u30F3\u30B8\u306E\u5BC6\u5EA6\uFF08\u97F3\u306E\u5165\u3063\u3066\u3044\u308B\u30C8\u30E9\u30C3\u30AF\u6570\uFF09\u306B\u5FDC\u3058\u3066\u81EA\u52D5\u8A08\u7B97</strong>\uFF082\u30C8\u30E9\u30C3\u30AF\u4EE5\u4E0B\u306728%\u30018\u30C8\u30E9\u30C3\u30AF\u4EE5\u4E0A\u306712%\u3001\u305D\u306E\u9593\u306F\u7DDA\u5F62\u88DC\u9593\uFF09</li>
13652
13749
  <li>\u30DE\u30B9\u30BF\u30EA\u30D0\u30FC\u30D6 Decay: <strong>\u73FE\u5728\u306EBPM\u306B\u5FDC\u3058\u3066\u81EA\u52D5\u8A08\u7B97</strong>\uFF08\u901F\u3044\u66F2\u307B\u3069\u77ED\u304F0.9\u79D2\u5BC4\u308A\u3001\u9045\u3044\u66F2\u307B\u3069\u9577\u304F3.0\u79D2\u5BC4\u308A\uFF09</li>
13653
13750
  <li>\u30DE\u30B9\u30BF\u30EA\u30D0\u30FC\u30D6 Pre Delay: 20ms\uFF08\u539F\u97F3\u306E\u8F2A\u90ED\u3092\u4FDD\u3063\u305F\u307E\u307E\u5965\u884C\u304D\u3092\u8DB3\u3059\u5B9A\u756A\u5024\uFF09</li>
13654
- <li>\u5404\u30C8\u30E9\u30C3\u30AF\u306E\u97F3\u5727\u5F37\u5316: \u697D\u566835%\u30FB\u6B4C\u8A5E\u306E\u3042\u308B\u30C8\u30E9\u30C3\u30AF\u306F25%\uFF08\u5F37\u304F\u6F70\u3059\u3068\u8868\u60C5\u304C\u5931\u308F\u308C\u308B\u305F\u3081\u63A7\u3048\u3081\u306B\uFF09</li>
13655
- <li>\u5168\u30C8\u30E9\u30C3\u30AF\u306E\u30B9\u30C6\u30EC\u30AA\u5E45: 115%\uFF08\u308F\u305A\u304B\u306B\u5E83\u3052\u308B\uFF09</li>
13751
+ <li>\u30D5\u30A7\u30FC\u30C9\u30A2\u30A6\u30C8: \u672A\u8A2D\u5B9A\uFF080\u79D2\uFF09\u306E\u3068\u304D\u3060\u30511.5\u79D2\u3092\u88DC\u3046\uFF08\u66F2\u306E\u7D42\u308F\u308A\u3092\u3076\u3064\u5207\u308A\u306B\u3057\u306A\u3044\uFF09\u3002\u65E2\u306B0\u79D2\u4EE5\u5916\u306E\u5024\u304C\u8A2D\u5B9A\u6E08\u307F\u306A\u3089\u4E0A\u66F8\u304D\u3057\u306A\u3044</li>
13656
13752
  <li>\u6B4C\u8A5E\u306E\u3042\u308B\u30C8\u30E9\u30C3\u30AF: \u81EA\u52D5\u30D3\u30D6\u30E9\u30FC\u30C8ON</li>
13657
13753
  </ul>
13658
- <h4>\u697D\u5668\u30FB\u97F3\u91CF\u306E\u81EA\u52D5\u5272\u308A\u5F53\u3066</h4>
13659
- <p>\u6B4C\u8A5E\u306E\u306A\u3044\u30C8\u30E9\u30C3\u30AF\u306F\u3001\u7F6E\u304B\u308C\u3066\u3044\u308B\u30CE\u30FC\u30C8\u306E\u97F3\u9AD8\u30FB\u30BF\u30A4\u30DF\u30F3\u30B0\u30FB\u548C\u97F3\u306E\u539A\u307F\u304B\u3089\u5F79\u5272\u3092\u63A8\u5B9A\u3057\u3001\u697D\u5668\u3068\u97F3\u91CF\u3092\u81EA\u52D5\u3067\u5F53\u3066\u307E\u3059\u3002</p>
13754
+ <p style="margin-top:4px;"><small>\u30DE\u30B9\u30BF\u30EA\u30D0\u30FC\u30D6Mix\u3092\u5BC6\u5EA6\u3067\u6C7A\u3081\u308B\u306E\u306F\u3001\u300C\u97F3\u6570\u306E\u591A\u3044\u539A\u3044\u30A2\u30EC\u30F3\u30B8\u306B\u6B8B\u97FF\u3092\u91CD\u306D\u3059\u304E\u308B\u3068\u6FC1\u308B\u3001\u97F3\u6570\u306E\u5C11\u306A\u3044\u9699\u9593\u306E\u591A\u3044\u7DE8\u6210\u306B\u306F\u6B8B\u97FF\u3067\u7A7A\u9593\u3092\u57CB\u3081\u308B\u3068\u5FC3\u5730\u3088\u3044\u300D\u3068\u3044\u3046\u30DF\u30AD\u30B7\u30F3\u30B0\u306E\u5B9A\u77F3\u306B\u57FA\u3065\u304D\u307E\u3059\u3002</small></p>
13755
+ <h4>\u697D\u5668\u30FB\u97F3\u91CF\u30FB\u5F79\u5272\u3054\u3068\u306E\u30DF\u30C3\u30AF\u30B9\u306E\u81EA\u52D5\u5272\u308A\u5F53\u3066</h4>
13756
+ <p>\u6B4C\u8A5E\u306E\u306A\u3044\u30C8\u30E9\u30C3\u30AF\u306F\u3001\u7F6E\u304B\u308C\u3066\u3044\u308B\u30CE\u30FC\u30C8\u306E\u97F3\u9AD8\u30FB\u30BF\u30A4\u30DF\u30F3\u30B0\u30FB\u548C\u97F3\u306E\u539A\u307F\u304B\u3089\u5F79\u5272\uFF08\u30E1\u30ED\u30C7\u30A3/\u30B5\u30D6\u30E1\u30ED/\u30D9\u30FC\u30B9/\u4F34\u594F\uFF09\u3092\u63A8\u5B9A\u3057\u3001\u697D\u5668\u30FB\u97F3\u91CF\u306B\u52A0\u3048\u3066\u97F3\u5727\u5F37\u5316\u30FB\u30B9\u30C6\u30EC\u30AA\u5E45\u30FB\u5B9A\u4F4D\u30FB\u30EA\u30D0\u30FC\u30D6\u9001\u308A\u30FB\u30C7\u30A3\u30EC\u30A4\u9001\u308A\u30FBEQ\u3092\u307E\u3068\u3081\u3066\u5F79\u5272\u76F8\u5FDC\u306E\u5024\u3078\u8A2D\u5B9A\u3057\u307E\u3059\u3002</p>
13660
13757
  <ul>
13661
- <li><strong>\u4F4E\u97F3\u57DF\uFF08C3\u672A\u6E80\uFF09\u304C\u4E2D\u5FC3</strong> \u2192 \u30D9\u30FC\u30B9\u697D\u5668\u30FB\u97F3\u91CF85</li>
13662
- <li><strong>\u548C\u97F3\uFF08\u540C\u6642\u767A\u97F3\uFF09\u304C\u591A\u304F\u97F3\u4FA1\u3082\u9577\u3044</strong> \u2192 \u4F34\u594F\uFF08\u30B3\u30FC\u30C9/\u30D1\u30C3\u30C9\uFF09\u697D\u5668\u30FB\u97F3\u91CF72</li>
13663
- <li><strong>\u5358\u97F3\u3067\u97F3\u6570\u304C\u5C11\u306A\u304F\u97F3\u4FA1\u304C\u9577\u3044</strong> \u2192 \u30B5\u30D6\u30E1\u30ED\uFF08\u30AA\u30D6\u30EA\u30AC\u30FC\u30C8\u5BC4\u308A\uFF09\u697D\u5668\u30FB\u97F3\u91CF92</li>
13664
- <li><strong>\u305D\u308C\u4EE5\u5916\uFF08\u5358\u97F3\u3067\u52D5\u304D\u304C\u591A\u3044\uFF09</strong> \u2192 \u30E1\u30ED\u30C7\u30A3\u697D\u5668\u30FB\u97F3\u91CF100</li>
13758
+ <li><strong>\u4F4E\u97F3\u57DF\uFF08C3\u672A\u6E80\uFF09\u304C\u4E2D\u5FC3</strong> \u2192 \u30D9\u30FC\u30B9\u3002\u57FA\u6E96\u97F3\u91CF85\uFF08\u4F4E\u3044\u307B\u3069\u5E95\u4E0A\u3052\u3001\u6700\u5927+12\uFF09\u3001\u97F3\u5727\u5F37\u531640%\uFF08\u7C92\u7ACB\u3061\u3092\u63C3\u3048\u308B\uFF09\u3001\u30B9\u30C6\u30EC\u30AA\u5E45100%\uFF08\u5E83\u3052\u306A\u3044\uFF09\u3001\u5B9A\u4F4D\u306F\u4E2D\u592E\u56FA\u5B9A\u3001\u30EA\u30D0\u30FC\u30D6\u9001\u308A5%\uFF08\u6FC1\u308A\u9632\u6B62\uFF09\u3001\u30C7\u30A3\u30EC\u30A4\u9001\u308A0%\uFF08\u4F4E\u57DF\u306B\u306F\u639B\u3051\u306A\u3044\uFF09\u3001EQ\u4F4E\u57DF+2dB\uFF0F\u9AD8\u57DF-3dB\u3002</li>
13759
+ <li><strong>\u548C\u97F3\uFF08\u540C\u6642\u767A\u97F3\uFF09\u304C\u591A\u304F\u97F3\u4FA1\u3082\u9577\u3044</strong> \u2192 \u4F34\u594F\uFF08\u30B3\u30FC\u30C9/\u30D1\u30C3\u30C9\uFF09\u3002\u57FA\u6E96\u97F3\u91CF72\uFF08\u91CD\u306A\u308A\u306E\u539A\u307F\u3076\u3093\u3055\u3089\u306B\u4E0B\u3052\u308B\uFF09\u3001\u97F3\u5727\u5F37\u531625%\uFF08\u81EA\u7136\u306A\u5F37\u5F31\u3092\u6B8B\u3059\uFF09\u3001\u30B9\u30C6\u30EC\u30AA\u5E45118%\uFF08\u7A7A\u9593\u3092\u57CB\u3081\u308B\uFF09\u3001\u5B9A\u4F4D\u306F\u5DE6\u53F3\u3078\u5E83\u3081\u306B\u632F\u308A\u5206\u3051\u3001\u30EA\u30D0\u30FC\u30D6\u9001\u308A22%\u3001\u30C7\u30A3\u30EC\u30A4\u9001\u308A0%\u3001EQ\u4F4E\u57DF-4dB\uFF08\u30D9\u30FC\u30B9\u306E\u5E2F\u57DF\u3092\u7A7A\u3051\u308B\uFF09\u3002</li>
13760
+ <li><strong>\u5358\u97F3\u3067\u97F3\u6570\u304C\u5C11\u306A\u304F\u97F3\u4FA1\u304C\u9577\u3044</strong> \u2192 \u30B5\u30D6\u30E1\u30ED\uFF08\u30AA\u30D6\u30EA\u30AC\u30FC\u30C8\u5BC4\u308A\uFF09\u3002\u57FA\u6E96\u97F3\u91CF92\u3001\u97F3\u5727\u5F37\u531632%\u3001\u5B9A\u4F4D\u306F\u5DE6\u53F3\u3078\u3084\u3084\u632F\u308A\u5206\u3051\u3001\u30EA\u30D0\u30FC\u30D6\u9001\u308A15%\uFF08\u30E1\u30ED\u30C7\u30A3\u306E\u4E00\u6B69\u5F8C\u308D\u3078\uFF09\u3001\u30C7\u30A3\u30EC\u30A4\u9001\u308A8%\u3001EQ\u4F4E\u57DF-3dB\uFF0F\u9AD8\u57DF+1dB\u3002</li>
13761
+ <li><strong>\u305D\u308C\u4EE5\u5916\uFF08\u5358\u97F3\u3067\u52D5\u304D\u304C\u591A\u3044\uFF09</strong> \u2192 \u30E1\u30ED\u30C7\u30A3\u3002\u57FA\u6E96\u97F3\u91CF100\u3001\u97F3\u5727\u5F37\u531635%\u3001\u5B9A\u4F4D\u306F\u4E2D\u592E\u56FA\u5B9A\u3001\u30EA\u30D0\u30FC\u30D6\u9001\u308A12%\uFF08\u524D\u306B\u51FA\u3059\uFF09\u3001\u30C7\u30A3\u30EC\u30A4\u9001\u308A15%\uFF08\u805E\u304B\u305B\u3069\u3053\u308D\u306B\u8584\u304F\uFF09\u3001EQ\u4F4E\u57DF-2dB\uFF0F\u9AD8\u57DF+2dB\uFF08\u629C\u3051\u30FB\u30D7\u30EC\u30BC\u30F3\u30B9\uFF09\u3002</li>
13665
13762
  </ul>
13666
- <p style="margin-top:4px;"><small>\u697D\u5668\u540D\u306F\u73FE\u5728\u9078\u629E\u4E2D\u306E\u697D\u5668\u30D7\u30EA\u30BB\u30C3\u30C8\uFF08\u672A\u9078\u629E\u306A\u3089\u30B0\u30E9\u30F3\u30C9\u30D4\u30A2\u30CE\uFF09\u304B\u3089\u5F79\u5272\u306B\u5BFE\u5FDC\u3059\u308B\u3082\u306E\u3092\u5F15\u304D\u307E\u3059\u3002\u97F3\u306E\u5C11\u306A\u3044\u30C8\u30E9\u30C3\u30AF\uFF08\u7121\u97F3\uFF09\u306F\u5224\u5B9A\u3067\u304D\u306A\u3044\u305F\u3081\u5BFE\u8C61\u5916\u3067\u3059\u3002\u3042\u304F\u307E\u3067\u81EA\u52D5\u63A8\u5B9A\u306A\u306E\u3067\u3001\u610F\u56F3\u3068\u9055\u3046\u5834\u5408\u306F\u5404\u30C8\u30E9\u30C3\u30AF\u306E\u300C\u697D\u5668\u300D\u6B04\u304B\u3089\u500B\u5225\u306B\u9078\u3073\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002</small></p>
13763
+ <p style="margin-top:4px;"><small>\u3044\u305A\u308C\u3082\u4E00\u822C\u7684\u306A\u30DF\u30AD\u30B7\u30F3\u30B0\u306E\u7D4C\u9A13\u5247\u3067\u3059\u3002\u4F4E\u57DF\u306F\u30E2\u30CE\u30E9\u30EB\u306B\u5BC4\u305B\u308B\uFF08\u30D9\u30FC\u30B9\u306E\u30B9\u30C6\u30EC\u30AA\u5E45\u30FB\u5B9A\u4F4D\u3092\u4E2D\u592E\u56FA\u5B9A\u306B\u3059\u308B\uFF09\u3053\u3068\u3067\u4F4D\u76F8\u5E72\u6E09\u306B\u3088\u308B\u30E2\u30CE\u30E9\u30EB\u518D\u751F\u6642\u306E\u75E9\u305B\u3092\u9632\u304E\u3001\u4ED6\u30D1\u30FC\u30C8\u306FEQ\u3067\u4F4E\u57DF\u3092\u8EFD\u304F\u524A\u3063\u3066\u5468\u6CE2\u6570\u5E2F\u57DF\u3092\u30D9\u30FC\u30B9\u3068\u4F4F\u307F\u5206\u3051\u307E\u3059\uFF08frequency slotting\uFF09\u3002\u66F2\u306E\u8EF8\u306B\u306A\u308B\u30E1\u30ED\u30C7\u30A3\u30FB\u30D9\u30FC\u30B9\u306F\u4E2D\u592E\u3001\u5F69\u308A\u306E\u30B5\u30D6\u30E1\u30ED\u30FB\u4F34\u594F\u306F\u5DE6\u53F3\u3078\u6563\u3089\u3057\u3066\u5404\u30D1\u30FC\u30C8\u306E\u5C45\u5834\u6240\u3092\u5206\u3051\u307E\u3059\uFF08\u540C\u3058\u5F79\u5272\u306E\u30C8\u30E9\u30C3\u30AF\u304C\u8907\u6570\u3042\u308B\u3068\u304D\u306F\u5DE6\u53F3\u3092\u4EA4\u4E92\u306B\u632F\u308A\u5206\u3051\u307E\u3059\uFF09\u3002\u30C7\u30A3\u30EC\u30A4\u306F\u4F4E\u57DF\u306B\u639B\u3051\u308B\u3068\u7E70\u308A\u8FD4\u3057\u304C\u91CD\u306A\u308A\u30EA\u30BA\u30E0\u304C\u6FC1\u308B\u305F\u3081\u3001\u30D9\u30FC\u30B9\u30FB\u4F34\u594F\u306B\u306F\u9001\u308A\u307E\u305B\u3093\uFF08[delay]\u30D1\u30CD\u30EB\u306E\u639B\u304B\u308A\u5177\u5408\u304C\u65E2\u5B9A0%\uFF1D\u30AA\u30D5\u306A\u306E\u3067\u3001\u6709\u52B9\u5316\u3059\u308B\u307E\u3067\u306F\u7121\u97F3\uFF09\u3002\u697D\u5668\u540D\u306F\u73FE\u5728\u9078\u629E\u4E2D\u306E\u697D\u5668\u30D7\u30EA\u30BB\u30C3\u30C8\uFF08\u672A\u9078\u629E\u306A\u3089\u30B0\u30E9\u30F3\u30C9\u30D4\u30A2\u30CE\uFF09\u304B\u3089\u5F79\u5272\u306B\u5BFE\u5FDC\u3059\u308B\u3082\u306E\u3092\u5F15\u304D\u307E\u3059\u3002\u97F3\u306E\u7121\u3044\u30C8\u30E9\u30C3\u30AF\u306F\u5224\u5B9A\u3067\u304D\u306A\u3044\u305F\u3081\u5BFE\u8C61\u5916\u3067\u3059\u3002\u3042\u304F\u307E\u3067\u81EA\u52D5\u63A8\u5B9A\u306A\u306E\u3067\u3001\u610F\u56F3\u3068\u9055\u3046\u5834\u5408\u306F\u5404\u30C8\u30E9\u30C3\u30AF\u306E\u8A2D\u5B9A\u6B04\u304B\u3089\u500B\u5225\u306B\u9078\u3073\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002</small></p>
13667
13764
  <h4>\u30E1\u30A4\u30F3\u30DC\u30FC\u30AB\u30EB\u306E\u81EA\u52D5\u5224\u5B9A</h4>
13668
13765
  <p>\u6B4C\u8A5E\u306E\u3042\u308B\u30C8\u30E9\u30C3\u30AF\u304C\u8907\u6570\u3042\u308B\u5834\u5408\uFF08\u30CF\u30E2\u30EA\u30FB\u30B3\u30FC\u30E9\u30B9\u30FB\u639B\u3051\u58F0\u7B49\uFF09\u3001\u767A\u97F3\u6642\u9593\u304C\u6700\u3082\u9577\u3044\u30C8\u30E9\u30C3\u30AF\u3092\u300C\u30E1\u30A4\u30F3\u30DC\u30FC\u30AB\u30EB\u300D\u3068\u307F\u306A\u3057\u3001\u4ED6\u3068\u306F\u9055\u3046\u6271\u3044\u306B\u3057\u307E\u3059\u3002</p>
13669
13766
  <ul>
13670
- <li>\u30E1\u30A4\u30F3\u30DC\u30FC\u30AB\u30EB: \u97F3\u5727\u5F37\u531630%\u30FB\u30EA\u30D0\u30FC\u30D6\u9001\u308A15%\uFF08\u524D\u306B\u51FA\u3059\uFF09</li>
13671
- <li>\u305D\u308C\u4EE5\u5916\u306E\u30DC\u30FC\u30AB\u30EB: \u97F3\u5727\u5F37\u531625%\u30FB\u30EA\u30D0\u30FC\u30D6\u9001\u308A30%\uFF08\u5965\u3078\u99B4\u67D3\u307E\u305B\u308B\uFF09</li>
13767
+ <li>\u30E1\u30A4\u30F3\u30DC\u30FC\u30AB\u30EB: \u97F3\u5727\u5F37\u531630%\u30FB\u30EA\u30D0\u30FC\u30D6\u9001\u308A15%\uFF08\u524D\u306B\u51FA\u3059\uFF09\u30FB\u5B9A\u4F4D\u306F\u4E2D\u592E\u56FA\u5B9A</li>
13768
+ <li>\u305D\u308C\u4EE5\u5916\u306E\u30DC\u30FC\u30AB\u30EB: \u97F3\u5727\u5F37\u531625%\u30FB\u30EA\u30D0\u30FC\u30D6\u9001\u308A30%\uFF08\u5965\u3078\u99B4\u67D3\u307E\u305B\u308B\uFF09\u30FB\u5B9A\u4F4D\u306F\u5DE6\u53F3\u3078\u4EA4\u4E92\u306B\u632F\u3063\u3066\u30C0\u30D6\u30EA\u30F3\u30B0\u611F\u3092\u51FA\u3059</li>
13672
13769
  </ul>
13673
- <p style="margin-top:4px;"><small>\u300C\u524D\u306B\u51FA\u3057\u305F\u3044\u97F3\u306F\u30EA\u30D0\u30FC\u30D6\u5C11\u306A\u3081\u3001\u5965\u306B\u7F6E\u304D\u305F\u3044\u97F3\u306F\u30EA\u30D0\u30FC\u30D6\u591A\u3081\u300D\u3068\u3044\u3046\u5B9A\u77F3\u306B\u57FA\u3065\u3044\u3066\u3044\u307E\u3059\u3002EQ\u306F\u66F2\u30FB\u30D1\u30FC\u30C8\u3054\u3068\u306B\u4F55\u304C\u6FC1\u3063\u3066\u3044\u308B\u304B\u6B21\u7B2C\u3067\u81EA\u52D5\u5316\u306B\u5411\u304B\u306A\u3044\u305F\u3081\u5BFE\u8C61\u5916\u3067\u3059\u3002\u300C\u3044\u3044\u611F\u3058\u306E\u521D\u671F\u5024\u300D\u3092\u4E00\u62EC\u3067\u5F53\u3066\u308B\u3060\u3051\u3067\u3001\u66F2\u3084\u597D\u307F\u306B\u5FDC\u3058\u305F\u5FAE\u8ABF\u6574\u307E\u3067\u306F\u884C\u3044\u307E\u305B\u3093\u3002\u65E2\u5B58\u306E\u8A2D\u5B9A\u306F\u4E0A\u66F8\u304D\u3055\u308C\u308B\u306E\u3067\u3001\u6C17\u306B\u5165\u3089\u306A\u3051\u308C\u3070\u5404\u30B9\u30E9\u30A4\u30C0\u30FC\u304B\u3089\u500B\u5225\u306B\u623B\u3057\u3066\u304F\u3060\u3055\u3044\u3002</small></p>
13770
+ <p style="margin-top:4px;"><small>\u300C\u524D\u306B\u51FA\u3057\u305F\u3044\u97F3\u306F\u30EA\u30D0\u30FC\u30D6\u5C11\u306A\u3081\u3001\u5965\u306B\u7F6E\u304D\u305F\u3044\u97F3\u306F\u30EA\u30D0\u30FC\u30D6\u591A\u3081\u300D\u3068\u3044\u3046\u5B9A\u77F3\u306B\u57FA\u3065\u3044\u3066\u3044\u307E\u3059\u3002\u300C\u3044\u3044\u611F\u3058\u306E\u521D\u671F\u5024\u300D\u3092\u4E00\u62EC\u3067\u5F53\u3066\u308B\u3060\u3051\u3067\u3001\u66F2\u3084\u597D\u307F\u306B\u5FDC\u3058\u305F\u5FAE\u8ABF\u6574\u307E\u3067\u306F\u884C\u3044\u307E\u305B\u3093\u3002\u65E2\u5B58\u306E\u8A2D\u5B9A\u306F\u4E0A\u66F8\u304D\u3055\u308C\u308B\u306E\u3067\u3001\u6C17\u306B\u5165\u3089\u306A\u3051\u308C\u3070\u5404\u30B9\u30E9\u30A4\u30C0\u30FC\u304B\u3089\u500B\u5225\u306B\u623B\u3057\u3066\u304F\u3060\u3055\u3044\u3002</small></p>
13674
13771
  </div>
13675
13772
  `;
13676
13773
  var MIDI_INFO_HTML = `
@@ -13915,30 +14012,79 @@ var normalizeInstrumentName = (name) => {
13915
14012
  ) ?? name;
13916
14013
  };
13917
14014
  var AUTO_ROLE_STEPS_PER_BEAT = 48;
13918
- var AUTO_ROLE_VOLUME = {
14015
+ var AUTO_ROLE_BASE_VOLUME = {
13919
14016
  melody: 100,
13920
14017
  submelody: 92,
13921
14018
  bass: 85,
13922
14019
  chord: 72
13923
14020
  };
13924
- var classifyTrackRole = (notes) => {
14021
+ var computeAutoRoleStats = (notes) => {
13925
14022
  const avgPitch = notes.reduce((s, n) => s + n.pitch, 0) / notes.length;
13926
- if (avgPitch < 48) return "bass";
13927
14023
  const avgDur = notes.reduce((s, n) => s + n.durationSteps, 0) / notes.length;
13928
14024
  const byStart = /* @__PURE__ */ new Map();
13929
14025
  for (const n of notes)
13930
14026
  byStart.set(n.startStep, (byStart.get(n.startStep) ?? 0) + 1);
13931
14027
  let maxPoly = 0;
13932
14028
  for (const c of byStart.values()) if (c > maxPoly) maxPoly = c;
13933
- if (maxPoly >= 2 && avgDur >= AUTO_ROLE_STEPS_PER_BEAT) return "chord";
14029
+ const avgPoly = notes.length / byStart.size;
13934
14030
  const minStart = Math.min(...notes.map((n) => n.startStep));
13935
14031
  const maxEnd = Math.max(...notes.map((n) => n.startStep + n.durationSteps));
13936
14032
  const spanBeats = Math.max(1, (maxEnd - minStart) / AUTO_ROLE_STEPS_PER_BEAT);
13937
14033
  const notesPerBeat = notes.length / spanBeats;
13938
- if (notesPerBeat < 1.2 && avgDur >= AUTO_ROLE_STEPS_PER_BEAT * 1.5)
14034
+ return { avgPitch, avgDur, avgPoly, maxPoly, notesPerBeat };
14035
+ };
14036
+ var classifyTrackRole = (stats) => {
14037
+ if (stats.avgPitch < 48) return "bass";
14038
+ if (stats.maxPoly >= 2 && stats.avgDur >= AUTO_ROLE_STEPS_PER_BEAT)
14039
+ return "chord";
14040
+ if (stats.notesPerBeat < 1.2 && stats.avgDur >= AUTO_ROLE_STEPS_PER_BEAT * 1.5)
13939
14041
  return "submelody";
13940
14042
  return "melody";
13941
14043
  };
14044
+ var computeAutoRoleVolume = (role, stats) => {
14045
+ let vol = AUTO_ROLE_BASE_VOLUME[role];
14046
+ if (role === "chord" && stats.avgPoly > 1) {
14047
+ vol /= Math.sqrt(stats.avgPoly);
14048
+ } else if (role === "bass") {
14049
+ const depthSemitones = Math.max(0, 48 - stats.avgPitch);
14050
+ vol += Math.min(12, depthSemitones * 0.5);
14051
+ }
14052
+ return clamp5(Math.round(vol), 1, 127);
14053
+ };
14054
+ var AUTO_ROLE_MIX = {
14055
+ melody: {
14056
+ compression: 35,
14057
+ width: 115,
14058
+ reverbSend: 12,
14059
+ delaySend: 15,
14060
+ eqLow: -2,
14061
+ eqHigh: 2
14062
+ },
14063
+ submelody: {
14064
+ compression: 32,
14065
+ width: 115,
14066
+ reverbSend: 15,
14067
+ delaySend: 8,
14068
+ eqLow: -3,
14069
+ eqHigh: 1
14070
+ },
14071
+ chord: {
14072
+ compression: 25,
14073
+ width: 118,
14074
+ reverbSend: 22,
14075
+ delaySend: 0,
14076
+ eqLow: -4,
14077
+ eqHigh: 0
14078
+ },
14079
+ bass: {
14080
+ compression: 40,
14081
+ width: 100,
14082
+ reverbSend: 5,
14083
+ delaySend: 0,
14084
+ eqLow: 2,
14085
+ eqHigh: -3
14086
+ }
14087
+ };
13942
14088
  var mountDAW = (target, options = {}) => {
13943
14089
  injectStyles();
13944
14090
  const getAudioTime = options.getAudioTime ?? (() => performance.now() / 1e3);
@@ -13969,6 +14115,8 @@ var mountDAW = (target, options = {}) => {
13969
14115
  });
13970
14116
  refs.masterVolume.value = String(options.masterVolume ?? 50);
13971
14117
  refs.masterVolumeLabel.textContent = `${options.masterVolume ?? 50}%`;
14118
+ refs.masterComp.value = String(options.masterCompression ?? 0);
14119
+ refs.masterCompLabel.textContent = `${options.masterCompression ?? 0}%`;
13972
14120
  refs.reverbAmount.value = String(options.reverbAmount ?? 0);
13973
14121
  refs.reverbAmountLabel.textContent = `${options.reverbAmount ?? 0}%`;
13974
14122
  {
@@ -14006,14 +14154,38 @@ var mountDAW = (target, options = {}) => {
14006
14154
  let reverbPreDelay = options.reverbPreDelay ?? DEFAULT_REVERB_PREDELAY_MS;
14007
14155
  let delayAmount = options.delayAmount ?? 0;
14008
14156
  let delayDivision = options.delayDivision ?? "8";
14157
+ let masterCompression = options.masterCompression ?? 0;
14009
14158
  let fadeInSec = options.fadeInSec ?? 0;
14010
14159
  let fadeOutSec = options.fadeOutSec ?? 0;
14011
14160
  let unsubscribeClip;
14161
+ let observedPeakMax = 0;
14162
+ let observedPlayMs = 0;
14163
+ let peakSampleRafId = null;
14164
+ let peakSampleLastTs = 0;
14165
+ const PEAK_SAMPLE_MIN_PLAY_MS = 2e3;
14166
+ const samplePeakTick = (ts) => {
14167
+ if (peakSampleLastTs) observedPlayMs += ts - peakSampleLastTs;
14168
+ peakSampleLastTs = ts;
14169
+ const peak = options.clipMeter?.getPeakLevel() ?? 0;
14170
+ if (peak > observedPeakMax) observedPeakMax = peak;
14171
+ peakSampleRafId = requestAnimationFrame(samplePeakTick);
14172
+ };
14173
+ const startPeakSampling = () => {
14174
+ if (peakSampleRafId !== null || !options.clipMeter) return;
14175
+ peakSampleLastTs = 0;
14176
+ peakSampleRafId = requestAnimationFrame(samplePeakTick);
14177
+ };
14178
+ const stopPeakSampling = () => {
14179
+ if (peakSampleRafId !== null) cancelAnimationFrame(peakSampleRafId);
14180
+ peakSampleRafId = null;
14181
+ peakSampleLastTs = 0;
14182
+ };
14012
14183
  options.onReverbChange?.(reverbAmount);
14013
14184
  options.onReverbDecayChange?.(reverbDecay);
14014
14185
  options.onReverbPreDelayChange?.(reverbPreDelay);
14015
14186
  options.onDelayChange?.(delayAmount);
14016
14187
  options.onDelayDivisionChange?.(delayDivision);
14188
+ options.onMasterCompressionChange?.(masterCompression);
14017
14189
  let drumVolume = options.drumVolume ?? 80;
14018
14190
  let currentDrumPattern = refs.drumSelect.value;
14019
14191
  let currentDrumFont = options.drumFont ?? "FluidR3_GM_sf2_file:0";
@@ -14173,7 +14345,9 @@ var mountDAW = (target, options = {}) => {
14173
14345
  trackReverbSend: 0,
14174
14346
  trackEqLow: 0,
14175
14347
  trackEqMid: 0,
14176
- trackEqHigh: 0
14348
+ trackEqHigh: 0,
14349
+ trackPan: 64,
14350
+ trackDelaySend: 0
14177
14351
  };
14178
14352
  });
14179
14353
  };
@@ -15046,6 +15220,7 @@ var mountDAW = (target, options = {}) => {
15046
15220
  }
15047
15221
  playbackState = "playing";
15048
15222
  sequencer.start(fromStep);
15223
+ startPeakSampling();
15049
15224
  {
15050
15225
  const anchor = sequencer.getStartTime();
15051
15226
  const secondsPerStepFade = 60 / bpm / 48;
@@ -15088,6 +15263,7 @@ var mountDAW = (target, options = {}) => {
15088
15263
  clearSoundTimers();
15089
15264
  options.onScheduleFade?.(null);
15090
15265
  playbackState = "paused";
15266
+ stopPeakSampling();
15091
15267
  updateTransport();
15092
15268
  };
15093
15269
  const reloadVoicesForModel = (model) => {
@@ -15103,6 +15279,7 @@ var mountDAW = (target, options = {}) => {
15103
15279
  options.onScheduleFade?.(null);
15104
15280
  playbackState = "stopped";
15105
15281
  currentPlayStep = 0;
15282
+ stopPeakSampling();
15106
15283
  updateTransport();
15107
15284
  redrawAll();
15108
15285
  };
@@ -15171,12 +15348,24 @@ var mountDAW = (target, options = {}) => {
15171
15348
  <span class="dtm-label" data-dtm="track-width-label"></span>
15172
15349
  <button class="dtm-infobtn" data-dtm="track-width-info" title="\u30B9\u30C6\u30EC\u30AA\u5E45\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15173
15350
  </div>
15351
+ <div class="dtm-row">
15352
+ <span class="dtm-label">\u5B9A\u4F4D</span>
15353
+ <input type="range" class="dtm-range dtm-grow" data-dtm="track-pan" min="0" max="127" aria-label="\u3053\u306E\u30C8\u30E9\u30C3\u30AF\u306E\u5DE6\u53F3\u306E\u5B9A\u4F4D\uFF0864=\u4E2D\u592E\u30010=\u5DE6\u3044\u3063\u3071\u3044\u3001127=\u53F3\u3044\u3063\u3071\u3044\uFF09">
15354
+ <span class="dtm-label" data-dtm="track-pan-label"></span>
15355
+ <button class="dtm-infobtn" data-dtm="track-pan-info" title="\u5B9A\u4F4D\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15356
+ </div>
15174
15357
  <div class="dtm-row">
15175
15358
  <span class="dtm-label">\u30EA\u30D0\u30FC\u30D6\u9001\u308A</span>
15176
15359
  <input type="range" class="dtm-range dtm-grow" data-dtm="track-reverb-send" min="0" max="100" aria-label="\u3053\u306E\u30C8\u30E9\u30C3\u30AF\u306E\u30DE\u30B9\u30BF\u30EA\u30D0\u30FC\u30D6\u3078\u306E\u9001\u308A\u91CF\uFF080=\u639B\u304B\u3089\u306A\u3044\uFF09">
15177
15360
  <span class="dtm-label" data-dtm="track-reverb-send-label"></span>
15178
15361
  <button class="dtm-infobtn" data-dtm="track-reverb-send-info" title="\u30EA\u30D0\u30FC\u30D6\u9001\u308A\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15179
15362
  </div>
15363
+ <div class="dtm-row">
15364
+ <span class="dtm-label">\u30C7\u30A3\u30EC\u30A4\u9001\u308A</span>
15365
+ <input type="range" class="dtm-range dtm-grow" data-dtm="track-delay-send" min="0" max="100" aria-label="\u3053\u306E\u30C8\u30E9\u30C3\u30AF\u306E\u30DE\u30B9\u30BF\u30C7\u30A3\u30EC\u30A4\u3078\u306E\u9001\u308A\u91CF\uFF080=\u639B\u304B\u3089\u306A\u3044\uFF09">
15366
+ <span class="dtm-label" data-dtm="track-delay-send-label"></span>
15367
+ <button class="dtm-infobtn" data-dtm="track-delay-send-info" title="\u30C7\u30A3\u30EC\u30A4\u9001\u308A\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15368
+ </div>
15180
15369
  </details>`;
15181
15370
  refs.trackBody.querySelector(
15182
15371
  '[data-dtm="track-fx-advanced"]'
@@ -15286,6 +15475,26 @@ var mountDAW = (target, options = {}) => {
15286
15475
  trackWidthInfo.addEventListener("click", () => {
15287
15476
  showModal("\u30B9\u30C6\u30EC\u30AA\u5E45\u306E\u89E3\u8AAC", TRACK_WIDTH_INFO_HTML);
15288
15477
  });
15478
+ const trackPanInput = refs.trackBody.querySelector(
15479
+ '[data-dtm="track-pan"]'
15480
+ );
15481
+ const trackPanLabel = refs.trackBody.querySelector(
15482
+ '[data-dtm="track-pan-label"]'
15483
+ );
15484
+ const trackPanInfo = refs.trackBody.querySelector(
15485
+ '[data-dtm="track-pan-info"]'
15486
+ );
15487
+ const fmtTrackPan = (pan) => pan === 64 ? "C" : pan < 64 ? `L${64 - pan}` : `R${pan - 64}`;
15488
+ trackPanInput.value = String(active.trackPan);
15489
+ trackPanLabel.textContent = fmtTrackPan(active.trackPan);
15490
+ trackPanInput.addEventListener("input", () => {
15491
+ active.trackPan = Number.parseInt(trackPanInput.value, 10);
15492
+ trackPanLabel.textContent = fmtTrackPan(active.trackPan);
15493
+ options.onTrackPanChange?.(active.config.id, active.trackPan);
15494
+ });
15495
+ trackPanInfo.addEventListener("click", () => {
15496
+ showModal("\u5B9A\u4F4D\u306E\u89E3\u8AAC", TRACK_PAN_INFO_HTML);
15497
+ });
15289
15498
  const trackReverbSendInput = refs.trackBody.querySelector(
15290
15499
  '[data-dtm="track-reverb-send"]'
15291
15500
  );
@@ -15308,6 +15517,25 @@ var mountDAW = (target, options = {}) => {
15308
15517
  trackReverbSendInfo.addEventListener("click", () => {
15309
15518
  showModal("\u30EA\u30D0\u30FC\u30D6\u9001\u308A\u306E\u89E3\u8AAC", TRACK_REVERBSEND_INFO_HTML);
15310
15519
  });
15520
+ const trackDelaySendInput = refs.trackBody.querySelector(
15521
+ '[data-dtm="track-delay-send"]'
15522
+ );
15523
+ const trackDelaySendLabel = refs.trackBody.querySelector(
15524
+ '[data-dtm="track-delay-send-label"]'
15525
+ );
15526
+ const trackDelaySendInfo = refs.trackBody.querySelector(
15527
+ '[data-dtm="track-delay-send-info"]'
15528
+ );
15529
+ trackDelaySendInput.value = String(active.trackDelaySend);
15530
+ trackDelaySendLabel.textContent = `${active.trackDelaySend}%`;
15531
+ trackDelaySendInput.addEventListener("input", () => {
15532
+ active.trackDelaySend = Number.parseInt(trackDelaySendInput.value, 10);
15533
+ trackDelaySendLabel.textContent = `${active.trackDelaySend}%`;
15534
+ options.onTrackDelaySendChange?.(active.config.id, active.trackDelaySend);
15535
+ });
15536
+ trackDelaySendInfo.addEventListener("click", () => {
15537
+ showModal("\u30C7\u30A3\u30EC\u30A4\u9001\u308A\u306E\u89E3\u8AAC", TRACK_DELAYSEND_INFO_HTML);
15538
+ });
15311
15539
  const instRow = document.createElement("div");
15312
15540
  instRow.className = "dtm-row";
15313
15541
  instRow.innerHTML = `<span class="dtm-label">\u697D\u5668</span>`;
@@ -15911,6 +16139,8 @@ var mountDAW = (target, options = {}) => {
15911
16139
  const trackEqLowForMeta = {};
15912
16140
  const trackEqMidForMeta = {};
15913
16141
  const trackEqHighForMeta = {};
16142
+ const trackPanForMeta = {};
16143
+ const trackDelaySendForMeta = {};
15914
16144
  trackStates.forEach((t, i2) => {
15915
16145
  if (t.trackInstrument) trackInstrumentsForMeta[i2] = t.trackInstrument;
15916
16146
  if (t.trackCompression !== 0)
@@ -15921,6 +16151,8 @@ var mountDAW = (target, options = {}) => {
15921
16151
  if (t.trackEqLow !== 0) trackEqLowForMeta[i2] = t.trackEqLow;
15922
16152
  if (t.trackEqMid !== 0) trackEqMidForMeta[i2] = t.trackEqMid;
15923
16153
  if (t.trackEqHigh !== 0) trackEqHighForMeta[i2] = t.trackEqHigh;
16154
+ if (t.trackPan !== 64) trackPanForMeta[i2] = t.trackPan;
16155
+ if (t.trackDelaySend !== 0) trackDelaySendForMeta[i2] = t.trackDelaySend;
15924
16156
  });
15925
16157
  const trackInstMeta = Object.keys(trackInstrumentsForMeta).length > 0 ? trackInstrumentsForMeta : void 0;
15926
16158
  const trackCompMeta = Object.keys(trackCompressionForMeta).length > 0 ? trackCompressionForMeta : void 0;
@@ -15929,6 +16161,8 @@ var mountDAW = (target, options = {}) => {
15929
16161
  const trackEqLowMeta = Object.keys(trackEqLowForMeta).length > 0 ? trackEqLowForMeta : void 0;
15930
16162
  const trackEqMidMeta = Object.keys(trackEqMidForMeta).length > 0 ? trackEqMidForMeta : void 0;
15931
16163
  const trackEqHighMeta = Object.keys(trackEqHighForMeta).length > 0 ? trackEqHighForMeta : void 0;
16164
+ const trackPanMeta = Object.keys(trackPanForMeta).length > 0 ? trackPanForMeta : void 0;
16165
+ const trackDelaySendMeta = Object.keys(trackDelaySendForMeta).length > 0 ? trackDelaySendForMeta : void 0;
15932
16166
  const metaLineFull = formatMmlMeta(
15933
16167
  {
15934
16168
  instrument: currentInstrument || void 0,
@@ -15940,6 +16174,7 @@ var mountDAW = (target, options = {}) => {
15940
16174
  reverbPreDelay,
15941
16175
  delay: delayAmount,
15942
16176
  delayDivision,
16177
+ masterCompression,
15943
16178
  fadeIn: Math.round(fadeInSec * 10),
15944
16179
  fadeOut: Math.round(fadeOutSec * 10),
15945
16180
  mode,
@@ -15949,7 +16184,9 @@ var mountDAW = (target, options = {}) => {
15949
16184
  trackReverbSend: trackReverbSendMeta,
15950
16185
  trackEqLow: trackEqLowMeta,
15951
16186
  trackEqMid: trackEqMidMeta,
15952
- trackEqHigh: trackEqHighMeta
16187
+ trackEqHigh: trackEqHighMeta,
16188
+ trackPan: trackPanMeta,
16189
+ trackDelaySend: trackDelaySendMeta
15953
16190
  },
15954
16191
  " "
15955
16192
  );
@@ -15964,6 +16201,7 @@ var mountDAW = (target, options = {}) => {
15964
16201
  reverbPreDelay,
15965
16202
  delay: delayAmount,
15966
16203
  delayDivision,
16204
+ masterCompression,
15967
16205
  fadeIn: Math.round(fadeInSec * 10),
15968
16206
  fadeOut: Math.round(fadeOutSec * 10),
15969
16207
  mode,
@@ -15973,7 +16211,9 @@ var mountDAW = (target, options = {}) => {
15973
16211
  trackReverbSend: trackReverbSendMeta,
15974
16212
  trackEqLow: trackEqLowMeta,
15975
16213
  trackEqMid: trackEqMidMeta,
15976
- trackEqHigh: trackEqHighMeta
16214
+ trackEqHigh: trackEqHighMeta,
16215
+ trackPan: trackPanMeta,
16216
+ trackDelaySend: trackDelaySendMeta
15977
16217
  },
15978
16218
  ""
15979
16219
  );
@@ -16211,6 +16451,12 @@ var mountDAW = (target, options = {}) => {
16211
16451
  refs.delayDivision.value = delayDivision;
16212
16452
  options.onDelayDivisionChange?.(delayDivision);
16213
16453
  }
16454
+ if (meta.masterCompression !== void 0) {
16455
+ masterCompression = meta.masterCompression;
16456
+ refs.masterComp.value = String(meta.masterCompression);
16457
+ refs.masterCompLabel.textContent = `${meta.masterCompression}%`;
16458
+ options.onMasterCompressionChange?.(meta.masterCompression);
16459
+ }
16214
16460
  if (meta.fadeIn !== void 0) {
16215
16461
  fadeInSec = meta.fadeIn / 10;
16216
16462
  refs.fadeIn.value = String(fadeInSec);
@@ -16262,6 +16508,16 @@ var mountDAW = (target, options = {}) => {
16262
16508
  t.trackEqHigh = eqHigh;
16263
16509
  options.onTrackEqHighChange?.(t.config.id, eqHigh);
16264
16510
  }
16511
+ const pan = meta.trackPan?.[i2] ?? 64;
16512
+ if (t.trackPan !== pan) {
16513
+ t.trackPan = pan;
16514
+ options.onTrackPanChange?.(t.config.id, pan);
16515
+ }
16516
+ const delaySend = meta.trackDelaySend?.[i2] ?? 0;
16517
+ if (t.trackDelaySend !== delaySend) {
16518
+ t.trackDelaySend = delaySend;
16519
+ options.onTrackDelaySendChange?.(t.config.id, delaySend);
16520
+ }
16265
16521
  });
16266
16522
  trackStates.forEach((t, i2) => {
16267
16523
  if (applyActiveOnly && i2 !== activeTrackIndex) return;
@@ -16639,6 +16895,14 @@ var mountDAW = (target, options = {}) => {
16639
16895
  refs.masterVolumeLabel.textContent = `${masterVolume}%`;
16640
16896
  options.singingVoices?.setVolume(masterVolume / 100);
16641
16897
  });
16898
+ refs.masterComp.addEventListener("input", () => {
16899
+ masterCompression = Number.parseInt(refs.masterComp.value, 10) || 0;
16900
+ refs.masterCompLabel.textContent = `${masterCompression}%`;
16901
+ options.onMasterCompressionChange?.(masterCompression);
16902
+ });
16903
+ refs.masterCompInfoBtn.addEventListener("click", () => {
16904
+ showModal("\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u306E\u89E3\u8AAC", MASTER_COMP_INFO_HTML);
16905
+ });
16642
16906
  refs.reverbAmount.addEventListener("input", () => {
16643
16907
  reverbAmount = Number.parseInt(refs.reverbAmount.value, 10) || 0;
16644
16908
  refs.reverbAmountLabel.textContent = `${reverbAmount}%`;
@@ -16688,10 +16952,31 @@ var mountDAW = (target, options = {}) => {
16688
16952
  showModal("\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0\u89E3\u8AAC", AUTO_MASTER_INFO_HTML);
16689
16953
  });
16690
16954
  refs.autoMasterBtn.addEventListener("click", () => {
16691
- reverbAmount = 20;
16692
- refs.reverbAmount.value = "20";
16693
- refs.reverbAmountLabel.textContent = "20%";
16694
- options.onReverbChange?.(20);
16955
+ if (observedPlayMs >= PEAK_SAMPLE_MIN_PLAY_MS && observedPeakMax > 0) {
16956
+ const targetPeak = 0.5;
16957
+ const scale = targetPeak / observedPeakMax;
16958
+ const suggested = clamp5(Math.round(masterVolume * scale), 10, 100);
16959
+ if (suggested !== masterVolume) {
16960
+ masterVolume = suggested;
16961
+ refs.masterVolume.value = String(masterVolume);
16962
+ refs.masterVolumeLabel.textContent = `${masterVolume}%`;
16963
+ options.singingVoices?.setVolume(masterVolume / 100);
16964
+ }
16965
+ observedPeakMax = 0;
16966
+ observedPlayMs = 0;
16967
+ }
16968
+ masterCompression = 25;
16969
+ refs.masterComp.value = "25";
16970
+ refs.masterCompLabel.textContent = "25%";
16971
+ options.onMasterCompressionChange?.(25);
16972
+ const activeTrackCount = trackStates.filter(
16973
+ (t) => t.core.getNotes().length > 0
16974
+ ).length;
16975
+ const densityT = clamp5((activeTrackCount - 2) / (8 - 2), 0, 1);
16976
+ reverbAmount = Math.round(28 - densityT * (28 - 12));
16977
+ refs.reverbAmount.value = String(reverbAmount);
16978
+ refs.reverbAmountLabel.textContent = `${reverbAmount}%`;
16979
+ options.onReverbChange?.(reverbAmount);
16695
16980
  const bpmT = clamp5((bpm - 60) / (180 - 60), 0, 1);
16696
16981
  reverbDecay = clamp5(
16697
16982
  3 - bpmT * (3 - 0.9),
@@ -16705,6 +16990,11 @@ var mountDAW = (target, options = {}) => {
16705
16990
  refs.reverbPreDelay.value = "20";
16706
16991
  refs.reverbPreDelayLabel.textContent = "20ms";
16707
16992
  options.onReverbPreDelayChange?.(20);
16993
+ if (fadeOutSec === 0) {
16994
+ fadeOutSec = 1.5;
16995
+ refs.fadeOut.value = "1.5";
16996
+ refs.fadeOutLabel.textContent = "1.5s";
16997
+ }
16708
16998
  let mainVocalId = null;
16709
16999
  let mainVocalScore = -1;
16710
17000
  for (const t of trackStates) {
@@ -16716,29 +17006,64 @@ var mountDAW = (target, options = {}) => {
16716
17006
  }
16717
17007
  }
16718
17008
  const autoPreset = INSTRUMENT_PRESETS[currentInstrument] ?? INSTRUMENT_PRESETS.piano;
17009
+ const roleByTrackId = /* @__PURE__ */ new Map();
16719
17010
  for (const t of trackStates) {
16720
17011
  if (t.lyricModel) continue;
16721
17012
  const notes = t.core.getNotes();
16722
17013
  if (notes.length === 0) continue;
16723
- const role = classifyTrackRole(notes);
17014
+ const stats = computeAutoRoleStats(notes);
17015
+ const role = classifyTrackRole(stats);
17016
+ roleByTrackId.set(t.config.id, role);
16724
17017
  const instName = autoPreset[role];
16725
17018
  t.trackInstrument = instName;
16726
17019
  const trackIndex = trackStates.indexOf(t);
16727
17020
  options.onTrackInstrumentChange?.(trackIndex, instName);
16728
- const vol = AUTO_ROLE_VOLUME[role];
17021
+ const vol = computeAutoRoleVolume(role, stats);
16729
17022
  t.volume = vol;
16730
17023
  t.core.setVolume(vol);
16731
17024
  }
17025
+ const AUTO_PAN_OFFSETS = {
17026
+ melody: [0],
17027
+ bass: [0],
17028
+ submelody: [18, -18, 30, -30],
17029
+ chord: [36, -36, 48, -48]
17030
+ };
17031
+ const panRoleCounter = /* @__PURE__ */ new Map();
17032
+ let vocalSideCounter = 0;
16732
17033
  for (const t of trackStates) {
16733
17034
  const isMainVocal = !!t.lyricModel && t.config.id === mainVocalId;
16734
- const comp = !t.lyricModel ? 35 : isMainVocal ? 30 : 25;
17035
+ const role = roleByTrackId.get(t.config.id);
17036
+ const roleMix = role ? AUTO_ROLE_MIX[role] : void 0;
17037
+ let pan = 64;
17038
+ if (t.lyricModel) {
17039
+ pan = isMainVocal ? 64 : clamp5(64 + (vocalSideCounter++ % 2 === 0 ? 22 : -22), 0, 127);
17040
+ } else if (role) {
17041
+ const offsets = AUTO_PAN_OFFSETS[role];
17042
+ const n = panRoleCounter.get(role) ?? 0;
17043
+ panRoleCounter.set(role, n + 1);
17044
+ pan = clamp5(64 + offsets[n % offsets.length], 0, 127);
17045
+ }
17046
+ t.trackPan = pan;
17047
+ options.onTrackPanChange?.(t.config.id, pan);
17048
+ const comp = t.lyricModel ? isMainVocal ? 30 : 25 : roleMix?.compression ?? 35;
17049
+ const width = t.lyricModel ? 115 : roleMix?.width ?? 115;
16735
17050
  t.trackCompression = comp;
16736
- t.trackWidth = 115;
17051
+ t.trackWidth = width;
16737
17052
  options.onTrackCompressionChange?.(t.config.id, comp);
16738
- options.onTrackWidthChange?.(t.config.id, 115);
17053
+ options.onTrackWidthChange?.(t.config.id, width);
16739
17054
  if (!t.lyricModel) {
16740
- t.trackReverbSend = 15;
16741
- options.onTrackReverbSendChange?.(t.config.id, 15);
17055
+ const reverbSend = roleMix?.reverbSend ?? 15;
17056
+ t.trackReverbSend = reverbSend;
17057
+ options.onTrackReverbSendChange?.(t.config.id, reverbSend);
17058
+ const eqLow = roleMix?.eqLow ?? 0;
17059
+ const eqHigh = roleMix?.eqHigh ?? 0;
17060
+ t.trackEqLow = eqLow;
17061
+ t.trackEqHigh = eqHigh;
17062
+ options.onTrackEqLowChange?.(t.config.id, eqLow);
17063
+ options.onTrackEqHighChange?.(t.config.id, eqHigh);
17064
+ const delaySend = roleMix?.delaySend ?? 0;
17065
+ t.trackDelaySend = delaySend;
17066
+ options.onTrackDelaySendChange?.(t.config.id, delaySend);
16742
17067
  }
16743
17068
  if (t.lyricModel) {
16744
17069
  t.vocalVibrato = true;
@@ -17828,6 +18153,7 @@ var mountDAW = (target, options = {}) => {
17828
18153
  sequencer.stop();
17829
18154
  options.singingVoices?.stopStream();
17830
18155
  unsubscribeClip?.();
18156
+ stopPeakSampling();
17831
18157
  resizeObserver.disconnect();
17832
18158
  document.removeEventListener("pointermove", onPointerMove);
17833
18159
  document.removeEventListener("pointerup", onPointerUp);
@@ -18786,13 +19112,39 @@ var createDtmStudio = async (options = {}) => {
18786
19112
  division: options.delayDivision ?? "8"
18787
19113
  });
18788
19114
  const setDelayAmount = (amount) => delayBus.setAmount(amount);
19115
+ const glueComp = audioCtx.createDynamicsCompressor();
19116
+ glueComp.knee.value = 6;
19117
+ const glueMakeup = audioCtx.createGain();
19118
+ finalMix.connect(glueComp);
19119
+ glueComp.connect(glueMakeup);
19120
+ const glueCompressionParams = (amount) => {
19121
+ const t = Math.max(0, Math.min(100, amount)) / 100;
19122
+ return {
19123
+ threshold: 0 + (-18 - 0) * t,
19124
+ ratio: 1 + (4 - 1) * t,
19125
+ attack: 0.03 + (0.01 - 0.03) * t,
19126
+ release: 0.3 + (0.15 - 0.3) * t,
19127
+ makeupDb: 2.5 * t
19128
+ };
19129
+ };
19130
+ const applyGlueCompression = (amount) => {
19131
+ const p = glueCompressionParams(amount);
19132
+ const now = audioCtx.currentTime;
19133
+ glueComp.threshold.setValueAtTime(p.threshold, now);
19134
+ glueComp.ratio.setValueAtTime(p.ratio, now);
19135
+ glueComp.attack.setValueAtTime(p.attack, now);
19136
+ glueComp.release.setValueAtTime(p.release, now);
19137
+ glueMakeup.gain.setTargetAtTime(10 ** (p.makeupDb / 20), now, 0.02);
19138
+ };
19139
+ applyGlueCompression(options.masterCompression ?? 0);
19140
+ const setMasterCompression = (amount) => applyGlueCompression(amount);
18789
19141
  const safetyLimiter = audioCtx.createDynamicsCompressor();
18790
19142
  safetyLimiter.threshold.value = -1;
18791
19143
  safetyLimiter.knee.value = 0;
18792
19144
  safetyLimiter.ratio.value = 20;
18793
19145
  safetyLimiter.attack.value = 1e-3;
18794
19146
  safetyLimiter.release.value = 0.1;
18795
- finalMix.connect(safetyLimiter);
19147
+ glueMakeup.connect(safetyLimiter);
18796
19148
  const fadeGain = audioCtx.createGain();
18797
19149
  fadeGain.gain.value = 1;
18798
19150
  safetyLimiter.connect(fadeGain);
@@ -18815,13 +19167,14 @@ var createDtmStudio = async (options = {}) => {
18815
19167
  fadeGain.gain.linearRampToValueAtTime(0, fadeOutEndAt);
18816
19168
  }
18817
19169
  };
18818
- const clipMeter = createClipMeter(audioCtx, finalMix);
19170
+ const clipMeter = createClipMeter(audioCtx, glueMakeup);
18819
19171
  const channelStrips = /* @__PURE__ */ new Map();
18820
19172
  const getChannelStrip = (trackId) => {
18821
19173
  let strip = channelStrips.get(trackId);
18822
19174
  if (!strip) {
18823
19175
  strip = createChannelStrip(audioCtx, masterGain, {
18824
- reverbBus: reverbPreDelay
19176
+ reverbBus: reverbPreDelay,
19177
+ delayBus: delayBus.input
18825
19178
  });
18826
19179
  channelStrips.set(trackId, strip);
18827
19180
  }
@@ -19152,6 +19505,8 @@ var createDtmStudio = async (options = {}) => {
19152
19505
  onDelayChange: setDelayAmount,
19153
19506
  delayDivision: options.delayDivision,
19154
19507
  onDelayDivisionChange: (division) => delayBus.setDivision(division),
19508
+ masterCompression: options.masterCompression,
19509
+ onMasterCompressionChange: setMasterCompression,
19155
19510
  onBpmChange: (bpm) => delayBus.setBpm(bpm),
19156
19511
  fadeInSec: options.fadeInSec,
19157
19512
  fadeOutSec: options.fadeOutSec,
@@ -19159,9 +19514,11 @@ var createDtmStudio = async (options = {}) => {
19159
19514
  onTrackCompressionChange: (trackId, amount) => getChannelStrip(trackId).setCompression(amount),
19160
19515
  onTrackWidthChange: (trackId, width) => getChannelStrip(trackId).setWidth(width),
19161
19516
  onTrackReverbSendChange: (trackId, amount) => getChannelStrip(trackId).setReverbSend(amount),
19517
+ onTrackDelaySendChange: (trackId, amount) => getChannelStrip(trackId).setDelaySend(amount),
19162
19518
  onTrackEqLowChange: (trackId, db) => getChannelStrip(trackId).setEqLow(db),
19163
19519
  onTrackEqMidChange: (trackId, db) => getChannelStrip(trackId).setEqMid(db),
19164
19520
  onTrackEqHighChange: (trackId, db) => getChannelStrip(trackId).setEqHigh(db),
19521
+ onTrackPanChange: (trackId, pan) => getChannelStrip(trackId).setPan(panToStereo(pan)),
19165
19522
  clipMeter,
19166
19523
  ...dawOverrides,
19167
19524
  // dawOverrides で上書きされないよう、スプレッドの後に配置して合成する
@@ -19743,6 +20100,7 @@ var createDtmStudio = async (options = {}) => {
19743
20100
  setReverbDecay,
19744
20101
  setReverbPreDelay,
19745
20102
  setDelayAmount,
20103
+ setMasterCompression,
19746
20104
  dispose
19747
20105
  };
19748
20106
  };