@onjmin/dtm 0.1.95 → 0.1.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,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>
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>
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>
13529
13626
  <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>
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>
13534
13631
  </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>
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>
13536
13633
  <h4>\u30E1\u30A4\u30F3\u30DC\u30FC\u30AB\u30EB\u306E\u81EA\u52D5\u5224\u5B9A</h4>
13537
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>
13538
13635
  <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>
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>
13541
13638
  </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>
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>
13543
13640
  </div>
13544
13641
  `;
13545
13642
  var MIDI_INFO_HTML = `
@@ -13784,30 +13881,79 @@ var normalizeInstrumentName = (name) => {
13784
13881
  ) ?? name;
13785
13882
  };
13786
13883
  var AUTO_ROLE_STEPS_PER_BEAT = 48;
13787
- var AUTO_ROLE_VOLUME = {
13884
+ var AUTO_ROLE_BASE_VOLUME = {
13788
13885
  melody: 100,
13789
13886
  submelody: 92,
13790
13887
  bass: 85,
13791
13888
  chord: 72
13792
13889
  };
13793
- var classifyTrackRole = (notes) => {
13890
+ var computeAutoRoleStats = (notes) => {
13794
13891
  const avgPitch = notes.reduce((s, n) => s + n.pitch, 0) / notes.length;
13795
- if (avgPitch < 48) return "bass";
13796
13892
  const avgDur = notes.reduce((s, n) => s + n.durationSteps, 0) / notes.length;
13797
13893
  const byStart = /* @__PURE__ */ new Map();
13798
13894
  for (const n of notes)
13799
13895
  byStart.set(n.startStep, (byStart.get(n.startStep) ?? 0) + 1);
13800
13896
  let maxPoly = 0;
13801
13897
  for (const c of byStart.values()) if (c > maxPoly) maxPoly = c;
13802
- if (maxPoly >= 2 && avgDur >= AUTO_ROLE_STEPS_PER_BEAT) return "chord";
13898
+ const avgPoly = notes.length / byStart.size;
13803
13899
  const minStart = Math.min(...notes.map((n) => n.startStep));
13804
13900
  const maxEnd = Math.max(...notes.map((n) => n.startStep + n.durationSteps));
13805
13901
  const spanBeats = Math.max(1, (maxEnd - minStart) / AUTO_ROLE_STEPS_PER_BEAT);
13806
13902
  const notesPerBeat = notes.length / spanBeats;
13807
- if (notesPerBeat < 1.2 && avgDur >= AUTO_ROLE_STEPS_PER_BEAT * 1.5)
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)
13808
13910
  return "submelody";
13809
13911
  return "melody";
13810
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
+ };
13811
13957
  var mountDAW = (target, options = {}) => {
13812
13958
  injectStyles();
13813
13959
  const getAudioTime = options.getAudioTime ?? (() => performance.now() / 1e3);
@@ -13838,6 +13984,8 @@ var mountDAW = (target, options = {}) => {
13838
13984
  });
13839
13985
  refs.masterVolume.value = String(options.masterVolume ?? 50);
13840
13986
  refs.masterVolumeLabel.textContent = `${options.masterVolume ?? 50}%`;
13987
+ refs.masterComp.value = String(options.masterCompression ?? 0);
13988
+ refs.masterCompLabel.textContent = `${options.masterCompression ?? 0}%`;
13841
13989
  refs.reverbAmount.value = String(options.reverbAmount ?? 0);
13842
13990
  refs.reverbAmountLabel.textContent = `${options.reverbAmount ?? 0}%`;
13843
13991
  {
@@ -13875,14 +14023,38 @@ var mountDAW = (target, options = {}) => {
13875
14023
  let reverbPreDelay = options.reverbPreDelay ?? DEFAULT_REVERB_PREDELAY_MS;
13876
14024
  let delayAmount = options.delayAmount ?? 0;
13877
14025
  let delayDivision = options.delayDivision ?? "8";
14026
+ let masterCompression = options.masterCompression ?? 0;
13878
14027
  let fadeInSec = options.fadeInSec ?? 0;
13879
14028
  let fadeOutSec = options.fadeOutSec ?? 0;
13880
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
+ };
13881
14052
  options.onReverbChange?.(reverbAmount);
13882
14053
  options.onReverbDecayChange?.(reverbDecay);
13883
14054
  options.onReverbPreDelayChange?.(reverbPreDelay);
13884
14055
  options.onDelayChange?.(delayAmount);
13885
14056
  options.onDelayDivisionChange?.(delayDivision);
14057
+ options.onMasterCompressionChange?.(masterCompression);
13886
14058
  let drumVolume = options.drumVolume ?? 80;
13887
14059
  let currentDrumPattern = refs.drumSelect.value;
13888
14060
  let currentDrumFont = options.drumFont ?? "FluidR3_GM_sf2_file:0";
@@ -14042,7 +14214,9 @@ var mountDAW = (target, options = {}) => {
14042
14214
  trackReverbSend: 0,
14043
14215
  trackEqLow: 0,
14044
14216
  trackEqMid: 0,
14045
- trackEqHigh: 0
14217
+ trackEqHigh: 0,
14218
+ trackPan: 64,
14219
+ trackDelaySend: 0
14046
14220
  };
14047
14221
  });
