@onjmin/dtm 0.1.95 → 0.1.98

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 = {}) => {
@@ -11402,6 +11456,12 @@ var buildUI = (target, options) => {
11402
11456
  <input type="range" class="dtm-range dtm-grow" data-dtm="master-volume" value="50" min="0" max="100">
11403
11457
  <span class="dtm-label" data-dtm="master-volume-label">50%</span>
11404
11458
  </div>
11459
+ <div class="dtm-row">
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>
11405
11465
  <div class="dtm-row">
11406
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>
@@ -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,34 +13585,57 @@ 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>
13525
- <li>\u6B4C\u8A5E\u306E\u3042\u308B\u30C8\u30E9\u30C3\u30AF: \u81EA\u52D5\u30D3\u30D6\u30E9\u30FC\u30C8ON</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>
13526
13621
  </ul>
13527
- <h4>\u697D\u5668\u30FB\u97F3\u91CF\u306E\u81EA\u52D5\u5272\u308A\u5F53\u3066</h4>
13528
- <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>
13622
+ <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>
13623
+ <h4>\u697D\u5668\u30FB\u97F3\u91CF\u30FB\u5F79\u5272\u3054\u3068\u306E\u30DF\u30C3\u30AF\u30B9\u306E\u81EA\u52D5\u5272\u308A\u5F53\u3066</h4>
13624
+ <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>
13529
13625
  <ul>
13530
- <li><strong>\u4F4E\u97F3\u57DF\uFF08C3\u672A\u6E80\uFF09\u304C\u4E2D\u5FC3</strong> \u2192 \u30D9\u30FC\u30B9\u697D\u5668\u30FB\u97F3\u91CF85</li>
13531
- <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>
13532
- <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>
13533
- <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>
13626
+ <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>
13627
+ <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>
13628
+ <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>
13629
+ <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>
13534
13630
  </ul>
13535
- <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>
13631
+ <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>
13536
13632
  <h4>\u30E1\u30A4\u30F3\u30DC\u30FC\u30AB\u30EB\u306E\u81EA\u52D5\u5224\u5B9A</h4>
13537
13633
  <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>
13538
13634
  <ul>
13539
- <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>
13540
- <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>
13635
+ <li>\u30E1\u30A4\u30F3\u30DC\u30FC\u30AB\u30EB: \u81EA\u52D5\u30D3\u30D6\u30E9\u30FC\u30C8ON\u30FB\u58F0\u91CF\u3092\u65E2\u5B9A\u306E1.1\u500D\uFF08\u524D\u306B\u51FA\u3059\uFF09\u30FB\u97F3\u5727\u5F37\u531630%\u30FB\u30B9\u30C6\u30EC\u30AA\u5E45100%\uFF08\u72ED\u3081\u30FB\u4E2D\u592E\u5BC4\u308A\u3067\u30AF\u30EA\u30A2\u306B\uFF09\u30FBEQ\u4F4E\u57DF-3dB\uFF08\u30E9\u30F3\u30D6\u30EB/\u3053\u3082\u308A\u9664\u53BB\uFF09\u30FBEQ\u9AD8\u57DF+2dB\uFF08\u629C\u3051\u30FB\u30D7\u30EC\u30BC\u30F3\u30B9\uFF09\u30FB\u30C7\u30A3\u30EC\u30A4\u9001\u308A15%\uFF08\u8A9E\u5C3E\u306B\u8EFD\u3044\u30B9\u30E9\u30C3\u30D7\uFF09\u30FB\u30EA\u30D0\u30FC\u30D6\u9001\u308A25%\u30FB\u5B9A\u4F4D\u306F\u4E2D\u592E\u56FA\u5B9A</li>
13636
+ <li>\u305D\u308C\u4EE5\u5916\u306E\u30DC\u30FC\u30AB\u30EB\uFF08\u30CF\u30E2\u30EA\u30FB\u30B3\u30FC\u30E9\u30B9\u7B49\uFF09: \u81EA\u52D5\u30D3\u30D6\u30E9\u30FC\u30C8OFF\u30FB\u58F0\u91CF\u3092\u65E2\u5B9A\u306E0.85\u500D\u3092\u57FA\u6E96\u306B\u3001\u526F\u30DC\u30FC\u30AB\u30EB\u306E\u672C\u6570\u304C\u591A\u3044\u307B\u3069\u3055\u3089\u306B\u7D5E\u308B\uFF08\u91CD\u306A\u3063\u3066\u97F3\u5727\u304C\u7A4D\u307F\u4E0A\u304C\u308B\u5206\u3092\u7B49\u30D1\u30EF\u30FC\u5247\u3067\u76F8\u6BBA\uFF09\u30FB\u97F3\u5727\u5F37\u531625%\u30FB\u30B9\u30C6\u30EC\u30AA\u5E45120%\uFF08\u5E83\u3052\u3066\u300C\u58C1\u300D\u306E\u3088\u3046\u306A\u539A\u307F\u3092\u51FA\u3059\uFF09\u30FBEQ\u4F4E\u57DF-3dB\u30FBEQ\u9AD8\u57DF\u306F\u7121\u5909\u5316\uFF08\u660E\u308B\u304F\u3057\u3059\u304E\u308B\u3068\u524D\u306B\u51FA\u3066\u3057\u307E\u3046\u305F\u3081\uFF09\u30FB\u30C7\u30A3\u30EC\u30A4\u9001\u308A0%\uFF08\u639B\u3051\u308B\u3068\u8F2A\u90ED\u304C\u307C\u3084\u3051\u3066\u56E3\u5B50\u306B\u306A\u308B\u305F\u3081\uFF09\u30FB\u30EA\u30D0\u30FC\u30D6\u9001\u308A45%\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>
13541
13637
  </ul>
13542
- <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>
13638
+ <p style="margin-top:4px;"><small>\u300C\u524D\u306B\u51FA\u3057\u305F\u3044\u97F3\u306F\u58F0\u91CF\u5927\u304D\u3081\u30FB\u72ED\u3081\u30FB\u30EA\u30D0\u30FC\u30D6\u5C11\u306A\u3081\u3001\u5965\u306B\u7F6E\u304D\u305F\u3044\u97F3\u306F\u58F0\u91CF\u63A7\u3048\u3081\u30FB\u5E83\u3081\u30FB\u30EA\u30D0\u30FC\u30D6\u591A\u3081\u300D\u3068\u3044\u3046\u5B9A\u77F3\u306B\u57FA\u3065\u3044\u3066\u3044\u307E\u3059\u3002EQ\u306E\u4F4E\u57DF\u30AB\u30C3\u30C8\u306F\u30DC\u30FC\u30AB\u30EB\u3067\u307B\u307C\u666E\u904D\u7684\u306A\u5B9A\u77F3\uFF08\u5B9F\u8CEA\u7684\u306A\u30CF\u30A4\u30D1\u30B9\u30D5\u30A3\u30EB\u30BF\u306E\u4EE3\u7528\uFF09\u3067\u3059\u3002\u30D3\u30D6\u30E9\u30FC\u30C8\u3092\u30CF\u30E2\u30EA\u30FB\u30B3\u30FC\u30E9\u30B9\u3078\u639B\u3051\u306A\u3044\u306E\u306F\u3001\u8907\u6570\u306E\u58F0\u304C\u540C\u6642\u306B\u63FA\u308C\u308B\u3068\u58F0\u3054\u3068\u306E\u4F4D\u76F8\u30FB\u901F\u3055\u306E\u30BA\u30EC\u3067\u548C\u97F3\u304C\u300C\u3046\u306D\u308B\u300D\u300C\u6FC1\u308B\u300D\u305F\u3081\u3067\u3001\u5408\u5531\u3084\u30B9\u30C8\u30EA\u30F3\u30B0\u30B9\u306E\u30BB\u30AF\u30B7\u30E7\u30F3\u594F\u6CD5\u3068\u540C\u3058\u304F\u3001\u30CF\u30E2\u30EA/\u30B3\u30FC\u30E9\u30B9\u306F\u30B9\u30C8\u30EC\u30FC\u30C8\u30C8\u30FC\u30F3\u306B\u3057\u3066\u97F3\u7A0B\u306E\u8EF8\u3092\u5B89\u5B9A\u3055\u305B\u308B\u65B9\u304C\u99B4\u67D3\u307F\u307E\u3059\u3002\u30AA\u30AF\u30BF\u30FC\u30D6\u30E6\u30CB\u30BE\u30F3\uFF081\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A/\u4E0B\u3092\u91CD\u306D\u3066\u539A\u307F\u3092\u51FA\u3059\u52A0\u5DE5\uFF09\u306F\u3053\u3053\u3067\u306F\u81EA\u52D5\u9069\u7528\u3057\u307E\u305B\u3093 \u2014 \u58F0\u8CEA\u3092\u5927\u304D\u304F\u5909\u3048\u308B\u6F14\u51FA\u76EE\u7684\u306E\u52A0\u5DE5\u3067\u3042\u308A\u3001\u66F2\u306B\u3088\u3063\u3066\u5408\u3046/\u5408\u308F\u306A\u3044\u304C\u5206\u304B\u308C\u308B\u5275\u4F5C\u4E0A\u306E\u9078\u629E\uFF08\u30D0\u30E9\u30FC\u30C9\u3067\u306F\u4E0D\u81EA\u7136\u306B\u306A\u308A\u3084\u3059\u3044\u7B49\uFF09\u3067\u3001\u30DF\u30C3\u30AF\u30B9\u306E\u662F\u6B63\u3068\u306F\u6027\u8CEA\u304C\u9055\u3046\u305F\u3081\u3067\u3059\u3002\u4F7F\u3044\u305F\u3044\u5834\u5408\u306F\u5404\u30DC\u30FC\u30AB\u30EB\u30C8\u30E9\u30C3\u30AF\u306E\u8A2D\u5B9A\u6B04\u304B\u3089\u500B\u5225\u306B\u9078\u3093\u3067\u304F\u3060\u3055\u3044\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>
13543
13639
  </div>
13544
13640
  `;
13545
13641
  var MIDI_INFO_HTML = `
@@ -13784,30 +13880,79 @@ var normalizeInstrumentName = (name) => {
13784
13880
  ) ?? name;
13785
13881
  };
13786
13882
  var AUTO_ROLE_STEPS_PER_BEAT = 48;
13787
- var AUTO_ROLE_VOLUME = {
13883
+ var AUTO_ROLE_BASE_VOLUME = {
13788
13884
  melody: 100,
13789
13885
  submelody: 92,
13790
13886
  bass: 85,
13791
13887
  chord: 72
13792
13888
  };
13793
- var classifyTrackRole = (notes) => {
13889
+ var computeAutoRoleStats = (notes) => {
13794
13890
  const avgPitch = notes.reduce((s, n) => s + n.pitch, 0) / notes.length;
13795
- if (avgPitch < 48) return "bass";
13796
13891
  const avgDur = notes.reduce((s, n) => s + n.durationSteps, 0) / notes.length;
13797
13892
  const byStart = /* @__PURE__ */ new Map();
13798
13893
  for (const n of notes)
13799
13894
  byStart.set(n.startStep, (byStart.get(n.startStep) ?? 0) + 1);
13800
13895
  let maxPoly = 0;
13801
13896
  for (const c of byStart.values()) if (c > maxPoly) maxPoly = c;
13802
- if (maxPoly >= 2 && avgDur >= AUTO_ROLE_STEPS_PER_BEAT) return "chord";
13897
+ const avgPoly = notes.length / byStart.size;
13803
13898
  const minStart = Math.min(...notes.map((n) => n.startStep));
13804
13899
  const maxEnd = Math.max(...notes.map((n) => n.startStep + n.durationSteps));
13805
13900
  const spanBeats = Math.max(1, (maxEnd - minStart) / AUTO_ROLE_STEPS_PER_BEAT);
13806
13901
  const notesPerBeat = notes.length / spanBeats;
13807
- if (notesPerBeat < 1.2 && avgDur >= AUTO_ROLE_STEPS_PER_BEAT * 1.5)
13902
+ return { avgPitch, avgDur, avgPoly, maxPoly, notesPerBeat };
13903
+ };
13904
+ var classifyTrackRole = (stats) => {
13905
+ if (stats.avgPitch < 48) return "bass";
13906
+ if (stats.maxPoly >= 2 && stats.avgDur >= AUTO_ROLE_STEPS_PER_BEAT)
13907
+ return "chord";
13908
+ if (stats.notesPerBeat < 1.2 && stats.avgDur >= AUTO_ROLE_STEPS_PER_BEAT * 1.5)
13808
13909
  return "submelody";
13809
13910
  return "melody";
13810
13911
  };
13912
+ var computeAutoRoleVolume = (role, stats) => {
13913
+ let vol = AUTO_ROLE_BASE_VOLUME[role];
13914
+ if (role === "chord" && stats.avgPoly > 1) {
13915
+ vol /= Math.sqrt(stats.avgPoly);
13916
+ } else if (role === "bass") {
13917
+ const depthSemitones = Math.max(0, 48 - stats.avgPitch);
13918
+ vol += Math.min(12, depthSemitones * 0.5);
13919
+ }
13920
+ return clamp5(Math.round(vol), 1, 127);
13921
+ };
13922
+ var AUTO_ROLE_MIX = {
13923
+ melody: {
13924
+ compression: 35,
13925
+ width: 115,
13926
+ reverbSend: 12,
13927
+ delaySend: 15,
13928
+ eqLow: -2,
13929
+ eqHigh: 2
13930
+ },
13931
+ submelody: {
13932
+ compression: 32,
13933
+ width: 115,
13934
+ reverbSend: 15,
13935
+ delaySend: 8,
13936
+ eqLow: -3,
13937
+ eqHigh: 1
13938
+ },
13939
+ chord: {
13940
+ compression: 25,
13941
+ width: 118,
13942
+ reverbSend: 22,
13943
+ delaySend: 0,
13944
+ eqLow: -4,
13945
+ eqHigh: 0
13946
+ },
13947
+ bass: {
13948
+ compression: 40,
13949
+ width: 100,
13950
+ reverbSend: 5,
13951
+ delaySend: 0,
13952
+ eqLow: 2,
13953
+ eqHigh: -3
13954
+ }
13955
+ };
13811
13956
  var mountDAW = (target, options = {}) => {
13812
13957
  injectStyles();
13813
13958
  const getAudioTime = options.getAudioTime ?? (() => performance.now() / 1e3);
@@ -13838,6 +13983,8 @@ var mountDAW = (target, options = {}) => {
13838
13983
  });
13839
13984
  refs.masterVolume.value = String(options.masterVolume ?? 50);
13840
13985
  refs.masterVolumeLabel.textContent = `${options.masterVolume ?? 50}%`;
13986
+ refs.masterComp.value = String(options.masterCompression ?? 0);
13987
+ refs.masterCompLabel.textContent = `${options.masterCompression ?? 0}%`;
13841
13988
  refs.reverbAmount.value = String(options.reverbAmount ?? 0);
13842
13989
  refs.reverbAmountLabel.textContent = `${options.reverbAmount ?? 0}%`;
13843
13990
  {
@@ -13875,14 +14022,38 @@ var mountDAW = (target, options = {}) => {
13875
14022
  let reverbPreDelay = options.reverbPreDelay ?? DEFAULT_REVERB_PREDELAY_MS;
13876
14023
  let delayAmount = options.delayAmount ?? 0;
13877
14024
  let delayDivision = options.delayDivision ?? "8";
14025
+ let masterCompression = options.masterCompression ?? 0;
13878
14026
  let fadeInSec = options.fadeInSec ?? 0;
13879
14027
  let fadeOutSec = options.fadeOutSec ?? 0;
13880
14028
  let unsubscribeClip;
14029
+ let observedPeakMax = 0;
14030
+ let observedPlayMs = 0;
14031
+ let peakSampleRafId = null;
14032
+ let peakSampleLastTs = 0;
14033
+ const PEAK_SAMPLE_MIN_PLAY_MS = 2e3;
14034
+ const samplePeakTick = (ts) => {
14035
+ if (peakSampleLastTs) observedPlayMs += ts - peakSampleLastTs;
14036
+ peakSampleLastTs = ts;
14037
+ const peak = options.clipMeter?.getPeakLevel() ?? 0;
14038
+ if (peak > observedPeakMax) observedPeakMax = peak;
14039
+ peakSampleRafId = requestAnimationFrame(samplePeakTick);
14040
+ };
14041
+ const startPeakSampling = () => {
14042
+ if (peakSampleRafId !== null || !options.clipMeter) return;
14043
+ peakSampleLastTs = 0;
14044
+ peakSampleRafId = requestAnimationFrame(samplePeakTick);
14045
+ };
14046
+ const stopPeakSampling = () => {
14047
+ if (peakSampleRafId !== null) cancelAnimationFrame(peakSampleRafId);
14048
+ peakSampleRafId = null;
14049
+ peakSampleLastTs = 0;
14050
+ };
13881
14051
  options.onReverbChange?.(reverbAmount);
13882
14052
  options.onReverbDecayChange?.(reverbDecay);
13883
14053
  options.onReverbPreDelayChange?.(reverbPreDelay);
13884
14054
  options.onDelayChange?.(delayAmount);
13885
14055
  options.onDelayDivisionChange?.(delayDivision);
14056
+ options.onMasterCompressionChange?.(masterCompression);
13886
14057
  let drumVolume = options.drumVolume ?? 80;
13887
14058
  let currentDrumPattern = refs.drumSelect.value;
13888
14059
  let currentDrumFont = options.drumFont ?? "FluidR3_GM_sf2_file:0";
@@ -14042,7 +14213,9 @@ var mountDAW = (target, options = {}) => {
14042
14213
  trackReverbSend: 0,
14043
14214
  trackEqLow: 0,
14044
14215
  trackEqMid: 0,
14045
- trackEqHigh: 0
14216
+ trackEqHigh: 0,
14217
+ trackPan: 64,
14218
+ trackDelaySend: 0
14046
14219
  };
14047
14220
  });
14048
14221
  };
@@ -14915,6 +15088,7 @@ var mountDAW = (target, options = {}) => {
14915
15088
  }
14916
15089
  playbackState = "playing";
14917
15090
  sequencer.start(fromStep);
15091
+ startPeakSampling();
14918
15092
  {
14919
15093
  const anchor = sequencer.getStartTime();
14920
15094
  const secondsPerStepFade = 60 / bpm / 48;
@@ -14957,6 +15131,7 @@ var mountDAW = (target, options = {}) => {
14957
15131
  clearSoundTimers();
14958
15132
  options.onScheduleFade?.(null);
14959
15133
  playbackState = "paused";
15134
+ stopPeakSampling();
14960
15135
  updateTransport();
14961
15136
  };
14962
15137
  const reloadVoicesForModel = (model) => {
@@ -14972,6 +15147,7 @@ var mountDAW = (target, options = {}) => {
14972
15147
  options.onScheduleFade?.(null);
14973
15148
  playbackState = "stopped";
14974
15149
  currentPlayStep = 0;
15150
+ stopPeakSampling();
14975
15151
  updateTransport();
14976
15152
  redrawAll();
14977
15153
  };
@@ -15040,12 +15216,24 @@ var mountDAW = (target, options = {}) => {
15040
15216
  <span class="dtm-label" data-dtm="track-width-label"></span>
15041
15217
  <button class="dtm-infobtn" data-dtm="track-width-info" title="\u30B9\u30C6\u30EC\u30AA\u5E45\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15042
15218
  </div>
15219
+ <div class="dtm-row">
15220
+ <span class="dtm-label">\u5B9A\u4F4D</span>
15221
+ <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">
15222
+ <span class="dtm-label" data-dtm="track-pan-label"></span>
15223
+ <button class="dtm-infobtn" data-dtm="track-pan-info" title="\u5B9A\u4F4D\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15224
+ </div>
15043
15225
  <div class="dtm-row">
15044
15226
  <span class="dtm-label">\u30EA\u30D0\u30FC\u30D6\u9001\u308A</span>
15045
15227
  <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">
15046
15228
  <span class="dtm-label" data-dtm="track-reverb-send-label"></span>
15047
15229
  <button class="dtm-infobtn" data-dtm="track-reverb-send-info" title="\u30EA\u30D0\u30FC\u30D6\u9001\u308A\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15048
15230
  </div>
15231
+ <div class="dtm-row">
15232
+ <span class="dtm-label">\u30C7\u30A3\u30EC\u30A4\u9001\u308A</span>
15233
+ <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">
15234
+ <span class="dtm-label" data-dtm="track-delay-send-label"></span>
15235
+ <button class="dtm-infobtn" data-dtm="track-delay-send-info" title="\u30C7\u30A3\u30EC\u30A4\u9001\u308A\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15236
+ </div>
15049
15237
  </details>`;
15050
15238
  refs.trackBody.querySelector(
15051
15239
  '[data-dtm="track-fx-advanced"]'
@@ -15155,6 +15343,26 @@ var mountDAW = (target, options = {}) => {
15155
15343
  trackWidthInfo.addEventListener("click", () => {
15156
15344
  showModal("\u30B9\u30C6\u30EC\u30AA\u5E45\u306E\u89E3\u8AAC", TRACK_WIDTH_INFO_HTML);
15157
15345
  });
15346
+ const trackPanInput = refs.trackBody.querySelector(
15347
+ '[data-dtm="track-pan"]'
15348
+ );
15349
+ const trackPanLabel = refs.trackBody.querySelector(
15350
+ '[data-dtm="track-pan-label"]'
15351
+ );
15352
+ const trackPanInfo = refs.trackBody.querySelector(
15353
+ '[data-dtm="track-pan-info"]'
15354
+ );
15355
+ const fmtTrackPan = (pan) => pan === 64 ? "C" : pan < 64 ? `L${64 - pan}` : `R${pan - 64}`;
15356
+ trackPanInput.value = String(active.trackPan);
15357
+ trackPanLabel.textContent = fmtTrackPan(active.trackPan);
15358
+ trackPanInput.addEventListener("input", () => {
15359
+ active.trackPan = Number.parseInt(trackPanInput.value, 10);
15360
+ trackPanLabel.textContent = fmtTrackPan(active.trackPan);
15361
+ options.onTrackPanChange?.(active.config.id, active.trackPan);
15362
+ });
15363
+ trackPanInfo.addEventListener("click", () => {
15364
+ showModal("\u5B9A\u4F4D\u306E\u89E3\u8AAC", TRACK_PAN_INFO_HTML);
15365
+ });
15158
15366
  const trackReverbSendInput = refs.trackBody.querySelector(
15159
15367
  '[data-dtm="track-reverb-send"]'
15160
15368
  );
@@ -15177,6 +15385,25 @@ var mountDAW = (target, options = {}) => {
15177
15385
  trackReverbSendInfo.addEventListener("click", () => {
15178
15386
  showModal("\u30EA\u30D0\u30FC\u30D6\u9001\u308A\u306E\u89E3\u8AAC", TRACK_REVERBSEND_INFO_HTML);
15179
15387
  });
15388
+ const trackDelaySendInput = refs.trackBody.querySelector(
15389
+ '[data-dtm="track-delay-send"]'
15390
+ );
15391
+ const trackDelaySendLabel = refs.trackBody.querySelector(
15392
+ '[data-dtm="track-delay-send-label"]'
15393
+ );
15394
+ const trackDelaySendInfo = refs.trackBody.querySelector(
15395
+ '[data-dtm="track-delay-send-info"]'
15396
+ );
15397
+ trackDelaySendInput.value = String(active.trackDelaySend);
15398
+ trackDelaySendLabel.textContent = `${active.trackDelaySend}%`;
15399
+ trackDelaySendInput.addEventListener("input", () => {
15400
+ active.trackDelaySend = Number.parseInt(trackDelaySendInput.value, 10);
15401
+ trackDelaySendLabel.textContent = `${active.trackDelaySend}%`;
15402
+ options.onTrackDelaySendChange?.(active.config.id, active.trackDelaySend);
15403
+ });
15404
+ trackDelaySendInfo.addEventListener("click", () => {
15405
+ showModal("\u30C7\u30A3\u30EC\u30A4\u9001\u308A\u306E\u89E3\u8AAC", TRACK_DELAYSEND_INFO_HTML);
15406
+ });
15180
15407
  const instRow = document.createElement("div");
15181
15408
  instRow.className = "dtm-row";
15182
15409
  instRow.innerHTML = `<span class="dtm-label">\u697D\u5668</span>`;
@@ -15780,6 +16007,8 @@ var mountDAW = (target, options = {}) => {
15780
16007
  const trackEqLowForMeta = {};
15781
16008
  const trackEqMidForMeta = {};
15782
16009
  const trackEqHighForMeta = {};
16010
+ const trackPanForMeta = {};
16011
+ const trackDelaySendForMeta = {};
15783
16012
  trackStates.forEach((t, i2) => {
15784
16013
  if (t.trackInstrument) trackInstrumentsForMeta[i2] = t.trackInstrument;
15785
16014
  if (t.trackCompression !== 0)
@@ -15790,6 +16019,8 @@ var mountDAW = (target, options = {}) => {
15790
16019
  if (t.trackEqLow !== 0) trackEqLowForMeta[i2] = t.trackEqLow;
15791
16020
  if (t.trackEqMid !== 0) trackEqMidForMeta[i2] = t.trackEqMid;
15792
16021
  if (t.trackEqHigh !== 0) trackEqHighForMeta[i2] = t.trackEqHigh;
16022
+ if (t.trackPan !== 64) trackPanForMeta[i2] = t.trackPan;
16023
+ if (t.trackDelaySend !== 0) trackDelaySendForMeta[i2] = t.trackDelaySend;
15793
16024
  });
15794
16025
  const trackInstMeta = Object.keys(trackInstrumentsForMeta).length > 0 ? trackInstrumentsForMeta : void 0;
15795
16026
  const trackCompMeta = Object.keys(trackCompressionForMeta).length > 0 ? trackCompressionForMeta : void 0;
@@ -15798,6 +16029,8 @@ var mountDAW = (target, options = {}) => {
15798
16029
  const trackEqLowMeta = Object.keys(trackEqLowForMeta).length > 0 ? trackEqLowForMeta : void 0;
15799
16030
  const trackEqMidMeta = Object.keys(trackEqMidForMeta).length > 0 ? trackEqMidForMeta : void 0;
15800
16031
  const trackEqHighMeta = Object.keys(trackEqHighForMeta).length > 0 ? trackEqHighForMeta : void 0;
16032
+ const trackPanMeta = Object.keys(trackPanForMeta).length > 0 ? trackPanForMeta : void 0;
16033
+ const trackDelaySendMeta = Object.keys(trackDelaySendForMeta).length > 0 ? trackDelaySendForMeta : void 0;
15801
16034
  const metaLineFull = formatMmlMeta(
15802
16035
  {
15803
16036
  instrument: currentInstrument || void 0,
@@ -15809,6 +16042,7 @@ var mountDAW = (target, options = {}) => {
15809
16042
  reverbPreDelay,
15810
16043
  delay: delayAmount,
15811
16044
  delayDivision,
16045
+ masterCompression,
15812
16046
  fadeIn: Math.round(fadeInSec * 10),
15813
16047
  fadeOut: Math.round(fadeOutSec * 10),
15814
16048
  mode,
@@ -15818,7 +16052,9 @@ var mountDAW = (target, options = {}) => {
15818
16052
  trackReverbSend: trackReverbSendMeta,
15819
16053
  trackEqLow: trackEqLowMeta,
15820
16054
  trackEqMid: trackEqMidMeta,
15821
- trackEqHigh: trackEqHighMeta
16055
+ trackEqHigh: trackEqHighMeta,
16056
+ trackPan: trackPanMeta,
16057
+ trackDelaySend: trackDelaySendMeta
15822
16058
  },
15823
16059
  " "
15824
16060
  );
@@ -15833,6 +16069,7 @@ var mountDAW = (target, options = {}) => {
15833
16069
  reverbPreDelay,
15834
16070
  delay: delayAmount,
15835
16071
  delayDivision,
16072
+ masterCompression,
15836
16073
  fadeIn: Math.round(fadeInSec * 10),
15837
16074
  fadeOut: Math.round(fadeOutSec * 10),
15838
16075
  mode,
@@ -15842,7 +16079,9 @@ var mountDAW = (target, options = {}) => {
15842
16079
  trackReverbSend: trackReverbSendMeta,
15843
16080
  trackEqLow: trackEqLowMeta,
15844
16081
  trackEqMid: trackEqMidMeta,
15845
- trackEqHigh: trackEqHighMeta
16082
+ trackEqHigh: trackEqHighMeta,
16083
+ trackPan: trackPanMeta,
16084
+ trackDelaySend: trackDelaySendMeta
15846
16085
  },
15847
16086
  ""
15848
16087
  );
@@ -16080,6 +16319,12 @@ var mountDAW = (target, options = {}) => {
16080
16319
  refs.delayDivision.value = delayDivision;
16081
16320
  options.onDelayDivisionChange?.(delayDivision);
16082
16321
  }
16322
+ if (meta.masterCompression !== void 0) {
16323
+ masterCompression = meta.masterCompression;
16324
+ refs.masterComp.value = String(meta.masterCompression);
16325
+ refs.masterCompLabel.textContent = `${meta.masterCompression}%`;
16326
+ options.onMasterCompressionChange?.(meta.masterCompression);
16327
+ }
16083
16328
  if (meta.fadeIn !== void 0) {
16084
16329
  fadeInSec = meta.fadeIn / 10;
16085
16330
  refs.fadeIn.value = String(fadeInSec);
@@ -16131,6 +16376,16 @@ var mountDAW = (target, options = {}) => {
16131
16376
  t.trackEqHigh = eqHigh;
16132
16377
  options.onTrackEqHighChange?.(t.config.id, eqHigh);
16133
16378
  }
16379
+ const pan = meta.trackPan?.[i2] ?? 64;
16380
+ if (t.trackPan !== pan) {
16381
+ t.trackPan = pan;
16382
+ options.onTrackPanChange?.(t.config.id, pan);
16383
+ }
16384
+ const delaySend = meta.trackDelaySend?.[i2] ?? 0;
16385
+ if (t.trackDelaySend !== delaySend) {
16386
+ t.trackDelaySend = delaySend;
16387
+ options.onTrackDelaySendChange?.(t.config.id, delaySend);
16388
+ }
16134
16389
  });
16135
16390
  trackStates.forEach((t, i2) => {
16136
16391
  if (applyActiveOnly && i2 !== activeTrackIndex) return;
@@ -16508,6 +16763,14 @@ var mountDAW = (target, options = {}) => {
16508
16763
  refs.masterVolumeLabel.textContent = `${masterVolume}%`;
16509
16764
  options.singingVoices?.setVolume(masterVolume / 100);
16510
16765
  });
16766
+ refs.masterComp.addEventListener("input", () => {
16767
+ masterCompression = Number.parseInt(refs.masterComp.value, 10) || 0;
16768
+ refs.masterCompLabel.textContent = `${masterCompression}%`;
16769
+ options.onMasterCompressionChange?.(masterCompression);
16770
+ });
16771
+ refs.masterCompInfoBtn.addEventListener("click", () => {
16772
+ showModal("\u30B0\u30EB\u30FC\u30B3\u30F3\u30D7\u306E\u89E3\u8AAC", MASTER_COMP_INFO_HTML);
16773
+ });
16511
16774
  refs.reverbAmount.addEventListener("input", () => {
16512
16775
  reverbAmount = Number.parseInt(refs.reverbAmount.value, 10) || 0;
16513
16776
  refs.reverbAmountLabel.textContent = `${reverbAmount}%`;
@@ -16557,10 +16820,31 @@ var mountDAW = (target, options = {}) => {
16557
16820
  showModal("\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0\u89E3\u8AAC", AUTO_MASTER_INFO_HTML);
16558
16821
  });
16559
16822
  refs.autoMasterBtn.addEventListener("click", () => {
16560
- reverbAmount = 20;
16561
- refs.reverbAmount.value = "20";
16562
- refs.reverbAmountLabel.textContent = "20%";
16563
- options.onReverbChange?.(20);
16823
+ if (observedPlayMs >= PEAK_SAMPLE_MIN_PLAY_MS && observedPeakMax > 0) {
16824
+ const targetPeak = 0.5;
16825
+ const scale = targetPeak / observedPeakMax;
16826
+ const suggested = clamp5(Math.round(masterVolume * scale), 10, 100);
16827
+ if (suggested !== masterVolume) {
16828
+ masterVolume = suggested;
16829
+ refs.masterVolume.value = String(masterVolume);
16830
+ refs.masterVolumeLabel.textContent = `${masterVolume}%`;
16831
+ options.singingVoices?.setVolume(masterVolume / 100);
16832
+ }
16833
+ observedPeakMax = 0;
16834
+ observedPlayMs = 0;
16835
+ }
16836
+ masterCompression = 25;
16837
+ refs.masterComp.value = "25";
16838
+ refs.masterCompLabel.textContent = "25%";
16839
+ options.onMasterCompressionChange?.(25);
16840
+ const activeTrackCount = trackStates.filter(
16841
+ (t) => t.core.getNotes().length > 0
16842
+ ).length;
16843
+ const densityT = clamp5((activeTrackCount - 2) / (8 - 2), 0, 1);
16844
+ reverbAmount = Math.round(28 - densityT * (28 - 12));
16845
+ refs.reverbAmount.value = String(reverbAmount);
16846
+ refs.reverbAmountLabel.textContent = `${reverbAmount}%`;
16847
+ options.onReverbChange?.(reverbAmount);
16564
16848
  const bpmT = clamp5((bpm - 60) / (180 - 60), 0, 1);
16565
16849
  reverbDecay = clamp5(
16566
16850
  3 - bpmT * (3 - 0.9),
@@ -16574,8 +16858,14 @@ var mountDAW = (target, options = {}) => {
16574
16858
  refs.reverbPreDelay.value = "20";
16575
16859
  refs.reverbPreDelayLabel.textContent = "20ms";
16576
16860
  options.onReverbPreDelayChange?.(20);
16861
+ if (fadeOutSec === 0) {
16862
+ fadeOutSec = 1.5;
16863
+ refs.fadeOut.value = "1.5";
16864
+ refs.fadeOutLabel.textContent = "1.5s";
16865
+ }
16577
16866
  let mainVocalId = null;
16578
16867
  let mainVocalScore = -1;
16868
+ let nonMainVocalCount = 0;
16579
16869
  for (const t of trackStates) {
16580
16870
  if (!t.lyricModel) continue;
16581
16871
  const score = t.core.getNotes().reduce((sum, n) => sum + n.durationSteps, 0);
@@ -16584,34 +16874,87 @@ var mountDAW = (target, options = {}) => {
16584
16874
  mainVocalId = t.config.id;
16585
16875
  }
16586
16876
  }
16877
+ for (const t of trackStates) {
16878
+ if (t.lyricModel && t.config.id !== mainVocalId) nonMainVocalCount++;
16879
+ }
16587
16880
  const autoPreset = INSTRUMENT_PRESETS[currentInstrument] ?? INSTRUMENT_PRESETS.piano;
16881
+ const roleByTrackId = /* @__PURE__ */ new Map();
16588
16882
  for (const t of trackStates) {
16589
16883
  if (t.lyricModel) continue;
16590
16884
  const notes = t.core.getNotes();
16591
16885
  if (notes.length === 0) continue;
16592
- const role = classifyTrackRole(notes);
16886
+ const stats = computeAutoRoleStats(notes);
16887
+ const role = classifyTrackRole(stats);
16888
+ roleByTrackId.set(t.config.id, role);
16593
16889
  const instName = autoPreset[role];
16594
16890
  t.trackInstrument = instName;
16595
16891
  const trackIndex = trackStates.indexOf(t);
16596
16892
  options.onTrackInstrumentChange?.(trackIndex, instName);
16597
- const vol = AUTO_ROLE_VOLUME[role];
16893
+ const vol = computeAutoRoleVolume(role, stats);
16598
16894
  t.volume = vol;
16599
16895
  t.core.setVolume(vol);
16600
16896
  }
16897
+ const AUTO_PAN_OFFSETS = {
16898
+ melody: [0],
16899
+ bass: [0],
16900
+ submelody: [18, -18, 30, -30],
16901
+ chord: [36, -36, 48, -48]
16902
+ };
16903
+ const panRoleCounter = /* @__PURE__ */ new Map();
16904
+ let vocalSideCounter = 0;
16601
16905
  for (const t of trackStates) {
16602
16906
  const isMainVocal = !!t.lyricModel && t.config.id === mainVocalId;
16603
- const comp = !t.lyricModel ? 35 : isMainVocal ? 30 : 25;
16907
+ const role = roleByTrackId.get(t.config.id);
16908
+ const roleMix = role ? AUTO_ROLE_MIX[role] : void 0;
16909
+ let pan = 64;
16910
+ if (t.lyricModel) {
16911
+ pan = isMainVocal ? 64 : clamp5(64 + (vocalSideCounter++ % 2 === 0 ? 22 : -22), 0, 127);
16912
+ } else if (role) {
16913
+ const offsets = AUTO_PAN_OFFSETS[role];
16914
+ const n = panRoleCounter.get(role) ?? 0;
16915
+ panRoleCounter.set(role, n + 1);
16916
+ pan = clamp5(64 + offsets[n % offsets.length], 0, 127);
16917
+ }
16918
+ t.trackPan = pan;
16919
+ options.onTrackPanChange?.(t.config.id, pan);
16920
+ const comp = t.lyricModel ? isMainVocal ? 30 : 25 : roleMix?.compression ?? 35;
16921
+ const width = t.lyricModel ? isMainVocal ? 100 : 120 : roleMix?.width ?? 115;
16604
16922
  t.trackCompression = comp;
16605
- t.trackWidth = 115;
16923
+ t.trackWidth = width;
16606
16924
  options.onTrackCompressionChange?.(t.config.id, comp);
16607
- options.onTrackWidthChange?.(t.config.id, 115);
16925
+ options.onTrackWidthChange?.(t.config.id, width);
16926
+ if (t.lyricModel) {
16927
+ t.trackEqLow = -3;
16928
+ t.trackEqHigh = isMainVocal ? 2 : 0;
16929
+ options.onTrackEqLowChange?.(t.config.id, t.trackEqLow);
16930
+ options.onTrackEqHighChange?.(t.config.id, t.trackEqHigh);
16931
+ } else {
16932
+ const eqLow = roleMix?.eqLow ?? 0;
16933
+ const eqHigh = roleMix?.eqHigh ?? 0;
16934
+ t.trackEqLow = eqLow;
16935
+ t.trackEqHigh = eqHigh;
16936
+ options.onTrackEqLowChange?.(t.config.id, eqLow);
16937
+ options.onTrackEqHighChange?.(t.config.id, eqHigh);
16938
+ }
16608
16939
  if (!t.lyricModel) {
16609
- t.trackReverbSend = 15;
16610
- options.onTrackReverbSendChange?.(t.config.id, 15);
16940
+ const reverbSend = roleMix?.reverbSend ?? 15;
16941
+ t.trackReverbSend = reverbSend;
16942
+ options.onTrackReverbSendChange?.(t.config.id, reverbSend);
16943
+ const delaySend = roleMix?.delaySend ?? 0;
16944
+ t.trackDelaySend = delaySend;
16945
+ options.onTrackDelaySendChange?.(t.config.id, delaySend);
16611
16946
  }
16612
16947
  if (t.lyricModel) {
16613
- t.vocalVibrato = true;
16948
+ t.vocalVibrato = isMainVocal;
16614
16949
  t.vocalReverb = isMainVocal ? 25 : 45;
16950
+ t.vocalDelay = isMainVocal ? 15 : 0;
16951
+ t.vocalVolume = isMainVocal ? Math.round(DEFAULT_VOCAL_VOLUME * 1.1) : clamp5(
16952
+ Math.round(
16953
+ DEFAULT_VOCAL_VOLUME * 0.85 / Math.sqrt(Math.max(1, nonMainVocalCount))
16954
+ ),
16955
+ 60,
16956
+ MAX_VOCAL_VOLUME
16957
+ );
16615
16958
  fireLyricsChange(t);
16616
16959
  }
16617
16960
  }
@@ -17697,6 +18040,7 @@ var mountDAW = (target, options = {}) => {
17697
18040
  sequencer.stop();
17698
18041
  options.singingVoices?.stopStream();
17699
18042
  unsubscribeClip?.();
18043
+ stopPeakSampling();
17700
18044
  resizeObserver.disconnect();
17701
18045
  document.removeEventListener("pointermove", onPointerMove);
17702
18046
  document.removeEventListener("pointerup", onPointerUp);
@@ -18654,13 +18998,39 @@ var createDtmStudio = async (options = {}) => {
18654
18998
  division: options.delayDivision ?? "8"
18655
18999
  });
18656
19000
  const setDelayAmount = (amount) => delayBus.setAmount(amount);
19001
+ const glueComp = audioCtx.createDynamicsCompressor();
19002
+ glueComp.knee.value = 6;
19003
+ const glueMakeup = audioCtx.createGain();
19004
+ finalMix.connect(glueComp);
19005
+ glueComp.connect(glueMakeup);
19006
+ const glueCompressionParams = (amount) => {
19007
+ const t = Math.max(0, Math.min(100, amount)) / 100;
19008
+ return {
19009
+ threshold: 0 + (-18 - 0) * t,
19010
+ ratio: 1 + (4 - 1) * t,
19011
+ attack: 0.03 + (0.01 - 0.03) * t,
19012
+ release: 0.3 + (0.15 - 0.3) * t,
19013
+ makeupDb: 2.5 * t
19014
+ };
19015
+ };
19016
+ const applyGlueCompression = (amount) => {
19017
+ const p = glueCompressionParams(amount);
19018
+ const now = audioCtx.currentTime;
19019
+ glueComp.threshold.setValueAtTime(p.threshold, now);
19020
+ glueComp.ratio.setValueAtTime(p.ratio, now);
19021
+ glueComp.attack.setValueAtTime(p.attack, now);
19022
+ glueComp.release.setValueAtTime(p.release, now);
19023
+ glueMakeup.gain.setTargetAtTime(10 ** (p.makeupDb / 20), now, 0.02);
19024
+ };
19025
+ applyGlueCompression(options.masterCompression ?? 0);
19026
+ const setMasterCompression = (amount) => applyGlueCompression(amount);
18657
19027
  const safetyLimiter = audioCtx.createDynamicsCompressor();
18658
19028
  safetyLimiter.threshold.value = -1;
18659
19029
  safetyLimiter.knee.value = 0;
18660
19030
  safetyLimiter.ratio.value = 20;
18661
19031
  safetyLimiter.attack.value = 1e-3;
18662
19032
  safetyLimiter.release.value = 0.1;
18663
- finalMix.connect(safetyLimiter);
19033
+ glueMakeup.connect(safetyLimiter);
18664
19034
  const fadeGain = audioCtx.createGain();
18665
19035
  fadeGain.gain.value = 1;
18666
19036
  safetyLimiter.connect(fadeGain);
@@ -18683,13 +19053,14 @@ var createDtmStudio = async (options = {}) => {
18683
19053
  fadeGain.gain.linearRampToValueAtTime(0, fadeOutEndAt);
18684
19054
  }
18685
19055
  };
18686
- const clipMeter = createClipMeter(audioCtx, finalMix);
19056
+ const clipMeter = createClipMeter(audioCtx, glueMakeup);
18687
19057
  const channelStrips = /* @__PURE__ */ new Map();
18688
19058
  const getChannelStrip = (trackId) => {
18689
19059
  let strip = channelStrips.get(trackId);
18690
19060
  if (!strip) {
18691
19061
  strip = createChannelStrip(audioCtx, masterGain, {
18692
- reverbBus: reverbPreDelay
19062
+ reverbBus: reverbPreDelay,
19063
+ delayBus: delayBus.input
18693
19064
  });
18694
19065
  channelStrips.set(trackId, strip);
18695
19066
  }
@@ -19020,6 +19391,8 @@ var createDtmStudio = async (options = {}) => {
19020
19391
  onDelayChange: setDelayAmount,
19021
19392
  delayDivision: options.delayDivision,
19022
19393
  onDelayDivisionChange: (division) => delayBus.setDivision(division),
19394
+ masterCompression: options.masterCompression,
19395
+ onMasterCompressionChange: setMasterCompression,
19023
19396
  onBpmChange: (bpm) => delayBus.setBpm(bpm),
19024
19397
  fadeInSec: options.fadeInSec,
19025
19398
  fadeOutSec: options.fadeOutSec,
@@ -19027,9 +19400,11 @@ var createDtmStudio = async (options = {}) => {
19027
19400
  onTrackCompressionChange: (trackId, amount) => getChannelStrip(trackId).setCompression(amount),
19028
19401
  onTrackWidthChange: (trackId, width) => getChannelStrip(trackId).setWidth(width),
19029
19402
  onTrackReverbSendChange: (trackId, amount) => getChannelStrip(trackId).setReverbSend(amount),
19403
+ onTrackDelaySendChange: (trackId, amount) => getChannelStrip(trackId).setDelaySend(amount),
19030
19404
  onTrackEqLowChange: (trackId, db) => getChannelStrip(trackId).setEqLow(db),
19031
19405
  onTrackEqMidChange: (trackId, db) => getChannelStrip(trackId).setEqMid(db),
19032
19406
  onTrackEqHighChange: (trackId, db) => getChannelStrip(trackId).setEqHigh(db),
19407
+ onTrackPanChange: (trackId, pan) => getChannelStrip(trackId).setPan(panToStereo(pan)),
19033
19408
  clipMeter,
19034
19409
  ...dawOverrides,
19035
19410
  // dawOverrides で上書きされないよう、スプレッドの後に配置して合成する
@@ -19611,6 +19986,7 @@ var createDtmStudio = async (options = {}) => {
19611
19986
  setReverbDecay,
19612
19987
  setReverbPreDelay,
19613
19988
  setDelayAmount,
19989
+ setMasterCompression,
19614
19990
  dispose
19615
19991
  };
19616
19992
  };