@onjmin/dtm 2.1.4 → 2.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/dist/index.d.mts +85 -9
- package/dist/index.d.ts +85 -9
- package/dist/index.js +753 -128
- package/dist/index.mjs +747 -127
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4728,6 +4728,7 @@ var createSequencer = (options) => {
|
|
|
4728
4728
|
let drumCursor = 0;
|
|
4729
4729
|
let lastDrumStep = Number.NEGATIVE_INFINITY;
|
|
4730
4730
|
let lastPlayStep = 0;
|
|
4731
|
+
let maxTimelineEndSec = 0;
|
|
4731
4732
|
const secondsPerStep = () => 60 / options.getBpm() / STEPS_PER_BEAT;
|
|
4732
4733
|
const getWrappedPlayStep = (time, sps) => {
|
|
4733
4734
|
if (!isLooping || loopDurationSec <= 0 || time < loopEndSec) {
|
|
@@ -4754,6 +4755,7 @@ var createSequencer = (options) => {
|
|
|
4754
4755
|
}
|
|
4755
4756
|
const startLimit = isLooping ? Math.min(fromStep, loopStartStep) : fromStep;
|
|
4756
4757
|
let maxEndStep = 0;
|
|
4758
|
+
maxTimelineEndSec = 0;
|
|
4757
4759
|
for (const track of options.getTracks()) {
|
|
4758
4760
|
trackVolumeMap.set(track.id, track.volume);
|
|
4759
4761
|
for (const note of track.notes) {
|
|
@@ -4762,6 +4764,7 @@ var createSequencer = (options) => {
|
|
|
4762
4764
|
const when = relativeStart * sps;
|
|
4763
4765
|
const duration = note.durationSteps * sps;
|
|
4764
4766
|
maxEndStep = Math.max(maxEndStep, note.startStep + note.durationSteps);
|
|
4767
|
+
maxTimelineEndSec = Math.max(maxTimelineEndSec, when + duration);
|
|
4765
4768
|
timeline.push({
|
|
4766
4769
|
trackId: track.id,
|
|
4767
4770
|
pitch: note.pitchUnits,
|
|
@@ -4887,10 +4890,7 @@ var createSequencer = (options) => {
|
|
|
4887
4890
|
lastPlayStep = currentStep2;
|
|
4888
4891
|
}
|
|
4889
4892
|
if (!isLooping) {
|
|
4890
|
-
|
|
4891
|
-
const lastWhen = last?.when ?? 0;
|
|
4892
|
-
const lastDuration = last?.duration ?? 0;
|
|
4893
|
-
if (nowIndex >= timeline.length && time > lastWhen + lastDuration + 0.1) {
|
|
4893
|
+
if (nowIndex >= timeline.length && time > maxTimelineEndSec + 0.1) {
|
|
4894
4894
|
stop();
|
|
4895
4895
|
options.onEnd(false);
|
|
4896
4896
|
}
|
|
@@ -8222,6 +8222,21 @@ var DAW_CSS = `
|
|
|
8222
8222
|
.dtm-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
|
8223
8223
|
.dtm-track-body { display: flex; flex-direction: column; gap: 10px; }
|
|
8224
8224
|
|
|
8225
|
+
/* \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 */
|
|
8226
|
+
.dtm-compose-container {
|
|
8227
|
+
background: var(--dtm-deep);
|
|
8228
|
+
border: 2px solid var(--c-black);
|
|
8229
|
+
box-shadow:
|
|
8230
|
+
inset 0 0 0 1px var(--dtm-border2),
|
|
8231
|
+
0 0 0 1px var(--dtm-success),
|
|
8232
|
+
3px 3px 0 var(--c-black);
|
|
8233
|
+
padding: 10px 12px 12px;
|
|
8234
|
+
display: flex;
|
|
8235
|
+
flex-direction: column;
|
|
8236
|
+
gap: 10px;
|
|
8237
|
+
margin-bottom: 6px;
|
|
8238
|
+
}
|
|
8239
|
+
|
|
8225
8240
|
/* \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 */
|
|
8226
8241
|
.dtm-panel--track > summary::before,
|
|
8227
8242
|
.dtm-panel--track[open] > summary::before {
|
|
@@ -13016,11 +13031,25 @@ var densityFeatures = (notes, opts) => {
|
|
|
13016
13031
|
shortNoteRatio: short / notes.length
|
|
13017
13032
|
};
|
|
13018
13033
|
};
|
|
13019
|
-
var tensionFeatures = (barTension) => {
|
|
13020
|
-
if (barTension.length <
|
|
13034
|
+
var tensionFeatures = (barTension, opts) => {
|
|
13035
|
+
if (barTension.length < 8) return { rise: 0, resolve: 0 };
|
|
13021
13036
|
const mean2 = (xs) => xs.reduce((a2, b2) => a2 + b2, 0) / Math.max(1, xs.length);
|
|
13022
|
-
|
|
13023
|
-
|
|
13037
|
+
let a;
|
|
13038
|
+
let b;
|
|
13039
|
+
if (opts?.verseBars && opts?.chorusBars && opts.verseBars.length > 0 && opts.chorusBars.length > 0) {
|
|
13040
|
+
a = mean2(opts.verseBars.map((i2) => barTension[i2] ?? 0));
|
|
13041
|
+
b = mean2(opts.chorusBars.map((i2) => barTension[i2] ?? 0));
|
|
13042
|
+
} else if (barTension.length >= 16 && barTension.length <= 24) {
|
|
13043
|
+
a = mean2(barTension.slice(0, 4));
|
|
13044
|
+
b = mean2(barTension.slice(8, 12));
|
|
13045
|
+
} else {
|
|
13046
|
+
const q1Start = Math.floor(barTension.length * 0.15);
|
|
13047
|
+
const q1End = Math.max(q1Start + 2, Math.floor(barTension.length * 0.35));
|
|
13048
|
+
const q3Start = Math.floor(barTension.length * 0.55);
|
|
13049
|
+
const q3End = Math.max(q3Start + 2, Math.floor(barTension.length * 0.75));
|
|
13050
|
+
a = mean2(barTension.slice(q1Start, q1End));
|
|
13051
|
+
b = mean2(barTension.slice(q3Start, q3End));
|
|
13052
|
+
}
|
|
13024
13053
|
const all = mean2(barTension);
|
|
13025
13054
|
const last = barTension[barTension.length - 1];
|
|
13026
13055
|
const rise = Math.max(0, Math.min(1, (b - a) / 0.5));
|
|
@@ -13067,6 +13096,8 @@ var SECTION_LABELS = {
|
|
|
13067
13096
|
verse: "A\u30E1\u30ED",
|
|
13068
13097
|
prechorus: "B\u30E1\u30ED",
|
|
13069
13098
|
chorus: "\u30B5\u30D3",
|
|
13099
|
+
bridge: "C\u30E1\u30ED",
|
|
13100
|
+
drop_chorus: "\u843D\u3061\u30B5\u30D3",
|
|
13070
13101
|
interlude: "\u9593\u594F",
|
|
13071
13102
|
outro: "\u30A2\u30A6\u30C8\u30ED"
|
|
13072
13103
|
};
|
|
@@ -13075,6 +13106,8 @@ var SECTION_ORDER = [
|
|
|
13075
13106
|
"verse",
|
|
13076
13107
|
"prechorus",
|
|
13077
13108
|
"chorus",
|
|
13109
|
+
"bridge",
|
|
13110
|
+
"drop_chorus",
|
|
13078
13111
|
"interlude",
|
|
13079
13112
|
"outro"
|
|
13080
13113
|
];
|
|
@@ -13126,6 +13159,35 @@ var SECTION_SPECS = {
|
|
|
13126
13159
|
// 主音へ全終止
|
|
13127
13160
|
progression: "b"
|
|
13128
13161
|
},
|
|
13162
|
+
// Cメロ。Verse/Pre chorusとは違うメロディで、ラストのサビ前に緊張感を持たせる。
|
|
13163
|
+
// 2番のサビの後に来ることが多い(参考: ONLIVE Studio blog)。
|
|
13164
|
+
// 専用のコード進行 "c" を持ち、AメロともBメロとも雰囲気が違う。
|
|
13165
|
+
bridge: {
|
|
13166
|
+
bars: 4,
|
|
13167
|
+
melody: true,
|
|
13168
|
+
registerShift: 2,
|
|
13169
|
+
density: 0.9,
|
|
13170
|
+
drumLevel: 1,
|
|
13171
|
+
landing: 1,
|
|
13172
|
+
// 解決しない音で止めてラスサビへ渡す
|
|
13173
|
+
progression: "c"
|
|
13174
|
+
},
|
|
13175
|
+
// 落ちサビ。サビのメロディを伴奏控えめに歌う。J-POPの王道パターン。
|
|
13176
|
+
// density と drumLevel だけ下げ、メロディはサビと同じものを使う。
|
|
13177
|
+
drop_chorus: {
|
|
13178
|
+
bars: 4,
|
|
13179
|
+
melody: true,
|
|
13180
|
+
registerShift: 4,
|
|
13181
|
+
// サビと同じ高さ
|
|
13182
|
+
density: 0.6,
|
|
13183
|
+
// 薄い(ここが「落ち」の実体)
|
|
13184
|
+
drumLevel: 0,
|
|
13185
|
+
// ドラム控えめ
|
|
13186
|
+
landing: 0,
|
|
13187
|
+
// 主音へ全終止
|
|
13188
|
+
progression: "b"
|
|
13189
|
+
// サビと同じ進行
|
|
13190
|
+
},
|
|
13129
13191
|
interlude: {
|
|
13130
13192
|
bars: 4,
|
|
13131
13193
|
melody: false,
|
|
@@ -13145,18 +13207,120 @@ var SECTION_SPECS = {
|
|
|
13145
13207
|
progression: "a"
|
|
13146
13208
|
}
|
|
13147
13209
|
};
|
|
13148
|
-
var
|
|
13149
|
-
|
|
13150
|
-
|
|
13210
|
+
var STRUCTURE_TEMPLATES = [
|
|
13211
|
+
// 1コーラス(現行デフォルト、短い曲・初心者向け)
|
|
13212
|
+
{
|
|
13213
|
+
name: "1chorus",
|
|
13214
|
+
label: "1\u30B3\u30FC\u30E9\u30B9",
|
|
13215
|
+
plan: ["intro", "verse", "prechorus", "chorus"]
|
|
13216
|
+
},
|
|
13217
|
+
// JPOP王道(マリーゴールド型)
|
|
13218
|
+
// イントロ→Aメロ→Aメロ→Bメロ→サビ→Aメロ→Bメロ→サビ→Cメロ→間奏→サビ→アウトロ
|
|
13219
|
+
{
|
|
13220
|
+
name: "jpop_standard",
|
|
13221
|
+
label: "JPOP\u738B\u9053",
|
|
13222
|
+
plan: [
|
|
13223
|
+
"intro",
|
|
13224
|
+
"verse",
|
|
13225
|
+
"verse",
|
|
13226
|
+
"prechorus",
|
|
13227
|
+
"chorus",
|
|
13228
|
+
"verse",
|
|
13229
|
+
"prechorus",
|
|
13230
|
+
"chorus",
|
|
13231
|
+
"bridge",
|
|
13232
|
+
"interlude",
|
|
13233
|
+
"chorus",
|
|
13234
|
+
"outro"
|
|
13235
|
+
]
|
|
13236
|
+
},
|
|
13237
|
+
// 落ちサビ入り(J-POP王道の変形。ラスサビ前に落ちサビ)
|
|
13238
|
+
{
|
|
13239
|
+
name: "jpop_drop",
|
|
13240
|
+
label: "\u843D\u3061\u30B5\u30D3\u5165\u308A",
|
|
13241
|
+
plan: [
|
|
13242
|
+
"intro",
|
|
13243
|
+
"verse",
|
|
13244
|
+
"verse",
|
|
13245
|
+
"prechorus",
|
|
13246
|
+
"chorus",
|
|
13247
|
+
"verse",
|
|
13248
|
+
"prechorus",
|
|
13249
|
+
"chorus",
|
|
13250
|
+
"bridge",
|
|
13251
|
+
"drop_chorus",
|
|
13252
|
+
"chorus",
|
|
13253
|
+
"outro"
|
|
13254
|
+
]
|
|
13255
|
+
},
|
|
13256
|
+
// ボカロ王道(短め高速、Aメロ繰り返しなし)
|
|
13257
|
+
{
|
|
13258
|
+
name: "vocaloid",
|
|
13259
|
+
label: "\u30DC\u30AB\u30ED\u738B\u9053",
|
|
13260
|
+
plan: [
|
|
13261
|
+
"intro",
|
|
13262
|
+
"verse",
|
|
13263
|
+
"prechorus",
|
|
13264
|
+
"chorus",
|
|
13265
|
+
"verse",
|
|
13266
|
+
"prechorus",
|
|
13267
|
+
"chorus",
|
|
13268
|
+
"bridge",
|
|
13269
|
+
"chorus",
|
|
13270
|
+
"outro"
|
|
13271
|
+
]
|
|
13272
|
+
},
|
|
13273
|
+
// Verse-Chorus形式(Bメロなし、洋楽的)
|
|
13274
|
+
{
|
|
13275
|
+
name: "verse_chorus",
|
|
13276
|
+
label: "Verse-Chorus",
|
|
13277
|
+
plan: [
|
|
13278
|
+
"intro",
|
|
13279
|
+
"verse",
|
|
13280
|
+
"chorus",
|
|
13281
|
+
"verse",
|
|
13282
|
+
"chorus",
|
|
13283
|
+
"bridge",
|
|
13284
|
+
"chorus",
|
|
13285
|
+
"outro"
|
|
13286
|
+
]
|
|
13287
|
+
}
|
|
13288
|
+
];
|
|
13289
|
+
var buildSectionPlan = (kinds, templateName) => {
|
|
13290
|
+
let ordered;
|
|
13291
|
+
if (templateName) {
|
|
13292
|
+
const tmpl = STRUCTURE_TEMPLATES.find((t) => t.name === templateName);
|
|
13293
|
+
ordered = tmpl ? tmpl.plan : DEFAULT_SECTIONS;
|
|
13294
|
+
} else {
|
|
13295
|
+
const wanted = kinds.length > 0 ? kinds : DEFAULT_SECTIONS;
|
|
13296
|
+
ordered = SECTION_ORDER.filter((k) => wanted.includes(k));
|
|
13297
|
+
}
|
|
13151
13298
|
const plan = [];
|
|
13152
13299
|
let bar = 0;
|
|
13300
|
+
const seen = /* @__PURE__ */ new Map();
|
|
13153
13301
|
for (const kind of ordered) {
|
|
13154
13302
|
const spec = SECTION_SPECS[kind];
|
|
13155
|
-
|
|
13303
|
+
const count = seen.get(kind) ?? 0;
|
|
13304
|
+
plan.push({
|
|
13305
|
+
kind,
|
|
13306
|
+
startBar: bar,
|
|
13307
|
+
bars: spec.bars,
|
|
13308
|
+
spec,
|
|
13309
|
+
keyShift: 0,
|
|
13310
|
+
restatement: count > 0
|
|
13311
|
+
});
|
|
13312
|
+
seen.set(kind, count + 1);
|
|
13156
13313
|
bar += spec.bars;
|
|
13157
13314
|
}
|
|
13158
13315
|
return plan;
|
|
13159
13316
|
};
|
|
13317
|
+
var sectionAt = (plan, bar) => {
|
|
13318
|
+
for (const section of plan) {
|
|
13319
|
+
if (bar >= section.startBar && bar < section.startBar + section.bars)
|
|
13320
|
+
return section;
|
|
13321
|
+
}
|
|
13322
|
+
return plan[plan.length - 1];
|
|
13323
|
+
};
|
|
13160
13324
|
|
|
13161
13325
|
// src/compose.ts
|
|
13162
13326
|
var STEP_SEMITONES = 2;
|
|
@@ -13442,6 +13606,16 @@ var SECTION_A_PROGRESSIONS = [
|
|
|
13442
13606
|
["Am", "Dm7", "Bb", "E7"]
|
|
13443
13607
|
// bVI からドミナントへ
|
|
13444
13608
|
];
|
|
13609
|
+
var SECTION_C_PROGRESSIONS = [
|
|
13610
|
+
["Am", "Em", "F", "C"],
|
|
13611
|
+
["Dm7", "Em7", "FM7", "G7"],
|
|
13612
|
+
["Am7", "Dm7", "G7", "CM7"],
|
|
13613
|
+
["F", "G", "Am", "G"],
|
|
13614
|
+
["Dm7", "G7", "Em7", "Am"],
|
|
13615
|
+
["FM7", "Em7", "Am7", "Dm7"],
|
|
13616
|
+
["Am", "G", "FM7", "E7"],
|
|
13617
|
+
["C", "Am", "FM7", "G7"]
|
|
13618
|
+
];
|
|
13445
13619
|
var SECTION_B_PROGRESSIONS = [
|
|
13446
13620
|
["F", "G", "Em7", "Am"],
|
|
13447
13621
|
["Dm7", "G7", "CM7", "A7"],
|
|
@@ -13668,10 +13842,9 @@ var HALF_BAR_FIGURES = [
|
|
|
13668
13842
|
[EIGHTH, EIGHTH, EIGHTH, EIGHTH],
|
|
13669
13843
|
// タタタタ
|
|
13670
13844
|
[EIGHTH, EIGHTH, EIGHTH, EIGHTH],
|
|
13671
|
-
[EIGHTH, EIGHTH, EIGHTH, EIGHTH],
|
|
13672
|
-
[EIGHTH, EIGHTH, EIGHTH, EIGHTH],
|
|
13673
13845
|
[QUARTER, EIGHTH, EIGHTH],
|
|
13674
13846
|
// ター・タタ
|
|
13847
|
+
[QUARTER, EIGHTH, EIGHTH],
|
|
13675
13848
|
[EIGHTH, EIGHTH, QUARTER],
|
|
13676
13849
|
// タタ・ター
|
|
13677
13850
|
[DOT_QUARTER, EIGHTH],
|
|
@@ -13679,8 +13852,24 @@ var HALF_BAR_FIGURES = [
|
|
|
13679
13852
|
[DOT_QUARTER, EIGHTH],
|
|
13680
13853
|
[EIGHTH, QUARTER, EIGHTH],
|
|
13681
13854
|
// 頭抜き
|
|
13855
|
+
// 4分音符主体・ロングトーン(J-POPの歌い上げるバラード〜ミドル向け。音数過多を是正)
|
|
13856
|
+
[QUARTER, QUARTER],
|
|
13857
|
+
// ター・ター
|
|
13858
|
+
[QUARTER, QUARTER],
|
|
13682
13859
|
[HALF],
|
|
13683
|
-
//
|
|
13860
|
+
// ターーー
|
|
13861
|
+
[HALF],
|
|
13862
|
+
[-QUARTER, QUARTER],
|
|
13863
|
+
// 休・ター
|
|
13864
|
+
[QUARTER, -QUARTER],
|
|
13865
|
+
// ター・休
|
|
13866
|
+
// 弱起(アウフタクト)パターン:末尾から次へ飛び込む言い回し
|
|
13867
|
+
[-DOT_QUARTER, EIGHTH],
|
|
13868
|
+
// 3拍半休みからの裏拍アウフタクト
|
|
13869
|
+
[-QUARTER, EIGHTH, EIGHTH],
|
|
13870
|
+
// 2拍目裏からのアウフタクト(タタ)
|
|
13871
|
+
[QUARTER, -EIGHTH, EIGHTH],
|
|
13872
|
+
// ター・休タ(8分裏弱起)
|
|
13684
13873
|
// 付点8分+16分(タッカ)。歌モノで非常に多用される跳ね・推進力の型。
|
|
13685
13874
|
[DOT_EIGHTH, SIXTEENTH, EIGHTH, EIGHTH],
|
|
13686
13875
|
[EIGHTH, EIGHTH, DOT_EIGHTH, SIXTEENTH],
|
|
@@ -14349,7 +14538,10 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14349
14538
|
};
|
|
14350
14539
|
const quarterSteps = scaleStep(QUARTER);
|
|
14351
14540
|
const strongStep = Math.max(1, Math.round(stepsPerBar / 2));
|
|
14352
|
-
const sectionPlan = buildSectionPlan(
|
|
14541
|
+
const sectionPlan = buildSectionPlan(
|
|
14542
|
+
options.sections ?? DEFAULT_SECTIONS,
|
|
14543
|
+
options.template
|
|
14544
|
+
);
|
|
14353
14545
|
const totalBars = sectionPlan.reduce((sum, s) => sum + s.bars, 0);
|
|
14354
14546
|
if (rnd() < 0.35) {
|
|
14355
14547
|
const modType = pick(
|
|
@@ -14386,12 +14578,18 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14386
14578
|
(p) => p.join("|") !== progA.join("|")
|
|
14387
14579
|
);
|
|
14388
14580
|
const progB = pick(progBPool, rnd);
|
|
14581
|
+
const progC = pick(
|
|
14582
|
+
SECTION_C_PROGRESSIONS.filter(
|
|
14583
|
+
(p) => p.join("|") !== progA.join("|") && p.join("|") !== progB.join("|")
|
|
14584
|
+
),
|
|
14585
|
+
rnd
|
|
14586
|
+
);
|
|
14389
14587
|
const tonic = progA[0].startsWith("Am") ? "Am" : "C";
|
|
14390
14588
|
const progHalf = pick(SECTION_A2_DERIVATIONS, rnd)(progA);
|
|
14391
14589
|
const progFull = pick(SECTION_A3_DERIVATIONS, rnd)(progA, tonic);
|
|
14392
14590
|
const progression = [];
|
|
14393
14591
|
for (const section of sectionPlan) {
|
|
14394
|
-
const base = section.spec.progression === "b" ? progB : progA;
|
|
14592
|
+
const base = section.spec.progression === "c" ? progC : section.spec.progression === "b" ? progB : progA;
|
|
14395
14593
|
for (let i2 = 0; i2 < section.bars; i2 += 4) {
|
|
14396
14594
|
const isLastPhrase = i2 + 4 >= section.bars;
|
|
14397
14595
|
if (!isLastPhrase) {
|
|
@@ -14409,7 +14607,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14409
14607
|
const chordPattern = pick(CHORD_PATTERNS, rnd);
|
|
14410
14608
|
const rootShift = resolvedKey.rootShift;
|
|
14411
14609
|
const bpm = pick(BPM_CHOICES, rnd);
|
|
14412
|
-
const sourceOf = (kind) => kind === "chorus" || kind === "interlude" ? "b" : kind === "prechorus" ? "a2" : "a";
|
|
14610
|
+
const sourceOf = (kind) => kind === "chorus" || kind === "interlude" || kind === "drop_chorus" ? "b" : kind === "prechorus" ? "a2" : kind === "bridge" ? "c" : "a";
|
|
14413
14611
|
const units2 = [];
|
|
14414
14612
|
for (const section of sectionPlan) {
|
|
14415
14613
|
const unitCount = Math.max(1, Math.round(section.bars / 2));
|
|
@@ -14446,6 +14644,19 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14446
14644
|
const barInUnit = (bar) => bar % 2;
|
|
14447
14645
|
const unitOf = (bar) => Math.floor(bar / 2);
|
|
14448
14646
|
const restatementOf = (bar) => {
|
|
14647
|
+
const curSec = sectionAt(sectionPlan, bar);
|
|
14648
|
+
if (!curSec.spec.melody) return null;
|
|
14649
|
+
if (curSec.restatement) {
|
|
14650
|
+
const firstSec = sectionPlan.find(
|
|
14651
|
+
(s) => s.kind === curSec.kind && !s.restatement
|
|
14652
|
+
);
|
|
14653
|
+
if (firstSec) {
|
|
14654
|
+
const offset = bar - curSec.startBar;
|
|
14655
|
+
if (offset < firstSec.bars) {
|
|
14656
|
+
return firstSec.startBar + offset;
|
|
14657
|
+
}
|
|
14658
|
+
}
|
|
14659
|
+
}
|
|
14449
14660
|
const u = unitOf(bar);
|
|
14450
14661
|
if (units2[u].source === "silent") return null;
|
|
14451
14662
|
for (let v = 0; v < u; v++) {
|
|
@@ -14475,10 +14686,9 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14475
14686
|
),
|
|
14476
14687
|
// 人間の曲の跳躍率は p25〜p75 で 0.40〜0.55。上限が低いとその帯へ届かない。
|
|
14477
14688
|
leapAffinity: 0.08 + rnd() * 0.3,
|
|
14478
|
-
//
|
|
14479
|
-
|
|
14480
|
-
|
|
14481
|
-
barHeadWeight: rnd() < 0.65 ? 3 : 2,
|
|
14689
|
+
// 界隈曲らしさ:調の外の音(クロマチック)や微小な逸脱を積極的に許容する。
|
|
14690
|
+
chromaticAffinity: rnd() < 0.1 ? 0 : 0.3 + rnd() * 0.6,
|
|
14691
|
+
barHeadWeight: rnd() < 0.5 ? 3 : 2,
|
|
14482
14692
|
bassStyle: pick(
|
|
14483
14693
|
[
|
|
14484
14694
|
"quarter",
|
|
@@ -14504,7 +14714,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14504
14714
|
subInterval: pick([3, 4, 8, 9], rnd)
|
|
14505
14715
|
};
|
|
14506
14716
|
const motifPool = groovyCells(MOTIF_CELLS, style.groove, rnd);
|
|
14507
|
-
const targetNotesPerBar =
|
|
14717
|
+
const targetNotesPerBar = 4 + rnd() * 4;
|
|
14508
14718
|
const targetRestRatio = 0.02 + rnd() * 0.1;
|
|
14509
14719
|
const cellNotes = (c) => c.value.filter((v) => v > 0).length;
|
|
14510
14720
|
const cellRest = (c) => {
|
|
@@ -14516,27 +14726,49 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14516
14726
|
}
|
|
14517
14727
|
return total === 0 ? 0 : rest / total;
|
|
14518
14728
|
};
|
|
14519
|
-
const cellDistance = (c) => Math.abs(cellNotes(c) - targetNotesPerBar) + Math.abs(cellRest(c) - targetRestRatio) * 8;
|
|
14520
|
-
const pickCell = (pool) => {
|
|
14729
|
+
const cellDistance = (c, densityMul = 1) => Math.abs(cellNotes(c) - targetNotesPerBar * densityMul) + Math.abs(cellRest(c) - targetRestRatio / Math.max(0.5, densityMul)) * 8;
|
|
14730
|
+
const pickCell = (pool, densityMul = 1) => {
|
|
14521
14731
|
let best = pick(pool, rnd);
|
|
14522
14732
|
for (let i2 = 0; i2 < 2; i2++) {
|
|
14523
14733
|
const c = pick(pool, rnd);
|
|
14524
|
-
if (cellDistance(c) < cellDistance(best))
|
|
14734
|
+
if (cellDistance(c, densityMul) < cellDistance(best, densityMul))
|
|
14735
|
+
best = c;
|
|
14525
14736
|
}
|
|
14526
14737
|
return best;
|
|
14527
14738
|
};
|
|
14528
|
-
const motifCell = pickCell(motifPool);
|
|
14529
|
-
const motifCell2 = rnd() < 0.45 ? motifCell : pickCell(
|
|
14739
|
+
const motifCell = pickCell(motifPool, 0.85);
|
|
14740
|
+
const motifCell2 = rnd() < 0.45 ? motifCell : pickCell(
|
|
14741
|
+
motifPool.filter((c) => c !== motifCell),
|
|
14742
|
+
0.85
|
|
14743
|
+
);
|
|
14530
14744
|
const motifB = pickCell(
|
|
14531
|
-
motifPool.filter((c) => c !== motifCell && c !== motifCell2)
|
|
14745
|
+
motifPool.filter((c) => c !== motifCell && c !== motifCell2),
|
|
14746
|
+
1.2
|
|
14747
|
+
);
|
|
14748
|
+
const motifB2 = pickCell(
|
|
14749
|
+
motifPool.filter((c) => c !== motifB),
|
|
14750
|
+
1.2
|
|
14532
14751
|
);
|
|
14533
|
-
const motifB2 = pickCell(motifPool.filter((c) => c !== motifB));
|
|
14534
14752
|
const motifA2 = pickCell(
|
|
14535
14753
|
motifPool.filter(
|
|
14536
14754
|
(c) => c !== motifCell && c !== motifCell2 && c !== motifB
|
|
14537
|
-
)
|
|
14755
|
+
),
|
|
14756
|
+
1.1
|
|
14757
|
+
);
|
|
14758
|
+
const motifA22 = rnd() < 0.45 ? motifA2 : pickCell(
|
|
14759
|
+
motifPool.filter((c) => c !== motifA2),
|
|
14760
|
+
1.1
|
|
14761
|
+
);
|
|
14762
|
+
const motifC = pickCell(
|
|
14763
|
+
motifPool.filter(
|
|
14764
|
+
(c) => c !== motifCell && c !== motifCell2 && c !== motifB && c !== motifA2
|
|
14765
|
+
),
|
|
14766
|
+
0.9
|
|
14767
|
+
);
|
|
14768
|
+
const motifC2 = rnd() < 0.45 ? motifC : pickCell(
|
|
14769
|
+
motifPool.filter((c) => c !== motifC),
|
|
14770
|
+
0.9
|
|
14538
14771
|
);
|
|
14539
|
-
const motifA22 = rnd() < 0.45 ? motifA2 : pickCell(motifPool.filter((c) => c !== motifA2));
|
|
14540
14772
|
const motifVar = pickCell(
|
|
14541
14773
|
motifPool.filter((c) => c !== motifCell && c !== motifCell2)
|
|
14542
14774
|
);
|
|
@@ -14589,12 +14821,13 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14589
14821
|
}
|
|
14590
14822
|
const isB = units2[u].source === "b";
|
|
14591
14823
|
const isA2 = units2[u].source === "a2";
|
|
14824
|
+
const isC = units2[u].source === "c";
|
|
14592
14825
|
const isPrechorusEnd = units2[u].section.kind === "prechorus" && bar === units2[u].section.startBar + units2[u].section.bars - 1;
|
|
14593
14826
|
if (isPrechorusEnd) {
|
|
14594
14827
|
barRhythms.push(scaleCell(buildUpCell.value));
|
|
14595
14828
|
continue;
|
|
14596
14829
|
}
|
|
14597
|
-
const pair = () => isB ? [motifB, motifB2] : isA2 ? [motifA2, motifA22] : [motifCell, motifCell2];
|
|
14830
|
+
const pair = () => isB ? [motifB, motifB2] : isA2 ? [motifA2, motifA22] : isC ? [motifC, motifC2] : [motifCell, motifCell2];
|
|
14598
14831
|
let cell;
|
|
14599
14832
|
if (units2[u].source === "answer") {
|
|
14600
14833
|
const isPeriodEnd = units2[u].landing !== null;
|
|
@@ -14625,6 +14858,8 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14625
14858
|
const melody = [];
|
|
14626
14859
|
const submelody = [];
|
|
14627
14860
|
const bass = [];
|
|
14861
|
+
const harmony = [];
|
|
14862
|
+
const pad = [];
|
|
14628
14863
|
const melodyDurations = [];
|
|
14629
14864
|
const barTension = new Array(totalBars).fill(0);
|
|
14630
14865
|
let restSteps = 0;
|
|
@@ -14671,13 +14906,22 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14671
14906
|
(bar + style.arcPhase) / style.arcPeriod * Math.PI * 2
|
|
14672
14907
|
);
|
|
14673
14908
|
const arcCenter = MELODY_CENTER + arc * style.arcAmp;
|
|
14674
|
-
const
|
|
14675
|
-
|
|
14676
|
-
|
|
14677
|
-
tones,
|
|
14678
|
-
|
|
14679
|
-
|
|
14680
|
-
|
|
14909
|
+
const inUnit = barInUnit(bar);
|
|
14910
|
+
let headSemi;
|
|
14911
|
+
if (inUnit === 1 && bar > 0) {
|
|
14912
|
+
headSemi = nearestChordTone(prevSemi, tones, headWeight, isSectionB).semi;
|
|
14913
|
+
if (Math.abs(headSemi - prevSemi) > 4) {
|
|
14914
|
+
headSemi = nearestChordTone(prevSemi, tones, 1, isSectionB).semi;
|
|
14915
|
+
}
|
|
14916
|
+
} else {
|
|
14917
|
+
const headTarget = prevSemi + (arcCenter - prevSemi) * 0.5;
|
|
14918
|
+
headSemi = nearestChordTone(
|
|
14919
|
+
headTarget,
|
|
14920
|
+
tones,
|
|
14921
|
+
headWeight,
|
|
14922
|
+
isSectionB
|
|
14923
|
+
).semi;
|
|
14924
|
+
}
|
|
14681
14925
|
const contourOffset = barInUnit(bar) === 0 ? 0 : barRhythms[bar - 1].filter((v) => v > 0).length;
|
|
14682
14926
|
const prevRole = bar > 0 ? barRoles[bar - 1] : null;
|
|
14683
14927
|
const repeatShift = role === "motif" && (prevRole === "motif" || prevRole === "sequence" || prevRole === "climax") ? pick([-2, -1, 1, 2], rnd) : 0;
|
|
@@ -14857,6 +15101,48 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14857
15101
|
} else {
|
|
14858
15102
|
pushSub(scaleStep(QUARTER), scaleStep(DOT_HALF), subSemi);
|
|
14859
15103
|
}
|
|
15104
|
+
const barSec = sectionAt(sectionPlan, bar);
|
|
15105
|
+
if (!silent && (barSec.kind === "chorus" || barSec.kind === "drop_chorus")) {
|
|
15106
|
+
for (let i2 = 0; i2 < slots.length; i2++) {
|
|
15107
|
+
const hSemi = pitches[i2] + 3;
|
|
15108
|
+
const hTone = nearestChordTone(hSemi, tones, 2);
|
|
15109
|
+
const hClamped = clampSemi(hTone.semi, MELODY_LOW, MELODY_HIGH);
|
|
15110
|
+
const k = barKeyShift[bar];
|
|
15111
|
+
const fifthShift = k === 0 ? 0 : SEMITONE_TO_FIFTH_SHIFT[(k % 12 + 12) % 12];
|
|
15112
|
+
harmony.push({
|
|
15113
|
+
startStep: barStart + slots[i2].at,
|
|
15114
|
+
pitchUnits: spelledToUnits(
|
|
15115
|
+
hClamped + k,
|
|
15116
|
+
hTone.fifth + fifthShift,
|
|
15117
|
+
edo
|
|
15118
|
+
),
|
|
15119
|
+
durationSteps: slots[i2].value,
|
|
15120
|
+
velocity: slots[i2].at === 0 ? 82 : 76
|
|
15121
|
+
});
|
|
15122
|
+
}
|
|
15123
|
+
}
|
|
15124
|
+
if (barSec.kind === "prechorus" || barSec.kind === "chorus" || barSec.kind === "bridge" || barSec.kind === "drop_chorus") {
|
|
15125
|
+
const padTone = nearestChordTone(
|
|
15126
|
+
MELODY_HIGH + 2,
|
|
15127
|
+
// メロディの上の音域
|
|
15128
|
+
tones,
|
|
15129
|
+
2
|
|
15130
|
+
);
|
|
15131
|
+
const padSemi = clampSemi(padTone.semi, MELODY_HIGH - 4, MELODY_HIGH + 8);
|
|
15132
|
+
const k = barKeyShift[bar];
|
|
15133
|
+
const fifthShift = k === 0 ? 0 : SEMITONE_TO_FIFTH_SHIFT[(k % 12 + 12) % 12];
|
|
15134
|
+
pad.push({
|
|
15135
|
+
startStep: barStart,
|
|
15136
|
+
pitchUnits: spelledToUnits(
|
|
15137
|
+
padSemi + k,
|
|
15138
|
+
padTone.fifth + fifthShift,
|
|
15139
|
+
edo
|
|
15140
|
+
),
|
|
15141
|
+
durationSteps: stepsPerBar,
|
|
15142
|
+
// 小節全体を伸ばす
|
|
15143
|
+
velocity: barSec.kind === "drop_chorus" ? 50 : 62
|
|
15144
|
+
});
|
|
15145
|
+
}
|
|
14860
15146
|
const rootTone = tones[0];
|
|
14861
15147
|
const fifthTone = tones.find((t) => t.weight === 3 && t !== rootTone);
|
|
14862
15148
|
const thirdTone = tones.find((t) => t.weight === 2);
|
|
@@ -14963,6 +15249,69 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14963
15249
|
}
|
|
14964
15250
|
for (const n of barBass) bass.push(n);
|
|
14965
15251
|
}
|
|
15252
|
+
const eighthSteps = scaleStep(EIGHTH);
|
|
15253
|
+
for (let i2 = 0; i2 < melody.length - 1; i2++) {
|
|
15254
|
+
const cur = melody[i2];
|
|
15255
|
+
const nxt = melody[i2 + 1];
|
|
15256
|
+
const curEnd = cur.startStep + cur.durationSteps;
|
|
15257
|
+
const atBarBoundary = curEnd % stepsPerBar === 0 && nxt.startStep === curEnd;
|
|
15258
|
+
if (!atBarBoundary) continue;
|
|
15259
|
+
if (cur.durationSteps > eighthSteps) continue;
|
|
15260
|
+
const barIdx = Math.floor(curEnd / stepsPerBar);
|
|
15261
|
+
if (barIdx >= totalBars) continue;
|
|
15262
|
+
if (i2 + 1 >= melody.length - 1) continue;
|
|
15263
|
+
const curSec = sectionAt(sectionPlan, barIdx - 1);
|
|
15264
|
+
const nextSec = sectionAt(sectionPlan, barIdx);
|
|
15265
|
+
if (!nextSec.spec.melody || curSec !== nextSec) continue;
|
|
15266
|
+
const curSemi = Math.round(cur.pitchUnits / UNITS_PER_SEMITONE);
|
|
15267
|
+
const nxtSemi = Math.round(nxt.pitchUnits / UNITS_PER_SEMITONE);
|
|
15268
|
+
if (Math.abs(nxtSemi - curSemi) > 3) continue;
|
|
15269
|
+
const nextRole = barRoles[barIdx];
|
|
15270
|
+
let tieProb = 0.4;
|
|
15271
|
+
if (nextRole === "motif") tieProb = 0.05;
|
|
15272
|
+
else if (nextRole === "sequence") tieProb = 0.75;
|
|
15273
|
+
else if (nextRole === "climax") tieProb = 0.9;
|
|
15274
|
+
else if (nextRole === "cadence") tieProb = 0.1;
|
|
15275
|
+
if (rnd() < tieProb) {
|
|
15276
|
+
cur.durationSteps += nxt.durationSteps;
|
|
15277
|
+
melody.splice(i2 + 1, 1);
|
|
15278
|
+
if (i2 < melodyDurations.length - 1) {
|
|
15279
|
+
melodyDurations[i2] += melodyDurations[i2 + 1];
|
|
15280
|
+
melodyDurations.splice(i2 + 1, 1);
|
|
15281
|
+
}
|
|
15282
|
+
const hCurIdx = harmony.findIndex((h) => h.startStep === cur.startStep);
|
|
15283
|
+
const hNxtIdx = harmony.findIndex((h) => h.startStep === nxt.startStep);
|
|
15284
|
+
if (hCurIdx >= 0 && hNxtIdx >= 0) {
|
|
15285
|
+
harmony[hCurIdx].durationSteps += harmony[hNxtIdx].durationSteps;
|
|
15286
|
+
harmony.splice(hNxtIdx, 1);
|
|
15287
|
+
}
|
|
15288
|
+
i2--;
|
|
15289
|
+
}
|
|
15290
|
+
}
|
|
15291
|
+
for (let i2 = 0; i2 < melody.length; i2++) {
|
|
15292
|
+
const barIdx = Math.floor(melody[i2].startStep / stepsPerBar);
|
|
15293
|
+
if (barIdx >= totalBars) continue;
|
|
15294
|
+
const role = barRoles[barIdx];
|
|
15295
|
+
let splitProb = 0.15;
|
|
15296
|
+
if (role === "motif" || role === "sequence") splitProb = 0;
|
|
15297
|
+
else if (role === "climax") splitProb = 0.6;
|
|
15298
|
+
else if (role === "cadence") splitProb = 0;
|
|
15299
|
+
if (rnd() < splitProb && melody[i2].durationSteps === quarterSteps) {
|
|
15300
|
+
const half = scaleStep(EIGHTH);
|
|
15301
|
+
const newNote = {
|
|
15302
|
+
...melody[i2],
|
|
15303
|
+
startStep: melody[i2].startStep + half,
|
|
15304
|
+
durationSteps: half
|
|
15305
|
+
};
|
|
15306
|
+
melody[i2].durationSteps = half;
|
|
15307
|
+
melody.splice(i2 + 1, 0, newNote);
|
|
15308
|
+
if (i2 < melodyDurations.length) {
|
|
15309
|
+
melodyDurations[i2] = half;
|
|
15310
|
+
melodyDurations.splice(i2 + 1, 0, half);
|
|
15311
|
+
}
|
|
15312
|
+
i2++;
|
|
15313
|
+
}
|
|
15314
|
+
}
|
|
14966
15315
|
const range = (notes) => {
|
|
14967
15316
|
if (notes.length === 0) return 0;
|
|
14968
15317
|
const us = notes.map((n) => n.pitchUnits);
|
|
@@ -14970,7 +15319,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14970
15319
|
};
|
|
14971
15320
|
const shiftUnits = semitonesToUnits(rootShift, edo);
|
|
14972
15321
|
if (shiftUnits !== 0)
|
|
14973
|
-
for (const list of [melody, submelody, bass])
|
|
15322
|
+
for (const list of [melody, submelody, bass, harmony, pad])
|
|
14974
15323
|
for (const n of list) n.pitchUnits = n.pitchUnits + shiftUnits;
|
|
14975
15324
|
return {
|
|
14976
15325
|
chordProgression,
|
|
@@ -14985,6 +15334,8 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14985
15334
|
melody,
|
|
14986
15335
|
submelody,
|
|
14987
15336
|
bass,
|
|
15337
|
+
harmony,
|
|
15338
|
+
pad,
|
|
14988
15339
|
melodyDurations,
|
|
14989
15340
|
restSteps,
|
|
14990
15341
|
totalSteps: Math.max(1, sungBars) * stepsPerBar,
|
|
@@ -15020,7 +15371,16 @@ var evaluate = (d, recent) => {
|
|
|
15020
15371
|
fromMelody(toMetricNotes(d.submelody)),
|
|
15021
15372
|
opts
|
|
15022
15373
|
);
|
|
15023
|
-
const
|
|
15374
|
+
const verseBars = [];
|
|
15375
|
+
const chorusBars = [];
|
|
15376
|
+
for (const s of d.sections) {
|
|
15377
|
+
for (let b = s.startBar; b < s.startBar + s.bars; b++) {
|
|
15378
|
+
if (s.kind === "verse") verseBars.push(b);
|
|
15379
|
+
else if (s.kind === "chorus" || s.kind === "drop_chorus")
|
|
15380
|
+
chorusBars.push(b);
|
|
15381
|
+
}
|
|
15382
|
+
}
|
|
15383
|
+
const tension = tensionFeatures(d.barTension, { verseBars, chorusBars });
|
|
15024
15384
|
const density = densityFeatures(melodyFrom, opts);
|
|
15025
15385
|
const fingerprint = featureVector({
|
|
15026
15386
|
entropy,
|
|
@@ -15036,6 +15396,7 @@ var evaluate = (d, recent) => {
|
|
|
15036
15396
|
);
|
|
15037
15397
|
const at = (b, v) => band(v, b[0], b[1], b[2], b[3]);
|
|
15038
15398
|
const atc = (key, v) => centeredBand(v, CORPUS_BANDS[key], CORPUS_MEDIANS[key]);
|
|
15399
|
+
const peakBand = d.bars > 24 ? [0, 1, Math.round(d.bars / 16), Math.round(d.bars / 8) + 2] : HAND_BANDS.climaxPeaks;
|
|
15039
15400
|
const scoreBreakdown = {
|
|
15040
15401
|
entropy: atc("entropy", entropy),
|
|
15041
15402
|
valueKinds: atc("valueKinds", valueKinds),
|
|
@@ -15053,7 +15414,7 @@ var evaluate = (d, recent) => {
|
|
|
15053
15414
|
sim8: atc("sim8", structure.sim8),
|
|
15054
15415
|
phraseBreath: atc("phraseBreath", structure.phraseBreath),
|
|
15055
15416
|
climaxPosition: atc("climaxPosition", structure.climaxPosition),
|
|
15056
|
-
climaxPeaks: at(
|
|
15417
|
+
climaxPeaks: at(peakBand, structure.climaxPeaks),
|
|
15057
15418
|
complementarity: at(HAND_BANDS.complementarity, structure.complementarity),
|
|
15058
15419
|
subDensity: at(HAND_BANDS.subDensity, d.submelody.length / d.bars),
|
|
15059
15420
|
tensionRise: tension.rise,
|
|
@@ -15107,9 +15468,10 @@ var composeSong = (options) => {
|
|
|
15107
15468
|
bestScore = stats.score;
|
|
15108
15469
|
bestIsValid = ok;
|
|
15109
15470
|
best = {
|
|
15110
|
-
//
|
|
15471
|
+
// ドラム・楽器は勝った候補にだけ後から付ける(メロディに依存しないので
|
|
15111
15472
|
// 候補ごとに引いても採点は動かず、40本ぶん無駄になる)。
|
|
15112
15473
|
drum: "",
|
|
15474
|
+
instrument: "",
|
|
15113
15475
|
chordProgression: d.chordProgression,
|
|
15114
15476
|
chordPattern: d.chordPattern,
|
|
15115
15477
|
rootShift: d.rootShift,
|
|
@@ -15122,6 +15484,8 @@ var composeSong = (options) => {
|
|
|
15122
15484
|
melody: d.melody,
|
|
15123
15485
|
submelody: d.submelody,
|
|
15124
15486
|
bass: d.bass,
|
|
15487
|
+
harmony: d.harmony,
|
|
15488
|
+
pad: d.pad,
|
|
15125
15489
|
stats: { ...stats, attempts: attempt, rejected }
|
|
15126
15490
|
};
|
|
15127
15491
|
}
|
|
@@ -15129,6 +15493,7 @@ var composeSong = (options) => {
|
|
|
15129
15493
|
result.stats.attempts = count;
|
|
15130
15494
|
result.stats.rejected = rejected;
|
|
15131
15495
|
result.drum = pickBuiltinDrum(result, rnd);
|
|
15496
|
+
result.instrument = pickBuiltinInstrument(result, rnd);
|
|
15132
15497
|
return result;
|
|
15133
15498
|
};
|
|
15134
15499
|
var pickBuiltinDrum = (song, rnd) => {
|
|
@@ -15137,6 +15502,35 @@ var pickBuiltinDrum = (song, rnd) => {
|
|
|
15137
15502
|
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"];
|
|
15138
15503
|
return pick(pool, rnd);
|
|
15139
15504
|
};
|
|
15505
|
+
var pickBuiltinInstrument = (song, rnd) => {
|
|
15506
|
+
const eighth = BASE_STEPS_PER_BAR / 8;
|
|
15507
|
+
const short = song.melody.filter((n) => n.durationSteps <= eighth).length / Math.max(1, song.melody.length);
|
|
15508
|
+
if (rnd() < 0.06) {
|
|
15509
|
+
return pick(["japanese_wa", "arabic_exotic"], rnd);
|
|
15510
|
+
}
|
|
15511
|
+
let pool;
|
|
15512
|
+
if (song.drum === "dance" || song.drum === "disco") {
|
|
15513
|
+
pool = song.bpm >= 150 ? ["cyber_punk", "synth_pop", "retro_game"] : ["synth_pop", "retro_game", "rock", "piano"];
|
|
15514
|
+
} else if (song.drum === "bossa") {
|
|
15515
|
+
pool = ["jazz_night", "acoustic", "piano"];
|
|
15516
|
+
} else if (song.bpm <= 105 && short < 0.4) {
|
|
15517
|
+
pool = ["ambient_cloud", "acoustic", "orchestra", "piano", "fantasy_rpg"];
|
|
15518
|
+
} else if (song.bpm >= 145) {
|
|
15519
|
+
pool = ["rock", "synth_pop", "cyber_punk", "retro_game", "piano"];
|
|
15520
|
+
} else if (song.stats.leapRatio >= 0.45) {
|
|
15521
|
+
pool = ["fantasy_rpg", "orchestra", "acoustic", "piano"];
|
|
15522
|
+
} else {
|
|
15523
|
+
pool = [
|
|
15524
|
+
"piano",
|
|
15525
|
+
"acoustic",
|
|
15526
|
+
"synth_pop",
|
|
15527
|
+
"rock",
|
|
15528
|
+
"jazz_night",
|
|
15529
|
+
"fantasy_rpg"
|
|
15530
|
+
];
|
|
15531
|
+
}
|
|
15532
|
+
return pick(pool, rnd);
|
|
15533
|
+
};
|
|
15140
15534
|
var LYRIC_WORDS = [
|
|
15141
15535
|
"\u3042\u3055",
|
|
15142
15536
|
"\u3072\u304B\u308A",
|
|
@@ -15538,74 +15932,89 @@ var buildUI = (target, options) => {
|
|
|
15538
15932
|
<details class="dtm-panel" data-dtm-acc="macro">
|
|
15539
15933
|
<summary>\u30DE\u30AF\u30ED</summary>
|
|
15540
15934
|
<div class="dtm-panel-body">
|
|
15541
|
-
<div class="dtm-
|
|
15542
|
-
<
|
|
15543
|
-
|
|
15544
|
-
|
|
15545
|
-
|
|
15546
|
-
|
|
15547
|
-
|
|
15548
|
-
<
|
|
15549
|
-
|
|
15550
|
-
<
|
|
15551
|
-
|
|
15552
|
-
|
|
15553
|
-
|
|
15554
|
-
|
|
15555
|
-
|
|
15935
|
+
<div class="dtm-compose-container ${showCompose ? "" : "dtm-hidden"}" data-dtm="compose-container">
|
|
15936
|
+
<div class="dtm-row" data-dtm="compose-row">
|
|
15937
|
+
<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>
|
|
15938
|
+
<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>
|
|
15939
|
+
<button class="dtm-infobtn" data-dtm="macro-compose-info" title="\u4F5C\u66F2\u306E\u89E3\u8AAC">${icon("info", 12)}</button>
|
|
15940
|
+
<span class="dtm-grow"></span>
|
|
15941
|
+
</div>
|
|
15942
|
+
<div class="dtm-row" data-dtm="compose-template-row">
|
|
15943
|
+
<span class="dtm-label">\u69CB\u6210</span>
|
|
15944
|
+
<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">
|
|
15945
|
+
<option value="custom">\u81EA\u7531\u9078\u629E\uFF08\u4E0B\u8A18\u30C1\u30A7\u30C3\u30AF\uFF09</option>
|
|
15946
|
+
<option value="1chorus">1\u30B3\u30FC\u30E9\u30B9\uFF08\u77ED\u3081\u30FB\u521D\u5FC3\u8005\u5411\u3051\uFF09</option>
|
|
15947
|
+
<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>
|
|
15948
|
+
<option value="jpop_drop">\u843D\u3061\u30B5\u30D3\u5165\u308A\uFF08JPOP\u738B\u9053 + \u30E9\u30B9\u30B5\u30D3\u524D\u843D\u3061\u30B5\u30D3\uFF09</option>
|
|
15949
|
+
<option value="vocaloid">\u30DC\u30AB\u30ED\u738B\u9053\uFF08\u75BE\u8D70\u30FB2\u756A/C\u30E1\u30ED/\u30E9\u30B9\u30B5\u30D3\uFF09</option>
|
|
15950
|
+
<option value="verse_chorus">Verse-Chorus\uFF08B\u30E1\u30ED\u306A\u3057\u30FB\u6D0B\u697D\u98A8\uFF09</option>
|
|
15951
|
+
</select>
|
|
15952
|
+
</div>
|
|
15953
|
+
<div class="dtm-row" data-dtm="compose-sections-row">
|
|
15954
|
+
<span class="dtm-label">\u4F5C\u308B\u90E8\u5206</span>
|
|
15955
|
+
<div class="dtm-checks" data-dtm="compose-sections">
|
|
15956
|
+
<label class="dtm-check"><input type="checkbox" value="intro" checked>\u30A4\u30F3\u30C8\u30ED</label>
|
|
15957
|
+
<label class="dtm-check"><input type="checkbox" value="verse" checked>A\u30E1\u30ED</label>
|
|
15958
|
+
<label class="dtm-check"><input type="checkbox" value="prechorus" checked>B\u30E1\u30ED</label>
|
|
15959
|
+
<label class="dtm-check"><input type="checkbox" value="chorus" checked>\u30B5\u30D3</label>
|
|
15960
|
+
<label class="dtm-check"><input type="checkbox" value="bridge">C\u30E1\u30ED</label>
|
|
15961
|
+
<label class="dtm-check"><input type="checkbox" value="drop_chorus">\u843D\u3061\u30B5\u30D3</label>
|
|
15962
|
+
<label class="dtm-check"><input type="checkbox" value="interlude">\u9593\u594F</label>
|
|
15963
|
+
<label class="dtm-check"><input type="checkbox" value="outro">\u30A2\u30A6\u30C8\u30ED</label>
|
|
15964
|
+
</div>
|
|
15965
|
+
<span class="dtm-grow"></span>
|
|
15966
|
+
<span class="dtm-hint" data-dtm="compose-sections-len"></span>
|
|
15967
|
+
</div>
|
|
15968
|
+
<div class="dtm-row" data-dtm="compose-key-row">
|
|
15969
|
+
<span class="dtm-label">\u30D9\u30FC\u30B9\u8ABF</span>
|
|
15970
|
+
<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">
|
|
15971
|
+
<option value="any" title="\u516824\u8ABF\u304B\u3089\u30E9\u30F3\u30C0\u30E0\u306B\u6C7A\u5B9A\u3057\u307E\u3059">\u5E0C\u671B\u306A\u3057</option>
|
|
15972
|
+
<optgroup label="\u57FA\u672C">
|
|
15973
|
+
<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>
|
|
15974
|
+
<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>
|
|
15975
|
+
</optgroup>
|
|
15976
|
+
<optgroup label="\u96F0\u56F2\u6C17\u304B\u3089\u9078\u3076\uFF08\u62BD\u9078\uFF09">
|
|
15977
|
+
<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>
|
|
15978
|
+
<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>
|
|
15979
|
+
<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>
|
|
15980
|
+
<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>
|
|
15981
|
+
<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>
|
|
15982
|
+
<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>
|
|
15983
|
+
<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>
|
|
15984
|
+
<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>
|
|
15985
|
+
</optgroup>
|
|
15986
|
+
<optgroup label="\u9577\u8ABF\uFF08\u500B\u5225\u6307\u5B9A\uFF09">
|
|
15987
|
+
<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>
|
|
15988
|
+
<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>
|
|
15989
|
+
<option value="key_D" title="\u610F\u6C17\u63DA\u3005\u3068\u3057\u305F\u3001\u52DD\u5229\u306E\u3001\u558A\u58F0">\u30CB\u9577\u8ABF (D)</option>
|
|
15990
|
+
<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>
|
|
15991
|
+
<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>
|
|
15992
|
+
<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>
|
|
15993
|
+
<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>
|
|
15994
|
+
<option value="key_G" title="\u53B3\u7C9B\u306A\u3001\u5D07\u9AD8\u306A\u3001\u5E7B\u60F3\u3001\u8AA0\u5B9F">\u30C8\u9577\u8ABF (G)</option>
|
|
15995
|
+
<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>
|
|
15996
|
+
<option value="key_A" title="\u3046\u308C\u3057\u3044\u3001\u7267\u6B4C\u7684\u306A\u3001\u611B\u306E\u544A\u767D">\u30A4\u9577\u8ABF (A)</option>
|
|
15997
|
+
<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>
|
|
15998
|
+
<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>
|
|
15999
|
+
</optgroup>
|
|
16000
|
+
<optgroup label="\u77ED\u8ABF\uFF08\u500B\u5225\u6307\u5B9A\uFF09">
|
|
16001
|
+
<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>
|
|
16002
|
+
<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>
|
|
16003
|
+
<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>
|
|
16004
|
+
<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>
|
|
16005
|
+
<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>
|
|
16006
|
+
<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>
|
|
16007
|
+
<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>
|
|
16008
|
+
<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>
|
|
16009
|
+
<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>
|
|
16010
|
+
<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>
|
|
16011
|
+
<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>
|
|
16012
|
+
<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>
|
|
16013
|
+
</optgroup>
|
|
16014
|
+
</select>
|
|
16015
|
+
<span class="dtm-grow"></span>
|
|
16016
|
+
<span class="dtm-hint" data-dtm="compose-key-hint"></span>
|
|
15556
16017
|
</div>
|
|
15557
|
-
<span class="dtm-grow"></span>
|
|
15558
|
-
<span class="dtm-hint" data-dtm="compose-sections-len"></span>
|
|
15559
|
-
</div>
|
|
15560
|
-
<div class="dtm-row ${showCompose ? "" : "dtm-hidden"}" data-dtm="compose-key-row">
|
|
15561
|
-
<span class="dtm-label">\u30D9\u30FC\u30B9\u8ABF</span>
|
|
15562
|
-
<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">
|
|
15563
|
-
<option value="any" title="\u516824\u8ABF\u304B\u3089\u30E9\u30F3\u30C0\u30E0\u306B\u6C7A\u5B9A\u3057\u307E\u3059">\u5E0C\u671B\u306A\u3057</option>
|
|
15564
|
-
<optgroup label="\u57FA\u672C">
|
|
15565
|
-
<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>
|
|
15566
|
-
<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>
|
|
15567
|
-
</optgroup>
|
|
15568
|
-
<optgroup label="\u96F0\u56F2\u6C17\u304B\u3089\u9078\u3076\uFF08\u62BD\u9078\uFF09">
|
|
15569
|
-
<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>
|
|
15570
|
-
<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>
|
|
15571
|
-
<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>
|
|
15572
|
-
<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>
|
|
15573
|
-
<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>
|
|
15574
|
-
<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>
|
|
15575
|
-
<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>
|
|
15576
|
-
<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>
|
|
15577
|
-
</optgroup>
|
|
15578
|
-
<optgroup label="\u9577\u8ABF\uFF08\u500B\u5225\u6307\u5B9A\uFF09">
|
|
15579
|
-
<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>
|
|
15580
|
-
<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>
|
|
15581
|
-
<option value="key_D" title="\u610F\u6C17\u63DA\u3005\u3068\u3057\u305F\u3001\u52DD\u5229\u306E\u3001\u558A\u58F0">\u30CB\u9577\u8ABF (D)</option>
|
|
15582
|
-
<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>
|
|
15583
|
-
<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>
|
|
15584
|
-
<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>
|
|
15585
|
-
<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>
|
|
15586
|
-
<option value="key_G" title="\u53B3\u7C9B\u306A\u3001\u5D07\u9AD8\u306A\u3001\u5E7B\u60F3\u3001\u8AA0\u5B9F">\u30C8\u9577\u8ABF (G)</option>
|
|
15587
|
-
<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>
|
|
15588
|
-
<option value="key_A" title="\u3046\u308C\u3057\u3044\u3001\u7267\u6B4C\u7684\u306A\u3001\u611B\u306E\u544A\u767D">\u30A4\u9577\u8ABF (A)</option>
|
|
15589
|
-
<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>
|
|
15590
|
-
<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>
|
|
15591
|
-
</optgroup>
|
|
15592
|
-
<optgroup label="\u77ED\u8ABF\uFF08\u500B\u5225\u6307\u5B9A\uFF09">
|
|
15593
|
-
<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>
|
|
15594
|
-
<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>
|
|
15595
|
-
<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>
|
|
15596
|
-
<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>
|
|
15597
|
-
<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>
|
|
15598
|
-
<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>
|
|
15599
|
-
<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>
|
|
15600
|
-
<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>
|
|
15601
|
-
<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>
|
|
15602
|
-
<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>
|
|
15603
|
-
<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>
|
|
15604
|
-
<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>
|
|
15605
|
-
</optgroup>
|
|
15606
|
-
</select>
|
|
15607
|
-
<span class="dtm-grow"></span>
|
|
15608
|
-
<span class="dtm-hint" data-dtm="compose-key-hint"></span>
|
|
15609
16018
|
</div>
|
|
15610
16019
|
<div class="dtm-row">
|
|
15611
16020
|
<span class="dtm-label">\u5168\u4F53\u30B7\u30D5\u30C8</span>
|
|
@@ -15803,6 +16212,7 @@ var buildUI = (target, options) => {
|
|
|
15803
16212
|
transposeApplyBtn: sel("transpose-apply"),
|
|
15804
16213
|
transposeInfoBtn: sel("transpose-info"),
|
|
15805
16214
|
macroCompose: sel("macro-compose"),
|
|
16215
|
+
composeTemplate: sel("compose-template"),
|
|
15806
16216
|
composeSections: sel("compose-sections"),
|
|
15807
16217
|
composeSectionsLen: sel("compose-sections-len"),
|
|
15808
16218
|
composeKey: sel("compose-key"),
|
|
@@ -15945,6 +16355,45 @@ var INSTRUMENT_PRESETS = {
|
|
|
15945
16355
|
}
|
|
15946
16356
|
};
|
|
15947
16357
|
|
|
16358
|
+
// src/macro-state.ts
|
|
16359
|
+
var MACRO_STORAGE_KEYS = {
|
|
16360
|
+
template: "dtm-macro:template",
|
|
16361
|
+
sections: "dtm-macro:sections",
|
|
16362
|
+
key: "dtm-macro:key",
|
|
16363
|
+
shift: "dtm-macro:shift",
|
|
16364
|
+
transpose: "dtm-macro:transpose"
|
|
16365
|
+
};
|
|
16366
|
+
var readMacroSetting = (key) => {
|
|
16367
|
+
try {
|
|
16368
|
+
if (typeof localStorage === "undefined" || !localStorage) return null;
|
|
16369
|
+
return localStorage.getItem(MACRO_STORAGE_KEYS[key]);
|
|
16370
|
+
} catch (_) {
|
|
16371
|
+
return null;
|
|
16372
|
+
}
|
|
16373
|
+
};
|
|
16374
|
+
var writeMacroSetting = (key, value) => {
|
|
16375
|
+
try {
|
|
16376
|
+
if (typeof localStorage === "undefined" || !localStorage) return;
|
|
16377
|
+
localStorage.setItem(MACRO_STORAGE_KEYS[key], value);
|
|
16378
|
+
} catch (_) {
|
|
16379
|
+
}
|
|
16380
|
+
};
|
|
16381
|
+
var readMacroSections = () => {
|
|
16382
|
+
const raw = readMacroSetting("sections");
|
|
16383
|
+
if (!raw) return null;
|
|
16384
|
+
try {
|
|
16385
|
+
const parsed = JSON.parse(raw);
|
|
16386
|
+
if (Array.isArray(parsed) && parsed.every((x2) => typeof x2 === "string")) {
|
|
16387
|
+
return parsed;
|
|
16388
|
+
}
|
|
16389
|
+
} catch (_) {
|
|
16390
|
+
}
|
|
16391
|
+
return null;
|
|
16392
|
+
};
|
|
16393
|
+
var writeMacroSections = (sections) => {
|
|
16394
|
+
writeMacroSetting("sections", JSON.stringify(sections));
|
|
16395
|
+
};
|
|
16396
|
+
|
|
15948
16397
|
// src/macros.ts
|
|
15949
16398
|
var SCALES = [
|
|
15950
16399
|
[0, 2, 4, 5, 7, 9, 11],
|
|
@@ -18288,12 +18737,15 @@ var pickComposeVocal = (exclude) => {
|
|
|
18288
18737
|
var ADVANCED_COMPOSE_LAYOUT = [
|
|
18289
18738
|
{ index: 0, part: "melody", octave: 0, volume: 104 },
|
|
18290
18739
|
{ index: 1, part: "melody", octave: 1, volume: 62 },
|
|
18291
|
-
{ index: 2, part: "
|
|
18292
|
-
{ index: 3, part: "
|
|
18293
|
-
{ index: 4, part: "bass", octave:
|
|
18294
|
-
{ index: 5, part: "
|
|
18295
|
-
{ index: 6, part: "
|
|
18296
|
-
{ index: 7, part: "
|
|
18740
|
+
{ index: 2, part: "harmony", octave: 0, volume: 82 },
|
|
18741
|
+
{ index: 3, part: "submelody", octave: 0, volume: 86 },
|
|
18742
|
+
{ index: 4, part: "bass", octave: 0, volume: 92 },
|
|
18743
|
+
{ index: 5, part: "bass", octave: -1, volume: 58 },
|
|
18744
|
+
{ index: 6, part: "pad", octave: 0, volume: 64 },
|
|
18745
|
+
{ index: 7, part: "block", octave: 0, volume: 62 },
|
|
18746
|
+
{ index: 8, part: "arpeggio", octave: 0, volume: 54 },
|
|
18747
|
+
{ index: 9, part: "offbeat", octave: 0, volume: 50 },
|
|
18748
|
+
{ index: 10, part: "uwamono", octave: 1, volume: 56 }
|
|
18297
18749
|
];
|
|
18298
18750
|
var LYRIC_MODEL_CATEGORIES = [
|
|
18299
18751
|
{
|
|
@@ -18583,6 +19035,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
18583
19035
|
options.onDrumFontChange?.(font);
|
|
18584
19036
|
};
|
|
18585
19037
|
let currentInstrument = "";
|
|
19038
|
+
let autoComposeInstrument = null;
|
|
18586
19039
|
let activeTrackId = options.initialActiveTrack ?? trackConfigs[0].id;
|
|
18587
19040
|
let trackFxAdvancedOpen = readPanelOpen("track-fx-advanced") ?? false;
|
|
18588
19041
|
let lyricAdvancedOpen = readPanelOpen("lyric-advanced") ?? false;
|
|
@@ -19620,8 +20073,8 @@ var mountDAW = (target, options = {}) => {
|
|
|
19620
20073
|
redrawAll();
|
|
19621
20074
|
},
|
|
19622
20075
|
onEnd: (interrupted) => {
|
|
19623
|
-
options.onScheduleFade?.(null);
|
|
19624
20076
|
if (interrupted) {
|
|
20077
|
+
options.onScheduleFade?.(null);
|
|
19625
20078
|
playbackState = "paused";
|
|
19626
20079
|
pausedPlayStep = currentPlayStep;
|
|
19627
20080
|
} else {
|
|
@@ -21753,6 +22206,10 @@ var mountDAW = (target, options = {}) => {
|
|
|
21753
22206
|
}
|
|
21754
22207
|
return ADVANCED_COMPOSE_LAYOUT.filter((l) => l.part === "bass").map((l) => trackStates[l.index]).filter((t) => !!t);
|
|
21755
22208
|
};
|
|
22209
|
+
const selectedComposeTemplate = () => {
|
|
22210
|
+
const val = refs.composeTemplate?.value;
|
|
22211
|
+
return val && val !== "custom" ? val : void 0;
|
|
22212
|
+
};
|
|
21756
22213
|
const selectedComposeSections = () => {
|
|
21757
22214
|
const boxes = [
|
|
21758
22215
|
...refs.composeSections.querySelectorAll(
|
|
@@ -21763,11 +22220,97 @@ var mountDAW = (target, options = {}) => {
|
|
|
21763
22220
|
return picked.length > 0 ? picked : DEFAULT_SECTIONS;
|
|
21764
22221
|
};
|
|
21765
22222
|
const updateComposeSectionsLen = () => {
|
|
21766
|
-
const
|
|
22223
|
+
const tmpl = selectedComposeTemplate();
|
|
22224
|
+
const plan = buildSectionPlan(selectedComposeSections(), tmpl);
|
|
21767
22225
|
const bars = plan.reduce((sum, x2) => sum + x2.bars, 0);
|
|
21768
22226
|
refs.composeSectionsLen.textContent = `${bars}\u5C0F\u7BC0`;
|
|
21769
22227
|
};
|
|
21770
|
-
|
|
22228
|
+
const savedTemplate = readMacroSetting("template");
|
|
22229
|
+
if (savedTemplate && refs.composeTemplate) {
|
|
22230
|
+
const hasOption = Array.from(refs.composeTemplate.options).some(
|
|
22231
|
+
(opt) => opt.value === savedTemplate
|
|
22232
|
+
);
|
|
22233
|
+
if (hasOption) {
|
|
22234
|
+
refs.composeTemplate.value = savedTemplate;
|
|
22235
|
+
}
|
|
22236
|
+
}
|
|
22237
|
+
const savedSections = readMacroSections();
|
|
22238
|
+
if (savedSections && refs.composeSections) {
|
|
22239
|
+
const boxes = refs.composeSections.querySelectorAll(
|
|
22240
|
+
'input[type="checkbox"]'
|
|
22241
|
+
);
|
|
22242
|
+
const validValues = new Set(savedSections);
|
|
22243
|
+
for (const box of boxes) {
|
|
22244
|
+
box.checked = validValues.has(box.value);
|
|
22245
|
+
}
|
|
22246
|
+
} else if (savedTemplate && savedTemplate !== "custom" && refs.composeSections) {
|
|
22247
|
+
const tmpl = STRUCTURE_TEMPLATES.find((t) => t.name === savedTemplate);
|
|
22248
|
+
if (tmpl) {
|
|
22249
|
+
const planSet = new Set(tmpl.plan);
|
|
22250
|
+
const boxes = refs.composeSections.querySelectorAll(
|
|
22251
|
+
'input[type="checkbox"]'
|
|
22252
|
+
);
|
|
22253
|
+
for (const box of boxes) {
|
|
22254
|
+
box.checked = planSet.has(box.value);
|
|
22255
|
+
}
|
|
22256
|
+
}
|
|
22257
|
+
}
|
|
22258
|
+
const savedKey = readMacroSetting("key");
|
|
22259
|
+
if (savedKey && refs.composeKey) {
|
|
22260
|
+
const hasOption = Array.from(refs.composeKey.options).some(
|
|
22261
|
+
(opt) => opt.value === savedKey
|
|
22262
|
+
);
|
|
22263
|
+
if (hasOption) {
|
|
22264
|
+
refs.composeKey.value = savedKey;
|
|
22265
|
+
}
|
|
22266
|
+
}
|
|
22267
|
+
const savedShift = readMacroSetting("shift");
|
|
22268
|
+
if (savedShift && refs.shiftSelect) {
|
|
22269
|
+
const hasOption = Array.from(refs.shiftSelect.options).some(
|
|
22270
|
+
(opt) => opt.value === savedShift
|
|
22271
|
+
);
|
|
22272
|
+
if (hasOption) {
|
|
22273
|
+
refs.shiftSelect.value = savedShift;
|
|
22274
|
+
}
|
|
22275
|
+
}
|
|
22276
|
+
const savedTranspose = readMacroSetting("transpose");
|
|
22277
|
+
if (savedTranspose && refs.transposeSelect) {
|
|
22278
|
+
const hasOption = Array.from(refs.transposeSelect.options).some(
|
|
22279
|
+
(opt) => opt.value === savedTranspose
|
|
22280
|
+
);
|
|
22281
|
+
if (hasOption) {
|
|
22282
|
+
refs.transposeSelect.value = savedTranspose;
|
|
22283
|
+
}
|
|
22284
|
+
}
|
|
22285
|
+
refs.composeSections.addEventListener("change", () => {
|
|
22286
|
+
if (refs.composeTemplate) {
|
|
22287
|
+
refs.composeTemplate.value = "custom";
|
|
22288
|
+
writeMacroSetting("template", "custom");
|
|
22289
|
+
}
|
|
22290
|
+
writeMacroSections(selectedComposeSections());
|
|
22291
|
+
updateComposeSectionsLen();
|
|
22292
|
+
});
|
|
22293
|
+
const composeTemplate = refs.composeTemplate;
|
|
22294
|
+
if (composeTemplate) {
|
|
22295
|
+
composeTemplate.addEventListener("change", () => {
|
|
22296
|
+
writeMacroSetting("template", composeTemplate.value);
|
|
22297
|
+
const tmplName = selectedComposeTemplate();
|
|
22298
|
+
if (tmplName) {
|
|
22299
|
+
const tmpl = STRUCTURE_TEMPLATES.find((t) => t.name === tmplName);
|
|
22300
|
+
if (tmpl) {
|
|
22301
|
+
const planSet = new Set(tmpl.plan);
|
|
22302
|
+
const boxes = refs.composeSections.querySelectorAll(
|
|
22303
|
+
'input[type="checkbox"]'
|
|
22304
|
+
);
|
|
22305
|
+
for (const box of boxes) {
|
|
22306
|
+
box.checked = planSet.has(box.value);
|
|
22307
|
+
}
|
|
22308
|
+
}
|
|
22309
|
+
}
|
|
22310
|
+
writeMacroSections(selectedComposeSections());
|
|
22311
|
+
updateComposeSectionsLen();
|
|
22312
|
+
});
|
|
22313
|
+
}
|
|
21771
22314
|
updateComposeSectionsLen();
|
|
21772
22315
|
const updateComposeKeyHint = () => {
|
|
21773
22316
|
if (!refs.composeKey || !refs.composeKeyHint) return;
|
|
@@ -21775,17 +22318,33 @@ var mountDAW = (target, options = {}) => {
|
|
|
21775
22318
|
refs.composeKeyHint.textContent = desc;
|
|
21776
22319
|
refs.composeKeyHint.title = desc;
|
|
21777
22320
|
};
|
|
21778
|
-
|
|
21779
|
-
|
|
22321
|
+
const composeKey = refs.composeKey;
|
|
22322
|
+
if (composeKey) {
|
|
22323
|
+
composeKey.addEventListener("change", () => {
|
|
22324
|
+
writeMacroSetting("key", composeKey.value);
|
|
22325
|
+
updateComposeKeyHint();
|
|
22326
|
+
});
|
|
21780
22327
|
updateComposeKeyHint();
|
|
21781
22328
|
}
|
|
22329
|
+
if (refs.shiftSelect) {
|
|
22330
|
+
refs.shiftSelect.addEventListener("change", () => {
|
|
22331
|
+
writeMacroSetting("shift", refs.shiftSelect.value);
|
|
22332
|
+
});
|
|
22333
|
+
}
|
|
22334
|
+
if (refs.transposeSelect) {
|
|
22335
|
+
refs.transposeSelect.addEventListener("change", () => {
|
|
22336
|
+
writeMacroSetting("transpose", refs.transposeSelect.value);
|
|
22337
|
+
});
|
|
22338
|
+
}
|
|
21782
22339
|
const runCompose = (withVocal) => {
|
|
21783
22340
|
stop();
|
|
21784
22341
|
overlayDuring(() => {
|
|
22342
|
+
const tmpl = selectedComposeTemplate();
|
|
21785
22343
|
const song = composeSong({
|
|
21786
22344
|
stepsPerBar: renderConfig.stepsPerBar,
|
|
21787
22345
|
edo: renderConfig.edo,
|
|
21788
22346
|
sections: selectedComposeSections(),
|
|
22347
|
+
template: tmpl,
|
|
21789
22348
|
baseKey: refs.composeKey?.value ?? "any",
|
|
21790
22349
|
// 直近に作った曲の特徴を渡すと、それらから離れた候補に加点される。
|
|
21791
22350
|
// 「作曲」を続けて押したときに似た曲が並ぶのを防ぐ。
|
|
@@ -21824,7 +22383,19 @@ var mountDAW = (target, options = {}) => {
|
|
|
21824
22383
|
for (const layer of ADVANCED_COMPOSE_LAYOUT) {
|
|
21825
22384
|
const track = trackStates[layer.index];
|
|
21826
22385
|
if (!track) continue;
|
|
21827
|
-
const notes = layer.part === "melody" ? song.melody : layer.part === "submelody" ? song.submelody : layer.part === "bass" ? song.bass : buildChordPlacements({
|
|
22386
|
+
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({
|
|
22387
|
+
edo: renderConfig.edo,
|
|
22388
|
+
chordStr: song.chordProgression,
|
|
22389
|
+
patternType: "arpeggio",
|
|
22390
|
+
rootShift: song.rootShift,
|
|
22391
|
+
bpm: song.bpm,
|
|
22392
|
+
stepsPerBar: renderConfig.stepsPerBar
|
|
22393
|
+
}).map((p) => ({
|
|
22394
|
+
startStep: p.startStep,
|
|
22395
|
+
pitchUnits: p.pitchUnits,
|
|
22396
|
+
durationSteps: p.durationSteps,
|
|
22397
|
+
velocity: Math.max(30, p.velocity - 14)
|
|
22398
|
+
})) : buildChordPlacements({
|
|
21828
22399
|
edo: renderConfig.edo,
|
|
21829
22400
|
chordStr: song.chordProgression,
|
|
21830
22401
|
patternType: layer.part,
|
|
@@ -21863,6 +22434,12 @@ var mountDAW = (target, options = {}) => {
|
|
|
21863
22434
|
refs.drumSelect.value = song.drum;
|
|
21864
22435
|
options.onDrumChange?.(song.drum);
|
|
21865
22436
|
applyDrumPatternFont(song.drum);
|
|
22437
|
+
const shouldAutoInstrument = !currentInstrument || currentInstrument === "auto" || currentInstrument === autoComposeInstrument;
|
|
22438
|
+
if (shouldAutoInstrument && song.instrument) {
|
|
22439
|
+
currentInstrument = song.instrument;
|
|
22440
|
+
autoComposeInstrument = song.instrument;
|
|
22441
|
+
options.onInstrumentChange?.(song.instrument);
|
|
22442
|
+
}
|
|
21866
22443
|
for (const t of bassTracksForCompose()) {
|
|
21867
22444
|
t.trackCompression = AUTO_ROLE_MIX.bass.compression;
|
|
21868
22445
|
options.onTrackCompressionChange?.(t.config.id, t.trackCompression);
|
|
@@ -24135,6 +24712,8 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24135
24712
|
if (fadeOutStartAt !== void 0 && fadeOutEndAt !== void 0) {
|
|
24136
24713
|
fadeGain.gain.setValueAtTime(1, fadeOutStartAt);
|
|
24137
24714
|
fadeGain.gain.linearRampToValueAtTime(0, fadeOutEndAt);
|
|
24715
|
+
fadeGain.gain.setValueAtTime(0, fadeOutEndAt + 2);
|
|
24716
|
+
fadeGain.gain.setValueAtTime(1, fadeOutEndAt + 2);
|
|
24138
24717
|
}
|
|
24139
24718
|
};
|
|
24140
24719
|
const clipMeter = createClipMeter(audioCtx, glueMakeup);
|
|
@@ -24362,13 +24941,17 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24362
24941
|
}
|
|
24363
24942
|
const select = doc.createElement("select");
|
|
24364
24943
|
select.className = "dtm-select dtm-grow";
|
|
24944
|
+
const autoOpt = doc.createElement("option");
|
|
24945
|
+
autoOpt.value = "auto";
|
|
24946
|
+
autoOpt.textContent = "\u2728 \u81EA\u52D5\uFF08\u66F2\u8ABF\u9023\u52D5\uFF09";
|
|
24947
|
+
select.appendChild(autoOpt);
|
|
24365
24948
|
for (const [key, p] of Object.entries(INSTRUMENT_PRESETS)) {
|
|
24366
24949
|
const o = doc.createElement("option");
|
|
24367
24950
|
o.value = key;
|
|
24368
24951
|
o.textContent = p.displayName;
|
|
24369
24952
|
select.appendChild(o);
|
|
24370
24953
|
}
|
|
24371
|
-
select.value = opts.value && INSTRUMENT_PRESETS[opts.value] ? opts.value : defaultPreset;
|
|
24954
|
+
select.value = opts.value === "auto" || opts.value && INSTRUMENT_PRESETS[opts.value] ? opts.value : defaultPreset;
|
|
24372
24955
|
wrapper.appendChild(select);
|
|
24373
24956
|
let busy = false;
|
|
24374
24957
|
const onChange = async () => {
|
|
@@ -24377,6 +24960,10 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24377
24960
|
busy = true;
|
|
24378
24961
|
const key = select.value;
|
|
24379
24962
|
opts.onChange?.(key);
|
|
24963
|
+
if (key === "auto") {
|
|
24964
|
+
busy = false;
|
|
24965
|
+
return;
|
|
24966
|
+
}
|
|
24380
24967
|
const trackIds = opts.getTrackIds?.() ?? [...TRACK_ROLES];
|
|
24381
24968
|
const isAdvanced = trackIds.includes("t0");
|
|
24382
24969
|
const mode = isAdvanced ? "advanced" : "simple";
|
|
@@ -24394,7 +24981,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24394
24981
|
element: wrapper,
|
|
24395
24982
|
select,
|
|
24396
24983
|
setValue: (k) => {
|
|
24397
|
-
if (INSTRUMENT_PRESETS[k]) select.value = k;
|
|
24984
|
+
if (k === "auto" || INSTRUMENT_PRESETS[k]) select.value = k;
|
|
24398
24985
|
},
|
|
24399
24986
|
getValue: () => select.value,
|
|
24400
24987
|
destroy: () => {
|
|
@@ -24406,8 +24993,15 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24406
24993
|
await listReady;
|
|
24407
24994
|
nameToKey = await buildNameToKeyMapping();
|
|
24408
24995
|
await Promise.all([drumReady, loadPreset(defaultPreset)]);
|
|
24996
|
+
const restoreFadeGainIfMuted = () => {
|
|
24997
|
+
if (fadeGain.gain.value < 1) {
|
|
24998
|
+
fadeGain.gain.cancelScheduledValues(audioCtx.currentTime);
|
|
24999
|
+
fadeGain.gain.setValueAtTime(1, audioCtx.currentTime);
|
|
25000
|
+
}
|
|
25001
|
+
};
|
|
24409
25002
|
const playDrum = (e) => {
|
|
24410
25003
|
if (!sfDrum.font) return;
|
|
25004
|
+
if (e.when === 0) restoreFadeGainIfMuted();
|
|
24411
25005
|
if (KICK_PITCHES.has(e.pitch)) duckBassForKick(e.when);
|
|
24412
25006
|
sfDrum.play({
|
|
24413
25007
|
ctx: audioCtx,
|
|
@@ -24451,6 +25045,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24451
25045
|
}
|
|
24452
25046
|
}
|
|
24453
25047
|
const playNote4 = (e) => {
|
|
25048
|
+
if (e.when === 0) restoreFadeGainIfMuted();
|
|
24454
25049
|
const { trackIdx, role } = resolveTrackIdxAndRole(e.trackId);
|
|
24455
25050
|
const overrideKey = trackIdx >= 0 ? trackInstOverrides.get(trackIdx) : void 0;
|
|
24456
25051
|
let sfInst;
|
|
@@ -24476,12 +25071,33 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24476
25071
|
duration: e.duration
|
|
24477
25072
|
});
|
|
24478
25073
|
};
|
|
25074
|
+
let daw;
|
|
24479
25075
|
let presetSelect = null;
|
|
24480
25076
|
const handleInstrumentChange = (key) => {
|
|
25077
|
+
if (key === "auto") {
|
|
25078
|
+
if (presetSelect) {
|
|
25079
|
+
presetSelect.setValue("auto");
|
|
25080
|
+
}
|
|
25081
|
+
onInstrumentChange?.("auto");
|
|
25082
|
+
return;
|
|
25083
|
+
}
|
|
24481
25084
|
editorPreset = key;
|
|
24482
25085
|
if (presetSelect) {
|
|
24483
25086
|
presetSelect.setValue(key);
|
|
24484
25087
|
}
|
|
25088
|
+
if (INSTRUMENT_PRESETS[key]) {
|
|
25089
|
+
const wasPlaying = daw?.getPlaybackState() === "playing";
|
|
25090
|
+
if (wasPlaying) daw.pause();
|
|
25091
|
+
daw?.setLoading?.(true);
|
|
25092
|
+
void loadPreset(
|
|
25093
|
+
key,
|
|
25094
|
+
trackIds,
|
|
25095
|
+
isAdvancedMode ? "advanced" : "simple"
|
|
25096
|
+
).finally(() => {
|
|
25097
|
+
daw?.setLoading?.(false);
|
|
25098
|
+
if (wasPlaying) daw?.play();
|
|
25099
|
+
});
|
|
25100
|
+
}
|
|
24485
25101
|
onInstrumentChange?.(key);
|
|
24486
25102
|
};
|
|
24487
25103
|
const handleTrackInstrumentChange = async (trackIndex, instrumentName) => {
|
|
@@ -24495,7 +25111,6 @@ var createDtmStudio = async (options = {}) => {
|
|
|
24495
25111
|
trackInstOverrides.set(trackIndex, key);
|
|
24496
25112
|
await loadInstrument(key);
|
|
24497
25113
|
};
|
|
24498
|
-
let daw;
|
|
24499
25114
|
const base = {
|
|
24500
25115
|
getAudioTime: () => audioCtx.currentTime,
|
|
24501
25116
|
onResumeAudio: async () => {
|
|
@@ -25253,6 +25868,7 @@ export {
|
|
|
25253
25868
|
KOE_VOICEBANK_LABELS,
|
|
25254
25869
|
KOE_VOICEBANK_TERMS,
|
|
25255
25870
|
LinkedList,
|
|
25871
|
+
MACRO_STORAGE_KEYS,
|
|
25256
25872
|
MAJOR_KEY_IDS,
|
|
25257
25873
|
MAX_VOCAL_VOLUME,
|
|
25258
25874
|
MICRO_STEP,
|
|
@@ -25355,6 +25971,8 @@ export {
|
|
|
25355
25971
|
playNote,
|
|
25356
25972
|
playPlacements,
|
|
25357
25973
|
playSingingMML,
|
|
25974
|
+
readMacroSections,
|
|
25975
|
+
readMacroSetting,
|
|
25358
25976
|
resolveComposeKey,
|
|
25359
25977
|
resolveDrumPattern,
|
|
25360
25978
|
resolveLoopPoint,
|
|
@@ -25377,5 +25995,7 @@ export {
|
|
|
25377
25995
|
unitsToMidi,
|
|
25378
25996
|
unitsToMidiDetune,
|
|
25379
25997
|
unitsToPitchV1,
|
|
25380
|
-
vocalVolumeToGain
|
|
25998
|
+
vocalVolumeToGain,
|
|
25999
|
+
writeMacroSections,
|
|
26000
|
+
writeMacroSetting
|
|
25381
26001
|
};
|