14048
14222
  };
@@ -14915,6 +15089,7 @@ var mountDAW = (target, options = {}) => {
14915
15089
  }
14916
15090
  playbackState = "playing";
14917
15091
  sequencer.start(fromStep);
15092
+ startPeakSampling();
14918
15093
  {
14919
15094
  const anchor = sequencer.getStartTime();
14920
15095
  const secondsPerStepFade = 60 / bpm / 48;
@@ -14957,6 +15132,7 @@ var mountDAW = (target, options = {}) => {
14957
15132
  clearSoundTimers();
14958
15133
  options.onScheduleFade?.(null);
14959
15134
  playbackState = "paused";
15135
+ stopPeakSampling();
14960
15136
  updateTransport();
14961
15137
  };
14962
15138
  const reloadVoicesForModel = (model) => {
@@ -14972,6 +15148,7 @@ var mountDAW = (target, options = {}) => {
14972
15148
  options.onScheduleFade?.(null);
14973
15149
  playbackState = "stopped";
14974
15150
  currentPlayStep = 0;
15151
+ stopPeakSampling();
14975
15152
  updateTransport();
14976
15153
  redrawAll();
14977
15154
  };
@@ -15040,12 +15217,24 @@ var mountDAW = (target, options = {}) => {
15040
15217
  <span class="dtm-label" data-dtm="track-width-label"></span>
15041
15218
  <button class="dtm-infobtn" data-dtm="track-width-info" title="\u30B9\u30C6\u30EC\u30AA\u5E45\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15042
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>
15043
15226
  <div class="dtm-row">
15044
15227
  <span class="dtm-label">\u30EA\u30D0\u30FC\u30D6\u9001\u308A</span>
15045
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">
15046
15229
  <span class="dtm-label" data-dtm="track-reverb-send-label"></span>
15047
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>
15048
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>
15049
15238
  </details>`;
15050
15239
  refs.trackBody.querySelector(
15051
15240
  '[data-dtm="track-fx-advanced"]'
@@ -15155,6 +15344,26 @@ var mountDAW = (target, options = {}) => {
15155
15344
  trackWidthInfo.addEventListener("click", () => {
15156
15345
  showModal("\u30B9\u30C6\u30EC\u30AA\u5E45\u306E\u89E3\u8AAC", TRACK_WIDTH_INFO_HTML);
15157
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
+ });
15158
15367
  const trackReverbSendInput = refs.trackBody.querySelector(
15159
15368
  '[data-dtm="track-reverb-send"]'
15160
15369
  );
@@ -15177,6 +15386,25 @@ var mountDAW = (target, options = {}) => {
15177
15386
  trackReverbSendInfo.addEventListener("click", () => {
15178
15387
  showModal("\u30EA\u30D0\u30FC\u30D6\u9001\u308A\u306E\u89E3\u8AAC", TRACK_REVERBSEND_INFO_HTML);
15179
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
+ });
15180
15408
  const instRow = document.createElement("div");
15181
15409
  instRow.className = "dtm-row";
15182
15410
  instRow.innerHTML = `<span class="dtm-label">\u697D\u5668</span>`;
@@ -15780,6 +16008,8 @@ var mountDAW = (target, options = {}) => {
15780
16008
  const trackEqLowForMeta = {};
15781
16009
  const trackEqMidForMeta = {};
15782
16010
  const trackEqHighForMeta = {};
16011
+ const trackPanForMeta = {};
16012
+ const trackDelaySendForMeta = {};
15783
16013
  trackStates.forEach((t, i2) => {
15784
16014
  if (t.trackInstrument) trackInstrumentsForMeta[i2] = t.trackInstrument;
15785
16015
  if (t.trackCompression !== 0)
@@ -15790,6 +16020,8 @@ var mountDAW = (target, options = {}) => {
15790
16020
  if (t.trackEqLow !== 0) trackEqLowForMeta[i2] = t.trackEqLow;
15791
16021
  if (t.trackEqMid !== 0) trackEqMidForMeta[i2] = t.trackEqMid;
15792
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;
15793
16025
  });
15794
16026
  const trackInstMeta = Object.keys(trackInstrumentsForMeta).length > 0 ? trackInstrumentsForMeta : void 0;
15795
16027
  const trackCompMeta = Object.keys(trackCompressionForMeta).length > 0 ? trackCompressionForMeta : void 0;
@@ -15798,6 +16030,8 @@ var mountDAW = (target, options = {}) => {
15798
16030
  const trackEqLowMeta = Object.keys(trackEqLowForMeta).length > 0 ? trackEqLowForMeta : void 0;
15799
16031
  const trackEqMidMeta = Object.keys(trackEqMidForMeta).length > 0 ? trackEqMidForMeta : void 0;
15800
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;
15801
16035
  const metaLineFull = formatMmlMeta(
15802
16036
  {
15803
16037
  instrument: currentInstrument || void 0,
@@ -15809,6 +16043,7 @@ var mountDAW = (target, options = {}) => {
15809
16043
  reverbPreDelay,
15810
16044
  delay: delayAmount,
15811
16045
  delayDivision,
16046
+ masterCompression,
15812
16047
  fadeIn: Math.round(fadeInSec * 10),
15813
16048
  fadeOut: Math.round(fadeOutSec * 10),
15814
16049
  mode,
@@ -15818,7 +16053,9 @@ var mountDAW = (target, options = {}) => {
15818
16053
  trackReverbSend: trackReverbSendMeta,
15819
16054
  trackEqLow: trackEqLowMeta,
15820
16055
  trackEqMid: trackEqMidMeta,
15821
- trackEqHigh: trackEqHighMeta
16056
+ trackEqHigh: trackEqHighMeta,
16057
+ trackPan: trackPanMeta,
16058
+ trackDelaySend: trackDelaySendMeta
15822
16059
  },
15823
16060
  " "
15824
16061
  );
@@ -15833,6 +16070,7 @@ var mountDAW = (target, options = {}) => {
15833
16070
  reverbPreDelay,
15834
16071
  delay: delayAmount,
15835
16072
  delayDivision,
16073
+ masterCompression,
15836
16074
  fadeIn: Math.round(fadeInSec * 10),
15837
16075
  fadeOut: Math.round(fadeOutSec * 10),
15838
16076
  mode,
@@ -15842,7 +16080,9 @@ var mountDAW = (target, options = {}) => {
15842
16080
  trackReverbSend: trackReverbSendMeta,
15843
16081
  trackEqLow: trackEqLowMeta,
15844
16082
  trackEqMid: trackEqMidMeta,
15845
- trackEqHigh: trackEqHighMeta
16083
+ trackEqHigh: trackEqHighMeta,
16084
+ trackPan: trackPanMeta,
16085
+ trackDelaySend: trackDelaySendMeta
15846
16086
  },
15847
16087
  ""
15848
16088
  );
@@ -16080,6 +16320,12 @@ var mountDAW = (target, options = {}) => {
16080
16320
  refs.delayDivision.value = delayDivision;
16081
16321
  options.onDelayDivisionChange?.(delayDivision);
16082
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
+ }
16083
16329
  if (meta.fadeIn !== void 0) {
16084
16330
  fadeInSec = meta.fadeIn / 10;
16085
16331
  refs.fadeIn.value = String(fadeInSec);
@@ -16131,6 +16377,16 @@ var mountDAW = (target, options = {}) => {
16131
16377
  t.trackEqHigh = eqHigh;
16132
16378
  options.onTrackEqHighChange?.(t.config.id, eqHigh);
16133
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
+ }
16134
16390
  });
16135
16391
  trackStates.forEach((t, i2) => {
16136
16392
  if (applyActiveOnly && i2 !== activeTrackIndex) return;
@@ -16508,6 +16764,14 @@ var mountDAW = (target, options = {}) => {
16508
16764
  refs.masterVolumeLabel.textContent = `${masterVolume}%`;
16509
16765
  options.singingVoices?.setVolume(masterVolume / 100);
16510
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
+ });
16511
16775
  refs.reverbAmount.addEventListener("input", () => {
16512
16776
  reverbAmount = Number.parseInt(refs.reverbAmount.value, 10) || 0;
16513
16777
  refs.reverbAmountLabel.textContent = `${reverbAmount}%`;
@@ -16557,10 +16821,31 @@ var mountDAW = (target, options = {}) => {
16557
16821
  showModal("\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0\u89E3\u8AAC", AUTO_MASTER_INFO_HTML);
16558
16822
  });
16559
16823
  refs.autoMasterBtn.addEventListener("click", () => {
16560
- reverbAmount = 20;
16561
- refs.reverbAmount.value = "20";
16562
- refs.reverbAmountLabel.textContent = "20%";
16563
- 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);
16564
16849
  const bpmT = clamp5((bpm - 60) / (180 - 60), 0, 1);
16565
16850
  reverbDecay = clamp5(
16566
16851
  3 - bpmT * (3 - 0.9),
@@ -16574,6 +16859,11 @@ var mountDAW = (target, options = {}) => {
16574
16859
  refs.reverbPreDelay.value = "20";
16575
16860
  refs.reverbPreDelayLabel.textContent = "20ms";
16576
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
+ }
16577
16867
  let mainVocalId = null;
16578
16868
  let mainVocalScore = -1;
16579
16869
  for (const t of trackStates) {
@@ -16585,29 +16875,64 @@ var mountDAW = (target, options = {}) => {
16585
16875
  }
16586
16876
  }
16587
16877
  const autoPreset = INSTRUMENT_PRESETS[currentInstrument] ?? INSTRUMENT_PRESETS.piano;
16878
+ const roleByTrackId = /* @__PURE__ */ new Map();
16588
16879
  for (const t of trackStates) {
16589
16880
  if (t.lyricModel) continue;
16590
16881
  const notes = t.core.getNotes();
16591
16882
  if (notes.length === 0) continue;
16592
- const role = classifyTrackRole(notes);
16883
+ const stats = computeAutoRoleStats(notes);
16884
+ const role = classifyTrackRole(stats);
16885
+ roleByTrackId.set(t.config.id, role);
16593
16886
  const instName = autoPreset[role];
16594
16887
  t.trackInstrument = instName;
16595
16888
  const trackIndex = trackStates.indexOf(t);
16596
16889
  options.onTrackInstrumentChange?.(trackIndex, instName);
16597
- const vol = AUTO_ROLE_VOLUME[role];
16890
+ const vol = computeAutoRoleVolume(role, stats);
16598
16891
  t.volume = vol;
16599
16892
  t.core.setVolume(vol);
16600
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;
16601
16902
  for (const t of trackStates) {
16602
16903
  const isMainVocal = !!t.lyricModel && t.config.id === mainVocalId;
16603
- 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;
16604
16919
  t.trackCompression = comp;
16605
- t.trackWidth = 115;
16920
+ t.trackWidth = width;
16606
16921
  options.onTrackCompressionChange?.(t.config.id, comp);
16607
- options.onTrackWidthChange?.(t.config.id, 115);
16922
+ options.onTrackWidthChange?.(t.config.id, width);
16608
16923
  if (!t.lyricModel) {
16609
- t.trackReverbSend = 15;
16610
- 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);
16611
16936
  }
16612
16937
  if (t.lyricModel) {
16613
16938
  t.vocalVibrato = true;
@@ -17697,6 +18022,7 @@ var mountDAW = (target, options = {}) => {
17697
18022
  sequencer.stop();
17698
18023
  options.singingVoices?.stopStream();
17699
18024
  unsubscribeClip?.();
18025
+ stopPeakSampling();
17700
18026
  resizeObserver.disconnect();
17701
18027
  document.removeEventListener("pointermove", onPointerMove);
17702
18028
  document.removeEventListener("pointerup", onPointerUp);
@@ -18654,13 +18980,39 @@ var createDtmStudio = async (options = {}) => {
18654
18980
  division: options.delayDivision ?? "8"
18655
18981
  });
18656
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);
18657
19009
  const safetyLimiter = audioCtx.createDynamicsCompressor();
18658
19010
  safetyLimiter.threshold.value = -1;
18659
19011
  safetyLimiter.knee.value = 0;
18660
19012
  safetyLimiter.ratio.value = 20;
18661
19013
  safetyLimiter.attack.value = 1e-3;
18662
19014
  safetyLimiter.release.value = 0.1;
18663
- finalMix.connect(safetyLimiter);
19015
+ glueMakeup.connect(safetyLimiter);
18664
19016
  const fadeGain = audioCtx.createGain();
18665
19017
  fadeGain.gain.value = 1;
18666
19018
  safetyLimiter.connect(fadeGain);
@@ -18683,13 +19035,14 @@ var createDtmStudio = async (options = {}) => {
18683
19035
  fadeGain.gain.linearRampToValueAtTime(0, fadeOutEndAt);
18684
19036
  }
18685
19037
  };
18686
- const clipMeter = createClipMeter(audioCtx, finalMix);
19038
+ const clipMeter = createClipMeter(audioCtx, glueMakeup);
18687
19039
  const channelStrips = /* @__PURE__ */ new Map();
18688
19040
  const getChannelStrip = (trackId) => {
18689
19041
  let strip = channelStrips.get(trackId);
18690
19042
  if (!strip) {
18691
19043
  strip = createChannelStrip(audioCtx, masterGain, {
18692
- reverbBus: reverbPreDelay
19044
+ reverbBus: reverbPreDelay,
19045
+ delayBus: delayBus.input
18693
19046
  });
18694
19047
  channelStrips.set(trackId, strip);
18695
19048
  }
@@ -19020,6 +19373,8 @@ var createDtmStudio = async (options = {}) => {
19020
19373
  onDelayChange: setDelayAmount,
19021
19374
  delayDivision: options.delayDivision,
19022
19375
  onDelayDivisionChange: (division) => delayBus.setDivision(division),
19376
+ masterCompression: options.masterCompression,
19377
+ onMasterCompressionChange: setMasterCompression,
19023
19378
  onBpmChange: (bpm) => delayBus.setBpm(bpm),
19024
19379
  fadeInSec: options.fadeInSec,
19025
19380
  fadeOutSec: options.fadeOutSec,
@@ -19027,9 +19382,11 @@ var createDtmStudio = async (options = {}) => {
19027
19382
  onTrackCompressionChange: (trackId, amount) => getChannelStrip(trackId).setCompression(amount),
19028
19383
  onTrackWidthChange: (trackId, width) => getChannelStrip(trackId).setWidth(width),
19029
19384
  onTrackReverbSendChange: (trackId, amount) => getChannelStrip(trackId).setReverbSend(amount),
19385
+ onTrackDelaySendChange: (trackId, amount) => getChannelStrip(trackId).setDelaySend(amount),
19030
19386
  onTrackEqLowChange: (trackId, db) => getChannelStrip(trackId).setEqLow(db),
19031
19387
  onTrackEqMidChange: (trackId, db) => getChannelStrip(trackId).setEqMid(db),
19032
19388
  onTrackEqHighChange: (trackId, db) => getChannelStrip(trackId).setEqHigh(db),
19389
+ onTrackPanChange: (trackId, pan) => getChannelStrip(trackId).setPan(panToStereo(pan)),
19033
19390
  clipMeter,
19034
19391
  ...dawOverrides,
19035
19392
  // dawOverrides で上書きされないよう、スプレッドの後に配置して合成する
@@ -19611,6 +19968,7 @@ var createDtmStudio = async (options = {}) => {
19611
19968
  setReverbDecay,
19612
19969
  setReverbPreDelay,
19613
19970
  setDelayAmount,
19971
+ setMasterCompression,
19614
19972
  dispose
19615
19973
  };
19616
19974
  };