@onjmin/dtm 0.1.1 → 0.1.5
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/LICENSE +21 -21
- package/README.md +37 -37
- package/dist/index.d.mts +191 -3
- package/dist/index.d.ts +191 -3
- package/dist/index.js +794 -91
- package/dist/index.mjs +783 -91
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -285,7 +285,10 @@ var buildUI = (target, options) => {
|
|
|
285
285
|
<div class="dtm-tracks" data-dtm="track-tabs"></div>
|
|
286
286
|
|
|
287
287
|
<div class="dtm-roll-wrap">
|
|
288
|
-
<div class="dtm-roll" data-dtm="roll"
|
|
288
|
+
<div class="dtm-roll" data-dtm="roll">
|
|
289
|
+
<div data-dtm="wrapper" style="position:absolute;inset:0;"></div>
|
|
290
|
+
<div class="dtm-overlay" data-dtm="overlay" hidden><div class="dtm-spinner"></div></div>
|
|
291
|
+
</div>
|
|
289
292
|
<div class="dtm-vscroll" data-dtm="vscroll"><div class="dtm-vscroll-thumb" data-dtm="vscroll-thumb"></div></div>
|
|
290
293
|
</div>
|
|
291
294
|
<div class="dtm-hscroll" data-dtm="hscroll"><div class="dtm-hscroll-thumb" data-dtm="hscroll-thumb"></div></div>
|
|
@@ -418,8 +421,6 @@ var buildUI = (target, options) => {
|
|
|
418
421
|
</div>
|
|
419
422
|
</div>
|
|
420
423
|
</details>
|
|
421
|
-
|
|
422
|
-
<div class="dtm-overlay" data-dtm="overlay" hidden><div class="dtm-spinner"></div></div>
|
|
423
424
|
</div>`;
|
|
424
425
|
const root = q(target, '[data-dtm="root"]');
|
|
425
426
|
const sel = (name) => q(root, `[data-dtm="${name}"]`);
|
|
@@ -906,6 +907,15 @@ var Worldline = class _Worldline {
|
|
|
906
907
|
}
|
|
907
908
|
};
|
|
908
909
|
|
|
910
|
+
// src/types.ts
|
|
911
|
+
var DEFAULT_VOCAL_VOLUME = 200;
|
|
912
|
+
var DEFAULT_BPM = 120;
|
|
913
|
+
var DEFAULT_GATE = 100;
|
|
914
|
+
var DEFAULT_PAN = 64;
|
|
915
|
+
var DEFAULT_VELOCITY = 100;
|
|
916
|
+
var DEFAULT_PLAYBACK_VELOCITY = 127;
|
|
917
|
+
var DEFAULT_STEPS_PER_BAR = 192;
|
|
918
|
+
|
|
909
919
|
// src/lyrics.ts
|
|
910
920
|
var kanaTable = {
|
|
911
921
|
\u3042: ["", "a"],
|
|
@@ -1076,9 +1086,10 @@ var parseLyrics = (mml) => {
|
|
|
1076
1086
|
const trackId = Number.parseInt(m[1], 10);
|
|
1077
1087
|
const tokens = m[2].trim().split(/\s+/);
|
|
1078
1088
|
const modelToken = tokens.shift() ?? "";
|
|
1079
|
-
let volume =
|
|
1089
|
+
let volume = DEFAULT_VOCAL_VOLUME;
|
|
1080
1090
|
let gate = 100;
|
|
1081
1091
|
let pan = 64;
|
|
1092
|
+
let octave = 0;
|
|
1082
1093
|
const colon = modelToken.indexOf(":");
|
|
1083
1094
|
const model = (colon === -1 ? modelToken : modelToken.slice(0, colon)).toLowerCase();
|
|
1084
1095
|
if (colon !== -1) {
|
|
@@ -1090,12 +1101,15 @@ var parseLyrics = (mml) => {
|
|
|
1090
1101
|
const v = /^v(\d+)$/.exec(tokens[0]);
|
|
1091
1102
|
const q2 = /^q(\d+)$/.exec(tokens[0]);
|
|
1092
1103
|
const p = /^p(\d+)$/.exec(tokens[0]);
|
|
1104
|
+
const o = /^o(-?\d+)$/.exec(tokens[0]);
|
|
1093
1105
|
if (v) {
|
|
1094
1106
|
volume = clamp(Number.parseInt(v[1], 10), 0, MAX_VOCAL_VOLUME);
|
|
1095
1107
|
} else if (q2) {
|
|
1096
1108
|
gate = clamp(Number.parseInt(q2[1], 10), 0, 100);
|
|
1097
1109
|
} else if (p) {
|
|
1098
1110
|
pan = clamp(Number.parseInt(p[1], 10), 0, 127);
|
|
1111
|
+
} else if (o) {
|
|
1112
|
+
octave = clamp(Number.parseInt(o[1], 10), -2, 2);
|
|
1099
1113
|
} else {
|
|
1100
1114
|
break;
|
|
1101
1115
|
}
|
|
@@ -1112,6 +1126,7 @@ var parseLyrics = (mml) => {
|
|
|
1112
1126
|
volume,
|
|
1113
1127
|
gate,
|
|
1114
1128
|
pan,
|
|
1129
|
+
octave,
|
|
1115
1130
|
syllables,
|
|
1116
1131
|
metaText: metaTokens.join(" "),
|
|
1117
1132
|
...lineBreaks.length > 0 ? { lineBreaks } : {}
|
|
@@ -1145,9 +1160,9 @@ var createLyricsConductor = (lyrics) => {
|
|
|
1145
1160
|
return {
|
|
1146
1161
|
model: track.model,
|
|
1147
1162
|
syllable,
|
|
1148
|
-
volume: vocalVolumeToGain(track.volume ??
|
|
1149
|
-
gate: (track.gate ??
|
|
1150
|
-
pan: panToStereo(track.pan ??
|
|
1163
|
+
volume: vocalVolumeToGain(track.volume ?? DEFAULT_VOCAL_VOLUME),
|
|
1164
|
+
gate: (track.gate ?? DEFAULT_GATE) / 100,
|
|
1165
|
+
pan: panToStereo(track.pan ?? DEFAULT_PAN)
|
|
1151
1166
|
};
|
|
1152
1167
|
};
|
|
1153
1168
|
const reset = () => pointers.clear();
|
|
@@ -1255,7 +1270,8 @@ var KOE_VOICEBANKS = {
|
|
|
1255
1270
|
tsukuyomi: "\u3064\u304F\u3088\u307F\u3061\u3083\u3093.koe",
|
|
1256
1271
|
rino: "\u6625\u97F3\u30EA\u30CEver0.3.koe",
|
|
1257
1272
|
roze: "\u675F\u97F3\u30ED\u30BCver0.\uFF151(\u591A\u97F3\u968E).koe",
|
|
1258
|
-
|
|
1273
|
+
ruko_male: "\u6B32\u97F3\u30EB\u30B3\u2642\u9023\u7D9A\u97F3Ver.1.03.koe",
|
|
1274
|
+
ruko_female: "\u6B32\u97F3\u30EB\u30B3\u2640\u6B4C\u9023\u7D9A\u97F3\u666E1.00.koe",
|
|
1259
1275
|
teto: "\u91CD\u97F3\u30C6\u30C8\u5358\u72EC\u97F3.koe",
|
|
1260
1276
|
shiyo: "\u9769\u547D\u30B7\u30E8.koe"
|
|
1261
1277
|
};
|
|
@@ -1263,10 +1279,30 @@ var KOE_VOICEBANK_LABELS = {
|
|
|
1263
1279
|
tsukuyomi: "\u3064\u304F\u3088\u307F\u3061\u3083\u3093",
|
|
1264
1280
|
rino: "\u6625\u97F3\u30EA\u30CE",
|
|
1265
1281
|
roze: "\u675F\u97F3\u30ED\u30BC",
|
|
1266
|
-
|
|
1282
|
+
ruko_male: "\u6B32\u97F3\u30EB\u30B3\u2642",
|
|
1283
|
+
ruko_female: "\u6B32\u97F3\u30EB\u30B3\u2640",
|
|
1267
1284
|
teto: "\u91CD\u97F3\u30C6\u30C8",
|
|
1268
1285
|
shiyo: "\u9769\u547D\u30B7\u30E8"
|
|
1269
1286
|
};
|
|
1287
|
+
var VOICE_IMAGE_KEY = {
|
|
1288
|
+
klatt: "puyuyu",
|
|
1289
|
+
tsukuyomi: "tsukuyomi",
|
|
1290
|
+
rino: "rino",
|
|
1291
|
+
roze: "roze",
|
|
1292
|
+
ruko_male: "ruko",
|
|
1293
|
+
ruko_female: "ruko",
|
|
1294
|
+
teto: "teto",
|
|
1295
|
+
shiyo: "shiyo"
|
|
1296
|
+
};
|
|
1297
|
+
var KOE_VOICEBANK_TERMS = {
|
|
1298
|
+
tsukuyomi: "https://tyc.rei-yumesaki.net/material/utau/terms/",
|
|
1299
|
+
rino: "https://hatenakun1.github.io/halunelino/",
|
|
1300
|
+
roze: "https://tabaneroze.ninja-web.net/terms-of-use.html",
|
|
1301
|
+
ruko_male: "https://long-sleeper.net/index.php?id=22",
|
|
1302
|
+
ruko_female: "https://long-sleeper.net/index.php?id=22",
|
|
1303
|
+
teto: "https://kasaneteto.jp/guidelines/voice.html",
|
|
1304
|
+
shiyo: "https://kakumeisiyo.my.canva.site/dagkuyjwycs"
|
|
1305
|
+
};
|
|
1270
1306
|
var koeUrl = (name, base = KOE_BASE_URL) => `${base}/${encodeURIComponent(name)}`;
|
|
1271
1307
|
var DEFAULT_WORLDLINE_SCRIPT = "https://onjmin.github.io/koe/demo/world/worldline.js";
|
|
1272
1308
|
var KOE_SAMPLE_RATE = 48e3;
|
|
@@ -1414,9 +1450,10 @@ var createWorkerBackend = async (workerUrl, options) => {
|
|
|
1414
1450
|
}
|
|
1415
1451
|
}
|
|
1416
1452
|
};
|
|
1417
|
-
worker.onerror = (e) =>
|
|
1418
|
-
|
|
1419
|
-
|
|
1453
|
+
worker.onerror = (e) => {
|
|
1454
|
+
const ev = e;
|
|
1455
|
+
onFail?.(new Error(ev.message || ev.error || `Event: ${ev.type}`));
|
|
1456
|
+
};
|
|
1420
1457
|
await new Promise((resolve, reject) => {
|
|
1421
1458
|
onReady = resolve;
|
|
1422
1459
|
onFail = reject;
|
|
@@ -1592,22 +1629,18 @@ var createSingingVoices = (ctx, destination, options = {}) => {
|
|
|
1592
1629
|
if (inflight) return inflight;
|
|
1593
1630
|
const koe = catalog[m];
|
|
1594
1631
|
if (!koe) return Promise.resolve(null);
|
|
1595
|
-
const p = (async () =>
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
source = await res.blob();
|
|
1603
|
-
}
|
|
1604
|
-
return createKoeVoice(ctx, destination, {
|
|
1605
|
-
koe: source,
|
|
1632
|
+
const p = (async () => (
|
|
1633
|
+
// URL文字列はそのまま渡す。koe側が VoiceBank.load 内で HTTP Range により
|
|
1634
|
+
// マニフェストだけ先読みし、音素PCMは歌う直前にオンデマンド取得する
|
|
1635
|
+
// (= 初回に .koe 全体をDLしない。モバイル初回ロードの待ちを解消)。
|
|
1636
|
+
// Blob/File が直接渡されたケース(ローカル読み込み)はそのまま BlobVoiceSource。
|
|
1637
|
+
createKoeVoice(ctx, destination, {
|
|
1638
|
+
koe,
|
|
1606
1639
|
worldlineScriptUrl: options.worldlineScriptUrl,
|
|
1607
1640
|
lightweight: options.lightweight,
|
|
1608
1641
|
voiceWorkerUrl: options.voiceWorkerUrl
|
|
1609
|
-
})
|
|
1610
|
-
|
|
1642
|
+
})
|
|
1643
|
+
))().then((v) => {
|
|
1611
1644
|
loaded.set(m, v);
|
|
1612
1645
|
return v;
|
|
1613
1646
|
}).catch((err) => {
|
|
@@ -2131,7 +2164,7 @@ var exportMIDI = (options) => {
|
|
|
2131
2164
|
(n.startStep + (n.durationSteps || 1)) * tickPerStep
|
|
2132
2165
|
);
|
|
2133
2166
|
const vel = Math.round(
|
|
2134
|
-
(n.velocity ??
|
|
2167
|
+
(n.velocity ?? DEFAULT_VELOCITY) * (track.volume ?? 100) / 100
|
|
2135
2168
|
);
|
|
2136
2169
|
events.push({ t: startTick, m: [144 | ch & 15, n.pitch, vel] });
|
|
2137
2170
|
events.push({ t: endTick, m: [144 | ch & 15, n.pitch, 0] });
|
|
@@ -2686,7 +2719,7 @@ var MMLCore = class _MMLCore {
|
|
|
2686
2719
|
startStep: step,
|
|
2687
2720
|
durationSteps: options.noteLengthSteps,
|
|
2688
2721
|
pitch,
|
|
2689
|
-
velocity: options.velocity ??
|
|
2722
|
+
velocity: options.velocity ?? DEFAULT_VELOCITY
|
|
2690
2723
|
};
|
|
2691
2724
|
this.notes.push(newNote);
|
|
2692
2725
|
}
|
|
@@ -2861,19 +2894,15 @@ var MMLCore = class _MMLCore {
|
|
|
2861
2894
|
notesByStep.set(n.startStep, list);
|
|
2862
2895
|
}
|
|
2863
2896
|
const sortedSteps = Array.from(notesByStep.keys()).sort((a, b) => a - b);
|
|
2897
|
+
const MIN_STEP = config.stepsPerBar / 64;
|
|
2864
2898
|
const fillRests = (until) => {
|
|
2865
|
-
while (currentCursor
|
|
2899
|
+
while (until - currentCursor >= MIN_STEP) {
|
|
2866
2900
|
const gap = until - currentCursor;
|
|
2867
|
-
if (gap <= 2) {
|
|
2868
|
-
currentCursor = until;
|
|
2869
|
-
break;
|
|
2870
|
-
}
|
|
2871
2901
|
const { dur, steps } = this.findBestFitDuration(gap);
|
|
2872
2902
|
segments.push(`r${dur}`);
|
|
2873
2903
|
currentCursor += steps;
|
|
2874
2904
|
}
|
|
2875
2905
|
};
|
|
2876
|
-
const MIN_STEP = config.stepsPerBar / 64;
|
|
2877
2906
|
for (let i = 0; i < sortedSteps.length; i++) {
|
|
2878
2907
|
const startStep = sortedSteps[i];
|
|
2879
2908
|
const notes = notesByStep.get(startStep);
|
|
@@ -2882,7 +2911,6 @@ var MMLCore = class _MMLCore {
|
|
|
2882
2911
|
const nextStart = sortedSteps[i + 1] ?? endStep;
|
|
2883
2912
|
const physicsLimit = nextStart - currentCursor;
|
|
2884
2913
|
if (physicsLimit < MIN_STEP) {
|
|
2885
|
-
currentCursor = startStep;
|
|
2886
2914
|
continue;
|
|
2887
2915
|
}
|
|
2888
2916
|
const idealDuration = notes[0].durationSteps;
|
|
@@ -3007,7 +3035,7 @@ var formatMmlMeta = (meta) => {
|
|
|
3007
3035
|
return parts.join(" ");
|
|
3008
3036
|
};
|
|
3009
3037
|
var parseMML = (mml, options = {}) => {
|
|
3010
|
-
const stepsPerBar = options.stepsPerBar ??
|
|
3038
|
+
const stepsPerBar = options.stepsPerBar ?? DEFAULT_STEPS_PER_BAR;
|
|
3011
3039
|
const collectTokens = options.collectTokens ?? false;
|
|
3012
3040
|
const collectLyrics = options.collectLyrics ?? false;
|
|
3013
3041
|
const clampTrackCount = options.clampTrackCount;
|
|
@@ -3084,14 +3112,14 @@ var parseMML = (mml, options = {}) => {
|
|
|
3084
3112
|
numStr += body[j];
|
|
3085
3113
|
j++;
|
|
3086
3114
|
}
|
|
3087
|
-
octave = clamp2(Number.parseInt(numStr, 10)
|
|
3115
|
+
octave = numStr ? clamp2(Number.parseInt(numStr, 10), 0, 8) : 4;
|
|
3088
3116
|
pushTok("octave", currentStep, 0, tokStart);
|
|
3089
3117
|
} else if (ch === ">") {
|
|
3090
|
-
octave
|
|
3118
|
+
octave = Math.min(8, octave + 1);
|
|
3091
3119
|
j++;
|
|
3092
3120
|
pushTok("shift", currentStep, 0, tokStart);
|
|
3093
3121
|
} else if (ch === "<") {
|
|
3094
|
-
octave
|
|
3122
|
+
octave = Math.max(0, octave - 1);
|
|
3095
3123
|
j++;
|
|
3096
3124
|
pushTok("shift", currentStep, 0, tokStart);
|
|
3097
3125
|
} else if (ch === "l") {
|
|
@@ -3138,10 +3166,10 @@ var parseMML = (mml, options = {}) => {
|
|
|
3138
3166
|
}
|
|
3139
3167
|
chordNotes.push((octave + 1) * 12 + pitch);
|
|
3140
3168
|
} else if (c === ">") {
|
|
3141
|
-
octave
|
|
3169
|
+
octave = Math.min(8, octave + 1);
|
|
3142
3170
|
j++;
|
|
3143
3171
|
} else if (c === "<") {
|
|
3144
|
-
octave
|
|
3172
|
+
octave = Math.max(0, octave - 1);
|
|
3145
3173
|
j++;
|
|
3146
3174
|
} else if (c === "o") {
|
|
3147
3175
|
j++;
|
|
@@ -3150,7 +3178,7 @@ var parseMML = (mml, options = {}) => {
|
|
|
3150
3178
|
numStr += body[j];
|
|
3151
3179
|
j++;
|
|
3152
3180
|
}
|
|
3153
|
-
octave = clamp2(Number.parseInt(numStr, 10)
|
|
3181
|
+
octave = numStr ? clamp2(Number.parseInt(numStr, 10), 0, 8) : 4;
|
|
3154
3182
|
} else {
|
|
3155
3183
|
j++;
|
|
3156
3184
|
}
|
|
@@ -3225,7 +3253,7 @@ var createSequencer = (options) => {
|
|
|
3225
3253
|
for (const note of track.notes) {
|
|
3226
3254
|
const relativeStart = note.startStep - fromStep;
|
|
3227
3255
|
if (relativeStart < 0) continue;
|
|
3228
|
-
const velocity = note.velocity ??
|
|
3256
|
+
const velocity = note.velocity ?? DEFAULT_PLAYBACK_VELOCITY;
|
|
3229
3257
|
timeline.push({
|
|
3230
3258
|
trackId: track.id,
|
|
3231
3259
|
pitch: note.pitch,
|
|
@@ -3844,6 +3872,13 @@ var DAW_CSS = `
|
|
|
3844
3872
|
|
|
3845
3873
|
.dtm-hidden { display: none !important; }
|
|
3846
3874
|
.dtm-grow { flex: 1 1 auto; }
|
|
3875
|
+
.dtm-lyric-icon {
|
|
3876
|
+
flex: 0 0 auto;
|
|
3877
|
+
width: 20px;
|
|
3878
|
+
height: 20px;
|
|
3879
|
+
border-radius: 50%;
|
|
3880
|
+
object-fit: cover;
|
|
3881
|
+
}
|
|
3847
3882
|
|
|
3848
3883
|
/* \u2500\u2500\u2500 \u5E83\u5E45\u62E1\u5F35 \u2500\u2500\u2500 */
|
|
3849
3884
|
@media (min-width: 768px) {
|
|
@@ -3886,13 +3921,26 @@ var DAW_CSS = `
|
|
|
3886
3921
|
.dtm-player-play:active { transform: translate(2px, 2px); box-shadow: none; }
|
|
3887
3922
|
.dtm-player-play--stop { background: var(--dtm-danger); }
|
|
3888
3923
|
.dtm-player-play:disabled { opacity: 0.4; cursor: default; }
|
|
3889
|
-
.dtm-player-
|
|
3890
|
-
|
|
3924
|
+
.dtm-player-beat-row {
|
|
3925
|
+
display: flex;
|
|
3926
|
+
align-items: center;
|
|
3927
|
+
gap: 4px;
|
|
3928
|
+
}
|
|
3929
|
+
.dtm-player-beat-dot {
|
|
3930
|
+
width: 8px;
|
|
3931
|
+
height: 8px;
|
|
3932
|
+
border-radius: 50%;
|
|
3933
|
+
background: var(--dtm-border2);
|
|
3934
|
+
transition: background 0.06s;
|
|
3935
|
+
}
|
|
3936
|
+
.dtm-player-beat-dot--on { background: var(--dtm-primary); }
|
|
3937
|
+
.dtm-player-bar {
|
|
3891
3938
|
font-family: 'k8x12', monospace;
|
|
3892
|
-
font-size:
|
|
3893
|
-
color: var(--dtm-
|
|
3939
|
+
font-size: 11px;
|
|
3940
|
+
color: var(--dtm-text);
|
|
3941
|
+
min-width: 2em;
|
|
3942
|
+
margin-left: 4px;
|
|
3894
3943
|
}
|
|
3895
|
-
.dtm-player-time { color: var(--dtm-text); min-width: 3em; }
|
|
3896
3944
|
.dtm-player-dots {
|
|
3897
3945
|
margin-left: auto;
|
|
3898
3946
|
display: flex;
|
|
@@ -3900,6 +3948,40 @@ var DAW_CSS = `
|
|
|
3900
3948
|
gap: 6px;
|
|
3901
3949
|
}
|
|
3902
3950
|
.dtm-player-dot { width: 8px; height: 8px; display: inline-block; }
|
|
3951
|
+
.dtm-player-mml-header {
|
|
3952
|
+
margin-left: auto;
|
|
3953
|
+
display: flex;
|
|
3954
|
+
align-items: center;
|
|
3955
|
+
gap: 4px;
|
|
3956
|
+
}
|
|
3957
|
+
.dtm-player-mml-link {
|
|
3958
|
+
font-family: 'k8x12', monospace;
|
|
3959
|
+
font-size: 10px;
|
|
3960
|
+
color: var(--dtm-muted);
|
|
3961
|
+
text-decoration: none;
|
|
3962
|
+
white-space: nowrap;
|
|
3963
|
+
}
|
|
3964
|
+
.dtm-player-mml-link:hover { color: var(--dtm-primary); }
|
|
3965
|
+
.dtm-player-emoji {
|
|
3966
|
+
display: inline-flex;
|
|
3967
|
+
align-items: center;
|
|
3968
|
+
justify-content: center;
|
|
3969
|
+
width: 20px;
|
|
3970
|
+
height: 20px;
|
|
3971
|
+
border-radius: 50%;
|
|
3972
|
+
font-size: 18px;
|
|
3973
|
+
line-height: 1;
|
|
3974
|
+
user-select: none;
|
|
3975
|
+
}
|
|
3976
|
+
@keyframes dtm-emoji-jump {
|
|
3977
|
+
0% { transform: translateY(0); }
|
|
3978
|
+
35% { transform: translateY(-5px); }
|
|
3979
|
+
65% { transform: translateY(-5px); }
|
|
3980
|
+
100% { transform: translateY(0); }
|
|
3981
|
+
}
|
|
3982
|
+
.dtm-player-emoji--jump {
|
|
3983
|
+
animation: dtm-emoji-jump 0.18s ease-out forwards;
|
|
3984
|
+
}
|
|
3903
3985
|
.dtm-player-chip {
|
|
3904
3986
|
font-family: 'k8x12', monospace;
|
|
3905
3987
|
font-size: 9px;
|
|
@@ -3908,6 +3990,12 @@ var DAW_CSS = `
|
|
|
3908
3990
|
padding: 2px 6px;
|
|
3909
3991
|
white-space: nowrap;
|
|
3910
3992
|
}
|
|
3993
|
+
.dtm-player-body {
|
|
3994
|
+
position: relative; /* \u30ED\u30FC\u30C7\u30A3\u30F3\u30B0\u30AA\u30FC\u30D0\u30FC\u30EC\u30A4\u306E\u57FA\u6E96\u3002\u30EC\u30FC\u30F3\u7FA4\u3060\u3051\u3092\u8986\u3046 */
|
|
3995
|
+
display: flex;
|
|
3996
|
+
flex-direction: column;
|
|
3997
|
+
gap: var(--dtm-gap);
|
|
3998
|
+
}
|
|
3911
3999
|
.dtm-player-lane-row {
|
|
3912
4000
|
display: flex;
|
|
3913
4001
|
align-items: stretch;
|
|
@@ -3922,6 +4010,12 @@ var DAW_CSS = `
|
|
|
3922
4010
|
gap: 2px;
|
|
3923
4011
|
padding-top: 4px;
|
|
3924
4012
|
}
|
|
4013
|
+
.dtm-player-lane-label--btn {
|
|
4014
|
+
cursor: pointer;
|
|
4015
|
+
user-select: none;
|
|
4016
|
+
}
|
|
4017
|
+
.dtm-player-lane-label--btn:hover { opacity: 0.7; }
|
|
4018
|
+
.dtm-player-lane-label--muted { opacity: 0.3; }
|
|
3925
4019
|
.dtm-player-lane-no {
|
|
3926
4020
|
font-family: 'k8x12', monospace;
|
|
3927
4021
|
font-size: 9px;
|
|
@@ -4004,6 +4098,38 @@ var showLoadingOverlay = (container) => {
|
|
|
4004
4098
|
};
|
|
4005
4099
|
};
|
|
4006
4100
|
|
|
4101
|
+
// assets/puyuyu.png
|
|
4102
|
+
var puyuyu_default = "data:image/png;base64,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";
|
|
4103
|
+
|
|
4104
|
+
// assets/rino.png
|
|
4105
|
+
var rino_default = "data:image/png;base64,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";
|
|
4106
|
+
|
|
4107
|
+
// assets/roze.png
|
|
4108
|
+
var roze_default = "data:image/png;base64,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";
|
|
4109
|
+
|
|
4110
|
+
// assets/ruko.png
|
|
4111
|
+
var ruko_default = "data:image/png;base64,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";
|
|
4112
|
+
|
|
4113
|
+
// assets/shiyo.png
|
|
4114
|
+
var shiyo_default = "data:image/png;base64,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";
|
|
4115
|
+
|
|
4116
|
+
// assets/teto.png
|
|
4117
|
+
var teto_default = "data:image/png;base64,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";
|
|
4118
|
+
|
|
4119
|
+
// assets/tsukuyomi.png
|
|
4120
|
+
var tsukuyomi_default = "data:image/png;base64,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";
|
|
4121
|
+
|
|
4122
|
+
// src/voice-images.ts
|
|
4123
|
+
var VOICE_IMAGES = {
|
|
4124
|
+
puyuyu: puyuyu_default,
|
|
4125
|
+
rino: rino_default,
|
|
4126
|
+
roze: roze_default,
|
|
4127
|
+
ruko: ruko_default,
|
|
4128
|
+
shiyo: shiyo_default,
|
|
4129
|
+
teto: teto_default,
|
|
4130
|
+
tsukuyomi: tsukuyomi_default
|
|
4131
|
+
};
|
|
4132
|
+
|
|
4007
4133
|
// src/daw.ts
|
|
4008
4134
|
var BASE_STEP_WIDTH = 0.5;
|
|
4009
4135
|
var BASE_KEY_HEIGHT = 15;
|
|
@@ -4170,7 +4296,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
4170
4296
|
tracks: trackConfigs,
|
|
4171
4297
|
drumPatternNames: Object.keys(drumPatterns),
|
|
4172
4298
|
defaultDrumPattern: drumPatterns.dance ? "dance" : Object.keys(drumPatterns)[0] ?? "none",
|
|
4173
|
-
defaultBpm: options.defaultBpm ??
|
|
4299
|
+
defaultBpm: options.defaultBpm ?? DEFAULT_BPM,
|
|
4174
4300
|
showMidi,
|
|
4175
4301
|
showChord
|
|
4176
4302
|
});
|
|
@@ -4185,7 +4311,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
4185
4311
|
const leftPaddingSteps = renderConfig.stepsPerBar * 16;
|
|
4186
4312
|
let zoomX = 100;
|
|
4187
4313
|
let zoomY = 100;
|
|
4188
|
-
let bpm = options.defaultBpm ??
|
|
4314
|
+
let bpm = options.defaultBpm ?? DEFAULT_BPM;
|
|
4189
4315
|
let masterVolume = 50;
|
|
4190
4316
|
let drumVolume = 80;
|
|
4191
4317
|
let currentDrumPattern = refs.drumSelect.value;
|
|
@@ -4230,9 +4356,10 @@ var mountDAW = (target, options = {}) => {
|
|
|
4230
4356
|
lyrics: "",
|
|
4231
4357
|
lyricModel: "",
|
|
4232
4358
|
// 既定は「なし」(歌わない)
|
|
4233
|
-
vocalVolume:
|
|
4359
|
+
vocalVolume: DEFAULT_VOCAL_VOLUME,
|
|
4234
4360
|
vocalGate: 100,
|
|
4235
|
-
vocalPan: 64
|
|
4361
|
+
vocalPan: 64,
|
|
4362
|
+
vocalOctave: 0
|
|
4236
4363
|
}));
|
|
4237
4364
|
};
|
|
4238
4365
|
const buildLyricsMap = () => {
|
|
@@ -4249,6 +4376,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
4249
4376
|
volume: t.vocalVolume,
|
|
4250
4377
|
gate: t.vocalGate,
|
|
4251
4378
|
pan: t.vocalPan,
|
|
4379
|
+
octave: t.vocalOctave,
|
|
4252
4380
|
syllables
|
|
4253
4381
|
});
|
|
4254
4382
|
});
|
|
@@ -4767,6 +4895,13 @@ var mountDAW = (target, options = {}) => {
|
|
|
4767
4895
|
setDrawOffset(currentOffsetX, currentOffsetY);
|
|
4768
4896
|
redrawAll();
|
|
4769
4897
|
};
|
|
4898
|
+
const getViewState = () => ({
|
|
4899
|
+
zoomX,
|
|
4900
|
+
zoomY,
|
|
4901
|
+
decomposeChord: refs.decomposeChordToggle.checked,
|
|
4902
|
+
ignoreChordHeavy: refs.ignoreChordHeavyToggle.checked
|
|
4903
|
+
});
|
|
4904
|
+
const notifyViewState = () => options.onViewStateChange?.(getViewState());
|
|
4770
4905
|
const dispatchNote = (trackId, pitch, trackVol, velocity, when, duration) => {
|
|
4771
4906
|
const volume = trackVol / 100 * (velocity / 127) * (masterVolume / 100);
|
|
4772
4907
|
options.onPlayNote?.({ trackId, pitch, velocity, volume, when, duration });
|
|
@@ -4826,7 +4961,8 @@ var mountDAW = (target, options = {}) => {
|
|
|
4826
4961
|
const sorted = [...trackState?.core.getNotes() ?? []].sort(
|
|
4827
4962
|
(a, b) => a.startStep - b.startStep
|
|
4828
4963
|
);
|
|
4829
|
-
const gate = (lt.gate ??
|
|
4964
|
+
const gate = (lt.gate ?? DEFAULT_GATE) / 100;
|
|
4965
|
+
const semis = (lt.octave ?? 0) * 12;
|
|
4830
4966
|
const count = Math.min(sorted.length, lt.syllables.length);
|
|
4831
4967
|
const notes = [];
|
|
4832
4968
|
for (let i = 0; i < count; i++) {
|
|
@@ -4834,22 +4970,22 @@ var mountDAW = (target, options = {}) => {
|
|
|
4834
4970
|
if (n.startStep < fromStep) continue;
|
|
4835
4971
|
notes.push({
|
|
4836
4972
|
syllable: lt.syllables[i],
|
|
4837
|
-
pitch: n.pitch,
|
|
4973
|
+
pitch: n.pitch + semis,
|
|
4838
4974
|
startSec: (n.startStep - fromStep) * secondsPerStep,
|
|
4839
4975
|
durationSec: n.durationSteps * secondsPerStep * gate
|
|
4840
4976
|
});
|
|
4841
4977
|
}
|
|
4842
4978
|
return {
|
|
4843
4979
|
model: lt.model,
|
|
4844
|
-
volume: vocalVolumeToGain(lt.volume ??
|
|
4845
|
-
pan: panToStereo(lt.pan ??
|
|
4980
|
+
volume: vocalVolumeToGain(lt.volume ?? DEFAULT_VOCAL_VOLUME) * (masterVolume / 100),
|
|
4981
|
+
pan: panToStereo(lt.pan ?? DEFAULT_PAN),
|
|
4846
4982
|
notes
|
|
4847
4983
|
};
|
|
4848
4984
|
}) : [];
|
|
4849
4985
|
const voices = options.singingVoices;
|
|
4850
4986
|
const streaming = !!voices && streamTracks.some((t) => t.notes.length > 0);
|
|
4851
4987
|
if (streaming && voices) {
|
|
4852
|
-
const overlay = showLoadingOverlay(
|
|
4988
|
+
const overlay = showLoadingOverlay(refs.rollContainer);
|
|
4853
4989
|
try {
|
|
4854
4990
|
await voices.loadModels(streamTracks.map((t) => t.model));
|
|
4855
4991
|
await voices.warm(streamTracks);
|
|
@@ -4942,12 +5078,25 @@ var mountDAW = (target, options = {}) => {
|
|
|
4942
5078
|
<div class="dtm-row">
|
|
4943
5079
|
<span class="dtm-label">\u266A \u6B4C\u8A5E</span>
|
|
4944
5080
|
<select class="dtm-select" data-dtm="lyric-model" aria-label="\u6B4C\u5531\u30E2\u30C7\u30EB"></select>
|
|
5081
|
+
<img class="dtm-lyric-icon dtm-hidden" data-dtm="lyric-icon" width="20" height="20" alt="" draggable="false">
|
|
5082
|
+
<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">
|
|
5083
|
+
<option value="2">+2 oct</option>
|
|
5084
|
+
<option value="1">+1 oct</option>
|
|
5085
|
+
<option value="0">\xB10 oct</option>
|
|
5086
|
+
<option value="-1">-1 oct</option>
|
|
5087
|
+
<option value="-2">-2 oct</option>
|
|
5088
|
+
</select>
|
|
4945
5089
|
<span class="dtm-label dtm-grow" data-dtm="lyric-count" style="text-align:right"></span>
|
|
4946
5090
|
</div>
|
|
5091
|
+
<div class="dtm-row dtm-hidden" data-dtm="lyric-terms" style="font-size:10px;gap:4px;color:var(--dtm-warn)">
|
|
5092
|
+
<span>\u4F7F\u7528\u6642\u306B\u306F</span>
|
|
5093
|
+
<a data-dtm="lyric-terms-link" target="_blank" rel="noopener" style="color:var(--dtm-primary);text-decoration:underline"></a>
|
|
5094
|
+
<span>\u306E\u5229\u7528\u898F\u7D04\u306B\u5F93\u3063\u3066\u304F\u3060\u3055\u3044</span>
|
|
5095
|
+
</div>
|
|
4947
5096
|
<div class="dtm-row" data-dtm="lyric-body" style="flex-direction:column;align-items:stretch">
|
|
4948
5097
|
<div class="dtm-row">
|
|
4949
5098
|
<span class="dtm-label">\u58F0\u91CF</span>
|
|
4950
|
-
<input type="range" class="dtm-range dtm-grow" data-dtm="lyric-vol" min="0" max="${MAX_VOCAL_VOLUME}" aria-label="\u6B4C\u5531\u306E\u58F0\u91CF\uFF08100=\u7B49\u500D\u3001100\u8D85\u3067\u30D6\u30FC\u30B9\u30C8\u3001\u65E2\
|
|
5099
|
+
<input type="range" class="dtm-range dtm-grow" data-dtm="lyric-vol" min="0" max="${MAX_VOCAL_VOLUME}" aria-label="\u6B4C\u5531\u306E\u58F0\u91CF\uFF08100=\u7B49\u500D\u3001100\u8D85\u3067\u30D6\u30FC\u30B9\u30C8\u3001\u65E2\u5B9A200\uFF09">
|
|
4951
5100
|
<span class="dtm-label" data-dtm="lyric-vol-label"></span>
|
|
4952
5101
|
</div>
|
|
4953
5102
|
<div class="dtm-row">
|
|
@@ -4961,6 +5110,12 @@ var mountDAW = (target, options = {}) => {
|
|
|
4961
5110
|
const lyricModelSel = lyricDiv.querySelector(
|
|
4962
5111
|
'[data-dtm="lyric-model"]'
|
|
4963
5112
|
);
|
|
5113
|
+
const lyricOctaveSel = lyricDiv.querySelector(
|
|
5114
|
+
'[data-dtm="lyric-octave"]'
|
|
5115
|
+
);
|
|
5116
|
+
const lyricIcon = lyricDiv.querySelector(
|
|
5117
|
+
'[data-dtm="lyric-icon"]'
|
|
5118
|
+
);
|
|
4964
5119
|
const lyricBody = lyricDiv.querySelector(
|
|
4965
5120
|
'[data-dtm="lyric-body"]'
|
|
4966
5121
|
);
|
|
@@ -4982,6 +5137,12 @@ var mountDAW = (target, options = {}) => {
|
|
|
4982
5137
|
const lyricPanLabel = lyricDiv.querySelector(
|
|
4983
5138
|
'[data-dtm="lyric-pan-label"]'
|
|
4984
5139
|
);
|
|
5140
|
+
const lyricTerms = lyricDiv.querySelector(
|
|
5141
|
+
'[data-dtm="lyric-terms"]'
|
|
5142
|
+
);
|
|
5143
|
+
const lyricTermsLink = lyricDiv.querySelector(
|
|
5144
|
+
'[data-dtm="lyric-terms-link"]'
|
|
5145
|
+
);
|
|
4985
5146
|
const fmtPan = (pan) => pan === 64 ? "C" : pan < 64 ? `L${64 - pan}` : `R${pan - 64}`;
|
|
4986
5147
|
const addOpt = (value, label) => {
|
|
4987
5148
|
const o = document.createElement("option");
|
|
@@ -4995,6 +5156,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
4995
5156
|
addOpt(active.lyricModel, lyricModelLabel(active.lyricModel));
|
|
4996
5157
|
}
|
|
4997
5158
|
lyricModelSel.value = active.lyricModel;
|
|
5159
|
+
lyricOctaveSel.value = String(active.vocalOctave);
|
|
4998
5160
|
lyricInput.value = active.lyrics;
|
|
4999
5161
|
lyricVol.value = String(active.vocalVolume);
|
|
5000
5162
|
lyricVolLabel.textContent = String(active.vocalVolume);
|
|
@@ -5004,15 +5166,43 @@ var mountDAW = (target, options = {}) => {
|
|
|
5004
5166
|
const n = normalizeLyrics(lyricInput.value).length;
|
|
5005
5167
|
lyricCount.textContent = active.lyricModel && n > 0 ? `${n}\u97F3\u7BC0` : "";
|
|
5006
5168
|
};
|
|
5169
|
+
const syncLyricTerms = () => {
|
|
5170
|
+
const url = active.lyricModel ? KOE_VOICEBANK_TERMS[active.lyricModel] : void 0;
|
|
5171
|
+
if (url) {
|
|
5172
|
+
const label = lyricModelLabel(active.lyricModel);
|
|
5173
|
+
lyricTermsLink.textContent = `${label}UTAU\u97F3\u6E90`;
|
|
5174
|
+
lyricTermsLink.href = url;
|
|
5175
|
+
lyricTerms.classList.remove("dtm-hidden");
|
|
5176
|
+
} else {
|
|
5177
|
+
lyricTerms.classList.add("dtm-hidden");
|
|
5178
|
+
}
|
|
5179
|
+
};
|
|
5180
|
+
const syncLyricIcon = () => {
|
|
5181
|
+
const imgKey = active.lyricModel ? VOICE_IMAGE_KEY[active.lyricModel.toLowerCase()] : void 0;
|
|
5182
|
+
const src = imgKey ? VOICE_IMAGES[imgKey] : void 0;
|
|
5183
|
+
if (src) {
|
|
5184
|
+
lyricIcon.src = src;
|
|
5185
|
+
lyricIcon.classList.remove("dtm-hidden");
|
|
5186
|
+
} else {
|
|
5187
|
+
lyricIcon.removeAttribute("src");
|
|
5188
|
+
lyricIcon.classList.add("dtm-hidden");
|
|
5189
|
+
}
|
|
5190
|
+
};
|
|
5007
5191
|
const syncLyricVisibility = () => {
|
|
5008
5192
|
lyricBody.style.display = active.lyricModel ? "" : "none";
|
|
5193
|
+
lyricOctaveSel.style.display = active.lyricModel ? "" : "none";
|
|
5009
5194
|
updateLyricCount();
|
|
5195
|
+
syncLyricTerms();
|
|
5196
|
+
syncLyricIcon();
|
|
5010
5197
|
};
|
|
5011
5198
|
syncLyricVisibility();
|
|
5012
5199
|
lyricModelSel.addEventListener("change", () => {
|
|
5013
5200
|
active.lyricModel = lyricModelSel.value;
|
|
5014
5201
|
syncLyricVisibility();
|
|
5015
5202
|
});
|
|
5203
|
+
lyricOctaveSel.addEventListener("change", () => {
|
|
5204
|
+
active.vocalOctave = Number.parseInt(lyricOctaveSel.value, 10);
|
|
5205
|
+
});
|
|
5016
5206
|
lyricInput.addEventListener("input", () => {
|
|
5017
5207
|
active.lyrics = lyricInput.value;
|
|
5018
5208
|
updateLyricCount();
|
|
@@ -5161,12 +5351,14 @@ var mountDAW = (target, options = {}) => {
|
|
|
5161
5351
|
model: t.lyricModel.trim(),
|
|
5162
5352
|
vol: t.vocalVolume,
|
|
5163
5353
|
gate: t.vocalGate,
|
|
5164
|
-
pan: t.vocalPan
|
|
5354
|
+
pan: t.vocalPan,
|
|
5355
|
+
oct: t.vocalOctave
|
|
5165
5356
|
})).filter((x) => x.model.length > 0 && x.text.length > 0).map((x) => {
|
|
5166
5357
|
const params = [
|
|
5167
|
-
x.vol ===
|
|
5358
|
+
x.vol === DEFAULT_VOCAL_VOLUME ? "" : `v${x.vol}`,
|
|
5168
5359
|
x.gate === 100 ? "" : `q${x.gate}`,
|
|
5169
|
-
x.pan === 64 ? "" : `p${x.pan}
|
|
5360
|
+
x.pan === 64 ? "" : `p${x.pan}`,
|
|
5361
|
+
x.oct === 0 ? "" : `o${x.oct}`
|
|
5170
5362
|
].filter((s) => s.length > 0).join(" ");
|
|
5171
5363
|
const head = params ? `${x.model} ${params}` : x.model;
|
|
5172
5364
|
return `@@${x.i} ${head} ${x.text}`;
|
|
@@ -5247,6 +5439,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
5247
5439
|
if (meta.drum && drumPatterns[meta.drum]) {
|
|
5248
5440
|
currentDrumPattern = meta.drum;
|
|
5249
5441
|
refs.drumSelect.value = meta.drum;
|
|
5442
|
+
options.onDrumChange?.(meta.drum);
|
|
5250
5443
|
}
|
|
5251
5444
|
if (meta.volume !== void 0) {
|
|
5252
5445
|
masterVolume = meta.volume;
|
|
@@ -5256,9 +5449,10 @@ var mountDAW = (target, options = {}) => {
|
|
|
5256
5449
|
for (const t of trackStates) {
|
|
5257
5450
|
t.lyrics = "";
|
|
5258
5451
|
t.lyricModel = "";
|
|
5259
|
-
t.vocalVolume =
|
|
5452
|
+
t.vocalVolume = DEFAULT_VOCAL_VOLUME;
|
|
5260
5453
|
t.vocalGate = 100;
|
|
5261
5454
|
t.vocalPan = 64;
|
|
5455
|
+
t.vocalOctave = 0;
|
|
5262
5456
|
}
|
|
5263
5457
|
lyrics?.forEach((lt, idx) => {
|
|
5264
5458
|
const t = trackStates[idx];
|
|
@@ -5268,6 +5462,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
5268
5462
|
t.vocalVolume = lt.volume;
|
|
5269
5463
|
t.vocalGate = lt.gate;
|
|
5270
5464
|
t.vocalPan = lt.pan;
|
|
5465
|
+
t.vocalOctave = lt.octave ?? 0;
|
|
5271
5466
|
});
|
|
5272
5467
|
for (const p of placements) {
|
|
5273
5468
|
const t = trackStates[p.trackIndex];
|
|
@@ -5419,25 +5614,32 @@ var mountDAW = (target, options = {}) => {
|
|
|
5419
5614
|
refs.zoomXIn.addEventListener("click", () => {
|
|
5420
5615
|
zoomX = Math.min(200, zoomX + 25);
|
|
5421
5616
|
applyZoomX();
|
|
5617
|
+
notifyViewState();
|
|
5422
5618
|
});
|
|
5423
5619
|
refs.zoomXOut.addEventListener("click", () => {
|
|
5424
5620
|
zoomX = Math.max(25, zoomX - 25);
|
|
5425
5621
|
applyZoomX();
|
|
5622
|
+
notifyViewState();
|
|
5426
5623
|
});
|
|
5427
5624
|
refs.zoomYIn.addEventListener("click", () => {
|
|
5428
5625
|
zoomY = Math.min(200, zoomY + 25);
|
|
5429
5626
|
applyZoomY();
|
|
5627
|
+
notifyViewState();
|
|
5430
5628
|
});
|
|
5431
5629
|
refs.zoomYOut.addEventListener("click", () => {
|
|
5432
5630
|
zoomY = Math.max(50, zoomY - 25);
|
|
5433
5631
|
applyZoomY();
|
|
5632
|
+
notifyViewState();
|
|
5434
5633
|
});
|
|
5634
|
+
refs.decomposeChordToggle.addEventListener("change", notifyViewState);
|
|
5635
|
+
refs.ignoreChordHeavyToggle.addEventListener("change", notifyViewState);
|
|
5435
5636
|
refs.masterVolume.addEventListener("input", () => {
|
|
5436
5637
|
masterVolume = Number.parseInt(refs.masterVolume.value, 10) || 0;
|
|
5437
5638
|
refs.masterVolumeLabel.textContent = `${masterVolume}%`;
|
|
5438
5639
|
});
|
|
5439
5640
|
refs.drumSelect.addEventListener("change", () => {
|
|
5440
5641
|
currentDrumPattern = refs.drumSelect.value;
|
|
5642
|
+
options.onDrumChange?.(currentDrumPattern);
|
|
5441
5643
|
});
|
|
5442
5644
|
refs.drumVolume.addEventListener("input", () => {
|
|
5443
5645
|
drumVolume = Number.parseInt(refs.drumVolume.value, 10) || 0;
|
|
@@ -5630,6 +5832,30 @@ var mountDAW = (target, options = {}) => {
|
|
|
5630
5832
|
setInstrument: (name) => {
|
|
5631
5833
|
currentInstrument = name;
|
|
5632
5834
|
},
|
|
5835
|
+
getDrum: () => currentDrumPattern,
|
|
5836
|
+
setDrum: (name) => {
|
|
5837
|
+
if (name !== "none" && !drumPatterns[name]) return;
|
|
5838
|
+
currentDrumPattern = name;
|
|
5839
|
+
refs.drumSelect.value = name;
|
|
5840
|
+
options.onDrumChange?.(name);
|
|
5841
|
+
},
|
|
5842
|
+
getViewState,
|
|
5843
|
+
setViewState: (state) => {
|
|
5844
|
+
if (typeof state.zoomX === "number") {
|
|
5845
|
+
zoomX = clamp3(state.zoomX, 25, 200);
|
|
5846
|
+
applyZoomX();
|
|
5847
|
+
}
|
|
5848
|
+
if (typeof state.zoomY === "number") {
|
|
5849
|
+
zoomY = clamp3(state.zoomY, 50, 200);
|
|
5850
|
+
applyZoomY();
|
|
5851
|
+
}
|
|
5852
|
+
if (typeof state.decomposeChord === "boolean") {
|
|
5853
|
+
refs.decomposeChordToggle.checked = state.decomposeChord;
|
|
5854
|
+
}
|
|
5855
|
+
if (typeof state.ignoreChordHeavy === "boolean") {
|
|
5856
|
+
refs.ignoreChordHeavyToggle.checked = state.ignoreChordHeavy;
|
|
5857
|
+
}
|
|
5858
|
+
},
|
|
5633
5859
|
loadMML,
|
|
5634
5860
|
loadMIDI,
|
|
5635
5861
|
exportMIDI: exportMIDI2,
|
|
@@ -5755,11 +5981,6 @@ var STEPS_PER_BEAT3 = 48;
|
|
|
5755
5981
|
var STEPS_PER_BAR = 192;
|
|
5756
5982
|
var DEFAULT_TRACK_COLORS = ["#00e436", "#29adff", "#ff77a8", "#ffec27"];
|
|
5757
5983
|
var activePlayer = null;
|
|
5758
|
-
var formatTime = (seconds) => {
|
|
5759
|
-
const m = Math.floor(seconds / 60);
|
|
5760
|
-
const s = Math.floor(seconds % 60);
|
|
5761
|
-
return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
|
|
5762
|
-
};
|
|
5763
5984
|
var freqFromPitch = (pitch) => 440 * 2 ** ((pitch - 69) / 12);
|
|
5764
5985
|
var mountMmlPlayer = (target, mml, options = {}) => {
|
|
5765
5986
|
injectStyles(target.ownerDocument ?? document);
|
|
@@ -5774,7 +5995,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
5774
5995
|
collectLyrics: true
|
|
5775
5996
|
});
|
|
5776
5997
|
const lyricTracks = lyrics ?? /* @__PURE__ */ new Map();
|
|
5777
|
-
const bpm = parsedBpm ?? options.defaultBpm ??
|
|
5998
|
+
const bpm = parsedBpm ?? options.defaultBpm ?? DEFAULT_BPM;
|
|
5778
5999
|
const drumPatternDict = options.drumPatterns ?? DRUM_PATTERNS;
|
|
5779
6000
|
const drumPattern = meta.drum ? drumPatternDict[meta.drum] ?? null : null;
|
|
5780
6001
|
const trackVolume = meta.volume ?? options.volume ?? 100;
|
|
@@ -5889,32 +6110,118 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
5889
6110
|
playBtn.className = "dtm-player-play";
|
|
5890
6111
|
playBtn.innerHTML = icon("play", 12);
|
|
5891
6112
|
playBtn.disabled = trackIndices.length === 0;
|
|
5892
|
-
const
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
const
|
|
5896
|
-
|
|
5897
|
-
|
|
6113
|
+
const mmlHeader = doc.createElement("div");
|
|
6114
|
+
mmlHeader.className = "dtm-player-mml-header";
|
|
6115
|
+
const emojiEls = [];
|
|
6116
|
+
const emojiByTrack = /* @__PURE__ */ new Map();
|
|
6117
|
+
for (const index of trackIndices) {
|
|
6118
|
+
const em = doc.createElement("span");
|
|
6119
|
+
em.className = "dtm-player-emoji";
|
|
6120
|
+
em.style.backgroundColor = colorOf(index);
|
|
6121
|
+
em.textContent = "\u{1F97A}";
|
|
6122
|
+
mmlHeader.appendChild(em);
|
|
6123
|
+
emojiEls.push(em);
|
|
6124
|
+
emojiByTrack.set(index, em);
|
|
6125
|
+
}
|
|
6126
|
+
const promotedToImage = /* @__PURE__ */ new Set();
|
|
6127
|
+
for (const [index, lt] of lyricTracks) {
|
|
6128
|
+
const em = emojiByTrack.get(index);
|
|
6129
|
+
if (!em) continue;
|
|
6130
|
+
const imgKey = VOICE_IMAGE_KEY[lt.model.toLowerCase()];
|
|
6131
|
+
const src = imgKey ? VOICE_IMAGES[imgKey] : void 0;
|
|
6132
|
+
if (!src) continue;
|
|
6133
|
+
const img = doc.createElement("img");
|
|
6134
|
+
img.src = src;
|
|
6135
|
+
img.width = 20;
|
|
6136
|
+
img.height = 20;
|
|
6137
|
+
img.style.borderRadius = "50%";
|
|
6138
|
+
img.style.objectFit = "cover";
|
|
6139
|
+
img.draggable = false;
|
|
6140
|
+
promotedToImage.add(em);
|
|
6141
|
+
em.textContent = "";
|
|
6142
|
+
em.appendChild(img);
|
|
6143
|
+
}
|
|
6144
|
+
const JUMP_DEDUPE_MS = 50;
|
|
6145
|
+
const lastJumpAt = /* @__PURE__ */ new WeakMap();
|
|
6146
|
+
const jumpEmoji = (em) => {
|
|
6147
|
+
const now = performance.now();
|
|
6148
|
+
const prev = lastJumpAt.get(em);
|
|
6149
|
+
if (prev !== void 0 && now - prev < JUMP_DEDUPE_MS) return;
|
|
6150
|
+
lastJumpAt.set(em, now);
|
|
6151
|
+
em.classList.remove("dtm-player-emoji--jump");
|
|
6152
|
+
void em.offsetWidth;
|
|
6153
|
+
em.classList.add("dtm-player-emoji--jump");
|
|
6154
|
+
};
|
|
6155
|
+
const jumpTimers = [];
|
|
6156
|
+
const jumpEmojiAt = (em, when) => {
|
|
6157
|
+
if (when <= 0) {
|
|
6158
|
+
jumpEmoji(em);
|
|
6159
|
+
return;
|
|
6160
|
+
}
|
|
6161
|
+
jumpTimers.push(setTimeout(() => jumpEmoji(em), when * 1e3));
|
|
6162
|
+
};
|
|
6163
|
+
const clearJumpTimers = () => {
|
|
6164
|
+
for (const t of jumpTimers) clearTimeout(t);
|
|
6165
|
+
jumpTimers.length = 0;
|
|
6166
|
+
};
|
|
6167
|
+
const blinkTimers = [];
|
|
6168
|
+
const scheduleBlink = (em) => {
|
|
6169
|
+
const delay = 2e3 + Math.random() * 5e3;
|
|
6170
|
+
const t = setTimeout(() => {
|
|
6171
|
+
if (promotedToImage.has(em)) return;
|
|
6172
|
+
em.textContent = "\u{1F60C}";
|
|
6173
|
+
const t2 = setTimeout(
|
|
6174
|
+
() => {
|
|
6175
|
+
if (promotedToImage.has(em)) return;
|
|
6176
|
+
em.textContent = "\u{1F97A}";
|
|
6177
|
+
scheduleBlink(em);
|
|
6178
|
+
},
|
|
6179
|
+
200 + Math.random() * 150
|
|
6180
|
+
);
|
|
6181
|
+
blinkTimers.push(t2);
|
|
6182
|
+
}, delay);
|
|
6183
|
+
blinkTimers.push(t);
|
|
6184
|
+
};
|
|
6185
|
+
for (const em of emojiEls) scheduleBlink(em);
|
|
5898
6186
|
const dots = doc.createElement("div");
|
|
5899
6187
|
dots.className = "dtm-player-dots";
|
|
6188
|
+
dots.style.display = "none";
|
|
5900
6189
|
for (const index of trackIndices) {
|
|
5901
6190
|
const dot = doc.createElement("span");
|
|
5902
6191
|
dot.className = "dtm-player-dot";
|
|
5903
6192
|
dot.style.backgroundColor = colorOf(index);
|
|
5904
6193
|
dots.appendChild(dot);
|
|
5905
6194
|
}
|
|
5906
|
-
|
|
5907
|
-
|
|
6195
|
+
const beatRow = doc.createElement("div");
|
|
6196
|
+
beatRow.className = "dtm-player-beat-row";
|
|
6197
|
+
const beatDots = [];
|
|
6198
|
+
for (let i = 0; i < 4; i++) {
|
|
6199
|
+
const d = doc.createElement("span");
|
|
6200
|
+
d.className = "dtm-player-beat-dot";
|
|
6201
|
+
beatRow.appendChild(d);
|
|
6202
|
+
beatDots.push(d);
|
|
6203
|
+
}
|
|
6204
|
+
const barEl = doc.createElement("span");
|
|
6205
|
+
barEl.className = "dtm-player-bar";
|
|
6206
|
+
barEl.textContent = "-";
|
|
6207
|
+
beatRow.appendChild(barEl);
|
|
6208
|
+
const chips = [];
|
|
6209
|
+
const makeChip = (label) => {
|
|
5908
6210
|
const chip = doc.createElement("span");
|
|
5909
6211
|
chip.className = "dtm-player-chip";
|
|
5910
6212
|
chip.textContent = label;
|
|
5911
|
-
|
|
6213
|
+
chips.push(chip);
|
|
6214
|
+
return chip;
|
|
5912
6215
|
};
|
|
5913
|
-
if (meta.instrument)
|
|
5914
|
-
if (meta.drum)
|
|
5915
|
-
if (meta.volume !== void 0)
|
|
5916
|
-
head.
|
|
6216
|
+
if (meta.instrument) makeChip(`\u266A ${meta.instrument}`);
|
|
6217
|
+
if (meta.drum) makeChip(`\u{1F941} ${meta.drum}${drumPattern ? "" : " (?)"}`);
|
|
6218
|
+
if (meta.volume !== void 0) makeChip(`\u{1F50A} ${meta.volume}%`);
|
|
6219
|
+
head.append(playBtn, beatRow, ...chips, dots, mmlHeader);
|
|
5917
6220
|
root.appendChild(head);
|
|
6221
|
+
const body = doc.createElement("div");
|
|
6222
|
+
body.className = "dtm-player-body";
|
|
6223
|
+
root.appendChild(body);
|
|
6224
|
+
const mutedTracks = /* @__PURE__ */ new Set();
|
|
5918
6225
|
const laneViews = [];
|
|
5919
6226
|
for (const index of trackIndices) {
|
|
5920
6227
|
const lyricTrack = lyricTracks.get(index);
|
|
@@ -5922,7 +6229,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
5922
6229
|
const row = doc.createElement("div");
|
|
5923
6230
|
row.className = "dtm-player-lane-row";
|
|
5924
6231
|
const label = doc.createElement("div");
|
|
5925
|
-
label.className = "dtm-player-lane-label";
|
|
6232
|
+
label.className = "dtm-player-lane-label dtm-player-lane-label--btn";
|
|
5926
6233
|
const swatch = doc.createElement("span");
|
|
5927
6234
|
swatch.className = "dtm-player-dot";
|
|
5928
6235
|
swatch.style.backgroundColor = colorOf(index);
|
|
@@ -5930,13 +6237,22 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
5930
6237
|
no.className = "dtm-player-lane-no";
|
|
5931
6238
|
no.textContent = `@${index}`;
|
|
5932
6239
|
label.append(swatch, no);
|
|
6240
|
+
label.addEventListener("click", () => {
|
|
6241
|
+
if (mutedTracks.has(index)) {
|
|
6242
|
+
mutedTracks.delete(index);
|
|
6243
|
+
label.classList.remove("dtm-player-lane-label--muted");
|
|
6244
|
+
} else {
|
|
6245
|
+
mutedTracks.add(index);
|
|
6246
|
+
label.classList.add("dtm-player-lane-label--muted");
|
|
6247
|
+
}
|
|
6248
|
+
});
|
|
5933
6249
|
const lane = doc.createElement("div");
|
|
5934
6250
|
lane.className = "dtm-player-lane";
|
|
5935
6251
|
lane.style.setProperty("--tk", colorOf(index));
|
|
5936
6252
|
const laneTokens = [];
|
|
5937
6253
|
if (isLyricLane) {
|
|
5938
6254
|
const notes = placements.filter((p) => p.trackIndex === index).sort((a, b) => a.startStep - b.startStep);
|
|
5939
|
-
const gateScale = (lyricTrack.gate ??
|
|
6255
|
+
const gateScale = (lyricTrack.gate ?? DEFAULT_GATE) / 100;
|
|
5940
6256
|
const breaks = new Set(lyricTrack.lineBreaks ?? []);
|
|
5941
6257
|
if (lyricTrack.metaText) {
|
|
5942
6258
|
const metaEl = doc.createElement("span");
|
|
@@ -5983,9 +6299,46 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
5983
6299
|
}
|
|
5984
6300
|
}
|
|
5985
6301
|
row.append(label, lane);
|
|
5986
|
-
|
|
6302
|
+
body.appendChild(row);
|
|
5987
6303
|
laneViews.push({ lane, tokens: laneTokens });
|
|
5988
6304
|
}
|
|
6305
|
+
const termsModels = [
|
|
6306
|
+
...new Set([...lyricTracks.values()].map((lt) => lt.model))
|
|
6307
|
+
].filter((model) => KOE_VOICEBANK_TERMS[model]);
|
|
6308
|
+
if (termsModels.length > 0) {
|
|
6309
|
+
const termsDiv = doc.createElement("div");
|
|
6310
|
+
termsDiv.className = "dtm-player-terms";
|
|
6311
|
+
termsDiv.style.fontSize = "10px";
|
|
6312
|
+
termsDiv.style.color = "var(--dtm-warn)";
|
|
6313
|
+
termsDiv.style.display = "flex";
|
|
6314
|
+
termsDiv.style.flexDirection = "column";
|
|
6315
|
+
termsDiv.style.gap = "4px";
|
|
6316
|
+
termsDiv.style.marginTop = "4px";
|
|
6317
|
+
termsDiv.style.padding = "0 4px";
|
|
6318
|
+
for (const model of termsModels) {
|
|
6319
|
+
const termsRow = doc.createElement("div");
|
|
6320
|
+
termsRow.style.display = "flex";
|
|
6321
|
+
termsRow.style.alignItems = "center";
|
|
6322
|
+
termsRow.style.gap = "4px";
|
|
6323
|
+
termsRow.style.flexWrap = "wrap";
|
|
6324
|
+
const label = KOE_VOICEBANK_LABELS[model] ?? model;
|
|
6325
|
+
const url = KOE_VOICEBANK_TERMS[model];
|
|
6326
|
+
const span1 = doc.createElement("span");
|
|
6327
|
+
span1.textContent = "\u4F7F\u7528\u6642\u306B\u306F";
|
|
6328
|
+
const a = doc.createElement("a");
|
|
6329
|
+
a.textContent = `${label}UTAU\u97F3\u6E90`;
|
|
6330
|
+
a.href = url;
|
|
6331
|
+
a.target = "_blank";
|
|
6332
|
+
a.rel = "noopener";
|
|
6333
|
+
a.style.color = "var(--dtm-primary)";
|
|
6334
|
+
a.style.textDecoration = "underline";
|
|
6335
|
+
const span2 = doc.createElement("span");
|
|
6336
|
+
span2.textContent = "\u306E\u5229\u7528\u898F\u7D04\u306B\u5F93\u3063\u3066\u304F\u3060\u3055\u3044";
|
|
6337
|
+
termsRow.append(span1, a, span2);
|
|
6338
|
+
termsDiv.appendChild(termsRow);
|
|
6339
|
+
}
|
|
6340
|
+
root.appendChild(termsDiv);
|
|
6341
|
+
}
|
|
5989
6342
|
target.appendChild(root);
|
|
5990
6343
|
const autoScroll = (lane, el) => {
|
|
5991
6344
|
if (el.offsetWidth === 0 || lane.clientWidth === 0) return;
|
|
@@ -5995,7 +6348,10 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
5995
6348
|
lane.scrollLeft = Math.max(0, Math.min(next, maxScroll));
|
|
5996
6349
|
};
|
|
5997
6350
|
const renderPlayhead = (step) => {
|
|
5998
|
-
|
|
6351
|
+
const beatIndex = Math.floor(step / STEPS_PER_BEAT3) % 4;
|
|
6352
|
+
for (let i = 0; i < 4; i++)
|
|
6353
|
+
beatDots[i].classList.toggle("dtm-player-beat-dot--on", i === beatIndex);
|
|
6354
|
+
barEl.textContent = String(Math.floor(step / STEPS_PER_BAR) + 1);
|
|
5999
6355
|
for (const view of laneViews) {
|
|
6000
6356
|
let active = null;
|
|
6001
6357
|
for (const t of view.tokens) {
|
|
@@ -6007,7 +6363,8 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6007
6363
|
}
|
|
6008
6364
|
};
|
|
6009
6365
|
const resetPlayhead = () => {
|
|
6010
|
-
|
|
6366
|
+
for (const d of beatDots) d.classList.remove("dtm-player-beat-dot--on");
|
|
6367
|
+
barEl.textContent = "-";
|
|
6011
6368
|
for (const view of laneViews) {
|
|
6012
6369
|
for (const t of view.tokens) t.el.classList.remove("is-active");
|
|
6013
6370
|
view.lane.scrollLeft = 0;
|
|
@@ -6021,7 +6378,11 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6021
6378
|
getSoloTrackId: () => null,
|
|
6022
6379
|
getAudioTime,
|
|
6023
6380
|
onPlayNote: (e) => {
|
|
6024
|
-
|
|
6381
|
+
const trackIdx = Number(e.trackId);
|
|
6382
|
+
if (mutedTracks.has(trackIdx)) return;
|
|
6383
|
+
const em = emojiByTrack.get(trackIdx);
|
|
6384
|
+
if (em) jumpEmojiAt(em, e.when);
|
|
6385
|
+
if (lyricTracks.has(trackIdx)) return;
|
|
6025
6386
|
options.onPlayNote?.(e);
|
|
6026
6387
|
if (useSynth) synthPlay(e);
|
|
6027
6388
|
},
|
|
@@ -6044,6 +6405,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6044
6405
|
};
|
|
6045
6406
|
const finish = () => {
|
|
6046
6407
|
setPlayingUI(false);
|
|
6408
|
+
clearJumpTimers();
|
|
6047
6409
|
resetPlayhead();
|
|
6048
6410
|
if (activePlayer === instance) activePlayer = null;
|
|
6049
6411
|
};
|
|
@@ -6052,22 +6414,23 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6052
6414
|
const sorted = [...seqTrack?.notes ?? []].sort(
|
|
6053
6415
|
(a, b) => a.startStep - b.startStep
|
|
6054
6416
|
);
|
|
6055
|
-
const gate = (lt.gate ??
|
|
6417
|
+
const gate = (lt.gate ?? DEFAULT_GATE) / 100;
|
|
6418
|
+
const semis = (lt.octave ?? 0) * 12;
|
|
6056
6419
|
const count = Math.min(sorted.length, lt.syllables.length);
|
|
6057
6420
|
const notes = [];
|
|
6058
6421
|
for (let i = 0; i < count; i++) {
|
|
6059
6422
|
const n = sorted[i];
|
|
6060
6423
|
notes.push({
|
|
6061
6424
|
syllable: lt.syllables[i],
|
|
6062
|
-
pitch: n.pitch,
|
|
6425
|
+
pitch: n.pitch + semis,
|
|
6063
6426
|
startSec: n.startStep * secondsPerStep,
|
|
6064
6427
|
durationSec: n.durationSteps * secondsPerStep * gate
|
|
6065
6428
|
});
|
|
6066
6429
|
}
|
|
6067
6430
|
return {
|
|
6068
6431
|
model: lt.model,
|
|
6069
|
-
volume: vocalVolumeToGain(lt.volume ??
|
|
6070
|
-
pan: panToStereo(lt.pan ??
|
|
6432
|
+
volume: vocalVolumeToGain(lt.volume ?? DEFAULT_VOCAL_VOLUME) * (trackVolume / 100),
|
|
6433
|
+
pan: panToStereo(lt.pan ?? DEFAULT_PAN),
|
|
6071
6434
|
notes
|
|
6072
6435
|
};
|
|
6073
6436
|
});
|
|
@@ -6076,7 +6439,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6076
6439
|
const tracks = streaming ? buildStreamTracks() : [];
|
|
6077
6440
|
if (streaming) {
|
|
6078
6441
|
const v = ensureVoices();
|
|
6079
|
-
const overlay = showLoadingOverlay(
|
|
6442
|
+
const overlay = showLoadingOverlay(body);
|
|
6080
6443
|
try {
|
|
6081
6444
|
await v.loadModels(tracks.map((t) => t.model));
|
|
6082
6445
|
await v.warm(tracks);
|
|
@@ -6121,6 +6484,8 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6121
6484
|
void audioCtx.close();
|
|
6122
6485
|
audioCtx = null;
|
|
6123
6486
|
}
|
|
6487
|
+
for (const t of blinkTimers) clearTimeout(t);
|
|
6488
|
+
clearJumpTimers();
|
|
6124
6489
|
root.remove();
|
|
6125
6490
|
};
|
|
6126
6491
|
const instance = {
|
|
@@ -6414,8 +6779,332 @@ var createPianoRoll = (options, handlers) => {
|
|
|
6414
6779
|
}
|
|
6415
6780
|
};
|
|
6416
6781
|
};
|
|
6782
|
+
|
|
6783
|
+
// src/studio.ts
|
|
6784
|
+
var DEFAULT_CDN = {
|
|
6785
|
+
soundFont: "https://rpgen3.github.io/soundfont/mjs/surikov/SoundFont.mjs",
|
|
6786
|
+
soundFontDrum: "https://rpgen3.github.io/soundfont/mjs/surikov/SoundFont_drum.mjs",
|
|
6787
|
+
soundFontList: "https://rpgen3.github.io/soundfont/mjs/surikov/SoundFont_list.mjs",
|
|
6788
|
+
parseChord: "https://rpgen3.github.io/piano/mjs/parseChord.mjs",
|
|
6789
|
+
parseChords: "https://rpgen3.github.io/piano/mjs/parseChords.mjs",
|
|
6790
|
+
midiParser: "https://cdn.jsdelivr.net/npm/midi-parser-js@4.0.4/+esm"
|
|
6791
|
+
};
|
|
6792
|
+
var SOUNDFONT_NAME = "FluidR3_GM_sf2_file";
|
|
6793
|
+
var TRACK_ROLES = ["melody", "submelody", "bass", "chord"];
|
|
6794
|
+
var resolveDefaultVoiceWorkerUrl = () => {
|
|
6795
|
+
try {
|
|
6796
|
+
return new URL("./voice-worker.js", import.meta.url).href;
|
|
6797
|
+
} catch {
|
|
6798
|
+
return void 0;
|
|
6799
|
+
}
|
|
6800
|
+
};
|
|
6801
|
+
var importFrom = async (url, name) => {
|
|
6802
|
+
const mod = await import(
|
|
6803
|
+
/* @vite-ignore */
|
|
6804
|
+
url
|
|
6805
|
+
);
|
|
6806
|
+
return mod[name] ?? mod.default;
|
|
6807
|
+
};
|
|
6808
|
+
var createDtmStudio = async (options = {}) => {
|
|
6809
|
+
const cdn = { ...DEFAULT_CDN, ...options.cdn };
|
|
6810
|
+
const features = {
|
|
6811
|
+
recorder: true,
|
|
6812
|
+
midi: true,
|
|
6813
|
+
chord: true,
|
|
6814
|
+
presetUI: true,
|
|
6815
|
+
...options.features
|
|
6816
|
+
};
|
|
6817
|
+
const audioCtx = options.audioContext ?? new AudioContext();
|
|
6818
|
+
const masterGain = audioCtx.createGain();
|
|
6819
|
+
masterGain.gain.value = options.masterVolume ?? 1;
|
|
6820
|
+
masterGain.connect(audioCtx.destination);
|
|
6821
|
+
const drumGain = audioCtx.createGain();
|
|
6822
|
+
drumGain.gain.value = options.drumVolume ?? 1;
|
|
6823
|
+
drumGain.connect(audioCtx.destination);
|
|
6824
|
+
const resumeAudio = () => {
|
|
6825
|
+
if (audioCtx.state === "suspended") void audioCtx.resume();
|
|
6826
|
+
};
|
|
6827
|
+
const eng = options.engines ?? {};
|
|
6828
|
+
const [SoundFont, SoundFont_drum, SoundFont_list] = await Promise.all([
|
|
6829
|
+
eng.SoundFont ?? importFrom(cdn.soundFont, "SoundFont"),
|
|
6830
|
+
eng.SoundFont_drum ?? importFrom(cdn.soundFontDrum, "SoundFont_drum"),
|
|
6831
|
+
eng.SoundFont_list ?? importFrom(cdn.soundFontList, "SoundFont_list")
|
|
6832
|
+
]);
|
|
6833
|
+
let parseChord = eng.parseChord;
|
|
6834
|
+
let parseChords = eng.parseChords;
|
|
6835
|
+
if (features.chord && (!parseChord || !parseChords)) {
|
|
6836
|
+
try {
|
|
6837
|
+
[parseChord, parseChords] = await Promise.all([
|
|
6838
|
+
parseChord ?? importFrom(
|
|
6839
|
+
cdn.parseChord,
|
|
6840
|
+
"parseChord"
|
|
6841
|
+
),
|
|
6842
|
+
parseChords ?? importFrom(
|
|
6843
|
+
cdn.parseChords,
|
|
6844
|
+
"parseChords"
|
|
6845
|
+
)
|
|
6846
|
+
]);
|
|
6847
|
+
} catch (e) {
|
|
6848
|
+
console.warn("[dtm] \u30B3\u30FC\u30C9\u89E3\u6790\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F", e);
|
|
6849
|
+
}
|
|
6850
|
+
}
|
|
6851
|
+
let midiParser = null;
|
|
6852
|
+
let parseMidi;
|
|
6853
|
+
if (features.midi) {
|
|
6854
|
+
parseMidi = eng.parseMidi;
|
|
6855
|
+
if (!parseMidi) {
|
|
6856
|
+
const midiPromise = importFrom(
|
|
6857
|
+
cdn.midiParser,
|
|
6858
|
+
"default"
|
|
6859
|
+
).then((m) => {
|
|
6860
|
+
midiParser = m;
|
|
6861
|
+
}).catch((e) => console.warn("[dtm] midi-parser \u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557", e));
|
|
6862
|
+
void midiPromise;
|
|
6863
|
+
parseMidi = (bytes) => {
|
|
6864
|
+
if (!midiParser) throw new Error("midi-parser not ready");
|
|
6865
|
+
return midiParser.parse(bytes);
|
|
6866
|
+
};
|
|
6867
|
+
}
|
|
6868
|
+
}
|
|
6869
|
+
const voiceWorkerUrl = options.voiceWorkerUrl === null ? void 0 : options.voiceWorkerUrl ?? resolveDefaultVoiceWorkerUrl();
|
|
6870
|
+
const singingVoices = createSingingVoices(audioCtx, masterGain, {
|
|
6871
|
+
voiceWorkerUrl
|
|
6872
|
+
});
|
|
6873
|
+
const recorder = features.recorder ? setupRecorder(audioCtx, masterGain, drumGain) : null;
|
|
6874
|
+
const downloadWav = () => {
|
|
6875
|
+
if (!recorder) return;
|
|
6876
|
+
const recordedData = recorder.getRecordedData();
|
|
6877
|
+
const ch = recordedData.length;
|
|
6878
|
+
const len = recordedData[0].length;
|
|
6879
|
+
if (len === 0) return;
|
|
6880
|
+
const bufSize = recordedData[0][0].length;
|
|
6881
|
+
const wave = new Float32Array(ch * len * bufSize);
|
|
6882
|
+
let idx = 0;
|
|
6883
|
+
for (let i = 0; i < len; i++)
|
|
6884
|
+
for (let j = 0; j < bufSize; j++)
|
|
6885
|
+
for (let k = 0; k < ch; k++) wave[idx++] = recordedData[k][i][j];
|
|
6886
|
+
const sampleRate = audioCtx.sampleRate;
|
|
6887
|
+
const channels = 2;
|
|
6888
|
+
const bitRate = 16;
|
|
6889
|
+
const step = bitRate / 8;
|
|
6890
|
+
const blockSize = channels * step;
|
|
6891
|
+
const byteLen = wave.length * step;
|
|
6892
|
+
const view = new DataView(new ArrayBuffer(44 + byteLen));
|
|
6893
|
+
const ws = (off2, s) => {
|
|
6894
|
+
for (let i = 0; i < s.length; i++)
|
|
6895
|
+
view.setUint8(off2 + i, s.charCodeAt(i));
|
|
6896
|
+
};
|
|
6897
|
+
ws(0, "RIFF");
|
|
6898
|
+
view.setUint32(4, 32 + byteLen, true);
|
|
6899
|
+
ws(8, "WAVE");
|
|
6900
|
+
ws(12, "fmt ");
|
|
6901
|
+
view.setUint32(16, 16, true);
|
|
6902
|
+
view.setUint16(20, 1, true);
|
|
6903
|
+
view.setUint16(22, channels, true);
|
|
6904
|
+
view.setUint32(24, sampleRate, true);
|
|
6905
|
+
view.setUint32(28, sampleRate * blockSize, true);
|
|
6906
|
+
view.setUint16(32, blockSize, true);
|
|
6907
|
+
view.setUint16(34, bitRate, true);
|
|
6908
|
+
ws(36, "data");
|
|
6909
|
+
view.setUint32(40, byteLen, true);
|
|
6910
|
+
const clamp4 = (n, a2, b) => Math.max(a2, Math.min(b, n));
|
|
6911
|
+
let off = 44;
|
|
6912
|
+
for (let i = 0; i < wave.length; i++, off += step)
|
|
6913
|
+
view.setInt16(
|
|
6914
|
+
off,
|
|
6915
|
+
clamp4(Math.round(wave[i] * 32768), -32768, 32767),
|
|
6916
|
+
true
|
|
6917
|
+
);
|
|
6918
|
+
const blob = new Blob([view], { type: "audio/wav" });
|
|
6919
|
+
const url = URL.createObjectURL(blob);
|
|
6920
|
+
const a = document.createElement("a");
|
|
6921
|
+
a.href = url;
|
|
6922
|
+
a.download = "record.wav";
|
|
6923
|
+
a.click();
|
|
6924
|
+
URL.revokeObjectURL(url);
|
|
6925
|
+
};
|
|
6926
|
+
const onToggleRecord = recorder ? () => {
|
|
6927
|
+
if (recorder.isRecording()) {
|
|
6928
|
+
recorder.stopRecording();
|
|
6929
|
+
downloadWav();
|
|
6930
|
+
} else {
|
|
6931
|
+
recorder.clearRecordedData();
|
|
6932
|
+
recorder.startRecording();
|
|
6933
|
+
}
|
|
6934
|
+
} : void 0;
|
|
6935
|
+
const listReady = new Promise((resolve) => {
|
|
6936
|
+
SoundFont_list.init();
|
|
6937
|
+
SoundFont_list.onload(() => resolve());
|
|
6938
|
+
});
|
|
6939
|
+
const drumReady = (async () => {
|
|
6940
|
+
try {
|
|
6941
|
+
await SoundFont_drum.load({
|
|
6942
|
+
ctx: audioCtx,
|
|
6943
|
+
font: DRUM_FONT,
|
|
6944
|
+
id: "0",
|
|
6945
|
+
keys: Object.values(DRUM_KEYS)
|
|
6946
|
+
});
|
|
6947
|
+
} catch (e) {
|
|
6948
|
+
console.error("[dtm] \u30C9\u30E9\u30E0\u97F3\u6E90\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557", e);
|
|
6949
|
+
}
|
|
6950
|
+
})();
|
|
6951
|
+
let nameToKey = {};
|
|
6952
|
+
const soundFonts = /* @__PURE__ */ new Map();
|
|
6953
|
+
const loadedKeyByTrack = /* @__PURE__ */ new Map();
|
|
6954
|
+
const loadSoundFont = async (instrumentKey, trackId) => {
|
|
6955
|
+
if (loadedKeyByTrack.get(trackId) === instrumentKey) return;
|
|
6956
|
+
try {
|
|
6957
|
+
const fullName = `${instrumentKey}_${SOUNDFONT_NAME}`;
|
|
6958
|
+
soundFonts.set(
|
|
6959
|
+
trackId,
|
|
6960
|
+
await SoundFont.load({
|
|
6961
|
+
ctx: audioCtx,
|
|
6962
|
+
fontName: `_tone_${fullName}`,
|
|
6963
|
+
url: SoundFont.toURL(fullName)
|
|
6964
|
+
})
|
|
6965
|
+
);
|
|
6966
|
+
loadedKeyByTrack.set(trackId, instrumentKey);
|
|
6967
|
+
} catch (e) {
|
|
6968
|
+
console.error(`[dtm] \u697D\u5668 "${instrumentKey}" \u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557`, e);
|
|
6969
|
+
}
|
|
6970
|
+
};
|
|
6971
|
+
const defaultPreset = options.defaultPreset ?? "retro_game";
|
|
6972
|
+
const instrumentNameFor = (preset, trackId) => preset[trackId] ?? preset.melody;
|
|
6973
|
+
const loadPreset = async (presetKey, trackIds = [...TRACK_ROLES]) => {
|
|
6974
|
+
const preset = INSTRUMENT_PRESETS[presetKey];
|
|
6975
|
+
if (!preset) return;
|
|
6976
|
+
await listReady;
|
|
6977
|
+
await Promise.all(
|
|
6978
|
+
trackIds.map((trackId) => {
|
|
6979
|
+
const key = nameToKey[instrumentNameFor(preset, trackId)];
|
|
6980
|
+
return key ? loadSoundFont(key, trackId) : Promise.resolve();
|
|
6981
|
+
})
|
|
6982
|
+
);
|
|
6983
|
+
};
|
|
6984
|
+
await listReady;
|
|
6985
|
+
nameToKey = await buildNameToKeyMapping();
|
|
6986
|
+
await Promise.all([drumReady, loadPreset(defaultPreset)]);
|
|
6987
|
+
const playNote = (e) => {
|
|
6988
|
+
const sf = soundFonts.get(e.trackId);
|
|
6989
|
+
if (!sf) return;
|
|
6990
|
+
sf.play({
|
|
6991
|
+
ctx: audioCtx,
|
|
6992
|
+
destination: masterGain,
|
|
6993
|
+
pitch: e.pitch,
|
|
6994
|
+
volume: e.volume,
|
|
6995
|
+
when: e.when,
|
|
6996
|
+
duration: e.duration
|
|
6997
|
+
});
|
|
6998
|
+
};
|
|
6999
|
+
const playDrum = (e) => {
|
|
7000
|
+
if (!SoundFont_drum.font) return;
|
|
7001
|
+
SoundFont_drum.play({
|
|
7002
|
+
ctx: audioCtx,
|
|
7003
|
+
destination: drumGain,
|
|
7004
|
+
pitch: e.pitch,
|
|
7005
|
+
volume: e.velocity,
|
|
7006
|
+
when: e.when,
|
|
7007
|
+
duration: e.duration
|
|
7008
|
+
});
|
|
7009
|
+
};
|
|
7010
|
+
const sfForPlayerTrack = (trackId) => soundFonts.get(TRACK_ROLES[Number(trackId)] ?? "") ?? soundFonts.get(`t${trackId}`);
|
|
7011
|
+
const playPlayerNote = (e) => {
|
|
7012
|
+
const sf = sfForPlayerTrack(e.trackId);
|
|
7013
|
+
if (!sf) return;
|
|
7014
|
+
sf.play({
|
|
7015
|
+
ctx: audioCtx,
|
|
7016
|
+
destination: masterGain,
|
|
7017
|
+
pitch: e.pitch,
|
|
7018
|
+
volume: e.volume,
|
|
7019
|
+
when: e.when,
|
|
7020
|
+
duration: e.duration
|
|
7021
|
+
});
|
|
7022
|
+
};
|
|
7023
|
+
const editorPresetSelects = /* @__PURE__ */ new WeakMap();
|
|
7024
|
+
const mountedEditors = [];
|
|
7025
|
+
const mountedPlayers = [];
|
|
7026
|
+
const mountEditor = (target, opts = {}) => {
|
|
7027
|
+
const { preset, presetUI, ...dawOverrides } = opts;
|
|
7028
|
+
const tracks = dawOverrides.tracks ?? TRACKS_SIMPLE;
|
|
7029
|
+
const trackIds = tracks.map((t) => t.id);
|
|
7030
|
+
const base = {
|
|
7031
|
+
getAudioTime: () => audioCtx.currentTime,
|
|
7032
|
+
onResumeAudio: resumeAudio,
|
|
7033
|
+
onPlayNote: playNote,
|
|
7034
|
+
onPlayDrum: playDrum,
|
|
7035
|
+
singingVoices,
|
|
7036
|
+
parseChord,
|
|
7037
|
+
parseChords,
|
|
7038
|
+
parseMidi,
|
|
7039
|
+
onToggleRecord,
|
|
7040
|
+
...dawOverrides
|
|
7041
|
+
};
|
|
7042
|
+
const wantPresetUI = presetUI ?? features.presetUI;
|
|
7043
|
+
if (wantPresetUI) {
|
|
7044
|
+
const select = target.ownerDocument.createElement("select");
|
|
7045
|
+
select.className = "dtm-studio-preset";
|
|
7046
|
+
for (const [key, p] of Object.entries(INSTRUMENT_PRESETS)) {
|
|
7047
|
+
const opt = target.ownerDocument.createElement("option");
|
|
7048
|
+
opt.value = key;
|
|
7049
|
+
opt.textContent = p.displayName;
|
|
7050
|
+
select.appendChild(opt);
|
|
7051
|
+
}
|
|
7052
|
+
select.value = preset && INSTRUMENT_PRESETS[preset] ? preset : defaultPreset;
|
|
7053
|
+
target.appendChild(select);
|
|
7054
|
+
editorPresetSelects.set(target, select);
|
|
7055
|
+
select.addEventListener("change", async () => {
|
|
7056
|
+
daw.setInstrument(select.value);
|
|
7057
|
+
await loadPreset(select.value, trackIds);
|
|
7058
|
+
});
|
|
7059
|
+
}
|
|
7060
|
+
const daw = mountDAW(target, base);
|
|
7061
|
+
mountedEditors.push(daw);
|
|
7062
|
+
const presetKey = preset && INSTRUMENT_PRESETS[preset] ? preset : defaultPreset;
|
|
7063
|
+
daw.setInstrument(presetKey);
|
|
7064
|
+
void loadPreset(presetKey, trackIds);
|
|
7065
|
+
return daw;
|
|
7066
|
+
};
|
|
7067
|
+
const mountPlayer = (target, mml, opts = {}) => {
|
|
7068
|
+
const meta = parseMML(mml, {}).meta ?? {};
|
|
7069
|
+
if (meta.instrument && INSTRUMENT_PRESETS[meta.instrument]) {
|
|
7070
|
+
void loadPreset(meta.instrument);
|
|
7071
|
+
}
|
|
7072
|
+
const player = mountMmlPlayer(target, mml, {
|
|
7073
|
+
getAudioTime: () => audioCtx.currentTime,
|
|
7074
|
+
onResumeAudio: resumeAudio,
|
|
7075
|
+
onPlayNote: playPlayerNote,
|
|
7076
|
+
onPlayDrum: playDrum,
|
|
7077
|
+
singingVoices,
|
|
7078
|
+
...opts
|
|
7079
|
+
});
|
|
7080
|
+
mountedPlayers.push(player);
|
|
7081
|
+
return player;
|
|
7082
|
+
};
|
|
7083
|
+
const dispose = () => {
|
|
7084
|
+
for (const p of mountedPlayers) p.destroy();
|
|
7085
|
+
for (const d of mountedEditors) d.destroy();
|
|
7086
|
+
mountedPlayers.length = 0;
|
|
7087
|
+
mountedEditors.length = 0;
|
|
7088
|
+
void audioCtx.close();
|
|
7089
|
+
};
|
|
7090
|
+
return {
|
|
7091
|
+
audioContext: audioCtx,
|
|
7092
|
+
singingVoices,
|
|
7093
|
+
mountEditor,
|
|
7094
|
+
mountPlayer,
|
|
7095
|
+
loadPreset,
|
|
7096
|
+
dispose
|
|
7097
|
+
};
|
|
7098
|
+
};
|
|
6417
7099
|
export {
|
|
6418
7100
|
DAW_CSS,
|
|
7101
|
+
DEFAULT_BPM,
|
|
7102
|
+
DEFAULT_GATE,
|
|
7103
|
+
DEFAULT_PAN,
|
|
7104
|
+
DEFAULT_PLAYBACK_VELOCITY,
|
|
7105
|
+
DEFAULT_STEPS_PER_BAR,
|
|
7106
|
+
DEFAULT_VELOCITY,
|
|
7107
|
+
DEFAULT_VOCAL_VOLUME,
|
|
6419
7108
|
DRUM_FONT,
|
|
6420
7109
|
DRUM_KEYS,
|
|
6421
7110
|
DRUM_PATTERNS,
|
|
@@ -6423,6 +7112,7 @@ export {
|
|
|
6423
7112
|
KOE_BASE_URL,
|
|
6424
7113
|
KOE_VOICEBANKS,
|
|
6425
7114
|
KOE_VOICEBANK_LABELS,
|
|
7115
|
+
KOE_VOICEBANK_TERMS,
|
|
6426
7116
|
LinkedList,
|
|
6427
7117
|
MAX_VOCAL_VOLUME,
|
|
6428
7118
|
MMLCore,
|
|
@@ -6430,6 +7120,7 @@ export {
|
|
|
6430
7120
|
PREWARM_NOTES,
|
|
6431
7121
|
TRACKS_ADVANCED,
|
|
6432
7122
|
TRACKS_SIMPLE,
|
|
7123
|
+
VOICE_IMAGE_KEY,
|
|
6433
7124
|
analyzeMidiTracks,
|
|
6434
7125
|
applyHarmonicFilter,
|
|
6435
7126
|
applyMonophonic,
|
|
@@ -6437,6 +7128,7 @@ export {
|
|
|
6437
7128
|
buildNameToKeyMapping,
|
|
6438
7129
|
collectPitchTokens,
|
|
6439
7130
|
createAudioContext,
|
|
7131
|
+
createDtmStudio,
|
|
6440
7132
|
createKlattVoice,
|
|
6441
7133
|
createKoeVoice,
|
|
6442
7134
|
createLyricsConductor,
|