@onjmin/dtm 0.1.90 → 0.1.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2285,6 +2285,15 @@ var vibratoPitchCurve = (baseHz, preMs) => (tMs) => {
2285
2285
  return baseHz * 2 ** (cents / 1200);
2286
2286
  };
2287
2287
 
2288
+ // src/voice-worker-types.ts
2289
+ var COMPOSITE_ALIAS_SEP = "\0";
2290
+ var packCompositeAlias = (consonantAlias, vowelAlias) => `${COMPOSITE_ALIAS_SEP}${consonantAlias}${COMPOSITE_ALIAS_SEP}${vowelAlias}`;
2291
+ var unpackCompositeAlias = (alias) => {
2292
+ if (!alias.startsWith(COMPOSITE_ALIAS_SEP)) return null;
2293
+ const parts = alias.slice(COMPOSITE_ALIAS_SEP.length).split(COMPOSITE_ALIAS_SEP);
2294
+ return parts.length === 2 ? [parts[0], parts[1]] : null;
2295
+ };
2296
+
2288
2297
  // src/lyrics.ts
2289
2298
  var kanaTable = {
2290
2299
  \u3042: ["", "a"],
@@ -2463,9 +2472,10 @@ var parseLyrics = (mml) => {
2463
2472
  let delay = 0;
2464
2473
  let gender = 50;
2465
2474
  let breathiness = 50;
2475
+ let tension = 50;
2466
2476
  let octaveUnison = "none";
2467
2477
  const modelMatch = rest.match(
2468
- /^([a-z_][a-z0-9_]*?)(?=(?:[vqpobrghew]-?\d)|[^a-z0-9_]|$)(?::(\d+))?/i
2478
+ /^([a-z_][a-z0-9_]*?)(?=(?:[vqpobrghewt]-?\d)|[^a-z0-9_]|$)(?::(\d+))?/i
2469
2479
  );
2470
2480
  let model = "";
2471
2481
  const metaTokens = [];
@@ -2534,6 +2544,13 @@ var parseLyrics = (mml) => {
2534
2544
  rest = rest.substring(hMatch[0].length).trim();
2535
2545
  continue;
2536
2546
  }
2547
+ const tMatch = rest.match(/^t(\d+)/i);
2548
+ if (tMatch) {
2549
+ tension = clamp2(Number.parseInt(tMatch[1], 10), 0, 100);
2550
+ metaTokens.push(tMatch[0]);
2551
+ rest = rest.substring(tMatch[0].length).trim();
2552
+ continue;
2553
+ }
2537
2554
  const eMatch = rest.match(/^e(\d+)/i);
2538
2555
  if (eMatch) {
2539
2556
  delay = clamp2(Number.parseInt(eMatch[1], 10), 0, 100);
@@ -2567,6 +2584,7 @@ var parseLyrics = (mml) => {
2567
2584
  delay,
2568
2585
  gender,
2569
2586
  breathiness,
2587
+ tension,
2570
2588
  octaveUnison,
2571
2589
  syllables,
2572
2590
  metaText: metaTokens.join(" "),
@@ -2888,8 +2906,33 @@ var resolveKoeAlias = (hasAlias, pitchTokens, syl, prevVowel, noteNum) => {
2888
2906
  const hit = tryAlias(base);
2889
2907
  if (hit) return hit;
2890
2908
  }
2909
+ if (cons && vow) {
2910
+ const vowelAlias = tryAlias(vow) ?? tryAlias(`${pv} ${vow}`);
2911
+ const consAlias = vowelAlias ? tryAlias(cons) : null;
2912
+ if (vowelAlias && consAlias)
2913
+ return packCompositeAlias(consAlias, vowelAlias);
2914
+ }
2891
2915
  return null;
2892
2916
  };
2917
+ var COMPOSITE_SPLICE_XFADE_SEC = 5e-3;
2918
+ var spliceCompositePcm = (consonantPcm, vowelPcm, sampleRate) => {
2919
+ if (consonantPcm.length === 0 || vowelPcm.length === 0) return null;
2920
+ const xfade = Math.min(
2921
+ Math.floor(sampleRate * COMPOSITE_SPLICE_XFADE_SEC),
2922
+ consonantPcm.length,
2923
+ vowelPcm.length
2924
+ );
2925
+ const pcm = new Float64Array(consonantPcm.length + vowelPcm.length - xfade);
2926
+ pcm.set(consonantPcm, 0);
2927
+ for (let i2 = 0; i2 < xfade; i2++) {
2928
+ const t = (i2 + 1) / (xfade + 1);
2929
+ const idx = consonantPcm.length - xfade + i2;
2930
+ pcm[idx] = consonantPcm[idx] * (1 - t) + vowelPcm[i2] * t;
2931
+ }
2932
+ pcm.set(vowelPcm.subarray(xfade), consonantPcm.length);
2933
+ const consonantMs = (consonantPcm.length - xfade / 2) / sampleRate * 1e3;
2934
+ return { pcm, preMs: consonantMs, consonantMs };
2935
+ };
2893
2936
  var createLocalBackend = async (options) => {
2894
2937
  const bank = await VoiceBank.load(options.koe);
2895
2938
  const worldline = options.lightweight ? null : await Worldline.load({
@@ -2904,7 +2947,40 @@ var createLocalBackend = async (options) => {
2904
2947
  }
2905
2948
  return p;
2906
2949
  };
2950
+ const renderComposite = async (consonantAlias, vowelAlias, pitch, durationMs, vibrato, expr) => {
2951
+ if (!worldline) return null;
2952
+ const [consonantPcm, vowelPcm] = await Promise.all([
2953
+ getPcm(consonantAlias),
2954
+ getPcm(vowelAlias)
2955
+ ]);
2956
+ if (!consonantPcm || !vowelPcm) return null;
2957
+ const spliced = spliceCompositePcm(consonantPcm, vowelPcm, KOE_SAMPLE_RATE);
2958
+ if (!spliced) return null;
2959
+ const targetHz = midiToFreq(pitch);
2960
+ const audio = worldline.renderNote({
2961
+ pcm: spliced.pcm,
2962
+ pitch: vibrato ? vibratoPitchCurve(targetHz, spliced.preMs) : targetHz,
2963
+ durationMs,
2964
+ preMs: spliced.preMs,
2965
+ consonantMs: spliced.consonantMs,
2966
+ gender: expr?.gender,
2967
+ breathiness: expr?.breathiness,
2968
+ tension: expr?.tension
2969
+ });
2970
+ return audio ? { pcm: audio, preSec: spliced.preMs / 1e3, rate: 1 } : null;
2971
+ };
2907
2972
  const renderAlias = async (alias, pitch, durationMs, vibrato, expr) => {
2973
+ const composite = unpackCompositeAlias(alias);
2974
+ if (composite) {
2975
+ return renderComposite(
2976
+ composite[0],
2977
+ composite[1],
2978
+ pitch,
2979
+ durationMs,
2980
+ vibrato,
2981
+ expr
2982
+ );
2983
+ }
2908
2984
  const pcm = await getPcm(alias);
2909
2985
  if (!pcm || pcm.length === 0) return null;
2910
2986
  const entry = bank.manifest.phonemes[alias];
@@ -2917,7 +2993,8 @@ var createLocalBackend = async (options) => {
2917
2993
  durationMs,
2918
2994
  ...lead,
2919
2995
  gender: expr?.gender,
2920
- breathiness: expr?.breathiness
2996
+ breathiness: expr?.breathiness,
2997
+ tension: expr?.tension
2921
2998
  });
2922
2999
  if (audio) return { pcm: audio, preSec: lead.preMs / 1e3, rate: 1 };
2923
3000
  }
@@ -2998,7 +3075,8 @@ var createWorkerBackend = async (workerUrl, options) => {
2998
3075
  durationMs,
2999
3076
  vibrato,
3000
3077
  gender: expr?.gender,
3001
- breathiness: expr?.breathiness
3078
+ breathiness: expr?.breathiness,
3079
+ tension: expr?.tension
3002
3080
  });
3003
3081
  });
3004
3082
  return {
@@ -3027,7 +3105,7 @@ var createKoeVoice = async (ctx, destination, options) => {
3027
3105
  const inflight = /* @__PURE__ */ new Map();
3028
3106
  const active = /* @__PURE__ */ new Set();
3029
3107
  let prevVowel = "";
3030
- const keyOf = (alias, pitch, durationMs, vibrato, expr) => `${alias}|${pitch}|${Math.round(durationMs / 10) * 10}${vibrato ? "|vib" : ""}${expr?.gender !== void 0 ? `|g${Math.round(expr.gender * 100)}` : ""}${expr?.breathiness !== void 0 ? `|h${Math.round(expr.breathiness * 100)}` : ""}`;
3108
+ const keyOf = (alias, pitch, durationMs, vibrato, expr) => `${alias}|${pitch}|${Math.round(durationMs / 10) * 10}${vibrato ? "|vib" : ""}${expr?.gender !== void 0 ? `|g${Math.round(expr.gender * 100)}` : ""}${expr?.breathiness !== void 0 ? `|h${Math.round(expr.breathiness * 100)}` : ""}${expr?.tension !== void 0 ? `|t${Math.round(expr.tension * 100)}` : ""}`;
3031
3109
  const renderInto = (alias, pitch, durationMs, vibrato, expr) => {
3032
3110
  const key = keyOf(alias, pitch, durationMs, vibrato, expr);
3033
3111
  const existing = renderCache.get(key);
@@ -3258,7 +3336,8 @@ var createSingingVoices = (ctx, destination, options = {}) => {
3258
3336
  let n = 0;
3259
3337
  const expr = {
3260
3338
  gender: track.gender,
3261
- breathiness: track.breathiness
3339
+ breathiness: track.breathiness,
3340
+ tension: track.tension
3262
3341
  };
3263
3342
  forEachSungNote(track, (note, prevVowel) => {
3264
3343
  if (n >= count && note.startSec >= STREAM_LOOKAHEAD_SEC) return;
@@ -3345,7 +3424,11 @@ var createSingingVoices = (ctx, destination, options = {}) => {
3345
3424
  pitch,
3346
3425
  note.durationSec * 1e3,
3347
3426
  track.vibrato,
3348
- { gender: track.gender, breathiness: track.breathiness }
3427
+ {
3428
+ gender: track.gender,
3429
+ breathiness: track.breathiness,
3430
+ tension: track.tension
3431
+ }
3349
3432
  );
3350
3433
  if (session !== streamSession) return;
3351
3434
  if (key) {
@@ -8036,14 +8119,33 @@ var DAW_CSS = `
8036
8119
  border-right: 2px solid var(--c-black);
8037
8120
  border-bottom: 2px solid var(--c-black);
8038
8121
  }
8122
+ /* \u30A2\u30A4\u30B3\u30F3\u304C\u753B\u9762\u4E0A\u7AEF\u306B\u8FD1\u304F\u4E0A\u306B\u51FA\u3059\u4F59\u767D\u304C\u7121\u3044\u5834\u5408\u306F\u4E0B\u306B\u53CD\u8EE2\u8868\u793A\u3059\u308B\uFF08positionBalloon \u304C\u4ED8\u4E0E\uFF09 */
8123
+ .dtm-player-balloon--below {
8124
+ transform: translate(-50%, 0);
8125
+ }
8126
+ .dtm-player-balloon--below::after {
8127
+ bottom: auto;
8128
+ top: -6px;
8129
+ border-right: none;
8130
+ border-bottom: none;
8131
+ border-left: 2px solid var(--c-black);
8132
+ border-top: 2px solid var(--c-black);
8133
+ }
8039
8134
  .dtm-player-balloon--visible {
8040
8135
  display: block;
8041
8136
  animation: dtm-balloon-fade-in 0.1s steps(2);
8042
8137
  }
8138
+ .dtm-player-balloon--below.dtm-player-balloon--visible {
8139
+ animation-name: dtm-balloon-fade-in-below;
8140
+ }
8043
8141
  @keyframes dtm-balloon-fade-in {
8044
8142
  from { opacity: 0; transform: translate(-50%, -100%) translateY(4px); }
8045
8143
  to { opacity: 1; transform: translate(-50%, -100%) translateY(0); }
8046
8144
  }
8145
+ @keyframes dtm-balloon-fade-in-below {
8146
+ from { opacity: 0; transform: translate(-50%, 0) translateY(-4px); }
8147
+ to { opacity: 1; transform: translate(-50%, 0) translateY(0); }
8148
+ }
8047
8149
  @keyframes dtm-emoji-jump {
8048
8150
  0% { transform: translateY(0); }
8049
8151
  35% { transform: translateY(-5px); }
@@ -8469,9 +8571,17 @@ var balloonAnchors = /* @__PURE__ */ new WeakMap();
8469
8571
  var positionBalloon = (balloonEl) => {
8470
8572
  const anchor = balloonAnchors.get(balloonEl);
8471
8573
  if (!anchor) return;
8574
+ const win = balloonEl.ownerDocument?.defaultView ?? window;
8472
8575
  const rect = anchor.getBoundingClientRect();
8473
- balloonEl.style.left = `${rect.left + rect.width / 2}px`;
8474
- balloonEl.style.top = `${rect.top - 6}px`;
8576
+ const centerX = rect.left + rect.width / 2;
8577
+ const balloonRect = balloonEl.getBoundingClientRect();
8578
+ const showBelow = rect.top - balloonRect.height - 6 < 0;
8579
+ balloonEl.classList.toggle("dtm-player-balloon--below", showBelow);
8580
+ balloonEl.style.top = showBelow ? `${rect.bottom + 6}px` : `${rect.top - 6}px`;
8581
+ const halfWidth = balloonRect.width / 2 || 40;
8582
+ const minX = halfWidth + 4;
8583
+ const maxX = win.innerWidth - halfWidth - 4;
8584
+ balloonEl.style.left = `${Math.min(Math.max(centerX, minX), maxX)}px`;
8475
8585
  };
8476
8586
  var balloonListenersBound = false;
8477
8587
  var ensureBalloonListeners = () => {
@@ -8497,6 +8607,7 @@ var hideActiveBalloon = () => {
8497
8607
  }
8498
8608
  };
8499
8609
  var showBalloon = (balloonEl) => {
8610
+ balloonEl.classList.add("dtm-player-balloon--visible");
8500
8611
  positionBalloon(balloonEl);
8501
8612
  if (activeBalloonEl === balloonEl) {
8502
8613
  if (activeBalloonTimer) {
@@ -8505,7 +8616,6 @@ var showBalloon = (balloonEl) => {
8505
8616
  } else {
8506
8617
  hideActiveBalloon();
8507
8618
  activeBalloonEl = balloonEl;
8508
- balloonEl.classList.add("dtm-player-balloon--visible");
8509
8619
  }
8510
8620
  activeBalloonTimer = setTimeout(() => {
8511
8621
  hideActiveBalloon();
@@ -8807,10 +8917,6 @@ var mountMmlPlayer = (target, mml, options = {}) => {
8807
8917
  const textSpan = doc.createElement("span");
8808
8918
  textSpan.textContent = "\u{1F97A}";
8809
8919
  em.appendChild(textSpan);
8810
- em.addEventListener("click", (e) => {
8811
- e.stopPropagation();
8812
- toggleMute(index);
8813
- });
8814
8920
  mmlHeader.appendChild(em);
8815
8921
  emojiEls.push(em);
8816
8922
  emojiByTrack.set(index, em);
@@ -9572,6 +9678,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
9572
9678
  delaySend: (lt.delay ?? 0) / 100,
9573
9679
  gender: (lt.gender ?? 50) / 100,
9574
9680
  breathiness: (lt.breathiness ?? 50) / 100,
9681
+ tension: (lt.tension ?? 50) / 100,
9575
9682
  octaveUnison: lt.octaveUnison,
9576
9683
  notes
9577
9684
  };
@@ -13422,6 +13529,16 @@ var BREATHINESS_INFO_HTML = `
13422
13529
  <p>\u81EA\u52D5\u30D3\u30D6\u30E9\u30FC\u30C8\u3068\u7D44\u307F\u5408\u308F\u305B\u308B\u3068\u3001\u63FA\u308C\u306A\u304C\u3089\u606F\u3063\u307D\u3044\u3001\u3088\u308A\u30A8\u30E2\u30FC\u30B7\u30E7\u30CA\u30EB\u306A\u8868\u73FE\u306B\u306A\u308A\u3084\u3059\u3044\u3067\u3059\u3002koe\u97F3\u6E90\uFF08UTAU\u7531\u6765\u306E.koe\u97F3\u6E90\uFF09\u9650\u5B9A\u306E\u52B9\u679C\u3067\u3001klatt\uFF08\u5185\u8535\u306E\u7C21\u6613\u5408\u6210\uFF09\u3067\u306F\u5909\u5316\u3057\u307E\u305B\u3093\u3002</p>
13423
13530
  </div>
13424
13531
  `;
13532
+ var TENSION_INFO_HTML = `
13533
+ <div class="dtm-modal-body-content">
13534
+ <h4>\u4F55\u3092\u3059\u308B\u8A2D\u5B9A\u304B</h4>
13535
+ <p>\u58F0\u306E\u5F35\u308A\uFF0F\u62BC\u3057\u51FA\u3057\u306E\u5F37\u3055\u3067\u3059\u300250\u304C\u7121\u5909\u5316\u3001\u5927\u304D\u3044\u307B\u3069\u5F35\u3063\u305F\u30FB\u62BC\u3057\u305F\u58F0\uFF08\u300C\u3053\u3076\u3057\u300D\u5BC4\u308A\u3001\u529B\u5F37\u304F\u6B4C\u308F\u305B\u308B\uFF09\u306B\u306A\u308A\u3001\u5C0F\u3055\u3044\u307B\u3069\u8131\u529B\u3057\u305F\u30EA\u30E9\u30C3\u30AF\u30B9\u3057\u305F\u58F0\u306B\u306A\u308A\u307E\u3059\u3002</p>
13536
+ <h4>\u30D6\u30EC\u30B7\u30CD\u30B9\u3068\u306E\u9055\u3044</h4>
13537
+ <p>\u30D6\u30EC\u30B7\u30CD\u30B9\u306F\u606F\u6210\u5206\u306E\u91CF\uFF08\u82AF\u306E\u3042\u308B\u58F0\u21D4\u606F\u3063\u307D\u3044\u58F0\uFF09\u3092\u52D5\u304B\u3057\u307E\u3059\u304C\u3001\u30C6\u30F3\u30B7\u30E7\u30F3\u306F\u58F0\u5E2F\u306E\u7DE0\u307E\u308A\u30FB\u62BC\u3057\u306E\u5F37\u3055\uFF08\u8131\u529B\u21D4\u5F35\u3063\u305F\u58F0\uFF09\u3092\u52D5\u304B\u3057\u307E\u3059\u3002\u30C6\u30F3\u30B7\u30E7\u30F3\u3092\u4E0A\u3052\u308B\u3068\u30B5\u30D3\u306E\u529B\u5F37\u3055\u3001\u4E0B\u3052\u308B\u3068\u7A4F\u3084\u304B\u306A\u56C1\u304D\u306B\u5BC4\u305B\u305F\u6B4C\u308F\u305B\u65B9\u306B\u306A\u308A\u307E\u3059\u3002</p>
13538
+ <h4>\u4ED6\u306E\u8A2D\u5B9A\u3068\u306E\u517C\u306D\u5408\u3044</h4>
13539
+ <p>\u30D6\u30EC\u30B7\u30CD\u30B9\u3092\u4E0B\u3052\u3064\u3064\u30C6\u30F3\u30B7\u30E7\u30F3\u3092\u4E0A\u3052\u308B\u3068\u3001\u3088\u308A\u82AF\u304C\u3042\u308A\u529B\u5F37\u3044\u6B4C\u58F0\u306B\u306A\u308A\u307E\u3059\u3002\u9006\u306B\u30D6\u30EC\u30B7\u30CD\u30B9\u3092\u4E0A\u3052\u3064\u3064\u30C6\u30F3\u30B7\u30E7\u30F3\u3092\u4E0B\u3052\u308B\u3068\u3001\u3088\u308A\u8131\u529B\u3057\u305F\u606F\u3063\u307D\u3044\u6B4C\u58F0\u306B\u306A\u308A\u307E\u3059\u3002koe\u97F3\u6E90\uFF08UTAU\u7531\u6765\u306E.koe\u97F3\u6E90\uFF09\u9650\u5B9A\u306E\u52B9\u679C\u3067\u3001klatt\uFF08\u5185\u8535\u306E\u7C21\u6613\u5408\u6210\uFF09\u3067\u306F\u5909\u5316\u3057\u307E\u305B\u3093\u3002</p>
13540
+ </div>
13541
+ `;
13425
13542
  var LYRIC_REVERB_INFO_HTML = `
13426
13543
  <div class="dtm-modal-body-content">
13427
13544
  <h4>\u4F55\u3092\u3059\u308B\u8A2D\u5B9A\u304B</h4>
@@ -13946,6 +14063,7 @@ var mountDAW = (target, options = {}) => {
13946
14063
  vocalDelay: t.vocalDelay,
13947
14064
  vocalGender: t.vocalGender,
13948
14065
  vocalBreathiness: t.vocalBreathiness,
14066
+ vocalTension: t.vocalTension,
13949
14067
  vocalOctaveUnison: t.vocalOctaveUnison
13950
14068
  };
13951
14069
  if (lyricsDebounceTimer) clearTimeout(lyricsDebounceTimer);
@@ -14011,6 +14129,7 @@ var mountDAW = (target, options = {}) => {
14011
14129
  vocalDelay: 0,
14012
14130
  vocalGender: 50,
14013
14131
  vocalBreathiness: 50,
14132
+ vocalTension: 50,
14014
14133
  vocalOctaveUnison: "none",
14015
14134
  trackInstrument: "",
14016
14135
  trackCompression: 0,
@@ -14042,6 +14161,7 @@ var mountDAW = (target, options = {}) => {
14042
14161
  delay: t.vocalDelay,
14043
14162
  gender: t.vocalGender,
14044
14163
  breathiness: t.vocalBreathiness,
14164
+ tension: t.vocalTension,
14045
14165
  octaveUnison: t.vocalOctaveUnison,
14046
14166
  syllables
14047
14167
  });
@@ -14852,6 +14972,7 @@ var mountDAW = (target, options = {}) => {
14852
14972
  delaySend: (lt.delay ?? 0) / 100,
14853
14973
  gender: (lt.gender ?? 50) / 100,
14854
14974
  breathiness: (lt.breathiness ?? 50) / 100,
14975
+ tension: (lt.tension ?? 50) / 100,
14855
14976
  octaveUnison: lt.octaveUnison,
14856
14977
  notes
14857
14978
  };
@@ -15280,6 +15401,12 @@ var mountDAW = (target, options = {}) => {
15280
15401
  <span class="dtm-label" data-dtm="lyric-breathiness-label"></span>
15281
15402
  <button class="dtm-infobtn" data-dtm="lyric-breathiness-info" title="\u30D6\u30EC\u30B7\u30CD\u30B9\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15282
15403
  </div>
15404
+ <div class="dtm-row">
15405
+ <span class="dtm-label">\u30C6\u30F3\u30B7\u30E7\u30F3</span>
15406
+ <input type="range" class="dtm-range dtm-grow" data-dtm="lyric-tension" min="0" max="100" aria-label="\u30C6\u30F3\u30B7\u30E7\u30F3\uFF08\u5F35\u308A/\u529B\u5F37\u3055\u3001koe\u97F3\u6E90\u9650\u5B9A\uFF09">
15407
+ <span class="dtm-label" data-dtm="lyric-tension-label"></span>
15408
+ <button class="dtm-infobtn" data-dtm="lyric-tension-info" title="\u30C6\u30F3\u30B7\u30E7\u30F3\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
15409
+ </div>
15283
15410
  <div class="dtm-row">
15284
15411
  <span class="dtm-label" style="display:inline-flex;align-items:center;gap:2px">
15285
15412
  <input type="checkbox" data-dtm="lyric-vibrato" aria-label="\u81EA\u52D5\u30D3\u30D6\u30E9\u30FC\u30C8">\u30D3\u30D6\u30E9\u30FC\u30C8
@@ -15383,6 +15510,18 @@ var mountDAW = (target, options = {}) => {
15383
15510
  lyricBreathinessInfo.addEventListener("click", () => {
15384
15511
  showModal("\u30D6\u30EC\u30B7\u30CD\u30B9\u306E\u89E3\u8AAC", BREATHINESS_INFO_HTML);
15385
15512
  });
15513
+ const lyricTension = lyricDiv.querySelector(
15514
+ '[data-dtm="lyric-tension"]'
15515
+ );
15516
+ const lyricTensionLabel = lyricDiv.querySelector(
15517
+ '[data-dtm="lyric-tension-label"]'
15518
+ );
15519
+ const lyricTensionInfo = lyricDiv.querySelector(
15520
+ '[data-dtm="lyric-tension-info"]'
15521
+ );
15522
+ lyricTensionInfo.addEventListener("click", () => {
15523
+ showModal("\u30C6\u30F3\u30B7\u30E7\u30F3\u306E\u89E3\u8AAC", TENSION_INFO_HTML);
15524
+ });
15386
15525
  const lyricVibrato = lyricDiv.querySelector(
15387
15526
  '[data-dtm="lyric-vibrato"]'
15388
15527
  );
@@ -15470,6 +15609,8 @@ var mountDAW = (target, options = {}) => {
15470
15609
  lyricGenderLabel.textContent = `${active.vocalGender}`;
15471
15610
  lyricBreathiness.value = String(active.vocalBreathiness);
15472
15611
  lyricBreathinessLabel.textContent = `${active.vocalBreathiness}`;
15612
+ lyricTension.value = String(active.vocalTension);
15613
+ lyricTensionLabel.textContent = `${active.vocalTension}`;
15473
15614
  lyricVibrato.checked = active.vocalVibrato;
15474
15615
  lyricOctaveUnison.value = active.vocalOctaveUnison;
15475
15616
  const updateLyricCount = () => {
@@ -15640,6 +15781,11 @@ var mountDAW = (target, options = {}) => {
15640
15781
  lyricBreathinessLabel.textContent = `${active.vocalBreathiness}`;
15641
15782
  fireLyricsChange(active);
15642
15783
  });
15784
+ lyricTension.addEventListener("input", () => {
15785
+ active.vocalTension = Number.parseInt(lyricTension.value, 10);
15786
+ lyricTensionLabel.textContent = `${active.vocalTension}`;
15787
+ fireLyricsChange(active);
15788
+ });
15643
15789
  }
15644
15790
  if (active.config.id === "chord" && showChord) {
15645
15791
  const div = document.createElement("div");
@@ -15844,6 +15990,7 @@ var mountDAW = (target, options = {}) => {
15844
15990
  del: t.vocalDelay,
15845
15991
  gen: t.vocalGender,
15846
15992
  bre: t.vocalBreathiness,
15993
+ ten: t.vocalTension,
15847
15994
  uni: t.vocalOctaveUnison
15848
15995
  })).filter(
15849
15996
  (x2) => x2.model.length > 0 && x2.text.length > 0 && x2.notes.length > 0
@@ -15858,6 +16005,7 @@ var mountDAW = (target, options = {}) => {
15858
16005
  x2.del === 0 ? "" : `e${x2.del}`,
15859
16006
  x2.gen === 50 ? "" : `g${x2.gen}`,
15860
16007
  x2.bre === 50 ? "" : `h${x2.bre}`,
16008
+ x2.ten === 50 ? "" : `t${x2.ten}`,
15861
16009
  OCTAVE_UNISON_TOKEN[x2.uni]
15862
16010
  ].filter((s) => s.length > 0).join(" ");
15863
16011
  const head = params ? `${x2.model} ${params}` : x2.model;
@@ -16100,6 +16248,7 @@ var mountDAW = (target, options = {}) => {
16100
16248
  active.vocalDelay = 0;
16101
16249
  active.vocalGender = 50;
16102
16250
  active.vocalBreathiness = 50;
16251
+ active.vocalTension = 50;
16103
16252
  active.vocalOctaveUnison = "none";
16104
16253
  } else {
16105
16254
  for (const t of trackStates) {
@@ -16114,6 +16263,7 @@ var mountDAW = (target, options = {}) => {
16114
16263
  t.vocalDelay = 0;
16115
16264
  t.vocalGender = 50;
16116
16265
  t.vocalBreathiness = 50;
16266
+ t.vocalTension = 50;
16117
16267
  t.vocalOctaveUnison = "none";
16118
16268
  }
16119
16269
  }
@@ -16132,6 +16282,8 @@ var mountDAW = (target, options = {}) => {
16132
16282
  t.vocalDelay = lt.delay ?? 0;
16133
16283
  t.vocalGender = lt.gender ?? 50;
16134
16284
  t.vocalBreathiness = lt.breathiness ?? 50;
16285
+ t.vocalTension = lt.tension ?? 50;
16286
+ t.vocalTension = lt.tension ?? 50;
16135
16287
  t.vocalOctaveUnison = lt.octaveUnison ?? "none";
16136
16288
  });
16137
16289
  for (const p of placements) {
@@ -16216,6 +16368,7 @@ var mountDAW = (target, options = {}) => {
16216
16368
  active.vocalDelay = 0;
16217
16369
  active.vocalGender = 50;
16218
16370
  active.vocalBreathiness = 50;
16371
+ active.vocalTension = 50;
16219
16372
  active.vocalOctaveUnison = "none";
16220
16373
  } else {
16221
16374
  clearAll();
@@ -16232,6 +16385,7 @@ var mountDAW = (target, options = {}) => {
16232
16385
  t.vocalDelay = 0;
16233
16386
  t.vocalGender = 50;
16234
16387
  t.vocalBreathiness = 50;
16388
+ t.vocalTension = 50;
16235
16389
  t.vocalOctaveUnison = "none";
16236
16390
  }
16237
16391
  }
@@ -17596,6 +17750,7 @@ var mountDAW = (target, options = {}) => {
17596
17750
  t.vocalDelay = data.vocalDelay ?? 0;
17597
17751
  t.vocalGender = data.vocalGender ?? 50;
17598
17752
  t.vocalBreathiness = data.vocalBreathiness ?? 50;
17753
+ t.vocalTension = data.vocalTension ?? 50;
17599
17754
  t.vocalOctaveUnison = data.vocalOctaveUnison ?? "none";
17600
17755
  },
17601
17756
  applyTrackInstrument: (trackIndex, instrumentName) => {
@@ -17718,6 +17873,7 @@ var playSingingMML = async (mml, options = {}) => {
17718
17873
  delaySend: (lt.delay ?? 0) / 100,
17719
17874
  gender: (lt.gender ?? 50) / 100,
17720
17875
  breathiness: (lt.breathiness ?? 50) / 100,
17876
+ tension: (lt.tension ?? 50) / 100,
17721
17877
  octaveUnison: lt.octaveUnison,
17722
17878
  notes
17723
17879
  };