@onjmin/dtm 0.1.94 → 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.mjs CHANGED
@@ -1418,13 +1418,21 @@ var createChannelStrip = (ctx, destination, options = {}) => {
1418
1418
  );
1419
1419
  };
1420
1420
  setWidth(options.width ?? 100);
1421
+ const panner = typeof ctx.createStereoPanner === "function" ? ctx.createStereoPanner() : null;
1422
+ if (panner) panner.pan.value = clamp(options.pan ?? 0, -1, 1);
1423
+ const panOut = panner ?? merger;
1421
1424
  eqHigh.connect(compressor);
1422
1425
  compressor.connect(splitter);
1423
- merger.connect(destination);
1426
+ if (panner) merger.connect(panner);
1427
+ panOut.connect(destination);
1424
1428
  const reverbSendGain = ctx.createGain();
1425
1429
  reverbSendGain.gain.value = clamp(options.reverbSend ?? 0, 0, 100) / 100;
1426
- merger.connect(reverbSendGain);
1430
+ panOut.connect(reverbSendGain);
1427
1431
  if (options.reverbBus) reverbSendGain.connect(options.reverbBus);
1432
+ const delaySendGain = ctx.createGain();
1433
+ delaySendGain.gain.value = clamp(options.delaySend ?? 0, 0, 100) / 100;
1434
+ panOut.connect(delaySendGain);
1435
+ if (options.delayBus) delaySendGain.connect(options.delayBus);
1428
1436
  return {
1429
1437
  input,
1430
1438
  setEqLow: (db) => {
@@ -1457,6 +1465,17 @@ var createChannelStrip = (ctx, destination, options = {}) => {
1457
1465
  0.02
1458
1466
  );
1459
1467
  },
1468
+ setDelaySend: (amount) => {
1469
+ delaySendGain.gain.setTargetAtTime(
1470
+ clamp(amount, 0, 100) / 100,
1471
+ ctx.currentTime,
1472
+ 0.02
1473
+ );
1474
+ },
1475
+ setPan: (pan) => {
1476
+ if (!panner) return;
1477
+ panner.pan.setTargetAtTime(clamp(pan, -1, 1), ctx.currentTime, 0.02);
1478
+ },
1460
1479
  dispose: () => {
1461
1480
  input.disconnect();
1462
1481
  eqLow.disconnect();
@@ -1473,7 +1492,9 @@ var createChannelStrip = (ctx, destination, options = {}) => {
1473
1492
  outL.disconnect();
1474
1493
  outR.disconnect();
1475
1494
  merger.disconnect();
1495
+ panner?.disconnect();
1476
1496
  reverbSendGain.disconnect();
1497
+ delaySendGain.disconnect();
1477
1498
  }
1478
1499
  };
1479
1500
  };
@@ -3405,7 +3426,7 @@ var PITCH_MAP = {
3405
3426
  b: 11
3406
3427
  };
3407
3428
  var clamp3 = (value, lo, hi) => Math.min(hi, Math.max(lo, value));
3408
- var META_DIRECTIVE = /#(inst|drum|drumfont|volume|drumvolume|reverb|reverbdecay|reverbpredelay|delay|delaydiv|fadein|fadeout|mode)=([\w-]+)/gi;
3429
+ var META_DIRECTIVE = /#(inst|drum|drumfont|volume|drumvolume|reverb|reverbdecay|reverbpredelay|delay|delaydiv|mastercomp|fadein|fadeout|mode)=([\w-]+)/gi;
3409
3430
  var TRACK_INST_DIRECTIVE = /#t(\d+)inst=([^#;\r\n]+)/gi;
3410
3431
  var TRACK_COMP_DIRECTIVE = /#t(\d+)comp=(\d+)/gi;
3411
3432
  var TRACK_WIDTH_DIRECTIVE = /#t(\d+)width=(\d+)/gi;
@@ -3413,6 +3434,8 @@ var TRACK_REVERBSEND_DIRECTIVE = /#t(\d+)rev=(\d+)/gi;
3413
3434
  var TRACK_EQLOW_DIRECTIVE = /#t(\d+)eqlo=(-?\d+)/gi;
3414
3435
  var TRACK_EQMID_DIRECTIVE = /#t(\d+)eqmid=(-?\d+)/gi;
3415
3436
  var TRACK_EQHIGH_DIRECTIVE = /#t(\d+)eqhi=(-?\d+)/gi;
