@onjmin/dtm 0.1.36 → 0.1.38
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/README.md +43 -0
- package/dist/index.d.mts +56 -2
- package/dist/index.d.ts +56 -2
- package/dist/index.js +481 -175
- package/dist/index.mjs +480 -175
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ __export(index_exports, {
|
|
|
31
31
|
DRUM_FONT: () => DRUM_FONT,
|
|
32
32
|
DRUM_KEYS: () => DRUM_KEYS,
|
|
33
33
|
DRUM_PATTERNS: () => DRUM_PATTERNS,
|
|
34
|
+
GM_INSTRUMENT_NAMES: () => GM_INSTRUMENT_NAMES,
|
|
34
35
|
INSTRUMENT_PRESETS: () => INSTRUMENT_PRESETS,
|
|
35
36
|
KOE_BASE_URL: () => KOE_BASE_URL,
|
|
36
37
|
KOE_VOICEBANKS: () => KOE_VOICEBANKS,
|
|
@@ -256,6 +257,7 @@ async function buildNameToKeyMapping() {
|
|
|
256
257
|
}
|
|
257
258
|
return nameToKey;
|
|
258
259
|
}
|
|
260
|
+
var GM_INSTRUMENT_NAMES = FONT_NAME_SURIKOV.trim().split("\n").map((line) => line.slice(line.indexOf(" ") + 1));
|
|
259
261
|
|
|
260
262
|
// node_modules/.pnpm/@onjmin+chord-parser@1.0.2/node_modules/@onjmin/chord-parser/dist/index.mjs
|
|
261
263
|
var SHARP_NAMES = [
|
|
@@ -1333,14 +1335,17 @@ var buildUI = (target, options) => {
|
|
|
1333
1335
|
target.innerHTML = `
|
|
1334
1336
|
<div class="dtm-daw" data-dtm="root">
|
|
1335
1337
|
<div class="dtm-topbar" data-dtm="transport">
|
|
1336
|
-
<
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1338
|
+
<div class="dtm-topbar-row1">
|
|
1339
|
+
<button class="dtm-iconbtn" data-dtm="prev-bar" title="1\u5C0F\u7BC0\u524D">${icon("chevronLeft")}</button>
|
|
1340
|
+
<button class="dtm-play" data-dtm="play" disabled>${icon("play")}<span>\u8A66\u8074</span></button>
|
|
1341
|
+
<button class="dtm-iconbtn" data-dtm="next-bar" title="1\u5C0F\u7BC0\u5F8C">${icon("chevronRight")}</button>
|
|
1342
|
+
<label class="dtm-toggle"><input type="checkbox" data-dtm="solo"><span>\u30BD\u30ED</span></label>
|
|
1343
|
+
<span class="dtm-topbar-loading dtm-blink" data-dtm="topbar-loading">... LOADING ...</span>
|
|
1344
|
+
<span class="dtm-grow"></span>
|
|
1345
|
+
<span class="dtm-label">BPM</span>
|
|
1346
|
+
<input type="number" class="dtm-input dtm-input--num" data-dtm="bpm" value="${defaultBpm}" min="20" max="300">
|
|
1347
|
+
</div>
|
|
1348
|
+
<div class="dtm-tracks" data-dtm="track-tabs"></div>
|
|
1344
1349
|
</div>
|
|
1345
1350
|
|
|
1346
1351
|
<div class="dtm-tooldock">
|
|
@@ -1363,8 +1368,6 @@ var buildUI = (target, options) => {
|
|
|
1363
1368
|
</select>
|
|
1364
1369
|
</div>
|
|
1365
1370
|
|
|
1366
|
-
<div class="dtm-tracks" data-dtm="track-tabs"></div>
|
|
1367
|
-
|
|
1368
1371
|
<div class="dtm-roll-wrap">
|
|
1369
1372
|
<div class="dtm-roll" data-dtm="roll">
|
|
1370
1373
|
<div data-dtm="wrapper" style="position:absolute;inset:0;"></div>
|
|
@@ -3659,12 +3662,14 @@ var drawKeyboard = () => {
|
|
|
3659
3662
|
const totalPitch = pitchIndex + pitchRangeStart;
|
|
3660
3663
|
const pitchMod12 = totalPitch % 12;
|
|
3661
3664
|
const isBlackKey = blackKeyPitches.has(pitchMod12);
|
|
3665
|
+
const octave = Math.floor(totalPitch / 12) - 1;
|
|
3666
|
+
const isC4Range = octave === 4;
|
|
3662
3667
|
const screenY = y - g_draw_offset_y;
|
|
3663
3668
|
const bkW = Math.floor(KEYBOARD_WIDTH * BK_RATIO);
|
|
3664
3669
|
if (isBlackKey) {
|
|
3665
|
-
g_key_ctx.fillStyle = WHITE_KEY;
|
|
3670
|
+
g_key_ctx.fillStyle = isC4Range ? "#d8d4be" : WHITE_KEY;
|
|
3666
3671
|
g_key_ctx.fillRect(0, screenY, KEYBOARD_WIDTH, keyHeight);
|
|
3667
|
-
g_key_ctx.fillStyle = BLACK_KEY;
|
|
3672
|
+
g_key_ctx.fillStyle = isC4Range ? "#1a1408" : BLACK_KEY;
|
|
3668
3673
|
g_key_ctx.fillRect(0, screenY, bkW, keyHeight);
|
|
3669
3674
|
g_key_ctx.strokeStyle = BK_EDGE;
|
|
3670
3675
|
g_key_ctx.lineWidth = 1;
|
|
@@ -3673,7 +3678,7 @@ var drawKeyboard = () => {
|
|
|
3673
3678
|
g_key_ctx.lineTo(bkW, screenY + keyHeight);
|
|
3674
3679
|
g_key_ctx.stroke();
|
|
3675
3680
|
} else {
|
|
3676
|
-
g_key_ctx.fillStyle = WHITE_KEY;
|
|
3681
|
+
g_key_ctx.fillStyle = isC4Range ? "#dedad0" : WHITE_KEY;
|
|
3677
3682
|
g_key_ctx.fillRect(0, screenY, KEYBOARD_WIDTH, keyHeight);
|
|
3678
3683
|
if (pitchMod12 === 5 || pitchMod12 === 0) {
|
|
3679
3684
|
g_key_ctx.strokeStyle = WW_SEP;
|
|
@@ -3685,13 +3690,13 @@ var drawKeyboard = () => {
|
|
|
3685
3690
|
}
|
|
3686
3691
|
}
|
|
3687
3692
|
if (pitchMod12 === 0) {
|
|
3688
|
-
const
|
|
3693
|
+
const octave2 = Math.floor(totalPitch / 12) - 1;
|
|
3689
3694
|
g_key_ctx.fillStyle = "#555040";
|
|
3690
3695
|
g_key_ctx.font = "10px 'k8x12',monospace";
|
|
3691
3696
|
g_key_ctx.textAlign = "right";
|
|
3692
3697
|
g_key_ctx.textBaseline = "bottom";
|
|
3693
3698
|
g_key_ctx.fillText(
|
|
3694
|
-
`${KEY_NAMES[pitchMod12]}${
|
|
3699
|
+
`${KEY_NAMES[pitchMod12]}${octave2}`,
|
|
3695
3700
|
KEYBOARD_WIDTH - 4,
|
|
3696
3701
|
screenY + keyHeight - 2
|
|
3697
3702
|
);
|
|
@@ -3743,17 +3748,22 @@ var drawGrid = (noteLengthSteps = 1) => {
|
|
|
3743
3748
|
drawKeyboard();
|
|
3744
3749
|
drawHeader();
|
|
3745
3750
|
g_grid_ctx.clearRect(0, 0, g_grid_canvas.width, g_grid_canvas.height);
|
|
3746
|
-
const { keyHeight, keyCount, stepWidth, stepsPerBar } = g_config;
|
|
3751
|
+
const { keyHeight, keyCount, stepWidth, stepsPerBar, pitchRangeStart } = g_config;
|
|
3747
3752
|
const startY = Math.floor(g_draw_offset_y / keyHeight) * keyHeight;
|
|
3748
3753
|
const endY = g_draw_offset_y + g_grid_canvas.height;
|
|
3749
3754
|
for (let y = startY; y < endY; y += keyHeight) {
|
|
3750
3755
|
const pitchIndex = keyCount - 1 - y / keyHeight;
|
|
3756
|
+
const totalPitch = pitchIndex + pitchRangeStart;
|
|
3751
3757
|
const pitchMod12 = pitchIndex % 12;
|
|
3752
3758
|
const isBlackKey = blackKeyPitches.has(pitchMod12);
|
|
3753
3759
|
const isC = pitchMod12 === 0;
|
|
3760
|
+
const octave = Math.floor(totalPitch / 12) - 1;
|
|
3761
|
+
const isC4Range = octave === 4;
|
|
3754
3762
|
const screenY = y - g_draw_offset_y;
|
|
3755
|
-
|
|
3756
|
-
|
|
3763
|
+
g_grid_ctx.fillStyle = isBlackKey ? "#080b16" : "#111628";
|
|
3764
|
+
g_grid_ctx.fillRect(0, screenY, g_grid_canvas.width, keyHeight);
|
|
3765
|
+
if (isC4Range) {
|
|
3766
|
+
g_grid_ctx.fillStyle = "rgba(41,173,255,0.05)";
|
|
3757
3767
|
g_grid_ctx.fillRect(0, screenY, g_grid_canvas.width, keyHeight);
|
|
3758
3768
|
}
|
|
3759
3769
|
g_grid_ctx.beginPath();
|
|
@@ -4395,6 +4405,7 @@ var PITCH_MAP2 = {
|
|
|
4395
4405
|
};
|
|
4396
4406
|
var clamp2 = (value, lo, hi) => Math.min(hi, Math.max(lo, value));
|
|
4397
4407
|
var META_DIRECTIVE = /#(inst|drum|volume|drumvolume|mode)=([\w-]+)/gi;
|
|
4408
|
+
var TRACK_INST_DIRECTIVE = /#t(\d+)inst=([^#;\r\n]+)/gi;
|
|
4398
4409
|
var parseMmlMeta = (mml) => {
|
|
4399
4410
|
const meta = {};
|
|
4400
4411
|
for (const m of mml.matchAll(META_DIRECTIVE)) {
|
|
@@ -4413,9 +4424,17 @@ var parseMmlMeta = (mml) => {
|
|
|
4413
4424
|
}
|
|
4414
4425
|
}
|
|
4415
4426
|
}
|
|
4427
|
+
for (const m of mml.matchAll(TRACK_INST_DIRECTIVE)) {
|
|
4428
|
+
const idx = Number.parseInt(m[1], 10);
|
|
4429
|
+
const name = m[2].trim();
|
|
4430
|
+
if (!Number.isNaN(idx) && name) {
|
|
4431
|
+
meta.trackInstruments ??= {};
|
|
4432
|
+
meta.trackInstruments[idx] = name;
|
|
4433
|
+
}
|
|
4434
|
+
}
|
|
4416
4435
|
return meta;
|
|
4417
4436
|
};
|
|
4418
|
-
var stripMmlMeta = (mml) => mml.replace(META_DIRECTIVE, "");
|
|
4437
|
+
var stripMmlMeta = (mml) => mml.replace(META_DIRECTIVE, "").replace(TRACK_INST_DIRECTIVE, "");
|
|
4419
4438
|
var formatMmlMeta = (meta, space = "") => {
|
|
4420
4439
|
const parts = [];
|
|
4421
4440
|
if (meta.instrument) parts.push(`#inst=${meta.instrument}`);
|
|
@@ -4424,6 +4443,11 @@ var formatMmlMeta = (meta, space = "") => {
|
|
|
4424
4443
|
if (meta.drumVolume !== void 0)
|
|
4425
4444
|
parts.push(`#drumvolume=${meta.drumVolume}`);
|
|
4426
4445
|
if (meta.mode) parts.push(`#mode=${meta.mode}`);
|
|
4446
|
+
if (meta.trackInstruments) {
|
|
4447
|
+
for (const [idx, name] of Object.entries(meta.trackInstruments)) {
|
|
4448
|
+
if (name) parts.push(`#t${idx}inst=${name}`);
|
|
4449
|
+
}
|
|
4450
|
+
}
|
|
4427
4451
|
return parts.join(space);
|
|
4428
4452
|
};
|
|
4429
4453
|
var parseMML = (mml, options = {}) => {
|
|
@@ -5045,7 +5069,7 @@ var DAW_CSS = `
|
|
|
5045
5069
|
top: 0;
|
|
5046
5070
|
z-index: 20;
|
|
5047
5071
|
display: flex;
|
|
5048
|
-
flex-wrap:
|
|
5072
|
+
flex-wrap: wrap;
|
|
5049
5073
|
align-items: center;
|
|
5050
5074
|
gap: var(--dtm-gap);
|
|
5051
5075
|
padding: 6px;
|
|
@@ -5055,18 +5079,19 @@ var DAW_CSS = `
|
|
|
5055
5079
|
inset 0 0 0 2px var(--c-black),
|
|
5056
5080
|
0 0 0 2px var(--dtm-success),
|
|
5057
5081
|
4px 4px 0 var(--c-black);
|
|
5082
|
+
}
|
|
5083
|
+
.dtm-topbar-row1 {
|
|
5084
|
+
display: flex;
|
|
5085
|
+
align-items: center;
|
|
5086
|
+
gap: var(--dtm-gap);
|
|
5087
|
+
flex-basis: 100%;
|
|
5088
|
+
min-width: 0;
|
|
5058
5089
|
overflow-x: auto;
|
|
5059
5090
|
scrollbar-width: none;
|
|
5060
5091
|
}
|
|
5061
|
-
.dtm-topbar::-webkit-scrollbar {
|
|
5062
|
-
|
|
5063
|
-
}
|
|
5064
|
-
.dtm-topbar > * {
|
|
5065
|
-
flex-shrink: 0;
|
|
5066
|
-
}
|
|
5067
|
-
.dtm-topbar > .dtm-grow {
|
|
5068
|
-
flex-shrink: 1;
|
|
5069
|
-
}
|
|
5092
|
+
.dtm-topbar-row1::-webkit-scrollbar { display: none; }
|
|
5093
|
+
.dtm-topbar-row1 > * { flex-shrink: 0; }
|
|
5094
|
+
.dtm-topbar-row1 > .dtm-grow { flex-shrink: 1; }
|
|
5070
5095
|
|
|
5071
5096
|
/* PLAY\u30DC\u30BF\u30F3 \u2014 \u30B2\u30FC\u30E0\u306E\u300C\u6C7A\u5B9A\u30DC\u30BF\u30F3\u300D\u7684\u5B58\u5728\u611F */
|
|
5072
5097
|
.dtm-play {
|
|
@@ -5256,46 +5281,39 @@ var DAW_CSS = `
|
|
|
5256
5281
|
.dtm-modebtn--active { background: var(--dtm-primary); color: var(--dtm-pfg); }
|
|
5257
5282
|
.dtm-modebtn:not(.dtm-modebtn--active):active { background: var(--dtm-border2); }
|
|
5258
5283
|
|
|
5259
|
-
/* \u2500\u2500\u2500 \u30C8\u30E9\u30C3\u30AF\u30D4\u30EB\uFF08\
|
|
5284
|
+
/* \u2500\u2500\u2500 \u30C8\u30E9\u30C3\u30AF\u30D4\u30EB\uFF08\u756A\u53F7\u30DC\u30BF\u30F3\u3001\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u30D0\u30FC2\u884C\u76EE\uFF09 \u2500\u2500\u2500 */
|
|
5260
5285
|
.dtm-tracks {
|
|
5286
|
+
flex-basis: 100%;
|
|
5261
5287
|
display: flex;
|
|
5262
|
-
flex-wrap:
|
|
5263
|
-
gap:
|
|
5288
|
+
flex-wrap: nowrap;
|
|
5289
|
+
gap: 3px;
|
|
5264
5290
|
}
|
|
5265
5291
|
.dtm-pill {
|
|
5266
5292
|
--dtm-pill-color: var(--dtm-primary);
|
|
5267
5293
|
display: inline-flex;
|
|
5268
5294
|
align-items: center;
|
|
5269
|
-
gap: 8px;
|
|
5270
|
-
flex: 1 1 auto;
|
|
5271
5295
|
justify-content: center;
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5296
|
+
flex: 1 1 0;
|
|
5297
|
+
min-width: 0;
|
|
5298
|
+
height: 26px;
|
|
5299
|
+
padding: 0;
|
|
5300
|
+
border: 2px solid var(--c-black);
|
|
5301
|
+
background: color-mix(in srgb, var(--dtm-pill-color) 40%, black);
|
|
5302
|
+
color: var(--c-white);
|
|
5277
5303
|
font-family: var(--dtm-font);
|
|
5278
|
-
font-size:
|
|
5279
|
-
|
|
5280
|
-
letter-spacing: .1em;
|
|
5304
|
+
font-size: 11px;
|
|
5305
|
+
font-weight: bold;
|
|
5281
5306
|
cursor: pointer;
|
|
5282
|
-
box-shadow:
|
|
5283
|
-
|
|
5284
|
-
.dtm-pill .dtm-dot {
|
|
5285
|
-
width: 8px; height: 8px;
|
|
5286
|
-
background: var(--dtm-pill-color);
|
|
5287
|
-
flex: 0 0 auto;
|
|
5288
|
-
box-shadow: 1px 1px 0 var(--c-black);
|
|
5307
|
+
box-shadow: 2px 2px 0 var(--c-black);
|
|
5308
|
+
opacity: 0.7;
|
|
5289
5309
|
}
|
|
5290
|
-
/* \u30A2\u30AF\u30C6\u30A3\u30D6\u9078\u629E = \
|
|
5310
|
+
/* \u30A2\u30AF\u30C6\u30A3\u30D6\u9078\u629E = \u4E0D\u900F\u660E + \u91D1\u67A0 */
|
|
5291
5311
|
.dtm-pill--active {
|
|
5312
|
+
opacity: 1;
|
|
5292
5313
|
border-color: var(--dtm-gold);
|
|
5293
|
-
|
|
5294
|
-
background: var(--dtm-surface);
|
|
5295
|
-
box-shadow: 0 0 0 2px var(--dtm-gold), 3px 3px 0 var(--c-black);
|
|
5314
|
+
box-shadow: 0 0 0 1px var(--dtm-gold), 2px 2px 0 var(--c-black);
|
|
5296
5315
|
}
|
|
5297
|
-
.dtm-pill--active
|
|
5298
|
-
.dtm-pill:not(.dtm-pill--active):active { transform: translate(3px,3px); box-shadow: none; }
|
|
5316
|
+
.dtm-pill:not(.dtm-pill--active):active { transform: translate(2px,2px); box-shadow: none; }
|
|
5299
5317
|
|
|
5300
5318
|
/* \u2500\u2500\u2500 \u30D4\u30A2\u30CE\u30ED\u30FC\u30EB\uFF08\u30C8\u30E9\u30C3\u30AB\u30FC\u98A8\uFF09 \u2500\u2500\u2500 */
|
|
5301
5319
|
.dtm-roll-wrap { display: flex; gap: var(--dtm-gap); }
|
|
@@ -5439,7 +5457,7 @@ var DAW_CSS = `
|
|
|
5439
5457
|
}
|
|
5440
5458
|
.dtm-overlay[hidden] { display: none; }
|
|
5441
5459
|
.dtm-overlay::before {
|
|
5442
|
-
content: '
|
|
5460
|
+
content: '\u30ED\u30FC\u30C9\u4E2D';
|
|
5443
5461
|
font-family: var(--dtm-font);
|
|
5444
5462
|
font-size: 13px;
|
|
5445
5463
|
color: var(--dtm-primary);
|
|
@@ -5632,6 +5650,15 @@ var DAW_CSS = `
|
|
|
5632
5650
|
justify-content: center;
|
|
5633
5651
|
}
|
|
5634
5652
|
|
|
5653
|
+
.dtm-confirm-footer {
|
|
5654
|
+
padding: 8px 12px;
|
|
5655
|
+
border-top: 2px solid var(--c-black);
|
|
5656
|
+
background: var(--dtm-deep);
|
|
5657
|
+
display: flex;
|
|
5658
|
+
gap: 8px;
|
|
5659
|
+
justify-content: flex-end;
|
|
5660
|
+
}
|
|
5661
|
+
|
|
5635
5662
|
.dtm-modal {
|
|
5636
5663
|
max-width: 500px;
|
|
5637
5664
|
width: 100%;
|
|
@@ -6654,9 +6681,11 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6654
6681
|
const mmlInfoItem = makeMenuItem("MML\u66F8\u5F0F\u3068\u306F");
|
|
6655
6682
|
const embedItem = makeMenuItem("\u57CB\u3081\u8FBC\u3080");
|
|
6656
6683
|
const copyMmlItem = makeMenuItem("MML\u30B3\u30D4\u30FC");
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6684
|
+
if (!options._skipInfoModals) {
|
|
6685
|
+
menuDropdown.appendChild(showMmlItem);
|
|
6686
|
+
menuDropdown.appendChild(mmlInfoItem);
|
|
6687
|
+
menuDropdown.appendChild(embedItem);
|
|
6688
|
+
}
|
|
6660
6689
|
menuDropdown.appendChild(copyMmlItem);
|
|
6661
6690
|
menuContainer.appendChild(menuDropdown);
|
|
6662
6691
|
mmlHeader.appendChild(menuContainer);
|
|
@@ -6810,6 +6839,8 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6810
6839
|
volume: trackVolume,
|
|
6811
6840
|
// 解説モーダル内の試聴サンプルは規約同意を要求しない。
|
|
6812
6841
|
skipConsent: true,
|
|
6842
|
+
// 再帰的なモーダル生成を防ぐ。
|
|
6843
|
+
_skipInfoModals: true,
|
|
6813
6844
|
onStop: () => {
|
|
6814
6845
|
if (activeSampleBtn === el) resetSampleBtn(el);
|
|
6815
6846
|
}
|
|
@@ -6819,65 +6850,67 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6819
6850
|
});
|
|
6820
6851
|
}
|
|
6821
6852
|
};
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
desc.textContent = "\u3053\u306EMML\u3092\u30B3\u30D4\u30FC\u3057\u3066\u3001\u4ED6\u306E\u30D7\u30EC\u30A4\u30E4\u30FC\u3084\u5171\u6709URL\u306B\u8CBC\u308A\u4ED8\u3051\u3066\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002";
|
|
6828
|
-
desc.style.marginBottom = "8px";
|
|
6829
|
-
modalBody.appendChild(desc);
|
|
6830
|
-
const sourceMml = options.getMml?.() ?? mml;
|
|
6831
|
-
const displayMml = sourceMml.split(";").map((s) => s.trim()).filter((s) => s.length > 0).join(";\n");
|
|
6832
|
-
const pre = doc.createElement("pre");
|
|
6833
|
-
pre.textContent = displayMml;
|
|
6834
|
-
pre.style.whiteSpace = "pre-wrap";
|
|
6835
|
-
pre.style.wordBreak = "break-all";
|
|
6836
|
-
pre.style.cursor = "text";
|
|
6837
|
-
pre.addEventListener("click", () => {
|
|
6838
|
-
const range = doc.createRange();
|
|
6839
|
-
range.selectNodeContents(pre);
|
|
6840
|
-
const sel = doc.defaultView?.getSelection();
|
|
6841
|
-
sel?.removeAllRanges();
|
|
6842
|
-
sel?.addRange(range);
|
|
6843
|
-
});
|
|
6844
|
-
modalBody.appendChild(pre);
|
|
6845
|
-
appendCopyButton(modalBody, sourceMml);
|
|
6846
|
-
});
|
|
6847
|
-
mmlInfoItem.addEventListener("click", (e) => {
|
|
6848
|
-
e.stopPropagation();
|
|
6849
|
-
toggleMenu(false);
|
|
6850
|
-
const modalBody = openInfoModal("MML\u306E\u66F8\u304D\u65B9\u89E3\u8AAC");
|
|
6851
|
-
modalBody.innerHTML = MML_INFO_HTML;
|
|
6852
|
-
wireSampleButtons(modalBody);
|
|
6853
|
-
});
|
|
6854
|
-
embedItem.addEventListener("click", async (e) => {
|
|
6855
|
-
e.stopPropagation();
|
|
6856
|
-
toggleMenu(false);
|
|
6857
|
-
const modalBody = openInfoModal("\u57CB\u3081\u8FBC\u307F");
|
|
6858
|
-
const loading = doc.createElement("p");
|
|
6859
|
-
loading.textContent = "\u751F\u6210\u4E2D...";
|
|
6860
|
-
modalBody.appendChild(loading);
|
|
6861
|
-
try {
|
|
6862
|
-
const embedBase = options.embedUrl ?? "https://onjmin.github.io/dtm/demo/embed.html";
|
|
6863
|
-
const payload = await encodeMml(mml);
|
|
6864
|
-
const url2 = `${embedBase}#${payload}`;
|
|
6865
|
-
const snippet = `<iframe src="${url2}" width="100%" height="260" frameborder="0" loading="lazy" title="@onjmin/dtm player"></iframe>`;
|
|
6866
|
-
if (!modalBody.isConnected) return;
|
|
6867
|
-
loading.remove();
|
|
6853
|
+
if (!options._skipInfoModals) {
|
|
6854
|
+
showMmlItem.addEventListener("click", (e) => {
|
|
6855
|
+
e.stopPropagation();
|
|
6856
|
+
toggleMenu(false);
|
|
6857
|
+
const modalBody = openInfoModal("MML\u3092\u8868\u793A");
|
|
6868
6858
|
const desc = doc.createElement("p");
|
|
6869
|
-
desc.textContent = "\u3053\
|
|
6859
|
+
desc.textContent = "\u3053\u306EMML\u3092\u30B3\u30D4\u30FC\u3057\u3066\u3001\u4ED6\u306E\u30D7\u30EC\u30A4\u30E4\u30FC\u3084\u5171\u6709URL\u306B\u8CBC\u308A\u4ED8\u3051\u3066\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002";
|
|
6860
|
+
desc.style.marginBottom = "8px";
|
|
6861
|
+
modalBody.appendChild(desc);
|
|
6862
|
+
const sourceMml = options.getMml?.() ?? mml;
|
|
6863
|
+
const displayMml = sourceMml.split(";").map((s) => s.trim()).filter((s) => s.length > 0).join(";\n");
|
|
6870
6864
|
const pre = doc.createElement("pre");
|
|
6871
|
-
pre.textContent =
|
|
6865
|
+
pre.textContent = displayMml;
|
|
6872
6866
|
pre.style.whiteSpace = "pre-wrap";
|
|
6873
6867
|
pre.style.wordBreak = "break-all";
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6868
|
+
pre.style.cursor = "text";
|
|
6869
|
+
pre.addEventListener("click", () => {
|
|
6870
|
+
const range = doc.createRange();
|
|
6871
|
+
range.selectNodeContents(pre);
|
|
6872
|
+
const sel = doc.defaultView?.getSelection();
|
|
6873
|
+
sel?.removeAllRanges();
|
|
6874
|
+
sel?.addRange(range);
|
|
6875
|
+
});
|
|
6876
|
+
modalBody.appendChild(pre);
|
|
6877
|
+
appendCopyButton(modalBody, sourceMml);
|
|
6878
|
+
});
|
|
6879
|
+
mmlInfoItem.addEventListener("click", (e) => {
|
|
6880
|
+
e.stopPropagation();
|
|
6881
|
+
toggleMenu(false);
|
|
6882
|
+
const modalBody = openInfoModal("MML\u306E\u66F8\u304D\u65B9\u89E3\u8AAC");
|
|
6883
|
+
modalBody.innerHTML = MML_INFO_HTML;
|
|
6884
|
+
wireSampleButtons(modalBody);
|
|
6885
|
+
});
|
|
6886
|
+
embedItem.addEventListener("click", async (e) => {
|
|
6887
|
+
e.stopPropagation();
|
|
6888
|
+
toggleMenu(false);
|
|
6889
|
+
const modalBody = openInfoModal("\u57CB\u3081\u8FBC\u307F");
|
|
6890
|
+
const loading = doc.createElement("p");
|
|
6891
|
+
loading.textContent = "\u751F\u6210\u4E2D...";
|
|
6892
|
+
modalBody.appendChild(loading);
|
|
6893
|
+
try {
|
|
6894
|
+
const embedBase = options.embedUrl ?? "https://onjmin.github.io/dtm/demo/embed.html";
|
|
6895
|
+
const payload = await encodeMml(mml);
|
|
6896
|
+
const url2 = `${embedBase}#${payload}`;
|
|
6897
|
+
const snippet = `<iframe src="${url2}" width="100%" height="260" frameborder="0" loading="lazy" title="@onjmin/dtm player"></iframe>`;
|
|
6898
|
+
if (!modalBody.isConnected) return;
|
|
6899
|
+
loading.remove();
|
|
6900
|
+
const desc = doc.createElement("p");
|
|
6901
|
+
desc.textContent = "\u3053\u306EHTML\u3092\u30D6\u30ED\u30B0\u3084\u30B5\u30A4\u30C8\u306B\u8CBC\u308A\u4ED8\u3051\u308B\u3068\u3001\u30D7\u30EC\u30A4\u30E4\u30FC\u3092\u305D\u306E\u307E\u307E\u57CB\u3081\u8FBC\u3081\u307E\u3059\u3002";
|
|
6902
|
+
const pre = doc.createElement("pre");
|
|
6903
|
+
pre.textContent = snippet;
|
|
6904
|
+
pre.style.whiteSpace = "pre-wrap";
|
|
6905
|
+
pre.style.wordBreak = "break-all";
|
|
6906
|
+
modalBody.append(desc, pre);
|
|
6907
|
+
appendCopyButton(modalBody, snippet);
|
|
6908
|
+
} catch (err2) {
|
|
6909
|
+
console.error("[dtm] failed to generate embed snippet", err2);
|
|
6910
|
+
if (modalBody.isConnected) loading.textContent = "\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F";
|
|
6911
|
+
}
|
|
6912
|
+
});
|
|
6913
|
+
}
|
|
6881
6914
|
copyMmlItem.addEventListener("click", async (e) => {
|
|
6882
6915
|
e.stopPropagation();
|
|
6883
6916
|
const success = await copyToClipboard(doc, options.getMml?.() ?? mml);
|
|
@@ -7474,8 +7507,8 @@ var MIDI_INFO_HTML = `
|
|
|
7474
7507
|
|
|
7475
7508
|
<h4>3. \u30E2\u30FC\u30C9\u306B\u3088\u308B\u53D6\u308A\u8FBC\u307F\u65B9\u306E\u9055\u3044</h4>
|
|
7476
7509
|
<ul>
|
|
7477
|
-
<li><strong
|
|
7478
|
-
<li><strong
|
|
7510
|
+
<li><strong>\u521D\u5FC3\u8005\u30E2\u30FC\u30C9</strong>: \u5404\u30C8\u30E9\u30C3\u30AF\u306E\u7279\u5FB4\u304B\u3089\u3001\u30E1\u30ED\u30C7\u30A3\u30FC\u30FB\u30B5\u30D6\u30E1\u30ED\u30FB\u30D9\u30FC\u30B9\u30FB\u4F34\u594F\u306E4\u3064\u306E\u5F79\u5272\u306B\u81EA\u52D5\u3067\u632F\u308A\u5206\u3051\u3089\u308C\u307E\u3059\u3002</li>
|
|
7511
|
+
<li><strong>\u4E0A\u7D1A\u8005\u30E2\u30FC\u30C9</strong>: MIDI\u306E\u30C8\u30E9\u30C3\u30AF\u69CB\u6210\u304C\u305D\u306E\u307E\u307E\u53CD\u6620\u3055\u308C\u307E\u3059\uFF081\u5BFE1\uFF09\u3002</li>
|
|
7479
7512
|
</ul>
|
|
7480
7513
|
|
|
7481
7514
|
<h4>4. MIDI\u30D5\u30A1\u30A4\u30EB\u3092\u624B\u306B\u5165\u308C\u308B</h4>
|
|
@@ -7527,105 +7560,105 @@ var TRACKS_SIMPLE = [
|
|
|
7527
7560
|
var TRACKS_ADVANCED = [
|
|
7528
7561
|
{
|
|
7529
7562
|
id: "t0",
|
|
7530
|
-
name: "
|
|
7563
|
+
name: "\u30C8\u30E9\u30C3\u30AF1",
|
|
7531
7564
|
color: [41, 173, 255],
|
|
7532
7565
|
instrument: 0,
|
|
7533
7566
|
volume: 100
|
|
7534
7567
|
},
|
|
7535
7568
|
{
|
|
7536
7569
|
id: "t1",
|
|
7537
|
-
name: "
|
|
7570
|
+
name: "\u30C8\u30E9\u30C3\u30AF2",
|
|
7538
7571
|
color: [0, 228, 54],
|
|
7539
7572
|
instrument: 1,
|
|
7540
7573
|
volume: 100
|
|
7541
7574
|
},
|
|
7542
7575
|
{
|
|
7543
7576
|
id: "t2",
|
|
7544
|
-
name: "
|
|
7577
|
+
name: "\u30C8\u30E9\u30C3\u30AF3",
|
|
7545
7578
|
color: [255, 119, 168],
|
|
7546
7579
|
instrument: 2,
|
|
7547
7580
|
volume: 100
|
|
7548
7581
|
},
|
|
7549
7582
|
{
|
|
7550
7583
|
id: "t3",
|
|
7551
|
-
name: "
|
|
7584
|
+
name: "\u30C8\u30E9\u30C3\u30AF4",
|
|
7552
7585
|
color: [255, 163, 0],
|
|
7553
7586
|
instrument: 3,
|
|
7554
7587
|
volume: 100
|
|
7555
7588
|
},
|
|
7556
7589
|
{
|
|
7557
7590
|
id: "t4",
|
|
7558
|
-
name: "
|
|
7591
|
+
name: "\u30C8\u30E9\u30C3\u30AF5",
|
|
7559
7592
|
color: [255, 236, 39],
|
|
7560
7593
|
instrument: 4,
|
|
7561
7594
|
volume: 100
|
|
7562
7595
|
},
|
|
7563
7596
|
{
|
|
7564
7597
|
id: "t5",
|
|
7565
|
-
name: "
|
|
7598
|
+
name: "\u30C8\u30E9\u30C3\u30AF6",
|
|
7566
7599
|
color: [131, 118, 156],
|
|
7567
7600
|
instrument: 5,
|
|
7568
7601
|
volume: 100
|
|
7569
7602
|
},
|
|
7570
7603
|
{
|
|
7571
7604
|
id: "t6",
|
|
7572
|
-
name: "
|
|
7605
|
+
name: "\u30C8\u30E9\u30C3\u30AF7",
|
|
7573
7606
|
color: [255, 0, 77],
|
|
7574
7607
|
instrument: 6,
|
|
7575
7608
|
volume: 100
|
|
7576
7609
|
},
|
|
7577
7610
|
{
|
|
7578
7611
|
id: "t7",
|
|
7579
|
-
name: "
|
|
7612
|
+
name: "\u30C8\u30E9\u30C3\u30AF8",
|
|
7580
7613
|
color: [255, 204, 170],
|
|
7581
7614
|
instrument: 7,
|
|
7582
7615
|
volume: 100
|
|
7583
7616
|
},
|
|
7584
7617
|
{
|
|
7585
7618
|
id: "t8",
|
|
7586
|
-
name: "
|
|
7619
|
+
name: "\u30C8\u30E9\u30C3\u30AF9",
|
|
7587
7620
|
color: [194, 195, 199],
|
|
7588
7621
|
instrument: 8,
|
|
7589
7622
|
volume: 100
|
|
7590
7623
|
},
|
|
7591
7624
|
{
|
|
7592
7625
|
id: "t9",
|
|
7593
|
-
name: "
|
|
7626
|
+
name: "\u30C8\u30E9\u30C3\u30AF10",
|
|
7594
7627
|
color: [0, 135, 81],
|
|
7595
7628
|
instrument: 9,
|
|
7596
7629
|
volume: 100
|
|
7597
7630
|
},
|
|
7598
7631
|
{
|
|
7599
7632
|
id: "t10",
|
|
7600
|
-
name: "
|
|
7633
|
+
name: "\u30C8\u30E9\u30C3\u30AF11",
|
|
7601
7634
|
color: [171, 82, 54],
|
|
7602
7635
|
instrument: 10,
|
|
7603
7636
|
volume: 100
|
|
7604
7637
|
},
|
|
7605
7638
|
{
|
|
7606
7639
|
id: "t11",
|
|
7607
|
-
name: "
|
|
7640
|
+
name: "\u30C8\u30E9\u30C3\u30AF12",
|
|
7608
7641
|
color: [126, 37, 83],
|
|
7609
7642
|
instrument: 11,
|
|
7610
7643
|
volume: 100
|
|
7611
7644
|
},
|
|
7612
7645
|
{
|
|
7613
7646
|
id: "t12",
|
|
7614
|
-
name: "
|
|
7647
|
+
name: "\u30C8\u30E9\u30C3\u30AF13",
|
|
7615
7648
|
color: [255, 241, 232],
|
|
7616
7649
|
instrument: 12,
|
|
7617
7650
|
volume: 100
|
|
7618
7651
|
},
|
|
7619
7652
|
{
|
|
7620
7653
|
id: "t13",
|
|
7621
|
-
name: "
|
|
7654
|
+
name: "\u30C8\u30E9\u30C3\u30AF14",
|
|
7622
7655
|
color: [120, 200, 255],
|
|
7623
7656
|
instrument: 13,
|
|
7624
7657
|
volume: 100
|
|
7625
7658
|
},
|
|
7626
7659
|
{
|
|
7627
7660
|
id: "t14",
|
|
7628
|
-
name: "
|
|
7661
|
+
name: "\u30C8\u30E9\u30C3\u30AF15",
|
|
7629
7662
|
color: [100, 255, 160],
|
|
7630
7663
|
instrument: 14,
|
|
7631
7664
|
volume: 100
|
|
@@ -7639,6 +7672,13 @@ var LYRIC_MODEL_LABELS2 = {
|
|
|
7639
7672
|
};
|
|
7640
7673
|
var lyricModelLabel = (model) => LYRIC_MODEL_LABELS2[model] ?? model;
|
|
7641
7674
|
var clamp3 = (v, min, max) => Math.min(Math.max(v, min), max);
|
|
7675
|
+
var normalizeInstrumentName = (name) => {
|
|
7676
|
+
if (!name) return "";
|
|
7677
|
+
const stripped = name.replace(/\s+/g, "").toLowerCase();
|
|
7678
|
+
return GM_INSTRUMENT_NAMES.find(
|
|
7679
|
+
(n) => n.replace(/\s+/g, "").toLowerCase() === stripped
|
|
7680
|
+
) ?? name;
|
|
7681
|
+
};
|
|
7642
7682
|
var mountDAW = (target, options = {}) => {
|
|
7643
7683
|
injectStyles();
|
|
7644
7684
|
const getAudioTime = options.getAudioTime ?? (() => performance.now() / 1e3);
|
|
@@ -7678,7 +7718,8 @@ var mountDAW = (target, options = {}) => {
|
|
|
7678
7718
|
let snapGridSteps = 12;
|
|
7679
7719
|
const gridLineSteps = 48;
|
|
7680
7720
|
let currentOffsetX = 0;
|
|
7681
|
-
|
|
7721
|
+
const _initPitch = options.initialScrollPitch;
|
|
7722
|
+
let currentOffsetY = _initPitch !== void 0 ? (renderConfig.keyCount - 1 - _initPitch) * renderConfig.keyHeight - 215 : (104 - 1 - 60) * renderConfig.keyHeight - 215;
|
|
7682
7723
|
let playStartStep = 0;
|
|
7683
7724
|
let isSolo = false;
|
|
7684
7725
|
let lyricTrackIndices = /* @__PURE__ */ new Set();
|
|
@@ -7691,6 +7732,24 @@ var mountDAW = (target, options = {}) => {
|
|
|
7691
7732
|
let copiedNotes = [];
|
|
7692
7733
|
let trackStates = [];
|
|
7693
7734
|
let suppressPatch = false;
|
|
7735
|
+
let lyricsDebounceTimer = null;
|
|
7736
|
+
const fireLyricsChange = (t) => {
|
|
7737
|
+
if (!options.onLyricsChange) return;
|
|
7738
|
+
const trackId = t.config.id;
|
|
7739
|
+
const data = {
|
|
7740
|
+
lyrics: t.lyrics,
|
|
7741
|
+
model: t.lyricModel,
|
|
7742
|
+
vocalVolume: t.vocalVolume,
|
|
7743
|
+
vocalGate: t.vocalGate,
|
|
7744
|
+
vocalPan: t.vocalPan,
|
|
7745
|
+
vocalOctave: t.vocalOctave
|
|
7746
|
+
};
|
|
7747
|
+
if (lyricsDebounceTimer) clearTimeout(lyricsDebounceTimer);
|
|
7748
|
+
lyricsDebounceTimer = setTimeout(() => {
|
|
7749
|
+
options.onLyricsChange(trackId, data);
|
|
7750
|
+
lyricsDebounceTimer = null;
|
|
7751
|
+
}, 300);
|
|
7752
|
+
};
|
|
7694
7753
|
const hiddenTracks = /* @__PURE__ */ new Set();
|
|
7695
7754
|
const audioMutedTracks = /* @__PURE__ */ new Set();
|
|
7696
7755
|
const createTrackStates = () => {
|
|
@@ -7739,7 +7798,8 @@ var mountDAW = (target, options = {}) => {
|
|
|
7739
7798
|
vocalVolume: DEFAULT_VOCAL_VOLUME,
|
|
7740
7799
|
vocalGate: 100,
|
|
7741
7800
|
vocalPan: 64,
|
|
7742
|
-
vocalOctave: 0
|
|
7801
|
+
vocalOctave: 0,
|
|
7802
|
+
trackInstrument: ""
|
|
7743
7803
|
};
|
|
7744
7804
|
});
|
|
7745
7805
|
};
|
|
@@ -8445,19 +8505,20 @@ var mountDAW = (target, options = {}) => {
|
|
|
8445
8505
|
};
|
|
8446
8506
|
const updateTrackPanel = () => {
|
|
8447
8507
|
refs.trackTabs.innerHTML = "";
|
|
8448
|
-
for (const t of trackStates) {
|
|
8508
|
+
for (const [i, t] of trackStates.entries()) {
|
|
8449
8509
|
const [r, g, b] = t.config.color;
|
|
8450
8510
|
const btn = document.createElement("button");
|
|
8451
8511
|
btn.className = `dtm-pill ${t.config.id === activeTrackId ? "dtm-pill--active" : ""}`;
|
|
8452
8512
|
btn.style.setProperty("--dtm-pill-color", `rgb(${r},${g},${b})`);
|
|
8453
|
-
btn.
|
|
8513
|
+
btn.title = t.config.name;
|
|
8514
|
+
btn.textContent = String(i + 1);
|
|
8454
8515
|
btn.addEventListener("click", () => switchTrack(t.config.id));
|
|
8455
8516
|
refs.trackTabs.appendChild(btn);
|
|
8456
8517
|
}
|
|
8457
8518
|
const active = getActive();
|
|
8458
8519
|
refs.trackBody.innerHTML = `
|
|
8459
8520
|
<div class="dtm-row">
|
|
8460
|
-
<span class="dtm-label"
|
|
8521
|
+
<span class="dtm-label">\u30D9\u30ED\u30B7\u30C6\u30A3</span>
|
|
8461
8522
|
<input type="range" class="dtm-range dtm-grow" data-dtm="track-vol" min="0" max="127" value="${active.volume}">
|
|
8462
8523
|
<span class="dtm-label" data-dtm="track-vol-label">${active.volume}</span>
|
|
8463
8524
|
</div>`;
|
|
@@ -8472,6 +8533,59 @@ var mountDAW = (target, options = {}) => {
|
|
|
8472
8533
|
active.core.setVolume(active.volume);
|
|
8473
8534
|
volLabel.textContent = String(active.volume);
|
|
8474
8535
|
});
|
|
8536
|
+
const instRow = document.createElement("div");
|
|
8537
|
+
instRow.className = "dtm-row";
|
|
8538
|
+
instRow.innerHTML = `<span class="dtm-label">\u697D\u5668</span>`;
|
|
8539
|
+
const instSel = document.createElement("select");
|
|
8540
|
+
instSel.className = "dtm-select dtm-grow";
|
|
8541
|
+
const defaultOpt = document.createElement("option");
|
|
8542
|
+
defaultOpt.value = "";
|
|
8543
|
+
defaultOpt.textContent = "\u30C7\u30D5\u30A9\u30EB\u30C8\uFF08\u30D7\u30EA\u30BB\u30C3\u30C8\uFF09";
|
|
8544
|
+
instSel.appendChild(defaultOpt);
|
|
8545
|
+
const GM_GROUPS = [
|
|
8546
|
+
"\u30D4\u30A2\u30CE",
|
|
8547
|
+
"\u30AF\u30ED\u30DE\u30C6\u30A3\u30C3\u30AF\u30D1\u30FC\u30AB\u30C3\u30B7\u30E7\u30F3",
|
|
8548
|
+
"\u30AA\u30EB\u30AC\u30F3",
|
|
8549
|
+
"\u30AE\u30BF\u30FC",
|
|
8550
|
+
"\u30D9\u30FC\u30B9",
|
|
8551
|
+
"\u30B9\u30C8\u30EA\u30F3\u30B0\u30B9",
|
|
8552
|
+
"\u30A2\u30F3\u30B5\u30F3\u30D6\u30EB",
|
|
8553
|
+
"\u30D6\u30E9\u30B9",
|
|
8554
|
+
"\u30EA\u30FC\u30C9\uFF08\u6728\u7BA1\uFF09",
|
|
8555
|
+
"\u30D1\u30A4\u30D7",
|
|
8556
|
+
"\u30B7\u30F3\u30BB\u30EA\u30FC\u30C9",
|
|
8557
|
+
"\u30B7\u30F3\u30BB\u30D1\u30C3\u30C9",
|
|
8558
|
+
"\u30B7\u30F3\u30BB\u30A8\u30D5\u30A7\u30AF\u30C8",
|
|
8559
|
+
"\u30A8\u30B9\u30CB\u30C3\u30AF",
|
|
8560
|
+
"\u30D1\u30FC\u30AB\u30C3\u30B7\u30D6",
|
|
8561
|
+
"\u30B5\u30A6\u30F3\u30C9\u30A8\u30D5\u30A7\u30AF\u30C8"
|
|
8562
|
+
];
|
|
8563
|
+
GM_GROUPS.forEach((groupName, gi) => {
|
|
8564
|
+
const grp = document.createElement("optgroup");
|
|
8565
|
+
grp.label = groupName;
|
|
8566
|
+
for (let j = 0; j < 8; j++) {
|
|
8567
|
+
const name = GM_INSTRUMENT_NAMES[gi * 8 + j];
|
|
8568
|
+
if (!name) break;
|
|
8569
|
+
const o = document.createElement("option");
|
|
8570
|
+
o.value = name;
|
|
8571
|
+
o.textContent = name;
|
|
8572
|
+
grp.appendChild(o);
|
|
8573
|
+
}
|
|
8574
|
+
instSel.appendChild(grp);
|
|
8575
|
+
});
|
|
8576
|
+
instSel.value = normalizeInstrumentName(active.trackInstrument);
|
|
8577
|
+
const syncInstDisabled = () => {
|
|
8578
|
+
instSel.disabled = !!active.lyricModel;
|
|
8579
|
+
instSel.title = active.lyricModel ? "\u6B4C\u8A5E\u30E2\u30FC\u30C9\u306E\u3068\u304D\u306F\u697D\u5668\u3092\u500B\u5225\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093" : "";
|
|
8580
|
+
};
|
|
8581
|
+
syncInstDisabled();
|
|
8582
|
+
instSel.addEventListener("change", () => {
|
|
8583
|
+
active.trackInstrument = instSel.value;
|
|
8584
|
+
const trackIndex = trackStates.indexOf(active);
|
|
8585
|
+
options.onTrackInstrumentChange?.(trackIndex, active.trackInstrument);
|
|
8586
|
+
});
|
|
8587
|
+
instRow.appendChild(instSel);
|
|
8588
|
+
refs.trackBody.appendChild(instRow);
|
|
8475
8589
|
if (isAdvanced || active.config.id !== "chord") {
|
|
8476
8590
|
const lyricDiv = document.createElement("div");
|
|
8477
8591
|
lyricDiv.className = "dtm-row";
|
|
@@ -8479,7 +8593,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
8479
8593
|
lyricDiv.style.alignItems = "stretch";
|
|
8480
8594
|
lyricDiv.innerHTML = `
|
|
8481
8595
|
<div class="dtm-row">
|
|
8482
|
-
<span class="dtm-label">\u266A
|
|
8596
|
+
<span class="dtm-label">\u266A UTAU</span>
|
|
8483
8597
|
<select class="dtm-select" data-dtm="lyric-model" aria-label="\u6B4C\u5531\u30E2\u30C7\u30EB"></select>
|
|
8484
8598
|
<img class="dtm-lyric-icon dtm-hidden" data-dtm="lyric-icon" width="20" height="20" alt="" draggable="false">
|
|
8485
8599
|
<select class="dtm-select" data-dtm="lyric-octave" aria-label="\u30AA\u30AF\u30BF\u30FC\u30D6\uFF08\u97F3\u6E90\u306E\u5F97\u610F\u97F3\u57DF\u306B\u5408\u308F\u305B\u308B\uFF09" title="\u30AA\u30AF\u30BF\u30FC\u30D6">
|
|
@@ -8553,7 +8667,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
8553
8667
|
o.textContent = label;
|
|
8554
8668
|
lyricModelSel.appendChild(o);
|
|
8555
8669
|
};
|
|
8556
|
-
addOpt("", "\u306A\u3057");
|
|
8670
|
+
addOpt("", "\u30DC\u30FC\u30AB\u30EB\u306A\u3057");
|
|
8557
8671
|
for (const m of LYRIC_MODELS) addOpt(m, lyricModelLabel(m));
|
|
8558
8672
|
if (active.lyricModel && !LYRIC_MODELS.includes(active.lyricModel)) {
|
|
8559
8673
|
addOpt(active.lyricModel, lyricModelLabel(active.lyricModel));
|
|
@@ -8602,21 +8716,27 @@ var mountDAW = (target, options = {}) => {
|
|
|
8602
8716
|
lyricModelSel.addEventListener("change", () => {
|
|
8603
8717
|
active.lyricModel = lyricModelSel.value;
|
|
8604
8718
|
syncLyricVisibility();
|
|
8719
|
+
syncInstDisabled();
|
|
8720
|
+
fireLyricsChange(active);
|
|
8605
8721
|
});
|
|
8606
8722
|
lyricOctaveSel.addEventListener("change", () => {
|
|
8607
8723
|
active.vocalOctave = Number.parseInt(lyricOctaveSel.value, 10);
|
|
8724
|
+
fireLyricsChange(active);
|
|
8608
8725
|
});
|
|
8609
8726
|
lyricInput.addEventListener("input", () => {
|
|
8610
8727
|
active.lyrics = lyricInput.value;
|
|
8611
8728
|
updateLyricCount();
|
|
8729
|
+
fireLyricsChange(active);
|
|
8612
8730
|
});
|
|
8613
8731
|
lyricVol.addEventListener("input", () => {
|
|
8614
8732
|
active.vocalVolume = Number.parseInt(lyricVol.value, 10);
|
|
8615
8733
|
lyricVolLabel.textContent = lyricVol.value;
|
|
8734
|
+
fireLyricsChange(active);
|
|
8616
8735
|
});
|
|
8617
8736
|
lyricPan.addEventListener("input", () => {
|
|
8618
8737
|
active.vocalPan = Number.parseInt(lyricPan.value, 10);
|
|
8619
8738
|
lyricPanLabel.textContent = fmtPan(active.vocalPan);
|
|
8739
|
+
fireLyricsChange(active);
|
|
8620
8740
|
});
|
|
8621
8741
|
lyricPanLabel.style.cursor = "pointer";
|
|
8622
8742
|
lyricPanLabel.title = "\u30BF\u30C3\u30D7\u3067\u4E2D\u592E(C)\u3078";
|
|
@@ -8624,6 +8744,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
8624
8744
|
active.vocalPan = 64;
|
|
8625
8745
|
lyricPan.value = "64";
|
|
8626
8746
|
lyricPanLabel.textContent = fmtPan(64);
|
|
8747
|
+
fireLyricsChange(active);
|
|
8627
8748
|
});
|
|
8628
8749
|
}
|
|
8629
8750
|
if (active.config.id === "chord" && showChord) {
|
|
@@ -8698,13 +8819,19 @@ var mountDAW = (target, options = {}) => {
|
|
|
8698
8819
|
const barLimitBars = Number(refs.barLimitSelect.value);
|
|
8699
8820
|
const limitSteps = barLimitBars > 0 ? barLimitBars * renderConfig.stepsPerBar : Infinity;
|
|
8700
8821
|
const clipNotes = (notes) => limitSteps === Infinity ? notes : notes.filter((n) => n.startStep < limitSteps);
|
|
8822
|
+
const trackInstrumentsForMeta = {};
|
|
8823
|
+
trackStates.forEach((t, i) => {
|
|
8824
|
+
if (t.trackInstrument) trackInstrumentsForMeta[i] = t.trackInstrument;
|
|
8825
|
+
});
|
|
8826
|
+
const trackInstMeta = Object.keys(trackInstrumentsForMeta).length > 0 ? trackInstrumentsForMeta : void 0;
|
|
8701
8827
|
const metaLineFull = formatMmlMeta(
|
|
8702
8828
|
{
|
|
8703
8829
|
instrument: currentInstrument || void 0,
|
|
8704
8830
|
drum: currentDrumPattern !== "none" ? currentDrumPattern : void 0,
|
|
8705
8831
|
volume: masterVolume,
|
|
8706
8832
|
drumVolume,
|
|
8707
|
-
mode
|
|
8833
|
+
mode,
|
|
8834
|
+
trackInstruments: trackInstMeta
|
|
8708
8835
|
},
|
|
8709
8836
|
" "
|
|
8710
8837
|
);
|
|
@@ -8714,7 +8841,8 @@ var mountDAW = (target, options = {}) => {
|
|
|
8714
8841
|
drum: currentDrumPattern !== "none" ? currentDrumPattern : void 0,
|
|
8715
8842
|
volume: masterVolume,
|
|
8716
8843
|
drumVolume,
|
|
8717
|
-
mode
|
|
8844
|
+
mode,
|
|
8845
|
+
trackInstruments: trackInstMeta
|
|
8718
8846
|
},
|
|
8719
8847
|
""
|
|
8720
8848
|
);
|
|
@@ -8872,6 +9000,13 @@ var mountDAW = (target, options = {}) => {
|
|
|
8872
9000
|
refs.drumVolume.value = String(meta.drumVolume);
|
|
8873
9001
|
refs.drumVolumeLabel.textContent = `${meta.drumVolume}%`;
|
|
8874
9002
|
}
|
|
9003
|
+
trackStates.forEach((t, i) => {
|
|
9004
|
+
const name = normalizeInstrumentName(meta.trackInstruments?.[i] ?? "");
|
|
9005
|
+
if (t.trackInstrument !== name) {
|
|
9006
|
+
t.trackInstrument = name;
|
|
9007
|
+
options.onTrackInstrumentChange?.(i, name);
|
|
9008
|
+
}
|
|
9009
|
+
});
|
|
8875
9010
|
for (const t of trackStates) {
|
|
8876
9011
|
t.lyrics = "";
|
|
8877
9012
|
t.lyricModel = "";
|
|
@@ -9031,6 +9166,31 @@ var mountDAW = (target, options = {}) => {
|
|
|
9031
9166
|
setLoading(false);
|
|
9032
9167
|
}, 30);
|
|
9033
9168
|
};
|
|
9169
|
+
const showConfirmModal = (message) => new Promise((resolve) => {
|
|
9170
|
+
const overlay = document.createElement("div");
|
|
9171
|
+
overlay.className = "dtm-modal-overlay";
|
|
9172
|
+
overlay.innerHTML = `
|
|
9173
|
+
<div class="dtm-modal">
|
|
9174
|
+
<div class="dtm-modal-header">
|
|
9175
|
+
<span class="dtm-modal-title">\u30E2\u30FC\u30C9\u306E\u78BA\u8A8D</span>
|
|
9176
|
+
</div>
|
|
9177
|
+
<div class="dtm-modal-body"><p>${message}</p></div>
|
|
9178
|
+
<div class="dtm-confirm-footer">
|
|
9179
|
+
<button class="dtm-btn dtm-btn--ghost dtm-confirm-no">\u3044\u3044\u3048\uFF08\u3053\u306E\u307E\u307E\u8AAD\u307F\u8FBC\u3080\uFF09</button>
|
|
9180
|
+
<button class="dtm-btn dtm-btn--primary dtm-confirm-yes">\u306F\u3044\uFF08\u4E0A\u7D1A\u8005\u30E2\u30FC\u30C9\u306B\u5207\u308A\u66FF\u3048\u308B\uFF09</button>
|
|
9181
|
+
</div>
|
|
9182
|
+
</div>`;
|
|
9183
|
+
const close = (result) => {
|
|
9184
|
+
overlay.remove();
|
|
9185
|
+
resolve(result);
|
|
9186
|
+
};
|
|
9187
|
+
overlay.querySelector(".dtm-confirm-yes").addEventListener("click", () => close(true));
|
|
9188
|
+
overlay.querySelector(".dtm-confirm-no").addEventListener("click", () => close(false));
|
|
9189
|
+
overlay.addEventListener("click", (e) => {
|
|
9190
|
+
if (e.target === overlay) close(false);
|
|
9191
|
+
});
|
|
9192
|
+
document.body.appendChild(overlay);
|
|
9193
|
+
});
|
|
9034
9194
|
const wireEvents = () => {
|
|
9035
9195
|
refs.playBtn.addEventListener("click", togglePlay);
|
|
9036
9196
|
refs.playBtn.disabled = false;
|
|
@@ -9150,10 +9310,25 @@ var mountDAW = (target, options = {}) => {
|
|
|
9150
9310
|
"click",
|
|
9151
9311
|
() => copy(refs.outputMini.textContent ?? "", refs.copyMiniBtn)
|
|
9152
9312
|
);
|
|
9153
|
-
refs.mmlLoadBtn.addEventListener(
|
|
9154
|
-
|
|
9155
|
-
|
|
9156
|
-
|
|
9313
|
+
refs.mmlLoadBtn.addEventListener("click", async () => {
|
|
9314
|
+
const mml = refs.mmlInput.value;
|
|
9315
|
+
if (!isAdvanced && options.onRequestAdvancedMode) {
|
|
9316
|
+
const { mergedTrackCount } = parseMML(mml, {
|
|
9317
|
+
stepsPerBar: renderConfig.stepsPerBar,
|
|
9318
|
+
clampTrackCount: trackStates.length
|
|
9319
|
+
});
|
|
9320
|
+
if (mergedTrackCount > 0) {
|
|
9321
|
+
const confirmed = await showConfirmModal(
|
|
9322
|
+
"\u521D\u5FC3\u8005\u30E2\u30FC\u30C9\u3067\u8AAD\u307F\u8FBC\u3080\u3068\u3001\u97F3\u304C\u5D29\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002<br>\u4E0A\u7D1A\u8005\u30E2\u30FC\u30C9\u306B\u5207\u308A\u66FF\u3048\u307E\u3059\u304B\uFF1F"
|
|
9323
|
+
);
|
|
9324
|
+
if (confirmed) {
|
|
9325
|
+
options.onRequestAdvancedMode(mml);
|
|
9326
|
+
return;
|
|
9327
|
+
}
|
|
9328
|
+
}
|
|
9329
|
+
}
|
|
9330
|
+
overlayDuring(() => loadMML(mml));
|
|
9331
|
+
});
|
|
9157
9332
|
let activeSamplePlayer = null;
|
|
9158
9333
|
let activeSampleButton = null;
|
|
9159
9334
|
const collapseActiveSample = () => {
|
|
@@ -9246,6 +9421,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
9246
9421
|
singingVoices: options.singingVoices,
|
|
9247
9422
|
drumPatterns: options.drumPatterns,
|
|
9248
9423
|
volume: masterVolume,
|
|
9424
|
+
_skipInfoModals: true,
|
|
9249
9425
|
onStop: () => {
|
|
9250
9426
|
if (activeSampleButton === htmlBtn) {
|
|
9251
9427
|
htmlBtn.textContent = "\u25B6 \u8A66\u8074";
|
|
@@ -9327,7 +9503,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
9327
9503
|
refs.overlay.hidden = true;
|
|
9328
9504
|
setLoading(false);
|
|
9329
9505
|
});
|
|
9330
|
-
refs.midiLoadBtn.addEventListener("click", () => {
|
|
9506
|
+
refs.midiLoadBtn.addEventListener("click", async () => {
|
|
9331
9507
|
if (!pendingMidi) return;
|
|
9332
9508
|
const selected = [];
|
|
9333
9509
|
const btns = refs.midiTrackSelection.querySelectorAll("button");
|
|
@@ -9336,6 +9512,19 @@ var mountDAW = (target, options = {}) => {
|
|
|
9336
9512
|
selected.push(detectedTracks[i].index);
|
|
9337
9513
|
});
|
|
9338
9514
|
if (selected.length === 0) return;
|
|
9515
|
+
if (!isAdvanced && options.onRequestAdvancedMode && selected.length > trackStates.length) {
|
|
9516
|
+
const confirmed = await showConfirmModal(
|
|
9517
|
+
"\u521D\u5FC3\u8005\u30E2\u30FC\u30C9\u3067\u8AAD\u307F\u8FBC\u3080\u3068\u3001\u97F3\u304C\u5D29\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002<br>\u4E0A\u7D1A\u8005\u30E2\u30FC\u30C9\u306B\u5207\u308A\u66FF\u3048\u307E\u3059\u304B\uFF1F"
|
|
9518
|
+
);
|
|
9519
|
+
if (confirmed) {
|
|
9520
|
+
const midi = pendingMidi;
|
|
9521
|
+
const sel = selected.slice();
|
|
9522
|
+
options.onRequestAdvancedMode(void 0, (newDaw) => {
|
|
9523
|
+
newDaw.applyMidiParsed?.(midi, sel);
|
|
9524
|
+
});
|
|
9525
|
+
return;
|
|
9526
|
+
}
|
|
9527
|
+
}
|
|
9339
9528
|
overlayDuring(() => applyMidiSelection(pendingMidi, selected));
|
|
9340
9529
|
});
|
|
9341
9530
|
};
|
|
@@ -9472,6 +9661,9 @@ var mountDAW = (target, options = {}) => {
|
|
|
9472
9661
|
},
|
|
9473
9662
|
loadMML,
|
|
9474
9663
|
loadMIDI,
|
|
9664
|
+
applyMidiParsed: (midi, selectedIndices) => {
|
|
9665
|
+
overlayDuring(() => applyMidiSelection(midi, selectedIndices));
|
|
9666
|
+
},
|
|
9475
9667
|
exportMIDI: exportMIDI2,
|
|
9476
9668
|
setBpm,
|
|
9477
9669
|
getPlaybackState: () => playbackState,
|
|
@@ -9506,6 +9698,37 @@ var mountDAW = (target, options = {}) => {
|
|
|
9506
9698
|
if (audible) audioMutedTracks.delete(trackId);
|
|
9507
9699
|
else audioMutedTracks.add(trackId);
|
|
9508
9700
|
},
|
|
9701
|
+
applyLyrics: (trackId, data) => {
|
|
9702
|
+
const t = trackStates.find((s) => s.config.id === trackId);
|
|
9703
|
+
if (!t) return;
|
|
9704
|
+
t.lyrics = data.lyrics;
|
|
9705
|
+
t.lyricModel = data.model;
|
|
9706
|
+
t.vocalVolume = data.vocalVolume;
|
|
9707
|
+
t.vocalGate = data.vocalGate;
|
|
9708
|
+
t.vocalPan = data.vocalPan;
|
|
9709
|
+
t.vocalOctave = data.vocalOctave;
|
|
9710
|
+
},
|
|
9711
|
+
applyTrackInstrument: (trackIndex, instrumentName) => {
|
|
9712
|
+
const t = trackStates[trackIndex];
|
|
9713
|
+
if (!t) return;
|
|
9714
|
+
const name = normalizeInstrumentName(instrumentName);
|
|
9715
|
+
t.trackInstrument = name;
|
|
9716
|
+
if (t.config.id === activeTrackId) updateTrackPanel();
|
|
9717
|
+
},
|
|
9718
|
+
noteToCanvas: (step, pitch) => {
|
|
9719
|
+
const canvas = getGridCanvas();
|
|
9720
|
+
const x = step * renderConfig.stepWidth - currentOffsetX;
|
|
9721
|
+
const y = (renderConfig.keyCount - 1 - pitch) * renderConfig.keyHeight - currentOffsetY;
|
|
9722
|
+
const onScreen = x >= 0 && x <= canvas.width && y >= 0 && y <= canvas.height;
|
|
9723
|
+
let side = null;
|
|
9724
|
+
if (!onScreen) {
|
|
9725
|
+
if (x < 0) side = "left";
|
|
9726
|
+
else if (x > canvas.width) side = "right";
|
|
9727
|
+
else if (y < 0) side = "top";
|
|
9728
|
+
else side = "bottom";
|
|
9729
|
+
}
|
|
9730
|
+
return { x, y, onScreen, side };
|
|
9731
|
+
},
|
|
9509
9732
|
destroy: () => {
|
|
9510
9733
|
sequencer.stop();
|
|
9511
9734
|
options.singingVoices?.stopStream();
|
|
@@ -10156,7 +10379,7 @@ var SoundFont = class _SoundFont {
|
|
|
10156
10379
|
const { buffer, _param } = zone;
|
|
10157
10380
|
if (!buffer || !_param) return;
|
|
10158
10381
|
src.buffer = buffer;
|
|
10159
|
-
g.gain.
|
|
10382
|
+
g.gain.setValueAtTime(volume, _when);
|
|
10160
10383
|
src.playbackRate.setValueAtTime(_param.playbackRate, 0);
|
|
10161
10384
|
Object.assign(src, _param.src);
|
|
10162
10385
|
const _duration = duration + _SoundFont.afterTime;
|
|
@@ -10208,6 +10431,12 @@ var adjustZone = async (ctx, zone) => {
|
|
|
10208
10431
|
}
|
|
10209
10432
|
} else if (zone.file) {
|
|
10210
10433
|
const buf = Uint8Array.from(atob(zone.file), (c) => c.charCodeAt(0)).buffer;
|
|
10434
|
+
if (ctx.state !== "running") {
|
|
10435
|
+
try {
|
|
10436
|
+
await ctx.resume();
|
|
10437
|
+
} catch {
|
|
10438
|
+
}
|
|
10439
|
+
}
|
|
10211
10440
|
zone.buffer = await ctx.decodeAudioData(buf);
|
|
10212
10441
|
}
|
|
10213
10442
|
for (const [k, v] of [
|
|
@@ -10425,6 +10654,14 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10425
10654
|
}
|
|
10426
10655
|
})();
|
|
10427
10656
|
let nameToKey = {};
|
|
10657
|
+
const resolveNameToKey = (name) => {
|
|
10658
|
+
if (nameToKey[name]) return nameToKey[name];
|
|
10659
|
+
const stripped = name.replace(/\s+/g, "").toLowerCase();
|
|
10660
|
+
const canonical = Object.keys(nameToKey).find(
|
|
10661
|
+
(k) => k.replace(/\s+/g, "").toLowerCase() === stripped
|
|
10662
|
+
);
|
|
10663
|
+
return canonical ? nameToKey[canonical] : void 0;
|
|
10664
|
+
};
|
|
10428
10665
|
const soundFonts = /* @__PURE__ */ new Map();
|
|
10429
10666
|
const loadingByKey = /* @__PURE__ */ new Map();
|
|
10430
10667
|
const loadInstrument = (instrumentKey) => {
|
|
@@ -10510,7 +10747,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10510
10747
|
if (opts.label !== null) {
|
|
10511
10748
|
const lab = doc.createElement("span");
|
|
10512
10749
|
lab.className = "dtm-controlbar-label";
|
|
10513
|
-
lab.textContent = opts.label ?? "
|
|
10750
|
+
lab.textContent = opts.label ?? "\u697D\u5668\u30D7\u30EA\u30BB\u30C3\u30C8";
|
|
10514
10751
|
wrapper.appendChild(lab);
|
|
10515
10752
|
}
|
|
10516
10753
|
const select = doc.createElement("select");
|
|
@@ -10575,7 +10812,13 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10575
10812
|
const mountedPlayers = [];
|
|
10576
10813
|
const mountedModeSwitches = [];
|
|
10577
10814
|
const mountEditor = (target, opts = {}) => {
|
|
10578
|
-
const {
|
|
10815
|
+
const {
|
|
10816
|
+
preset,
|
|
10817
|
+
presetUI,
|
|
10818
|
+
onInstrumentChange,
|
|
10819
|
+
onTrackInstrumentChange: externalOnTrackInstrumentChange,
|
|
10820
|
+
...dawOverrides
|
|
10821
|
+
} = opts;
|
|
10579
10822
|
const tracks = dawOverrides.tracks ?? TRACKS_SIMPLE;
|
|
10580
10823
|
const trackIds = tracks.map((t) => t.id);
|
|
10581
10824
|
const presetKey = preset && INSTRUMENT_PRESETS[preset] ? preset : defaultPreset;
|
|
@@ -10583,14 +10826,29 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10583
10826
|
const initialPreset = meta.instrument && INSTRUMENT_PRESETS[meta.instrument] ? meta.instrument : presetKey;
|
|
10584
10827
|
let editorPreset = initialPreset;
|
|
10585
10828
|
const isAdvancedMode = dawOverrides.mode === "advanced";
|
|
10829
|
+
const trackInstOverrides = /* @__PURE__ */ new Map();
|
|
10830
|
+
if (meta.trackInstruments) {
|
|
10831
|
+
for (const [idxStr, name] of Object.entries(meta.trackInstruments)) {
|
|
10832
|
+
const idx = Number(idxStr);
|
|
10833
|
+
const key = resolveNameToKey(name);
|
|
10834
|
+
if (key) trackInstOverrides.set(idx, key);
|
|
10835
|
+
}
|
|
10836
|
+
}
|
|
10586
10837
|
const playNote = (e) => {
|
|
10587
|
-
const
|
|
10588
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
|
|
10838
|
+
const trackIdx = tracks.findIndex((t) => t.id === e.trackId);
|
|
10839
|
+
const overrideKey = trackIdx >= 0 ? trackInstOverrides.get(trackIdx) : void 0;
|
|
10840
|
+
let sfInst;
|
|
10841
|
+
if (overrideKey) {
|
|
10842
|
+
sfInst = soundFonts.get(overrideKey);
|
|
10843
|
+
} else {
|
|
10844
|
+
sfInst = resolveSoundFont(
|
|
10845
|
+
editorPreset,
|
|
10846
|
+
e.trackId,
|
|
10847
|
+
isAdvancedMode ? "advanced" : "simple"
|
|
10848
|
+
);
|
|
10849
|
+
}
|
|
10850
|
+
if (!sfInst) return;
|
|
10851
|
+
sfInst.play({
|
|
10594
10852
|
ctx: audioCtx,
|
|
10595
10853
|
destination: masterGain,
|
|
10596
10854
|
pitch: e.pitch,
|
|
@@ -10607,6 +10865,17 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10607
10865
|
}
|
|
10608
10866
|
onInstrumentChange?.(key);
|
|
10609
10867
|
};
|
|
10868
|
+
const handleTrackInstrumentChange = async (trackIndex, instrumentName) => {
|
|
10869
|
+
if (!instrumentName) {
|
|
10870
|
+
trackInstOverrides.delete(trackIndex);
|
|
10871
|
+
return;
|
|
10872
|
+
}
|
|
10873
|
+
await listReady;
|
|
10874
|
+
const key = resolveNameToKey(instrumentName);
|
|
10875
|
+
if (!key) return;
|
|
10876
|
+
trackInstOverrides.set(trackIndex, key);
|
|
10877
|
+
await loadInstrument(key);
|
|
10878
|
+
};
|
|
10610
10879
|
const base = {
|
|
10611
10880
|
getAudioTime: () => audioCtx.currentTime,
|
|
10612
10881
|
onResumeAudio: resumeAudio,
|
|
@@ -10615,6 +10884,10 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10615
10884
|
singingVoices,
|
|
10616
10885
|
parseMidi,
|
|
10617
10886
|
onInstrumentChange: handleInstrumentChange,
|
|
10887
|
+
onTrackInstrumentChange: (idx, name) => {
|
|
10888
|
+
void handleTrackInstrumentChange(idx, name);
|
|
10889
|
+
externalOnTrackInstrumentChange?.(idx, name);
|
|
10890
|
+
},
|
|
10618
10891
|
...dawOverrides
|
|
10619
10892
|
};
|
|
10620
10893
|
const daw = mountDAW(target, base);
|
|
@@ -10662,6 +10935,10 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10662
10935
|
presetSelect.setValue(name);
|
|
10663
10936
|
}
|
|
10664
10937
|
},
|
|
10938
|
+
applyTrackInstrument: (trackIndex, instrumentName) => {
|
|
10939
|
+
daw.applyTrackInstrument(trackIndex, instrumentName);
|
|
10940
|
+
void handleTrackInstrumentChange(trackIndex, instrumentName);
|
|
10941
|
+
},
|
|
10665
10942
|
destroy
|
|
10666
10943
|
};
|
|
10667
10944
|
};
|
|
@@ -10669,8 +10946,8 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10669
10946
|
const doc = target.ownerDocument;
|
|
10670
10947
|
const tracksFor = opts.tracksFor ?? ((m) => m === "advanced" ? TRACKS_ADVANCED : TRACKS_SIMPLE);
|
|
10671
10948
|
const labels = {
|
|
10672
|
-
simple: opts.labels?.simple ?? "\
|
|
10673
|
-
advanced: opts.labels?.advanced ?? "\
|
|
10949
|
+
simple: opts.labels?.simple ?? "\u521D\u5FC3\u8005",
|
|
10950
|
+
advanced: opts.labels?.advanced ?? "\u4E0A\u7D1A\u8005"
|
|
10674
10951
|
};
|
|
10675
10952
|
const editorOptionsFor = (mode) => typeof opts.editorOptions === "function" ? opts.editorOptions(mode) : opts.editorOptions ?? {};
|
|
10676
10953
|
let currentMode = opts.mode ?? "simple";
|
|
@@ -10680,7 +10957,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10680
10957
|
if (opts.label !== null) {
|
|
10681
10958
|
const lab = doc.createElement("span");
|
|
10682
10959
|
lab.className = "dtm-controlbar-label";
|
|
10683
|
-
lab.textContent = opts.label ?? "
|
|
10960
|
+
lab.textContent = opts.label ?? "\u30E2\u30FC\u30C9";
|
|
10684
10961
|
wrapper.appendChild(lab);
|
|
10685
10962
|
}
|
|
10686
10963
|
const seg = doc.createElement("div");
|
|
@@ -10711,7 +10988,15 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10711
10988
|
...editorOpts,
|
|
10712
10989
|
mode,
|
|
10713
10990
|
tracks: tracksFor(mode),
|
|
10714
|
-
initialMML: mml ?? editorOpts.initialMML
|
|
10991
|
+
initialMML: mml ?? editorOpts.initialMML,
|
|
10992
|
+
onRequestAdvancedMode: (pendingMml, applyMidi) => {
|
|
10993
|
+
doUnmount();
|
|
10994
|
+
currentMode = "advanced";
|
|
10995
|
+
updateButtons();
|
|
10996
|
+
opts.onChange?.("advanced");
|
|
10997
|
+
doMount("advanced", pendingMml);
|
|
10998
|
+
if (applyMidi && daw) applyMidi(daw);
|
|
10999
|
+
}
|
|
10715
11000
|
});
|
|
10716
11001
|
attachWrapper();
|
|
10717
11002
|
opts.onMount?.(daw, mode);
|
|
@@ -10761,24 +11046,44 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10761
11046
|
(idx) => getRoleForTrackIndex(idx, isAdvancedMode ? "advanced" : "simple")
|
|
10762
11047
|
);
|
|
10763
11048
|
const loadTrackIds = trackIds.length > 0 ? trackIds : [...TRACK_ROLES];
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
11049
|
+
const playerTrackInstKeys = /* @__PURE__ */ new Map();
|
|
11050
|
+
const loadPlayerTrackInstruments = async () => {
|
|
11051
|
+
if (!meta.trackInstruments) return;
|
|
11052
|
+
await listReady;
|
|
11053
|
+
for (const [idxStr, name] of Object.entries(meta.trackInstruments)) {
|
|
11054
|
+
const key = resolveNameToKey(name);
|
|
11055
|
+
if (!key) continue;
|
|
11056
|
+
playerTrackInstKeys.set(Number(idxStr), key);
|
|
11057
|
+
await loadInstrument(key);
|
|
11058
|
+
}
|
|
11059
|
+
};
|
|
11060
|
+
void Promise.all([
|
|
11061
|
+
loadPreset(
|
|
10776
11062
|
playerPreset,
|
|
10777
|
-
|
|
11063
|
+
loadTrackIds,
|
|
10778
11064
|
isAdvancedMode ? "advanced" : "simple"
|
|
10779
|
-
)
|
|
10780
|
-
|
|
10781
|
-
|
|
11065
|
+
),
|
|
11066
|
+
loadPlayerTrackInstruments()
|
|
11067
|
+
]);
|
|
11068
|
+
const playPlayerNote = (e) => {
|
|
11069
|
+
const idx = Number(e.trackId);
|
|
11070
|
+
const overrideKey = playerTrackInstKeys.get(idx);
|
|
11071
|
+
let sfInst;
|
|
11072
|
+
if (overrideKey) {
|
|
11073
|
+
sfInst = soundFonts.get(overrideKey);
|
|
11074
|
+
} else {
|
|
11075
|
+
const role = getRoleForTrackIndex(
|
|
11076
|
+
idx,
|
|
11077
|
+
isAdvancedMode ? "advanced" : "simple"
|
|
11078
|
+
);
|
|
11079
|
+
sfInst = resolveSoundFont(
|
|
11080
|
+
playerPreset,
|
|
11081
|
+
role,
|
|
11082
|
+
isAdvancedMode ? "advanced" : "simple"
|
|
11083
|
+
);
|
|
11084
|
+
}
|
|
11085
|
+
if (!sfInst) return;
|
|
11086
|
+
sfInst.play({
|
|
10782
11087
|
ctx: audioCtx,
|
|
10783
11088
|
destination: masterGain,
|
|
10784
11089
|
pitch: e.pitch,
|
|
@@ -10837,6 +11142,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10837
11142
|
DRUM_FONT,
|
|
10838
11143
|
DRUM_KEYS,
|
|
10839
11144
|
DRUM_PATTERNS,
|
|
11145
|
+
GM_INSTRUMENT_NAMES,
|
|
10840
11146
|
INSTRUMENT_PRESETS,
|
|
10841
11147
|
KOE_BASE_URL,
|
|
10842
11148
|
KOE_VOICEBANKS,
|