@onjmin/dtm 2.1.4 → 2.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +127 -9
- package/dist/index.d.ts +127 -9
- package/dist/index.js +793 -137
- package/dist/index.mjs +782 -136
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44,6 +44,7 @@ __export(index_exports, {
|
|
|
44
44
|
EDO31_NAMES: () => EDO31_NAMES,
|
|
45
45
|
FADE_IN_MARK: () => FADE_IN_MARK,
|
|
46
46
|
FADE_OUT_MARK: () => FADE_OUT_MARK,
|
|
47
|
+
GLOBAL_STORAGE_KEYS: () => GLOBAL_STORAGE_KEYS,
|
|
47
48
|
GM_INSTRUMENT_NAMES: () => GM_INSTRUMENT_NAMES,
|
|
48
49
|
INSTRUMENT_PRESETS: () => INSTRUMENT_PRESETS,
|
|
49
50
|
KEY_COUNT: () => KEY_COUNT,
|
|
@@ -52,6 +53,7 @@ __export(index_exports, {
|
|
|
52
53
|
KOE_VOICEBANK_LABELS: () => KOE_VOICEBANK_LABELS,
|
|
53
54
|
KOE_VOICEBANK_TERMS: () => KOE_VOICEBANK_TERMS,
|
|
54
55
|
LinkedList: () => LinkedList,
|
|
56
|
+
MACRO_STORAGE_KEYS: () => MACRO_STORAGE_KEYS,
|
|
55
57
|
MAJOR_KEY_IDS: () => MAJOR_KEY_IDS,
|
|
56
58
|
MAX_VOCAL_VOLUME: () => MAX_VOCAL_VOLUME,
|
|
57
59
|
MICRO_STEP: () => MICRO_STEP,
|
|
@@ -154,6 +156,11 @@ __export(index_exports, {
|
|
|
154
156
|
playNote: () => playNote,
|
|
155
157
|
playPlacements: () => playPlacements,
|
|
156
158
|
playSingingMML: () => playSingingMML,
|
|
159
|
+
readGlobalBool: () => readGlobalBool,
|
|
160
|
+
readGlobalNumber: () => readGlobalNumber,
|
|
161
|
+
readGlobalSetting: () => readGlobalSetting,
|
|
162
|
+
readMacroSections: () => readMacroSections,
|
|
163
|
+
readMacroSetting: () => readMacroSetting,
|
|
157
164
|
resolveComposeKey: () => resolveComposeKey,
|
|
158
165
|
resolveDrumPattern: () => resolveDrumPattern,
|
|
159
166
|
resolveLoopPoint: () => resolveLoopPoint,
|
|
@@ -176,7 +183,10 @@ __export(index_exports, {
|
|
|
176
183
|
unitsToMidi: () => unitsToMidi,
|
|
177
184
|
unitsToMidiDetune: () => unitsToMidiDetune,
|
|
178
185
|
unitsToPitchV1: () => unitsToPitchV1,
|
|
179
|
-
vocalVolumeToGain: () => vocalVolumeToGain
|
|
186
|
+
vocalVolumeToGain: () => vocalVolumeToGain,
|
|
187
|
+
writeGlobalSetting: () => writeGlobalSetting,
|
|
188
|
+
writeMacroSections: () => writeMacroSections,
|
|
189
|
+
writeMacroSetting: () => writeMacroSetting
|
|
180
190
|
});
|
|
181
191
|
module.exports = __toCommonJS(index_exports);
|
|
182
192
|
|
|
@@ -4910,6 +4920,7 @@ var createSequencer = (options) => {
|
|
|
4910
4920
|
let drumCursor = 0;
|
|
4911
4921
|
let lastDrumStep = Number.NEGATIVE_INFINITY;
|
|
4912
4922
|
let lastPlayStep = 0;
|
|
4923
|
+
let maxTimelineEndSec = 0;
|
|
4913
4924
|
const secondsPerStep = () => 60 / options.getBpm() / STEPS_PER_BEAT;
|
|
4914
4925
|
const getWrappedPlayStep = (time, sps) => {
|
|
4915
4926
|
if (!isLooping || loopDurationSec <= 0 || time < loopEndSec) {
|
|
@@ -4936,6 +4947,7 @@ var createSequencer = (options) => {
|
|
|
4936
4947
|
}
|
|
4937
4948
|
const startLimit = isLooping ? Math.min(fromStep, loopStartStep) : fromStep;
|
|
4938
4949
|
let maxEndStep = 0;
|
|
4950
|
+
maxTimelineEndSec = 0;
|
|
4939
4951
|
for (const track of options.getTracks()) {
|
|
4940
4952
|
trackVolumeMap.set(track.id, track.volume);
|
|
4941
4953
|
for (const note of track.notes) {
|
|
@@ -4944,6 +4956,7 @@ var createSequencer = (options) => {
|
|
|
4944
4956
|
const when = relativeStart * sps;
|
|
4945
4957
|
const duration = note.durationSteps * sps;
|
|
4946
4958
|
maxEndStep = Math.max(maxEndStep, note.startStep + note.durationSteps);
|
|
4959
|
+
maxTimelineEndSec = Math.max(maxTimelineEndSec, when + duration);
|
|
4947
4960
|
timeline.push({
|
|
4948
4961
|
trackId: track.id,
|
|
4949
4962
|
pitch: note.pitchUnits,
|
|
@@ -5069,10 +5082,7 @@ var createSequencer = (options) => {
|
|
|
5069
5082
|
lastPlayStep = currentStep2;
|
|
5070
5083
|
}
|
|
5071
5084
|
if (!isLooping) {
|
|
5072
|
-
|
|
5073
|
-
const lastWhen = last?.when ?? 0;
|
|
5074
|
-
const lastDuration = last?.duration ?? 0;
|
|
5075
|
-
if (nowIndex >= timeline.length && time > lastWhen + lastDuration + 0.1) {
|
|
5085
|
+
if (nowIndex >= timeline.length && time > maxTimelineEndSec + 0.1) {
|
|
5076
5086
|
stop();
|
|
5077
5087
|
options.onEnd(false);
|
|
5078
5088
|
}
|
|
@@ -8404,6 +8414,21 @@ var DAW_CSS = `
|
|
|
8404
8414
|
.dtm-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
|
8405
8415
|
.dtm-track-body { display: flex; flex-direction: column; gap: 10px; }
|
|
8406
8416
|
|
|
8417
|
+
/* \u2500\u2500\u2500 \u81EA\u52D5\u4F5C\u66F2\u30B3\u30F3\u30C6\u30CA\uFF08\u30DE\u30AF\u30ED\u30D1\u30CD\u30EB\u5185\u306E\u5C02\u7528\u30AB\u30FC\u30C9\u98A8\u30B0\u30EB\u30FC\u30D7\u67A0\uFF09 \u2500\u2500\u2500 */
|
|
8418
|
+
.dtm-compose-container {
|
|
8419
|
+
background: var(--dtm-deep);
|
|
8420
|
+
border: 2px solid var(--c-black);
|
|
8421
|
+
box-shadow:
|
|
8422
|
+
inset 0 0 0 1px var(--dtm-border2),
|
|
8423
|
+
0 0 0 1px var(--dtm-success),
|
|
8424
|
+
3px 3px 0 var(--c-black);
|
|
8425
|
+
padding: 10px 12px 12px;
|
|
8426
|
+
display: flex;
|
|
8427
|
+
flex-direction: column;
|
|
8428
|
+
gap: 10px;
|
|
8429
|
+
margin-bottom: 6px;
|
|
8430
|
+
}
|
|
8431
|
+
|
|
8407
8432
|
/* \u2500\u2500\u2500 \u30A2\u30AF\u30C6\u30A3\u30D6\u30C8\u30E9\u30C3\u30AF\u8272\uFF08\u500B\u5225\u30C8\u30E9\u30C3\u30AF\u8A2D\u5B9A\u30D1\u30CD\u30EB\u306E\u5DE6\u7AEF\u30E9\u30A4\u30F3\uFF09 \u2500\u2500\u2500 */
|
|
8408
8433
|
.dtm-panel--track > summary::before,
|
|
8409
8434
|
.dtm-panel--track[open] > summary::before {
|
|
@@ -13198,11 +13223,25 @@ var densityFeatures = (notes, opts) => {
|
|
|
13198
13223
|
shortNoteRatio: short / notes.length
|
|
13199
13224
|
};
|
|
13200
13225
|
};
|
|
13201
|
-
var tensionFeatures = (barTension) => {
|
|
13202
|
-
if (barTension.length <
|
|
13226
|
+
var tensionFeatures = (barTension, opts) => {
|
|
13227
|
+
if (barTension.length < 8) return { rise: 0, resolve: 0 };
|
|
13203
13228
|
const mean2 = (xs) => xs.reduce((a2, b2) => a2 + b2, 0) / Math.max(1, xs.length);
|
|
13204
|
-
|
|
13205
|
-
|
|
13229
|
+
let a;
|
|
13230
|
+
let b;
|
|
13231
|
+
if (opts?.verseBars && opts?.chorusBars && opts.verseBars.length > 0 && opts.chorusBars.length > 0) {
|
|
13232
|
+
a = mean2(opts.verseBars.map((i2) => barTension[i2] ?? 0));
|
|
13233
|
+
b = mean2(opts.chorusBars.map((i2) => barTension[i2] ?? 0));
|
|
13234
|
+
} else if (barTension.length >= 16 && barTension.length <= 24) {
|
|
13235
|
+
a = mean2(barTension.slice(0, 4));
|
|
13236
|
+
b = mean2(barTension.slice(8, 12));
|
|
13237
|
+
} else {
|
|
13238
|
+
const q1Start = Math.floor(barTension.length * 0.15);
|
|
13239
|
+
const q1End = Math.max(q1Start + 2, Math.floor(barTension.length * 0.35));
|
|
13240
|
+
const q3Start = Math.floor(barTension.length * 0.55);
|
|
13241
|
+
const q3End = Math.max(q3Start + 2, Math.floor(barTension.length * 0.75));
|
|
13242
|
+
a = mean2(barTension.slice(q1Start, q1End));
|
|
13243
|
+
b = mean2(barTension.slice(q3Start, q3End));
|
|
13244
|
+
}
|
|
13206
13245
|
const all = mean2(barTension);
|
|
13207
13246
|
const last = barTension[barTension.length - 1];
|
|
13208
13247
|
const rise = Math.max(0, Math.min(1, (b - a) / 0.5));
|
|
@@ -13249,6 +13288,8 @@ var SECTION_LABELS = {
|
|
|
13249
13288
|
verse: "A\u30E1\u30ED",
|
|
13250
13289
|
prechorus: "B\u30E1\u30ED",
|
|
13251
13290
|
chorus: "\u30B5\u30D3",
|
|
13291
|
+
bridge: "C\u30E1\u30ED",
|
|
13292
|
+
drop_chorus: "\u843D\u3061\u30B5\u30D3",
|
|
13252
13293
|
interlude: "\u9593\u594F",
|
|
13253
13294
|
outro: "\u30A2\u30A6\u30C8\u30ED"
|
|
13254
13295
|
};
|
|
@@ -13257,6 +13298,8 @@ var SECTION_ORDER = [
|
|
|
13257
13298
|
"verse",
|
|
13258
13299
|
"prechorus",
|
|
13259
13300
|
"chorus",
|
|
13301
|
+
"bridge",
|
|
13302
|
+
"drop_chorus",
|
|
13260
13303
|
"interlude",
|
|
13261
13304
|
"outro"
|
|
13262
13305
|
];
|
|
@@ -13308,6 +13351,35 @@ var SECTION_SPECS = {
|
|
|
13308
13351
|
// 主音へ全終止
|
|
13309
13352
|
progression: "b"
|
|
13310
13353
|
},
|
|
13354
|
+
// Cメロ。Verse/Pre chorusとは違うメロディで、ラストのサビ前に緊張感を持たせる。
|
|
13355
|
+
// 2番のサビの後に来ることが多い(参考: ONLIVE Studio blog)。
|
|
13356
|
+
// 専用のコード進行 "c" を持ち、AメロともBメロとも雰囲気が違う。
|
|
13357
|
+
bridge: {
|
|
13358
|
+
bars: 4,
|
|
13359
|
+
melody: true,
|
|
13360
|
+
registerShift: 2,
|
|
13361
|
+
density: 0.9,
|
|
13362
|
+
drumLevel: 1,
|
|
13363
|
+
landing: 1,
|
|
13364
|
+
// 解決しない音で止めてラスサビへ渡す
|
|
13365
|
+
progression: "c"
|
|
13366
|
+
},
|
|
13367
|
+
// 落ちサビ。サビのメロディを伴奏控えめに歌う。J-POPの王道パターン。
|
|
13368
|
+
// density と drumLevel だけ下げ、メロディはサビと同じものを使う。
|
|
13369
|
+
drop_chorus: {
|
|
13370
|
+
bars: 4,
|
|
13371
|
+
melody: true,
|
|
13372
|
+
registerShift: 4,
|
|
13373
|
+
// サビと同じ高さ
|
|
13374
|
+
density: 0.6,
|
|
13375
|
+
// 薄い(ここが「落ち」の実体)
|
|
13376
|
+
drumLevel: 0,
|
|
13377
|
+
// ドラム控えめ
|
|
13378
|
+
landing: 0,
|
|
13379
|
+
// 主音へ全終止
|
|
13380
|
+
progression: "b"
|
|
13381
|
+
// サビと同じ進行
|
|
13382
|
+
},
|
|
13311
13383
|
interlude: {
|
|
13312
13384
|
bars: 4,
|
|
13313
13385
|
melody: false,
|
|
@@ -13327,18 +13399,120 @@ var SECTION_SPECS = {
|
|
|
13327
13399
|
progression: "a"
|
|
13328
13400
|
}
|
|
13329
13401
|
};
|
|
13330
|
-
var
|
|
13331
|
-
|
|
13332
|
-
|
|
13402
|
+
var STRUCTURE_TEMPLATES = [
|
|
13403
|
+
// 1コーラス(現行デフォルト、短い曲・初心者向け)
|
|
13404
|
+
{
|
|
13405
|
+
name: "1chorus",
|
|
13406
|
+
label: "1\u30B3\u30FC\u30E9\u30B9",
|
|
13407
|
+
plan: ["intro", "verse", "prechorus", "chorus"]
|
|
13408
|
+
},
|
|
13409
|
+
// JPOP王道(マリーゴールド型)
|
|
13410
|
+
// イントロ→Aメロ→Aメロ→Bメロ→サビ→Aメロ→Bメロ→サビ→Cメロ→間奏→サビ→アウトロ
|
|
13411
|
+
{
|
|
13412
|
+
name: "jpop_standard",
|
|
13413
|
+
label: "JPOP\u738B\u9053",
|
|
13414
|
+
plan: [
|
|
13415
|
+
"intro",
|
|
13416
|
+
"verse",
|
|
13417
|
+
"verse",
|
|
13418
|
+
"prechorus",
|
|
13419
|
+
"chorus",
|
|
13420
|
+
"verse",
|
|
13421
|
+
"prechorus",
|
|
13422
|
+
"chorus",
|
|
13423
|
+
"bridge",
|
|
13424
|
+
"interlude",
|
|
13425
|
+
"chorus",
|
|
13426
|
+
"outro"
|
|
13427
|
+
]
|
|
13428
|
+
},
|
|
13429
|
+
// 落ちサビ入り(J-POP王道の変形。ラスサビ前に落ちサビ)
|
|
13430
|
+
{
|
|
13431
|
+
name: "jpop_drop",
|
|
13432
|
+
label: "\u843D\u3061\u30B5\u30D3\u5165\u308A",
|
|
13433
|
+
plan: [
|
|
13434
|
+
"intro",
|
|
13435
|
+
"verse",
|
|
13436
|
+
"verse",
|
|
13437
|
+
"prechorus",
|
|
13438
|
+
"chorus",
|
|
13439
|
+
"verse",
|
|
13440
|
+
"prechorus",
|
|
13441
|
+
"chorus",
|
|
13442
|
+
"bridge",
|
|
13443
|
+
"drop_chorus",
|
|
13444
|
+
"chorus",
|
|
13445
|
+
"outro"
|
|
13446
|
+
]
|
|
13447
|
+
},
|
|
13448
|
+
// ボカロ王道(短め高速、Aメロ繰り返しなし)
|
|
13449
|
+
{
|
|
13450
|
+
name: "vocaloid",
|
|
13451
|
+
label: "\u30DC\u30AB\u30ED\u738B\u9053",
|
|
13452
|
+
plan: [
|
|
13453
|
+
"intro",
|
|
13454
|
+
"verse",
|
|
13455
|
+
"prechorus",
|
|
13456
|
+
"chorus",
|
|
13457
|
+
"verse",
|
|
13458
|
+
"prechorus",
|
|
13459
|
+
"chorus",
|
|
13460
|
+
"bridge",
|
|
13461
|
+
"chorus",
|
|
13462
|
+
"outro"
|
|
13463
|
+
]
|
|
13464
|
+
},
|
|
13465
|
+
// Verse-Chorus形式(Bメロなし、洋楽的)
|
|
13466
|
+
{
|
|
13467
|
+
name: "verse_chorus",
|
|
13468
|
+
label: "Verse-Chorus",
|
|
13469
|
+
plan: [
|
|
13470
|
+
"intro",
|
|
13471
|
+
"verse",
|
|
13472
|
+
"chorus",
|
|
13473
|
+
"verse",
|
|
13474
|
+
"chorus",
|
|
13475
|
+
"bridge",
|
|
13476
|
+
"chorus",
|
|
13477
|
+
"outro"
|
|
13478
|
+
]
|
|
13479
|
+
}
|
|
13480
|
+
];
|
|
13481
|
+
var buildSectionPlan = (kinds, templateName) => {
|
|
13482
|
+
let ordered;
|
|
13483
|
+
if (templateName) {
|
|
13484
|
+
const tmpl = STRUCTURE_TEMPLATES.find((t) => t.name === templateName);
|
|
13485
|
+
ordered = tmpl ? tmpl.plan : DEFAULT_SECTIONS;
|
|
13486
|
+
} else {
|
|
13487
|
+
const wanted = kinds.length > 0 ? kinds : DEFAULT_SECTIONS;
|
|
13488
|
+
ordered = SECTION_ORDER.filter((k) => wanted.includes(k));
|
|
13489
|
+
}
|
|
13333
13490
|
const plan = [];
|
|
13334
13491
|
let bar = 0;
|
|
13492
|
+
const seen = /* @__PURE__ */ new Map();
|
|
13335
13493
|
for (const kind of ordered) {
|
|
13336
13494
|
const spec = SECTION_SPECS[kind];
|
|
13337
|
-
|
|
13495
|
+
const count = seen.get(kind) ?? 0;
|
|
13496
|
+
plan.push({
|
|
13497
|
+
kind,
|
|
13498
|
+
startBar: bar,
|
|
13499
|
+
bars: spec.bars,
|
|
13500
|
+
spec,
|
|
13501
|
+
keyShift: 0,
|
|
13502
|
+
restatement: count > 0
|
|
13503
|
+
});
|
|
13504
|
+
seen.set(kind, count + 1);
|
|
13338
13505
|
bar += spec.bars;
|
|
13339
13506
|
}
|
|
13340
13507
|
return plan;
|
|
13341
13508
|
};
|
|
13509
|
+
var sectionAt = (plan, bar) => {
|
|
13510
|
+
for (const section of plan) {
|
|
13511
|
+
if (bar >= section.startBar && bar < section.startBar + section.bars)
|
|
13512
|
+
return section;
|
|
13513
|
+
}
|
|
13514
|
+
return plan[plan.length - 1];
|
|
13515
|
+
};
|
|
13342
13516
|
|
|
13343
13517
|
// src/compose.ts
|
|
13344
13518
|
var STEP_SEMITONES = 2;
|
|
@@ -13624,6 +13798,16 @@ var SECTION_A_PROGRESSIONS = [
|
|
|
13624
13798
|
["Am", "Dm7", "Bb", "E7"]
|
|
13625
13799
|
// bVI からドミナントへ
|
|
13626
13800
|
];
|
|
13801
|
+
var SECTION_C_PROGRESSIONS = [
|
|
13802
|
+
["Am", "Em", "F", "C"],
|
|
13803
|
+
["Dm7", "Em7", "FM7", "G7"],
|
|
13804
|
+
["Am7", "Dm7", "G7", "CM7"],
|
|
13805
|
+
["F", "G", "Am", "G"],
|
|
13806
|
+
["Dm7", "G7", "Em7", "Am"],
|
|
13807
|
+
["FM7", "Em7", "Am7", "Dm7"],
|
|
13808
|
+
["Am", "G", "FM7", "E7"],
|
|
13809
|
+
["C", "Am", "FM7", "G7"]
|
|
13810
|
+
];
|
|
13627
13811
|
var SECTION_B_PROGRESSIONS = [
|
|
13628
13812
|
["F", "G", "Em7", "Am"],
|
|
13629
13813
|
["Dm7", "G7", "CM7", "A7"],
|
|
@@ -13850,10 +14034,9 @@ var HALF_BAR_FIGURES = [
|
|
|
13850
14034
|
[EIGHTH, EIGHTH, EIGHTH, EIGHTH],
|
|
13851
14035
|
// タタタタ
|
|
13852
14036
|
[EIGHTH, EIGHTH, EIGHTH, EIGHTH],
|
|
13853
|
-
[EIGHTH, EIGHTH, EIGHTH, EIGHTH],
|
|
13854
|
-
[EIGHTH, EIGHTH, EIGHTH, EIGHTH],
|
|
13855
14037
|
[QUARTER, EIGHTH, EIGHTH],
|
|
13856
14038
|
// ター・タタ
|
|
14039
|
+
[QUARTER, EIGHTH, EIGHTH],
|
|
13857
14040
|
[EIGHTH, EIGHTH, QUARTER],
|
|
13858
14041
|
// タタ・ター
|
|
13859
14042
|
[DOT_QUARTER, EIGHTH],
|
|
@@ -13861,8 +14044,24 @@ var HALF_BAR_FIGURES = [
|
|
|
13861
14044
|
[DOT_QUARTER, EIGHTH],
|
|
13862
14045
|
[EIGHTH, QUARTER, EIGHTH],
|
|
13863
14046
|
// 頭抜き
|
|
14047
|
+
// 4分音符主体・ロングトーン(J-POPの歌い上げるバラード〜ミドル向け。音数過多を是正)
|
|
14048
|
+
[QUARTER, QUARTER],
|
|
14049
|
+
// ター・ター
|
|
14050
|
+
[QUARTER, QUARTER],
|
|
14051
|
+
[HALF],
|
|
14052
|
+
// ターーー
|
|
13864
14053
|
[HALF],
|
|
13865
|
-
|
|
14054
|
+
[-QUARTER, QUARTER],
|
|
14055
|
+
// 休・ター
|
|
14056
|
+
[QUARTER, -QUARTER],
|
|
14057
|
+
// ター・休
|
|
14058
|
+
// 弱起(アウフタクト)パターン:末尾から次へ飛び込む言い回し
|
|
14059
|
+
[-DOT_QUARTER, EIGHTH],
|
|
14060
|
+
// 3拍半休みからの裏拍アウフタクト
|
|
14061
|
+
[-QUARTER, EIGHTH, EIGHTH],
|
|
14062
|
+
// 2拍目裏からのアウフタクト(タタ)
|
|
14063
|
+
[QUARTER, -EIGHTH, EIGHTH],
|
|
14064
|
+
// ター・休タ(8分裏弱起)
|
|
13866
14065
|
// 付点8分+16分(タッカ)。歌モノで非常に多用される跳ね・推進力の型。
|
|
13867
14066
|
[DOT_EIGHTH, SIXTEENTH, EIGHTH, EIGHTH],
|
|
13868
14067
|
[EIGHTH, EIGHTH, DOT_EIGHTH, SIXTEENTH],
|
|
@@ -14531,7 +14730,10 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14531
14730
|
};
|
|
14532
14731
|
const quarterSteps = scaleStep(QUARTER);
|
|
14533
14732
|
const strongStep = Math.max(1, Math.round(stepsPerBar / 2));
|
|
14534
|
-
const sectionPlan = buildSectionPlan(
|
|
14733
|
+
const sectionPlan = buildSectionPlan(
|
|
14734
|
+
options.sections ?? DEFAULT_SECTIONS,
|
|
14735
|
+
options.template
|
|
14736
|
+
);
|
|
14535
14737
|
const totalBars = sectionPlan.reduce((sum, s) => sum + s.bars, 0);
|
|
14536
14738
|
if (rnd() < 0.35) {
|
|
14537
14739
|
const modType = pick(
|
|
@@ -14568,12 +14770,18 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14568
14770
|
(p) => p.join("|") !== progA.join("|")
|
|
14569
14771
|
);
|
|
14570
14772
|
const progB = pick(progBPool, rnd);
|
|
14773
|
+
const progC = pick(
|
|
14774
|
+
SECTION_C_PROGRESSIONS.filter(
|
|
14775
|
+
(p) => p.join("|") !== progA.join("|") && p.join("|") !== progB.join("|")
|
|
14776
|
+
),
|
|
14777
|
+
rnd
|
|
14778
|
+
);
|
|
14571
14779
|
const tonic = progA[0].startsWith("Am") ? "Am" : "C";
|
|
14572
14780
|
const progHalf = pick(SECTION_A2_DERIVATIONS, rnd)(progA);
|
|
14573
14781
|
const progFull = pick(SECTION_A3_DERIVATIONS, rnd)(progA, tonic);
|
|
14574
14782
|
const progression = [];
|
|
14575
14783
|
for (const section of sectionPlan) {
|
|
14576
|
-
const base = section.spec.progression === "b" ? progB : progA;
|
|
14784
|
+
const base = section.spec.progression === "c" ? progC : section.spec.progression === "b" ? progB : progA;
|
|
14577
14785
|
for (let i2 = 0; i2 < section.bars; i2 += 4) {
|
|
14578
14786
|
const isLastPhrase = i2 + 4 >= section.bars;
|
|
14579
14787
|
if (!isLastPhrase) {
|
|
@@ -14591,7 +14799,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14591
14799
|
const chordPattern = pick(CHORD_PATTERNS, rnd);
|
|
14592
14800
|
const rootShift = resolvedKey.rootShift;
|
|
14593
14801
|
const bpm = pick(BPM_CHOICES, rnd);
|
|
14594
|
-
const sourceOf = (kind) => kind === "chorus" || kind === "interlude" ? "b" : kind === "prechorus" ? "a2" : "a";
|
|
14802
|
+
const sourceOf = (kind) => kind === "chorus" || kind === "interlude" || kind === "drop_chorus" ? "b" : kind === "prechorus" ? "a2" : kind === "bridge" ? "c" : "a";
|
|
14595
14803
|
const units2 = [];
|
|
14596
14804
|
for (const section of sectionPlan) {
|
|
14597
14805
|
const unitCount = Math.max(1, Math.round(section.bars / 2));
|
|
@@ -14628,6 +14836,19 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14628
14836
|
const barInUnit = (bar) => bar % 2;
|
|
14629
14837
|
const unitOf = (bar) => Math.floor(bar / 2);
|
|
14630
14838
|
const restatementOf = (bar) => {
|
|
14839
|
+
const curSec = sectionAt(sectionPlan, bar);
|
|
14840
|
+
if (!curSec.spec.melody) return null;
|
|
14841
|
+
if (curSec.restatement) {
|
|
14842
|
+
const firstSec = sectionPlan.find(
|
|
14843
|
+
(s) => s.kind === curSec.kind && !s.restatement
|
|
14844
|
+
);
|
|
14845
|
+
if (firstSec) {
|
|
14846
|
+
const offset = bar - curSec.startBar;
|
|
14847
|
+
if (offset < firstSec.bars) {
|
|
14848
|
+
return firstSec.startBar + offset;
|
|
14849
|
+
}
|
|
14850
|
+
}
|
|
14851
|
+
}
|
|
14631
14852
|
const u = unitOf(bar);
|
|
14632
14853
|
if (units2[u].source === "silent") return null;
|
|
14633
14854
|
for (let v = 0; v < u; v++) {
|
|
@@ -14657,10 +14878,9 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14657
14878
|
),
|
|
14658
14879
|
// 人間の曲の跳躍率は p25〜p75 で 0.40〜0.55。上限が低いとその帯へ届かない。
|
|
14659
14880
|
leapAffinity: 0.08 + rnd() * 0.3,
|
|
14660
|
-
//
|
|
14661
|
-
|
|
14662
|
-
|
|
14663
|
-
barHeadWeight: rnd() < 0.65 ? 3 : 2,
|
|
14881
|
+
// 界隈曲らしさ:調の外の音(クロマチック)や微小な逸脱を積極的に許容する。
|
|
14882
|
+
chromaticAffinity: rnd() < 0.1 ? 0 : 0.3 + rnd() * 0.6,
|
|
14883
|
+
barHeadWeight: rnd() < 0.5 ? 3 : 2,
|
|
14664
14884
|
bassStyle: pick(
|
|
14665
14885
|
[
|
|
14666
14886
|
"quarter",
|
|
@@ -14686,7 +14906,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14686
14906
|
subInterval: pick([3, 4, 8, 9], rnd)
|
|
14687
14907
|
};
|
|
14688
14908
|
const motifPool = groovyCells(MOTIF_CELLS, style.groove, rnd);
|
|
14689
|
-
const targetNotesPerBar =
|
|
14909
|
+
const targetNotesPerBar = 4 + rnd() * 4;
|
|
14690
14910
|
const targetRestRatio = 0.02 + rnd() * 0.1;
|
|
14691
14911
|
const cellNotes = (c) => c.value.filter((v) => v > 0).length;
|
|
14692
14912
|
const cellRest = (c) => {
|
|
@@ -14698,27 +14918,49 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14698
14918
|
}
|
|
14699
14919
|
return total === 0 ? 0 : rest / total;
|
|
14700
14920
|
};
|
|
14701
|
-
const cellDistance = (c) => Math.abs(cellNotes(c) - targetNotesPerBar) + Math.abs(cellRest(c) - targetRestRatio) * 8;
|
|
14702
|
-
const pickCell = (pool) => {
|
|
14921
|
+
const cellDistance = (c, densityMul = 1) => Math.abs(cellNotes(c) - targetNotesPerBar * densityMul) + Math.abs(cellRest(c) - targetRestRatio / Math.max(0.5, densityMul)) * 8;
|
|
14922
|
+
const pickCell = (pool, densityMul = 1) => {
|
|
14703
14923
|
let best = pick(pool, rnd);
|
|
14704
14924
|
for (let i2 = 0; i2 < 2; i2++) {
|
|
14705
14925
|
const c = pick(pool, rnd);
|
|
14706
|
-
if (cellDistance(c) < cellDistance(best))
|
|
14926
|
+
if (cellDistance(c, densityMul) < cellDistance(best, densityMul))
|
|
14927
|
+
best = c;
|
|
14707
14928
|
}
|
|
14708
14929
|
return best;
|
|
14709
14930
|
};
|
|
14710
|
-
const motifCell = pickCell(motifPool);
|
|
14711
|
-
const motifCell2 = rnd() < 0.45 ? motifCell : pickCell(
|
|
14931
|
+
const motifCell = pickCell(motifPool, 0.85);
|
|
14932
|
+
const motifCell2 = rnd() < 0.45 ? motifCell : pickCell(
|
|
14933
|
+
motifPool.filter((c) => c !== motifCell),
|
|
14934
|
+
0.85
|
|
14935
|
+
);
|
|
14712
14936
|
const motifB = pickCell(
|
|
14713
|
-
motifPool.filter((c) => c !== motifCell && c !== motifCell2)
|
|
14937
|
+
motifPool.filter((c) => c !== motifCell && c !== motifCell2),
|
|
14938
|
+
1.2
|
|
14939
|
+
);
|
|
14940
|
+
const motifB2 = pickCell(
|
|
14941
|
+
motifPool.filter((c) => c !== motifB),
|
|
14942
|
+
1.2
|
|
14714
14943
|
);
|
|
14715
|
-
const motifB2 = pickCell(motifPool.filter((c) => c !== motifB));
|
|
14716
14944
|
const motifA2 = pickCell(
|
|
14717
14945
|
motifPool.filter(
|
|
14718
14946
|
(c) => c !== motifCell && c !== motifCell2 && c !== motifB
|
|
14719
|
-
)
|
|
14947
|
+
),
|
|
14948
|
+
1.1
|
|
14949
|
+
);
|
|
14950
|
+
const motifA22 = rnd() < 0.45 ? motifA2 : pickCell(
|
|
14951
|
+
motifPool.filter((c) => c !== motifA2),
|
|
14952
|
+
1.1
|
|
14953
|
+
);
|
|
14954
|
+
const motifC = pickCell(
|
|
14955
|
+
motifPool.filter(
|
|
14956
|
+
(c) => c !== motifCell && c !== motifCell2 && c !== motifB && c !== motifA2
|
|
14957
|
+
),
|
|
14958
|
+
0.9
|
|
14959
|
+
);
|
|
14960
|
+
const motifC2 = rnd() < 0.45 ? motifC : pickCell(
|
|
14961
|
+
motifPool.filter((c) => c !== motifC),
|
|
14962
|
+
0.9
|
|
14720
14963
|
);
|
|
14721
|
-
const motifA22 = rnd() < 0.45 ? motifA2 : pickCell(motifPool.filter((c) => c !== motifA2));
|
|
14722
14964
|
const motifVar = pickCell(
|
|
14723
14965
|
motifPool.filter((c) => c !== motifCell && c !== motifCell2)
|
|
14724
14966
|
);
|
|
@@ -14771,12 +15013,13 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14771
15013
|
}
|
|
14772
15014
|
const isB = units2[u].source === "b";
|
|
14773
15015
|
const isA2 = units2[u].source === "a2";
|
|
15016
|
+
const isC = units2[u].source === "c";
|
|
14774
15017
|
const isPrechorusEnd = units2[u].section.kind === "prechorus" && bar === units2[u].section.startBar + units2[u].section.bars - 1;
|
|
14775
15018
|
if (isPrechorusEnd) {
|
|
14776
15019
|
barRhythms.push(scaleCell(buildUpCell.value));
|
|
14777
15020
|
continue;
|
|
14778
15021
|
}
|
|
14779
|
-
const pair = () => isB ? [motifB, motifB2] : isA2 ? [motifA2, motifA22] : [motifCell, motifCell2];
|
|
15022
|
+
const pair = () => isB ? [motifB, motifB2] : isA2 ? [motifA2, motifA22] : isC ? [motifC, motifC2] : [motifCell, motifCell2];
|
|
14780
15023
|
let cell;
|
|
14781
15024
|
if (units2[u].source === "answer") {
|
|
14782
15025
|
const isPeriodEnd = units2[u].landing !== null;
|
|
@@ -14807,6 +15050,8 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14807
15050
|
const melody = [];
|
|
14808
15051
|
const submelody = [];
|
|
14809
15052
|
const bass = [];
|
|
15053
|
+
const harmony = [];
|
|
15054
|
+
const pad = [];
|
|
14810
15055
|
const melodyDurations = [];
|
|
14811
15056
|
const barTension = new Array(totalBars).fill(0);
|
|
14812
15057
|
let restSteps = 0;
|
|
@@ -14853,13 +15098,22 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14853
15098
|
(bar + style.arcPhase) / style.arcPeriod * Math.PI * 2
|
|
14854
15099
|
);
|
|
14855
15100
|
const arcCenter = MELODY_CENTER + arc * style.arcAmp;
|
|
14856
|
-
const
|
|
14857
|
-
|
|
14858
|
-
|
|
14859
|
-
tones,
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
|
|
15101
|
+
const inUnit = barInUnit(bar);
|
|
15102
|
+
let headSemi;
|
|
15103
|
+
if (inUnit === 1 && bar > 0) {
|
|
15104
|
+
headSemi = nearestChordTone(prevSemi, tones, headWeight, isSectionB).semi;
|
|
15105
|
+
if (Math.abs(headSemi - prevSemi) > 4) {
|
|
15106
|
+
headSemi = nearestChordTone(prevSemi, tones, 1, isSectionB).semi;
|
|
15107
|
+
}
|
|
15108
|
+
} else {
|
|
15109
|
+
const headTarget = prevSemi + (arcCenter - prevSemi) * 0.5;
|
|
15110
|
+
headSemi = nearestChordTone(
|
|
15111
|
+
headTarget,
|
|
15112
|
+
tones,
|
|
15113
|
+
headWeight,
|
|
15114
|
+
isSectionB
|
|
15115
|
+
).semi;
|
|
15116
|
+
}
|
|
14863
15117
|
const contourOffset = barInUnit(bar) === 0 ? 0 : barRhythms[bar - 1].filter((v) => v > 0).length;
|
|
14864
15118
|
const prevRole = bar > 0 ? barRoles[bar - 1] : null;
|
|
14865
15119
|
const repeatShift = role === "motif" && (prevRole === "motif" || prevRole === "sequence" || prevRole === "climax") ? pick([-2, -1, 1, 2], rnd) : 0;
|
|
@@ -15039,6 +15293,48 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15039
15293
|
} else {
|
|
15040
15294
|
pushSub(scaleStep(QUARTER), scaleStep(DOT_HALF), subSemi);
|
|
15041
15295
|
}
|
|
15296
|
+
const barSec = sectionAt(sectionPlan, bar);
|
|
15297
|
+
if (!silent && (barSec.kind === "chorus" || barSec.kind === "drop_chorus")) {
|
|
15298
|
+
for (let i2 = 0; i2 < slots.length; i2++) {
|
|
15299
|
+
const hSemi = pitches[i2] + 3;
|
|
15300
|
+
const hTone = nearestChordTone(hSemi, tones, 2);
|
|
15301
|
+
const hClamped = clampSemi(hTone.semi, MELODY_LOW, MELODY_HIGH);
|
|
15302
|
+
const k = barKeyShift[bar];
|
|
15303
|
+
const fifthShift = k === 0 ? 0 : SEMITONE_TO_FIFTH_SHIFT[(k % 12 + 12) % 12];
|
|
15304
|
+
harmony.push({
|
|
15305
|
+
startStep: barStart + slots[i2].at,
|
|
15306
|
+
pitchUnits: spelledToUnits(
|
|
15307
|
+
hClamped + k,
|
|
15308
|
+
hTone.fifth + fifthShift,
|
|
15309
|
+
edo
|
|
15310
|
+
),
|
|
15311
|
+
durationSteps: slots[i2].value,
|
|
15312
|
+
velocity: slots[i2].at === 0 ? 82 : 76
|
|
15313
|
+
});
|
|
15314
|
+
}
|
|
15315
|
+
}
|
|
15316
|
+
if (barSec.kind === "prechorus" || barSec.kind === "chorus" || barSec.kind === "bridge" || barSec.kind === "drop_chorus") {
|
|
15317
|
+
const padTone = nearestChordTone(
|
|
15318
|
+
MELODY_HIGH + 2,
|
|
15319
|
+
// メロディの上の音域
|
|
15320
|
+
tones,
|
|
15321
|
+
2
|
|
15322
|
+
);
|
|
15323
|
+
const padSemi = clampSemi(padTone.semi, MELODY_HIGH - 4, MELODY_HIGH + 8);
|
|
15324
|
+
const k = barKeyShift[bar];
|
|
15325
|
+
const fifthShift = k === 0 ? 0 : SEMITONE_TO_FIFTH_SHIFT[(k % 12 + 12) % 12];
|
|
15326
|
+
pad.push({
|
|
15327
|
+
startStep: barStart,
|
|
15328
|
+
pitchUnits: spelledToUnits(
|
|
15329
|
+
padSemi + k,
|
|
15330
|
+
padTone.fifth + fifthShift,
|
|
15331
|
+
edo
|
|
15332
|
+
),
|
|
15333
|
+
durationSteps: stepsPerBar,
|
|
15334
|
+
// 小節全体を伸ばす
|
|
15335
|
+
velocity: barSec.kind === "drop_chorus" ? 50 : 62
|
|
15336
|
+
});
|
|
15337
|
+
}
|
|
15042
15338
|
const rootTone = tones[0];
|
|
15043
15339
|
const fifthTone = tones.find((t) => t.weight === 3 && t !== rootTone);
|
|
15044
15340
|
const thirdTone = tones.find((t) => t.weight === 2);
|
|
@@ -15145,6 +15441,69 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15145
15441
|
}
|
|
15146
15442
|
for (const n of barBass) bass.push(n);
|
|
15147
15443
|
}
|
|
15444
|
+
const eighthSteps = scaleStep(EIGHTH);
|
|
15445
|
+
for (let i2 = 0; i2 < melody.length - 1; i2++) {
|
|
15446
|
+
const cur = melody[i2];
|
|
15447
|
+
const nxt = melody[i2 + 1];
|
|
15448
|
+
const curEnd = cur.startStep + cur.durationSteps;
|
|
15449
|
+
const atBarBoundary = curEnd % stepsPerBar === 0 && nxt.startStep === curEnd;
|
|
15450
|
+
if (!atBarBoundary) continue;
|
|
15451
|
+
if (cur.durationSteps > eighthSteps) continue;
|
|
15452
|
+
const barIdx = Math.floor(curEnd / stepsPerBar);
|
|
15453
|
+
if (barIdx >= totalBars) continue;
|
|
15454
|
+
if (i2 + 1 >= melody.length - 1) continue;
|
|
15455
|
+
const curSec = sectionAt(sectionPlan, barIdx - 1);
|
|
15456
|
+
const nextSec = sectionAt(sectionPlan, barIdx);
|
|
15457
|
+
if (!nextSec.spec.melody || curSec !== nextSec) continue;
|
|
15458
|
+
const curSemi = Math.round(cur.pitchUnits / UNITS_PER_SEMITONE);
|
|
15459
|
+
const nxtSemi = Math.round(nxt.pitchUnits / UNITS_PER_SEMITONE);
|
|
15460
|
+
if (Math.abs(nxtSemi - curSemi) > 3) continue;
|
|
15461
|
+
const nextRole = barRoles[barIdx];
|
|
15462
|
+
let tieProb = 0.4;
|
|
15463
|
+
if (nextRole === "motif") tieProb = 0.05;
|
|
15464
|
+
else if (nextRole === "sequence") tieProb = 0.75;
|
|
15465
|
+
else if (nextRole === "climax") tieProb = 0.9;
|
|
15466
|
+
else if (nextRole === "cadence") tieProb = 0.1;
|
|
15467
|
+
if (rnd() < tieProb) {
|
|
15468
|
+
cur.durationSteps += nxt.durationSteps;
|
|
15469
|
+
melody.splice(i2 + 1, 1);
|
|
15470
|
+
if (i2 < melodyDurations.length - 1) {
|
|
15471
|
+
melodyDurations[i2] += melodyDurations[i2 + 1];
|
|
15472
|
+
melodyDurations.splice(i2 + 1, 1);
|
|
15473
|
+
}
|
|
15474
|
+
const hCurIdx = harmony.findIndex((h) => h.startStep === cur.startStep);
|
|
15475
|
+
const hNxtIdx = harmony.findIndex((h) => h.startStep === nxt.startStep);
|
|
15476
|
+
if (hCurIdx >= 0 && hNxtIdx >= 0) {
|
|
15477
|
+
harmony[hCurIdx].durationSteps += harmony[hNxtIdx].durationSteps;
|
|
15478
|
+
harmony.splice(hNxtIdx, 1);
|
|
15479
|
+
}
|
|
15480
|
+
i2--;
|
|
15481
|
+
}
|
|
15482
|
+
}
|
|
15483
|
+
for (let i2 = 0; i2 < melody.length; i2++) {
|
|
15484
|
+
const barIdx = Math.floor(melody[i2].startStep / stepsPerBar);
|
|
15485
|
+
if (barIdx >= totalBars) continue;
|
|
15486
|
+
const role = barRoles[barIdx];
|
|
15487
|
+
let splitProb = 0.15;
|
|
15488
|
+
if (role === "motif" || role === "sequence") splitProb = 0;
|
|
15489
|
+
else if (role === "climax") splitProb = 0.6;
|
|
15490
|
+
else if (role === "cadence") splitProb = 0;
|
|
15491
|
+
if (rnd() < splitProb && melody[i2].durationSteps === quarterSteps) {
|
|
15492
|
+
const half = scaleStep(EIGHTH);
|
|
15493
|
+
const newNote = {
|
|
15494
|
+
...melody[i2],
|
|
15495
|
+
startStep: melody[i2].startStep + half,
|
|
15496
|
+
durationSteps: half
|
|
15497
|
+
};
|
|
15498
|
+
melody[i2].durationSteps = half;
|
|
15499
|
+
melody.splice(i2 + 1, 0, newNote);
|
|
15500
|
+
if (i2 < melodyDurations.length) {
|
|
15501
|
+
melodyDurations[i2] = half;
|
|
15502
|
+
melodyDurations.splice(i2 + 1, 0, half);
|
|
15503
|
+
}
|
|
15504
|
+
i2++;
|
|
15505
|
+
}
|
|
15506
|
+
}
|
|
15148
15507
|
const range = (notes) => {
|
|
15149
15508
|
if (notes.length === 0) return 0;
|
|
15150
15509
|
const us = notes.map((n) => n.pitchUnits);
|
|
@@ -15152,7 +15511,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15152
15511
|
};
|
|
15153
15512
|
const shiftUnits = semitonesToUnits(rootShift, edo);
|
|
15154
15513
|
if (shiftUnits !== 0)
|
|
15155
|
-
for (const list of [melody, submelody, bass])
|
|
15514
|
+
for (const list of [melody, submelody, bass, harmony, pad])
|
|
15156
15515
|
for (const n of list) n.pitchUnits = n.pitchUnits + shiftUnits;
|
|
15157
15516
|
return {
|
|
15158
15517
|
chordProgression,
|
|
@@ -15167,6 +15526,8 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15167
15526
|
melody,
|
|
15168
15527
|
submelody,
|
|
15169
15528
|
bass,
|
|
15529
|
+
harmony,
|
|
15530
|
+
pad,
|
|
15170
15531
|
melodyDurations,
|
|
15171
15532
|
restSteps,
|
|
15172
15533
|
totalSteps: Math.max(1, sungBars) * stepsPerBar,
|
|
@@ -15202,7 +15563,16 @@ var evaluate = (d, recent) => {
|
|
|
15202
15563
|
fromMelody(toMetricNotes(d.submelody)),
|
|
15203
15564
|
opts
|
|
15204
15565
|
);
|
|
15205
|
-
const
|
|
15566
|
+
const verseBars = [];
|
|
15567
|
+
const chorusBars = [];
|
|
15568
|
+
for (const s of d.sections) {
|
|
15569
|
+
for (let b = s.startBar; b < s.startBar + s.bars; b++) {
|
|
15570
|
+
if (s.kind === "verse") verseBars.push(b);
|
|
15571
|
+
else if (s.kind === "chorus" || s.kind === "drop_chorus")
|
|
15572
|
+
chorusBars.push(b);
|
|
15573
|
+
}
|
|
15574
|
+
}
|
|
15575
|
+
const tension = tensionFeatures(d.barTension, { verseBars, chorusBars });
|
|
15206
15576
|
const density = densityFeatures(melodyFrom, opts);
|
|
15207
15577
|
const fingerprint = featureVector({
|
|
15208
15578
|
entropy,
|
|
@@ -15218,6 +15588,7 @@ var evaluate = (d, recent) => {
|
|
|
15218
15588
|
);
|
|
15219
15589
|
const at = (b, v) => band(v, b[0], b[1], b[2], b[3]);
|
|
15220
15590
|
const atc = (key, v) => centeredBand(v, CORPUS_BANDS[key], CORPUS_MEDIANS[key]);
|
|
15591
|
+
const peakBand = d.bars > 24 ? [0, 1, Math.round(d.bars / 16), Math.round(d.bars / 8) + 2] : HAND_BANDS.climaxPeaks;
|
|
15221
15592
|
const scoreBreakdown = {
|
|
15222
15593
|
entropy: atc("entropy", entropy),
|
|
15223
15594
|
valueKinds: atc("valueKinds", valueKinds),
|
|
@@ -15235,7 +15606,7 @@ var evaluate = (d, recent) => {
|
|
|
15235
15606
|
sim8: atc("sim8", structure.sim8),
|
|
15236
15607
|
phraseBreath: atc("phraseBreath", structure.phraseBreath),
|
|
15237
15608
|
climaxPosition: atc("climaxPosition", structure.climaxPosition),
|
|
15238
|
-
climaxPeaks: at(
|
|
15609
|
+
climaxPeaks: at(peakBand, structure.climaxPeaks),
|
|
15239
15610
|
complementarity: at(HAND_BANDS.complementarity, structure.complementarity),
|
|
15240
15611
|
subDensity: at(HAND_BANDS.subDensity, d.submelody.length / d.bars),
|
|
15241
15612
|
tensionRise: tension.rise,
|
|
@@ -15289,9 +15660,10 @@ var composeSong = (options) => {
|
|
|
15289
15660
|
bestScore = stats.score;
|
|
15290
15661
|
bestIsValid = ok;
|
|
15291
15662
|
best = {
|
|
15292
|
-
//
|
|
15663
|
+
// ドラム・楽器は勝った候補にだけ後から付ける(メロディに依存しないので
|
|
15293
15664
|
// 候補ごとに引いても採点は動かず、40本ぶん無駄になる)。
|
|
15294
15665
|
drum: "",
|
|
15666
|
+
instrument: "",
|
|
15295
15667
|
chordProgression: d.chordProgression,
|
|
15296
15668
|
chordPattern: d.chordPattern,
|
|
15297
15669
|
rootShift: d.rootShift,
|
|
@@ -15304,6 +15676,8 @@ var composeSong = (options) => {
|
|
|
15304
15676
|
melody: d.melody,
|
|
15305
15677
|
submelody: d.submelody,
|
|
15306
15678
|
bass: d.bass,
|
|
15679
|
+
harmony: d.harmony,
|
|
15680
|
+
pad: d.pad,
|
|
15307
15681
|
stats: { ...stats, attempts: attempt, rejected }
|
|
15308
15682
|
};
|
|
15309
15683
|
}
|
|
@@ -15311,6 +15685,7 @@ var composeSong = (options) => {
|
|
|
15311
15685
|
result.stats.attempts = count;
|
|
15312
15686
|
result.stats.rejected = rejected;
|
|
15313
15687
|
result.drum = pickBuiltinDrum(result, rnd);
|
|
15688
|
+
result.instrument = pickBuiltinInstrument(result, rnd);
|
|
15314
15689
|
return result;
|
|
15315
15690
|
};
|
|
15316
15691
|
var pickBuiltinDrum = (song, rnd) => {
|
|
@@ -15319,6 +15694,35 @@ var pickBuiltinDrum = (song, rnd) => {
|
|
|
15319
15694
|
const pool = song.bpm >= 150 ? ["4beat", "dance", "16beat", "disco"] : short >= 0.6 ? ["16beat", "dance", "4beat", "disco"] : song.bpm <= 110 && short < 0.4 ? ["bossa", "8beat"] : ["8beat", "4beat", "16beat"];
|
|
15320
15695
|
return pick(pool, rnd);
|
|
15321
15696
|
};
|
|
15697
|
+
var pickBuiltinInstrument = (song, rnd) => {
|
|
15698
|
+
const eighth = BASE_STEPS_PER_BAR / 8;
|
|
15699
|
+
const short = song.melody.filter((n) => n.durationSteps <= eighth).length / Math.max(1, song.melody.length);
|
|
15700
|
+
if (rnd() < 0.06) {
|
|
15701
|
+
return pick(["japanese_wa", "arabic_exotic"], rnd);
|
|
15702
|
+
}
|
|
15703
|
+
let pool;
|
|
15704
|
+
if (song.drum === "dance" || song.drum === "disco") {
|
|
15705
|
+
pool = song.bpm >= 150 ? ["cyber_punk", "synth_pop", "retro_game"] : ["synth_pop", "retro_game", "rock", "piano"];
|
|
15706
|
+
} else if (song.drum === "bossa") {
|
|
15707
|
+
pool = ["jazz_night", "acoustic", "piano"];
|
|
15708
|
+
} else if (song.bpm <= 105 && short < 0.4) {
|
|
15709
|
+
pool = ["ambient_cloud", "acoustic", "orchestra", "piano", "fantasy_rpg"];
|
|
15710
|
+
} else if (song.bpm >= 145) {
|
|
15711
|
+
pool = ["rock", "synth_pop", "cyber_punk", "retro_game", "piano"];
|
|
15712
|
+
} else if (song.stats.leapRatio >= 0.45) {
|
|
15713
|
+
pool = ["fantasy_rpg", "orchestra", "acoustic", "piano"];
|
|
15714
|
+
} else {
|
|
15715
|
+
pool = [
|
|
15716
|
+
"piano",
|
|
15717
|
+
"acoustic",
|
|
15718
|
+
"synth_pop",
|
|
15719
|
+
"rock",
|
|
15720
|
+
"jazz_night",
|
|
15721
|
+
"fantasy_rpg"
|
|
15722
|
+
];
|
|
15723
|
+
}
|
|
15724
|
+
return pick(pool, rnd);
|
|
15725
|
+
};
|
|
15322
15726
|
var LYRIC_WORDS = [
|
|
15323
15727
|
"\u3042\u3055",
|
|
15324
15728
|
"\u3072\u304B\u308A",
|
|
@@ -15720,74 +16124,89 @@ var buildUI = (target, options) => {
|
|
|
15720
16124
|
<details class="dtm-panel" data-dtm-acc="macro">
|
|
15721
16125
|
<summary>\u30DE\u30AF\u30ED</summary>
|
|
15722
16126
|
<div class="dtm-panel-body">
|
|
15723
|
-
<div class="dtm-
|
|
15724
|
-
<
|
|
15725
|
-
|
|
15726
|
-
|
|
15727
|
-
|
|
15728
|
-
|
|
15729
|
-
|
|
15730
|
-
<
|
|
15731
|
-
|
|
15732
|
-
<
|
|
15733
|
-
|
|
15734
|
-
|
|
15735
|
-
|
|
15736
|
-
|
|
15737
|
-
|
|
16127
|
+
<div class="dtm-compose-container ${showCompose ? "" : "dtm-hidden"}" data-dtm="compose-container">
|
|
16128
|
+
<div class="dtm-row" data-dtm="compose-row">
|
|
16129
|
+
<button class="dtm-btn dtm-btn--success" data-dtm="macro-compose" title="\u30B3\u30FC\u30C9\u9032\u884C\u30FB\u30E1\u30ED\u30C7\u30A3\u30FB\u30B5\u30D6\u30E1\u30ED\u30FB\u30D9\u30FC\u30B9\u30FB\u4F34\u594F\u30FB\u30C9\u30E9\u30E0\u3092\u81EA\u52D5\u3067\u4F5C\u308A\u307E\u3059">\u4F5C\u66F2</button>
|
|
16130
|
+
<button class="dtm-btn dtm-btn--success" data-dtm="macro-compose-vocal" title="\u4F5C\u66F2\u3057\u305F\u3046\u3048\u3067\u3001\u30E1\u30ED\u30C7\u30A3\u306B\u6B4C\u8A5E\u3092\u4ED8\u3051\u3066\u6B4C\u308F\u305B\u307E\u3059">\u6B4C\u5165\u308A\u4F5C\u66F2</button>
|
|
16131
|
+
<button class="dtm-infobtn" data-dtm="macro-compose-info" title="\u4F5C\u66F2\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
|
|
16132
|
+
<span class="dtm-grow"></span>
|
|
16133
|
+
</div>
|
|
16134
|
+
<div class="dtm-row" data-dtm="compose-template-row">
|
|
16135
|
+
<span class="dtm-label">\u69CB\u6210</span>
|
|
16136
|
+
<select class="dtm-select" data-dtm="compose-template" title="J-POP\u738B\u9053\u306A\u3069\u306E\u30D7\u30EA\u30BB\u30C3\u30C8\u69CB\u6210\u3092\u9078\u3073\u307E\u3059">
|
|
16137
|
+
<option value="custom">\u81EA\u7531\u9078\u629E\uFF08\u4E0B\u8A18\u30C1\u30A7\u30C3\u30AF\uFF09</option>
|
|
16138
|
+
<option value="1chorus">1\u30B3\u30FC\u30E9\u30B9\uFF08\u77ED\u3081\u30FB\u521D\u5FC3\u8005\u5411\u3051\uFF09</option>
|
|
16139
|
+
<option value="jpop_standard">JPOP\u738B\u9053\uFF08\u30DE\u30EA\u30FC\u30B4\u30FC\u30EB\u30C9\u578B 2\u756A/C\u30E1\u30ED/\u30E9\u30B9\u30B5\u30D3\uFF09</option>
|
|
16140
|
+
<option value="jpop_drop">\u843D\u3061\u30B5\u30D3\u5165\u308A\uFF08JPOP\u738B\u9053 + \u30E9\u30B9\u30B5\u30D3\u524D\u843D\u3061\u30B5\u30D3\uFF09</option>
|
|
16141
|
+
<option value="vocaloid">\u30DC\u30AB\u30ED\u738B\u9053\uFF08\u75BE\u8D70\u30FB2\u756A/C\u30E1\u30ED/\u30E9\u30B9\u30B5\u30D3\uFF09</option>
|
|
16142
|
+
<option value="verse_chorus">Verse-Chorus\uFF08B\u30E1\u30ED\u306A\u3057\u30FB\u6D0B\u697D\u98A8\uFF09</option>
|
|
16143
|
+
</select>
|
|
16144
|
+
</div>
|
|
16145
|
+
<div class="dtm-row" data-dtm="compose-sections-row">
|
|
16146
|
+
<span class="dtm-label">\u4F5C\u308B\u90E8\u5206</span>
|
|
16147
|
+
<div class="dtm-checks" data-dtm="compose-sections">
|
|
16148
|
+
<label class="dtm-check"><input type="checkbox" value="intro" checked>\u30A4\u30F3\u30C8\u30ED</label>
|
|
16149
|
+
<label class="dtm-check"><input type="checkbox" value="verse" checked>A\u30E1\u30ED</label>
|
|
16150
|
+
<label class="dtm-check"><input type="checkbox" value="prechorus" checked>B\u30E1\u30ED</label>
|
|
16151
|
+
<label class="dtm-check"><input type="checkbox" value="chorus" checked>\u30B5\u30D3</label>
|
|
16152
|
+
<label class="dtm-check"><input type="checkbox" value="bridge">C\u30E1\u30ED</label>
|
|
16153
|
+
<label class="dtm-check"><input type="checkbox" value="drop_chorus">\u843D\u3061\u30B5\u30D3</label>
|
|
16154
|
+
<label class="dtm-check"><input type="checkbox" value="interlude">\u9593\u594F</label>
|
|
16155
|
+
<label class="dtm-check"><input type="checkbox" value="outro">\u30A2\u30A6\u30C8\u30ED</label>
|
|
16156
|
+
</div>
|
|
16157
|
+
<span class="dtm-grow"></span>
|
|
16158
|
+
<span class="dtm-hint" data-dtm="compose-sections-len"></span>
|
|
16159
|
+
</div>
|
|
16160
|
+
<div class="dtm-row" data-dtm="compose-key-row">
|
|
16161
|
+
<span class="dtm-label">\u30D9\u30FC\u30B9\u8ABF</span>
|
|
16162
|
+
<select class="dtm-select" data-dtm="compose-key" title="\u81EA\u52D5\u4F5C\u66F2\u306E\u30D9\u30FC\u30B9\u3068\u306A\u308B\u8ABF\u3084\u96F0\u56F2\u6C17\u3092\u9078\u3073\u307E\u3059">
|
|
16163
|
+
<option value="any" title="\u516824\u8ABF\u304B\u3089\u30E9\u30F3\u30C0\u30E0\u306B\u6C7A\u5B9A\u3057\u307E\u3059">\u5E0C\u671B\u306A\u3057</option>
|
|
16164
|
+
<optgroup label="\u57FA\u672C">
|
|
16165
|
+
<option value="major" title="12\u306E\u9577\u8ABF\u306E\u4E2D\u304B\u3089\u30E9\u30F3\u30C0\u30E0\u306B\u62BD\u9078\u3057\u307E\u3059">\u9577\u8ABF</option>
|
|
16166
|
+
<option value="minor" title="12\u306E\u77ED\u8ABF\u306E\u4E2D\u304B\u3089\u30E9\u30F3\u30C0\u30E0\u306B\u62BD\u9078\u3057\u307E\u3059">\u77ED\u8ABF</option>
|
|
16167
|
+
</optgroup>
|
|
16168
|
+
<optgroup label="\u96F0\u56F2\u6C17\u304B\u3089\u9078\u3076\uFF08\u62BD\u9078\uFF09">
|
|
16169
|
+
<option value="mood_happy" title="\u30CF\u9577\u8ABF\u30FB\u30A4\u9577\u8ABF\u30FB\u5909\u30ED\u9577\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u7121\u57A2\u306B\u559C\u3070\u3057\u3044\u3001\u7267\u6B4C\u7684\u3001\u967D\u6C17\uFF09">\u559C\u3070\u3057\u3044\u30FB\u967D\u6C17\u306A\u66F2</option>
|
|
16170
|
+
<option value="mood_triumphant" title="\u30CB\u9577\u8ABF\u30FB\u5909\u30C8\u9577\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u610F\u6C17\u63DA\u3005\u3001\u52DD\u5229\u306E\u558A\u58F0\u3001\u56F0\u96E3\u6253\u7834\u3001\u5B89\u5835\uFF09">\u52DD\u5229\u30FB\u529B\u5F37\u3044\u66F2</option>
|
|
16171
|
+
<option value="mood_fierce" title="\u30DB\u9577\u8ABF\u30FB\u30D8\u9577\u8ABF\u30FB\u30ED\u9577\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u3051\u3093\u304B\u3063\u65E9\u3044\u3001\u6012\u308A\u72C2\u3063\u305F\u8352\u3005\u3057\u3055\u3001\u3069\u304E\u3064\u304F\u731B\u70C8\uFF09">\u6FC0\u3057\u3044\u30FB\u8352\u3005\u3057\u3044\u66F2</option>
|
|
16172
|
+
<option value="mood_solemn" title="\u30C8\u9577\u8ABF\u30FB\u30CB\u77ED\u8ABF\u30FB\u30A4\u77ED\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u53B3\u7C9B\u3001\u5D07\u9AD8\u3001\u5E7B\u60F3\u3001\u656C\u8654\u3001\u601D\u7D22\u7684\uFF09">\u53B3\u7C9B\u30FB\u5E7B\u60F3\u7684\u306A\u66F2</option>
|
|
16173
|
+
<option value="mood_plaintive" title="\u30CF\u77ED\u8ABF\u30FB\u30DB\u77ED\u8ABF\u30FB\u30D8\u77ED\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u7D14\u7C8B\u306B\u60B2\u3057\u3052\u3001\u604B\u308F\u305A\u3089\u3044\u3001\u843D\u3061\u7740\u304D\u306E\u306A\u3044\u3001\u7269\u60B2\u3057\u3044\u54C0\u6101\uFF09">\u7269\u60B2\u3057\u3044\u30FB\u54C0\u6101\u306E\u66F2</option>
|
|
16174
|
+
<option value="mood_melancholy" title="\u5909\u30CB\u9577\u8ABF\u30FB\u30ED\u77ED\u8ABF\u30FB\u5B30\u30CF\u77ED\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u60B2\u3057\u307F\u3001\u6182\u9B31\u3001\u5B64\u72EC\u3001\u5FCD\u8010\u3001\u843D\u80C6\u3001\u60B2\u6D99\uFF09">\u6182\u9B31\u30FB\u5B64\u72EC\u306A\u66F2</option>
|
|
16175
|
+
<option value="mood_anxious" title="\u30C8\u77ED\u8ABF\u30FB\u5909\u30DB\u77ED\u8ABF\u30FB\u5B30\u30D8\u77ED\u8ABF\u30FB\u5909\u30A4\u77ED\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u4E0D\u6E80\u3001\u4E0D\u5B89\u3001\u6DF1\u3044\u82E6\u60A9\u3001\u9670\u6C17\u306A\u61A4\u308A\uFF09">\u4E0D\u5B89\u30FB\u82E6\u60A9\u306A\u66F2</option>
|
|
16176
|
+
<option value="mood_dark" title="\u5909\u30DB\u9577\u8ABF\u30FB\u5909\u30A4\u9577\u8ABF\u30FB\u5909\u30ED\u77ED\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u53B3\u3057\u3044\u611B\u3001\u6B7B\u3001\u6C38\u9060\u3001\u88C1\u304D\u3001\u6697\u95C7\u3001\u6050\u308D\u3057\u3044\u5632\u308A\uFF09">\u6697\u95C7\u30FB\u91CD\u539A\u306A\u66F2</option>
|
|
16177
|
+
</optgroup>
|
|
16178
|
+
<optgroup label="\u9577\u8ABF\uFF08\u500B\u5225\u6307\u5B9A\uFF09">
|
|
16179
|
+
<option value="key_C" title="\u7121\u57A2\u306B\u559C\u3070\u3057\u3044\u3001\u7D14\u7C8B\u3001\u7D20\u6734\u3001\u51FA\u767A">\u30CF\u9577\u8ABF (C)</option>
|
|
16180
|
+
<option value="key_Db" title="\u60B2\u3057\u307F\u3001\u6182\u9B31\u306A\u3001\u7518\u7F8E\u306A\u611F\u50B7">\u5909\u30CB\u9577\u8ABF (D\u266D)</option>
|
|
16181
|
+
<option value="key_D" title="\u610F\u6C17\u63DA\u3005\u3068\u3057\u305F\u3001\u52DD\u5229\u306E\u3001\u558A\u58F0">\u30CB\u9577\u8ABF (D)</option>
|
|
16182
|
+
<option value="key_Eb" title="\u53B3\u3057\u3044\u3001\u304D\u3064\u3044\u3001\u305D\u308C\u3067\u3044\u3066\u611B\u306B\u6E80\u3061\u305F">\u5909\u30DB\u9577\u8ABF (E\u266D)</option>
|
|
16183
|
+
<option value="key_E" title="\u3051\u3093\u304B\u3063\u65E9\u3044\u3001\u8352\u3005\u3057\u3044\u3001\u8F1D\u304B\u3057\u3044\u60C5\u71B1">\u30DB\u9577\u8ABF (E)</option>
|
|
16184
|
+
<option value="key_F" title="\u6012\u308A\u72C2\u3063\u305F\u3001\u6C17\u6027\u306E\u8352\u3044\u3001\u4E00\u6642\u7684\u306A\u60B2\u5606">\u30D8\u9577\u8ABF (F)</option>
|
|
16185
|
+
<option value="key_Gb" title="\u56F0\u96E3\u306E\u6253\u7834\u3001\u5B89\u5835\u306E\u305F\u3081\u606F\u3001\u51F1\u65CB">\u5909\u30C8\u9577\u8ABF (G\u266D)</option>
|
|
16186
|
+
<option value="key_G" title="\u53B3\u7C9B\u306A\u3001\u5D07\u9AD8\u306A\u3001\u5E7B\u60F3\u3001\u8AA0\u5B9F">\u30C8\u9577\u8ABF (G)</option>
|
|
16187
|
+
<option value="key_Ab" title="\u6B7B\u3001\u6C38\u9060\u3001\u88C1\u304D\u3001\u6DF1\u9060\u306A\u7791\u60F3">\u5909\u30A4\u9577\u8ABF (A\u266D)</option>
|
|
16188
|
+
<option value="key_A" title="\u3046\u308C\u3057\u3044\u3001\u7267\u6B4C\u7684\u306A\u3001\u611B\u306E\u544A\u767D">\u30A4\u9577\u8ABF (A)</option>
|
|
16189
|
+
<option value="key_Bb" title="\u559C\u3070\u3057\u3044\u3001\u98A8\u5909\u308F\u308A\u306A\u3001\u967D\u6C17\u306A\u3001\u8EFD\u5FEB">\u5909\u30ED\u9577\u8ABF (B\u266D)</option>
|
|
16190
|
+
<option value="key_B" title="\u3069\u304E\u3064\u3044\u3001\u5F37\u70C8\u306A\u3001\u8352\u3063\u307D\u3044\u3001\u731B\u70C8">\u30ED\u9577\u8ABF (B)</option>
|
|
16191
|
+
</optgroup>
|
|
16192
|
+
<optgroup label="\u77ED\u8ABF\uFF08\u500B\u5225\u6307\u5B9A\uFF09">
|
|
16193
|
+
<option value="key_Am" title="\u67D4\u3089\u304B\u306A\u3001\u7269\u60B2\u3057\u3044\u3001\u656C\u8654\u306A\u3001\u7D20\u6734\u306A\u54C0\u6101">\u30A4\u77ED\u8ABF (Am)</option>
|
|
16194
|
+
<option value="key_Bbm" title="\u6050\u308D\u3057\u3044\u3001\u6697\u95C7\u3001\u5632\u308B\u3088\u3046\u306A\u3001\u4E0D\u6C17\u5473">\u5909\u30ED\u77ED\u8ABF (B\u266Dm)</option>
|
|
16195
|
+
<option value="key_Bm" title="\u5B64\u72EC\u306A\u3001\u6182\u9B31\u306A\u3001\u5FCD\u8010\u3001\u9759\u304B\u306A\u8AE6\u5FF5">\u30ED\u77ED\u8ABF (Bm)</option>
|
|
16196
|
+
<option value="key_Cm" title="\u7D14\u7C8B\u306B\u60B2\u3057\u3052\u306A\u3001\u604B\u308F\u305A\u3089\u3044\u306E\u3001\u60B2\u5287\u7684">\u30CF\u77ED\u8ABF (Cm)</option>
|
|
16197
|
+
<option value="key_Csm" title="\u843D\u80C6\u3001\u6CE3\u304D\u53EB\u3093\u3060\u3001\u60B2\u6D99\u306E\u3001\u6DF1\u3044\u5606\u304D">\u5B30\u30CF\u77ED\u8ABF (C\u266Fm)</option>
|
|
16198
|
+
<option value="key_Dm" title="\u53B3\u7C9B\u306A\u3001\u656C\u8654\u306A\u3001\u601D\u7D22\u7684\u306A\u3001\u91CD\u539A\u306A\u7948\u308A">\u30CB\u77ED\u8ABF (Dm)</option>
|
|
16199
|
+
<option value="key_Ebm" title="\u6DF1\u3044\u82E6\u60A9\u3001\u5B9F\u5B58\u7684\u306A\u4E0D\u5B89\u3001\u6226\u6144">\u5909\u30DB\u77ED\u8ABF (E\u266Dm)</option>
|
|
16200
|
+
<option value="key_Em" title="\u5F31\u3005\u3057\u3044\u3001\u306A\u307E\u3081\u304B\u3057\u3044\u3001\u843D\u3061\u7740\u304D\u306E\u306A\u3044">\u30DB\u77ED\u8ABF (Em)</option>
|
|
16201
|
+
<option value="key_Fm" title="\u307C\u3093\u3084\u308A\u3057\u305F\u3001\u7269\u60B2\u3057\u3044\u3001\u3057\u3081\u3084\u304B\u306A\u3001\u846C\u9001">\u30D8\u77ED\u8ABF (Fm)</option>
|
|
16202
|
+
<option value="key_Fsm" title="\u9670\u6C17\u306A\u3001\u6FC0\u3057\u3044\u61A4\u308A\u3001\u6697\u3044\u60C5\u5FF5">\u5B30\u30D8\u77ED\u8ABF (F\u266Fm)</option>
|
|
16203
|
+
<option value="key_Gm" title="\u4E0D\u6E80\u3001\u4E0D\u5B89\u3001\u3084\u308B\u305B\u306A\u3055\u3001\u60B2\u75DB\u306A\u53EB\u3073">\u30C8\u77ED\u8ABF (Gm)</option>
|
|
16204
|
+
<option value="key_Abm" title="\u4E0D\u670D\u306A\u3001\u5606\u304D\u306E\u3001\u6CE3\u304D\u53EB\u3093\u3060">\u5909\u30A4\u77ED\u8ABF (A\u266Dm)</option>
|
|
16205
|
+
</optgroup>
|
|
16206
|
+
</select>
|
|
16207
|
+
<span class="dtm-grow"></span>
|
|
16208
|
+
<span class="dtm-hint" data-dtm="compose-key-hint"></span>
|
|
15738
16209
|
</div>
|
|
15739
|
-
<span class="dtm-grow"></span>
|
|
15740
|
-
<span class="dtm-hint" data-dtm="compose-sections-len"></span>
|
|
15741
|
-
</div>
|
|
15742
|
-
<div class="dtm-row ${showCompose ? "" : "dtm-hidden"}" data-dtm="compose-key-row">
|
|
15743
|
-
<span class="dtm-label">\u30D9\u30FC\u30B9\u8ABF</span>
|
|
15744
|
-
<select class="dtm-select" data-dtm="compose-key" title="\u81EA\u52D5\u4F5C\u66F2\u306E\u30D9\u30FC\u30B9\u3068\u306A\u308B\u8ABF\u3084\u96F0\u56F2\u6C17\u3092\u9078\u3073\u307E\u3059">
|
|
15745
|
-
<option value="any" title="\u516824\u8ABF\u304B\u3089\u30E9\u30F3\u30C0\u30E0\u306B\u6C7A\u5B9A\u3057\u307E\u3059">\u5E0C\u671B\u306A\u3057</option>
|
|
15746
|
-
<optgroup label="\u57FA\u672C">
|
|
15747
|
-
<option value="major" title="12\u306E\u9577\u8ABF\u306E\u4E2D\u304B\u3089\u30E9\u30F3\u30C0\u30E0\u306B\u62BD\u9078\u3057\u307E\u3059">\u9577\u8ABF</option>
|
|
15748
|
-
<option value="minor" title="12\u306E\u77ED\u8ABF\u306E\u4E2D\u304B\u3089\u30E9\u30F3\u30C0\u30E0\u306B\u62BD\u9078\u3057\u307E\u3059">\u77ED\u8ABF</option>
|
|
15749
|
-
</optgroup>
|
|
15750
|
-
<optgroup label="\u96F0\u56F2\u6C17\u304B\u3089\u9078\u3076\uFF08\u62BD\u9078\uFF09">
|
|
15751
|
-
<option value="mood_happy" title="\u30CF\u9577\u8ABF\u30FB\u30A4\u9577\u8ABF\u30FB\u5909\u30ED\u9577\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u7121\u57A2\u306B\u559C\u3070\u3057\u3044\u3001\u7267\u6B4C\u7684\u3001\u967D\u6C17\uFF09">\u559C\u3070\u3057\u3044\u30FB\u967D\u6C17\u306A\u66F2</option>
|
|
15752
|
-
<option value="mood_triumphant" title="\u30CB\u9577\u8ABF\u30FB\u5909\u30C8\u9577\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u610F\u6C17\u63DA\u3005\u3001\u52DD\u5229\u306E\u558A\u58F0\u3001\u56F0\u96E3\u6253\u7834\u3001\u5B89\u5835\uFF09">\u52DD\u5229\u30FB\u529B\u5F37\u3044\u66F2</option>
|
|
15753
|
-
<option value="mood_fierce" title="\u30DB\u9577\u8ABF\u30FB\u30D8\u9577\u8ABF\u30FB\u30ED\u9577\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u3051\u3093\u304B\u3063\u65E9\u3044\u3001\u6012\u308A\u72C2\u3063\u305F\u8352\u3005\u3057\u3055\u3001\u3069\u304E\u3064\u304F\u731B\u70C8\uFF09">\u6FC0\u3057\u3044\u30FB\u8352\u3005\u3057\u3044\u66F2</option>
|
|
15754
|
-
<option value="mood_solemn" title="\u30C8\u9577\u8ABF\u30FB\u30CB\u77ED\u8ABF\u30FB\u30A4\u77ED\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u53B3\u7C9B\u3001\u5D07\u9AD8\u3001\u5E7B\u60F3\u3001\u656C\u8654\u3001\u601D\u7D22\u7684\uFF09">\u53B3\u7C9B\u30FB\u5E7B\u60F3\u7684\u306A\u66F2</option>
|
|
15755
|
-
<option value="mood_plaintive" title="\u30CF\u77ED\u8ABF\u30FB\u30DB\u77ED\u8ABF\u30FB\u30D8\u77ED\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u7D14\u7C8B\u306B\u60B2\u3057\u3052\u3001\u604B\u308F\u305A\u3089\u3044\u3001\u843D\u3061\u7740\u304D\u306E\u306A\u3044\u3001\u7269\u60B2\u3057\u3044\u54C0\u6101\uFF09">\u7269\u60B2\u3057\u3044\u30FB\u54C0\u6101\u306E\u66F2</option>
|
|
15756
|
-
<option value="mood_melancholy" title="\u5909\u30CB\u9577\u8ABF\u30FB\u30ED\u77ED\u8ABF\u30FB\u5B30\u30CF\u77ED\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u60B2\u3057\u307F\u3001\u6182\u9B31\u3001\u5B64\u72EC\u3001\u5FCD\u8010\u3001\u843D\u80C6\u3001\u60B2\u6D99\uFF09">\u6182\u9B31\u30FB\u5B64\u72EC\u306A\u66F2</option>
|
|
15757
|
-
<option value="mood_anxious" title="\u30C8\u77ED\u8ABF\u30FB\u5909\u30DB\u77ED\u8ABF\u30FB\u5B30\u30D8\u77ED\u8ABF\u30FB\u5909\u30A4\u77ED\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u4E0D\u6E80\u3001\u4E0D\u5B89\u3001\u6DF1\u3044\u82E6\u60A9\u3001\u9670\u6C17\u306A\u61A4\u308A\uFF09">\u4E0D\u5B89\u30FB\u82E6\u60A9\u306A\u66F2</option>
|
|
15758
|
-
<option value="mood_dark" title="\u5909\u30DB\u9577\u8ABF\u30FB\u5909\u30A4\u9577\u8ABF\u30FB\u5909\u30ED\u77ED\u8ABF\u304B\u3089\u62BD\u9078\uFF08\u53B3\u3057\u3044\u611B\u3001\u6B7B\u3001\u6C38\u9060\u3001\u88C1\u304D\u3001\u6697\u95C7\u3001\u6050\u308D\u3057\u3044\u5632\u308A\uFF09">\u6697\u95C7\u30FB\u91CD\u539A\u306A\u66F2</option>
|
|
15759
|
-
</optgroup>
|
|
15760
|
-
<optgroup label="\u9577\u8ABF\uFF08\u500B\u5225\u6307\u5B9A\uFF09">
|
|
15761
|
-
<option value="key_C" title="\u7121\u57A2\u306B\u559C\u3070\u3057\u3044\u3001\u7D14\u7C8B\u3001\u7D20\u6734\u3001\u51FA\u767A">\u30CF\u9577\u8ABF (C)</option>
|
|
15762
|
-
<option value="key_Db" title="\u60B2\u3057\u307F\u3001\u6182\u9B31\u306A\u3001\u7518\u7F8E\u306A\u611F\u50B7">\u5909\u30CB\u9577\u8ABF (D\u266D)</option>
|
|
15763
|
-
<option value="key_D" title="\u610F\u6C17\u63DA\u3005\u3068\u3057\u305F\u3001\u52DD\u5229\u306E\u3001\u558A\u58F0">\u30CB\u9577\u8ABF (D)</option>
|
|
15764
|
-
<option value="key_Eb" title="\u53B3\u3057\u3044\u3001\u304D\u3064\u3044\u3001\u305D\u308C\u3067\u3044\u3066\u611B\u306B\u6E80\u3061\u305F">\u5909\u30DB\u9577\u8ABF (E\u266D)</option>
|
|
15765
|
-
<option value="key_E" title="\u3051\u3093\u304B\u3063\u65E9\u3044\u3001\u8352\u3005\u3057\u3044\u3001\u8F1D\u304B\u3057\u3044\u60C5\u71B1">\u30DB\u9577\u8ABF (E)</option>
|
|
15766
|
-
<option value="key_F" title="\u6012\u308A\u72C2\u3063\u305F\u3001\u6C17\u6027\u306E\u8352\u3044\u3001\u4E00\u6642\u7684\u306A\u60B2\u5606">\u30D8\u9577\u8ABF (F)</option>
|
|
15767
|
-
<option value="key_Gb" title="\u56F0\u96E3\u306E\u6253\u7834\u3001\u5B89\u5835\u306E\u305F\u3081\u606F\u3001\u51F1\u65CB">\u5909\u30C8\u9577\u8ABF (G\u266D)</option>
|
|
15768
|
-
<option value="key_G" title="\u53B3\u7C9B\u306A\u3001\u5D07\u9AD8\u306A\u3001\u5E7B\u60F3\u3001\u8AA0\u5B9F">\u30C8\u9577\u8ABF (G)</option>
|
|
15769
|
-
<option value="key_Ab" title="\u6B7B\u3001\u6C38\u9060\u3001\u88C1\u304D\u3001\u6DF1\u9060\u306A\u7791\u60F3">\u5909\u30A4\u9577\u8ABF (A\u266D)</option>
|
|
15770
|
-
<option value="key_A" title="\u3046\u308C\u3057\u3044\u3001\u7267\u6B4C\u7684\u306A\u3001\u611B\u306E\u544A\u767D">\u30A4\u9577\u8ABF (A)</option>
|
|
15771
|
-
<option value="key_Bb" title="\u559C\u3070\u3057\u3044\u3001\u98A8\u5909\u308F\u308A\u306A\u3001\u967D\u6C17\u306A\u3001\u8EFD\u5FEB">\u5909\u30ED\u9577\u8ABF (B\u266D)</option>
|
|
15772
|
-
<option value="key_B" title="\u3069\u304E\u3064\u3044\u3001\u5F37\u70C8\u306A\u3001\u8352\u3063\u307D\u3044\u3001\u731B\u70C8">\u30ED\u9577\u8ABF (B)</option>
|
|
15773
|
-
</optgroup>
|
|
15774
|
-
<optgroup label="\u77ED\u8ABF\uFF08\u500B\u5225\u6307\u5B9A\uFF09">
|
|
15775
|
-
<option value="key_Am" title="\u67D4\u3089\u304B\u306A\u3001\u7269\u60B2\u3057\u3044\u3001\u656C\u8654\u306A\u3001\u7D20\u6734\u306A\u54C0\u6101">\u30A4\u77ED\u8ABF (Am)</option>
|
|
15776
|
-
<option value="key_Bbm" title="\u6050\u308D\u3057\u3044\u3001\u6697\u95C7\u3001\u5632\u308B\u3088\u3046\u306A\u3001\u4E0D\u6C17\u5473">\u5909\u30ED\u77ED\u8ABF (B\u266Dm)</option>
|
|
15777
|
-
<option value="key_Bm" title="\u5B64\u72EC\u306A\u3001\u6182\u9B31\u306A\u3001\u5FCD\u8010\u3001\u9759\u304B\u306A\u8AE6\u5FF5">\u30ED\u77ED\u8ABF (Bm)</option>
|
|
15778
|
-
<option value="key_Cm" title="\u7D14\u7C8B\u306B\u60B2\u3057\u3052\u306A\u3001\u604B\u308F\u305A\u3089\u3044\u306E\u3001\u60B2\u5287\u7684">\u30CF\u77ED\u8ABF (Cm)</option>
|
|
15779
|
-
<option value="key_Csm" title="\u843D\u80C6\u3001\u6CE3\u304D\u53EB\u3093\u3060\u3001\u60B2\u6D99\u306E\u3001\u6DF1\u3044\u5606\u304D">\u5B30\u30CF\u77ED\u8ABF (C\u266Fm)</option>
|
|
15780
|
-
<option value="key_Dm" title="\u53B3\u7C9B\u306A\u3001\u656C\u8654\u306A\u3001\u601D\u7D22\u7684\u306A\u3001\u91CD\u539A\u306A\u7948\u308A">\u30CB\u77ED\u8ABF (Dm)</option>
|
|
15781
|
-
<option value="key_Ebm" title="\u6DF1\u3044\u82E6\u60A9\u3001\u5B9F\u5B58\u7684\u306A\u4E0D\u5B89\u3001\u6226\u6144">\u5909\u30DB\u77ED\u8ABF (E\u266Dm)</option>
|
|
15782
|
-
<option value="key_Em" title="\u5F31\u3005\u3057\u3044\u3001\u306A\u307E\u3081\u304B\u3057\u3044\u3001\u843D\u3061\u7740\u304D\u306E\u306A\u3044">\u30DB\u77ED\u8ABF (Em)</option>
|
|
15783
|
-
<option value="key_Fm" title="\u307C\u3093\u3084\u308A\u3057\u305F\u3001\u7269\u60B2\u3057\u3044\u3001\u3057\u3081\u3084\u304B\u306A\u3001\u846C\u9001">\u30D8\u77ED\u8ABF (Fm)</option>
|
|
15784
|
-
<option value="key_Fsm" title="\u9670\u6C17\u306A\u3001\u6FC0\u3057\u3044\u61A4\u308A\u3001\u6697\u3044\u60C5\u5FF5">\u5B30\u30D8\u77ED\u8ABF (F\u266Fm)</option>
|
|
15785
|
-
<option value="key_Gm" title="\u4E0D\u6E80\u3001\u4E0D\u5B89\u3001\u3084\u308B\u305B\u306A\u3055\u3001\u60B2\u75DB\u306A\u53EB\u3073">\u30C8\u77ED\u8ABF (Gm)</option>
|
|
15786
|
-
<option value="key_Abm" title="\u4E0D\u670D\u306A\u3001\u5606\u304D\u306E\u3001\u6CE3\u304D\u53EB\u3093\u3060">\u5909\u30A4\u77ED\u8ABF (A\u266Dm)</option>
|
|
15787
|
-
</optgroup>
|
|
15788
|
-
</select>
|
|
15789
|
-
<span class="dtm-grow"></span>
|
|
15790
|
-
<span class="dtm-hint" data-dtm="compose-key-hint"></span>
|
|
15791
16210
|
</div>
|
|
15792
16211
|
<div class="dtm-row">
|
|
15793
16212
|
<span class="dtm-label">\u5168\u4F53\u30B7\u30D5\u30C8</span>
|
|
@@ -15985,6 +16404,7 @@ var buildUI = (target, options) => {
|
|
|
15985
16404
|
transposeApplyBtn: sel("transpose-apply"),
|
|
15986
16405
|
transposeInfoBtn: sel("transpose-info"),
|
|
15987
16406
|
macroCompose: sel("macro-compose"),
|
|
16407
|
+
composeTemplate: sel("compose-template"),
|
|
15988
16408
|
composeSections: sel("compose-sections"),
|
|
15989
16409
|
composeSectionsLen: sel("compose-sections-len"),
|
|
15990
16410
|
composeKey: sel("compose-key"),
|
|
@@ -16127,6 +16547,45 @@ var INSTRUMENT_PRESETS = {
|
|
|
16127
16547
|
}
|
|
16128
16548
|
};
|
|
16129
16549
|
|
|
16550
|
+
// src/macro-state.ts
|
|
16551
|
+
var MACRO_STORAGE_KEYS = {
|
|
16552
|
+
template: "dtm-macro:template",
|
|
16553
|
+
sections: "dtm-macro:sections",
|
|
16554
|
+
key: "dtm-macro:key",
|
|
16555
|
+
shift: "dtm-macro:shift",
|
|
16556
|
+
transpose: "dtm-macro:transpose"
|
|
16557
|
+
};
|
|
16558
|
+
var readMacroSetting = (key) => {
|
|
16559
|
+
try {
|
|
16560
|
+
if (typeof localStorage === "undefined" || !localStorage) return null;
|
|
16561
|
+
return localStorage.getItem(MACRO_STORAGE_KEYS[key]);
|
|
16562
|
+
} catch (_) {
|
|
16563
|
+
return null;
|
|
16564
|
+
}
|
|
16565
|
+
};
|
|
16566
|
+
var writeMacroSetting = (key, value) => {
|
|
16567
|
+
try {
|
|
16568
|
+
if (typeof localStorage === "undefined" || !localStorage) return;
|
|
16569
|
+
localStorage.setItem(MACRO_STORAGE_KEYS[key], value);
|
|
16570
|
+
} catch (_) {
|
|
16571
|
+
}
|
|
16572
|
+
};
|
|
16573
|
+
var readMacroSections = () => {
|
|
16574
|
+
const raw = readMacroSetting("sections");
|
|
16575
|
+
if (!raw) return null;
|
|
16576
|
+
try {
|
|
16577
|
+
const parsed = JSON.parse(raw);
|
|
16578
|
+
if (Array.isArray(parsed) && parsed.every((x2) => typeof x2 === "string")) {
|
|
16579
|
+
return parsed;
|
|
16580
|
+
}
|
|
16581
|
+
} catch (_) {
|
|
16582
|
+
}
|
|
16583
|
+
return null;
|
|
16584
|
+
};
|
|
16585
|
+
var writeMacroSections = (sections) => {
|
|
16586
|
+
writeMacroSetting("sections", JSON.stringify(sections));
|
|
16587
|
+
};
|
|
16588
|
+
|
|
16130
16589
|
// src/macros.ts
|
|
16131
16590
|
var SCALES = [
|
|
16132
16591
|
[0, 2, 4, 5, 7, 9, 11],
|
|
@@ -18162,7 +18621,7 @@ var COMPOSE_INFO_HTML = `
|
|
|
18162
18621
|
<tr><td>\u30A2\u30A6\u30C8\u30ED</td><td>\u6709\u308A</td><td>\u4F4E\u3081</td><td>\u8584\u3044</td><td>\u4E3B\u97F3\u3078\u7740\u5730</td></tr>
|
|
18163
18622
|
</table>
|
|
18164
18623
|
<p>\u30A4\u30F3\u30C8\u30ED\u3068\u9593\u594F\u306F\u30E1\u30ED\u30C7\u30A3\u3092\u66F8\u304D\u307E\u305B\u3093\uFF08\u4F34\u594F\u30FB\u30D9\u30FC\u30B9\u30FB\u30C9\u30E9\u30E0\u30FB\u30B5\u30D6\u30E1\u30ED\u3060\u3051\u304C\u9CF4\u308A\u307E\u3059\uFF09\u3002\u3053\u3053\u306B\u6B4C\u30E1\u30ED\u3092\u7F6E\u304F\u3068\u3001\u3069\u306E\u30BB\u30AF\u30B7\u30E7\u30F3\u3082\u540C\u3058\u9854\u306B\u306A\u3063\u3066\u300C\u305A\u3063\u3068\u6B4C\u3063\u3066\u3044\u308B\u66F2\u300D\u306B\u306A\u3063\u3066\u3057\u307E\u3046\u305F\u3081\u3067\u3059\u3002\u30BB\u30AF\u30B7\u30E7\u30F3\u306E\u982D\u3067\u306F\u30C9\u30E9\u30E0\u304C\u30AF\u30E9\u30C3\u30B7\u30E5\u3092\u53E9\u304D\u3001\u7D42\u308F\u308A\u306E1\u3064\u624B\u524D\u3067\u30D5\u30A3\u30EB\u304C\u5165\u308A\u307E\u3059\u3002</p>
|
|
18165
|
-
<p>\u30CE\u30FC\u30C8\
|
|
18624
|
+
<p>\u30CE\u30FC\u30C8\u306E\u914D\u7F6E\u306B\u52A0\u3048\u3066\u3001\u30C6\u30F3\u30DD\u30FB\u30C9\u30E9\u30E0\u30FB\u697D\u5668\u30FB<strong>\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0</strong>\uFF08\u5404\u30C8\u30E9\u30C3\u30AF\u306E\u97F3\u91CF\u30D0\u30E9\u30F3\u30B9\u30FB\u5B9A\u4F4D\u30FBEQ\u30FB\u30B3\u30F3\u30D7\u30EC\u30C3\u30B5\u30FC\u30FB\u30EA\u30D0\u30FC\u30D6\u30FB\u30DE\u30B9\u30BF\u8A2D\u5B9A\uFF09\u3082\u81EA\u52D5\u3067\u4E00\u62EC\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u3067\u304D\u305F\u5F8C\u306B\u5FAE\u8ABF\u6574\u3057\u305F\u3044\u3068\u304D\u306F\u3001\u5404\u30C8\u30E9\u30C3\u30AF\u306E\u8A2D\u5B9A\u3084\u300C\u5168\u4F53\u30C8\u30E9\u30C3\u30AF\u8A2D\u5B9A\u300D\u304B\u3089\u81EA\u7531\u306B\u5909\u66F4\u3067\u304D\u307E\u3059\u3002</p>
|
|
18166
18625
|
<h4>\u66F2\u306E\u7D44\u307F\u7ACB\u3066\u65B9</h4>
|
|
18167
18626
|
<p>\u5358\u7D14\u306B\u30E9\u30F3\u30C0\u30E0\u306A\u97F3\u3092\u4E26\u3079\u3066\u3044\u308B\u308F\u3051\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u6B21\u306E\u9806\u756A\u3067\u7D44\u307F\u7ACB\u3066\u3066\u3044\u307E\u3059\u3002</p>
|
|
18168
18627
|
<ol>
|
|
@@ -18470,12 +18929,15 @@ var pickComposeVocal = (exclude) => {
|
|
|
18470
18929
|
var ADVANCED_COMPOSE_LAYOUT = [
|
|
18471
18930
|
{ index: 0, part: "melody", octave: 0, volume: 104 },
|
|
18472
18931
|
{ index: 1, part: "melody", octave: 1, volume: 62 },
|
|
18473
|
-
{ index: 2, part: "
|
|
18474
|
-
{ index: 3, part: "
|
|
18475
|
-
{ index: 4, part: "bass", octave:
|
|
18476
|
-
{ index: 5, part: "
|
|
18477
|
-
{ index: 6, part: "
|
|
18478
|
-
{ index: 7, part: "
|
|
18932
|
+
{ index: 2, part: "harmony", octave: 0, volume: 82 },
|
|
18933
|
+
{ index: 3, part: "submelody", octave: 0, volume: 86 },
|
|
18934
|
+
{ index: 4, part: "bass", octave: 0, volume: 92 },
|
|
18935
|
+
{ index: 5, part: "bass", octave: -1, volume: 58 },
|
|
18936
|
+
{ index: 6, part: "pad", octave: 0, volume: 64 },
|
|
18937
|
+
{ index: 7, part: "block", octave: 0, volume: 62 },
|
|
18938
|
+
{ index: 8, part: "arpeggio", octave: 0, volume: 54 },
|
|
18939
|
+
{ index: 9, part: "offbeat", octave: 0, volume: 50 },
|
|
18940
|
+
{ index: 10, part: "uwamono", octave: 1, volume: 56 }
|
|
18479
18941
|
];
|
|
18480
18942
|
var LYRIC_MODEL_CATEGORIES = [
|
|
18481
18943
|
{
|
|
@@ -18765,6 +19227,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
18765
19227
|
options.onDrumFontChange?.(font);
|
|
18766
19228
|
};
|
|
18767
19229
|
let currentInstrument = "";
|
|
19230
|
+
let autoComposeInstrument = null;
|
|
18768
19231
|
let activeTrackId = options.initialActiveTrack ?? trackConfigs[0].id;
|
|
18769
19232
|
let trackFxAdvancedOpen = readPanelOpen("track-fx-advanced") ?? false;
|
|
18770
19233
|
let lyricAdvancedOpen = readPanelOpen("lyric-advanced") ?? false;
|
|
@@ -19802,8 +20265,8 @@ var mountDAW = (target, options = {}) => {
|
|
|
19802
20265
|
redrawAll();
|
|
19803
20266
|
},
|
|
19804
20267
|
onEnd: (interrupted) => {
|
|
19805
|
-
options.onScheduleFade?.(null);
|
|
19806
20268
|
if (interrupted) {
|
|
20269
|
+
options.onScheduleFade?.(null);
|
|
19807
20270
|
playbackState = "paused";
|
|
19808
20271
|
pausedPlayStep = currentPlayStep;
|
|
19809
20272
|
} else {
|
|
@@ -21758,7 +22221,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
21758
22221
|
refs.autoMasterInfoBtn.addEventListener("click", () => {
|
|
21759
22222
|
showModal("\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0\u89E3\u8AAC", AUTO_MASTER_INFO_HTML);
|
|
21760
22223
|
});
|
|
21761
|
-
|
|
22224
|
+
const applyAutoMastering = () => {
|
|
21762
22225
|
if (observedPlayMs >= PEAK_SAMPLE_MIN_PLAY_MS && observedPeakMax > 0) {
|
|
21763
22226
|
const targetPeak = 0.5;
|
|
21764
22227
|
const scale = targetPeak / observedPeakMax;
|
|
@@ -21911,6 +22374,9 @@ var mountDAW = (target, options = {}) => {
|
|
|
21911
22374
|
}
|
|
21912
22375
|
}
|
|
21913
22376
|
updateTrackPanel();
|
|
22377
|
+
};
|
|
22378
|
+
refs.autoMasterBtn.addEventListener("click", () => {
|
|
22379
|
+
applyAutoMastering();
|
|
21914
22380
|
});
|
|
21915
22381
|
refs.drumSelect.addEventListener("change", () => {
|
|
21916
22382
|
currentDrumPattern = refs.drumSelect.value;
|
|
@@ -21928,12 +22394,9 @@ var mountDAW = (target, options = {}) => {
|
|
|
21928
22394
|
refs.macroComposeInfo.addEventListener("click", () => {
|
|
21929
22395
|
showModal("\u4F5C\u66F2\u306E\u89E3\u8AAC", COMPOSE_INFO_HTML);
|
|
21930
22396
|
});
|
|
21931
|
-
const
|
|
21932
|
-
|
|
21933
|
-
|
|
21934
|
-
return t ? [t] : [];
|
|
21935
|
-
}
|
|
21936
|
-
return ADVANCED_COMPOSE_LAYOUT.filter((l) => l.part === "bass").map((l) => trackStates[l.index]).filter((t) => !!t);
|
|
22397
|
+
const selectedComposeTemplate = () => {
|
|
22398
|
+
const val = refs.composeTemplate?.value;
|
|
22399
|
+
return val && val !== "custom" ? val : void 0;
|
|
21937
22400
|
};
|
|
21938
22401
|
const selectedComposeSections = () => {
|
|
21939
22402
|
const boxes = [
|
|
@@ -21945,11 +22408,97 @@ var mountDAW = (target, options = {}) => {
|
|
|
21945
22408
|
return picked.length > 0 ? picked : DEFAULT_SECTIONS;
|
|
21946
22409
|
};
|
|
21947
22410
|
const updateComposeSectionsLen = () => {
|
|
21948
|
-
const
|
|
22411
|
+
const tmpl = selectedComposeTemplate();
|
|
22412
|
+
const plan = buildSectionPlan(selectedComposeSections(), tmpl);
|
|
21949
22413
|
const bars = plan.reduce((sum, x2) => sum + x2.bars, 0);
|
|
21950
22414
|
refs.composeSectionsLen.textContent = `${bars}\u5C0F\u7BC0`;
|
|
21951
22415
|
};
|
|
21952
|
-
|
|
22416
|
+
const savedTemplate = readMacroSetting("template");
|
|
22417
|
+
if (savedTemplate && refs.composeTemplate) {
|
|
22418
|
+
const hasOption = Array.from(refs.composeTemplate.options).some(
|
|
22419
|
+
(opt) => opt.value === savedTemplate
|
|
22420
|
+
);
|
|
22421
|
+
if (hasOption) {
|
|
22422
|
+
refs.composeTemplate.value = savedTemplate;
|
|
22423
|
+
}
|
|
22424
|
+
}
|
|
22425
|
+
const savedSections = readMacroSections();
|
|
22426
|
+
if (savedSections && refs.composeSections) {
|
|
22427
|
+
const boxes = refs.composeSections.querySelectorAll(
|
|
22428
|
+
'input[type="checkbox"]'
|
|
22429
|
+
);
|
|
22430
|
+
const validValues = new Set(savedSections);
|
|
22431
|
+
for (const box of boxes) {
|
|
22432
|
+
box.checked = validValues.has(box.value);
|
|
22433
|
+
}
|
|
22434
|
+
} else if (savedTemplate && savedTemplate !== "custom" && refs.composeSections) {
|
|
22435
|
+
const tmpl = STRUCTURE_TEMPLATES.find((t) => t.name === savedTemplate);
|
|
22436
|
+
if (tmpl) {
|
|
22437
|
+
const planSet = new Set(tmpl.plan);
|
|
22438
|
+
const boxes = refs.composeSections.querySelectorAll(
|
|
22439
|
+
'input[type="checkbox"]'
|
|
22440
|
+
);
|
|
22441
|
+
for (const box of boxes) {
|
|
22442
|
+
box.checked = planSet.has(box.value);
|
|
22443
|
+
}
|
|
22444
|
+
}
|
|
22445
|
+
}
|
|
22446
|
+
const savedKey = readMacroSetting("key");
|
|
22447
|
+
if (savedKey && refs.composeKey) {
|
|
22448
|
+
const hasOption = Array.from(refs.composeKey.options).some(
|
|
22449
|
+
(opt) => opt.value === savedKey
|
|
22450
|
+
);
|
|
22451
|
+
if (hasOption) {
|
|
22452
|
+
refs.composeKey.value = savedKey;
|
|
22453
|
+
}
|
|
22454
|
+
}
|
|
22455
|
+
const savedShift = readMacroSetting("shift");
|
|
22456
|
+
if (savedShift && refs.shiftSelect) {
|
|
22457
|
+
const hasOption = Array.from(refs.shiftSelect.options).some(
|
|
22458
|
+
(opt) => opt.value === savedShift
|
|
22459
|
+
);
|
|
22460
|
+
if (hasOption) {
|
|
22461
|
+
refs.shiftSelect.value = savedShift;
|
|
22462
|
+
}
|
|
22463
|
+
}
|
|
22464
|
+
const savedTranspose = readMacroSetting("transpose");
|
|
22465
|
+
if (savedTranspose && refs.transposeSelect) {
|
|
22466
|
+
const hasOption = Array.from(refs.transposeSelect.options).some(
|
|
22467
|
+
(opt) => opt.value === savedTranspose
|
|
22468
|
+
);
|
|
22469
|
+
if (hasOption) {
|
|
22470
|
+
refs.transposeSelect.value = savedTranspose;
|
|
22471
|
+
}
|
|
22472
|
+
}
|
|
22473
|
+
refs.composeSections.addEventListener("change", () => {
|
|
22474
|
+
if (refs.composeTemplate) {
|
|
22475
|
+
refs.composeTemplate.value = "custom";
|
|
22476
|
+
writeMacroSetting("template", "custom");
|
|
22477
|
+
}
|
|
22478
|
+
writeMacroSections(selectedComposeSections());
|
|
22479
|
+
updateComposeSectionsLen();
|
|
22480
|
+
});
|
|
22481
|
+
const composeTemplate = refs.composeTemplate;
|
|
22482
|
+
if (composeTemplate) {
|
|
22483
|
+
composeTemplate.addEventListener("change", () => {
|
|
22484
|
+
writeMacroSetting("template", composeTemplate.value);
|
|
22485
|
+
const tmplName = selectedComposeTemplate();
|
|
22486
|
+
if (tmplName) {
|
|
22487
|
+
const tmpl = STRUCTURE_TEMPLATES.find((t) => t.name === tmplName);
|
|
22488
|
+
if (tmpl) {
|
|
22489
|
+
const planSet = new Set(tmpl.plan);
|
|
22490
|
+
const boxes = refs.composeSections.querySelectorAll(
|
|
22491
|
+
'input[type="checkbox"]'
|
|
22492
|
+
);
|
|
22493
|
+
for (const box of boxes) {
|
|
22494
|
+
box.checked = planSet.has(box.value);
|
|
22495
|
+
}
|
|
22496
|
+
}
|
|
22497
|
+
}
|
|
22498
|
+
writeMacroSections(selectedComposeSections());
|
|
22499
|
+
updateComposeSectionsLen();
|
|
22500
|
+
});
|
|
22501
|
+
}
|
|
21953
22502
|
updateComposeSectionsLen();
|
|
21954
22503
|
const updateComposeKeyHint = () => {
|
|
21955
22504
|
if (!refs.composeKey || !refs.composeKeyHint) return;
|
|
@@ -21957,17 +22506,33 @@ var mountDAW = (target, options = {}) => {
|
|
|
21957
22506
|
refs.composeKeyHint.textContent = desc;
|
|
21958
22507
|
refs.composeKeyHint.title = desc;
|
|
21959
22508
|
};
|
|
21960
|
-
|
|
21961
|
-
|
|
22509
|
+
const composeKey = refs.composeKey;
|
|
22510
|
+
if (composeKey) {
|
|
22511
|
+
composeKey.addEventListener("change", () => {
|
|
22512
|
+
writeMacroSetting("key", composeKey.value);
|
|
22513
|
+
updateComposeKeyHint();
|
|
22514
|
+
});
|
|
21962
22515
|
updateComposeKeyHint();
|
|
21963
22516
|
}
|
|
22517
|
+
if (refs.shiftSelect) {
|
|
22518
|
+
refs.shiftSelect.addEventListener("change", () => {
|
|
22519
|
+
writeMacroSetting("shift", refs.shiftSelect.value);
|
|
22520
|
+
});
|
|
22521
|
+
}
|
|
22522
|
+
if (refs.transposeSelect) {
|
|
22523
|
+
refs.transposeSelect.addEventListener("change", () => {
|
|
22524
|
+
writeMacroSetting("transpose", refs.transposeSelect.value);
|
|
22525
|
+
});
|
|
22526
|
+
}
|
|
21964
22527
|
const runCompose = (withVocal) => {
|
|
21965
22528
|
stop();
|
|
21966
22529
|
overlayDuring(() => {
|
|
22530
|
+
const tmpl = selectedComposeTemplate();
|
|
21967
22531
|
const song = composeSong({
|
|
21968
22532
|
stepsPerBar: renderConfig.stepsPerBar,
|
|
21969
22533
|
edo: renderConfig.edo,
|
|
21970
22534
|
sections: selectedComposeSections(),
|
|
22535
|
+
template: tmpl,
|
|
21971
22536
|
baseKey: refs.composeKey?.value ?? "any",
|
|
21972
22537
|
// 直近に作った曲の特徴を渡すと、それらから離れた候補に加点される。
|
|
21973
22538
|
// 「作曲」を続けて押したときに似た曲が並ぶのを防ぐ。
|
|
@@ -22006,7 +22571,19 @@ var mountDAW = (target, options = {}) => {
|
|
|
22006
22571
|
for (const layer of ADVANCED_COMPOSE_LAYOUT) {
|
|
22007
22572
|
const track = trackStates[layer.index];
|
|
22008
22573
|
if (!track) continue;
|
|
22009
|
-
const notes = layer.part === "melody" ? song.melody : layer.part === "submelody" ? song.submelody : layer.part === "bass" ? song.bass : buildChordPlacements({
|
|
22574
|
+
const notes = layer.part === "melody" ? song.melody : layer.part === "harmony" ? song.harmony : layer.part === "submelody" ? song.submelody : layer.part === "bass" ? song.bass : layer.part === "pad" ? song.pad : layer.part === "uwamono" ? buildChordPlacements({
|
|
22575
|
+
edo: renderConfig.edo,
|
|
22576
|
+
chordStr: song.chordProgression,
|
|
22577
|
+
patternType: "arpeggio",
|
|
22578
|
+
rootShift: song.rootShift,
|
|
22579
|
+
bpm: song.bpm,
|
|
22580
|
+
stepsPerBar: renderConfig.stepsPerBar
|
|
22581
|
+
}).map((p) => ({
|
|
22582
|
+
startStep: p.startStep,
|
|
22583
|
+
pitchUnits: p.pitchUnits,
|
|
22584
|
+
durationSteps: p.durationSteps,
|
|
22585
|
+
velocity: Math.max(30, p.velocity - 14)
|
|
22586
|
+
})) : buildChordPlacements({
|
|
22010
22587
|
edo: renderConfig.edo,
|
|
22011
22588
|
chordStr: song.chordProgression,
|
|
22012
22589
|
patternType: layer.part,
|
|
@@ -22045,9 +22622,11 @@ var mountDAW = (target, options = {}) => {
|
|
|
22045
22622
|
refs.drumSelect.value = song.drum;
|
|
22046
22623
|
options.onDrumChange?.(song.drum);
|
|
22047
22624
|
applyDrumPatternFont(song.drum);
|
|
22048
|
-
|
|
22049
|
-
|
|
22050
|
-
|
|
22625
|
+
const shouldAutoInstrument = !currentInstrument || currentInstrument === "auto" || currentInstrument === autoComposeInstrument;
|
|
22626
|
+
if (shouldAutoInstrument && song.instrument) {
|
|
22627
|
+
currentInstrument = song.instrument;
|
|
22628
|
+
autoComposeInstrument = song.instrument;
|
|
22629
|
+
options.onInstrumentChange?.(song.instrument);
|
|
22051
22630
|
}
|
|
22052
22631
|
if (withVocal) {
|
|
22053
22632
|
const melodyTrack = isAdvanced ? trackStates[0] : trackStates.find((t) => t.config.id === "melody");
|
|
@@ -22063,6 +22642,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
22063
22642
|
fireLyricsChange(melodyTrack);
|
|
22064
22643
|
}
|
|
22065
22644
|
}
|
|
22645
|
+
applyAutoMastering();
|
|
22066
22646
|
if (refs.composeKeyHint) {
|
|
22067
22647
|
refs.composeKeyHint.textContent = `${song.keyLabel} \u3067\u4F5C\u6210`;
|
|
22068
22648
|
refs.composeKeyHint.title = `${song.keyLabel}${song.moodLabel ? `\uFF08${song.moodLabel}\uFF09` : ""}`;
|
|
@@ -23234,6 +23814,49 @@ var mountDAW = (target, options = {}) => {
|
|
|
23234
23814
|
};
|
|
23235
23815
|
};
|
|
23236
23816
|
|
|
23817
|
+
// src/global-state.ts
|
|
23818
|
+
var GLOBAL_STORAGE_KEYS = {
|
|
23819
|
+
edo: "dtm-global:edo",
|
|
23820
|
+
loop: "dtm-global:loop",
|
|
23821
|
+
masterVolume: "dtm-global:master-volume",
|
|
23822
|
+
masterComp: "dtm-global:master-comp",
|
|
23823
|
+
reverbAmount: "dtm-global:reverb-amount",
|
|
23824
|
+
reverbDecay: "dtm-global:reverb-decay",
|
|
23825
|
+
reverbPreDelay: "dtm-global:reverb-predelay",
|
|
23826
|
+
delayAmount: "dtm-global:delay-amount",
|
|
23827
|
+
delayDivision: "dtm-global:delay-division",
|
|
23828
|
+
fadeIn: "dtm-global:fade-in",
|
|
23829
|
+
fadeOut: "dtm-global:fade-out"
|
|
23830
|
+
};
|
|
23831
|
+
var readGlobalSetting = (key) => {
|
|
23832
|
+
try {
|
|
23833
|
+
if (typeof localStorage === "undefined" || !localStorage) return null;
|
|
23834
|
+
return localStorage.getItem(GLOBAL_STORAGE_KEYS[key]);
|
|
23835
|
+
} catch (_) {
|
|
23836
|
+
return null;
|
|
23837
|
+
}
|
|
23838
|
+
};
|
|
23839
|
+
var writeGlobalSetting = (key, value) => {
|
|
23840
|
+
try {
|
|
23841
|
+
if (typeof localStorage === "undefined" || !localStorage) return;
|
|
23842
|
+
localStorage.setItem(GLOBAL_STORAGE_KEYS[key], value);
|
|
23843
|
+
} catch (_) {
|
|
23844
|
+
}
|
|
23845
|
+
};
|
|
23846
|
+
var readGlobalNumber = (key, min, max) => {
|
|
23847
|
+
const raw = readGlobalSetting(key);
|
|
23848
|
+
if (raw === null) return null;
|
|
23849
|
+
const n = Number.parseFloat(raw);
|
|
23850
|
+
if (Number.isNaN(n)) return null;
|
|
23851
|
+
return Math.max(min, Math.min(max, n));
|
|
23852
|
+
};
|
|
23853
|
+
var readGlobalBool = (key) => {
|
|
23854
|
+
const raw = readGlobalSetting(key);
|
|
23855
|
+
if (raw === "1" || raw === "true") return true;
|
|
23856
|
+
if (raw === "0" || raw === "false") return false;
|
|
23857
|
+
return null;
|
|
23858
|
+
};
|
|
23859
|
+
|
|
23237
23860
|
// src/headless-singing-player.ts
|
|
23238
23861
|
var STEPS_PER_BEAT4 = 48;
|
|
23239
23862
|
var STEPS_PER_BAR3 = 192;
|
|
@@ -24318,6 +24941,8 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24318
24941
|
if (fadeOutStartAt !== void 0 && fadeOutEndAt !== void 0) {
|
|
24319
24942
|
fadeGain.gain.setValueAtTime(1, fadeOutStartAt);
|
|
24320
24943
|
fadeGain.gain.linearRampToValueAtTime(0, fadeOutEndAt);
|
|
24944
|
+
fadeGain.gain.setValueAtTime(0, fadeOutEndAt + 2);
|
|
24945
|
+
fadeGain.gain.setValueAtTime(1, fadeOutEndAt + 2);
|
|
24321
24946
|
}
|
|
24322
24947
|
};
|
|
24323
24948
|
const clipMeter = createClipMeter(audioCtx, glueMakeup);
|
|
@@ -24589,8 +25214,15 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24589
25214
|
await listReady;
|
|
24590
25215
|
nameToKey = await buildNameToKeyMapping();
|
|
24591
25216
|
await Promise.all([drumReady, loadPreset(defaultPreset)]);
|
|
25217
|
+
const restoreFadeGainIfMuted = () => {
|
|
25218
|
+
if (fadeGain.gain.value < 1) {
|
|
25219
|
+
fadeGain.gain.cancelScheduledValues(audioCtx.currentTime);
|
|
25220
|
+
fadeGain.gain.setValueAtTime(1, audioCtx.currentTime);
|
|
25221
|
+
}
|
|
25222
|
+
};
|
|
24592
25223
|
const playDrum = (e) => {
|
|
24593
25224
|
if (!sfDrum.font) return;
|
|
25225
|
+
if (e.when === 0) restoreFadeGainIfMuted();
|
|
24594
25226
|
if (KICK_PITCHES.has(e.pitch)) duckBassForKick(e.when);
|
|
24595
25227
|
sfDrum.play({
|
|
24596
25228
|
ctx: audioCtx,
|
|
@@ -24634,6 +25266,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24634
25266
|
}
|
|
24635
25267
|
}
|
|
24636
25268
|
const playNote4 = (e) => {
|
|
25269
|
+
if (e.when === 0) restoreFadeGainIfMuted();
|
|
24637
25270
|
const { trackIdx, role } = resolveTrackIdxAndRole(e.trackId);
|
|
24638
25271
|
const overrideKey = trackIdx >= 0 ? trackInstOverrides.get(trackIdx) : void 0;
|
|
24639
25272
|
let sfInst;
|
|
@@ -24659,12 +25292,26 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24659
25292
|
duration: e.duration
|
|
24660
25293
|
});
|
|
24661
25294
|
};
|
|
25295
|
+
let daw;
|
|
24662
25296
|
let presetSelect = null;
|
|
24663
25297
|
const handleInstrumentChange = (key) => {
|
|
24664
25298
|
editorPreset = key;
|
|
24665
25299
|
if (presetSelect) {
|
|
24666
25300
|
presetSelect.setValue(key);
|
|
24667
25301
|
}
|
|
25302
|
+
if (INSTRUMENT_PRESETS[key]) {
|
|
25303
|
+
const wasPlaying = daw?.getPlaybackState() === "playing";
|
|
25304
|
+
if (wasPlaying) daw.pause();
|
|
25305
|
+
daw?.setLoading?.(true);
|
|
25306
|
+
void loadPreset(
|
|
25307
|
+
key,
|
|
25308
|
+
trackIds,
|
|
25309
|
+
isAdvancedMode ? "advanced" : "simple"
|
|
25310
|
+
).finally(() => {
|
|
25311
|
+
daw?.setLoading?.(false);
|
|
25312
|
+
if (wasPlaying) daw?.play();
|
|
25313
|
+
});
|
|
25314
|
+
}
|
|
24668
25315
|
onInstrumentChange?.(key);
|
|
24669
25316
|
};
|
|
24670
25317
|
const handleTrackInstrumentChange = async (trackIndex, instrumentName) => {
|
|
@@ -24678,7 +25325,6 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24678
25325
|
trackInstOverrides.set(trackIndex, key);
|
|
24679
25326
|
await loadInstrument(key);
|
|
24680
25327
|
};
|
|
24681
|
-
let daw;
|
|
24682
25328
|
const base = {
|
|
24683
25329
|
getAudioTime: () => audioCtx.currentTime,
|
|
24684
25330
|
onResumeAudio: async () => {
|
|
@@ -25429,6 +26075,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
25429
26075
|
EDO31_NAMES,
|
|
25430
26076
|
FADE_IN_MARK,
|
|
25431
26077
|
FADE_OUT_MARK,
|
|
26078
|
+
GLOBAL_STORAGE_KEYS,
|
|
25432
26079
|
GM_INSTRUMENT_NAMES,
|
|
25433
26080
|
INSTRUMENT_PRESETS,
|
|
25434
26081
|
KEY_COUNT,
|
|
@@ -25437,6 +26084,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
25437
26084
|
KOE_VOICEBANK_LABELS,
|
|
25438
26085
|
KOE_VOICEBANK_TERMS,
|
|
25439
26086
|
LinkedList,
|
|
26087
|
+
MACRO_STORAGE_KEYS,
|
|
25440
26088
|
MAJOR_KEY_IDS,
|
|
25441
26089
|
MAX_VOCAL_VOLUME,
|
|
25442
26090
|
MICRO_STEP,
|
|
@@ -25539,6 +26187,11 @@ var createDtmStudio = async (options = {}) => {
|
|
|
25539
26187
|
playNote,
|
|
25540
26188
|
playPlacements,
|
|
25541
26189
|
playSingingMML,
|
|
26190
|
+
readGlobalBool,
|
|
26191
|
+
readGlobalNumber,
|
|
26192
|
+
readGlobalSetting,
|
|
26193
|
+
readMacroSections,
|
|
26194
|
+
readMacroSetting,
|
|
25542
26195
|
resolveComposeKey,
|
|
25543
26196
|
resolveDrumPattern,
|
|
25544
26197
|
resolveLoopPoint,
|
|
@@ -25561,5 +26214,8 @@ var createDtmStudio = async (options = {}) => {
|
|
|
25561
26214
|
unitsToMidi,
|
|
25562
26215
|
unitsToMidiDetune,
|
|
25563
26216
|
unitsToPitchV1,
|
|
25564
|
-
vocalVolumeToGain
|
|
26217
|
+
vocalVolumeToGain,
|
|
26218
|
+
writeGlobalSetting,
|
|
26219
|
+
writeMacroSections,
|
|
26220
|
+
writeMacroSetting
|
|
25565
26221
|
});
|