3437
+ var TRACK_PAN_DIRECTIVE = /#t(\d+)pan=(\d+)/gi;
3438
+ var TRACK_DELAYSEND_DIRECTIVE = /#t(\d+)dly=(\d+)/gi;
3416
3439
  var parseMmlMeta = (mml) => {
3417
3440
  const meta = {};
3418
3441
  for (const m of mml.matchAll(META_DIRECTIVE)) {
@@ -3440,6 +3463,9 @@ var parseMmlMeta = (mml) => {
3440
3463
  if (!Number.isNaN(dv)) meta.delay = clamp3(dv, 0, 100);
3441
3464
  } else if (key === "delaydiv") {
3442
3465
  if (["4", "8", "8d", "16"].includes(m[2])) meta.delayDivision = m[2];
3466
+ } else if (key === "mastercomp") {
3467
+ const mc = Number.parseInt(m[2], 10);
3468
+ if (!Number.isNaN(mc)) meta.masterCompression = clamp3(mc, 0, 100);
3443
3469
  } else if (key === "fadein") {
3444
3470
  const fi = Number.parseInt(m[2], 10);
3445
3471
  if (!Number.isNaN(fi)) meta.fadeIn = clamp3(fi, 0, 100);
@@ -3508,9 +3534,25 @@ var parseMmlMeta = (mml) => {
3508
3534
  meta.trackEqHigh[idx] = val;
3509
3535
  }
3510
3536
  }
3537
+ for (const m of mml.matchAll(TRACK_PAN_DIRECTIVE)) {
3538
+ const idx = Number.parseInt(m[1], 10);
3539
+ const val = clamp3(Number.parseInt(m[2], 10), 0, 127);
3540
+ if (!Number.isNaN(idx) && !Number.isNaN(val)) {
3541
+ meta.trackPan ??= {};
3542
+ meta.trackPan[idx] = val;
3543
+ }
3544
+ }
3545
+ for (const m of mml.matchAll(TRACK_DELAYSEND_DIRECTIVE)) {
3546
+ const idx = Number.parseInt(m[1], 10);
3547
+ const val = clamp3(Number.parseInt(m[2], 10), 0, 100);
3548
+ if (!Number.isNaN(idx) && !Number.isNaN(val)) {
3549
+ meta.trackDelaySend ??= {};
3550
+ meta.trackDelaySend[idx] = val;
3551
+ }
3552
+ }
3511
3553
  return meta;
3512
3554
  };
3513
- 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, "");
3555
+ 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, "");
3514
3556
  var formatMmlMeta = (meta, space = "") => {
3515
3557
  const parts = [];
3516
3558
  if (meta.instrument) parts.push(`#inst=${meta.instrument}`);
@@ -3529,6 +3571,8 @@ var formatMmlMeta = (meta, space = "") => {
3529
3571
  parts.push(`#delay=${meta.delay}`);
3530
3572
  if (meta.delayDivision && meta.delayDivision !== "8")
3531
3573
  parts.push(`#delaydiv=${meta.delayDivision}`);
3574
+ if (meta.masterCompression !== void 0 && meta.masterCompression !== 0)
3575
+ parts.push(`#mastercomp=${meta.masterCompression}`);
3532
3576
  if (meta.fadeIn !== void 0 && meta.fadeIn !== 0)
3533
3577
  parts.push(`#fadein=${meta.fadeIn}`);
3534
3578
  if (meta.fadeOut !== void 0 && meta.fadeOut !== 0)
@@ -3569,6 +3613,16 @@ var formatMmlMeta = (meta, space = "") => {
3569
3613
  if (val !== 0) parts.push(`#t${idx}eqhi=${val}`);
3570
3614
  }
3571
3615
  }
3616
+ if (meta.trackPan) {
3617
+ for (const [idx, val] of Object.entries(meta.trackPan)) {
3618
+ if (val !== 64) parts.push(`#t${idx}pan=${val}`);
3619
+ }
3620
+ }
3621
+ if (meta.trackDelaySend) {
3622
+ for (const [idx, val] of Object.entries(meta.trackDelaySend)) {
3623
+ if (val !== 0) parts.push(`#t${idx}dly=${val}`);
3624
+ }
3625
+ }
3572
3626
  return parts.join(space);
3573
3627
  };
3574
3628
  var parseMML = (mml, options = {}) => {
@@ -11403,7 +11457,13 @@ var buildUI = (target, options) => {
11403
11457
  <span class="dtm-label" data-dtm="master-volume-label">50%</span>
11404
11458
  </div>
11405
11459
  <div class="dtm-row">
11406
- <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\u3092\u5546\u696D\u66F2\u5BC4\u308A\u306E\u5024\u306B\u4E00\u62EC\u8A2D\u5B9A\u3057\u307E\u3059">\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0</button>
11460
+ <span class="dtm-label">\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7</span>
11461
+ <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">
11462
+ <span class="dtm-label" data-dtm="master-comp-label">0%</span>
11463
+ <button class="dtm-infobtn" data-dtm="master-comp-info" title="\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
11464
+ </div>
11465
+ <div class="dtm-row">
11466
+ <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>
11407
11467
  <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>
11408
11468
  <span class="dtm-grow"></span>
11409
11469
  </div>
@@ -11657,6 +11717,9 @@ var buildUI = (target, options) => {
11657
11717
  hScrollThumb: sel("hscroll-thumb"),
11658
11718
  masterVolume: sel("master-volume"),
11659
11719
  masterVolumeLabel: sel("master-volume-label"),
11720
+ masterComp: sel("master-comp"),
11721
+ masterCompLabel: sel("master-comp-label"),
11722
+ masterCompInfoBtn: sel("master-comp-info"),
11660
11723
  reverbAmount: sel("reverb-amount"),
11661
11724
  reverbAmountLabel: sel("reverb-amount-label"),
11662
11725
  reverbAmountInfoBtn: sel("reverb-amount-info"),
@@ -13502,6 +13565,16 @@ var TRACK_WIDTH_INFO_HTML = `
13502
13565
  <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>
13503
13566
  </div>
13504
13567
  `;
13568
+ var TRACK_PAN_INFO_HTML = `
13569
+ <div class="dtm-modal-body-content">
13570
+ <h4>\u4F55\u3092\u3059\u308B\u8A2D\u5B9A\u304B</h4>
13571
+ <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>
13572
+ <h4>\u300C\u30B9\u30C6\u30EC\u30AA\u5E45\u300D\u3068\u306E\u9055\u3044</h4>
13573
+ <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>
13574
+ <h4>\u30DF\u30C3\u30AF\u30B9\u306E\u5B9A\u77F3</h4>
13575
+ <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>
13576
+ </div>
13577
+ `;
13505
13578
  var TRACK_REVERBSEND_INFO_HTML = `
13506
13579
  <div class="dtm-modal-body-content">
13507
13580
  <h4>\u4F55\u3092\u3059\u308B\u8A2D\u5B9A\u304B</h4>
@@ -13512,25 +13585,58 @@ var TRACK_REVERBSEND_INFO_HTML = `
13512
13585
  <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>
13513
13586
  </div>
13514
13587
  `;
13588
+ var TRACK_DELAYSEND_INFO_HTML = `
13589
+ <div class="dtm-modal-body-content">
13590
+ <h4>\u4F55\u3092\u3059\u308B\u8A2D\u5B9A\u304B</h4>
13591
+ <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>
13592
+ <h4>\u300C\u4F4E\u57DF\u306B\u306F\u639B\u3051\u306A\u3044\u300D\u304C\u5B9A\u77F3</h4>
13593
+ <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>
13594
+ <h4>[delay]\u30D1\u30CD\u30EB\u306EMix\u3068\u306E\u95A2\u4FC2</h4>
13595
+ <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>
13596
+ </div>
13597
+ `;
13598
+ var MASTER_COMP_INFO_HTML = `
13599
+ <div class="dtm-modal-body-content">
13600
+ <h4>\u4F55\u3092\u3059\u308B\u8A2D\u5B9A\u304B</h4>
13601
+ <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>
13602
+ <h4>\u5E38\u6642ON\u306E\u300C\u5B89\u5168\u30EA\u30DF\u30C3\u30BF\u30FC\u300D\u3068\u306E\u9055\u3044</h4>
13603
+ <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>
13604
+ <h4>\u30C8\u30E9\u30C3\u30AF\u5358\u4F4D\u306E\u300C\u97F3\u5727\u5F37\u5316\u300D\u3068\u306E\u9055\u3044</h4>
13605
+ <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>
13606
+ </div>
13607
+ `;
13515
13608
  var AUTO_MASTER_INFO_HTML = `
13516
13609
  <div class="dtm-modal-body-content">
13517
13610
  <h4>\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0\u3068\u306F</h4>
13518
13611
  <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>
13612
+ <h4>\u30B2\u30A4\u30F3\u30B9\u30C6\u30FC\u30B8\u30F3\u30B0\uFF08\u5B9F\u6E2C\u30D9\u30FC\u30B9\u306E\u97F3\u91CF\u8ABF\u6574\uFF09</h4>
13613
+ <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>
13614
+ <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>
13519
13615
  <ul>
13520
- <li>\u30DE\u30B9\u30BF\u30EA\u30D0\u30FC\u30D6 Mix: 20%</li>
13616
+ <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>
13617
+ <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>
13521
13618
  <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>
13522
13619
  <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>
13523
- <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>
13524
- <li>\u5168\u30C8\u30E9\u30C3\u30AF\u306E\u30B9\u30C6\u30EC\u30AA\u5E45: 115%\uFF08\u308F\u305A\u304B\u306B\u5E83\u3052\u308B\uFF09</li>
13620
+ <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>
13525
13621
  <li>\u6B4C\u8A5E\u306E\u3042\u308B\u30C8\u30E9\u30C3\u30AF: \u81EA\u52D5\u30D3\u30D6\u30E9\u30FC\u30C8ON</li>
13526
13622
  </ul>
13623
+ <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>
13624
+ <h4>\u697D\u5668\u30FB\u97F3\u91CF\u30FB\u5F79\u5272\u3054\u3068\u306E\u30DF\u30C3\u30AF\u30B9\u306E\u81EA\u52D5\u5272\u308A\u5F53\u3066</h4>
13625
+ <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>
13626
+ <ul>
13627
+ <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>
13628
+ <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>
13629
+ <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>
13630
+ <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>
13631
+ </ul>
13632
+ <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>
13527
13633
  <h4>\u30E1\u30A4\u30F3\u30DC\u30FC\u30AB\u30EB\u306E\u81EA\u52D5\u5224\u5B9A</h4>
13528
13634
  <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>
13529
13635
  <ul>
13530
- <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>
13531
- <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>
13636
+ <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>
13637
+ <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>
13532
13638
  </ul>
13533
- <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>
13639
+ <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>
13534
13640
  </div>
13535
13641
  `;
13536
13642
  var MIDI_INFO_HTML = `
@@ -13774,6 +13880,80 @@ var normalizeInstrumentName = (name) => {
13774
13880
  (n) => n.replace(/\s+/g, "").toLowerCase() === stripped
13775
13881
  ) ?? name;
13776
13882
  };
13883
+ var AUTO_ROLE_STEPS_PER_BEAT = 48;
13884
+ var AUTO_ROLE_BASE_VOLUME = {
13885
+ melody: 100,
13886
+ submelody: 92,
13887
+ bass: 85,
13888
+ chord: 72
13889
+ };
13890
+ var computeAutoRoleStats = (notes) => {
13891
+ const avgPitch = notes.reduce((s, n) => s + n.pitch, 0) / notes.length;
13892
+ const avgDur = notes.reduce((s, n) => s + n.durationSteps, 0) / notes.length;
13893
+ const byStart = /* @__PURE__ */ new Map();
13894
+ for (const n of notes)
13895
+ byStart.set(n.startStep, (byStart.get(n.startStep) ?? 0) + 1);
13896
+ let maxPoly = 0;
13897
+ for (const c of byStart.values()) if (c > maxPoly) maxPoly = c;
13898
+ const avgPoly = notes.length / byStart.size;
13899
+ const minStart = Math.min(...notes.map((n) => n.startStep));
13900
+ const maxEnd = Math.max(...notes.map((n) => n.startStep + n.durationSteps));
13901
+ const spanBeats = Math.max(1, (maxEnd - minStart) / AUTO_ROLE_STEPS_PER_BEAT);
13902
+ const notesPerBeat = notes.length / spanBeats;
13903
+ return { avgPitch, avgDur, avgPoly, maxPoly, notesPerBeat };
13904
+ };
13905
+ var classifyTrackRole = (stats) => {
13906
+ if (stats.avgPitch < 48) return "bass";
13907
+ if (stats.maxPoly >= 2 && stats.avgDur >= AUTO_ROLE_STEPS_PER_BEAT)
13908
+ return "chord";
13909
+ if (stats.notesPerBeat < 1.2 && stats.avgDur >= AUTO_ROLE_STEPS_PER_BEAT * 1.5)
13910
+ return "submelody";
13911
+ return "melody";
13912
+ };
13913
+ var computeAutoRoleVolume = (role, stats) => {
13914
+ let vol = AUTO_ROLE_BASE_VOLUME[role];
13915
+ if (role === "chord" && stats.avgPoly > 1) {
13916
+ vol /= Math.sqrt(stats.avgPoly);
13917
+ } else if (role === "bass") {
13918
+ const depthSemitones = Math.max(0, 48 - stats.avgPitch);
13919
+ vol += Math.min(12, depthSemitones * 0.5);
13920
+ }
13921
+ return clamp5(Math.round(vol), 1, 127);
13922
+ };
13923
+ var AUTO_ROLE_MIX = {
13924
+ melody: {
13925
+ compression: 35,
13926
+ width: 115,
13927
+ reverbSend: 12,
13928
+ delaySend: 15,
13929
+ eqLow: -2,
13930
+ eqHigh: 2
13931
+ },
13932
+ submelody: {
13933
+ compression: 32,
13934
+ width: 115,
13935
+ reverbSend: 15,
13936
+ delaySend: 8,
13937
+ eqLow: -3,
13938
+ eqHigh: 1
13939
+ },
13940
+ chord: {
13941
+ compression: 25,
13942
+ width: 118,
13943
+ reverbSend: 22,
13944
+ delaySend: 0,
13945
+ eqLow: -4,
13946
+ eqHigh: 0
13947
+ },
13948
+ bass: {
13949
+ compression: 40,
13950
+ width: 100,
13951
+ reverbSend: 5,
13952
+ delaySend: 0,
13953
+ eqLow: 2,
13954
+ eqHigh: -3
13955
+ }
13956
+ };
13777
13957
  var mountDAW = (target, options = {}) => {
13778
13958
  injectStyles();
13779
13959
  const getAudioTime = options.getAudioTime ?? (() => performance.now() / 1e3);
@@ -13804,6 +13984,8 @@ var mountDAW = (target, options = {}) => {
13804
13984
  });
13805
13985
  refs.masterVolume.value = String(options.masterVolume ?? 50);
13806
13986
  refs.masterVolumeLabel.textContent = `${options.masterVolume ?? 50}%`;
13987
+ refs.masterComp.value = String(options.masterCompression ?? 0);
13988
+ refs.masterCompLabel.textContent = `${options.masterCompression ?? 0}%`;
13807
13989
  refs.reverbAmount.value = String(options.reverbAmount ?? 0);
13808
13990
  refs.reverbAmountLabel.textContent = `${options.reverbAmount ?? 0}%`;
13809
13991
  {
@@ -13841,14 +14023,38 @@ var mountDAW = (target, options = {}) => {
13841
14023
  let reverbPreDelay = options.reverbPreDelay ?? DEFAULT_REVERB_PREDELAY_MS;
13842
14024
  let delayAmount = options.delayAmount ?? 0;
13843
14025
  let delayDivision = options.delayDivision ?? "8";
14026
+ let masterCompression = options.masterCompression ?? 0;
13844
14027
  let fadeInSec = options.fadeInSec ?? 0;
13845
14028
  let fadeOutSec = options.fadeOutSec ?? 0;
13846
14029
  let unsubscribeClip;
14030
+ let observedPeakMax = 0;
14031
+ let observedPlayMs = 0;
14032
+ let peakSampleRafId = null;
14033
+ let peakSampleLastTs = 0;
14034
+ const PEAK_SAMPLE_MIN_PLAY_MS = 2e3;
14035
+ const samplePeakTick = (ts) => {
14036
+ if (peakSampleLastTs) observedPlayMs += ts - peakSampleLastTs;
14037
+ peakSampleLastTs = ts;
14038
+ const peak = options.clipMeter?.getPeakLevel() ?? 0;
14039
+ if (peak > observedPeakMax) observedPeakMax = peak;
14040
+ peakSampleRafId = requestAnimationFrame(samplePeakTick);
14041
+ };
14042
+ const startPeakSampling = () => {
14043
+ if (peakSampleRafId !== null || !options.clipMeter) return;
14044
+ peakSampleLastTs = 0;
14045
+ peakSampleRafId = requestAnimationFrame(samplePeakTick);
14046
+ };
14047
+ const stopPeakSampling = () => {
14048
+ if (peakSampleRafId !== null) cancelAnimationFrame(peakSampleRafId);
14049
+ peakSampleRafId = null;
14050
+ peakSampleLastTs = 0;
14051
+ };
13847
14052
  options.onReverbChange?.(reverbAmount);
13848
14053
  options.onReverbDecayChange?.(reverbDecay);
13849
14054
  options.onReverbPreDelayChange?.(reverbPreDelay);
13850
14055
  options.onDelayChange?.(delayAmount);
13851
14056
  options.onDelayDivisionChange?.(delayDivision);
14057
+ options.onMasterCompressionChange?.(masterCompression);
13852
14058
  let drumVolume = options.drumVolume ?? 80;
13853
14059
  let currentDrumPattern = refs.drumSelect.value;
13854
14060
  let currentDrumFont = options.drumFont ?? "FluidR3_GM_sf2_file:0";
@@ -14008,7 +14214,9 @@ var mountDAW = (target, options = {}) => {
14008
14214
  trackReverbSend: 0,
14009
14215
  trackEqLow: 0,
14010
14216
  trackEqMid: 0,
14011
- trackEqHigh: 0
14217
+ trackEqHigh: 0,
14218
+ trackPan: 64,
14219
+ trackDelaySend: 0
14012
14220
  };
14013
14221
  });
14014
14222
  };
@@ -14881,6 +15089,7 @@ var mountDAW = (target, options = {}) => {
14881
15089
  }
14882
15090
  playbackState = "playing";
14883
15091
  sequencer.start(fromStep);
15092
+ startPeakSampling();
14884
15093
  {
14885
15094
  const anchor = sequencer.getStartTime();
14886
15095
  const secondsPerStepFade = 60 / bpm / 48;
@@ -14923,6 +15132,7 @@ var mountDAW = (target, options = {}) => {
14923
15132
  clearSoundTimers();
14924
15133
  options.onScheduleFade?.(null);
14925
15134
  playbackState = "paused";
15135
+ stopPeakSampling();
14926
15136
  updateTransport();
14927
15137
  };
14928
15138
  const reloadVoicesForModel = (model) => {
@@ -14938,6 +15148,7 @@ var mountDAW = (target, options = {}) => {
14938
15148
  options.onScheduleFade?.(null);
14939
15149
  playbackState = "stopped";
14940
15150
  currentPlayStep = 0;
15151
+ stopPeakSampling();
14941
15152
  updateTransport();
14942
15153
  redrawAll();
14943
15154
  };
@@ -15006,12 +15217,24 @@ var mountDAW = (target, options = {}) => {
15006
15217
  <span class="dtm-label" data-dtm="track-width-label"></span>
15007
15218
  <button class="dtm-infobtn" data-dtm="track-width-info" title="\u30B9\u30C6\u30EC\u30AA\u5E45\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15008
15219
  </div>
15220
+ <div class="dtm-row">
15221
+ <span class="dtm-label">\u5B9A\u4F4D</span>
15222
+ <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">
15223
+ <span class="dtm-label" data-dtm="track-pan-label"></span>
15224
+ <button class="dtm-infobtn" data-dtm="track-pan-info" title="\u5B9A\u4F4D\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15225
+ </div>
15009
15226
  <div class="dtm-row">
15010
15227
  <span class="dtm-label">\u30EA\u30D0\u30FC\u30D6\u9001\u308A</span>
15011
15228
  <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">
15012
15229
  <span class="dtm-label" data-dtm="track-reverb-send-label"></span>
15013
15230
  <button class="dtm-infobtn" data-dtm="track-reverb-send-info" title="\u30EA\u30D0\u30FC\u30D6\u9001\u308A\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15014
15231
  </div>
15232
+ <div class="dtm-row">
15233
+ <span class="dtm-label">\u30C7\u30A3\u30EC\u30A4\u9001\u308A</span>
15234
+ <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">
15235
+ <span class="dtm-label" data-dtm="track-delay-send-label"></span>
15236
+ <button class="dtm-infobtn" data-dtm="track-delay-send-info" title="\u30C7\u30A3\u30EC\u30A4\u9001\u308A\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15237
+ </div>
15015
15238
  </details>`;
15016
15239
  refs.trackBody.querySelector(
15017
15240
  '[data-dtm="track-fx-advanced"]'
@@ -15121,6 +15344,26 @@ var mountDAW = (target, options = {}) => {
15121
15344
  trackWidthInfo.addEventListener("click", () => {
15122
15345
  showModal("\u30B9\u30C6\u30EC\u30AA\u5E45\u306E\u89E3\u8AAC", TRACK_WIDTH_INFO_HTML);
15123
15346
  });
15347
+ const trackPanInput = refs.trackBody.querySelector(
15348
+ '[data-dtm="track-pan"]'
15349
+ );
15350
+ const trackPanLabel = refs.trackBody.querySelector(
15351
+ '[data-dtm="track-pan-label"]'
15352
+ );
15353
+ const trackPanInfo = refs.trackBody.querySelector(
15354
+ '[data-dtm="track-pan-info"]'
15355
+ );
15356
+ const fmtTrackPan = (pan) => pan === 64 ? "C" : pan < 64 ? `L${64 - pan}` : `R${pan - 64}`;
15357
+ trackPanInput.value = String(active.trackPan);
15358
+ trackPanLabel.textContent = fmtTrackPan(active.trackPan);
15359
+ trackPanInput.addEventListener("input", () => {
15360
+ active.trackPan = Number.parseInt(trackPanInput.value, 10);
15361
+ trackPanLabel.textContent = fmtTrackPan(active.trackPan);
15362
+ options.onTrackPanChange?.(active.config.id, active.trackPan);
15363
+ });
15364
+ trackPanInfo.addEventListener("click", () => {
15365
+ showModal("\u5B9A\u4F4D\u306E\u89E3\u8AAC", TRACK_PAN_INFO_HTML);
15366
+ });
15124
15367
  const trackReverbSendInput = refs.trackBody.querySelector(
15125
15368
  '[data-dtm="track-reverb-send"]'
15126
15369
  );
@@ -15143,6 +15386,25 @@ var mountDAW = (target, options = {}) => {
15143
15386
  trackReverbSendInfo.addEventListener("click", () => {
15144
15387
  showModal("\u30EA\u30D0\u30FC\u30D6\u9001\u308A\u306E\u89E3\u8AAC", TRACK_REVERBSEND_INFO_HTML);
15145
15388
  });
15389
+ const trackDelaySendInput = refs.trackBody.querySelector(
15390
+ '[data-dtm="track-delay-send"]'
15391
+ );
15392
+ const trackDelaySendLabel = refs.trackBody.querySelector(
15393
+ '[data-dtm="track-delay-send-label"]'
15394
+ );
15395
+ const trackDelaySendInfo = refs.trackBody.querySelector(
15396
+ '[data-dtm="track-delay-send-info"]'
15397
+ );
15398
+ trackDelaySendInput.value = String(active.trackDelaySend);
15399
+ trackDelaySendLabel.textContent = `${active.trackDelaySend}%`;
15400
+ trackDelaySendInput.addEventListener("input", () => {
15401
+ active.trackDelaySend = Number.parseInt(trackDelaySendInput.value, 10);
15402
+ trackDelaySendLabel.textContent = `${active.trackDelaySend}%`;
15403
+ options.onTrackDelaySendChange?.(active.config.id, active.trackDelaySend);
15404
+ });
15405
+ trackDelaySendInfo.addEventListener("click", () => {
15406
+ showModal("\u30C7\u30A3\u30EC\u30A4\u9001\u308A\u306E\u89E3\u8AAC", TRACK_DELAYSEND_INFO_HTML);
15407
+ });
15146
15408
  const instRow = document.createElement("div");
15147
15409
  instRow.className = "dtm-row";
15148
15410
  instRow.innerHTML = `<span class="dtm-label">\u697D\u5668</span>`;
@@ -15746,6 +16008,8 @@ var mountDAW = (target, options = {}) => {
15746
16008
  const trackEqLowForMeta = {};
15747
16009
  const trackEqMidForMeta = {};
15748
16010
  const trackEqHighForMeta = {};
16011
+ const trackPanForMeta = {};
16012
+ const trackDelaySendForMeta = {};
15749
16013
  trackStates.forEach((t, i2) => {
15750
16014
  if (t.trackInstrument) trackInstrumentsForMeta[i2] = t.trackInstrument;
15751
16015
  if (t.trackCompression !== 0)
@@ -15756,6 +16020,8 @@ var mountDAW = (target, options = {}) => {
15756
16020
  if (t.trackEqLow !== 0) trackEqLowForMeta[i2] = t.trackEqLow;
15757
16021
  if (t.trackEqMid !== 0) trackEqMidForMeta[i2] = t.trackEqMid;
15758
16022
  if (t.trackEqHigh !== 0) trackEqHighForMeta[i2] = t.trackEqHigh;
16023
+ if (t.trackPan !== 64) trackPanForMeta[i2] = t.trackPan;
16024
+ if (t.trackDelaySend !== 0) trackDelaySendForMeta[i2] = t.trackDelaySend;
15759
16025
  });
15760
16026
  const trackInstMeta = Object.keys(trackInstrumentsForMeta).length > 0 ? trackInstrumentsForMeta : void 0;
15761
16027
  const trackCompMeta = Object.keys(trackCompressionForMeta).length > 0 ? trackCompressionForMeta : void 0;
@@ -15764,6 +16030,8 @@ var mountDAW = (target, options = {}) => {
15764
16030
  const trackEqLowMeta = Object.keys(trackEqLowForMeta).length > 0 ? trackEqLowForMeta : void 0;
15765
16031
  const trackEqMidMeta = Object.keys(trackEqMidForMeta).length > 0 ? trackEqMidForMeta : void 0;
15766
16032
  const trackEqHighMeta = Object.keys(trackEqHighForMeta).length > 0 ? trackEqHighForMeta : void 0;
16033
+ const trackPanMeta = Object.keys(trackPanForMeta).length > 0 ? trackPanForMeta : void 0;
16034
+ const trackDelaySendMeta = Object.keys(trackDelaySendForMeta).length > 0 ? trackDelaySendForMeta : void 0;
15767
16035
  const metaLineFull = formatMmlMeta(
15768
16036
  {
15769
16037
  instrument: currentInstrument || void 0,
@@ -15775,6 +16043,7 @@ var mountDAW = (target, options = {}) => {
15775
16043
  reverbPreDelay,
15776
16044
  delay: delayAmount,
15777
16045
  delayDivision,
16046
+ masterCompression,
15778
16047
  fadeIn: Math.round(fadeInSec * 10),
15779
16048
  fadeOut: Math.round(fadeOutSec * 10),
15780
16049
  mode,
@@ -15784,7 +16053,9 @@ var mountDAW = (target, options = {}) => {
15784
16053
  trackReverbSend: trackReverbSendMeta,
15785
16054
  trackEqLow: trackEqLowMeta,
15786
16055
  trackEqMid: trackEqMidMeta,
15787
- trackEqHigh: trackEqHighMeta
16056
+ trackEqHigh: trackEqHighMeta,
16057
+ trackPan: trackPanMeta,
16058
+ trackDelaySend: trackDelaySendMeta
15788
16059
  },
15789
16060
  " "
15790
16061
  );
@@ -15799,6 +16070,7 @@ var mountDAW = (target, options = {}) => {
15799
16070
  reverbPreDelay,
15800
16071
  delay: delayAmount,
15801
16072
  delayDivision,
16073
+ masterCompression,
15802
16074
  fadeIn: Math.round(fadeInSec * 10),
15803
16075
  fadeOut: Math.round(fadeOutSec * 10),
15804
16076
  mode,
@@ -15808,7 +16080,9 @@ var mountDAW = (target, options = {}) => {
15808
16080
  trackReverbSend: trackReverbSendMeta,
15809
16081
  trackEqLow: trackEqLowMeta,
15810
16082
  trackEqMid: trackEqMidMeta,
15811
- trackEqHigh: trackEqHighMeta
16083
+ trackEqHigh: trackEqHighMeta,
16084
+ trackPan: trackPanMeta,
16085
+ trackDelaySend: trackDelaySendMeta
15812
16086
  },
15813
16087
  ""
15814
16088
  );
@@ -16046,6 +16320,12 @@ var mountDAW = (target, options = {}) => {
16046
16320
  refs.delayDivision.value = delayDivision;
16047
16321
  options.onDelayDivisionChange?.(delayDivision);
16048
16322
  }
16323
+ if (meta.masterCompression !== void 0) {
16324
+ masterCompression = meta.masterCompression;
16325
+ refs.masterComp.value = String(meta.masterCompression);
16326
+ refs.masterCompLabel.textContent = `${meta.masterCompression}%`;
16327
+ options.onMasterCompressionChange?.(meta.masterCompression);
16328
+ }
16049
16329
  if (meta.fadeIn !== void 0) {
16050
16330
  fadeInSec = meta.fadeIn / 10;
16051
16331
  refs.fadeIn.value = String(fadeInSec);
@@ -16097,6 +16377,16 @@ var mountDAW = (target, options = {}) => {
16097
16377
  t.trackEqHigh = eqHigh;
16098
16378
  options.onTrackEqHighChange?.(t.config.id, eqHigh);
16099
16379
  }
16380
+ const pan = meta.trackPan?.[i2] ?? 64;
16381
+ if (t.trackPan !== pan) {
16382
+ t.trackPan = pan;
16383
+ options.onTrackPanChange?.(t.config.id, pan);
16384
+ }
16385
+ const delaySend = meta.trackDelaySend?.[i2] ?? 0;
16386
+ if (t.trackDelaySend !== delaySend) {
16387
+ t.trackDelaySend = delaySend;
16388
+ options.onTrackDelaySendChange?.(t.config.id, delaySend);
16389
+ }
16100
16390
  });
16101
16391
  trackStates.forEach((t, i2) => {
16102
16392
  if (applyActiveOnly && i2 !== activeTrackIndex) return;
@@ -16474,6 +16764,14 @@ var mountDAW = (target, options = {}) => {
16474
16764
  refs.masterVolumeLabel.textContent = `${masterVolume}%`;
16475
16765
  options.singingVoices?.setVolume(masterVolume / 100);
16476
16766
  });
16767
+ refs.masterComp.addEventListener("input", () => {
16768
+ masterCompression = Number.parseInt(refs.masterComp.value, 10) || 0;
16769
+ refs.masterCompLabel.textContent = `${masterCompression}%`;
16770
+ options.onMasterCompressionChange?.(masterCompression);
16771
+ });
16772
+ refs.masterCompInfoBtn.addEventListener("click", () => {
16773
+ showModal("\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u306E\u89E3\u8AAC", MASTER_COMP_INFO_HTML);
16774
+ });
16477
16775
  refs.reverbAmount.addEventListener("input", () => {
16478
16776
  reverbAmount = Number.parseInt(refs.reverbAmount.value, 10) || 0;
16479
16777
  refs.reverbAmountLabel.textContent = `${reverbAmount}%`;
@@ -16523,10 +16821,31 @@ var mountDAW = (target, options = {}) => {
16523
16821
  showModal("\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0\u89E3\u8AAC", AUTO_MASTER_INFO_HTML);
16524
16822
  });
16525
16823
  refs.autoMasterBtn.addEventListener("click", () => {
16526
- reverbAmount = 20;
16527
- refs.reverbAmount.value = "20";
16528
- refs.reverbAmountLabel.textContent = "20%";
16529
- options.onReverbChange?.(20);
16824
+ if (observedPlayMs >= PEAK_SAMPLE_MIN_PLAY_MS && observedPeakMax > 0) {
16825
+ const targetPeak = 0.5;
16826
+ const scale = targetPeak / observedPeakMax;
16827
+ const suggested = clamp5(Math.round(masterVolume * scale), 10, 100);
16828
+ if (suggested !== masterVolume) {
16829
+ masterVolume = suggested;
16830
+ refs.masterVolume.value = String(masterVolume);
16831
+ refs.masterVolumeLabel.textContent = `${masterVolume}%`;
16832
+ options.singingVoices?.setVolume(masterVolume / 100);
16833
+ }
16834
+ observedPeakMax = 0;
16835
+ observedPlayMs = 0;
16836
+ }
16837
+ masterCompression = 25;
16838
+ refs.masterComp.value = "25";
16839
+ refs.masterCompLabel.textContent = "25%";
16840
+ options.onMasterCompressionChange?.(25);
16841
+ const activeTrackCount = trackStates.filter(
16842
+ (t) => t.core.getNotes().length > 0
16843
+ ).length;
16844
+ const densityT = clamp5((activeTrackCount - 2) / (8 - 2), 0, 1);
16845
+ reverbAmount = Math.round(28 - densityT * (28 - 12));
16846
+ refs.reverbAmount.value = String(reverbAmount);
16847
+ refs.reverbAmountLabel.textContent = `${reverbAmount}%`;
16848
+ options.onReverbChange?.(reverbAmount);
16530
16849
  const bpmT = clamp5((bpm - 60) / (180 - 60), 0, 1);
16531
16850
  reverbDecay = clamp5(
16532
16851
  3 - bpmT * (3 - 0.9),
@@ -16540,6 +16859,11 @@ var mountDAW = (target, options = {}) => {
16540
16859
  refs.reverbPreDelay.value = "20";
16541
16860
  refs.reverbPreDelayLabel.textContent = "20ms";
16542
16861
  options.onReverbPreDelayChange?.(20);
16862
+ if (fadeOutSec === 0) {
16863
+ fadeOutSec = 1.5;
16864
+ refs.fadeOut.value = "1.5";
16865
+ refs.fadeOutLabel.textContent = "1.5s";
16866
+ }
16543
16867
  let mainVocalId = null;
16544
16868
  let mainVocalScore = -1;
16545
16869
  for (const t of trackStates) {
@@ -16550,16 +16874,65 @@ var mountDAW = (target, options = {}) => {
16550
16874
  mainVocalId = t.config.id;
16551
16875
  }
16552
16876
  }
16877
+ const autoPreset = INSTRUMENT_PRESETS[currentInstrument] ?? INSTRUMENT_PRESETS.piano;
16878
+ const roleByTrackId = /* @__PURE__ */ new Map();
16879
+ for (const t of trackStates) {
16880
+ if (t.lyricModel) continue;
16881
+ const notes = t.core.getNotes();
16882
+ if (notes.length === 0) continue;
16883
+ const stats = computeAutoRoleStats(notes);
16884
+ const role = classifyTrackRole(stats);
16885
+ roleByTrackId.set(t.config.id, role);
16886
+ const instName = autoPreset[role];
16887
+ t.trackInstrument = instName;
16888
+ const trackIndex = trackStates.indexOf(t);
16889
+ options.onTrackInstrumentChange?.(trackIndex, instName);
16890
+ const vol = computeAutoRoleVolume(role, stats);
16891
+ t.volume = vol;
16892
+ t.core.setVolume(vol);
16893
+ }
16894
+ const AUTO_PAN_OFFSETS = {
16895
+ melody: [0],
16896
+ bass: [0],
16897
+ submelody: [18, -18, 30, -30],
16898
+ chord: [36, -36, 48, -48]
16899
+ };
16900
+ const panRoleCounter = /* @__PURE__ */ new Map();
16901
+ let vocalSideCounter = 0;
16553
16902
  for (const t of trackStates) {
16554
16903
  const isMainVocal = !!t.lyricModel && t.config.id === mainVocalId;
16555
- const comp = !t.lyricModel ? 35 : isMainVocal ? 30 : 25;
16904
+ const role = roleByTrackId.get(t.config.id);
16905
+ const roleMix = role ? AUTO_ROLE_MIX[role] : void 0;
16906
+ let pan = 64;
16907
+ if (t.lyricModel) {
16908
+ pan = isMainVocal ? 64 : clamp5(64 + (vocalSideCounter++ % 2 === 0 ? 22 : -22), 0, 127);
16909
+ } else if (role) {
16910
+ const offsets = AUTO_PAN_OFFSETS[role];
16911
+ const n = panRoleCounter.get(role) ?? 0;
16912
+ panRoleCounter.set(role, n + 1);
16913
+ pan = clamp5(64 + offsets[n % offsets.length], 0, 127);
16914
+ }
16915
+ t.trackPan = pan;
16916
+ options.onTrackPanChange?.(t.config.id, pan);
16917
+ const comp = t.lyricModel ? isMainVocal ? 30 : 25 : roleMix?.compression ?? 35;
16918
+ const width = t.lyricModel ? 115 : roleMix?.width ?? 115;
16556
16919
  t.trackCompression = comp;
16557
- t.trackWidth = 115;
16920
+ t.trackWidth = width;
16558
16921
  options.onTrackCompressionChange?.(t.config.id, comp);
16559
- options.onTrackWidthChange?.(t.config.id, 115);
16922
+ options.onTrackWidthChange?.(t.config.id, width);
16560
16923
  if (!t.lyricModel) {
16561
- t.trackReverbSend = 15;
16562
- options.onTrackReverbSendChange?.(t.config.id, 15);
16924
+ const reverbSend = roleMix?.reverbSend ?? 15;
16925
+ t.trackReverbSend = reverbSend;
16926
+ options.onTrackReverbSendChange?.(t.config.id, reverbSend);
16927
+ const eqLow = roleMix?.eqLow ?? 0;
16928
+ const eqHigh = roleMix?.eqHigh ?? 0;
16929
+ t.trackEqLow = eqLow;
16930
+ t.trackEqHigh = eqHigh;
16931
+ options.onTrackEqLowChange?.(t.config.id, eqLow);
16932
+ options.onTrackEqHighChange?.(t.config.id, eqHigh);
16933
+ const delaySend = roleMix?.delaySend ?? 0;
16934
+ t.trackDelaySend = delaySend;
16935
+ options.onTrackDelaySendChange?.(t.config.id, delaySend);
16563
16936
  }
16564
16937
  if (t.lyricModel) {
16565
16938
  t.vocalVibrato = true;
@@ -17649,6 +18022,7 @@ var mountDAW = (target, options = {}) => {
17649
18022
  sequencer.stop();
17650
18023
  options.singingVoices?.stopStream();
17651
18024
  unsubscribeClip?.();
18025
+ stopPeakSampling();
17652
18026
  resizeObserver.disconnect();
17653
18027
  document.removeEventListener("pointermove", onPointerMove);
17654
18028
  document.removeEventListener("pointerup", onPointerUp);
@@ -18606,13 +18980,39 @@ var createDtmStudio = async (options = {}) => {
18606
18980
  division: options.delayDivision ?? "8"
18607
18981
  });
18608
18982
  const setDelayAmount = (amount) => delayBus.setAmount(amount);
18983
+ const glueComp = audioCtx.createDynamicsCompressor();
18984
+ glueComp.knee.value = 6;
18985
+ const glueMakeup = audioCtx.createGain();
18986
+ finalMix.connect(glueComp);
18987
+ glueComp.connect(glueMakeup);
18988
+ const glueCompressionParams = (amount) => {
18989
+ const t = Math.max(0, Math.min(100, amount)) / 100;
18990
+ return {
18991
+ threshold: 0 + (-18 - 0) * t,
18992
+ ratio: 1 + (4 - 1) * t,
18993
+ attack: 0.03 + (0.01 - 0.03) * t,
18994
+ release: 0.3 + (0.15 - 0.3) * t,
18995
+ makeupDb: 2.5 * t
18996
+ };
18997
+ };
18998
+ const applyGlueCompression = (amount) => {
18999
+ const p = glueCompressionParams(amount);
19000
+ const now = audioCtx.currentTime;
19001
+ glueComp.threshold.setValueAtTime(p.threshold, now);
19002
+ glueComp.ratio.setValueAtTime(p.ratio, now);
19003
+ glueComp.attack.setValueAtTime(p.attack, now);
19004
+ glueComp.release.setValueAtTime(p.release, now);
19005
+ glueMakeup.gain.setTargetAtTime(10 ** (p.makeupDb / 20), now, 0.02);
19006
+ };
19007
+ applyGlueCompression(options.masterCompression ?? 0);
19008
+ const setMasterCompression = (amount) => applyGlueCompression(amount);
18609
19009
  const safetyLimiter = audioCtx.createDynamicsCompressor();
18610
19010
  safetyLimiter.threshold.value = -1;
18611
19011
  safetyLimiter.knee.value = 0;
18612
19012
  safetyLimiter.ratio.value = 20;
18613
19013
  safetyLimiter.attack.value = 1e-3;
18614
19014
  safetyLimiter.release.value = 0.1;
18615
- finalMix.connect(safetyLimiter);
19015
+ glueMakeup.connect(safetyLimiter);
18616
19016
  const fadeGain = audioCtx.createGain();
18617
19017
  fadeGain.gain.value = 1;
18618
19018
  safetyLimiter.connect(fadeGain);
@@ -18635,13 +19035,14 @@ var createDtmStudio = async (options = {}) => {
18635
19035
  fadeGain.gain.linearRampToValueAtTime(0, fadeOutEndAt);
18636
19036
  }
18637
19037
  };
18638
- const clipMeter = createClipMeter(audioCtx, finalMix);
19038
+ const clipMeter = createClipMeter(audioCtx, glueMakeup);
18639
19039
  const channelStrips = /* @__PURE__ */ new Map();
18640
19040
  const getChannelStrip = (trackId) => {
18641
19041
  let strip = channelStrips.get(trackId);
18642
19042
  if (!strip) {
18643
19043
  strip = createChannelStrip(audioCtx, masterGain, {
18644
- reverbBus: reverbPreDelay
19044
+ reverbBus: reverbPreDelay,
19045
+ delayBus: delayBus.input
18645
19046
  });
18646
19047
  channelStrips.set(trackId, strip);
18647
19048
  }
@@ -18972,6 +19373,8 @@ var createDtmStudio = async (options = {}) => {
18972
19373
  onDelayChange: setDelayAmount,
18973
19374
  delayDivision: options.delayDivision,
18974
19375
  onDelayDivisionChange: (division) => delayBus.setDivision(division),
19376
+ masterCompression: options.masterCompression,
19377
+ onMasterCompressionChange: setMasterCompression,
18975
19378
  onBpmChange: (bpm) => delayBus.setBpm(bpm),
18976
19379
  fadeInSec: options.fadeInSec,
18977
19380
  fadeOutSec: options.fadeOutSec,
@@ -18979,9 +19382,11 @@ var createDtmStudio = async (options = {}) => {
18979
19382
  onTrackCompressionChange: (trackId, amount) => getChannelStrip(trackId).setCompression(amount),
18980
19383
  onTrackWidthChange: (trackId, width) => getChannelStrip(trackId).setWidth(width),
18981
19384
  onTrackReverbSendChange: (trackId, amount) => getChannelStrip(trackId).setReverbSend(amount),
19385
+ onTrackDelaySendChange: (trackId, amount) => getChannelStrip(trackId).setDelaySend(amount),
18982
19386
  onTrackEqLowChange: (trackId, db) => getChannelStrip(trackId).setEqLow(db),
18983
19387
  onTrackEqMidChange: (trackId, db) => getChannelStrip(trackId).setEqMid(db),
18984
19388
  onTrackEqHighChange: (trackId, db) => getChannelStrip(trackId).setEqHigh(db),
19389
+ onTrackPanChange: (trackId, pan) => getChannelStrip(trackId).setPan(panToStereo(pan)),
18985
19390
  clipMeter,
18986
19391
  ...dawOverrides,
18987
19392
  // dawOverrides で上書きされないよう、スプレッドの後に配置して合成する
@@ -19563,6 +19968,7 @@ var createDtmStudio = async (options = {}) => {
19563
19968
  setReverbDecay,
19564
19969
  setReverbPreDelay,
19565
19970
  setDelayAmount,
19971
+ setMasterCompression,
19566
19972
  dispose
19567
19973
  };
19568
19974
  };