@onjmin/dtm 2.1.8 → 2.1.10
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 +481 -135
- package/dist/index.d.ts +481 -135
- package/dist/index.js +2504 -417
- package/dist/index.mjs +2489 -417
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -22,10 +22,13 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
A4_HZ: () => A4_HZ,
|
|
24
24
|
A4_UNITS: () => A4_UNITS,
|
|
25
|
+
BLUES_SCALE: () => BLUES_SCALE,
|
|
25
26
|
BREATH_MARK: () => BREATH_MARK,
|
|
26
27
|
CENTS_PER_UNIT: () => CENTS_PER_UNIT,
|
|
27
28
|
COMPOSE_KEYS: () => COMPOSE_KEYS,
|
|
28
29
|
COMPOSE_MOOD_GROUPS: () => COMPOSE_MOOD_GROUPS,
|
|
30
|
+
COMPOSE_SCALES: () => COMPOSE_SCALES,
|
|
31
|
+
COMPOSE_SCALE_IDS: () => COMPOSE_SCALE_IDS,
|
|
29
32
|
CORPUS_BANDS: () => CORPUS_BANDS,
|
|
30
33
|
CORPUS_SIZE: () => CORPUS_SIZE,
|
|
31
34
|
DAW_CSS: () => DAW_CSS,
|
|
@@ -45,7 +48,11 @@ __export(index_exports, {
|
|
|
45
48
|
FADE_IN_MARK: () => FADE_IN_MARK,
|
|
46
49
|
FADE_OUT_MARK: () => FADE_OUT_MARK,
|
|
47
50
|
GLOBAL_STORAGE_KEYS: () => GLOBAL_STORAGE_KEYS,
|
|
51
|
+
GM_BRIGHT_CEILING: () => GM_BRIGHT_CEILING,
|
|
48
52
|
GM_INSTRUMENT_NAMES: () => GM_INSTRUMENT_NAMES,
|
|
53
|
+
GM_INSTRUMENT_RANGE: () => GM_INSTRUMENT_RANGE,
|
|
54
|
+
HARMONIC_MINOR_SCALE: () => HARMONIC_MINOR_SCALE,
|
|
55
|
+
HUNGARIAN_SCALE: () => HUNGARIAN_SCALE,
|
|
49
56
|
INSTRUMENT_PRESETS: () => INSTRUMENT_PRESETS,
|
|
50
57
|
KEY_COUNT: () => KEY_COUNT,
|
|
51
58
|
KOE_BASE_URL: () => KOE_BASE_URL,
|
|
@@ -55,6 +62,7 @@ __export(index_exports, {
|
|
|
55
62
|
LinkedList: () => LinkedList,
|
|
56
63
|
MACRO_STORAGE_KEYS: () => MACRO_STORAGE_KEYS,
|
|
57
64
|
MAJOR_KEY_IDS: () => MAJOR_KEY_IDS,
|
|
65
|
+
MAJOR_SCALE: () => MAJOR_SCALE2,
|
|
58
66
|
MAX_VOCAL_VOLUME: () => MAX_VOCAL_VOLUME,
|
|
59
67
|
MICRO_STEP: () => MICRO_STEP,
|
|
60
68
|
MINOR_KEY_IDS: () => MINOR_KEY_IDS,
|
|
@@ -123,10 +131,12 @@ __export(index_exports, {
|
|
|
123
131
|
featureVector: () => featureVector,
|
|
124
132
|
fifthToStep: () => fifthToStep,
|
|
125
133
|
fifthToUnits: () => fifthToUnits,
|
|
134
|
+
fitInstrumentOctave: () => fitInstrumentOctave,
|
|
126
135
|
formatMmlMeta: () => formatMmlMeta,
|
|
127
136
|
freqFromPitch: () => freqFromPitch,
|
|
128
137
|
generateRandomPattern: () => generateRandomPattern,
|
|
129
138
|
getComposeKeyDescription: () => getComposeKeyDescription,
|
|
139
|
+
getComposeScaleDescription: () => getComposeScaleDescription,
|
|
130
140
|
getDrumPatternKeys: () => getDrumPatternKeys,
|
|
131
141
|
getMidiBPM: () => getMidiBPM,
|
|
132
142
|
icon: () => icon,
|
|
@@ -156,14 +166,19 @@ __export(index_exports, {
|
|
|
156
166
|
playNote: () => playNote,
|
|
157
167
|
playPlacements: () => playPlacements,
|
|
158
168
|
playSingingMML: () => playSingingMML,
|
|
169
|
+
programOfInstrumentName: () => programOfInstrumentName,
|
|
159
170
|
readGlobalBool: () => readGlobalBool,
|
|
160
171
|
readGlobalNumber: () => readGlobalNumber,
|
|
161
172
|
readGlobalSetting: () => readGlobalSetting,
|
|
162
173
|
readMacroSections: () => readMacroSections,
|
|
163
174
|
readMacroSetting: () => readMacroSetting,
|
|
175
|
+
resolveCenter: () => resolveCenter,
|
|
164
176
|
resolveComposeKey: () => resolveComposeKey,
|
|
177
|
+
resolveComposeScale: () => resolveComposeScale,
|
|
165
178
|
resolveDrumPattern: () => resolveDrumPattern,
|
|
166
179
|
resolveLoopPoint: () => resolveLoopPoint,
|
|
180
|
+
scaleDegrees: () => scaleDegrees,
|
|
181
|
+
scaleSize: () => scaleSize,
|
|
167
182
|
semitonesToUnits: () => semitonesToUnits,
|
|
168
183
|
shiftNotes: () => shiftNotes,
|
|
169
184
|
showLoadingOverlay: () => showLoadingOverlay,
|
|
@@ -339,6 +354,14 @@ async function buildNameToKeyMapping() {
|
|
|
339
354
|
return nameToKey;
|
|
340
355
|
}
|
|
341
356
|
var GM_INSTRUMENT_NAMES = FONT_NAME_SURIKOV.trim().split("\n").map((line) => line.slice(line.indexOf(" ") + 1));
|
|
357
|
+
var programOfInstrumentName = (name) => {
|
|
358
|
+
if (!name) return null;
|
|
359
|
+
const stripped = name.replace(/\s+/g, "").toLowerCase();
|
|
360
|
+
const idx = GM_INSTRUMENT_NAMES.findIndex(
|
|
361
|
+
(n) => n.replace(/\s+/g, "").toLowerCase() === stripped
|
|
362
|
+
);
|
|
363
|
+
return idx >= 0 ? idx : null;
|
|
364
|
+
};
|
|
342
365
|
|
|
343
366
|
// node_modules/.pnpm/@onjmin+chord-parser@1.1.1/node_modules/@onjmin/chord-parser/dist/index.mjs
|
|
344
367
|
var SHARP_NAMES = [
|
|
@@ -8305,6 +8328,22 @@ var DAW_CSS = `
|
|
|
8305
8328
|
opacity: 0.85;
|
|
8306
8329
|
}
|
|
8307
8330
|
.dtm-pill:not(.dtm-pill--active):active { transform: translate(1px,1px); box-shadow: none; }
|
|
8331
|
+
/* \u30DC\u30FC\u30AB\u30EB\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u308B\u30C8\u30E9\u30C3\u30AF\u306E\u30BF\u30D6\u306B\u3001\u3046\u3063\u3059\u3089\u58F0\u306E\u30A2\u30A4\u30B3\u30F3\u3092\u91CD\u306D\u308B\uFF08\u80CC\u666F\u8272\u30FB\u30B5\u30A4\u30BA\u306F\u5909\u3048\u306A\u3044\uFF09 */
|
|
8332
|
+
.dtm-pill--vocal::after {
|
|
8333
|
+
content: '';
|
|
8334
|
+
position: absolute;
|
|
8335
|
+
inset: 0;
|
|
8336
|
+
background-image: var(--dtm-pill-icon);
|
|
8337
|
+
background-size: contain;
|
|
8338
|
+
background-repeat: no-repeat;
|
|
8339
|
+
background-position: right center;
|
|
8340
|
+
opacity: 0.4;
|
|
8341
|
+
pointer-events: none;
|
|
8342
|
+
}
|
|
8343
|
+
.dtm-pill__label {
|
|
8344
|
+
position: relative;
|
|
8345
|
+
z-index: 1;
|
|
8346
|
+
}
|
|
8308
8347
|
/* \u518D\u751F\u4E2D\u3001\u5B9F\u969B\u306B\u767A\u97F3\u3057\u305F\u77AC\u9593\u3060\u3051\u70B9\u706F\uFF08\u3069\u306E\u30BF\u30D6\u304C\u4ECA\u9CF4\u3063\u3066\u3044\u308B\u304B\u8996\u899A\u7684\u306B\u5206\u304B\u308B\u3088\u3046\u306B\uFF09 */
|
|
8309
8348
|
.dtm-pill--sounding {
|
|
8310
8349
|
filter: brightness(1.6);
|
|
@@ -12702,44 +12741,365 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
12702
12741
|
// src/compose-corpus.ts
|
|
12703
12742
|
var CORPUS_SIZE = 91;
|
|
12704
12743
|
var CORPUS_BANDS = {
|
|
12705
|
-
entropy: [0.
|
|
12706
|
-
valueKinds: [2, 3,
|
|
12707
|
-
restRatio: [
|
|
12708
|
-
leapRatio: [0.
|
|
12709
|
-
stepRatio: [0.
|
|
12710
|
-
chromaticRatio: [0, 0.
|
|
12711
|
-
maxLeap: [
|
|
12712
|
-
melodyRange: [
|
|
12713
|
-
notesPerBar: [
|
|
12714
|
-
shortNoteRatio: [0.
|
|
12715
|
-
|
|
12716
|
-
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12744
|
+
entropy: [0.25, 0.711, 1.237, 1.754],
|
|
12745
|
+
valueKinds: [2, 3, 6, 7],
|
|
12746
|
+
restRatio: [0.016, 0.091, 0.223, 0.464],
|
|
12747
|
+
leapRatio: [0.202, 0.28, 0.412, 0.71],
|
|
12748
|
+
stepRatio: [0.188, 0.438, 0.617, 0.693],
|
|
12749
|
+
chromaticRatio: [0, 0.017, 0.121, 0.242],
|
|
12750
|
+
maxLeap: [5, 8, 12, 16],
|
|
12751
|
+
melodyRange: [8, 17, 22, 28],
|
|
12752
|
+
notesPerBar: [2.743, 4.77, 6.473, 11.995],
|
|
12753
|
+
shortNoteRatio: [0.055, 0.753, 0.91, 1],
|
|
12754
|
+
barDensityCv: [0.148, 0.206, 0.328, 0.451],
|
|
12755
|
+
densityCliff: [0, 0, 0.043, 0.125],
|
|
12756
|
+
sim1: [0.345, 0.465, 0.598, 0.803],
|
|
12757
|
+
sim2: [0.389, 0.5, 0.647, 0.845],
|
|
12758
|
+
sim4: [0.437, 0.549, 0.723, 0.882],
|
|
12759
|
+
sim8: [0.063, 0.561, 0.771, 0.972],
|
|
12760
|
+
phraseBreath: [0, 0.115, 0.323, 0.884],
|
|
12761
|
+
turnRatio: [0.4, 0.478, 0.556, 0.769],
|
|
12762
|
+
climaxPosition: [0.016, 0.14, 0.655, 0.92],
|
|
12763
|
+
climaxPeaks: [1, 2, 13.5, 26],
|
|
12764
|
+
complementarity: [0, 0.026, 0.179, 0.405]
|
|
12723
12765
|
};
|
|
12724
12766
|
var CORPUS_MEDIANS = {
|
|
12725
|
-
entropy: 0.
|
|
12767
|
+
entropy: 0.907,
|
|
12726
12768
|
valueKinds: 4,
|
|
12727
|
-
restRatio: 0.
|
|
12728
|
-
leapRatio: 0.
|
|
12729
|
-
stepRatio: 0.
|
|
12730
|
-
chromaticRatio: 0.
|
|
12769
|
+
restRatio: 0.149,
|
|
12770
|
+
leapRatio: 0.339,
|
|
12771
|
+
stepRatio: 0.538,
|
|
12772
|
+
chromaticRatio: 0.052,
|
|
12731
12773
|
maxLeap: 12,
|
|
12732
|
-
melodyRange:
|
|
12733
|
-
notesPerBar: 5.
|
|
12734
|
-
shortNoteRatio: 0.
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
|
|
12739
|
-
|
|
12774
|
+
melodyRange: 20,
|
|
12775
|
+
notesPerBar: 5.511,
|
|
12776
|
+
shortNoteRatio: 0.816,
|
|
12777
|
+
barDensityCv: 0.279,
|
|
12778
|
+
densityCliff: 0.026,
|
|
12779
|
+
sim1: 0.518,
|
|
12780
|
+
sim2: 0.552,
|
|
12781
|
+
sim4: 0.616,
|
|
12782
|
+
sim8: 0.676,
|
|
12783
|
+
phraseBreath: 0.227,
|
|
12784
|
+
turnRatio: 0.519,
|
|
12740
12785
|
climaxPosition: 0.273,
|
|
12741
|
-
climaxPeaks:
|
|
12742
|
-
complementarity: 0.
|
|
12786
|
+
climaxPeaks: 6,
|
|
12787
|
+
complementarity: 0.075
|
|
12788
|
+
};
|
|
12789
|
+
var CORPUS_CELL_WEIGHTS = {
|
|
12790
|
+
"0,2,4,6,8,10,12,14": 584,
|
|
12791
|
+
"0,2,4,6,8,12,14": 512,
|
|
12792
|
+
"0,4,6,8,10,12,14": 246,
|
|
12793
|
+
"0,8": 187,
|
|
12794
|
+
"0,4,8,10,12,14": 158,
|
|
12795
|
+
"0,6,8,10,12,14": 153,
|
|
12796
|
+
"2,5,10,13": 128,
|
|
12797
|
+
"0,12,14": 123,
|
|
12798
|
+
"0,4,6,8,12,14": 114,
|
|
12799
|
+
"0,4,8,12": 110,
|
|
12800
|
+
"0": 105,
|
|
12801
|
+
"0,2,4,6,8,12": 103,
|
|
12802
|
+
"0,4,8,12,14": 102,
|
|
12803
|
+
"0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15": 89,
|
|
12804
|
+
"0,2,4,6,8": 76,
|
|
12805
|
+
"0,6,8,12,14": 58,
|
|
12806
|
+
"0,6,8,14": 48,
|
|
12807
|
+
"0,4,6,8,12": 44,
|
|
12808
|
+
"0,4,8,14": 44,
|
|
12809
|
+
"0,2,4,5,6,8,9,10,12,13,14,15": 44,
|
|
12810
|
+
"2,6,10,14": 42,
|
|
12811
|
+
"0,8,12": 40,
|
|
12812
|
+
"0,2,4,6,8,10,12": 39,
|
|
12813
|
+
"0,3,9,10,11,12,13,14,15": 36,
|
|
12814
|
+
"0,3,6,8,11,14": 32,
|
|
12815
|
+
"0,2,4,6,7,9,10,12,14": 32,
|
|
12816
|
+
"0,2,4,6,10,12,14": 31,
|
|
12817
|
+
"0,10,12,14": 28,
|
|
12818
|
+
"12,14": 27,
|
|
12819
|
+
"0,2,4,6,8,14": 27,
|
|
12820
|
+
"0,6,8,12": 25,
|
|
12821
|
+
"0,4,6,8,10,12": 24,
|
|
12822
|
+
"0,1,2,4,5,6,7,8,9,10,11,12,13,14,15": 24,
|
|
12823
|
+
"2,4,6,8,10,12,14": 22,
|
|
12824
|
+
"0,6,8": 19,
|
|
12825
|
+
"0,12": 19,
|
|
12826
|
+
"8,12": 17,
|
|
12827
|
+
"0,2,4,8,12,14": 16,
|
|
12828
|
+
"0,3,5,6,7,8,11,13,14,15": 16,
|
|
12829
|
+
"0,3,4,5,6,7,8,10,12,14": 16,
|
|
12830
|
+
"0,14": 15,
|
|
12831
|
+
"0,4,8": 15,
|
|
12832
|
+
"0,4,6,8,14": 14,
|
|
12833
|
+
"0,4,6,8,10,11,12,14": 14,
|
|
12834
|
+
"2,4,6,8": 13,
|
|
12835
|
+
"0,4,6,10,12,14": 13,
|
|
12836
|
+
"0,4,6,8": 13,
|
|
12837
|
+
"0,2,4,8,9,11,14,15": 12,
|
|
12838
|
+
"0,4,8,10,11,12,14": 12,
|
|
12839
|
+
"0,2,4,6,8,9,12,14": 12,
|
|
12840
|
+
"0,3,4,6,8,12,14": 12,
|
|
12841
|
+
"0,2,4,6,8,11,14": 12,
|
|
12842
|
+
"0,2,4,5,6,7,8,9,10,11,12,14": 12,
|
|
12843
|
+
"2,4,6,8,12,14": 11,
|
|
12844
|
+
"0,2,4,8,10,12": 11,
|
|
12845
|
+
"0,1,2,3,4,5,6,7,8,9,10,11,12": 11,
|
|
12846
|
+
"0,2,4,6,8,10,11,12,14": 10,
|
|
12847
|
+
"0,4,6,7,8,14,15": 10,
|
|
12848
|
+
"0,8,10,12,14": 10,
|
|
12849
|
+
"0,3,4,6,8,10,12,14": 9,
|
|
12850
|
+
"0,2,3,4,6,8,12,14": 9,
|
|
12851
|
+
"0,2,4,5,6,8,12,14": 9,
|
|
12852
|
+
"0,3,4,6,8,9,10,11,12": 9,
|
|
12853
|
+
"0,3,4,6,8,9,10,11,12,14,15": 9,
|
|
12854
|
+
"0,3,4,6,7,8,10,12,14,15": 9,
|
|
12855
|
+
"0,2,4,5,6,7,8,9,10,12,13,14,15": 9,
|
|
12856
|
+
"0,2,4,8,10,12,14": 8,
|
|
12857
|
+
"0,2,4,6,8,10,12,14,15": 8,
|
|
12858
|
+
"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15": 8,
|
|
12859
|
+
"0,3,6,8,12,14": 7,
|
|
12860
|
+
"0,1,2,3,4,5,6,7,8": 7,
|
|
12861
|
+
"0,4,8,10,12": 7,
|
|
12862
|
+
"0,2,3,4,5,6,7,8": 7,
|
|
12863
|
+
"0,3,4,6,8,12": 6,
|
|
12864
|
+
"0,2,4,6,10,14": 6,
|
|
12865
|
+
"4,12": 6,
|
|
12866
|
+
"0,6,8,10,14": 6,
|
|
12867
|
+
"0,2,3,4,5,6,7,8,9,10,11,12": 6,
|
|
12868
|
+
"0,1,2,3,4,6,7,8,10,12,14,15": 6,
|
|
12869
|
+
"0,3,6,8,12": 6,
|
|
12870
|
+
"2,4,6,8,10,11,12,14": 6,
|
|
12871
|
+
"6,8,10,12,14": 5,
|
|
12872
|
+
"2,6,8,10,12,14": 5,
|
|
12873
|
+
"0,8,12,14": 5,
|
|
12874
|
+
"0,3,4,6,8": 5,
|
|
12875
|
+
"0,8,11,14": 5,
|
|
12876
|
+
"0,3,4,6,8,10,11,12,14": 5,
|
|
12877
|
+
"0,3,6,8": 5,
|
|
12878
|
+
"0,1,4,8,9,12,13": 5,
|
|
12879
|
+
"10,12,14": 5,
|
|
12880
|
+
"0,4,6,8,10,11,12,13,14": 5,
|
|
12881
|
+
"12,13,14,15": 5,
|
|
12882
|
+
"0,2,4,7,8,14,15": 5,
|
|
12883
|
+
"0,4,8,9,10,11,12,13,14,15": 5,
|
|
12884
|
+
"0,4,7,8,14,15": 5,
|
|
12885
|
+
"0,4,8,9,10,11,12": 5,
|
|
12886
|
+
"0,2,6,8,10,12,14": 5,
|
|
12887
|
+
"2,4,6,12,14": 4,
|
|
12888
|
+
"0,2,4,6,7,8,10,12,14": 4,
|
|
12889
|
+
"4,5,7,8,10,12,13,14": 4,
|
|
12890
|
+
"0,2,3,4,5,8,9,12,13": 4,
|
|
12891
|
+
"2,3,4,6,8,12,13,14": 4,
|
|
12892
|
+
"0,1,2,3,4,5,6,7,8,9,10,11,12,13,14": 4,
|
|
12893
|
+
"0,2,4,8,12": 4,
|
|
12894
|
+
"4,6,8,10,12": 4,
|
|
12895
|
+
"0,2,4,5,6,8,12,13,14,15": 4,
|
|
12896
|
+
"0,2,3,4,6,8": 4,
|
|
12897
|
+
"0,4,6,8,10,12,13,14": 4,
|
|
12898
|
+
"0,6,8,12,14,15": 4,
|
|
12899
|
+
"0,4,8,9,10,12,14": 4,
|
|
12900
|
+
"0,3,4,7,8,9,10,11,12": 4,
|
|
12901
|
+
"0,1,2,3,4,5,7,8,9,10,11,12": 4,
|
|
12902
|
+
"2,4,8,12": 4,
|
|
12903
|
+
"0,2,4,6,10,12": 4,
|
|
12904
|
+
"0,3,4,6,7,8,9,10,12,14": 4,
|
|
12905
|
+
"0,3,6,9,11,12": 4,
|
|
12906
|
+
"0,1,4,6,8,12,14": 4,
|
|
12907
|
+
"4,8,12": 4,
|
|
12908
|
+
"2,4,6,14": 3,
|
|
12909
|
+
"0,3,4,8": 3,
|
|
12910
|
+
"0,2,4,12,14": 3,
|
|
12911
|
+
"14": 3,
|
|
12912
|
+
"0,4,6,12,14": 3,
|
|
12913
|
+
"0,6,10,12,14": 3,
|
|
12914
|
+
"4,8,9,11,14": 3,
|
|
12915
|
+
"0,2,4,8,9,11,14": 3,
|
|
12916
|
+
"0,4,8,9,11,14": 3,
|
|
12917
|
+
"0,2,4,5,7,9,11,12": 3,
|
|
12918
|
+
"0,3,6,8,10,12,14": 3,
|
|
12919
|
+
"0,3,4,6,8,11,12,14": 3,
|
|
12920
|
+
"0,1,4,5,8,9,12,13": 3,
|
|
12921
|
+
"0,2,4,5,8,9": 3,
|
|
12922
|
+
"2,3,4,6,8,9,12,14": 3,
|
|
12923
|
+
"0,2,4,8": 3,
|
|
12924
|
+
"0,2,3,4,5,6,8,9": 3,
|
|
12925
|
+
"2,3,4,6,8,10,12,13": 3,
|
|
12926
|
+
"12,14,15": 3,
|
|
12927
|
+
"0,2,3,4,6,7,8,10,12": 3,
|
|
12928
|
+
"0,2,3,4,5,6,7,8,9,10,12": 3,
|
|
12929
|
+
"0,1,2,3,4,5,6,7,8,9,10,11,12,14": 3,
|
|
12930
|
+
"0,2,3,4,6,7,8,9,10,11,12": 3,
|
|
12931
|
+
"0,4,6,12": 3,
|
|
12932
|
+
"0,2,3,6,8,11,14": 3,
|
|
12933
|
+
"0,2,6,8,12,14": 3,
|
|
12934
|
+
"2,4,6,8,14,15": 3,
|
|
12935
|
+
"0,2,4,6,12,14": 2,
|
|
12936
|
+
"2,4,6,10,12,14": 2,
|
|
12937
|
+
"4,6,10,12,14": 2,
|
|
12938
|
+
"0,8,14": 2,
|
|
12939
|
+
"2,4,8,10,12,14": 2,
|
|
12940
|
+
"8": 2,
|
|
12941
|
+
"0,2,4,6,8,9,10,11,12,14": 2,
|
|
12942
|
+
"0,2,4,6,8,12,13,14": 2,
|
|
12943
|
+
"0,6,8,11,12,14": 2,
|
|
12944
|
+
"0,1,2,3,4,5,6,7,8,9,11,12,13,14,15": 2,
|
|
12945
|
+
"0,1,3,4,5,6,7,8,9,10,11,12,13,14,15": 2,
|
|
12946
|
+
"0,6,7,8,10,12": 2,
|
|
12947
|
+
"0,3,6,7,8,10,12": 2,
|
|
12948
|
+
"1,2,3,4,6,8,10,12,13": 2,
|
|
12949
|
+
"0,2,8,10,12,14": 2,
|
|
12950
|
+
"0,2,7,8,9,10": 2,
|
|
12951
|
+
"4,8,9,10,12,13": 2,
|
|
12952
|
+
"0,2,4,7,8,9,10": 2,
|
|
12953
|
+
"2,4,7,8,12,15": 2,
|
|
12954
|
+
"0,4,7,8,10": 2,
|
|
12955
|
+
"0,4,8,9,12,13": 2,
|
|
12956
|
+
"0,2,4,5,6,8,9": 2,
|
|
12957
|
+
"0,1,4": 2,
|
|
12958
|
+
"0,4": 2,
|
|
12959
|
+
"0,3,6,10,12,14": 2,
|
|
12960
|
+
"0,2,6,10,12,14": 2,
|
|
12961
|
+
"0,2,3,4,6,8,14,15": 2,
|
|
12962
|
+
"2,4,6,8,12,14,15": 2,
|
|
12963
|
+
"0,2,4,6,8,9,10,12": 2,
|
|
12964
|
+
"0,3,6,8,10,12": 2,
|
|
12965
|
+
"0,3,4,6,8,10,14": 2,
|
|
12966
|
+
"0,4,8,11,12,14": 2,
|
|
12967
|
+
"0,2,4,6,8,9,10,11,12,13,14": 2,
|
|
12968
|
+
"0,2,4,5,6,7,8,9,10,12": 2,
|
|
12969
|
+
"0,1,2,3,4,6,7,8,9,10,12,14": 2,
|
|
12970
|
+
"0,1,2,4,5,6,8,9,10,11,12,13,14": 2,
|
|
12971
|
+
"0,1,2,3,4,6,7,8,9,10,11,12,13,14": 2,
|
|
12972
|
+
"0,1,2,3,4,6,7,8,9,10,11,12,13,14,15": 2,
|
|
12973
|
+
"0,1,2,4,6,8,9,10,11,12,13,14": 2,
|
|
12974
|
+
"0,1,2,3,4,5,6,8,9,10,11,12,13,14": 2,
|
|
12975
|
+
"0,1,2,3,4,6,7,8,9,10,12,13,14,15": 2,
|
|
12976
|
+
"0,2,4,6,8,9,10,11,12,13,14,15": 2,
|
|
12977
|
+
"0,2,3,4,5,6,8,10,12": 2,
|
|
12978
|
+
"0,2,3,4,5,6,7,8,10,11,12": 2,
|
|
12979
|
+
"0,2,3,4,6,7,8,9,10,12": 2,
|
|
12980
|
+
"0,1,2,3,4,6,7,8,9,10,11,12": 2,
|
|
12981
|
+
"0,4,5,8,12,13": 2,
|
|
12982
|
+
"0,3,4,5,8,11,12,13": 2,
|
|
12983
|
+
"0,2,4,7,8,9": 2,
|
|
12984
|
+
"0,4,6,7,8,12": 2,
|
|
12985
|
+
"0,2,3,4,6,7,8,10,11,12,14": 2,
|
|
12986
|
+
"0,2,3,4,5,6,7,8,10,11,12,13": 2,
|
|
12987
|
+
"12": 2,
|
|
12988
|
+
"0,2,4,6,8,13": 2,
|
|
12989
|
+
"2,4,6,8,11,14": 2,
|
|
12990
|
+
"0,5,8,13": 2,
|
|
12991
|
+
"0,2,4,6,8,10,11,12,13,14": 2,
|
|
12992
|
+
"0,4,6,8,10,11,12,13,14,15": 2,
|
|
12993
|
+
"0,5,8,12": 2,
|
|
12994
|
+
"2,4,6,8,14": 1,
|
|
12995
|
+
"0,6,7,8,14": 1,
|
|
12996
|
+
"0,6,8,14,15": 1,
|
|
12997
|
+
"0,6,7,8,10,11,12,13": 1,
|
|
12998
|
+
"0,6,7,8,9,10,11,12,14": 1,
|
|
12999
|
+
"0,1,2,4,6,7,8,10,11,12,13,14,15": 1,
|
|
13000
|
+
"0,4,8,10,11,12": 1,
|
|
13001
|
+
"0,6,7,8,11,14": 1,
|
|
13002
|
+
"0,2,5,8,11,14": 1,
|
|
13003
|
+
"0,2,4,6,8,10,11,12": 1,
|
|
13004
|
+
"0,11,14": 1,
|
|
13005
|
+
"0,8,11,12,13,14,15": 1,
|
|
13006
|
+
"0,1,12": 1,
|
|
13007
|
+
"0,3,5,8,12": 1,
|
|
13008
|
+
"0,4,8,11,14": 1,
|
|
13009
|
+
"2,6,8,11,14": 1,
|
|
13010
|
+
"0,2,3,4,6,8,12": 1,
|
|
13011
|
+
"0,4,6,8,11,12,14": 1,
|
|
13012
|
+
"0,1,12,14": 1,
|
|
13013
|
+
"0,9,12": 1,
|
|
13014
|
+
"0,3": 1,
|
|
13015
|
+
"0,1": 1,
|
|
13016
|
+
"4,6,8,14": 1,
|
|
13017
|
+
"2,12,14": 1,
|
|
13018
|
+
"2,8,12": 1,
|
|
13019
|
+
"0,3,6,8,11": 1,
|
|
13020
|
+
"10,12,14,15": 1,
|
|
13021
|
+
"0,2,3,6,8,9,11,14": 1,
|
|
13022
|
+
"0,2,4,8,10,11": 1,
|
|
13023
|
+
"0,2,4,6,7,8,10,12,13": 1,
|
|
13024
|
+
"2,3,4,5,8,10,12,13,15": 1,
|
|
13025
|
+
"0,2,3,4,5,6,8,10,11,12": 1,
|
|
13026
|
+
"4,6,8,10,11,12": 1,
|
|
13027
|
+
"0,1,2,3,4,6,8,9,10,13,15": 1,
|
|
13028
|
+
"0,1,2,3,4,10,11,12": 1,
|
|
13029
|
+
"0,3,6,7,8,9,11": 1,
|
|
13030
|
+
"0,2,4,5,8,10,11,15": 1,
|
|
13031
|
+
"0,2,4,6,7,8,9,12,13": 1,
|
|
13032
|
+
"0,1,2,4,5,8,10,12,13": 1,
|
|
13033
|
+
"0,2,3,4,5,6,8,10,11,12,13": 1,
|
|
13034
|
+
"4,6,8,10,11,12,13": 1,
|
|
13035
|
+
"0,3,8,12,14": 1,
|
|
13036
|
+
"0,3,4,5,7,8,9,10,12,14,15": 1,
|
|
13037
|
+
"0,2,4,6,8,9,11": 1,
|
|
13038
|
+
"10,14": 1,
|
|
13039
|
+
"0,2,4,6,9,10,12,14": 1,
|
|
13040
|
+
"0,2,4,6,7,9,10,12": 1,
|
|
13041
|
+
"0,2,3,5,8,10,12,13,14": 1,
|
|
13042
|
+
"0,1,2,3,5,6,7,8,9,10,12,13,14": 1,
|
|
13043
|
+
"2,3,4,6,7,8,12,13,14": 1,
|
|
13044
|
+
"0,1,2,3,6,7,8,10,12,13,14": 1,
|
|
13045
|
+
"2,3,4,5,6,8,9,10,11,12,13,14": 1,
|
|
13046
|
+
"0,2,3,4,5,6,7,8,9,10,11,12,13,14": 1,
|
|
13047
|
+
"2,3,4,6,8,9,10,11,12,13,14,15": 1,
|
|
13048
|
+
"0,3,4,7,8,11,12": 1,
|
|
13049
|
+
"0,4,10,12,14": 1,
|
|
13050
|
+
"0,3,4,7,8,11,12,15": 1,
|
|
13051
|
+
"0,4,12,14": 1,
|
|
13052
|
+
"0,4,12": 1,
|
|
13053
|
+
"0,4,7,8,10,11,12,14": 1,
|
|
13054
|
+
"2,6,8,12": 1,
|
|
13055
|
+
"0,2,4,5,6,8": 1,
|
|
13056
|
+
"2,6,8,10,12": 1,
|
|
13057
|
+
"0,2,4,6,8,12,13,14,15": 1,
|
|
13058
|
+
"0,4,6,8,10,11,12": 1,
|
|
13059
|
+
"0,4,8,10,11,12,13,14": 1,
|
|
13060
|
+
"0,2,3,4,6,7,8,9,10,12,13,14,15": 1,
|
|
13061
|
+
"0,2,4,5,6,8,9,10,11,12,13,14": 1,
|
|
13062
|
+
"0,3,4,7,8,9,10,12,13": 1,
|
|
13063
|
+
"0,1,2,4,6,7,8,9,10,12,13,14,15": 1,
|
|
13064
|
+
"0,2,3,4,5,6,8,9,10,11,12,13,14": 1,
|
|
13065
|
+
"0,4,6,7,8,10,12,14,15": 1,
|
|
13066
|
+
"0,2,4,6,7,8,10,12,14,15": 1,
|
|
13067
|
+
"0,1,2,3,4,5,7,8,10,11,12": 1,
|
|
13068
|
+
"0,2,4,6,7,8,9,10,11,12,14": 1,
|
|
13069
|
+
"0,1,2,4,5,6,7,8,10,12,14,15": 1,
|
|
13070
|
+
"0,2,3,4,5,7,8,9,10,11,12": 1,
|
|
13071
|
+
"0,2,3,4,6,7,8,10,11,12": 1,
|
|
13072
|
+
"0,8,9,10,11,12,13,14,15": 1,
|
|
13073
|
+
"14,15": 1,
|
|
13074
|
+
"2,4,6,8,12": 1,
|
|
13075
|
+
"2,4,8,10,12": 1,
|
|
13076
|
+
"0,2,4,8,9,12,14": 1,
|
|
13077
|
+
"0,4,5,8,9,12": 1,
|
|
13078
|
+
"0,4,8,10,14": 1,
|
|
13079
|
+
"0,6,7,12": 1,
|
|
13080
|
+
"0,4,5,8,11,12,13": 1,
|
|
13081
|
+
"0,2,4,8,9": 1,
|
|
13082
|
+
"2,4,7,8,11,12": 1,
|
|
13083
|
+
"0,4,7,8,11": 1,
|
|
13084
|
+
"0,4,8,12,14,15": 1,
|
|
13085
|
+
"0,1,2,4,5,6,7,8,9,10,12": 1,
|
|
13086
|
+
"0,1,2,3,4,5,6,7,8,9,10,12": 1,
|
|
13087
|
+
"0,2,3,4,5,6,7,8,9,10,12,13,14,15": 1,
|
|
13088
|
+
"0,3,4,7,8,9,11,12": 1,
|
|
13089
|
+
"0,1,2,3,4,5,6,7,8,10,11,12,13": 1,
|
|
13090
|
+
"0,6,8,10,12": 1,
|
|
13091
|
+
"0,2,3,4,6,8,10,11,12,14": 1,
|
|
13092
|
+
"0,2,4,6,8,10,13": 1,
|
|
13093
|
+
"2,6,8": 1,
|
|
13094
|
+
"0,2,3,4,6,7,8,12,14": 1,
|
|
13095
|
+
"2,4,6,8,10,14": 1,
|
|
13096
|
+
"0,2,4": 1,
|
|
13097
|
+
"0,2,4,5,6,7,8,9,10": 1,
|
|
13098
|
+
"0,2,4,5,6,7,8,9,10,12,13,14": 1,
|
|
13099
|
+
"0,3,6,10,14": 1,
|
|
13100
|
+
"0,14,15": 1,
|
|
13101
|
+
"0,6,7,12,14": 1,
|
|
13102
|
+
"0,6,8,10,11,12,14": 1
|
|
12743
13103
|
};
|
|
12744
13104
|
|
|
12745
13105
|
// src/compose-keys.ts
|
|
@@ -13074,8 +13434,7 @@ var resolveComposeKey = (choice, rnd = Math.random) => {
|
|
|
13074
13434
|
const target = COMPOSE_KEYS[pickedKeyId];
|
|
13075
13435
|
const targetMood = COMPOSE_MOOD_GROUPS.find((m) => m.id === target.moodId);
|
|
13076
13436
|
return {
|
|
13077
|
-
mode:
|
|
13078
|
-
// コード進行の長短制約は掛けず従来通りランダム
|
|
13437
|
+
mode: target.mode,
|
|
13079
13438
|
rootShift: target.rootShift,
|
|
13080
13439
|
keyName: target.name,
|
|
13081
13440
|
keyLabel: target.label,
|
|
@@ -13202,9 +13561,24 @@ var complementarity = (melody, submelody, opts) => {
|
|
|
13202
13561
|
}
|
|
13203
13562
|
return free / submelody.length;
|
|
13204
13563
|
};
|
|
13564
|
+
var turnRatio = (notes) => {
|
|
13565
|
+
const sorted = [...notes].sort((a, b) => a.startStep - b.startStep);
|
|
13566
|
+
let turns = 0;
|
|
13567
|
+
let intervals = 0;
|
|
13568
|
+
let prevDir = 0;
|
|
13569
|
+
for (let i2 = 1; i2 < sorted.length; i2++) {
|
|
13570
|
+
const dir = Math.sign(sorted[i2].pitchSemi - sorted[i2 - 1].pitchSemi);
|
|
13571
|
+
if (dir === 0) continue;
|
|
13572
|
+
intervals++;
|
|
13573
|
+
if (prevDir !== 0 && dir !== prevDir) turns++;
|
|
13574
|
+
prevDir = dir;
|
|
13575
|
+
}
|
|
13576
|
+
return intervals === 0 ? 0 : turns / intervals;
|
|
13577
|
+
};
|
|
13205
13578
|
var structureFeatures = (melody, submelody, opts) => {
|
|
13206
13579
|
const sigs = barSignatures(melody, opts);
|
|
13207
13580
|
return {
|
|
13581
|
+
turnRatio: turnRatio(melody),
|
|
13208
13582
|
sim1: selfSimilarity(sigs, 1),
|
|
13209
13583
|
sim2: selfSimilarity(sigs, 2),
|
|
13210
13584
|
sim4: selfSimilarity(sigs, 4),
|
|
@@ -13214,13 +13588,40 @@ var structureFeatures = (melody, submelody, opts) => {
|
|
|
13214
13588
|
complementarity: complementarity(melody, submelody, opts)
|
|
13215
13589
|
};
|
|
13216
13590
|
};
|
|
13591
|
+
var barNoteCounts = (notes, opts) => {
|
|
13592
|
+
const out = new Array(Math.max(1, opts.bars)).fill(0);
|
|
13593
|
+
for (const n of notes) {
|
|
13594
|
+
const bar = Math.floor(n.startStep / opts.stepsPerBar);
|
|
13595
|
+
if (bar >= 0 && bar < out.length) out[bar]++;
|
|
13596
|
+
}
|
|
13597
|
+
return out;
|
|
13598
|
+
};
|
|
13217
13599
|
var densityFeatures = (notes, opts) => {
|
|
13218
|
-
if (notes.length === 0)
|
|
13600
|
+
if (notes.length === 0)
|
|
13601
|
+
return {
|
|
13602
|
+
notesPerBar: 0,
|
|
13603
|
+
shortNoteRatio: 0,
|
|
13604
|
+
barDensityCv: 0,
|
|
13605
|
+
densityCliff: 0
|
|
13606
|
+
};
|
|
13219
13607
|
const eighth = opts.stepsPerBar / 8;
|
|
13220
13608
|
const short = notes.filter((n) => n.durationSteps <= eighth).length;
|
|
13609
|
+
const counts = barNoteCounts(notes, opts);
|
|
13610
|
+
const sung = counts.filter((c) => c > 0);
|
|
13611
|
+
const mean2 = sung.reduce((a, b) => a + b, 0) / Math.max(1, sung.length);
|
|
13612
|
+
const variance = sung.reduce((a, b) => a + (b - mean2) ** 2, 0) / Math.max(1, sung.length);
|
|
13613
|
+
let cliffs = 0;
|
|
13614
|
+
let pairs = 0;
|
|
13615
|
+
for (let i2 = 1; i2 < counts.length; i2++) {
|
|
13616
|
+
if (counts[i2 - 1] < 3 || counts[i2] === 0) continue;
|
|
13617
|
+
pairs++;
|
|
13618
|
+
if (counts[i2] <= counts[i2 - 1] * 0.3) cliffs++;
|
|
13619
|
+
}
|
|
13221
13620
|
return {
|
|
13222
13621
|
notesPerBar: notes.length / Math.max(1, opts.bars),
|
|
13223
|
-
shortNoteRatio: short / notes.length
|
|
13622
|
+
shortNoteRatio: short / notes.length,
|
|
13623
|
+
barDensityCv: mean2 === 0 ? 0 : Math.sqrt(variance) / mean2,
|
|
13624
|
+
densityCliff: pairs === 0 ? 0 : cliffs / pairs
|
|
13224
13625
|
};
|
|
13225
13626
|
};
|
|
13226
13627
|
var tensionFeatures = (barTension, opts) => {
|
|
@@ -13282,6 +13683,650 @@ var featureDistance = (a, b) => {
|
|
|
13282
13683
|
return Math.sqrt(sum);
|
|
13283
13684
|
};
|
|
13284
13685
|
|
|
13686
|
+
// src/compose-scales.ts
|
|
13687
|
+
var MAJOR_SCALE2 = [
|
|
13688
|
+
{ semi: 0, fifth: 0 },
|
|
13689
|
+
// C
|
|
13690
|
+
{ semi: 2, fifth: 2 },
|
|
13691
|
+
// D
|
|
13692
|
+
{ semi: 4, fifth: 4 },
|
|
13693
|
+
// E
|
|
13694
|
+
{ semi: 5, fifth: -1 },
|
|
13695
|
+
// F
|
|
13696
|
+
{ semi: 7, fifth: 1 },
|
|
13697
|
+
// G
|
|
13698
|
+
{ semi: 9, fifth: 3 },
|
|
13699
|
+
// A
|
|
13700
|
+
{ semi: 11, fifth: 5 }
|
|
13701
|
+
// B
|
|
13702
|
+
];
|
|
13703
|
+
var HARMONIC_MINOR_SCALE = [
|
|
13704
|
+
{ semi: 0, fifth: 0 },
|
|
13705
|
+
// C
|
|
13706
|
+
{ semi: 2, fifth: 2 },
|
|
13707
|
+
// D
|
|
13708
|
+
{ semi: 4, fifth: 4 },
|
|
13709
|
+
// E
|
|
13710
|
+
{ semi: 5, fifth: -1 },
|
|
13711
|
+
// F
|
|
13712
|
+
{ semi: 8, fifth: 8 },
|
|
13713
|
+
// G#
|
|
13714
|
+
{ semi: 9, fifth: 3 },
|
|
13715
|
+
// A
|
|
13716
|
+
{ semi: 11, fifth: 5 }
|
|
13717
|
+
// B
|
|
13718
|
+
];
|
|
13719
|
+
var HUNGARIAN_SCALE = [
|
|
13720
|
+
{ semi: 0, fifth: 0 },
|
|
13721
|
+
// C
|
|
13722
|
+
{ semi: 3, fifth: 9 },
|
|
13723
|
+
// D#
|
|
13724
|
+
{ semi: 4, fifth: 4 },
|
|
13725
|
+
// E
|
|
13726
|
+
{ semi: 5, fifth: -1 },
|
|
13727
|
+
// F
|
|
13728
|
+
{ semi: 8, fifth: 8 },
|
|
13729
|
+
// G#
|
|
13730
|
+
{ semi: 9, fifth: 3 },
|
|
13731
|
+
// A
|
|
13732
|
+
{ semi: 11, fifth: 5 }
|
|
13733
|
+
// B
|
|
13734
|
+
];
|
|
13735
|
+
var BLUES_SCALE = [
|
|
13736
|
+
{ semi: 0, fifth: 0 },
|
|
13737
|
+
// C
|
|
13738
|
+
{ semi: 3, fifth: -3 },
|
|
13739
|
+
// Eb
|
|
13740
|
+
{ semi: 5, fifth: -1 },
|
|
13741
|
+
// F
|
|
13742
|
+
{ semi: 6, fifth: -6 },
|
|
13743
|
+
// Gb(ブルーノート)
|
|
13744
|
+
{ semi: 7, fifth: 1 },
|
|
13745
|
+
// G
|
|
13746
|
+
{ semi: 10, fifth: -2 }
|
|
13747
|
+
// Bb
|
|
13748
|
+
];
|
|
13749
|
+
var RYUKYU_CENTER = {
|
|
13750
|
+
tonic: "C",
|
|
13751
|
+
half: "G",
|
|
13752
|
+
deceptive: "Em",
|
|
13753
|
+
tonicPattern: /^C(?![#b]|m)/,
|
|
13754
|
+
a: [
|
|
13755
|
+
["C", "F", "G", "C"],
|
|
13756
|
+
["C", "C", "F", "G"],
|
|
13757
|
+
["F", "G", "C", "C"],
|
|
13758
|
+
["C", "G", "F", "G"],
|
|
13759
|
+
["CM7", "F", "G", "C"],
|
|
13760
|
+
["C", "F", "C", "G"],
|
|
13761
|
+
["C", "Em", "F", "G"],
|
|
13762
|
+
["F", "C", "G", "C"]
|
|
13763
|
+
],
|
|
13764
|
+
b: [
|
|
13765
|
+
["F", "G", "Em", "C"],
|
|
13766
|
+
["F", "G", "C", "G"],
|
|
13767
|
+
["G", "F", "C", "C"],
|
|
13768
|
+
["FM7", "G", "Em", "F"],
|
|
13769
|
+
["C", "G", "F", "C"],
|
|
13770
|
+
["F", "Em", "F", "G"]
|
|
13771
|
+
],
|
|
13772
|
+
c: [
|
|
13773
|
+
["Em", "F", "G", "C"],
|
|
13774
|
+
["F", "C", "G", "Em"],
|
|
13775
|
+
["C", "Em", "F", "G"]
|
|
13776
|
+
]
|
|
13777
|
+
};
|
|
13778
|
+
var MIYAKOBUSHI_CENTER = {
|
|
13779
|
+
tonic: "Em",
|
|
13780
|
+
half: "Am",
|
|
13781
|
+
deceptive: "F",
|
|
13782
|
+
tonicPattern: /^E(?:m|sus)/,
|
|
13783
|
+
a: [
|
|
13784
|
+
["Em", "F", "Em", "Em"],
|
|
13785
|
+
["Esus4", "F", "Esus4", "Em"],
|
|
13786
|
+
["Em", "Am", "F", "Em"],
|
|
13787
|
+
["Am", "Em", "F", "Em"],
|
|
13788
|
+
["Em", "F", "Am", "Em"],
|
|
13789
|
+
["Em", "Em", "F", "F"],
|
|
13790
|
+
["Am", "F", "Em", "Em"],
|
|
13791
|
+
["Em", "FM7", "Am", "Em"]
|
|
13792
|
+
],
|
|
13793
|
+
b: [
|
|
13794
|
+
["F", "Am", "Em", "Em"],
|
|
13795
|
+
["Am", "F", "Em", "Em"],
|
|
13796
|
+
["F", "Em", "Am", "Em"],
|
|
13797
|
+
["FM7", "Am", "F", "Em"],
|
|
13798
|
+
["Am", "Em", "F", "Am"],
|
|
13799
|
+
["F", "Am", "F", "Em"]
|
|
13800
|
+
],
|
|
13801
|
+
c: [
|
|
13802
|
+
["Am", "Em", "F", "Am"],
|
|
13803
|
+
["F", "Am", "Esus4", "Em"],
|
|
13804
|
+
["Am", "F", "Em", "Em"]
|
|
13805
|
+
]
|
|
13806
|
+
};
|
|
13807
|
+
var RITSU_CENTER = {
|
|
13808
|
+
tonic: "Dsus4",
|
|
13809
|
+
half: "G",
|
|
13810
|
+
deceptive: "Em",
|
|
13811
|
+
tonicPattern: /^Dsus/,
|
|
13812
|
+
a: [
|
|
13813
|
+
["Dsus4", "G", "Dsus4", "Dsus4"],
|
|
13814
|
+
["Dsus4", "Em", "G", "Dsus4"],
|
|
13815
|
+
["G", "Dsus4", "Em", "Dsus4"],
|
|
13816
|
+
["Dsus4", "G", "Em", "G"],
|
|
13817
|
+
["Em", "G", "Dsus4", "Dsus4"],
|
|
13818
|
+
["Dsus4", "Em7", "G", "Dsus4"],
|
|
13819
|
+
["G", "Em", "Dsus4", "G"],
|
|
13820
|
+
["Dsus4", "Am", "G", "Dsus4"]
|
|
13821
|
+
],
|
|
13822
|
+
b: [
|
|
13823
|
+
["G", "Em", "Dsus4", "Dsus4"],
|
|
13824
|
+
["Em", "G", "Em", "Dsus4"],
|
|
13825
|
+
["G", "Am", "Em", "Dsus4"],
|
|
13826
|
+
["Em7", "G", "Dsus4", "Dsus4"],
|
|
13827
|
+
["Am", "G", "Em", "Dsus4"],
|
|
13828
|
+
["Dsus4", "Em", "G", "Em"]
|
|
13829
|
+
],
|
|
13830
|
+
c: [
|
|
13831
|
+
["Em", "Dsus4", "G", "Em"],
|
|
13832
|
+
["G", "Em7", "Am", "G"],
|
|
13833
|
+
["Am", "G", "Em", "Dsus4"]
|
|
13834
|
+
]
|
|
13835
|
+
};
|
|
13836
|
+
var HARMONIC_MINOR_CENTER = {
|
|
13837
|
+
tonic: "Am",
|
|
13838
|
+
half: "E7",
|
|
13839
|
+
deceptive: "F",
|
|
13840
|
+
tonicPattern: /^Am/,
|
|
13841
|
+
a: [
|
|
13842
|
+
["Am", "Dm", "E7", "Am"],
|
|
13843
|
+
// i-iv-V7-i。和声的短音階の基本形
|
|
13844
|
+
["Am", "F", "E7", "Am"],
|
|
13845
|
+
["Am", "E7", "Am", "Am"],
|
|
13846
|
+
["Dm", "E7", "Am", "Am"],
|
|
13847
|
+
["Am", "AmM7", "Dm", "E7"],
|
|
13848
|
+
// 主和音に導音を重ねたクリシェ
|
|
13849
|
+
["Am", "F", "Dm", "E7"],
|
|
13850
|
+
["F", "E7", "Am", "Am"],
|
|
13851
|
+
["Am", "Bm7-5", "E7", "Am"]
|
|
13852
|
+
],
|
|
13853
|
+
b: [
|
|
13854
|
+
["Dm", "E7", "Am", "Am"],
|
|
13855
|
+
["F", "E7", "Am", "E7"],
|
|
13856
|
+
["Dm7", "G#dim", "Am", "E7"],
|
|
13857
|
+
["F", "Dm", "E7", "Am"],
|
|
13858
|
+
["Am", "Dm", "Bm7-5", "E7"],
|
|
13859
|
+
["FM7", "E7", "Am", "Am"]
|
|
13860
|
+
],
|
|
13861
|
+
c: [
|
|
13862
|
+
["Dm", "Am", "Bm7-5", "E7"],
|
|
13863
|
+
["F", "C+", "Dm", "E7"],
|
|
13864
|
+
["Am", "F", "Dm", "E7"]
|
|
13865
|
+
]
|
|
13866
|
+
};
|
|
13867
|
+
var HIJAZ_CENTER = {
|
|
13868
|
+
tonic: "E",
|
|
13869
|
+
half: "F",
|
|
13870
|
+
deceptive: "Am",
|
|
13871
|
+
tonicPattern: /^E(?![#b]|m)/,
|
|
13872
|
+
a: [
|
|
13873
|
+
["E", "F", "E", "E"],
|
|
13874
|
+
// I-♭II。ヒジャーズの顔
|
|
13875
|
+
["E7", "F", "E", "E"],
|
|
13876
|
+
["Am", "F", "E", "E"],
|
|
13877
|
+
["E", "F", "Dm", "E"],
|
|
13878
|
+
["F", "E", "F", "E"],
|
|
13879
|
+
["Dm", "E", "F", "E"],
|
|
13880
|
+
["E7", "Am", "F", "E"],
|
|
13881
|
+
["E", "Dm", "F", "E"]
|
|
13882
|
+
],
|
|
13883
|
+
b: [
|
|
13884
|
+
["F", "E", "Am", "E"],
|
|
13885
|
+
["Dm", "C+", "F", "E"],
|
|
13886
|
+
["Am", "Dm", "F", "E"],
|
|
13887
|
+
["F", "Dm", "E", "E"],
|
|
13888
|
+
["E7", "F", "Dm", "E"],
|
|
13889
|
+
["Bm7-5", "E7", "Am", "E"]
|
|
13890
|
+
],
|
|
13891
|
+
c: [
|
|
13892
|
+
["Am", "Dm", "F", "E"],
|
|
13893
|
+
["Dm", "Am", "F", "E7"],
|
|
13894
|
+
["F", "C+", "Dm", "E"]
|
|
13895
|
+
]
|
|
13896
|
+
};
|
|
13897
|
+
var HUNGARIAN_CENTER = {
|
|
13898
|
+
tonic: "Am",
|
|
13899
|
+
half: "E",
|
|
13900
|
+
deceptive: "F",
|
|
13901
|
+
tonicPattern: /^Am/,
|
|
13902
|
+
a: [
|
|
13903
|
+
["Am", "E", "Am", "Am"],
|
|
13904
|
+
["Am", "F", "E", "Am"],
|
|
13905
|
+
["Am", "AmM7", "F", "E"],
|
|
13906
|
+
["F", "E", "Am", "Am"],
|
|
13907
|
+
["Am", "Fm", "E", "Am"],
|
|
13908
|
+
// ♭VIm。増2度を和音の側でも鳴らす
|
|
13909
|
+
["Am", "E", "F", "E"],
|
|
13910
|
+
["FM7", "E", "Am", "Am"],
|
|
13911
|
+
["Am", "C+", "F", "E"]
|
|
13912
|
+
],
|
|
13913
|
+
b: [
|
|
13914
|
+
["F", "E", "Am", "E"],
|
|
13915
|
+
["Fm", "E", "Am", "Am"],
|
|
13916
|
+
["Am", "F", "C+", "E"],
|
|
13917
|
+
["FM7", "Am", "F", "E"],
|
|
13918
|
+
["E", "F", "E", "Am"],
|
|
13919
|
+
["Am", "AmM7", "Fm", "E"]
|
|
13920
|
+
],
|
|
13921
|
+
c: [
|
|
13922
|
+
["F", "Am", "Fm", "E"],
|
|
13923
|
+
["C+", "F", "Am", "E"],
|
|
13924
|
+
["Am", "Fm", "F", "E"]
|
|
13925
|
+
]
|
|
13926
|
+
};
|
|
13927
|
+
var BLUES_CENTER = {
|
|
13928
|
+
tonic: "C7",
|
|
13929
|
+
half: "G7",
|
|
13930
|
+
deceptive: "F7",
|
|
13931
|
+
tonicPattern: /^C7/,
|
|
13932
|
+
a: [
|
|
13933
|
+
["C7", "C7", "C7", "C7"],
|
|
13934
|
+
// 12小節ブルースの1〜4小節
|
|
13935
|
+
["C7", "F7", "C7", "C7"],
|
|
13936
|
+
["C7", "C7", "F7", "F7"],
|
|
13937
|
+
["F7", "F7", "C7", "C7"],
|
|
13938
|
+
// 5〜8小節
|
|
13939
|
+
["C7", "F7", "C7", "G7"],
|
|
13940
|
+
["C7", "C7", "G7", "F7"],
|
|
13941
|
+
["C7", "F7", "G7", "C7"],
|
|
13942
|
+
["F7", "C7", "G7", "C7"]
|
|
13943
|
+
],
|
|
13944
|
+
b: [
|
|
13945
|
+
["F7", "F7", "C7", "C7"],
|
|
13946
|
+
["G7", "F7", "C7", "C7"],
|
|
13947
|
+
// 9〜12小節(ターンアラウンド)
|
|
13948
|
+
["F7", "G7", "C7", "C7"],
|
|
13949
|
+
["C7", "F7", "G7", "C7"],
|
|
13950
|
+
["F7", "C7", "G7", "F7"],
|
|
13951
|
+
["G7", "G7", "F7", "C7"]
|
|
13952
|
+
],
|
|
13953
|
+
c: [
|
|
13954
|
+
["G7", "F7", "C7", "G7"],
|
|
13955
|
+
["F7", "F7", "G7", "G7"],
|
|
13956
|
+
["C7", "C7", "F7", "G7"]
|
|
13957
|
+
]
|
|
13958
|
+
};
|
|
13959
|
+
var COMPOSE_SCALES = {
|
|
13960
|
+
yo: {
|
|
13961
|
+
id: "yo",
|
|
13962
|
+
label: "\u967D\u97F3\u968E\uFF08\u9577\u8ABF\u30DA\u30F3\u30BF\u30C8\u30CB\u30C3\u30AF\uFF09",
|
|
13963
|
+
tonic: 0,
|
|
13964
|
+
core: [0, 1, 2, 4, 5],
|
|
13965
|
+
// ド レ ミ ソ ラ
|
|
13966
|
+
minorish: false,
|
|
13967
|
+
strict: false,
|
|
13968
|
+
description: "J-POP\u306E\u6A19\u6E96\u3002\u660E\u308B\u304F\u7D20\u76F4\u3067\u6B4C\u3044\u3084\u3059\u3044\u3002\u5F93\u6765\u306E\u9577\u8ABF\u3068\u540C\u3058"
|
|
13969
|
+
},
|
|
13970
|
+
minyo: {
|
|
13971
|
+
id: "minyo",
|
|
13972
|
+
label: "\u6C11\u8B21\u97F3\u968E\uFF08\u77ED\u8ABF\u30DA\u30F3\u30BF\u30C8\u30CB\u30C3\u30AF\uFF09",
|
|
13973
|
+
tonic: 5,
|
|
13974
|
+
core: [5, 0, 1, 2, 4],
|
|
13975
|
+
// ラ ド レ ミ ソ
|
|
13976
|
+
minorish: true,
|
|
13977
|
+
strict: false,
|
|
13978
|
+
description: "\u308F\u3089\u3079\u6B4C\u30FB\u6C11\u8B21\u306E\u97F3\u968E\u3002\u7FF3\u308A\u304C\u3042\u308B\u304C\u6697\u3059\u304E\u306A\u3044\u3002\u5F93\u6765\u306E\u77ED\u8ABF\u3068\u540C\u3058"
|
|
13979
|
+
},
|
|
13980
|
+
ritsu: {
|
|
13981
|
+
id: "ritsu",
|
|
13982
|
+
label: "\u5F8B\u97F3\u968E",
|
|
13983
|
+
tonic: 1,
|
|
13984
|
+
core: [1, 2, 4, 5, 6],
|
|
13985
|
+
// レ ミ ソ ラ シ
|
|
13986
|
+
minorish: true,
|
|
13987
|
+
strict: true,
|
|
13988
|
+
center: RITSU_CENTER,
|
|
13989
|
+
description: "\u96C5\u697D\u30FB\u58F0\u660E\u306E\u97F3\u968E\u3002\u534A\u97F3\u3092\u542B\u307E\u305A\u3001\u5E73\u3089\u3067\u8358\u91CD\u306B\u6D41\u308C\u308B"
|
|
13990
|
+
},
|
|
13991
|
+
miyakobushi: {
|
|
13992
|
+
id: "miyakobushi",
|
|
13993
|
+
label: "\u90FD\u7BC0\u97F3\u968E\uFF08\u9670\u97F3\u968E\uFF09",
|
|
13994
|
+
tonic: 2,
|
|
13995
|
+
core: [2, 3, 5, 6, 0],
|
|
13996
|
+
// ミ ファ ラ シ ド
|
|
13997
|
+
minorish: true,
|
|
13998
|
+
strict: true,
|
|
13999
|
+
center: MIYAKOBUSHI_CENTER,
|
|
14000
|
+
description: "\u300E\u3055\u304F\u3089\u3055\u304F\u3089\u300F\u306E\u97F3\u968E\u3002\u4E3B\u97F3\u306E\u3059\u3050\u4E0A\u304C\u534A\u97F3\u3067\u3001\u7FF3\u308A\u304C\u6FC3\u3044"
|
|
14001
|
+
},
|
|
14002
|
+
ryukyu: {
|
|
14003
|
+
id: "ryukyu",
|
|
14004
|
+
label: "\u7409\u7403\u97F3\u968E",
|
|
14005
|
+
tonic: 0,
|
|
14006
|
+
core: [0, 2, 3, 4, 6],
|
|
14007
|
+
// ド ミ ファ ソ シ
|
|
14008
|
+
minorish: false,
|
|
14009
|
+
strict: true,
|
|
14010
|
+
center: RYUKYU_CENTER,
|
|
14011
|
+
description: "\u6C96\u7E04\u97F3\u968E\u3002\u30EC\u3068\u30E9\u3092\u629C\u304D\u3001\u30D5\u30A1\u3068\u30B7\u3092\u67F1\u306B\u3059\u308B\u3002\u660E\u308B\u304F\u8DF3\u306D\u308B"
|
|
14012
|
+
},
|
|
14013
|
+
dorian: {
|
|
14014
|
+
id: "dorian",
|
|
14015
|
+
label: "\u30C9\u30EA\u30A2\u30F3",
|
|
14016
|
+
tonic: 1,
|
|
14017
|
+
core: [1, 3, 4, 5, 0],
|
|
14018
|
+
// レ ファ ソ ラ ド
|
|
14019
|
+
minorish: true,
|
|
14020
|
+
strict: false,
|
|
14021
|
+
description: "\u77ED\u8ABF\u3060\u304C6\u5EA6\u304C\u660E\u308B\u3044\u3002\u30B1\u30EB\u30C8\u30FB\u30ED\u30C3\u30AF\u30FB\u30B7\u30C6\u30A3\u30DD\u30C3\u30D7"
|
|
14022
|
+
},
|
|
14023
|
+
phrygian: {
|
|
14024
|
+
id: "phrygian",
|
|
14025
|
+
label: "\u30D5\u30EA\u30B8\u30A2\u30F3",
|
|
14026
|
+
tonic: 2,
|
|
14027
|
+
core: [2, 3, 5, 6, 1],
|
|
14028
|
+
// ミ ファ ラ シ レ
|
|
14029
|
+
minorish: true,
|
|
14030
|
+
strict: false,
|
|
14031
|
+
description: "\u4E3B\u97F3\u306E\u4E0A\u304C\u534A\u97F3\u3002\u30B9\u30D1\u30CB\u30C3\u30B7\u30E5\uFF0F\u30E1\u30BF\u30EB\u306E\u7DCA\u8FEB\u3057\u305F\u97FF\u304D"
|
|
14032
|
+
},
|
|
14033
|
+
lydian: {
|
|
14034
|
+
id: "lydian",
|
|
14035
|
+
label: "\u30EA\u30C7\u30A3\u30A2\u30F3",
|
|
14036
|
+
tonic: 3,
|
|
14037
|
+
core: [3, 4, 6, 0, 2],
|
|
14038
|
+
// ファ ソ シ ド ミ
|
|
14039
|
+
minorish: false,
|
|
14040
|
+
strict: false,
|
|
14041
|
+
description: "4\u5EA6\u304C\u9AD8\u304F\u3001\u6D6E\u904A\u3057\u3066\u5E83\u304C\u308B\u3002\u6620\u753B\u97F3\u697D\u30FB\u30B2\u30FC\u30E0\u306E\u7A7A\u306E\u8272"
|
|
14042
|
+
},
|
|
14043
|
+
mixolydian: {
|
|
14044
|
+
id: "mixolydian",
|
|
14045
|
+
label: "\u30DF\u30AF\u30BD\u30EA\u30C7\u30A3\u30A2\u30F3",
|
|
14046
|
+
tonic: 4,
|
|
14047
|
+
core: [4, 5, 0, 1, 3],
|
|
14048
|
+
// ソ ラ ド レ ファ
|
|
14049
|
+
minorish: false,
|
|
14050
|
+
strict: false,
|
|
14051
|
+
description: "\u9577\u8ABF\u3060\u304C7\u5EA6\u304C\u4F4E\u3044\u3002\u30D6\u30EB\u30FC\u30B9\u30ED\u30C3\u30AF\u30FB\u6C11\u65CF\u97F3\u697D\u306E\u571F\u304F\u3055\u3055"
|
|
14052
|
+
},
|
|
14053
|
+
harmonic_minor: {
|
|
14054
|
+
id: "harmonic_minor",
|
|
14055
|
+
label: "\u548C\u58F0\u7684\u77ED\u97F3\u968E",
|
|
14056
|
+
tonic: 5,
|
|
14057
|
+
parent: HARMONIC_MINOR_SCALE,
|
|
14058
|
+
core: [5, 0, 1, 2, 4],
|
|
14059
|
+
// ラ ド レ ミ ソ♯
|
|
14060
|
+
minorish: true,
|
|
14061
|
+
strict: false,
|
|
14062
|
+
center: HARMONIC_MINOR_CENTER,
|
|
14063
|
+
description: "\u5C0E\u97F3\u30BD\u266F\u3092\u6301\u3064\u77ED\u8ABF\u3002\u58972\u5EA6\u304C\u6CE3\u304D\u3092\u4F5C\u308B\u3002\u30AF\u30E9\u30B7\u30C3\u30AF\u30FBV\u7CFB\u30FB\u5287\u4F34"
|
|
14064
|
+
},
|
|
14065
|
+
hijaz: {
|
|
14066
|
+
id: "hijaz",
|
|
14067
|
+
label: "\u30D2\u30B8\u30E3\u30FC\u30BA\uFF08\u30D5\u30EA\u30B8\u30A2\u30F3\u30FB\u30C9\u30DF\u30CA\u30F3\u30C8\uFF09",
|
|
14068
|
+
tonic: 2,
|
|
14069
|
+
parent: HARMONIC_MINOR_SCALE,
|
|
14070
|
+
core: [2, 3, 4, 5, 6],
|
|
14071
|
+
// ミ ファ ソ♯ ラ シ
|
|
14072
|
+
minorish: false,
|
|
14073
|
+
strict: false,
|
|
14074
|
+
center: HIJAZ_CENTER,
|
|
14075
|
+
description: "\u4E3B\u97F3\u306E\u4E0A\u304C\u534A\u97F3\u3001\u4E3B\u548C\u97F3\u306F\u9577\u4E09\u548C\u97F3\u3002\u4E2D\u6771\u30FB\u30B9\u30D1\u30CB\u30C3\u30B7\u30E5\u30FB\u30E1\u30BF\u30EB"
|
|
14076
|
+
},
|
|
14077
|
+
hungarian: {
|
|
14078
|
+
id: "hungarian",
|
|
14079
|
+
label: "\u30CF\u30F3\u30AC\u30EA\u30A2\u30F3\u30FB\u30DE\u30A4\u30CA\u30FC\uFF08\u30B8\u30D7\u30B7\u30FC\uFF09",
|
|
14080
|
+
tonic: 5,
|
|
14081
|
+
parent: HUNGARIAN_SCALE,
|
|
14082
|
+
core: [5, 0, 1, 2, 4],
|
|
14083
|
+
// ラ ド レ♯ ミ ソ♯
|
|
14084
|
+
minorish: true,
|
|
14085
|
+
strict: false,
|
|
14086
|
+
center: HUNGARIAN_CENTER,
|
|
14087
|
+
description: "\u58972\u5EA6\u304C2\u304B\u6240\u3002\u97F3\u968E\u306E\u4E2D\u3067\u3044\u3061\u3070\u3093\u8DF3\u306D\u305F\u3001\u7570\u56FD\u3081\u3044\u305F\u97FF\u304D"
|
|
14088
|
+
},
|
|
14089
|
+
blues: {
|
|
14090
|
+
id: "blues",
|
|
14091
|
+
label: "\u30D6\u30EB\u30FC\u30B9\u97F3\u968E",
|
|
14092
|
+
tonic: 0,
|
|
14093
|
+
parent: BLUES_SCALE,
|
|
14094
|
+
core: [0, 1, 2, 4, 5],
|
|
14095
|
+
// ド ミ♭ ファ ソ シ♭
|
|
14096
|
+
minorish: true,
|
|
14097
|
+
strict: true,
|
|
14098
|
+
center: BLUES_CENTER,
|
|
14099
|
+
description: "\u30D6\u30EB\u30FC\u30CE\u30FC\u30C8\u5165\u308A\u306E6\u97F3\u97F3\u968E\u3002\u77ED3\u5EA6\u3067\u6B4C\u3044\u3001\u4F34\u594F\u306F\u95773\u5EA6\u3067\u9CF4\u308B"
|
|
14100
|
+
}
|
|
14101
|
+
};
|
|
14102
|
+
var COMPOSE_SCALE_IDS = Object.keys(
|
|
14103
|
+
COMPOSE_SCALES
|
|
14104
|
+
);
|
|
14105
|
+
var TONIC_CENTERS = {
|
|
14106
|
+
// --- レ(律・ドリアン) ---
|
|
14107
|
+
1: {
|
|
14108
|
+
tonic: "Dm",
|
|
14109
|
+
half: "G",
|
|
14110
|
+
deceptive: "F",
|
|
14111
|
+
tonicPattern: /^Dm/,
|
|
14112
|
+
a: [
|
|
14113
|
+
["Dm", "G", "Dm", "Dm"],
|
|
14114
|
+
// i-IV の往復。ドリアンの顔
|
|
14115
|
+
["Dm", "Am", "G", "Dm"],
|
|
14116
|
+
["Dm", "C", "G", "Dm"],
|
|
14117
|
+
["Dm7", "G", "Dm7", "C"],
|
|
14118
|
+
["Dm", "F", "C", "G"],
|
|
14119
|
+
["Dm", "Em", "F", "G"],
|
|
14120
|
+
["Dm", "G", "F", "C"],
|
|
14121
|
+
["Dm7", "Em7", "FM7", "G"]
|
|
14122
|
+
],
|
|
14123
|
+
b: [
|
|
14124
|
+
["F", "G", "Am", "Dm"],
|
|
14125
|
+
["C", "G", "Dm", "Dm"],
|
|
14126
|
+
["G", "F", "C", "Dm"],
|
|
14127
|
+
["Am", "G", "F", "Dm"],
|
|
14128
|
+
["FM7", "G", "Em7", "Dm7"],
|
|
14129
|
+
["Dm", "G", "C", "Am"]
|
|
14130
|
+
],
|
|
14131
|
+
c: [
|
|
14132
|
+
["Am", "Dm", "G", "C"],
|
|
14133
|
+
["F", "Em", "Dm", "G"],
|
|
14134
|
+
["Dm", "Am", "Em", "G"]
|
|
14135
|
+
]
|
|
14136
|
+
},
|
|
14137
|
+
// --- ミ(都節・フリジアン) ---
|
|
14138
|
+
2: {
|
|
14139
|
+
tonic: "Em",
|
|
14140
|
+
half: "Am",
|
|
14141
|
+
deceptive: "C",
|
|
14142
|
+
tonicPattern: /^Em/,
|
|
14143
|
+
a: [
|
|
14144
|
+
["Em", "F", "Em", "Em"],
|
|
14145
|
+
// i-♭II。フリジアン/都節の顔
|
|
14146
|
+
["Em", "Am", "F", "Em"],
|
|
14147
|
+
["Am", "Em", "F", "Em"],
|
|
14148
|
+
["Em", "F", "G", "Em"],
|
|
14149
|
+
["Em", "Em", "F", "F"],
|
|
14150
|
+
["Em", "C", "F", "Em"],
|
|
14151
|
+
["Am", "F", "Em", "Em"],
|
|
14152
|
+
["Em7", "FM7", "Em7", "Am7"]
|
|
14153
|
+
],
|
|
14154
|
+
b: [
|
|
14155
|
+
["F", "G", "Am", "Em"],
|
|
14156
|
+
["Am", "G", "F", "Em"],
|
|
14157
|
+
["F", "Em", "Am", "Em"],
|
|
14158
|
+
["C", "F", "Em", "Em"],
|
|
14159
|
+
["FM7", "G", "Em7", "Am"],
|
|
14160
|
+
["Am", "Em", "F", "G"]
|
|
14161
|
+
],
|
|
14162
|
+
c: [
|
|
14163
|
+
["Am", "Em", "F", "C"],
|
|
14164
|
+
["C", "G", "Am", "Em"],
|
|
14165
|
+
["F", "C", "Am", "Em"]
|
|
14166
|
+
]
|
|
14167
|
+
},
|
|
14168
|
+
// --- ファ(リディアン) ---
|
|
14169
|
+
3: {
|
|
14170
|
+
tonic: "FM7",
|
|
14171
|
+
half: "C",
|
|
14172
|
+
deceptive: "Dm",
|
|
14173
|
+
tonicPattern: /^F(?![#b]|m)/,
|
|
14174
|
+
a: [
|
|
14175
|
+
["FM7", "G", "FM7", "FM7"],
|
|
14176
|
+
// I-II。リディアンの顔(♯4 が G の3度に居る)
|
|
14177
|
+
["FM7", "G", "Em", "Am"],
|
|
14178
|
+
["F", "G", "C", "F"],
|
|
14179
|
+
["FM7", "G", "Am", "F"],
|
|
14180
|
+
["F", "C", "G", "F"],
|
|
14181
|
+
["FM7", "Em7", "Dm7", "G"],
|
|
14182
|
+
["F", "G", "F", "C"],
|
|
14183
|
+
["FM7", "G", "Dm7", "F"]
|
|
14184
|
+
],
|
|
14185
|
+
b: [
|
|
14186
|
+
["G", "F", "C", "F"],
|
|
14187
|
+
["Am", "G", "FM7", "FM7"],
|
|
14188
|
+
["C", "G", "Am", "F"],
|
|
14189
|
+
["G", "Em", "Am", "F"],
|
|
14190
|
+
["Dm7", "G", "FM7", "FM7"],
|
|
14191
|
+
["FM7", "G", "Em7", "F"]
|
|
14192
|
+
],
|
|
14193
|
+
c: [
|
|
14194
|
+
["Dm", "Am", "F", "G"],
|
|
14195
|
+
["Am", "Em", "F", "G"],
|
|
14196
|
+
["C", "Am", "Dm", "F"]
|
|
14197
|
+
]
|
|
14198
|
+
},
|
|
14199
|
+
// --- ソ(ミクソリディアン) ---
|
|
14200
|
+
4: {
|
|
14201
|
+
tonic: "G",
|
|
14202
|
+
half: "Dm",
|
|
14203
|
+
deceptive: "Em",
|
|
14204
|
+
tonicPattern: /^G(?![#b]|m)/,
|
|
14205
|
+
a: [
|
|
14206
|
+
["G", "F", "C", "G"],
|
|
14207
|
+
// I-♭VII-IV。ミクソリディアンの顔
|
|
14208
|
+
["G", "C", "F", "G"],
|
|
14209
|
+
["G", "F", "G", "G"],
|
|
14210
|
+
["C", "G", "F", "G"],
|
|
14211
|
+
["G", "Dm", "F", "G"],
|
|
14212
|
+
["G", "Am", "F", "G"],
|
|
14213
|
+
["G", "F", "Dm", "C"],
|
|
14214
|
+
["G", "C", "G", "F"]
|
|
14215
|
+
],
|
|
14216
|
+
b: [
|
|
14217
|
+
["F", "C", "G", "G"],
|
|
14218
|
+
["Am", "F", "C", "G"],
|
|
14219
|
+
["C", "Dm", "F", "G"],
|
|
14220
|
+
["Em", "F", "C", "G"],
|
|
14221
|
+
["F", "G", "Am", "G"],
|
|
14222
|
+
["Dm7", "F", "C", "G"]
|
|
14223
|
+
],
|
|
14224
|
+
c: [
|
|
14225
|
+
["Am", "Em", "F", "G"],
|
|
14226
|
+
["C", "Am", "Dm", "G"],
|
|
14227
|
+
["Em", "Am", "F", "C"]
|
|
14228
|
+
]
|
|
14229
|
+
}
|
|
14230
|
+
};
|
|
14231
|
+
var scaleDegrees = (scale) => scale.parent ?? MAJOR_SCALE2;
|
|
14232
|
+
var scaleSize = (scale) => scaleDegrees(scale).length;
|
|
14233
|
+
var degreeToPitch = (scale, degree) => {
|
|
14234
|
+
const list = scaleDegrees(scale);
|
|
14235
|
+
const size = list.length;
|
|
14236
|
+
const index = (degree % size + size) % size;
|
|
14237
|
+
const octave = Math.floor(degree / size);
|
|
14238
|
+
const d = list[index];
|
|
14239
|
+
return { semi: d.semi + octave * 12, fifth: d.fifth };
|
|
14240
|
+
};
|
|
14241
|
+
var semitoneToDegree = (scale, semi) => {
|
|
14242
|
+
const list = scaleDegrees(scale);
|
|
14243
|
+
const octave = Math.floor(semi / 12);
|
|
14244
|
+
const within = semi - octave * 12;
|
|
14245
|
+
let best = 0;
|
|
14246
|
+
let bestDist = Number.POSITIVE_INFINITY;
|
|
14247
|
+
for (let i2 = 0; i2 < list.length; i2++) {
|
|
14248
|
+
const dist = Math.abs(list[i2].semi - within);
|
|
14249
|
+
if (dist < bestDist) {
|
|
14250
|
+
bestDist = dist;
|
|
14251
|
+
best = i2;
|
|
14252
|
+
}
|
|
14253
|
+
}
|
|
14254
|
+
return octave * list.length + best;
|
|
14255
|
+
};
|
|
14256
|
+
var walk = (scale, semi, delta) => degreeToPitch(scale, semitoneToDegree(scale, semi) + delta).semi;
|
|
14257
|
+
var scaleFifth = (scale, semi) => degreeToPitch(scale, semitoneToDegree(scale, semi)).fifth;
|
|
14258
|
+
var SCALE_PCS = /* @__PURE__ */ new Map();
|
|
14259
|
+
var scalePcs = (scale) => {
|
|
14260
|
+
const hit = SCALE_PCS.get(scale.id);
|
|
14261
|
+
if (hit) return hit;
|
|
14262
|
+
const set = new Set(
|
|
14263
|
+
scaleDegrees(scale).map((d) => (d.semi % 12 + 12) % 12)
|
|
14264
|
+
);
|
|
14265
|
+
SCALE_PCS.set(scale.id, set);
|
|
14266
|
+
return set;
|
|
14267
|
+
};
|
|
14268
|
+
var CORE_SORTED = /* @__PURE__ */ new Map();
|
|
14269
|
+
var sortedCore = (scale) => {
|
|
14270
|
+
const hit = CORE_SORTED.get(scale.id);
|
|
14271
|
+
if (hit) return hit;
|
|
14272
|
+
const sorted = [...scale.core].sort((a, b) => a - b);
|
|
14273
|
+
CORE_SORTED.set(scale.id, sorted);
|
|
14274
|
+
return sorted;
|
|
14275
|
+
};
|
|
14276
|
+
var CORE_PCS = /* @__PURE__ */ new Map();
|
|
14277
|
+
var corePcs = (scale) => {
|
|
14278
|
+
const hit = CORE_PCS.get(scale.id);
|
|
14279
|
+
if (hit) return hit;
|
|
14280
|
+
const list = scaleDegrees(scale);
|
|
14281
|
+
const set = new Set(scale.core.map((d) => (list[d].semi % 12 + 12) % 12));
|
|
14282
|
+
CORE_PCS.set(scale.id, set);
|
|
14283
|
+
return set;
|
|
14284
|
+
};
|
|
14285
|
+
var isCoreDegree = (scale, degree) => {
|
|
14286
|
+
const size = scaleSize(scale);
|
|
14287
|
+
return sortedCore(scale).includes((degree % size + size) % size);
|
|
14288
|
+
};
|
|
14289
|
+
var coreToDegree = (scale, step) => {
|
|
14290
|
+
const sorted = sortedCore(scale);
|
|
14291
|
+
const n = sorted.length;
|
|
14292
|
+
const index = (step % n + n) % n;
|
|
14293
|
+
const octave = Math.floor(step / n);
|
|
14294
|
+
return sorted[index] + octave * scaleSize(scale);
|
|
14295
|
+
};
|
|
14296
|
+
var degreeToCore = (scale, degree) => {
|
|
14297
|
+
const sorted = sortedCore(scale);
|
|
14298
|
+
const size = scaleSize(scale);
|
|
14299
|
+
const index = (degree % size + size) % size;
|
|
14300
|
+
const octave = Math.floor(degree / size);
|
|
14301
|
+
let best = 0;
|
|
14302
|
+
let bestDist = Number.POSITIVE_INFINITY;
|
|
14303
|
+
for (let i2 = 0; i2 < sorted.length; i2++) {
|
|
14304
|
+
const dist = Math.abs(sorted[i2] - index);
|
|
14305
|
+
if (dist < bestDist) {
|
|
14306
|
+
bestDist = dist;
|
|
14307
|
+
best = i2;
|
|
14308
|
+
}
|
|
14309
|
+
}
|
|
14310
|
+
return octave * sorted.length + best;
|
|
14311
|
+
};
|
|
14312
|
+
var isOutsideCore = (scale, semi) => scale.strict ? !corePcs(scale).has((semi % 12 + 12) % 12) : !isCoreDegree(scale, semitoneToDegree(scale, semi));
|
|
14313
|
+
var resolveComposeScale = (choice, minorKey, rnd = Math.random) => {
|
|
14314
|
+
const c = (choice ?? "").trim() || "auto";
|
|
14315
|
+
const hit = COMPOSE_SCALES[c];
|
|
14316
|
+
if (hit) return hit;
|
|
14317
|
+
if (c === "any")
|
|
14318
|
+
return COMPOSE_SCALES[COMPOSE_SCALE_IDS[Math.floor(rnd() * COMPOSE_SCALE_IDS.length)] ?? "yo"];
|
|
14319
|
+
return COMPOSE_SCALES[minorKey ? "minyo" : "yo"];
|
|
14320
|
+
};
|
|
14321
|
+
var getComposeScaleDescription = (choice) => {
|
|
14322
|
+
const hit = COMPOSE_SCALES[choice];
|
|
14323
|
+
if (hit) return hit.description;
|
|
14324
|
+
if (choice === "any")
|
|
14325
|
+
return `${COMPOSE_SCALE_IDS.length}\u3064\u306E\u97F3\u968E\u304B\u3089\u30E9\u30F3\u30C0\u30E0\u306B\u62BD\u9078\u3057\u307E\u3059`;
|
|
14326
|
+
return "\u30D9\u30FC\u30B9\u8ABF\u306E\u9577\u77ED\u306B\u5408\u308F\u305B\u3066\u3001\u967D\u97F3\u968E\uFF08\u9577\u8ABF\uFF09\u304B\u6C11\u8B21\u97F3\u968E\uFF08\u77ED\u8ABF\uFF09\u3092\u4F7F\u3044\u307E\u3059";
|
|
14327
|
+
};
|
|
14328
|
+
var resolveCenter = (scale) => scale.center ?? TONIC_CENTERS[scale.tonic] ?? null;
|
|
14329
|
+
|
|
13285
14330
|
// src/compose-sections.ts
|
|
13286
14331
|
var SECTION_LABELS = {
|
|
13287
14332
|
intro: "\u30A4\u30F3\u30C8\u30ED",
|
|
@@ -13516,8 +14561,8 @@ var sectionAt = (plan, bar) => {
|
|
|
13516
14561
|
|
|
13517
14562
|
// src/compose.ts
|
|
13518
14563
|
var STEP_SEMITONES = 2;
|
|
13519
|
-
var MAX_LEAP_SEMITONES =
|
|
13520
|
-
var MAX_BAR_LEAP_SEMITONES =
|
|
14564
|
+
var MAX_LEAP_SEMITONES = 10;
|
|
14565
|
+
var MAX_BAR_LEAP_SEMITONES = 10;
|
|
13521
14566
|
var HARD = {
|
|
13522
14567
|
/** メロディが1音も無い、音域が半音未満(同じ音を並べただけ)。 */
|
|
13523
14568
|
minMelodyRange: 3,
|
|
@@ -13543,6 +14588,9 @@ var WEIGHTS = {
|
|
|
13543
14588
|
*/
|
|
13544
14589
|
notesPerBar: 0.8,
|
|
13545
14590
|
shortNoteRatio: 0.6,
|
|
14591
|
+
/** 小節ごとの音数のばらつきと崖。平均だけを見ていて見逃していた偏り。 */
|
|
14592
|
+
barDensityCv: 0.6,
|
|
14593
|
+
densityCliff: 1,
|
|
13546
14594
|
/** 順次進行の比率。跳躍率だけを見ていると、跳躍の帯の上端に張り付く。 */
|
|
13547
14595
|
stepRatio: 0.8,
|
|
13548
14596
|
/** 調の外の音。0のままだと全曲が同じ音階をなぞるだけになる。 */
|
|
@@ -13555,10 +14603,15 @@ var WEIGHTS = {
|
|
|
13555
14603
|
sim4: 1.4,
|
|
13556
14604
|
sim8: 1.4,
|
|
13557
14605
|
phraseBreath: 1,
|
|
14606
|
+
/** 折り返しの多さ。跳躍率・順次進行率が揃っていても、これは別に足りなくなる。 */
|
|
14607
|
+
turnRatio: 0.8,
|
|
13558
14608
|
climaxPosition: 1,
|
|
13559
14609
|
climaxPeaks: 1,
|
|
13560
14610
|
/** メロディとサブメロが呼応しているか。 */
|
|
13561
14611
|
complementarity: 1,
|
|
14612
|
+
/** サブメロの音数と、その崖。メロディと同じ物差しで見る。 */
|
|
14613
|
+
subDensity: 0.6,
|
|
14614
|
+
subDensityCliff: 0.5,
|
|
13562
14615
|
// --- 和声(コードが要るのでコーパスからは較正できない) ---
|
|
13563
14616
|
/** B部でテンションが上がるか。 */
|
|
13564
14617
|
tensionRise: 1,
|
|
@@ -13634,6 +14687,10 @@ var FLAT_NOTE_NAMES = [
|
|
|
13634
14687
|
"Bb",
|
|
13635
14688
|
"B"
|
|
13636
14689
|
];
|
|
14690
|
+
var fifthsDistance = (semitones) => {
|
|
14691
|
+
const steps = (semitones * 7 % 12 + 12) % 12;
|
|
14692
|
+
return Math.min(steps, 12 - steps);
|
|
14693
|
+
};
|
|
13637
14694
|
var SEMITONE_TO_FIFTH_SHIFT = [
|
|
13638
14695
|
0,
|
|
13639
14696
|
// 0: C
|
|
@@ -13694,65 +14751,6 @@ var BPM_CHOICES = [
|
|
|
13694
14751
|
180,
|
|
13695
14752
|
185
|
|
13696
14753
|
];
|
|
13697
|
-
var MAJOR_SCALE2 = [
|
|
13698
|
-
{ semi: 0, fifth: 0 },
|
|
13699
|
-
// C
|
|
13700
|
-
{ semi: 2, fifth: 2 },
|
|
13701
|
-
// D
|
|
13702
|
-
{ semi: 4, fifth: 4 },
|
|
13703
|
-
// E
|
|
13704
|
-
{ semi: 5, fifth: -1 },
|
|
13705
|
-
// F
|
|
13706
|
-
{ semi: 7, fifth: 1 },
|
|
13707
|
-
// G
|
|
13708
|
-
{ semi: 9, fifth: 3 },
|
|
13709
|
-
// A
|
|
13710
|
-
{ semi: 11, fifth: 5 }
|
|
13711
|
-
// B
|
|
13712
|
-
];
|
|
13713
|
-
var degreeToPitch = (degree) => {
|
|
13714
|
-
const index = (degree % 7 + 7) % 7;
|
|
13715
|
-
const octave = Math.floor(degree / 7);
|
|
13716
|
-
const d = MAJOR_SCALE2[index];
|
|
13717
|
-
return { semi: d.semi + octave * 12, fifth: d.fifth };
|
|
13718
|
-
};
|
|
13719
|
-
var semitoneToDegree = (semi) => {
|
|
13720
|
-
const octave = Math.floor(semi / 12);
|
|
13721
|
-
const within = semi - octave * 12;
|
|
13722
|
-
let best = 0;
|
|
13723
|
-
let bestDist = Number.POSITIVE_INFINITY;
|
|
13724
|
-
for (let i2 = 0; i2 < MAJOR_SCALE2.length; i2++) {
|
|
13725
|
-
const dist = Math.abs(MAJOR_SCALE2[i2].semi - within);
|
|
13726
|
-
if (dist < bestDist) {
|
|
13727
|
-
bestDist = dist;
|
|
13728
|
-
best = i2;
|
|
13729
|
-
}
|
|
13730
|
-
}
|
|
13731
|
-
return octave * 7 + best;
|
|
13732
|
-
};
|
|
13733
|
-
var walk = (semi, delta) => degreeToPitch(semitoneToDegree(semi) + delta).semi;
|
|
13734
|
-
var NON_PENTATONIC_DEGREES = /* @__PURE__ */ new Set([3, 6]);
|
|
13735
|
-
var isNonPentatonic = (semi) => NON_PENTATONIC_DEGREES.has((semitoneToDegree(semi) % 7 + 7) % 7);
|
|
13736
|
-
var PENTATONIC_DEGREES = [0, 1, 2, 4, 5];
|
|
13737
|
-
var pentaToDegree = (penta) => {
|
|
13738
|
-
const index = (penta % 5 + 5) % 5;
|
|
13739
|
-
const octave = Math.floor(penta / 5);
|
|
13740
|
-
return PENTATONIC_DEGREES[index] + octave * 7;
|
|
13741
|
-
};
|
|
13742
|
-
var degreeToPenta = (degree) => {
|
|
13743
|
-
const index = (degree % 7 + 7) % 7;
|
|
13744
|
-
const octave = Math.floor(degree / 7);
|
|
13745
|
-
let best = 0;
|
|
13746
|
-
let bestDist = Number.POSITIVE_INFINITY;
|
|
13747
|
-
for (let i2 = 0; i2 < PENTATONIC_DEGREES.length; i2++) {
|
|
13748
|
-
const dist = Math.abs(PENTATONIC_DEGREES[i2] - index);
|
|
13749
|
-
if (dist < bestDist) {
|
|
13750
|
-
bestDist = dist;
|
|
13751
|
-
best = i2;
|
|
13752
|
-
}
|
|
13753
|
-
}
|
|
13754
|
-
return octave * 5 + best;
|
|
13755
|
-
};
|
|
13756
14754
|
var SECTION_A_PROGRESSIONS = [
|
|
13757
14755
|
["C", "G", "Am", "Em7"],
|
|
13758
14756
|
// カノン進行の前半
|
|
@@ -13786,6 +14784,22 @@ var SECTION_A_PROGRESSIONS = [
|
|
|
13786
14784
|
// ジャズ寄りの2-5-1
|
|
13787
14785
|
["Dm7", "G7", "Em7", "Am7"],
|
|
13788
14786
|
// 2-5-3-6
|
|
14787
|
+
// --- ライン・クリシェ(内声が半音ずつ動く) ---
|
|
14788
|
+
// 和音の1声だけを半音で動かして、和音記号は変わるのに響きは繋がったまま進む。
|
|
14789
|
+
// J-POPのサビ後半やAメロの定番。
|
|
14790
|
+
["Am", "AmM7", "Am7", "Am6"],
|
|
14791
|
+
// ラ→ソ#→ソ→ファ# の下行
|
|
14792
|
+
["C", "CM7", "C7", "F"],
|
|
14793
|
+
// ド→シ→シb→ラ
|
|
14794
|
+
["Am", "AmM7", "Am7", "D7"],
|
|
14795
|
+
// クリシェからドリアンのIVへ
|
|
14796
|
+
["F", "Fm", "CM7", "Am7"],
|
|
14797
|
+
// サブドミナントマイナーのクリシェ
|
|
14798
|
+
// --- ペダルポイント(ベースを保続する) ---
|
|
14799
|
+
// ベースだけ動かさずに上の和音を変える。緊張感が出る。分数和音のルートを
|
|
14800
|
+
// {@link chordTones} が先頭で返すので、ベースは自然に保続音になる。
|
|
14801
|
+
["C", "Am/C", "F/C", "G/C"],
|
|
14802
|
+
["Am", "Em/A", "F/A", "G/A"],
|
|
13789
14803
|
// --- 借用和音(同主短調・ミクソリディアンから借りる) ---
|
|
13790
14804
|
// **調の外の和音を進行そのものに持たせる。** ここまでの候補は全部ハ長調/イ短調の
|
|
13791
14805
|
// ダイアトニックで、セカンダリドミナント以外に調の外の音が出てこなかった。
|
|
@@ -13842,10 +14856,50 @@ var SECTION_A2_DERIVATIONS = [
|
|
|
13842
14856
|
var SECTION_A3_DERIVATIONS = [
|
|
13843
14857
|
(a, t) => [a[0], a[1], "G7", t],
|
|
13844
14858
|
(a, t) => [a[0], "Dm7", "G7", t],
|
|
13845
|
-
(a, t) => [a[0], "F", "G7", t],
|
|
13846
14859
|
(a, t) => [a[0], a[1], "Em7", t],
|
|
13847
|
-
|
|
14860
|
+
// アーメン終止(IV→I)
|
|
14861
|
+
(a, t) => [a[0], "G7", "F", t],
|
|
14862
|
+
(a, t) => [a[0], "Dm7", "FM7", t],
|
|
14863
|
+
// サブドミナントマイナー終止(IVm→I)
|
|
14864
|
+
(a, t) => [a[0], "G7", "Fm", t],
|
|
14865
|
+
(a, t) => [a[0], "F", "Fm", t]
|
|
13848
14866
|
];
|
|
14867
|
+
var SECTION_DECEPTIVE_DERIVATIONS = [
|
|
14868
|
+
(a, t) => [a[0], a[1], "G7", t === "Am" ? "F" : "Am"],
|
|
14869
|
+
(a, t) => [a[0], "Dm7", "G7", t === "Am" ? "FM7" : "Am7"],
|
|
14870
|
+
(a, t) => [a[0], "F", "G7", t === "Am" ? "F" : "Am7"]
|
|
14871
|
+
];
|
|
14872
|
+
var MODAL_FULL_DERIVATIONS = [
|
|
14873
|
+
(a, c) => [a[0], a[1], c.half, c.tonic],
|
|
14874
|
+
(a, c) => [a[0], c.half, a[2], c.tonic],
|
|
14875
|
+
(a, c) => [a[0], a[1], a[2], c.tonic],
|
|
14876
|
+
(a, c) => [c.tonic, c.half, a[2], c.tonic]
|
|
14877
|
+
];
|
|
14878
|
+
var MODAL_HALF_DERIVATIONS = [
|
|
14879
|
+
(a, c) => [a[0], a[1], a[2], c.half],
|
|
14880
|
+
(a, c) => [a[0], a[1], c.tonic, c.half],
|
|
14881
|
+
(a, c) => [a[0], c.tonic, a[2], c.half]
|
|
14882
|
+
];
|
|
14883
|
+
var MODAL_DECEPTIVE_DERIVATIONS = [
|
|
14884
|
+
(a, c) => [a[0], a[1], c.half, c.deceptive],
|
|
14885
|
+
(a, c) => [a[0], c.half, a[2], c.deceptive],
|
|
14886
|
+
(a, c) => [a[0], a[1], a[2], c.deceptive]
|
|
14887
|
+
];
|
|
14888
|
+
var MODAL_BORROW = {
|
|
14889
|
+
F: "Fm",
|
|
14890
|
+
// IV → IVm(サブドミナントマイナー。いちばん定番)
|
|
14891
|
+
FM7: "Fm7",
|
|
14892
|
+
Am: "Ab",
|
|
14893
|
+
// VIm → ♭VI
|
|
14894
|
+
Am7: "Ab",
|
|
14895
|
+
G: "Bb",
|
|
14896
|
+
// V → ♭VII(ミクソリディアン)
|
|
14897
|
+
G7: "Bb",
|
|
14898
|
+
Em7: "Eb",
|
|
14899
|
+
// IIIm → ♭III
|
|
14900
|
+
Dm7: "Dm7-5"
|
|
14901
|
+
// IIm7 → IIm7♭5(エオリアン)
|
|
14902
|
+
};
|
|
13849
14903
|
var CHORD_PATTERNS = [
|
|
13850
14904
|
"block",
|
|
13851
14905
|
"arpeggio",
|
|
@@ -13853,6 +14907,7 @@ var CHORD_PATTERNS = [
|
|
|
13853
14907
|
"yatsume",
|
|
13854
14908
|
"alternating"
|
|
13855
14909
|
];
|
|
14910
|
+
var chordPatternPool = (bpm) => bpm <= 130 ? [...CHORD_PATTERNS, "arpeggio-fast"] : CHORD_PATTERNS;
|
|
13856
14911
|
var CHORD_TONE_WEIGHT = {
|
|
13857
14912
|
0: 3,
|
|
13858
14913
|
// ルート
|
|
@@ -14030,6 +15085,54 @@ var RHYTHM_CELLS = [
|
|
|
14030
15085
|
density: "dense"
|
|
14031
15086
|
}
|
|
14032
15087
|
];
|
|
15088
|
+
var PHRASE_END_CELLS = [
|
|
15089
|
+
// 白玉で受けてから息を継ぐ(いちばん歌らしい終わり方)。
|
|
15090
|
+
{ value: [HALF, QUARTER, -QUARTER], density: "sparse" },
|
|
15091
|
+
{ value: [DOT_QUARTER, EIGHTH, HALF], density: "sparse" },
|
|
15092
|
+
{ value: [QUARTER, DOT_QUARTER, EIGHTH, -QUARTER], density: "sparse" },
|
|
15093
|
+
// 2音で降りてから息を継ぐ。
|
|
15094
|
+
{ value: [QUARTER, QUARTER, -HALF], density: "sparse" },
|
|
15095
|
+
{ value: [DOT_QUARTER, EIGHTH, -HALF], density: "sparse" },
|
|
15096
|
+
{ value: [HALF, -QUARTER, QUARTER], density: "sparse" },
|
|
15097
|
+
// 3音で言い切ってから息を継ぐ。
|
|
15098
|
+
{ value: [EIGHTH, EIGHTH, QUARTER, -HALF], density: "sparse" },
|
|
15099
|
+
{ value: [QUARTER, EIGHTH, EIGHTH, -HALF], density: "sparse" },
|
|
15100
|
+
{ value: [QUARTER, QUARTER, QUARTER, -QUARTER], density: "sparse" },
|
|
15101
|
+
{ value: [HALF, EIGHTH, EIGHTH, -QUARTER], density: "sparse" },
|
|
15102
|
+
// 4音で言い切ってから息を継ぐ。周りが7音前後の曲では、2音まで落とすと崖になる。
|
|
15103
|
+
{ value: [EIGHTH, EIGHTH, EIGHTH, EIGHTH, -HALF], density: "sparse" },
|
|
15104
|
+
{ value: [QUARTER, EIGHTH, EIGHTH, QUARTER, -QUARTER], density: "sparse" },
|
|
15105
|
+
{ value: [EIGHTH, EIGHTH, QUARTER, QUARTER, -QUARTER], density: "sparse" }
|
|
15106
|
+
];
|
|
15107
|
+
var MID_BREATH_CELLS = [
|
|
15108
|
+
{ value: [QUARTER, EIGHTH, EIGHTH, QUARTER, -QUARTER], density: "medium" },
|
|
15109
|
+
{ value: [EIGHTH, EIGHTH, QUARTER, QUARTER, -QUARTER], density: "medium" },
|
|
15110
|
+
{ value: [DOT_QUARTER, EIGHTH, QUARTER, QUARTER], density: "medium" },
|
|
15111
|
+
{ value: [QUARTER, QUARTER, EIGHTH, EIGHTH, -QUARTER], density: "medium" },
|
|
15112
|
+
{ value: [EIGHTH, EIGHTH, EIGHTH, EIGHTH, HALF], density: "medium" },
|
|
15113
|
+
{ value: [QUARTER, EIGHTH, EIGHTH, DOT_QUARTER, EIGHTH], density: "medium" }
|
|
15114
|
+
];
|
|
15115
|
+
var CELL_GRID = BASE_STEPS_PER_BAR / 16;
|
|
15116
|
+
var onsetKeyOf = (value) => {
|
|
15117
|
+
const on = [];
|
|
15118
|
+
let at = 0;
|
|
15119
|
+
for (const v of value) {
|
|
15120
|
+
if (v > 0) on.push(Math.round(at / CELL_GRID));
|
|
15121
|
+
at += Math.abs(v);
|
|
15122
|
+
}
|
|
15123
|
+
return on.join(",");
|
|
15124
|
+
};
|
|
15125
|
+
var UNSEEN_CELL_WEIGHT = 0.5;
|
|
15126
|
+
var cellEntryCount = /* @__PURE__ */ new Map();
|
|
15127
|
+
var cellWeightCache = /* @__PURE__ */ new Map();
|
|
15128
|
+
var cellWeight = (c) => {
|
|
15129
|
+
const cached = cellWeightCache.get(c.value);
|
|
15130
|
+
if (cached !== void 0) return cached;
|
|
15131
|
+
const key = onsetKeyOf(c.value);
|
|
15132
|
+
const w = (CORPUS_CELL_WEIGHTS[key] ?? UNSEEN_CELL_WEIGHT) / Math.max(1, cellEntryCount.get(key) ?? 1);
|
|
15133
|
+
cellWeightCache.set(c.value, w);
|
|
15134
|
+
return w;
|
|
15135
|
+
};
|
|
14033
15136
|
var HALF_BAR_FIGURES = [
|
|
14034
15137
|
[EIGHTH, EIGHTH, EIGHTH, EIGHTH],
|
|
14035
15138
|
// タタタタ
|
|
@@ -14062,6 +15165,14 @@ var HALF_BAR_FIGURES = [
|
|
|
14062
15165
|
// 2拍目裏からのアウフタクト(タタ)
|
|
14063
15166
|
[QUARTER, -EIGHTH, EIGHTH],
|
|
14064
15167
|
// ター・休タ(8分裏弱起)
|
|
15168
|
+
// **3+3+2(トレシーヨ)。** 参考曲91本で最も多かった「語彙に無い形」で、
|
|
15169
|
+
// 174小節ぶんの穴が空いていた(`scripts/compare-vocabulary.ts` の①)。
|
|
15170
|
+
// 付点8分が `[DOT_EIGHTH, SIXTEENTH]` の対でしか入っておらず、
|
|
15171
|
+
// 付点8分を2つ並べる形が作れなかった。界隈曲・ボカロの推進力の中心。
|
|
15172
|
+
[DOT_EIGHTH, DOT_EIGHTH, EIGHTH],
|
|
15173
|
+
[DOT_EIGHTH, DOT_EIGHTH, EIGHTH],
|
|
15174
|
+
// 4分音符が全部8分裏に来る形(食い)。参考曲で67小節ぶん取りこぼしていた。
|
|
15175
|
+
[-EIGHTH, QUARTER, EIGHTH],
|
|
14065
15176
|
// 付点8分+16分(タッカ)。歌モノで非常に多用される跳ね・推進力の型。
|
|
14066
15177
|
[DOT_EIGHTH, SIXTEENTH, EIGHTH, EIGHTH],
|
|
14067
15178
|
[EIGHTH, EIGHTH, DOT_EIGHTH, SIXTEENTH],
|
|
@@ -14227,9 +15338,21 @@ var MOTIF_CELLS = [
|
|
|
14227
15338
|
...buildMotifCells(),
|
|
14228
15339
|
...HAND_MOTIF_CELLS
|
|
14229
15340
|
];
|
|
15341
|
+
for (const c of [...MOTIF_CELLS, ...RHYTHM_CELLS]) {
|
|
15342
|
+
const key = onsetKeyOf(c.value);
|
|
15343
|
+
cellEntryCount.set(key, (cellEntryCount.get(key) ?? 0) + 1);
|
|
15344
|
+
}
|
|
14230
15345
|
var groovyCells = (cells, groove, rnd) => {
|
|
14231
15346
|
const hasSixteenth = (c) => c.value.some((v) => Math.abs(v) <= SIXTEENTH);
|
|
14232
|
-
if (groove === "eighth")
|
|
15347
|
+
if (groove === "eighth") {
|
|
15348
|
+
const plain = cells.filter((c) => !hasSixteenth(c));
|
|
15349
|
+
const spiced = cells.filter(hasSixteenth);
|
|
15350
|
+
if (spiced.length === 0) return plain;
|
|
15351
|
+
const out = [...plain];
|
|
15352
|
+
const take = Math.max(1, Math.round(plain.length * 0.1));
|
|
15353
|
+
for (let i2 = 0; i2 < take; i2++) out.push(pick(spiced, rnd));
|
|
15354
|
+
return out;
|
|
15355
|
+
}
|
|
14233
15356
|
const withSixteenth = cells.filter(hasSixteenth);
|
|
14234
15357
|
return withSixteenth.length > 0 && rnd() < 0.75 ? withSixteenth : cells;
|
|
14235
15358
|
};
|
|
@@ -14350,8 +15473,36 @@ var nearestChordTone = (targetSemi, tones, minWeight, preferColor = false) => {
|
|
|
14350
15473
|
return best;
|
|
14351
15474
|
};
|
|
14352
15475
|
var MELODY_LOW = 60;
|
|
14353
|
-
var MELODY_HIGH =
|
|
15476
|
+
var MELODY_HIGH = 81;
|
|
14354
15477
|
var MELODY_CENTER = (MELODY_LOW + MELODY_HIGH) / 2;
|
|
15478
|
+
var harmonyPitch = (scale, melodySemi, tones, prevHarmony, offset, parallel, against) => {
|
|
15479
|
+
const lo = Math.max(-12, Math.min(offset, 0) - 7);
|
|
15480
|
+
const hi = Math.min(12, Math.max(offset, 0) + 7);
|
|
15481
|
+
let best = null;
|
|
15482
|
+
let bestCost = Number.POSITIVE_INFINITY;
|
|
15483
|
+
for (const tone of tones) {
|
|
15484
|
+
const pc = pitchClass(tone.semi);
|
|
15485
|
+
for (let oct = 0; oct <= 10; oct++) {
|
|
15486
|
+
const semi = pc + oct * 12;
|
|
15487
|
+
const delta = semi - melodySemi;
|
|
15488
|
+
if (delta > hi || delta < lo) continue;
|
|
15489
|
+
const move = prevHarmony === null ? 0 : Math.abs(semi - prevHarmony);
|
|
15490
|
+
const stay = parallel ? move * 0.06 : move <= 2 ? move * 0.04 : 0.1 + (move - 2) * 0.9;
|
|
15491
|
+
let clash = 0;
|
|
15492
|
+
if (against !== null) {
|
|
15493
|
+
const g = Math.abs(semi - against) % 12;
|
|
15494
|
+
clash = g === 3 || g === 4 || g === 8 || g === 9 || g === 7 ? 0 : g === 0 ? 0.5 : 1.2;
|
|
15495
|
+
}
|
|
15496
|
+
const offCore = scale.strict && isOutsideCore(scale, semi) ? 1.5 : 0;
|
|
15497
|
+
const cost = stay + clash + offCore + Math.abs(delta - offset) * (parallel ? 1.4 : 0.7) + (3 - tone.weight) * 0.4;
|
|
15498
|
+
if (cost < bestCost) {
|
|
15499
|
+
bestCost = cost;
|
|
15500
|
+
best = { semi, fifth: tone.fifth };
|
|
15501
|
+
}
|
|
15502
|
+
}
|
|
15503
|
+
}
|
|
15504
|
+
return best ?? nearestChordTone(melodySemi + offset, tones, 2);
|
|
15505
|
+
};
|
|
14355
15506
|
var SUBMELODY_LOW = 55;
|
|
14356
15507
|
var SUBMELODY_HIGH = 74;
|
|
14357
15508
|
var BASS_LOW = 33;
|
|
@@ -14388,40 +15539,43 @@ var leapTarget = (from, tones, rnd) => {
|
|
|
14388
15539
|
];
|
|
14389
15540
|
return pick(weighted.length > 0 ? weighted : candidates, rnd);
|
|
14390
15541
|
};
|
|
14391
|
-
var landOn = (degrees, scaleIndex) => {
|
|
15542
|
+
var landOn = (scale, degrees, scaleIndex) => {
|
|
14392
15543
|
if (degrees.length === 0) return;
|
|
15544
|
+
const size = scaleSize(scale);
|
|
14393
15545
|
const last = degrees[degrees.length - 1];
|
|
14394
|
-
const index = (last %
|
|
15546
|
+
const index = (last % size + size) % size;
|
|
14395
15547
|
let delta = scaleIndex - index;
|
|
14396
|
-
if (delta >
|
|
14397
|
-
if (delta < -
|
|
15548
|
+
if (delta > size / 2) delta -= size;
|
|
15549
|
+
if (delta < -size / 2) delta += size;
|
|
14398
15550
|
degrees[degrees.length - 1] = last + delta;
|
|
14399
15551
|
};
|
|
14400
|
-
var landPitch = (pitches, scaleIndex) => {
|
|
15552
|
+
var landPitch = (scale, pitches, scaleIndex) => {
|
|
14401
15553
|
if (pitches.length === 0) return;
|
|
15554
|
+
const size = scaleSize(scale);
|
|
14402
15555
|
const last = pitches[pitches.length - 1];
|
|
14403
|
-
const degree = semitoneToDegree(last);
|
|
14404
|
-
const index = (degree %
|
|
15556
|
+
const degree = semitoneToDegree(scale, last);
|
|
15557
|
+
const index = (degree % size + size) % size;
|
|
14405
15558
|
let delta = scaleIndex - index;
|
|
14406
|
-
if (delta >
|
|
14407
|
-
if (delta < -
|
|
15559
|
+
if (delta > size / 2) delta -= size;
|
|
15560
|
+
if (delta < -size / 2) delta += size;
|
|
14408
15561
|
pitches[pitches.length - 1] = clampSemi(
|
|
14409
|
-
degreeToPitch(degree + delta).semi,
|
|
15562
|
+
degreeToPitch(scale, degree + delta).semi,
|
|
14410
15563
|
MELODY_LOW,
|
|
14411
15564
|
MELODY_HIGH
|
|
14412
15565
|
);
|
|
14413
15566
|
};
|
|
14414
|
-
var barDegrees = (role, slots, tones, style, motifContour, startDegree, contourOffset, repeatShift, barHeadWeight, preferColor, quarterSteps, rnd) => {
|
|
15567
|
+
var barDegrees = (role, slots, tones, style, scale, motifContour, startDegree, contourOffset, repeatShift, barHeadWeight, preferColor, quarterSteps, rnd) => {
|
|
14415
15568
|
const noteCount = slots.length;
|
|
14416
15569
|
const out = [];
|
|
14417
15570
|
if (role === "motif" || role === "sequence" || role === "climax" || role === "answer") {
|
|
14418
15571
|
const shift = (role === "sequence" ? pick([-2, -1, 1, 2], rnd) : role === "climax" ? 5 : 0) + repeatShift;
|
|
14419
15572
|
if (style.pentatonicMotif) {
|
|
14420
|
-
const
|
|
15573
|
+
const startCore = degreeToCore(scale, startDegree);
|
|
14421
15574
|
for (let i2 = 0; i2 < noteCount; i2++)
|
|
14422
15575
|
out.push(
|
|
14423
|
-
|
|
14424
|
-
|
|
15576
|
+
coreToDegree(
|
|
15577
|
+
scale,
|
|
15578
|
+
startCore + shift + motifContour[(contourOffset + i2) % motifContour.length]
|
|
14425
15579
|
)
|
|
14426
15580
|
);
|
|
14427
15581
|
} else {
|
|
@@ -14441,9 +15595,9 @@ var barDegrees = (role, slots, tones, style, motifContour, startDegree, contourO
|
|
|
14441
15595
|
for (let i2 = 0; i2 < noteCount; i2++)
|
|
14442
15596
|
out.push(startDegree + dir2 * (i2 < peak ? i2 : peak * 2 - i2 - 1));
|
|
14443
15597
|
} else if (style.runShape === "broken") {
|
|
14444
|
-
const arp = tones.map((t) => semitoneToDegree(clampSemi(t.semi, 60, 71))).sort((a, b) => a - b);
|
|
15598
|
+
const arp = tones.map((t) => semitoneToDegree(scale, clampSemi(t.semi, 60, 71))).sort((a, b) => a - b);
|
|
14445
15599
|
for (let i2 = 0; i2 < noteCount; i2++) {
|
|
14446
|
-
const oct = Math.floor(i2 / arp.length) *
|
|
15600
|
+
const oct = Math.floor(i2 / arp.length) * scaleSize(scale);
|
|
14447
15601
|
const idx = dir2 > 0 ? i2 % arp.length : arp.length - 1 - i2 % arp.length;
|
|
14448
15602
|
out.push(arp[idx] + dir2 * oct);
|
|
14449
15603
|
}
|
|
@@ -14466,7 +15620,10 @@ var barDegrees = (role, slots, tones, style, motifContour, startDegree, contourO
|
|
|
14466
15620
|
return out;
|
|
14467
15621
|
}
|
|
14468
15622
|
if (role === "cadence") {
|
|
14469
|
-
const tonic = semitoneToDegree(
|
|
15623
|
+
const tonic = semitoneToDegree(
|
|
15624
|
+
scale,
|
|
15625
|
+
clampSemi(72, MELODY_LOW, MELODY_HIGH)
|
|
15626
|
+
);
|
|
14470
15627
|
for (let i2 = 0; i2 < noteCount; i2++) {
|
|
14471
15628
|
if (style.cadenceShape === "descend") {
|
|
14472
15629
|
out.push(tonic + noteCount - 1 - i2);
|
|
@@ -14474,7 +15631,9 @@ var barDegrees = (role, slots, tones, style, motifContour, startDegree, contourO
|
|
|
14474
15631
|
const shape = [4, 2, 0];
|
|
14475
15632
|
out.push(tonic + shape[Math.min(i2, shape.length - 1)]);
|
|
14476
15633
|
} else if (style.cadenceShape === "leap-up") {
|
|
14477
|
-
out.push(
|
|
15634
|
+
out.push(
|
|
15635
|
+
i2 === noteCount - 1 ? tonic : tonic - scaleSize(scale) + Math.min(i2, 4)
|
|
15636
|
+
);
|
|
14478
15637
|
} else {
|
|
14479
15638
|
out.push(i2 === 0 && noteCount > 1 ? tonic + 1 : tonic);
|
|
14480
15639
|
}
|
|
@@ -14509,8 +15668,9 @@ var barDegrees = (role, slots, tones, style, motifContour, startDegree, contourO
|
|
|
14509
15668
|
for (let i2 = 0; i2 < out.length; i2++) {
|
|
14510
15669
|
if (!slots[i2].isStrong) continue;
|
|
14511
15670
|
out[i2] = semitoneToDegree(
|
|
15671
|
+
scale,
|
|
14512
15672
|
nearestChordTone(
|
|
14513
|
-
degreeToPitch(out[i2]).semi,
|
|
15673
|
+
degreeToPitch(scale, out[i2]).semi,
|
|
14514
15674
|
tones,
|
|
14515
15675
|
barHeadWeight,
|
|
14516
15676
|
preferColor
|
|
@@ -14521,9 +15681,9 @@ var barDegrees = (role, slots, tones, style, motifContour, startDegree, contourO
|
|
|
14521
15681
|
if (slots[i2].isStrong) continue;
|
|
14522
15682
|
if (slots[i2].value >= quarterSteps) {
|
|
14523
15683
|
if (rnd() < style.leapAffinity) {
|
|
14524
|
-
const from = degreeToPitch(out[i2 - 1]).semi;
|
|
15684
|
+
const from = degreeToPitch(scale, out[i2 - 1]).semi;
|
|
14525
15685
|
const target = leapTarget(from, tones, rnd);
|
|
14526
|
-
if (target !== null) out[i2] = semitoneToDegree(target);
|
|
15686
|
+
if (target !== null) out[i2] = semitoneToDegree(scale, target);
|
|
14527
15687
|
}
|
|
14528
15688
|
continue;
|
|
14529
15689
|
}
|
|
@@ -14533,17 +15693,20 @@ var barDegrees = (role, slots, tones, style, motifContour, startDegree, contourO
|
|
|
14533
15693
|
}
|
|
14534
15694
|
return out;
|
|
14535
15695
|
};
|
|
14536
|
-
var fitMotif = (degrees, slots, tones, prevSemi, quarterSteps, pentatonic) => {
|
|
15696
|
+
var fitMotif = (degrees, slots, tones, prevSemi, quarterSteps, scale, pentatonic, preferShift) => {
|
|
14537
15697
|
let best = degrees;
|
|
15698
|
+
let bestShift = 0;
|
|
14538
15699
|
let bestScore = Number.NEGATIVE_INFINITY;
|
|
15700
|
+
let preferScore = Number.NEGATIVE_INFINITY;
|
|
15701
|
+
let preferMoved = null;
|
|
14539
15702
|
for (let shift = -3; shift <= 3; shift++) {
|
|
14540
15703
|
const moved = degrees.map(
|
|
14541
|
-
(d) => pentatonic ?
|
|
15704
|
+
(d) => pentatonic ? coreToDegree(scale, degreeToCore(scale, d) + shift) : d + shift
|
|
14542
15705
|
);
|
|
14543
15706
|
let score = 0;
|
|
14544
15707
|
for (let i2 = 0; i2 < moved.length; i2++) {
|
|
14545
15708
|
const semi = clampSemi(
|
|
14546
|
-
degreeToPitch(moved[i2]).semi,
|
|
15709
|
+
degreeToPitch(scale, moved[i2]).semi,
|
|
14547
15710
|
MELODY_LOW,
|
|
14548
15711
|
MELODY_HIGH
|
|
14549
15712
|
);
|
|
@@ -14552,23 +15715,30 @@ var fitMotif = (degrees, slots, tones, prevSemi, quarterSteps, pentatonic) => {
|
|
|
14552
15715
|
score += important ? w * 3 : w;
|
|
14553
15716
|
}
|
|
14554
15717
|
const head = clampSemi(
|
|
14555
|
-
degreeToPitch(moved[0]).semi,
|
|
15718
|
+
degreeToPitch(scale, moved[0]).semi,
|
|
14556
15719
|
MELODY_LOW,
|
|
14557
15720
|
MELODY_HIGH
|
|
14558
15721
|
);
|
|
14559
15722
|
score -= Math.max(0, Math.abs(head - prevSemi) - MAX_BAR_LEAP_SEMITONES);
|
|
15723
|
+
if (shift === preferShift) {
|
|
15724
|
+
preferScore = score;
|
|
15725
|
+
preferMoved = moved;
|
|
15726
|
+
}
|
|
14560
15727
|
if (score > bestScore) {
|
|
14561
15728
|
bestScore = score;
|
|
15729
|
+
bestShift = shift;
|
|
14562
15730
|
best = moved;
|
|
14563
15731
|
}
|
|
14564
15732
|
}
|
|
14565
|
-
|
|
15733
|
+
if (preferMoved !== null && preferScore >= bestScore - 3)
|
|
15734
|
+
return { degrees: preferMoved, shift: preferShift };
|
|
15735
|
+
return { degrees: best, shift: bestShift };
|
|
14566
15736
|
};
|
|
14567
15737
|
var shapeBar = (degrees, slots, tones, prevSemi, opts) => {
|
|
14568
15738
|
const out = [];
|
|
14569
15739
|
let prev = prevSemi;
|
|
14570
15740
|
if (opts.preserveContour) {
|
|
14571
|
-
const raw = degrees.map((d) => degreeToPitch(d).semi);
|
|
15741
|
+
const raw = degrees.map((d) => degreeToPitch(opts.scale, d).semi);
|
|
14572
15742
|
const lo = Math.min(...raw);
|
|
14573
15743
|
const hi = Math.max(...raw);
|
|
14574
15744
|
let shift = 0;
|
|
@@ -14582,30 +15752,42 @@ var shapeBar = (degrees, slots, tones, prevSemi, opts) => {
|
|
|
14582
15752
|
}
|
|
14583
15753
|
for (let i2 = 0; i2 < degrees.length; i2++) {
|
|
14584
15754
|
let semi = clampSemi(
|
|
14585
|
-
degreeToPitch(degrees[i2]).semi,
|
|
15755
|
+
degreeToPitch(opts.scale, degrees[i2]).semi,
|
|
14586
15756
|
MELODY_LOW,
|
|
14587
15757
|
MELODY_HIGH
|
|
14588
15758
|
);
|
|
14589
15759
|
const limit = i2 === 0 ? MAX_BAR_LEAP_SEMITONES : MAX_LEAP_SEMITONES;
|
|
14590
15760
|
if (!opts.allowLeap && Math.abs(semi - prev) > limit) {
|
|
14591
15761
|
semi = clampSemi(
|
|
14592
|
-
walk(prev, Math.sign(semi - prev) * 3),
|
|
15762
|
+
walk(opts.scale, prev, Math.sign(semi - prev) * 3),
|
|
14593
15763
|
MELODY_LOW,
|
|
14594
15764
|
MELODY_HIGH
|
|
14595
15765
|
);
|
|
14596
15766
|
}
|
|
14597
15767
|
if (!opts.allowArpeggio && i2 >= 2 && Math.abs(out[i2 - 1] - out[i2 - 2]) > STEP_SEMITONES) {
|
|
14598
15768
|
const back = -Math.sign(out[i2 - 1] - out[i2 - 2]);
|
|
14599
|
-
semi = clampSemi(
|
|
15769
|
+
semi = clampSemi(
|
|
15770
|
+
walk(opts.scale, out[i2 - 1], back),
|
|
15771
|
+
MELODY_LOW,
|
|
15772
|
+
MELODY_HIGH
|
|
15773
|
+
);
|
|
14600
15774
|
}
|
|
14601
15775
|
if (toneWeight(semi, tones) === 0 && (slots[i2].isStrong || slots[i2].value >= opts.quarterSteps)) {
|
|
14602
15776
|
const resolved = semi + 1;
|
|
14603
|
-
const useResolved = resolved <= MELODY_HIGH && !
|
|
15777
|
+
const useResolved = resolved <= MELODY_HIGH && !scalePcs(opts.scale).has(pitchClass(resolved)) && toneWeight(resolved, tones) >= 2 && resolved !== prev && opts.rnd() < opts.chromaticAffinity;
|
|
14604
15778
|
if (useResolved) {
|
|
14605
15779
|
semi = resolved;
|
|
14606
15780
|
} else {
|
|
14607
|
-
const up = clampSemi(
|
|
14608
|
-
|
|
15781
|
+
const up = clampSemi(
|
|
15782
|
+
walk(opts.scale, semi, 1),
|
|
15783
|
+
MELODY_LOW,
|
|
15784
|
+
MELODY_HIGH
|
|
15785
|
+
);
|
|
15786
|
+
const down = clampSemi(
|
|
15787
|
+
walk(opts.scale, semi, -1),
|
|
15788
|
+
MELODY_LOW,
|
|
15789
|
+
MELODY_HIGH
|
|
15790
|
+
);
|
|
14609
15791
|
const score = (s) => toneWeight(s, tones) * 2 + (i2 > 0 && s === prev ? -3 : 0);
|
|
14610
15792
|
semi = score(down) >= score(up) ? down : up;
|
|
14611
15793
|
}
|
|
@@ -14613,7 +15795,14 @@ var shapeBar = (degrees, slots, tones, prevSemi, opts) => {
|
|
|
14613
15795
|
out.push(semi);
|
|
14614
15796
|
prev = semi;
|
|
14615
15797
|
}
|
|
14616
|
-
applyPentatonic(
|
|
15798
|
+
applyPentatonic(
|
|
15799
|
+
out,
|
|
15800
|
+
slots,
|
|
15801
|
+
tones,
|
|
15802
|
+
prevSemi,
|
|
15803
|
+
opts.quarterSteps / 2,
|
|
15804
|
+
opts.scale
|
|
15805
|
+
);
|
|
14617
15806
|
applyOctaveJumps(out, slots, opts.octaveAffinity, opts.rnd);
|
|
14618
15807
|
return out;
|
|
14619
15808
|
};
|
|
@@ -14630,27 +15819,27 @@ var applyOctaveJumps = (out, slots, affinity, rnd) => {
|
|
|
14630
15819
|
out[i2] = canUp && (!canDown || rnd() < 0.5) ? up : down;
|
|
14631
15820
|
}
|
|
14632
15821
|
};
|
|
14633
|
-
var applyPentatonic = (out, slots, tones, prevSemi, shortSteps) => {
|
|
15822
|
+
var applyPentatonic = (out, slots, tones, prevSemi, shortSteps, scale) => {
|
|
14634
15823
|
for (let i2 = 0; i2 < out.length; i2++) {
|
|
14635
15824
|
const semi = out[i2];
|
|
14636
|
-
if (!
|
|
14637
|
-
if (tones.some((t) => pitchClass(t.semi) === pitchClass(semi)))
|
|
15825
|
+
if (!isOutsideCore(scale, semi)) continue;
|
|
15826
|
+
if (!scale.strict && tones.some((t) => pitchClass(t.semi) === pitchClass(semi)))
|
|
15827
|
+
continue;
|
|
14638
15828
|
const before = i2 === 0 ? prevSemi : out[i2 - 1];
|
|
14639
15829
|
const after = i2 + 1 < out.length ? out[i2 + 1] : null;
|
|
14640
15830
|
const inByStep = Math.abs(semi - before) <= STEP_SEMITONES;
|
|
14641
15831
|
const outByStep = after !== null && Math.abs(after - semi) <= STEP_SEMITONES;
|
|
14642
|
-
if (inByStep || outByStep) continue;
|
|
14643
|
-
if (!slots[i2].isStrong && slots[i2].value <= shortSteps)
|
|
14644
|
-
|
|
14645
|
-
const
|
|
14646
|
-
const
|
|
15832
|
+
if (scale.strict ? inByStep && outByStep : inByStep || outByStep) continue;
|
|
15833
|
+
if (!scale.strict && !slots[i2].isStrong && slots[i2].value <= shortSteps)
|
|
15834
|
+
continue;
|
|
15835
|
+
const up = clampSemi(walk(scale, semi, 1), MELODY_LOW, MELODY_HIGH);
|
|
15836
|
+
const down = clampSemi(walk(scale, semi, -1), MELODY_LOW, MELODY_HIGH);
|
|
15837
|
+
const score = (s) => (isOutsideCore(scale, s) ? -4 : 0) + toneWeight(s, tones) + (s === before ? -3 : 0) + (after !== null ? -Math.abs(after - s) / 12 : 0);
|
|
14647
15838
|
out[i2] = score(down) >= score(up) ? down : up;
|
|
14648
15839
|
}
|
|
14649
15840
|
};
|
|
14650
|
-
var DIATONIC_PCS = new Set(MAJOR_SCALE2.map((d) => d.semi));
|
|
14651
15841
|
var SHARP_FIFTHS = [0, 7, 2, 9, 4, -1, 6, 1, 8, 3, 10, 5];
|
|
14652
15842
|
var FLAT_FIFTHS = [0, -5, 2, -3, 4, -1, -6, 1, -4, 3, -2, 5];
|
|
14653
|
-
var diatonicFifth = (semi) => degreeToPitch(semitoneToDegree(semi)).fifth;
|
|
14654
15843
|
var nearestOctaveOf = (near, semi) => {
|
|
14655
15844
|
const pc = pitchClass(semi);
|
|
14656
15845
|
let best = pc;
|
|
@@ -14665,7 +15854,7 @@ var nearestOctaveOf = (near, semi) => {
|
|
|
14665
15854
|
}
|
|
14666
15855
|
return best;
|
|
14667
15856
|
};
|
|
14668
|
-
var applyChromatic = (pitches, fifths, slots, tones, opts) => {
|
|
15857
|
+
var applyChromatic = (scale, pitches, fifths, slots, tones, opts) => {
|
|
14669
15858
|
const last = pitches.length - 1;
|
|
14670
15859
|
for (let i2 = 0; i2 < pitches.length; i2++) {
|
|
14671
15860
|
const tone = tones.find(
|
|
@@ -14673,7 +15862,8 @@ var applyChromatic = (pitches, fifths, slots, tones, opts) => {
|
|
|
14673
15862
|
);
|
|
14674
15863
|
if (tone) fifths[i2] = tone.fifth;
|
|
14675
15864
|
}
|
|
14676
|
-
const
|
|
15865
|
+
const pcs = scalePcs(scale);
|
|
15866
|
+
const altered = tones.filter((t) => !pcs.has(pitchClass(t.semi)));
|
|
14677
15867
|
for (let i2 = 0; i2 < pitches.length; i2++) {
|
|
14678
15868
|
if (opts.keepLast && i2 === last) continue;
|
|
14679
15869
|
if (!slots[i2].isStrong && slots[i2].value < opts.quarterSteps) continue;
|
|
@@ -14701,7 +15891,7 @@ var applyChromatic = (pitches, fifths, slots, tones, opts) => {
|
|
|
14701
15891
|
const span = Math.abs(after - before);
|
|
14702
15892
|
const target = span === 2 ? before + dir : span === 3 ? after - dir : null;
|
|
14703
15893
|
if (target === null) continue;
|
|
14704
|
-
if (
|
|
15894
|
+
if (pcs.has(pitchClass(target))) continue;
|
|
14705
15895
|
if (target === before || target === after) continue;
|
|
14706
15896
|
if (target < MELODY_LOW || target > MELODY_HIGH) continue;
|
|
14707
15897
|
pitches[i2] = target;
|
|
@@ -14709,7 +15899,8 @@ var applyChromatic = (pitches, fifths, slots, tones, opts) => {
|
|
|
14709
15899
|
lastAltered = i2;
|
|
14710
15900
|
}
|
|
14711
15901
|
};
|
|
14712
|
-
var draw = (options, resolvedKey, rnd) => {
|
|
15902
|
+
var draw = (options, resolvedKey, scale, rnd) => {
|
|
15903
|
+
const center = resolveCenter(scale);
|
|
14713
15904
|
const stepsPerBar = options.stepsPerBar;
|
|
14714
15905
|
const edo = options.edo === 31 ? 31 : 12;
|
|
14715
15906
|
const scaleStep = (v) => Math.max(1, Math.round(Math.abs(v) * stepsPerBar / BASE_STEPS_PER_BAR)) * Math.sign(v);
|
|
@@ -14735,9 +15926,24 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14735
15926
|
options.template
|
|
14736
15927
|
);
|
|
14737
15928
|
const totalBars = sectionPlan.reduce((sum, s) => sum + s.bars, 0);
|
|
14738
|
-
|
|
15929
|
+
const relativeKinds = /* @__PURE__ */ new Set();
|
|
15930
|
+
let relativeShift = 0;
|
|
15931
|
+
if (rnd() < 0.25 && !center) {
|
|
15932
|
+
for (const kind of pick(
|
|
15933
|
+
[["prechorus"], ["bridge"], ["prechorus", "bridge"]],
|
|
15934
|
+
rnd
|
|
15935
|
+
))
|
|
15936
|
+
relativeKinds.add(kind);
|
|
15937
|
+
if (rnd() < 0.33) relativeShift = resolvedKey.mode === "minor" ? -3 : 3;
|
|
15938
|
+
}
|
|
15939
|
+
const floating = rnd() < 0.12;
|
|
15940
|
+
if (relativeKinds.size > 0 && relativeShift !== 0) {
|
|
15941
|
+
for (const s of sectionPlan)
|
|
15942
|
+
if (relativeKinds.has(s.kind)) s.keyShift = relativeShift;
|
|
15943
|
+
}
|
|
15944
|
+
if (relativeKinds.size === 0 && !floating && rnd() < 0.32) {
|
|
14739
15945
|
const modType = pick(
|
|
14740
|
-
["chorus_up", "chorus_up", "
|
|
15946
|
+
["chorus_up", "chorus_up", "color", "dominant", "subdominant"],
|
|
14741
15947
|
rnd
|
|
14742
15948
|
);
|
|
14743
15949
|
if (modType === "chorus_up") {
|
|
@@ -14746,15 +15952,83 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14746
15952
|
for (let i2 = 0; i2 < sectionPlan.length; i2++) {
|
|
14747
15953
|
if (sectionPlan[i2].kind === "chorus") lastChorusIdx = i2;
|
|
14748
15954
|
}
|
|
14749
|
-
if (lastChorusIdx >= 0)
|
|
14750
|
-
for (let i2 = lastChorusIdx; i2 < sectionPlan.length; i2++)
|
|
15955
|
+
if (lastChorusIdx >= 0)
|
|
15956
|
+
for (let i2 = lastChorusIdx; i2 < sectionPlan.length; i2++)
|
|
14751
15957
|
sectionPlan[i2].keyShift = shift;
|
|
14752
|
-
}
|
|
14753
|
-
}
|
|
14754
15958
|
} else {
|
|
14755
|
-
const shift = pick([-2, 3], rnd);
|
|
14756
|
-
|
|
14757
|
-
|
|
15959
|
+
const shift = modType === "dominant" ? 7 : modType === "subdominant" ? 5 : pick([-2, 3], rnd);
|
|
15960
|
+
const kinds = pick(
|
|
15961
|
+
[["prechorus"], ["bridge"], ["prechorus", "bridge"]],
|
|
15962
|
+
rnd
|
|
15963
|
+
);
|
|
15964
|
+
for (const s of sectionPlan)
|
|
15965
|
+
if (kinds.includes(s.kind)) s.keyShift = shift;
|
|
15966
|
+
}
|
|
15967
|
+
}
|
|
15968
|
+
const harmonyFrom = pick(
|
|
15969
|
+
["chorus", "chorus", "prechorus"],
|
|
15970
|
+
rnd
|
|
15971
|
+
);
|
|
15972
|
+
const harmonyParallel = rnd() < 0.45;
|
|
15973
|
+
const harmonyCoverage = 0.7 + rnd() * 0.3;
|
|
15974
|
+
const useHarmony2 = rnd() < 0.3;
|
|
15975
|
+
const useOctaveLayer = !useHarmony2 && rnd() < 0.25;
|
|
15976
|
+
const octaveCoverage = 0.3 + rnd() * 0.3;
|
|
15977
|
+
const harmonyOffset = useHarmony2 ? (
|
|
15978
|
+
// 3声のときは1声目を下〜ユニゾン側へ寄せ、2声目を上へ回して主旋律を挟む
|
|
15979
|
+
// (参考: チョウチン少女 ch12/ch11/ch13)。
|
|
15980
|
+
pick([-5, -3, 0, 0, 3], rnd)
|
|
15981
|
+
) : harmonyParallel ? pick([3, 4, 5, 9, 7, 0, -5], rnd) : pick([3, 4, 5, 0, -5, -4, -7], rnd);
|
|
15982
|
+
let prevHarmony = null;
|
|
15983
|
+
let prevHarmony2 = null;
|
|
15984
|
+
const harmony2Offset = harmonyOffset + pick([9, 9, 9, 8, 7], rnd);
|
|
15985
|
+
const harmonyKinds = harmonyFrom === "prechorus" ? ["prechorus", "chorus", "bridge"] : ["chorus"];
|
|
15986
|
+
const duetStyle = pick(
|
|
15987
|
+
[
|
|
15988
|
+
"none",
|
|
15989
|
+
"none",
|
|
15990
|
+
"none",
|
|
15991
|
+
"none",
|
|
15992
|
+
"none",
|
|
15993
|
+
"section",
|
|
15994
|
+
"phrase",
|
|
15995
|
+
"chorus",
|
|
15996
|
+
"verse"
|
|
15997
|
+
],
|
|
15998
|
+
rnd
|
|
15999
|
+
);
|
|
16000
|
+
const duetOwner = new Array(totalBars).fill(false);
|
|
16001
|
+
if (duetStyle !== "none") {
|
|
16002
|
+
let melodySection = 0;
|
|
16003
|
+
for (const section of sectionPlan) {
|
|
16004
|
+
if (!section.spec.melody) continue;
|
|
16005
|
+
const isChorus = section.kind === "chorus" || section.kind === "drop_chorus";
|
|
16006
|
+
const isVerse = section.kind === "verse";
|
|
16007
|
+
const takeSection = melodySection % 2 === 1;
|
|
16008
|
+
melodySection++;
|
|
16009
|
+
const alternate = duetStyle === "phrase" ? !isChorus : duetStyle === "chorus" ? isChorus : duetStyle === "verse" ? isVerse : false;
|
|
16010
|
+
if (!alternate && !(duetStyle === "section" && takeSection && !isChorus))
|
|
16011
|
+
continue;
|
|
16012
|
+
for (let b = section.startBar; b < section.startBar + section.bars; b++) {
|
|
16013
|
+
if (alternate) {
|
|
16014
|
+
if (Math.floor((b - section.startBar) / 2) % 2 === 1)
|
|
16015
|
+
duetOwner[b] = true;
|
|
16016
|
+
} else duetOwner[b] = true;
|
|
16017
|
+
}
|
|
16018
|
+
}
|
|
16019
|
+
}
|
|
16020
|
+
const duetSpans = [];
|
|
16021
|
+
{
|
|
16022
|
+
let from = -1;
|
|
16023
|
+
for (let b = 0; b <= totalBars; b++) {
|
|
16024
|
+
const owned = b < totalBars && duetOwner[b];
|
|
16025
|
+
if (owned && from < 0) from = b;
|
|
16026
|
+
if (!owned && from >= 0) {
|
|
16027
|
+
const lead = from === 0 ? 0 : scaleStep(
|
|
16028
|
+
pick([0, 0, EIGHTH, EIGHTH, QUARTER, DOT_QUARTER], rnd)
|
|
16029
|
+
);
|
|
16030
|
+
duetSpans.push([from * stepsPerBar - lead, b * stepsPerBar]);
|
|
16031
|
+
from = -1;
|
|
14758
16032
|
}
|
|
14759
16033
|
}
|
|
14760
16034
|
}
|
|
@@ -14764,51 +16038,129 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14764
16038
|
barKeyShift[b] = s.keyShift;
|
|
14765
16039
|
}
|
|
14766
16040
|
}
|
|
14767
|
-
const progAPool = resolvedKey.mode === "major" ? SECTION_A_PROGRESSIONS.filter((p) => !p[0].startsWith("Am")) : resolvedKey.mode === "minor" ? SECTION_A_PROGRESSIONS.filter((p) => p[0].startsWith("Am")) : SECTION_A_PROGRESSIONS;
|
|
14768
|
-
const
|
|
14769
|
-
|
|
16041
|
+
const progAPool = center ? center.a : resolvedKey.mode === "major" ? SECTION_A_PROGRESSIONS.filter((p) => !p[0].startsWith("Am")) : resolvedKey.mode === "minor" ? SECTION_A_PROGRESSIONS.filter((p) => p[0].startsWith("Am")) : SECTION_A_PROGRESSIONS;
|
|
16042
|
+
const withoutTonic = (pool, root) => {
|
|
16043
|
+
const isTonic = (c) => center ? center.tonicPattern.test(c) : root === "Am" ? /^Am/.test(c) : /^C(?![#b]|m)/.test(c);
|
|
16044
|
+
const out = pool.filter((p) => !p.some(isTonic));
|
|
16045
|
+
return out.length > 0 ? out : pool;
|
|
16046
|
+
};
|
|
16047
|
+
const homeRoot = center ? center.tonic : resolvedKey.mode === "minor" ? "Am" : "C";
|
|
16048
|
+
const progA = pick(
|
|
16049
|
+
floating ? withoutTonic(progAPool, homeRoot) : progAPool,
|
|
16050
|
+
rnd
|
|
16051
|
+
);
|
|
16052
|
+
const progBPool = (center ? center.b : SECTION_B_PROGRESSIONS).filter(
|
|
14770
16053
|
(p) => p.join("|") !== progA.join("|")
|
|
14771
16054
|
);
|
|
14772
|
-
const progB = pick(
|
|
16055
|
+
const progB = pick(
|
|
16056
|
+
floating ? withoutTonic(progBPool, homeRoot) : progBPool,
|
|
16057
|
+
rnd
|
|
16058
|
+
);
|
|
16059
|
+
const progRelativePool = center ? center.a : SECTION_A_PROGRESSIONS.filter(
|
|
16060
|
+
(p) => resolvedKey.mode === "minor" ? !p[0].startsWith("Am") : p[0].startsWith("Am")
|
|
16061
|
+
);
|
|
16062
|
+
const progRelative = pick(
|
|
16063
|
+
floating ? withoutTonic(progRelativePool, homeRoot) : progRelativePool,
|
|
16064
|
+
rnd
|
|
16065
|
+
);
|
|
16066
|
+
const progCPool = (center ? center.c : SECTION_C_PROGRESSIONS).filter(
|
|
16067
|
+
(p) => p.join("|") !== progA.join("|") && p.join("|") !== progB.join("|")
|
|
16068
|
+
);
|
|
14773
16069
|
const progC = pick(
|
|
14774
|
-
|
|
14775
|
-
(p) => p.join("|") !== progA.join("|") && p.join("|") !== progB.join("|")
|
|
14776
|
-
),
|
|
16070
|
+
floating ? withoutTonic(progCPool, homeRoot) : progCPool,
|
|
14777
16071
|
rnd
|
|
14778
16072
|
);
|
|
14779
|
-
const tonic = progA[0].startsWith("Am") ? "Am" : "C";
|
|
14780
|
-
const progHalf = pick(SECTION_A2_DERIVATIONS, rnd)(progA);
|
|
14781
|
-
const progFull = pick(SECTION_A3_DERIVATIONS, rnd)(progA, tonic);
|
|
16073
|
+
const tonic = center ? center.tonic : progA[0].startsWith("Am") ? "Am" : "C";
|
|
16074
|
+
const progHalf = center ? pick(MODAL_HALF_DERIVATIONS, rnd)(progA, center) : pick(SECTION_A2_DERIVATIONS, rnd)(progA);
|
|
16075
|
+
const progFull = center ? pick(MODAL_FULL_DERIVATIONS, rnd)(progA, center) : pick(SECTION_A3_DERIVATIONS, rnd)(progA, tonic);
|
|
16076
|
+
const progDeceptive = center ? pick(MODAL_DECEPTIVE_DERIVATIONS, rnd)(progA, center) : pick(SECTION_DECEPTIVE_DERIVATIONS, rnd)(progA, tonic);
|
|
16077
|
+
let lastChorusBar = -1;
|
|
16078
|
+
for (const section of sectionPlan)
|
|
16079
|
+
if (section.kind === "chorus" || section.kind === "outro")
|
|
16080
|
+
lastChorusBar = section.startBar;
|
|
14782
16081
|
const progression = [];
|
|
14783
16082
|
for (const section of sectionPlan) {
|
|
14784
|
-
const base = section.spec.progression === "c" ? progC : section.spec.progression === "b" ? progB : progA;
|
|
16083
|
+
const base = relativeKinds.has(section.kind) ? progRelative : section.spec.progression === "c" ? progC : section.spec.progression === "b" ? progB : progA;
|
|
14785
16084
|
for (let i2 = 0; i2 < section.bars; i2 += 4) {
|
|
14786
16085
|
const isLastPhrase = i2 + 4 >= section.bars;
|
|
14787
16086
|
if (!isLastPhrase) {
|
|
14788
16087
|
progression.push(...base);
|
|
14789
16088
|
continue;
|
|
14790
16089
|
}
|
|
14791
|
-
if (section.kind
|
|
16090
|
+
if (relativeKinds.has(section.kind)) progression.push(...base);
|
|
16091
|
+
else if (section.kind === "prechorus") progression.push(...progHalf);
|
|
14792
16092
|
else if (section.kind === "chorus" || section.kind === "outro")
|
|
14793
|
-
progression.push(
|
|
16093
|
+
progression.push(
|
|
16094
|
+
...floating ? progHalf : section.startBar === lastChorusBar ? progFull : progDeceptive
|
|
16095
|
+
);
|
|
14794
16096
|
else progression.push(...base);
|
|
14795
16097
|
}
|
|
14796
16098
|
}
|
|
14797
16099
|
progression.length = totalBars;
|
|
16100
|
+
const PIVOT_CHORDS = {
|
|
16101
|
+
7: ["C", "Em7", "G", "Am"],
|
|
16102
|
+
// 属調(ト長調)と共通
|
|
16103
|
+
5: ["C", "Dm7", "F", "Am"]
|
|
16104
|
+
// 下属調(ヘ長調)と共通
|
|
16105
|
+
};
|
|
16106
|
+
for (let bar = 1; bar < totalBars; bar++) {
|
|
16107
|
+
const shift = barKeyShift[bar];
|
|
16108
|
+
const prev = barKeyShift[bar - 1];
|
|
16109
|
+
if (shift === prev) continue;
|
|
16110
|
+
const distance = fifthsDistance(shift - prev);
|
|
16111
|
+
if (distance >= 4) continue;
|
|
16112
|
+
const prevSec = sectionAt(sectionPlan, bar - 1);
|
|
16113
|
+
if (prevSec.kind === "prechorus" || prevSec.kind === "chorus" || prevSec.kind === "outro")
|
|
16114
|
+
continue;
|
|
16115
|
+
if (rnd() < 0.35) continue;
|
|
16116
|
+
const pivots = PIVOT_CHORDS[((shift - prev) % 12 + 12) % 12];
|
|
16117
|
+
if (distance <= 1 && pivots && rnd() < 0.6) {
|
|
16118
|
+
progression[bar - 1] = pick(pivots, rnd);
|
|
16119
|
+
} else {
|
|
16120
|
+
progression[bar - 1] = transposeChordName("G7", shift - prev);
|
|
16121
|
+
}
|
|
16122
|
+
}
|
|
16123
|
+
if (rnd() < 0.3 && !center) {
|
|
16124
|
+
const tonicNames = tonic === "Am" ? ["Am", "Am7"] : ["C", "CM7"];
|
|
16125
|
+
const spots = [];
|
|
16126
|
+
for (let bar = 0; bar + 1 < totalBars; bar++) {
|
|
16127
|
+
if (barKeyShift[bar] !== barKeyShift[bar + 1]) continue;
|
|
16128
|
+
if (!MODAL_BORROW[progression[bar]]) continue;
|
|
16129
|
+
if (!tonicNames.includes(progression[bar + 1])) continue;
|
|
16130
|
+
spots.push(bar);
|
|
16131
|
+
}
|
|
16132
|
+
if (spots.length > 0) {
|
|
16133
|
+
const at = pick(spots, rnd);
|
|
16134
|
+
progression[at] = MODAL_BORROW[progression[at]];
|
|
16135
|
+
}
|
|
16136
|
+
}
|
|
14798
16137
|
const chordProgression = progression.map((chord, bar) => transposeChordName(chord, barKeyShift[bar])).join("|");
|
|
14799
|
-
const chordPattern = pick(CHORD_PATTERNS, rnd);
|
|
14800
16138
|
const rootShift = resolvedKey.rootShift;
|
|
14801
16139
|
const bpm = pick(BPM_CHOICES, rnd);
|
|
16140
|
+
const chordPattern = pick(chordPatternPool(bpm), rnd);
|
|
14802
16141
|
const sourceOf = (kind) => kind === "chorus" || kind === "interlude" || kind === "drop_chorus" ? "b" : kind === "prechorus" ? "a2" : kind === "bridge" ? "c" : "a";
|
|
16142
|
+
const landingOf = (section) => {
|
|
16143
|
+
if (section.spec.landing === null) return null;
|
|
16144
|
+
const relativeHere = relativeKinds.has(section.kind);
|
|
16145
|
+
const tonicDegree = relativeHere ? scale.tonic === 5 ? 0 : 5 : scale.tonic;
|
|
16146
|
+
const size = scaleSize(scale);
|
|
16147
|
+
let landing = (section.spec.landing + tonicDegree) % size;
|
|
16148
|
+
if (floating && landing === tonicDegree)
|
|
16149
|
+
landing = (landing + pick([2, 4], rnd)) % size;
|
|
16150
|
+
return landing;
|
|
16151
|
+
};
|
|
14803
16152
|
const units2 = [];
|
|
14804
16153
|
for (const section of sectionPlan) {
|
|
14805
16154
|
const unitCount = Math.max(1, Math.round(section.bars / 2));
|
|
14806
16155
|
const src = sourceOf(section.kind);
|
|
14807
16156
|
for (let u = 0; u < unitCount; u++) {
|
|
14808
16157
|
if (!section.spec.melody) {
|
|
16158
|
+
const solo2 = section.kind === "interlude";
|
|
14809
16159
|
units2.push({
|
|
14810
|
-
|
|
14811
|
-
|
|
16160
|
+
// 見せ場なので走句と山を交互に置く。`hold` のままだと
|
|
16161
|
+
// リズム型が最も薄いものになり、ソロにならない。
|
|
16162
|
+
role: solo2 ? u % 2 === 0 ? "run" : "climax" : "hold",
|
|
16163
|
+
source: solo2 ? "solo" : "silent",
|
|
14812
16164
|
landing: null,
|
|
14813
16165
|
section
|
|
14814
16166
|
});
|
|
@@ -14817,22 +16169,28 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14817
16169
|
const isLast = u === unitCount - 1;
|
|
14818
16170
|
if (u % 2 === 0) {
|
|
14819
16171
|
units2.push({
|
|
14820
|
-
role: section.kind === "chorus" ? "climax" : src === "a2" || u > 0 ? "sequence" : "motif",
|
|
16172
|
+
role: section.kind === "bridge" ? "step" : section.kind === "chorus" ? "climax" : src === "a2" || u > 0 ? "sequence" : "motif",
|
|
14821
16173
|
source: src,
|
|
14822
16174
|
landing: null,
|
|
14823
16175
|
section
|
|
14824
16176
|
});
|
|
14825
16177
|
} else {
|
|
16178
|
+
const landing = landingOf(section);
|
|
14826
16179
|
units2.push({
|
|
14827
|
-
role: isLast &&
|
|
16180
|
+
role: isLast && landing === 0 ? "cadence" : "answer",
|
|
14828
16181
|
source: "answer",
|
|
14829
|
-
landing: isLast ?
|
|
16182
|
+
landing: isLast ? landing : null,
|
|
14830
16183
|
section
|
|
14831
16184
|
});
|
|
14832
16185
|
}
|
|
14833
16186
|
}
|
|
14834
16187
|
}
|
|
14835
16188
|
const barRoles = units2.flatMap((u) => [u.role, u.role]);
|
|
16189
|
+
for (const section of sectionPlan) {
|
|
16190
|
+
if (section.kind !== "prechorus") continue;
|
|
16191
|
+
const last = section.startBar + section.bars - 1;
|
|
16192
|
+
if (last < barRoles.length) barRoles[last] = "run";
|
|
16193
|
+
}
|
|
14836
16194
|
const barInUnit = (bar) => bar % 2;
|
|
14837
16195
|
const unitOf = (bar) => Math.floor(bar / 2);
|
|
14838
16196
|
const restatementOf = (bar) => {
|
|
@@ -14863,9 +16221,13 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14863
16221
|
groove: pick(["eighth", "sixteenth"], rnd),
|
|
14864
16222
|
arcPeriod: pick([4, 8, 8, 16], rnd),
|
|
14865
16223
|
arcPhase: pick([0, 1, 2], rnd),
|
|
14866
|
-
arcAmp:
|
|
14867
|
-
|
|
14868
|
-
|
|
16224
|
+
arcAmp: 2 + rnd() * 3,
|
|
16225
|
+
// オクターブ跳躍は参考曲では音程の1.0%しかない。上げすぎると音域が広がる。
|
|
16226
|
+
octaveAffinity: 0.06 + rnd() * 0.12,
|
|
16227
|
+
// **音階を厳しく締める曲は必ず中核音の歩数で組む。** ダイアトニックの度数で輪郭を
|
|
16228
|
+
// 作ると、琉球音階なのにレやラが輪郭の中に入り込む。ファ・シを自由に使う
|
|
16229
|
+
// 陽・民謡だけが、曲ごとに掛けたり掛けなかったりする({@link ComposeScale.strict})。
|
|
16230
|
+
pentatonicMotif: rnd() < 0.55 || scale.strict,
|
|
14869
16231
|
runShape: pick(["scale", "turn", "broken", "zigzag"], rnd),
|
|
14870
16232
|
stepShape: pick(
|
|
14871
16233
|
["arch", "valley", "ascend", "descend", "wave", "pivot"],
|
|
@@ -14876,10 +16238,18 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14876
16238
|
["descend", "five-three-one", "leap-up", "hold-tonic"],
|
|
14877
16239
|
rnd
|
|
14878
16240
|
),
|
|
14879
|
-
//
|
|
14880
|
-
|
|
16241
|
+
// 参考曲の跳躍率は p25〜p75 で 0.28〜0.41、最大跳躍の中央値は9半音。
|
|
16242
|
+
// 2声を交互に書いたチャンネルを主旋律と誤検出していた頃は 0.31〜0.65 に
|
|
16243
|
+
// 見えており、それに合わせて上限を高く取っていた。
|
|
16244
|
+
leapAffinity: 0.05 + rnd() * 0.2,
|
|
14881
16245
|
// 界隈曲らしさ:調の外の音(クロマチック)や微小な逸脱を積極的に許容する。
|
|
14882
|
-
|
|
16246
|
+
// 刻みを細かくすると経過音の置き場所が増えるので、同じ係数でも変化音は増える。
|
|
16247
|
+
// 参考曲の1.75倍まで伸びていたぶんを引く。
|
|
16248
|
+
// **音階を厳しく締める曲は変化音を控える。** 半音の経過音は長調・短調の泣きメロの
|
|
16249
|
+
// 芯だが、琉球・都節・律ではその半音が音階の外にしか無く、入れたぶんだけ
|
|
16250
|
+
// 音階の色が薄まる(実測で嬰ヘが3%出て、音階内のラ2%より多いという逆転が
|
|
16251
|
+
// 起きていた)。0 にはしない——民族音階の実際の曲にも装飾の半音は出る。
|
|
16252
|
+
chromaticAffinity: (rnd() < 0.2 ? 0 : 0.12 + rnd() * 0.33) * (scale.strict ? 0.4 : 1),
|
|
14883
16253
|
barHeadWeight: rnd() < 0.5 ? 3 : 2,
|
|
14884
16254
|
bassStyle: pick(
|
|
14885
16255
|
[
|
|
@@ -14906,7 +16276,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14906
16276
|
subInterval: pick([3, 4, 8, 9], rnd)
|
|
14907
16277
|
};
|
|
14908
16278
|
const motifPool = groovyCells(MOTIF_CELLS, style.groove, rnd);
|
|
14909
|
-
const targetNotesPerBar = 4 + rnd() * 4;
|
|
16279
|
+
const targetNotesPerBar = 4.5 + rnd() * 4.5;
|
|
14910
16280
|
const targetRestRatio = 0.02 + rnd() * 0.1;
|
|
14911
16281
|
const cellNotes = (c) => c.value.filter((v) => v > 0).length;
|
|
14912
16282
|
const cellRest = (c) => {
|
|
@@ -14919,17 +16289,27 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14919
16289
|
return total === 0 ? 0 : rest / total;
|
|
14920
16290
|
};
|
|
14921
16291
|
const cellDistance = (c, densityMul = 1) => Math.abs(cellNotes(c) - targetNotesPerBar * densityMul) + Math.abs(cellRest(c) - targetRestRatio / Math.max(0.5, densityMul)) * 8;
|
|
16292
|
+
const weightedPick = (pool) => {
|
|
16293
|
+
let total = 0;
|
|
16294
|
+
for (const c of pool) total += cellWeight(c);
|
|
16295
|
+
let r = rnd() * total;
|
|
16296
|
+
for (const c of pool) {
|
|
16297
|
+
r -= cellWeight(c);
|
|
16298
|
+
if (r <= 0) return c;
|
|
16299
|
+
}
|
|
16300
|
+
return pool[pool.length - 1];
|
|
16301
|
+
};
|
|
14922
16302
|
const pickCell = (pool, densityMul = 1) => {
|
|
14923
|
-
let best =
|
|
16303
|
+
let best = weightedPick(pool);
|
|
14924
16304
|
for (let i2 = 0; i2 < 2; i2++) {
|
|
14925
|
-
const c =
|
|
16305
|
+
const c = weightedPick(pool);
|
|
14926
16306
|
if (cellDistance(c, densityMul) < cellDistance(best, densityMul))
|
|
14927
16307
|
best = c;
|
|
14928
16308
|
}
|
|
14929
16309
|
return best;
|
|
14930
16310
|
};
|
|
14931
16311
|
const motifCell = pickCell(motifPool, 0.85);
|
|
14932
|
-
const motifCell2 = rnd() < 0.
|
|
16312
|
+
const motifCell2 = rnd() < 0.72 ? motifCell : pickCell(
|
|
14933
16313
|
motifPool.filter((c) => c !== motifCell),
|
|
14934
16314
|
0.85
|
|
14935
16315
|
);
|
|
@@ -14947,7 +16327,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14947
16327
|
),
|
|
14948
16328
|
1.1
|
|
14949
16329
|
);
|
|
14950
|
-
const motifA22 = rnd() < 0.
|
|
16330
|
+
const motifA22 = rnd() < 0.72 ? motifA2 : pickCell(
|
|
14951
16331
|
motifPool.filter((c) => c !== motifA2),
|
|
14952
16332
|
1.1
|
|
14953
16333
|
);
|
|
@@ -14957,7 +16337,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14957
16337
|
),
|
|
14958
16338
|
0.9
|
|
14959
16339
|
);
|
|
14960
|
-
const motifC2 = rnd() < 0.
|
|
16340
|
+
const motifC2 = rnd() < 0.72 ? motifC : pickCell(
|
|
14961
16341
|
motifPool.filter((c) => c !== motifC),
|
|
14962
16342
|
0.9
|
|
14963
16343
|
);
|
|
@@ -14996,12 +16376,24 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
14996
16376
|
),
|
|
14997
16377
|
rnd
|
|
14998
16378
|
).value;
|
|
14999
|
-
const
|
|
15000
|
-
|
|
15001
|
-
|
|
15002
|
-
)
|
|
15003
|
-
|
|
15004
|
-
|
|
16379
|
+
const breathBySection = /* @__PURE__ */ new Map();
|
|
16380
|
+
{
|
|
16381
|
+
let prev = null;
|
|
16382
|
+
for (const section of sectionPlan) {
|
|
16383
|
+
if (!section.spec.melody) continue;
|
|
16384
|
+
const pool = PHRASE_END_CELLS.filter((c) => c !== prev);
|
|
16385
|
+
const cell = pick(pool.length > 0 ? pool : PHRASE_END_CELLS, rnd);
|
|
16386
|
+
breathBySection.set(section.startBar, cell);
|
|
16387
|
+
prev = cell;
|
|
16388
|
+
}
|
|
16389
|
+
}
|
|
16390
|
+
const midBreathCell = pick(MID_BREATH_CELLS, rnd);
|
|
16391
|
+
const breathBars = /* @__PURE__ */ new Set();
|
|
16392
|
+
const phraseEndBars = /* @__PURE__ */ new Set();
|
|
16393
|
+
for (const section of sectionPlan) {
|
|
16394
|
+
if (!section.spec.melody) continue;
|
|
16395
|
+
phraseEndBars.add(section.startBar + section.bars - 1);
|
|
16396
|
+
}
|
|
15005
16397
|
const barRhythms = [];
|
|
15006
16398
|
for (let bar = 0; bar < totalBars; bar++) {
|
|
15007
16399
|
const u = unitOf(bar);
|
|
@@ -15009,9 +16401,10 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15009
16401
|
const source = restatementOf(bar);
|
|
15010
16402
|
if (source !== null) {
|
|
15011
16403
|
barRhythms.push(barRhythms[source]);
|
|
16404
|
+
if (breathBars.has(source)) breathBars.add(bar);
|
|
15012
16405
|
continue;
|
|
15013
16406
|
}
|
|
15014
|
-
const isB = units2[u].source === "b";
|
|
16407
|
+
const isB = units2[u].source === "b" || units2[u].source === "solo";
|
|
15015
16408
|
const isA2 = units2[u].source === "a2";
|
|
15016
16409
|
const isC = units2[u].source === "c";
|
|
15017
16410
|
const isPrechorusEnd = units2[u].section.kind === "prechorus" && bar === units2[u].section.startBar + units2[u].section.bars - 1;
|
|
@@ -15026,7 +16419,14 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15026
16419
|
const prevSource = units2[u - 1]?.source;
|
|
15027
16420
|
const [head, tail] = prevSource === "b" ? [motifB, motifB2] : prevSource === "a2" ? [motifA2, motifA22] : [motifCell, motifCell2];
|
|
15028
16421
|
const answerVar = prevSource === "b" ? motifBVar : motifVar;
|
|
15029
|
-
|
|
16422
|
+
if (half === 0) {
|
|
16423
|
+
cell = rnd() < 0.15 ? answerVar : head;
|
|
16424
|
+
} else if (isPeriodEnd) {
|
|
16425
|
+
cell = breathBySection.get(units2[u].section.startBar) ?? tail;
|
|
16426
|
+
breathBars.add(bar);
|
|
16427
|
+
} else {
|
|
16428
|
+
cell = rnd() < 0.28 ? midBreathCell : rnd() < 0.12 ? answerVar : tail;
|
|
16429
|
+
}
|
|
15030
16430
|
} else {
|
|
15031
16431
|
const [head, tail] = pair();
|
|
15032
16432
|
cell = half === 0 ? head : tail;
|
|
@@ -15047,11 +16447,14 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15047
16447
|
motifContour.push(baseDegree + archetype[idx]);
|
|
15048
16448
|
}
|
|
15049
16449
|
const plannedDegrees = new Array(totalBars).fill(null);
|
|
16450
|
+
const motifShiftMemo = /* @__PURE__ */ new Map();
|
|
15050
16451
|
const melody = [];
|
|
15051
16452
|
const submelody = [];
|
|
15052
16453
|
const bass = [];
|
|
15053
16454
|
const harmony = [];
|
|
16455
|
+
const harmony2 = [];
|
|
15054
16456
|
const pad = [];
|
|
16457
|
+
const solo = [];
|
|
15055
16458
|
const melodyDurations = [];
|
|
15056
16459
|
const barTension = new Array(totalBars).fill(0);
|
|
15057
16460
|
let restSteps = 0;
|
|
@@ -15062,9 +16465,9 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15062
16465
|
let chromaticNotes = 0;
|
|
15063
16466
|
let sungBars = 0;
|
|
15064
16467
|
let prevSemi = pick([60, 64, 65, 67, 69, 72, 74, 76], rnd);
|
|
15065
|
-
const pickFigure = (gapSteps,
|
|
16468
|
+
const pickFigure = (gapSteps, scale2) => {
|
|
15066
16469
|
const fits = ANSWER_FIGURES.filter(
|
|
15067
|
-
(f) => f.reduce((sum, v) => sum +
|
|
16470
|
+
(f) => f.reduce((sum, v) => sum + scale2(Math.abs(v)), 0) <= gapSteps
|
|
15068
16471
|
);
|
|
15069
16472
|
return fits.length === 0 ? null : pick(fits, rnd);
|
|
15070
16473
|
};
|
|
@@ -15122,8 +16525,9 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15122
16525
|
slots,
|
|
15123
16526
|
tones,
|
|
15124
16527
|
style,
|
|
16528
|
+
scale,
|
|
15125
16529
|
motifContour,
|
|
15126
|
-
semitoneToDegree(headSemi),
|
|
16530
|
+
semitoneToDegree(scale, headSemi),
|
|
15127
16531
|
contourOffset,
|
|
15128
16532
|
repeatShift,
|
|
15129
16533
|
headWeight,
|
|
@@ -15139,47 +16543,55 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15139
16543
|
...plannedDegrees[source]
|
|
15140
16544
|
);
|
|
15141
16545
|
const landing = units2[unitOf(bar)].landing;
|
|
15142
|
-
if (landing !== null && barInUnit(bar) === 1)
|
|
16546
|
+
if (landing !== null && barInUnit(bar) === 1)
|
|
16547
|
+
landOn(scale, degrees, landing);
|
|
15143
16548
|
plannedDegrees[bar] = [...degrees];
|
|
15144
16549
|
const isMotifBar = source !== null || role === "motif" || role === "sequence" || role === "climax" || role === "answer";
|
|
15145
|
-
|
|
15146
|
-
|
|
16550
|
+
let fitted = degrees;
|
|
16551
|
+
if (isMotifBar) {
|
|
16552
|
+
const shiftKey = degrees.join(",");
|
|
16553
|
+
const r = fitMotif(
|
|
15147
16554
|
degrees,
|
|
15148
16555
|
slots,
|
|
15149
16556
|
tones,
|
|
15150
16557
|
prevSemi,
|
|
15151
16558
|
quarterSteps,
|
|
15152
|
-
|
|
15153
|
-
|
|
15154
|
-
|
|
15155
|
-
|
|
15156
|
-
|
|
15157
|
-
|
|
15158
|
-
|
|
15159
|
-
|
|
15160
|
-
|
|
15161
|
-
|
|
15162
|
-
|
|
15163
|
-
|
|
15164
|
-
|
|
15165
|
-
|
|
15166
|
-
|
|
15167
|
-
|
|
15168
|
-
|
|
15169
|
-
|
|
15170
|
-
|
|
15171
|
-
|
|
15172
|
-
|
|
15173
|
-
|
|
15174
|
-
|
|
15175
|
-
|
|
16559
|
+
scale,
|
|
16560
|
+
style.pentatonicMotif,
|
|
16561
|
+
motifShiftMemo.get(shiftKey) ?? null
|
|
16562
|
+
);
|
|
16563
|
+
fitted = r.degrees;
|
|
16564
|
+
motifShiftMemo.set(shiftKey, r.shift);
|
|
16565
|
+
}
|
|
16566
|
+
const pitches = shapeBar(fitted, slots, tones, prevSemi, {
|
|
16567
|
+
scale,
|
|
16568
|
+
allowLeap: role === "climax",
|
|
16569
|
+
allowArpeggio: role === "climax" || role === "run" && style.runShape === "broken" || role === "cadence" && style.cadenceShape !== "descend",
|
|
16570
|
+
quarterSteps,
|
|
16571
|
+
// モチーフの小節はオクターブ移動を入れない。モチーフは輪郭が命なので、
|
|
16572
|
+
// 後から音を1つ跳ばすと「同じフレーズが返ってきた」と分からなくなる。
|
|
16573
|
+
// モチーフ側は {@link MOTIF_ARCHETYPES} が自前でオクターブを持つ。
|
|
16574
|
+
// モチーフ・セクエンツ・サビの小節はオクターブ移動を入れない
|
|
16575
|
+
// (輪郭が命なので、後から音を1つ跳ばすと同じフレーズと分からなくなる)。
|
|
16576
|
+
// 答えの小節は輪郭を借りているだけなので許す。
|
|
16577
|
+
octaveAffinity: role === "motif" || role === "sequence" || role === "climax" ? 0 : style.octaveAffinity,
|
|
16578
|
+
chromaticAffinity: style.chromaticAffinity,
|
|
16579
|
+
rnd,
|
|
16580
|
+
preserveContour: isMotifBar
|
|
16581
|
+
});
|
|
16582
|
+
if (landing !== null && barInUnit(bar) === 1)
|
|
16583
|
+
landPitch(scale, pitches, landing);
|
|
16584
|
+
const fifths = pitches.map((semi) => scaleFifth(scale, semi));
|
|
16585
|
+
applyChromatic(scale, pitches, fifths, slots, tones, {
|
|
15176
16586
|
affinity: style.chromaticAffinity,
|
|
15177
16587
|
quarterSteps,
|
|
15178
16588
|
shortSteps: scaleStep(EIGHTH),
|
|
15179
16589
|
keepLast: landing !== null && barInUnit(bar) === 1,
|
|
15180
16590
|
rnd
|
|
15181
16591
|
});
|
|
15182
|
-
const
|
|
16592
|
+
const unitSource = units2[unitOf(bar)].source;
|
|
16593
|
+
const isSolo = unitSource === "solo";
|
|
16594
|
+
const silent = unitSource === "silent" || isSolo;
|
|
15183
16595
|
const barHead = pitches[0];
|
|
15184
16596
|
let tensionSum = 0;
|
|
15185
16597
|
let tensionSteps = 0;
|
|
@@ -15187,7 +16599,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15187
16599
|
const semi = pitches[i2];
|
|
15188
16600
|
tensionSum += (3 - toneWeight(semi, tones)) / 3 * slots[i2].value;
|
|
15189
16601
|
tensionSteps += slots[i2].value;
|
|
15190
|
-
if (role !== "climax") {
|
|
16602
|
+
if (!silent && role !== "climax") {
|
|
15191
16603
|
const gap = Math.abs(semi - prevSemi);
|
|
15192
16604
|
maxLeap = Math.max(maxLeap, gap);
|
|
15193
16605
|
intervals++;
|
|
@@ -15196,10 +16608,25 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15196
16608
|
}
|
|
15197
16609
|
const slot = slots[i2];
|
|
15198
16610
|
if (silent) {
|
|
16611
|
+
if (isSolo) {
|
|
16612
|
+
const ks = barKeyShift[bar];
|
|
16613
|
+
const fifthShiftSolo = ks === 0 ? 0 : SEMITONE_TO_FIFTH_SHIFT[(ks % 12 + 12) % 12];
|
|
16614
|
+
solo.push({
|
|
16615
|
+
startStep: barStart + slot.at,
|
|
16616
|
+
pitchUnits: spelledToUnits(
|
|
16617
|
+
semi + ks,
|
|
16618
|
+
fifths[i2] + fifthShiftSolo,
|
|
16619
|
+
edo
|
|
16620
|
+
),
|
|
16621
|
+
durationSteps: slot.value,
|
|
16622
|
+
// ソロは前に出る声部なので、歌メロより気持ち強く弾く。
|
|
16623
|
+
velocity: slot.at === 0 ? 116 : slot.value <= scaleStep(SIXTEENTH) ? 96 : 106
|
|
16624
|
+
});
|
|
16625
|
+
}
|
|
15199
16626
|
prevSemi = semi;
|
|
15200
16627
|
continue;
|
|
15201
16628
|
}
|
|
15202
|
-
if (!
|
|
16629
|
+
if (!scalePcs(scale).has(pitchClass(semi))) chromaticNotes++;
|
|
15203
16630
|
const k = barKeyShift[bar];
|
|
15204
16631
|
const fifthShift = k === 0 ? 0 : SEMITONE_TO_FIFTH_SHIFT[(k % 12 + 12) % 12];
|
|
15205
16632
|
melody.push({
|
|
@@ -15253,7 +16680,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15253
16680
|
subSemi = pushSub(
|
|
15254
16681
|
cursor,
|
|
15255
16682
|
step,
|
|
15256
|
-
i2 === 0 ? subSemi : walk(subSemi, subDir)
|
|
16683
|
+
i2 === 0 ? subSemi : walk(scale, subSemi, subDir)
|
|
15257
16684
|
);
|
|
15258
16685
|
placed++;
|
|
15259
16686
|
}
|
|
@@ -15277,7 +16704,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15277
16704
|
subSemi = pushSub(
|
|
15278
16705
|
cursor,
|
|
15279
16706
|
step,
|
|
15280
|
-
index === 0 ? subSemi : walk(subSemi, subDir * (index % 2 === 0 ? 1 : -1))
|
|
16707
|
+
index === 0 ? subSemi : walk(scale, subSemi, subDir * (index % 2 === 0 ? 1 : -1))
|
|
15281
16708
|
);
|
|
15282
16709
|
index++;
|
|
15283
16710
|
}
|
|
@@ -15287,30 +16714,62 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15287
16714
|
pushSub(0, stepsPerBar, subSemi);
|
|
15288
16715
|
} else if (subStyle === "long-short") {
|
|
15289
16716
|
subSemi = pushSub(0, scaleStep(DOT_HALF), subSemi);
|
|
15290
|
-
pushSub(
|
|
16717
|
+
pushSub(
|
|
16718
|
+
scaleStep(DOT_HALF),
|
|
16719
|
+
scaleStep(QUARTER),
|
|
16720
|
+
walk(scale, subSemi, subDir)
|
|
16721
|
+
);
|
|
15291
16722
|
} else if (role === "cadence") {
|
|
15292
16723
|
pushSub(0, stepsPerBar, subSemi);
|
|
15293
16724
|
} else {
|
|
15294
16725
|
pushSub(scaleStep(QUARTER), scaleStep(DOT_HALF), subSemi);
|
|
15295
16726
|
}
|
|
15296
16727
|
const barSec = sectionAt(sectionPlan, bar);
|
|
15297
|
-
if (!silent && (barSec.kind
|
|
15298
|
-
|
|
15299
|
-
|
|
15300
|
-
|
|
15301
|
-
|
|
15302
|
-
const
|
|
15303
|
-
|
|
15304
|
-
|
|
15305
|
-
|
|
15306
|
-
|
|
15307
|
-
|
|
15308
|
-
|
|
15309
|
-
|
|
15310
|
-
|
|
15311
|
-
|
|
15312
|
-
|
|
15313
|
-
|
|
16728
|
+
if (!silent && harmonyKinds.includes(barSec.kind)) {
|
|
16729
|
+
const k = barKeyShift[bar];
|
|
16730
|
+
const fifthShift = k === 0 ? 0 : SEMITONE_TO_FIFTH_SHIFT[(k % 12 + 12) % 12];
|
|
16731
|
+
const writeHarmony = (out, prev, offset, against) => {
|
|
16732
|
+
let last = prev;
|
|
16733
|
+
const written = [];
|
|
16734
|
+
for (let i2 = 0; i2 < slots.length; i2++) {
|
|
16735
|
+
const hTone = harmonyPitch(
|
|
16736
|
+
scale,
|
|
16737
|
+
pitches[i2],
|
|
16738
|
+
tones,
|
|
16739
|
+
last,
|
|
16740
|
+
offset,
|
|
16741
|
+
harmonyParallel,
|
|
16742
|
+
against?.[i2] ?? null
|
|
16743
|
+
);
|
|
16744
|
+
let hClamped = clampSemi(
|
|
16745
|
+
hTone.semi,
|
|
16746
|
+
MELODY_LOW - 12,
|
|
16747
|
+
MELODY_HIGH + 7
|
|
16748
|
+
);
|
|
16749
|
+
while (hClamped - pitches[i2] > 12) hClamped -= 12;
|
|
16750
|
+
while (hClamped - pitches[i2] < -12) hClamped += 12;
|
|
16751
|
+
last = hClamped;
|
|
16752
|
+
written.push(hClamped);
|
|
16753
|
+
const keep = slots[i2].isStrong || slots[i2].value >= quarterSteps || rnd() < harmonyCoverage;
|
|
16754
|
+
if (!keep) continue;
|
|
16755
|
+
out.push({
|
|
16756
|
+
startStep: barStart + slots[i2].at,
|
|
16757
|
+
pitchUnits: spelledToUnits(
|
|
16758
|
+
hClamped + k,
|
|
16759
|
+
hTone.fifth + fifthShift,
|
|
16760
|
+
edo
|
|
16761
|
+
),
|
|
16762
|
+
durationSteps: slots[i2].value,
|
|
16763
|
+
velocity: slots[i2].at === 0 ? 82 : 76
|
|
16764
|
+
});
|
|
16765
|
+
}
|
|
16766
|
+
return written;
|
|
16767
|
+
};
|
|
16768
|
+
const h1 = writeHarmony(harmony, prevHarmony, harmonyOffset, null);
|
|
16769
|
+
prevHarmony = h1[h1.length - 1] ?? prevHarmony;
|
|
16770
|
+
if (useHarmony2) {
|
|
16771
|
+
const h2 = writeHarmony(harmony2, prevHarmony2, harmony2Offset, h1);
|
|
16772
|
+
prevHarmony2 = h2[h2.length - 1] ?? prevHarmony2;
|
|
15314
16773
|
}
|
|
15315
16774
|
}
|
|
15316
16775
|
if (barSec.kind === "prechorus" || barSec.kind === "chorus" || barSec.kind === "bridge" || barSec.kind === "drop_chorus") {
|
|
@@ -15345,6 +16804,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15345
16804
|
const nextTones = chordTones(progression[(bar + 1) % totalBars]);
|
|
15346
16805
|
const A = clampSemi(
|
|
15347
16806
|
walk(
|
|
16807
|
+
scale,
|
|
15348
16808
|
nextTones[0] ? clampSemi(nextTones[0].semi, BASS_LOW, BASS_HIGH) : R,
|
|
15349
16809
|
-1
|
|
15350
16810
|
),
|
|
@@ -15401,7 +16861,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15401
16861
|
let bassCursor = 0;
|
|
15402
16862
|
for (const [semi, value] of bassCell) {
|
|
15403
16863
|
const len = scaleStep(value);
|
|
15404
|
-
const fifth = semi === R || semi === O ? rootTone.fifth : semi === F ? fifthTone?.fifth ?? rootTone.fifth : semi === T ? thirdTone?.fifth ?? rootTone.fifth :
|
|
16864
|
+
const fifth = semi === R || semi === O ? rootTone.fifth : semi === F ? fifthTone?.fifth ?? rootTone.fifth : semi === T ? thirdTone?.fifth ?? rootTone.fifth : scaleFifth(scale, semi);
|
|
15405
16865
|
const k = barKeyShift[bar];
|
|
15406
16866
|
const fifthShift = k === 0 ? 0 : SEMITONE_TO_FIFTH_SHIFT[(k % 12 + 12) % 12];
|
|
15407
16867
|
barBass.push({
|
|
@@ -15442,6 +16902,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15442
16902
|
for (const n of barBass) bass.push(n);
|
|
15443
16903
|
}
|
|
15444
16904
|
const eighthSteps = scaleStep(EIGHTH);
|
|
16905
|
+
const tieMemo = /* @__PURE__ */ new Map();
|
|
15445
16906
|
for (let i2 = 0; i2 < melody.length - 1; i2++) {
|
|
15446
16907
|
const cur = melody[i2];
|
|
15447
16908
|
const nxt = melody[i2 + 1];
|
|
@@ -15455,40 +16916,71 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15455
16916
|
const curSec = sectionAt(sectionPlan, barIdx - 1);
|
|
15456
16917
|
const nextSec = sectionAt(sectionPlan, barIdx);
|
|
15457
16918
|
if (!nextSec.spec.melody || curSec !== nextSec) continue;
|
|
16919
|
+
if (breathBars.has(barIdx)) continue;
|
|
15458
16920
|
const curSemi = Math.round(cur.pitchUnits / UNITS_PER_SEMITONE);
|
|
15459
16921
|
const nxtSemi = Math.round(nxt.pitchUnits / UNITS_PER_SEMITONE);
|
|
15460
16922
|
if (Math.abs(nxtSemi - curSemi) > 3) continue;
|
|
16923
|
+
const after = melody[i2 + 2];
|
|
16924
|
+
if (after && Math.floor(after.startStep / stepsPerBar) === barIdx) {
|
|
16925
|
+
const afterSemi = Math.round(after.pitchUnits / UNITS_PER_SEMITONE) - (barKeyShift[barIdx] ?? 0);
|
|
16926
|
+
if (!scalePcs(scale).has(pitchClass(afterSemi))) continue;
|
|
16927
|
+
}
|
|
15461
16928
|
const nextRole = barRoles[barIdx];
|
|
15462
|
-
let tieProb = 0.
|
|
15463
|
-
if (nextRole === "motif") tieProb = 0.
|
|
15464
|
-
else if (nextRole === "sequence") tieProb = 0.
|
|
15465
|
-
else if (nextRole === "climax") tieProb = 0.
|
|
16929
|
+
let tieProb = 0.3;
|
|
16930
|
+
if (nextRole === "motif") tieProb = 0.1;
|
|
16931
|
+
else if (nextRole === "sequence") tieProb = 0.35;
|
|
16932
|
+
else if (nextRole === "climax") tieProb = 0.45;
|
|
15466
16933
|
else if (nextRole === "cadence") tieProb = 0.1;
|
|
15467
|
-
|
|
16934
|
+
const tieKey = `${barRhythms[barIdx].join(",")}|${barInUnit(barIdx)}`;
|
|
16935
|
+
let tie = tieMemo.get(tieKey);
|
|
16936
|
+
if (tie === void 0) {
|
|
16937
|
+
tie = rnd() < tieProb;
|
|
16938
|
+
tieMemo.set(tieKey, tie);
|
|
16939
|
+
}
|
|
16940
|
+
if (tie) {
|
|
15468
16941
|
cur.durationSteps += nxt.durationSteps;
|
|
15469
16942
|
melody.splice(i2 + 1, 1);
|
|
15470
16943
|
if (i2 < melodyDurations.length - 1) {
|
|
15471
16944
|
melodyDurations[i2] += melodyDurations[i2 + 1];
|
|
15472
16945
|
melodyDurations.splice(i2 + 1, 1);
|
|
15473
16946
|
}
|
|
15474
|
-
const
|
|
15475
|
-
|
|
15476
|
-
|
|
15477
|
-
|
|
15478
|
-
|
|
16947
|
+
for (const voice of [harmony, harmony2]) {
|
|
16948
|
+
const nxtIdx = voice.findIndex((h) => h.startStep === nxt.startStep);
|
|
16949
|
+
if (nxtIdx < 0) continue;
|
|
16950
|
+
const curIdx = voice.findIndex((h) => h.startStep === cur.startStep);
|
|
16951
|
+
if (curIdx >= 0)
|
|
16952
|
+
voice[curIdx].durationSteps += voice[nxtIdx].durationSteps;
|
|
16953
|
+
voice.splice(nxtIdx, 1);
|
|
15479
16954
|
}
|
|
15480
16955
|
i2--;
|
|
15481
16956
|
}
|
|
15482
16957
|
}
|
|
16958
|
+
const splitMemo = /* @__PURE__ */ new Map();
|
|
16959
|
+
let splitLastBar = -1;
|
|
16960
|
+
let splitIdxInBar = 0;
|
|
15483
16961
|
for (let i2 = 0; i2 < melody.length; i2++) {
|
|
15484
16962
|
const barIdx = Math.floor(melody[i2].startStep / stepsPerBar);
|
|
16963
|
+
if (barIdx !== splitLastBar) {
|
|
16964
|
+
splitLastBar = barIdx;
|
|
16965
|
+
splitIdxInBar = 0;
|
|
16966
|
+
} else splitIdxInBar++;
|
|
15485
16967
|
if (barIdx >= totalBars) continue;
|
|
16968
|
+
if (phraseEndBars.has(barIdx)) continue;
|
|
15486
16969
|
const role = barRoles[barIdx];
|
|
15487
|
-
let splitProb = 0.
|
|
16970
|
+
let splitProb = 0.08;
|
|
15488
16971
|
if (role === "motif" || role === "sequence") splitProb = 0;
|
|
15489
|
-
else if (role === "climax") splitProb = 0.
|
|
16972
|
+
else if (role === "climax") splitProb = 0.3;
|
|
15490
16973
|
else if (role === "cadence") splitProb = 0;
|
|
15491
|
-
|
|
16974
|
+
let doSplit = false;
|
|
16975
|
+
if (melody[i2].durationSteps === quarterSteps) {
|
|
16976
|
+
const key = `${barRhythms[barIdx].join(",")}|${barInUnit(barIdx)}|${role}|${splitIdxInBar}`;
|
|
16977
|
+
const memo = splitMemo.get(key);
|
|
16978
|
+
if (memo === void 0) {
|
|
16979
|
+
doSplit = rnd() < splitProb;
|
|
16980
|
+
splitMemo.set(key, doSplit);
|
|
16981
|
+
} else doSplit = memo;
|
|
16982
|
+
}
|
|
16983
|
+
if (doSplit) {
|
|
15492
16984
|
const half = scaleStep(EIGHTH);
|
|
15493
16985
|
const newNote = {
|
|
15494
16986
|
...melody[i2],
|
|
@@ -15502,6 +16994,7 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15502
16994
|
melodyDurations.splice(i2 + 1, 0, half);
|
|
15503
16995
|
}
|
|
15504
16996
|
i2++;
|
|
16997
|
+
splitIdxInBar++;
|
|
15505
16998
|
}
|
|
15506
16999
|
}
|
|
15507
17000
|
const range = (notes) => {
|
|
@@ -15511,23 +17004,39 @@ var draw = (options, resolvedKey, rnd) => {
|
|
|
15511
17004
|
};
|
|
15512
17005
|
const shiftUnits = semitonesToUnits(rootShift, edo);
|
|
15513
17006
|
if (shiftUnits !== 0)
|
|
15514
|
-
for (const list of [melody, submelody, bass, harmony, pad])
|
|
17007
|
+
for (const list of [melody, submelody, bass, harmony, harmony2, pad, solo])
|
|
15515
17008
|
for (const n of list) n.pitchUnits = n.pitchUnits + shiftUnits;
|
|
17009
|
+
const octave = useOctaveLayer ? melody.filter(
|
|
17010
|
+
(n) => n.durationSteps >= quarterSteps || rnd() < octaveCoverage
|
|
17011
|
+
).map((n) => ({ ...n, velocity: Math.max(40, n.velocity - 26) })) : [];
|
|
15516
17012
|
return {
|
|
15517
17013
|
chordProgression,
|
|
15518
17014
|
chordPattern,
|
|
15519
17015
|
rootShift,
|
|
15520
17016
|
keyName: resolvedKey.keyName,
|
|
15521
17017
|
keyLabel: resolvedKey.keyLabel,
|
|
17018
|
+
scaleId: scale.id,
|
|
17019
|
+
scaleLabel: scale.label,
|
|
15522
17020
|
moodLabel: resolvedKey.moodLabel,
|
|
15523
17021
|
bpm,
|
|
15524
17022
|
sections: sectionPlan,
|
|
15525
17023
|
bars: totalBars,
|
|
17024
|
+
vocal: {
|
|
17025
|
+
duetSpans,
|
|
17026
|
+
duetStyle,
|
|
17027
|
+
harmonyKinds,
|
|
17028
|
+
harmony2: useHarmony2,
|
|
17029
|
+
octaveLayer: useOctaveLayer
|
|
17030
|
+
},
|
|
17031
|
+
tonal: { relativeKinds: [...relativeKinds], relativeShift, floating },
|
|
15526
17032
|
melody,
|
|
15527
17033
|
submelody,
|
|
15528
17034
|
bass,
|
|
15529
17035
|
harmony,
|
|
17036
|
+
harmony2,
|
|
17037
|
+
octave,
|
|
15530
17038
|
pad,
|
|
17039
|
+
solo,
|
|
15531
17040
|
melodyDurations,
|
|
15532
17041
|
restSteps,
|
|
15533
17042
|
totalSteps: Math.max(1, sungBars) * stepsPerBar,
|
|
@@ -15598,6 +17107,8 @@ var evaluate = (d, recent) => {
|
|
|
15598
17107
|
melodyRange: atc("melodyRange", d.melodyRange),
|
|
15599
17108
|
notesPerBar: atc("notesPerBar", density.notesPerBar),
|
|
15600
17109
|
shortNoteRatio: atc("shortNoteRatio", density.shortNoteRatio),
|
|
17110
|
+
barDensityCv: atc("barDensityCv", density.barDensityCv),
|
|
17111
|
+
densityCliff: atc("densityCliff", density.densityCliff),
|
|
15601
17112
|
stepRatio: atc("stepRatio", d.stepRatio),
|
|
15602
17113
|
chromaticRatio: atc("chromaticRatio", d.chromaticRatio),
|
|
15603
17114
|
sim1: atc("sim1", structure.sim1),
|
|
@@ -15605,12 +17116,20 @@ var evaluate = (d, recent) => {
|
|
|
15605
17116
|
sim4: atc("sim4", structure.sim4),
|
|
15606
17117
|
sim8: atc("sim8", structure.sim8),
|
|
15607
17118
|
phraseBreath: atc("phraseBreath", structure.phraseBreath),
|
|
17119
|
+
turnRatio: atc("turnRatio", structure.turnRatio),
|
|
15608
17120
|
climaxPosition: atc("climaxPosition", structure.climaxPosition),
|
|
15609
17121
|
climaxPeaks: at(peakBand, structure.climaxPeaks),
|
|
15610
17122
|
complementarity: at(HAND_BANDS.complementarity, structure.complementarity),
|
|
15611
17123
|
subDensity: at(HAND_BANDS.subDensity, d.submelody.length / d.bars),
|
|
17124
|
+
// サブメロにも同じ崖の物差しを当てる。帯はメロディから採ったものを流用する。
|
|
17125
|
+
subDensityCliff: atc(
|
|
17126
|
+
"densityCliff",
|
|
17127
|
+
densityFeatures(fromMelody(toMetricNotes(d.submelody)), opts).densityCliff
|
|
17128
|
+
),
|
|
15612
17129
|
tensionRise: tension.rise,
|
|
15613
|
-
|
|
17130
|
+
// **浮遊感の曲に「終止で解決しろ」は要求しない。** 解決しないことが狙いなので、
|
|
17131
|
+
// この項目で減点すると候補40本の選抜で必ず負けて、狙って引いた曲が出てこない。
|
|
17132
|
+
tensionResolve: d.tonal.floating ? 1 : tension.resolve,
|
|
15614
17133
|
novelty
|
|
15615
17134
|
};
|
|
15616
17135
|
let weighted = 0;
|
|
@@ -15647,12 +17166,17 @@ var composeSong = (options) => {
|
|
|
15647
17166
|
const recent = options.recent ?? [];
|
|
15648
17167
|
const count = Math.max(1, options.drawCount ?? DRAW_COUNT);
|
|
15649
17168
|
const resolvedKey = resolveComposeKey(options.baseKey, rnd);
|
|
17169
|
+
const scale = resolveComposeScale(
|
|
17170
|
+
options.scale,
|
|
17171
|
+
resolvedKey.mode === "minor",
|
|
17172
|
+
rnd
|
|
17173
|
+
);
|
|
15650
17174
|
let best = null;
|
|
15651
17175
|
let bestScore = Number.NEGATIVE_INFINITY;
|
|
15652
17176
|
let bestIsValid = false;
|
|
15653
17177
|
let rejected = 0;
|
|
15654
17178
|
for (let attempt = 1; attempt <= count; attempt++) {
|
|
15655
|
-
const d = draw(options, resolvedKey, rnd);
|
|
17179
|
+
const d = draw(options, resolvedKey, scale, rnd);
|
|
15656
17180
|
const { stats, ok } = evaluate(d, recent);
|
|
15657
17181
|
if (!ok) rejected++;
|
|
15658
17182
|
const better = ok === bestIsValid ? stats.score > bestScore : ok;
|
|
@@ -15660,24 +17184,32 @@ var composeSong = (options) => {
|
|
|
15660
17184
|
bestScore = stats.score;
|
|
15661
17185
|
bestIsValid = ok;
|
|
15662
17186
|
best = {
|
|
15663
|
-
//
|
|
15664
|
-
//
|
|
17187
|
+
// ドラム・楽器・編曲プランは勝った候補にだけ後から付ける(メロディに
|
|
17188
|
+
// 依存しないので候補ごとに引いても採点は動かず、40本ぶん無駄になる)。
|
|
15665
17189
|
drum: "",
|
|
15666
17190
|
instrument: "",
|
|
17191
|
+
arrange: EMPTY_ARRANGE,
|
|
15667
17192
|
chordProgression: d.chordProgression,
|
|
15668
17193
|
chordPattern: d.chordPattern,
|
|
15669
17194
|
rootShift: d.rootShift,
|
|
15670
17195
|
keyName: d.keyName,
|
|
15671
17196
|
keyLabel: d.keyLabel,
|
|
17197
|
+
scaleId: scale.id,
|
|
17198
|
+
scaleLabel: scale.label,
|
|
15672
17199
|
moodLabel: d.moodLabel,
|
|
15673
17200
|
bpm: d.bpm,
|
|
15674
17201
|
sections: d.sections,
|
|
15675
17202
|
bars: d.bars,
|
|
17203
|
+
vocal: d.vocal,
|
|
17204
|
+
tonal: d.tonal,
|
|
15676
17205
|
melody: d.melody,
|
|
15677
17206
|
submelody: d.submelody,
|
|
15678
17207
|
bass: d.bass,
|
|
15679
17208
|
harmony: d.harmony,
|
|
17209
|
+
harmony2: d.harmony2,
|
|
17210
|
+
octave: d.octave,
|
|
15680
17211
|
pad: d.pad,
|
|
17212
|
+
solo: d.solo,
|
|
15681
17213
|
stats: { ...stats, attempts: attempt, rejected }
|
|
15682
17214
|
};
|
|
15683
17215
|
}
|
|
@@ -15686,14 +17218,92 @@ var composeSong = (options) => {
|
|
|
15686
17218
|
result.stats.rejected = rejected;
|
|
15687
17219
|
result.drum = pickBuiltinDrum(result, rnd);
|
|
15688
17220
|
result.instrument = pickBuiltinInstrument(result, rnd);
|
|
17221
|
+
result.arrange = buildArrangePlan(result, rnd);
|
|
15689
17222
|
return result;
|
|
15690
17223
|
};
|
|
15691
17224
|
var pickBuiltinDrum = (song, rnd) => {
|
|
15692
17225
|
const eighth = BASE_STEPS_PER_BAR / 8;
|
|
15693
17226
|
const short = song.melody.filter((n) => n.durationSteps <= eighth).length / Math.max(1, song.melody.length);
|
|
15694
|
-
const
|
|
17227
|
+
const dotted = song.melody.filter(
|
|
17228
|
+
(n) => n.durationSteps === Math.round(BASE_STEPS_PER_BAR * 3 / 16)
|
|
17229
|
+
).length / Math.max(1, song.melody.length);
|
|
17230
|
+
const pool = dotted >= 0.08 ? ["shuffle", "8beat", "16beat"] : song.bpm >= 150 ? ["4beat", "dance", "16beat", "disco"] : short >= 0.85 ? ["16beat", "dance", "disco"] : song.bpm <= 115 ? ["bossa", "8beat", "shuffle", "4beat"] : ["8beat", "4beat", "16beat", "dance"];
|
|
15695
17231
|
return pick(pool, rnd);
|
|
15696
17232
|
};
|
|
17233
|
+
var EMPTY_ARRANGE = {
|
|
17234
|
+
backing: [],
|
|
17235
|
+
sparkle: null,
|
|
17236
|
+
padSections: [],
|
|
17237
|
+
lead: null,
|
|
17238
|
+
bassLayer: null
|
|
17239
|
+
};
|
|
17240
|
+
var LOUD_KINDS = ["prechorus", "chorus", "bridge"];
|
|
17241
|
+
var QUIET_KINDS = [
|
|
17242
|
+
"intro",
|
|
17243
|
+
"verse",
|
|
17244
|
+
"interlude",
|
|
17245
|
+
"drop_chorus",
|
|
17246
|
+
"outro"
|
|
17247
|
+
];
|
|
17248
|
+
var CHORUS_KINDS = ["chorus", "drop_chorus"];
|
|
17249
|
+
var buildArrangePlan = (song, rnd) => {
|
|
17250
|
+
const present = new Set(song.sections.map((s) => s.kind));
|
|
17251
|
+
const narrow = (kinds) => {
|
|
17252
|
+
const hit = kinds.filter((k) => present.has(k));
|
|
17253
|
+
return hit.length === 0 ? null : hit;
|
|
17254
|
+
};
|
|
17255
|
+
const base = {
|
|
17256
|
+
pattern: song.chordPattern,
|
|
17257
|
+
sections: null,
|
|
17258
|
+
octave: 0
|
|
17259
|
+
};
|
|
17260
|
+
const others = chordPatternPool(song.bpm).filter((p) => p !== base.pattern);
|
|
17261
|
+
const backing = [base];
|
|
17262
|
+
const addKinds = pick(
|
|
17263
|
+
[LOUD_KINDS, CHORUS_KINDS, LOUD_KINDS, QUIET_KINDS],
|
|
17264
|
+
rnd
|
|
17265
|
+
);
|
|
17266
|
+
const second = pick(others, rnd);
|
|
17267
|
+
backing.push({
|
|
17268
|
+
pattern: second,
|
|
17269
|
+
sections: narrow(addKinds),
|
|
17270
|
+
octave: 0
|
|
17271
|
+
});
|
|
17272
|
+
if (rnd() < 0.55) {
|
|
17273
|
+
const rest = others.filter((p) => p !== second);
|
|
17274
|
+
backing.push({
|
|
17275
|
+
pattern: pick(rest.length > 0 ? rest : others, rnd),
|
|
17276
|
+
// 2本目と逆側へ置く(両方サビに寄せると、サビだけ団子になる)。
|
|
17277
|
+
sections: narrow(addKinds === QUIET_KINDS ? LOUD_KINDS : QUIET_KINDS),
|
|
17278
|
+
octave: 0
|
|
17279
|
+
});
|
|
17280
|
+
}
|
|
17281
|
+
const sparklePool = chordPatternPool(song.bpm).filter(
|
|
17282
|
+
(p) => p !== "block" && !backing.some((b) => b.pattern === p)
|
|
17283
|
+
);
|
|
17284
|
+
const sparkle = sparklePool.length > 0 && rnd() < 0.7 ? {
|
|
17285
|
+
pattern: pick(sparklePool, rnd),
|
|
17286
|
+
sections: narrow(pick([LOUD_KINDS, CHORUS_KINDS], rnd)) ?? CHORUS_KINDS,
|
|
17287
|
+
octave: 1
|
|
17288
|
+
} : null;
|
|
17289
|
+
const padSections = narrow(
|
|
17290
|
+
pick(
|
|
17291
|
+
[
|
|
17292
|
+
["prechorus", "chorus", "bridge", "drop_chorus"],
|
|
17293
|
+
["chorus", "drop_chorus"],
|
|
17294
|
+
["prechorus", "chorus", "bridge", "drop_chorus"],
|
|
17295
|
+
["bridge", "chorus"]
|
|
17296
|
+
],
|
|
17297
|
+
rnd
|
|
17298
|
+
)
|
|
17299
|
+
) ?? [];
|
|
17300
|
+
const lead = rnd() < 0.75 ? {
|
|
17301
|
+
sections: narrow(pick([CHORUS_KINDS, LOUD_KINDS], rnd)) ?? CHORUS_KINDS,
|
|
17302
|
+
octave: rnd() < 0.5 ? 0 : 1
|
|
17303
|
+
} : null;
|
|
17304
|
+
const bassLayer = rnd() < 0.25 ? { sections: narrow(CHORUS_KINDS) ?? CHORUS_KINDS, octave: 1 } : null;
|
|
17305
|
+
return { backing, sparkle, padSections, lead, bassLayer };
|
|
17306
|
+
};
|
|
15697
17307
|
var pickBuiltinInstrument = (song, rnd) => {
|
|
15698
17308
|
const eighth = BASE_STEPS_PER_BAR / 8;
|
|
15699
17309
|
const short = song.melody.filter((n) => n.durationSteps <= eighth).length / Math.max(1, song.melody.length);
|
|
@@ -15705,7 +17315,7 @@ var pickBuiltinInstrument = (song, rnd) => {
|
|
|
15705
17315
|
pool = song.bpm >= 150 ? ["cyber_punk", "synth_pop", "retro_game"] : ["synth_pop", "retro_game", "rock", "piano"];
|
|
15706
17316
|
} else if (song.drum === "bossa") {
|
|
15707
17317
|
pool = ["jazz_night", "acoustic", "piano"];
|
|
15708
|
-
} else if (song.bpm <=
|
|
17318
|
+
} else if (song.bpm <= 115) {
|
|
15709
17319
|
pool = ["ambient_cloud", "acoustic", "orchestra", "piano", "fantasy_rpg"];
|
|
15710
17320
|
} else if (song.bpm >= 145) {
|
|
15711
17321
|
pool = ["rock", "synth_pop", "cyber_punk", "retro_game", "piano"];
|
|
@@ -15761,6 +17371,23 @@ var LYRIC_WORDS = [
|
|
|
15761
17371
|
"\u305B\u304B\u3044",
|
|
15762
17372
|
"\u304D\u305B\u3064"
|
|
15763
17373
|
];
|
|
17374
|
+
var alignLyrics = (source, lyrics, target, options) => {
|
|
17375
|
+
const sorted = [...source].sort((a, b) => a.startStep - b.startStep);
|
|
17376
|
+
const kana = [...lyrics].filter((c) => c !== "\u3001");
|
|
17377
|
+
const at = /* @__PURE__ */ new Map();
|
|
17378
|
+
for (let i2 = 0; i2 < sorted.length && i2 < kana.length; i2++)
|
|
17379
|
+
at.set(sorted[i2].startStep, kana[i2]);
|
|
17380
|
+
const { stepsPerBar } = options;
|
|
17381
|
+
const tgt = [...target].sort((a, b) => a.startStep - b.startStep);
|
|
17382
|
+
const out = [];
|
|
17383
|
+
for (let i2 = 0; i2 < tgt.length; i2++) {
|
|
17384
|
+
out.push(at.get(tgt[i2].startStep) ?? "\u30FC");
|
|
17385
|
+
const next = tgt[i2 + 1];
|
|
17386
|
+
if (next && Math.floor(tgt[i2].startStep / (stepsPerBar * 4)) !== Math.floor(next.startStep / (stepsPerBar * 4)))
|
|
17387
|
+
out.push("\u3001");
|
|
17388
|
+
}
|
|
17389
|
+
return out.join("");
|
|
17390
|
+
};
|
|
15764
17391
|
var composeLyrics = (melody, options) => {
|
|
15765
17392
|
const rnd = options.random ?? Math.random;
|
|
15766
17393
|
const { stepsPerBar } = options;
|
|
@@ -16207,6 +17834,34 @@ var buildUI = (target, options) => {
|
|
|
16207
17834
|
<span class="dtm-grow"></span>
|
|
16208
17835
|
<span class="dtm-hint" data-dtm="compose-key-hint"></span>
|
|
16209
17836
|
</div>
|
|
17837
|
+
<div class="dtm-row" data-dtm="compose-scale-row">
|
|
17838
|
+
<span class="dtm-label">\u97F3\u968E</span>
|
|
17839
|
+
<select class="dtm-select" data-dtm="compose-scale" title="\u65CB\u5F8B\u304C\u4F7F\u3046\u97F3\u968E\u3092\u9078\u3073\u307E\u3059\u3002\u30D9\u30FC\u30B9\u8ABF\uFF08\u4E3B\u97F3\u306E\u9AD8\u3055\uFF09\u3068\u306F\u72EC\u7ACB\u3057\u305F\u8A2D\u5B9A\u3067\u3059">
|
|
17840
|
+
<option value="auto" title="\u30D9\u30FC\u30B9\u8ABF\u306E\u9577\u77ED\u306B\u5408\u308F\u305B\u3066\u3001\u967D\u97F3\u968E\uFF08\u9577\u8ABF\uFF09\u304B\u6C11\u8B21\u97F3\u968E\uFF08\u77ED\u8ABF\uFF09\u3092\u4F7F\u3044\u307E\u3059">\u304A\u307E\u304B\u305B\uFF08\u5F93\u6765\u3069\u304A\u308A\uFF09</option>
|
|
17841
|
+
<option value="any" title="9\u3064\u306E\u97F3\u968E\u304B\u3089\u30E9\u30F3\u30C0\u30E0\u306B\u62BD\u9078\u3057\u307E\u3059">\u5E0C\u671B\u306A\u3057\uFF08\u5168\u97F3\u968E\u304B\u3089\u62BD\u9078\uFF09</option>
|
|
17842
|
+
<optgroup label="\u30DA\u30F3\u30BF\u30C8\u30CB\u30C3\u30AF\uFF085\u97F3\u97F3\u968E\uFF09">
|
|
17843
|
+
<option value="yo" title="J-POP\u306E\u6A19\u6E96\u3002\u660E\u308B\u304F\u7D20\u76F4\u3067\u6B4C\u3044\u3084\u3059\u3044\u3002\u5F93\u6765\u306E\u9577\u8ABF\u3068\u540C\u3058">\u967D\u97F3\u968E\uFF08\u9577\u8ABF\u30DA\u30F3\u30BF\uFF09</option>
|
|
17844
|
+
<option value="minyo" title="\u308F\u3089\u3079\u6B4C\u30FB\u6C11\u8B21\u306E\u97F3\u968E\u3002\u7FF3\u308A\u304C\u3042\u308B\u304C\u6697\u3059\u304E\u306A\u3044\u3002\u5F93\u6765\u306E\u77ED\u8ABF\u3068\u540C\u3058">\u6C11\u8B21\u97F3\u968E\uFF08\u77ED\u8ABF\u30DA\u30F3\u30BF\uFF09</option>
|
|
17845
|
+
<option value="ryukyu" title="\u6C96\u7E04\u97F3\u968E\u3002\u30EC\u3068\u30E9\u3092\u629C\u304D\u3001\u30D5\u30A1\u3068\u30B7\u3092\u67F1\u306B\u3059\u308B\u3002\u660E\u308B\u304F\u8DF3\u306D\u308B">\u7409\u7403\u97F3\u968E\uFF08\u6C96\u7E04\uFF09</option>
|
|
17846
|
+
<option value="miyakobushi" title="\u300E\u3055\u304F\u3089\u3055\u304F\u3089\u300F\u306E\u97F3\u968E\u3002\u4E3B\u97F3\u306E\u3059\u3050\u4E0A\u304C\u534A\u97F3\u3067\u3001\u7FF3\u308A\u304C\u6FC3\u3044">\u90FD\u7BC0\u97F3\u968E\uFF08\u9670\u97F3\u968E\uFF09</option>
|
|
17847
|
+
<option value="ritsu" title="\u96C5\u697D\u30FB\u58F0\u660E\u306E\u97F3\u968E\u3002\u534A\u97F3\u3092\u542B\u307E\u305A\u3001\u5E73\u3089\u3067\u8358\u91CD\u306B\u6D41\u308C\u308B">\u5F8B\u97F3\u968E\uFF08\u96C5\u697D\uFF09</option>
|
|
17848
|
+
</optgroup>
|
|
17849
|
+
<optgroup label="\u30C1\u30E3\u30FC\u30C1\u30E2\u30FC\u30C9\uFF087\u97F3\u97F3\u968E\uFF09">
|
|
17850
|
+
<option value="dorian" title="\u77ED\u8ABF\u3060\u304C6\u5EA6\u304C\u660E\u308B\u3044\u3002\u30B1\u30EB\u30C8\u30FB\u30ED\u30C3\u30AF\u30FB\u30B7\u30C6\u30A3\u30DD\u30C3\u30D7">\u30C9\u30EA\u30A2\u30F3</option>
|
|
17851
|
+
<option value="phrygian" title="\u4E3B\u97F3\u306E\u4E0A\u304C\u534A\u97F3\u3002\u30B9\u30D1\u30CB\u30C3\u30B7\u30E5\uFF0F\u30E1\u30BF\u30EB\u306E\u7DCA\u8FEB\u3057\u305F\u97FF\u304D">\u30D5\u30EA\u30B8\u30A2\u30F3</option>
|
|
17852
|
+
<option value="lydian" title="4\u5EA6\u304C\u9AD8\u304F\u3001\u6D6E\u904A\u3057\u3066\u5E83\u304C\u308B\u3002\u6620\u753B\u97F3\u697D\u30FB\u30B2\u30FC\u30E0\u306E\u7A7A\u306E\u8272">\u30EA\u30C7\u30A3\u30A2\u30F3</option>
|
|
17853
|
+
<option value="mixolydian" title="\u9577\u8ABF\u3060\u304C7\u5EA6\u304C\u4F4E\u3044\u3002\u30D6\u30EB\u30FC\u30B9\u30ED\u30C3\u30AF\u30FB\u6C11\u65CF\u97F3\u697D\u306E\u571F\u304F\u3055\u3055">\u30DF\u30AF\u30BD\u30EA\u30C7\u30A3\u30A2\u30F3</option>
|
|
17854
|
+
</optgroup>
|
|
17855
|
+
<optgroup label="\u7279\u6B8A\u97F3\u968E\uFF08\u97F3\u7A0B\u96C6\u5408\u3054\u3068\u5165\u308C\u66FF\u308F\u308B\uFF09">
|
|
17856
|
+
<option value="harmonic_minor" title="\u5C0E\u97F3\u30BD\u266F\u3092\u6301\u3064\u77ED\u8ABF\u3002\u58972\u5EA6\u304C\u6CE3\u304D\u3092\u4F5C\u308B\u3002\u30AF\u30E9\u30B7\u30C3\u30AF\u30FBV\u7CFB\u30FB\u5287\u4F34">\u548C\u58F0\u7684\u77ED\u97F3\u968E</option>
|
|
17857
|
+
<option value="hijaz" title="\u4E3B\u97F3\u306E\u4E0A\u304C\u534A\u97F3\u3001\u4E3B\u548C\u97F3\u306F\u9577\u4E09\u548C\u97F3\u3002\u4E2D\u6771\u30FB\u30B9\u30D1\u30CB\u30C3\u30B7\u30E5\u30FB\u30E1\u30BF\u30EB">\u30D2\u30B8\u30E3\u30FC\u30BA\uFF08\u30D5\u30EA\u30B8\u30A2\u30F3\u30FB\u30C9\u30DF\u30CA\u30F3\u30C8\uFF09</option>
|
|
17858
|
+
<option value="hungarian" title="\u58972\u5EA6\u304C2\u304B\u6240\u3002\u97F3\u968E\u306E\u4E2D\u3067\u3044\u3061\u3070\u3093\u8DF3\u306D\u305F\u3001\u7570\u56FD\u3081\u3044\u305F\u97FF\u304D">\u30CF\u30F3\u30AC\u30EA\u30A2\u30F3\u30FB\u30DE\u30A4\u30CA\u30FC\uFF08\u30B8\u30D7\u30B7\u30FC\uFF09</option>
|
|
17859
|
+
<option value="blues" title="\u30D6\u30EB\u30FC\u30CE\u30FC\u30C8\u5165\u308A\u306E6\u97F3\u97F3\u968E\u3002\u77ED3\u5EA6\u3067\u6B4C\u3044\u3001\u4F34\u594F\u306F\u95773\u5EA6\u3067\u9CF4\u308B">\u30D6\u30EB\u30FC\u30B9\u97F3\u968E</option>
|
|
17860
|
+
</optgroup>
|
|
17861
|
+
</select>
|
|
17862
|
+
<span class="dtm-grow"></span>
|
|
17863
|
+
<span class="dtm-hint" data-dtm="compose-scale-hint"></span>
|
|
17864
|
+
</div>
|
|
16210
17865
|
</div>
|
|
16211
17866
|
<div class="dtm-row">
|
|
16212
17867
|
<span class="dtm-label">\u5168\u4F53\u30B7\u30D5\u30C8</span>
|
|
@@ -16409,6 +18064,8 @@ var buildUI = (target, options) => {
|
|
|
16409
18064
|
composeSectionsLen: sel("compose-sections-len"),
|
|
16410
18065
|
composeKey: sel("compose-key"),
|
|
16411
18066
|
composeKeyHint: sel("compose-key-hint"),
|
|
18067
|
+
composeScale: sel("compose-scale"),
|
|
18068
|
+
composeScaleHint: sel("compose-scale-hint"),
|
|
16412
18069
|
macroComposeVocal: sel("macro-compose-vocal"),
|
|
16413
18070
|
macroComposeInfo: sel("macro-compose-info"),
|
|
16414
18071
|
macroClear: sel("macro-clear"),
|
|
@@ -16452,7 +18109,12 @@ var INSTRUMENT_PRESETS = {
|
|
|
16452
18109
|
melody: "Acoustic Grand Piano",
|
|
16453
18110
|
submelody: "Vibraphone",
|
|
16454
18111
|
bass: "Electric Bass (finger)",
|
|
16455
|
-
chord: "Pad 2 (warm)"
|
|
18112
|
+
chord: "Pad 2 (warm)",
|
|
18113
|
+
solo: "Electric Guitar (clean)",
|
|
18114
|
+
// グロッケンは実物の音域が G5(79)〜 の高音楽器で、旋律の音域へそのまま置くと
|
|
18115
|
+
// 金切り音になる。**外すのではなくオクターブで下げて使う**
|
|
18116
|
+
// ({@link GM_BRIGHT_CEILING} / {@link fitInstrumentOctave})。
|
|
18117
|
+
chorusLead: "Glockenspiel"
|
|
16456
18118
|
},
|
|
16457
18119
|
acoustic: {
|
|
16458
18120
|
displayName: "\u30A2\u30B3\u30FC\u30B9\u30C6\u30A3\u30C3\u30AF",
|
|
@@ -16460,7 +18122,9 @@ var INSTRUMENT_PRESETS = {
|
|
|
16460
18122
|
melody: "Acoustic Guitar (steel)",
|
|
16461
18123
|
submelody: "Harmonica",
|
|
16462
18124
|
bass: "Acoustic Bass",
|
|
16463
|
-
chord: "Acoustic Guitar (nylon)"
|
|
18125
|
+
chord: "Acoustic Guitar (nylon)",
|
|
18126
|
+
solo: "Overdriven Guitar",
|
|
18127
|
+
chorusLead: "String Ensemble 1"
|
|
16464
18128
|
},
|
|
16465
18129
|
jazz_night: {
|
|
16466
18130
|
displayName: "\u30B8\u30E3\u30BA\u30FB\u30CA\u30A4\u30C8",
|
|
@@ -16468,7 +18132,9 @@ var INSTRUMENT_PRESETS = {
|
|
|
16468
18132
|
melody: "Electric Piano 1",
|
|
16469
18133
|
submelody: "Flute",
|
|
16470
18134
|
bass: "Acoustic Bass",
|
|
16471
|
-
chord: "Electric Guitar (jazz)"
|
|
18135
|
+
chord: "Electric Guitar (jazz)",
|
|
18136
|
+
solo: "Tenor Sax",
|
|
18137
|
+
chorusLead: "Muted Trumpet"
|
|
16472
18138
|
},
|
|
16473
18139
|
// --- MODERN & VIBE: エッジの効いた現代的な響き ---
|
|
16474
18140
|
synth_pop: {
|
|
@@ -16477,7 +18143,9 @@ var INSTRUMENT_PRESETS = {
|
|
|
16477
18143
|
melody: "Lead 2 (sawtooth)",
|
|
16478
18144
|
submelody: "Lead 4 (chiff)",
|
|
16479
18145
|
bass: "Synth Bass 2",
|
|
16480
|
-
chord: "Pad 3 (polysynth)"
|
|
18146
|
+
chord: "Pad 3 (polysynth)",
|
|
18147
|
+
solo: "Distortion Guitar",
|
|
18148
|
+
chorusLead: "Synth Brass 1"
|
|
16481
18149
|
},
|
|
16482
18150
|
cyber_punk: {
|
|
16483
18151
|
displayName: "\u30B5\u30A4\u30D0\u30FC\u30D1\u30F3\u30AF",
|
|
@@ -16485,7 +18153,9 @@ var INSTRUMENT_PRESETS = {
|
|
|
16485
18153
|
melody: "Lead 8 (bass + lead)",
|
|
16486
18154
|
submelody: "Lead 5 (charang)",
|
|
16487
18155
|
bass: "Synth Bass 2",
|
|
16488
|
-
chord: "Pad 8 (sweep)"
|
|
18156
|
+
chord: "Pad 8 (sweep)",
|
|
18157
|
+
solo: "Distortion Guitar",
|
|
18158
|
+
chorusLead: "Lead 7 (fifths)"
|
|
16489
18159
|
},
|
|
16490
18160
|
rock: {
|
|
16491
18161
|
displayName: "\u30CF\u30FC\u30C9\u30ED\u30C3\u30AF",
|
|
@@ -16493,7 +18163,9 @@ var INSTRUMENT_PRESETS = {
|
|
|
16493
18163
|
melody: "Distortion Guitar",
|
|
16494
18164
|
submelody: "Rock Organ",
|
|
16495
18165
|
bass: "Electric Bass (pick)",
|
|
16496
|
-
chord: "Overdriven Guitar"
|
|
18166
|
+
chord: "Overdriven Guitar",
|
|
18167
|
+
solo: "Distortion Guitar",
|
|
18168
|
+
chorusLead: "Brass Section"
|
|
16497
18169
|
},
|
|
16498
18170
|
// --- WORLD & CLASSIC: 特定のジャンル・地域 ---
|
|
16499
18171
|
orchestra: {
|
|
@@ -16502,7 +18174,9 @@ var INSTRUMENT_PRESETS = {
|
|
|
16502
18174
|
melody: "French Horn",
|
|
16503
18175
|
submelody: "Pizzicato Strings",
|
|
16504
18176
|
bass: "Cello",
|
|
16505
|
-
chord: "Tremolo Strings"
|
|
18177
|
+
chord: "Tremolo Strings",
|
|
18178
|
+
solo: "Violin",
|
|
18179
|
+
chorusLead: "Trumpet"
|
|
16506
18180
|
},
|
|
16507
18181
|
japanese_wa: {
|
|
16508
18182
|
displayName: "\u548C\u98A8\u30FB\u96C5",
|
|
@@ -16510,7 +18184,9 @@ var INSTRUMENT_PRESETS = {
|
|
|
16510
18184
|
melody: "Koto",
|
|
16511
18185
|
submelody: "Shamisen",
|
|
16512
18186
|
bass: "Taiko Drum",
|
|
16513
|
-
chord: "Shakuhachi"
|
|
18187
|
+
chord: "Shakuhachi",
|
|
18188
|
+
solo: "Shakuhachi",
|
|
18189
|
+
chorusLead: "Glockenspiel"
|
|
16514
18190
|
},
|
|
16515
18191
|
arabic_exotic: {
|
|
16516
18192
|
displayName: "\u30A8\u30AD\u30BE\u30C1\u30C3\u30AF",
|
|
@@ -16518,7 +18194,9 @@ var INSTRUMENT_PRESETS = {
|
|
|
16518
18194
|
melody: "Sitar",
|
|
16519
18195
|
submelody: "Bagpipe",
|
|
16520
18196
|
bass: "Fretless Bass",
|
|
16521
|
-
chord: "Kalimba"
|
|
18197
|
+
chord: "Kalimba",
|
|
18198
|
+
solo: "Shanai",
|
|
18199
|
+
chorusLead: "Steel Drums"
|
|
16522
18200
|
},
|
|
16523
18201
|
// --- FANTASY & ATMOSPHERE: 雰囲気と余韻 ---
|
|
16524
18202
|
fantasy_rpg: {
|
|
@@ -16527,7 +18205,9 @@ var INSTRUMENT_PRESETS = {
|
|
|
16527
18205
|
melody: "Ocarina",
|
|
16528
18206
|
submelody: "Celesta",
|
|
16529
18207
|
bass: "Timpani",
|
|
16530
|
-
chord: "Orchestral Harp"
|
|
18208
|
+
chord: "Orchestral Harp",
|
|
18209
|
+
solo: "Pan Flute",
|
|
18210
|
+
chorusLead: "Choir Aahs"
|
|
16531
18211
|
},
|
|
16532
18212
|
ambient_cloud: {
|
|
16533
18213
|
displayName: "\u30A2\u30F3\u30D3\u30A8\u30F3\u30C8",
|
|
@@ -16535,7 +18215,9 @@ var INSTRUMENT_PRESETS = {
|
|
|
16535
18215
|
melody: "Lead 6 (voice)",
|
|
16536
18216
|
submelody: "Music Box",
|
|
16537
18217
|
bass: "Synth Bass 1",
|
|
16538
|
-
chord: "Pad 7 (halo)"
|
|
18218
|
+
chord: "Pad 7 (halo)",
|
|
18219
|
+
solo: "Lead 3 (calliope)",
|
|
18220
|
+
chorusLead: "Synth Choir"
|
|
16539
18221
|
},
|
|
16540
18222
|
retro_game: {
|
|
16541
18223
|
displayName: "8-bit \u30EC\u30C8\u30ED",
|
|
@@ -16543,8 +18225,99 @@ var INSTRUMENT_PRESETS = {
|
|
|
16543
18225
|
melody: "Lead 1 (square)",
|
|
16544
18226
|
submelody: "Lead 2 (sawtooth)",
|
|
16545
18227
|
bass: "Synth Bass 1",
|
|
16546
|
-
chord: "Clavinet"
|
|
16547
|
-
|
|
18228
|
+
chord: "Clavinet",
|
|
18229
|
+
solo: "Lead 8 (bass + lead)",
|
|
18230
|
+
chorusLead: "Lead 4 (chiff)"
|
|
18231
|
+
}
|
|
18232
|
+
};
|
|
18233
|
+
var GM_INSTRUMENT_RANGE = {
|
|
18234
|
+
// 鍵盤・音板
|
|
18235
|
+
"Acoustic Grand Piano": [21, 108],
|
|
18236
|
+
"Electric Piano 1": [28, 103],
|
|
18237
|
+
Clavinet: [36, 96],
|
|
18238
|
+
Celesta: [60, 108],
|
|
18239
|
+
Glockenspiel: [79, 108],
|
|
18240
|
+
"Music Box": [72, 108],
|
|
18241
|
+
Vibraphone: [53, 89],
|
|
18242
|
+
Kalimba: [60, 84],
|
|
18243
|
+
"Orchestral Harp": [23, 104],
|
|
18244
|
+
// 弦・撥弦
|
|
18245
|
+
"Acoustic Guitar (steel)": [40, 83],
|
|
18246
|
+
"Acoustic Guitar (nylon)": [40, 83],
|
|
18247
|
+
"Electric Guitar (clean)": [40, 86],
|
|
18248
|
+
"Electric Guitar (jazz)": [40, 86],
|
|
18249
|
+
"Overdriven Guitar": [40, 88],
|
|
18250
|
+
"Distortion Guitar": [40, 88],
|
|
18251
|
+
Violin: [55, 103],
|
|
18252
|
+
Cello: [36, 76],
|
|
18253
|
+
"String Ensemble 1": [28, 100],
|
|
18254
|
+
"Tremolo Strings": [28, 100],
|
|
18255
|
+
"Pizzicato Strings": [28, 96],
|
|
18256
|
+
Sitar: [48, 79],
|
|
18257
|
+
Shamisen: [48, 84],
|
|
18258
|
+
Koto: [41, 77],
|
|
18259
|
+
// ベース
|
|
18260
|
+
"Acoustic Bass": [28, 60],
|
|
18261
|
+
"Electric Bass (finger)": [28, 67],
|
|
18262
|
+
"Electric Bass (pick)": [28, 67],
|
|
18263
|
+
"Fretless Bass": [28, 67],
|
|
18264
|
+
"Synth Bass 1": [24, 72],
|
|
18265
|
+
"Synth Bass 2": [24, 72],
|
|
18266
|
+
// 管
|
|
18267
|
+
Flute: [60, 96],
|
|
18268
|
+
"Pan Flute": [60, 91],
|
|
18269
|
+
Shakuhachi: [62, 86],
|
|
18270
|
+
Ocarina: [60, 84],
|
|
18271
|
+
Harmonica: [60, 96],
|
|
18272
|
+
Bagpipe: [62, 86],
|
|
18273
|
+
Shanai: [60, 86],
|
|
18274
|
+
"Tenor Sax": [44, 75],
|
|
18275
|
+
Trumpet: [55, 82],
|
|
18276
|
+
"Muted Trumpet": [55, 82],
|
|
18277
|
+
"French Horn": [41, 77],
|
|
18278
|
+
"Brass Section": [41, 84],
|
|
18279
|
+
// 声・打・オルガン
|
|
18280
|
+
"Choir Aahs": [43, 84],
|
|
18281
|
+
"Synth Choir": [43, 84],
|
|
18282
|
+
"Steel Drums": [55, 86],
|
|
18283
|
+
"Taiko Drum": [30, 60],
|
|
18284
|
+
Timpani: [36, 57],
|
|
18285
|
+
"Rock Organ": [36, 96],
|
|
18286
|
+
// シンセ(実物が無いので一般的な使用域)
|
|
18287
|
+
"Synth Brass 1": [36, 96],
|
|
18288
|
+
"Lead 1 (square)": [36, 96],
|
|
18289
|
+
"Lead 2 (sawtooth)": [36, 96],
|
|
18290
|
+
"Lead 3 (calliope)": [48, 96],
|
|
18291
|
+
"Lead 4 (chiff)": [48, 96],
|
|
18292
|
+
"Lead 5 (charang)": [40, 96],
|
|
18293
|
+
"Lead 6 (voice)": [43, 91],
|
|
18294
|
+
"Lead 7 (fifths)": [36, 84],
|
|
18295
|
+
"Lead 8 (bass + lead)": [28, 91],
|
|
18296
|
+
"Pad 2 (warm)": [24, 96],
|
|
18297
|
+
"Pad 3 (polysynth)": [24, 96],
|
|
18298
|
+
"Pad 7 (halo)": [24, 96],
|
|
18299
|
+
"Pad 8 (sweep)": [24, 96]
|
|
18300
|
+
};
|
|
18301
|
+
var GM_BRIGHT_CEILING = {
|
|
18302
|
+
Glockenspiel: 72,
|
|
18303
|
+
"Tinkle Bell": 72,
|
|
18304
|
+
"Music Box": 79,
|
|
18305
|
+
Celesta: 84,
|
|
18306
|
+
Kalimba: 79,
|
|
18307
|
+
"Steel Drums": 84,
|
|
18308
|
+
"FX 3 (crystal)": 79
|
|
18309
|
+
};
|
|
18310
|
+
var OCTAVE_FIT_TOLERANCE = 3;
|
|
18311
|
+
var fitInstrumentOctave = (semitoneRange, instrument, wanted) => {
|
|
18312
|
+
const range = GM_INSTRUMENT_RANGE[instrument];
|
|
18313
|
+
if (!range || !semitoneRange) return wanted;
|
|
18314
|
+
const hi = Math.min(range[1], GM_BRIGHT_CEILING[instrument] ?? range[1]);
|
|
18315
|
+
let octave = wanted;
|
|
18316
|
+
while (octave > wanted - 2) {
|
|
18317
|
+
if (semitoneRange[1] + octave * 12 <= hi + OCTAVE_FIT_TOLERANCE) break;
|
|
18318
|
+
octave--;
|
|
18319
|
+
}
|
|
18320
|
+
return octave;
|
|
16548
18321
|
};
|
|
16549
18322
|
|
|
16550
18323
|
// src/macro-state.ts
|
|
@@ -16552,6 +18325,7 @@ var MACRO_STORAGE_KEYS = {
|
|
|
16552
18325
|
template: "dtm-macro:template",
|
|
16553
18326
|
sections: "dtm-macro:sections",
|
|
16554
18327
|
key: "dtm-macro:key",
|
|
18328
|
+
scale: "dtm-macro:scale",
|
|
16555
18329
|
shift: "dtm-macro:shift",
|
|
16556
18330
|
transpose: "dtm-macro:transpose"
|
|
16557
18331
|
};
|
|
@@ -17055,56 +18829,95 @@ var exportMIDI = (options) => {
|
|
|
17055
18829
|
const div = 480;
|
|
17056
18830
|
const tickPerStep = div / STEPS_PER_BEAT3;
|
|
17057
18831
|
const midiTracks = [];
|
|
17058
|
-
const NOTE_CHANNELS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15];
|
|
17059
|
-
const BEND_RANGE_SEMITONES = 2;
|
|
17060
18832
|
const bendKey = (cents) => Math.round(cents * 100);
|
|
17061
|
-
const
|
|
17062
|
-
|
|
17063
|
-
for (const n of track.notes) {
|
|
18833
|
+
const hasMicrotones = tracks.some(
|
|
18834
|
+
(track) => track.notes.some((n) => {
|
|
17064
18835
|
const { detuneCents } = unitsToMidiDetune(n.pitchUnits);
|
|
17065
|
-
|
|
17066
|
-
|
|
17067
|
-
|
|
17068
|
-
}
|
|
17069
|
-
const bendChannel = /* @__PURE__ */ new Map();
|
|
17070
|
-
const ordered = [...bendUse.entries()].sort((a, b) => b[1] - a[1]);
|
|
17071
|
-
for (const [k] of ordered) {
|
|
17072
|
-
if (bendChannel.size >= NOTE_CHANNELS.length) break;
|
|
17073
|
-
bendChannel.set(k, NOTE_CHANNELS[bendChannel.size]);
|
|
17074
|
-
}
|
|
17075
|
-
tracks.forEach((track) => {
|
|
17076
|
-
if (track.notes.length === 0) return;
|
|
17077
|
-
const events = [];
|
|
17078
|
-
for (const n of track.notes) {
|
|
17079
|
-
const { midi, detuneCents } = unitsToMidiDetune(n.pitchUnits);
|
|
17080
|
-
const k = bendKey(detuneCents);
|
|
17081
|
-
const channel = bendChannel.get(k) ?? bendChannel.get(0) ?? 0;
|
|
17082
|
-
const note = Math.max(0, Math.min(127, midi));
|
|
17083
|
-
const startTick = Math.round(n.startStep * tickPerStep);
|
|
17084
|
-
const endTick = Math.round(
|
|
17085
|
-
(n.startStep + (n.durationSteps || 1)) * tickPerStep
|
|
17086
|
-
);
|
|
17087
|
-
const vel = Math.round(
|
|
17088
|
-
(n.velocity ?? DEFAULT_VELOCITY) * (track.volume ?? 100) / 100
|
|
17089
|
-
);
|
|
17090
|
-
events.push({ t: startTick, m: [144 | channel, note, vel] });
|
|
17091
|
-
events.push({ t: endTick, m: [144 | channel, note, 0] });
|
|
17092
|
-
}
|
|
17093
|
-
events.sort((a, b) => a.t - b.t);
|
|
17094
|
-
midiTracks.push(events);
|
|
17095
|
-
});
|
|
18836
|
+
return bendKey(detuneCents) !== 0;
|
|
18837
|
+
})
|
|
18838
|
+
);
|
|
17096
18839
|
const bendSetup = [];
|
|
17097
|
-
|
|
17098
|
-
const
|
|
17099
|
-
|
|
17100
|
-
|
|
17101
|
-
|
|
17102
|
-
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
|
|
18840
|
+
if (hasMicrotones) {
|
|
18841
|
+
const NOTE_CHANNELS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15];
|
|
18842
|
+
const BEND_RANGE_SEMITONES = 2;
|
|
18843
|
+
const bendUse = /* @__PURE__ */ new Map();
|
|
18844
|
+
for (const track of tracks) {
|
|
18845
|
+
for (const n of track.notes) {
|
|
18846
|
+
const { detuneCents } = unitsToMidiDetune(n.pitchUnits);
|
|
18847
|
+
const k = bendKey(detuneCents);
|
|
18848
|
+
bendUse.set(k, (bendUse.get(k) ?? 0) + 1);
|
|
18849
|
+
}
|
|
18850
|
+
}
|
|
18851
|
+
const bendChannel = /* @__PURE__ */ new Map();
|
|
18852
|
+
const ordered = [...bendUse.entries()].sort((a, b) => b[1] - a[1]);
|
|
18853
|
+
for (const [k] of ordered) {
|
|
18854
|
+
if (bendChannel.size >= NOTE_CHANNELS.length) break;
|
|
18855
|
+
bendChannel.set(k, NOTE_CHANNELS[bendChannel.size]);
|
|
18856
|
+
}
|
|
18857
|
+
tracks.forEach((track) => {
|
|
18858
|
+
if (track.notes.length === 0) return;
|
|
18859
|
+
const events = [];
|
|
18860
|
+
for (const n of track.notes) {
|
|
18861
|
+
const { midi, detuneCents } = unitsToMidiDetune(n.pitchUnits);
|
|
18862
|
+
const k = bendKey(detuneCents);
|
|
18863
|
+
const channel = bendChannel.get(k) ?? bendChannel.get(0) ?? 0;
|
|
18864
|
+
const note = Math.max(0, Math.min(127, midi));
|
|
18865
|
+
const startTick = Math.round(n.startStep * tickPerStep);
|
|
18866
|
+
const endTick = Math.round(
|
|
18867
|
+
(n.startStep + (n.durationSteps || 1)) * tickPerStep
|
|
18868
|
+
);
|
|
18869
|
+
const vel = Math.round(
|
|
18870
|
+
(n.velocity ?? DEFAULT_VELOCITY) * (track.volume ?? 100) / 100
|
|
18871
|
+
);
|
|
18872
|
+
events.push({ t: startTick, m: [144 | channel, note, vel] });
|
|
18873
|
+
events.push({ t: endTick, m: [144 | channel, note, 0] });
|
|
18874
|
+
}
|
|
18875
|
+
events.sort((a, b) => a.t - b.t);
|
|
18876
|
+
midiTracks.push(events);
|
|
18877
|
+
});
|
|
18878
|
+
for (const [k, channel] of bendChannel) {
|
|
18879
|
+
const cents = k / 100;
|
|
18880
|
+
bendSetup.push({ t: 0, m: [176 | channel, 101, 0] });
|
|
18881
|
+
bendSetup.push({ t: 0, m: [176 | channel, 100, 0] });
|
|
18882
|
+
bendSetup.push({ t: 0, m: [176 | channel, 6, BEND_RANGE_SEMITONES] });
|
|
18883
|
+
bendSetup.push({ t: 0, m: [176 | channel, 38, 0] });
|
|
18884
|
+
bendSetup.push({ t: 0, m: [176 | channel, 101, 127] });
|
|
18885
|
+
bendSetup.push({ t: 0, m: [176 | channel, 100, 127] });
|
|
18886
|
+
const raw = 8192 + Math.round(cents / (BEND_RANGE_SEMITONES * 100) * 8192);
|
|
18887
|
+
const v = Math.max(0, Math.min(16383, raw));
|
|
18888
|
+
bendSetup.push({ t: 0, m: [224 | channel, v & 127, v >> 7 & 127] });
|
|
18889
|
+
}
|
|
18890
|
+
} else {
|
|
18891
|
+
tracks.forEach((track, trIdx) => {
|
|
18892
|
+
if (track.notes.length === 0) return;
|
|
18893
|
+
const channel = trIdx < 9 ? trIdx : trIdx + 1 & 15;
|
|
18894
|
+
const events = [];
|
|
18895
|
+
if (track.program !== void 0 && track.program >= 0 && track.program <= 127) {
|
|
18896
|
+
events.push({ t: 0, m: [192 | channel, track.program] });
|
|
18897
|
+
}
|
|
18898
|
+
for (const n of track.notes) {
|
|
18899
|
+
const { midi } = unitsToMidiDetune(n.pitchUnits);
|
|
18900
|
+
const note = Math.max(0, Math.min(127, midi));
|
|
18901
|
+
const startTick = Math.round(n.startStep * tickPerStep);
|
|
18902
|
+
const endTick = Math.round(
|
|
18903
|
+
(n.startStep + (n.durationSteps || 1)) * tickPerStep
|
|
18904
|
+
);
|
|
18905
|
+
const vel = Math.round(
|
|
18906
|
+
(n.velocity ?? DEFAULT_VELOCITY) * (track.volume ?? 100) / 100
|
|
18907
|
+
);
|
|
18908
|
+
events.push({ t: startTick, m: [144 | channel, note, vel] });
|
|
18909
|
+
events.push({ t: endTick, m: [144 | channel, note, 0] });
|
|
18910
|
+
}
|
|
18911
|
+
events.sort((a, b) => {
|
|
18912
|
+
if (a.t !== b.t) return a.t - b.t;
|
|
18913
|
+
const typeA = a.m[0] & 240;
|
|
18914
|
+
const typeB = b.m[0] & 240;
|
|
18915
|
+
if (typeA === 192 && typeB !== 192) return -1;
|
|
18916
|
+
if (typeB === 192 && typeA !== 192) return 1;
|
|
18917
|
+
return 0;
|
|
18918
|
+
});
|
|
18919
|
+
midiTracks.push(events);
|
|
18920
|
+
});
|
|
17108
18921
|
}
|
|
17109
18922
|
const maxStep = Math.max(
|
|
17110
18923
|
...tracks.filter((t) => t.notes.length > 0).map(
|
|
@@ -17840,28 +19653,6 @@ var isChordHeavyTrack = (notes, threshold = 0.6) => {
|
|
|
17840
19653
|
return chordNotes / notes.length >= threshold;
|
|
17841
19654
|
};
|
|
17842
19655
|
|
|
17843
|
-
// src/track1-state.ts
|
|
17844
|
-
var TRACK1_STORAGE_KEY = "dtm-track1:settings";
|
|
17845
|
-
var readTrack1Settings = () => {
|
|
17846
|
-
try {
|
|
17847
|
-
if (typeof localStorage === "undefined" || !localStorage) return null;
|
|
17848
|
-
const raw = localStorage.getItem(TRACK1_STORAGE_KEY);
|
|
17849
|
-
if (!raw) return null;
|
|
17850
|
-
const parsed = JSON.parse(raw);
|
|
17851
|
-
if (!parsed || typeof parsed !== "object") return null;
|
|
17852
|
-
return parsed;
|
|
17853
|
-
} catch (_) {
|
|
17854
|
-
return null;
|
|
17855
|
-
}
|
|
17856
|
-
};
|
|
17857
|
-
var writeTrack1Settings = (settings) => {
|
|
17858
|
-
try {
|
|
17859
|
-
if (typeof localStorage === "undefined" || !localStorage) return;
|
|
17860
|
-
localStorage.setItem(TRACK1_STORAGE_KEY, JSON.stringify(settings));
|
|
17861
|
-
} catch (_) {
|
|
17862
|
-
}
|
|
17863
|
-
};
|
|
17864
|
-
|
|
17865
19656
|
// src/renderer.ts
|
|
17866
19657
|
var KEYBOARD_WIDTH = 60;
|
|
17867
19658
|
var HEADER_HEIGHT = 20;
|
|
@@ -18351,6 +20142,28 @@ var createRenderer = (mountTarget, width = 800, height = 450, config) => {
|
|
|
18351
20142
|
};
|
|
18352
20143
|
};
|
|
18353
20144
|
|
|
20145
|
+
// src/track1-state.ts
|
|
20146
|
+
var TRACK1_STORAGE_KEY = "dtm-track1:settings";
|
|
20147
|
+
var readTrack1Settings = () => {
|
|
20148
|
+
try {
|
|
20149
|
+
if (typeof localStorage === "undefined" || !localStorage) return null;
|
|
20150
|
+
const raw = localStorage.getItem(TRACK1_STORAGE_KEY);
|
|
20151
|
+
if (!raw) return null;
|
|
20152
|
+
const parsed = JSON.parse(raw);
|
|
20153
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
20154
|
+
return parsed;
|
|
20155
|
+
} catch (_) {
|
|
20156
|
+
return null;
|
|
20157
|
+
}
|
|
20158
|
+
};
|
|
20159
|
+
var writeTrack1Settings = (settings) => {
|
|
20160
|
+
try {
|
|
20161
|
+
if (typeof localStorage === "undefined" || !localStorage) return;
|
|
20162
|
+
localStorage.setItem(TRACK1_STORAGE_KEY, JSON.stringify(settings));
|
|
20163
|
+
} catch (_) {
|
|
20164
|
+
}
|
|
20165
|
+
};
|
|
20166
|
+
|
|
18354
20167
|
// src/daw.ts
|
|
18355
20168
|
var CHORD_INFO_HTML2 = `
|
|
18356
20169
|
<div class="dtm-modal-body-content">
|
|
@@ -18672,6 +20485,7 @@ var COMPOSE_INFO_HTML = `
|
|
|
18672
20485
|
<li><strong>\u30E1\u30ED\u30C7\u30A3\u306E\u66F8\u6CD5</strong>\u2014\u2014\u8D70\u53E5\u306E\u5F62\uFF08\u97F3\u968E\uFF0F\u6298\u308A\u8FD4\u3057\uFF0F\u5206\u6563\u548C\u97F3\uFF0F\u30B8\u30B0\u30B6\u30B0\uFF09\u3001\u3064\u306A\u304E\u306E\u5F62\uFF08\u5C71\u306A\u308A\uFF0F\u8C37\uFF0F\u4E0A\u884C\uFF0F\u4E0B\u884C\uFF0F\u3046\u306D\u308A\uFF0F\u8EF8\u97F3\u307E\u308F\u308A\uFF09\u3001\u7D42\u6B62\u306E\u5F62\uFF08\u9806\u6B21\u4E0B\u964D\uFF0F\u30BD\u30DF\u30C9\uFF0F\u8DF3\u306D\u4E0A\u304C\u308A\uFF0F\u30ED\u30F3\u30B0\u30C8\u30FC\u30F3\uFF09\u3001\u30E2\u30C1\u30FC\u30D5\u306E\u539F\u578B\u3001\u8DF3\u8E8D\u306E\u6DF7\u305C\u5177\u5408\u3001\u958B\u59CB\u97F3\u3001\u57FA\u6E96\u306E\u523B\u307F\uFF088\u5206\uFF0F16\u5206\uFF0F\u4E09\u9023\uFF09\u3001\u30B9\u30A6\u30A3\u30F3\u30B0\u91CF</li>
|
|
18673
20486
|
<li><strong>\u30D9\u30FC\u30B9\u306E\u594F\u6CD5</strong>\uFF084\u5206\u6253\u3061\uFF0F\u30AA\u30EB\u30BF\u30CD\u30A4\u30C8\uFF0F2\u5206\uFF0F8\u5206\u30C9\u30E9\u30A4\u30D6\uFF0F\u30B7\u30F3\u30B3\u30DA\uFF0F\u30A6\u30A9\u30FC\u30AD\u30F3\u30B0\uFF0F\u30AA\u30AF\u30BF\u30FC\u30D6\uFF09</li>
|
|
18674
20487
|
<li><strong>\u30B5\u30D6\u30E1\u30ED\u306E\u66F8\u304D\u65B9</strong>\u2014\u2014\u5408\u3044\u306E\u624B\uFF08\u30E1\u30ED\u30C7\u30A3\u304C\u4F11\u3093\u3060\u9699\u9593\u306B\u3060\u3051\u5165\u308B\uFF09\u3001\u30CF\u30E2\u30EA\uFF08\u30E1\u30ED\u30C7\u30A3\u306E\u30EA\u30BA\u30E0\u3092\u306A\u305E\u3063\u30663\u5EA6\u30FB6\u5EA6\u4E0B\u3092\u6B4C\u3046\uFF09\u3001\u5BFE\u65CB\u5F8B\uFF088\u5206\u3067\u30E1\u30ED\u30C7\u30A3\u3068\u53CD\u884C\u3059\u308B\uFF09\u3001\u4FDD\u7D9A\u97F3\uFF08\u540C\u3058\u97F3\u3092\u4F38\u3070\u3057\u7D9A\u3051\u308B\uFF09\u3001\u30D1\u30C3\u30C9\u3002\u5C0F\u7BC0\u3054\u3068\u306B\u3001\u30E1\u30ED\u30C7\u30A3\u304C\u606F\u7D99\u304E\u3057\u3066\u3044\u308B\u5834\u6240\u3067\u306F\u81EA\u52D5\u3067\u5408\u3044\u306E\u624B\u306B\u5207\u308A\u66FF\u308F\u308A\u307E\u3059\u3002</li>
|
|
20488
|
+
<li><strong>\u7DE8\u66F2\u30D7\u30E9\u30F3</strong>\uFF08\u4E0A\u7D1A\u8005\u30E2\u30FC\u30C9\u306E\u307F\uFF09\u2014\u2014\u4F34\u594F\u3092\u4F55\u5C64\u306B\u3059\u308B\u304B\u3001\u305D\u308C\u305E\u308C\u3069\u306E\u594F\u6CD5\u3067\u3069\u306E\u30BB\u30AF\u30B7\u30E7\u30F3\u3092\u9CF4\u3089\u3059\u304B\u3001\u30B5\u30D3\u306E\u91CD\u306D\u3092\u51FA\u3059\u304B\u30FB\u30E6\u30CB\u30BE\u30F3\u304B\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u304B\u3001\u88C5\u98FE\u3092\u3069\u3053\u306B\u7F6E\u304F\u304B\u3002400\u66F2\u5F15\u304F\u3068392\u901A\u308A\u306E\u578B\u304C\u51FA\u307E\u3059\u3002</li>
|
|
18675
20489
|
</ul>
|
|
18676
20490
|
<p>\u3055\u3089\u306B\u3001\u76F4\u524D\u306B\u4F5C\u3063\u305F5\u66F2\u3068\u7279\u5FB4\u304C\u4F3C\u3066\u3044\u308B\u5019\u88DC\u306B\u306F\u6E1B\u70B9\u3057\u3066\u3044\u307E\u3059\u3002\u7D9A\u3051\u3066\u62BC\u3057\u305F\u3068\u304D\u306B\u4F3C\u305F\u66F2\u304C\u4E26\u3070\u306A\u3044\u3088\u3046\u306B\u3059\u308B\u305F\u3081\u3067\u3059\u3002</p>
|
|
18677
20491
|
<h4>\u3067\u304D\u3042\u304C\u308A\u306E\u9078\u3073\u65B9</h4>
|
|
@@ -18683,8 +20497,28 @@ var COMPOSE_INFO_HTML = `
|
|
|
18683
20497
|
<li><strong>\u97F3\u306E\u5206\u5E03</strong>\u2014\u2014\u97F3\u4FA1\u306E\u3070\u3089\u3064\u304D\u30FB\u4F11\u7B26\u306E\u5272\u5408\u30FB\u8DF3\u8E8D\u306E\u5927\u304D\u3055\u3068\u6BD4\u7387\u30FB\u4F7F\u3063\u3066\u3044\u308B\u97F3\u57DF\u3002</li>
|
|
18684
20498
|
</ul>
|
|
18685
20499
|
<p>\u5404\u9805\u76EE\u306E\u5408\u683C\u30E9\u30A4\u30F3\u306F\u52D8\u3067\u6C7A\u3081\u305F\u3082\u306E\u3067\u306F\u306A\u304F\u3001<strong>\u4EBA\u9593\u304C\u66F8\u3044\u305FMIDI\u3092\u5B9F\u969B\u306B\u6E2C\u3063\u3066\u3001\u305D\u306E\u5206\u5E03\u306E\u771F\u3093\u4E2D\u3042\u305F\u308A\u3092\u6E80\u70B9\u306B\u3057\u3066\u3044\u307E\u3059</strong>\u3002\u305F\u3068\u3048\u3070\u4E3B\u65CB\u5F8B\u306E\u4F11\u7B26\u306F\u3001\u4EBA\u304C\u66F8\u3044\u305F\u66F2\u3067\u306F\u5168\u4F53\u306E15\u301C43%\u3092\u5360\u3081\u3066\u3044\u307E\u3057\u305F\u3002</p>
|
|
20500
|
+
<h4>\u6B4C\u5165\u308A\u4F5C\u66F2\u306E\u30DC\u30FC\u30AB\u30EB</h4>
|
|
20501
|
+
<p>\u4E3B\u65CB\u5F8B\u306B\u6B4C\u8A5E\u3092\u4ED8\u3051\u3066\u6B4C\u308F\u305B\u307E\u3059\u3002\u6B4C\u8A5E\u306B\u610F\u5473\u306F\u3042\u308A\u307E\u305B\u3093\uFF08\u30E1\u30ED\u30C7\u30A3\u306B\u6B63\u3057\u304F\u4E57\u308B\u3001\u767A\u97F3\u3067\u304D\u308B\u97F3\u306E\u4E26\u3073\u3060\u3051\u3092\u4F5C\u3063\u3066\u3044\u307E\u3059\uFF09\u3002<strong>\u4E0A\u7D1A\u8005\u30E2\u30FC\u30C9\uFF0815\u30C8\u30E9\u30C3\u30AF\uFF09\u3067\u306F\u3001\u3055\u3089\u306B\u30DC\u30FC\u30AB\u30EB\u30A2\u30EC\u30F3\u30B8\u307E\u3067\u5C55\u958B\u3057\u307E\u3059\u3002</strong>\u3069\u3053\u3067\u4F55\u3092\u3059\u308B\u304B\u306F\u66F2\u3054\u3068\u306B\u81EA\u52D5\u3067\u6C7A\u307E\u308B\u306E\u3067\u3001\u8A2D\u5B9A\u9805\u76EE\u306F\u3042\u308A\u307E\u305B\u3093\u3002</p>
|
|
20502
|
+
<ul>
|
|
20503
|
+
<li><strong>\u30CF\u30E2\u30EA</strong> \u2014 \u30B5\u30D3\u304B\u3089\u3001\u66F2\u306B\u3088\u3063\u3066\u306FB\u30E1\u30ED\u304B\u3089\u5165\u308A\u307E\u3059\u3002<strong>\u4E3B\u65CB\u5F8B\u3068\u540C\u3058\u58F0\u30FB\u540C\u3058\u6B4C\u8A5E\u3067\u9055\u3046\u9AD8\u3055\u3092\u91CD\u306D\u308B</strong>\u306E\u3067\u3001\u305D\u306E\u30D1\u30FC\u30C8\u304B\u3089\u58F0\u304C\u539A\u304F\u306A\u3063\u3066\u8C6A\u83EF\u306B\u805E\u3053\u3048\u307E\u3059\u30023\u5EA6\u304B6\u5EA6\u304C\u57FA\u672C\u3067\u3001\u6D6E\u3044\u3066\u805E\u3053\u3048\u308B\u5B8C\u51685\u5EA6\u306F\u907F\u3051\u307E\u3059\u3002\u4E3B\u65CB\u5F8B\u304C\u30C6\u30F3\u30B7\u30E7\u30F3\u97F3\uFF089th\u30FB11th \u306A\u3069\uFF09\u306B\u4E57\u3063\u3066\u3044\u308B\u3068\u3053\u308D\u3060\u30514\u5EA6\u3067\u5F53\u3066\u307E\u3059\u2014\u2014\u305D\u3053\u3067\u306F3\u5EA6\u30826\u5EA6\u3082\u548C\u97F3\u306E\u69CB\u6210\u97F3\u3078\u5C4A\u304B\u306A\u3044\u305F\u3081\u3067\u3059\u3002\u843D\u3061\u30B5\u30D3\u306F\u58F0\u3060\u3051\u3092\u805E\u304B\u305B\u308B\u5834\u6240\u306A\u306E\u3067\u5916\u3057\u307E\u3059\u3002</li>
|
|
20504
|
+
<li><strong>\u639B\u3051\u5408\u3044\uFF08\u30C7\u30E5\u30A8\u30C3\u30C8\uFF09</strong> \u2014 4\u5272\u307B\u3069\u306E\u66F2\u304C2\u4EBA\u6B4C\u3044\u306B\u306A\u308A\u307E\u3059\u3002\u30BB\u30AF\u30B7\u30E7\u30F3\u3054\u3068\uFF0FA\u30E1\u30ED\u30672\u5C0F\u7BC0\u3054\u3068\uFF0F\u639B\u3051\u5408\u3044\u30B5\u30D3\uFF0FA\u30E1\u30ED\u3060\u3051\u3001\u306E4\u901A\u308A\u3002<strong>\u53D7\u3051\u6E21\u3057\u306F\u5C0F\u7BC0\u7DDA\u3074\u3063\u305F\u308A\u3067\u306F\u306A\u304F\u3001\u6B21\u306E\u4EBA\u304C\u624B\u524D\u304B\u3089\u98DF\u3044\u6C17\u5473\u306B\u5165\u308A\u307E\u3059\u3002</strong>\u4E00\u7DD2\u306B\u6B4C\u3046\u30B5\u30D3\u3067\u306F\u76F8\u65B9\u304C\u30CF\u30E2\u30EA\u3078\u56DE\u308A\u307E\u3059\uFF08\u540C\u3058\u97F3\u3092\u306A\u305E\u308B\u30E6\u30CB\u30BE\u30F3\u306B\u306F\u3057\u307E\u305B\u3093\uFF09\u3002</li>
|
|
20505
|
+
</ul>
|
|
20506
|
+
<p>\u30B7\u30F3\u30D7\u30EB\u30E2\u30FC\u30C9\uFF084\u30C8\u30E9\u30C3\u30AF\uFF09\u306F\u72EC\u5531\u3067\u3059\u30024\u672C\u304C\u57CB\u307E\u3063\u3066\u3044\u3066\u30CF\u30E2\u30EA\u306E\u7F6E\u304D\u5834\u6240\u304C\u7121\u3044\u305F\u3081\u3067\u3059\u3002</p>
|
|
20507
|
+
<h4>\u30BB\u30AF\u30B7\u30E7\u30F3\u3067\u697D\u5668\u30FB\u4F34\u594F\u304C\u5909\u308F\u308B\uFF08\u4E0A\u7D1A\u8005\u30E2\u30FC\u30C9\u306E\u307F\uFF09</h4>
|
|
20508
|
+
<p>1\u672C\u306E\u30C8\u30E9\u30C3\u30AF\u306F\u3001\u66F2\u306E\u6700\u521D\u304B\u3089\u6700\u5F8C\u307E\u30671\u3064\u306E\u697D\u5668\u3067\u9CF4\u308A\u307E\u3059\u3002\u3064\u307E\u308A<strong>\u300C\u30B5\u30D3\u3060\u3051\u5225\u306E\u697D\u5668\u306B\u3059\u308B\u300D\u306F\u30011\u672C\u306E\u30C8\u30E9\u30C3\u30AF\u306E\u4E2D\u3067\u306F\u4F5C\u308C\u307E\u305B\u3093</strong>\u3002\u4F5C\u308C\u308B\u306E\u306F\u3001\u9CF4\u3089\u3057\u305F\u3044\u533A\u9593\u3092\u5225\u306E\u30C8\u30E9\u30C3\u30AF\u3078\u66F8\u304D\u5206\u3051\u305F\u3068\u304D\u3060\u3051\u3067\u3059\u3002\u4E0A\u7D1A\u8005\u30E2\u30FC\u30C9\uFF0815\u30C8\u30E9\u30C3\u30AF\uFF09\u304C15\u672C\u3042\u308B\u306E\u306F\u305D\u306E\u305F\u3081\u3067\u3001\u300C\u4F5C\u66F2\u300D\u306F\u5834\u6240\u3054\u3068\u306B\u30C8\u30E9\u30C3\u30AF\u3092\u5206\u3051\u307E\u3059\u3002</p>
|
|
20509
|
+
<ul>
|
|
20510
|
+
<li><strong>\u4F34\u594F\u306E\u624B\u89E6\u308A\u304C\u30BB\u30AF\u30B7\u30E7\u30F3\u3067\u5909\u308F\u308B</strong> \u2014 \u540C\u3058\u30B3\u30FC\u30C9\u9032\u884C\u3092\u3001\u30D6\u30ED\u30C3\u30AF\u30FB\u30A2\u30EB\u30DA\u30B8\u30AA\u30FB\u88CF\u62CD\u30FB\u516B\u5206\u98DF\u3044\u30FB\u5206\u6563\u306E\u4E2D\u304B\u3089<strong>\u5225\u3005\u306E\u594F\u6CD5</strong>\u30671\u301C3\u5C64\u306B\u91CD\u306D\u307E\u3059\u3002\u3069\u306E\u594F\u6CD5\u3092\u3069\u306E\u30BB\u30AF\u30B7\u30E7\u30F3\u3067\u9CF4\u3089\u3059\u304B\u306F\u66F2\u3054\u3068\u306B\u5F15\u304F\u306E\u3067\u3001A\u30E1\u30ED\u3068\u30B5\u30D3\u3067\u4F34\u594F\u306E\u523B\u307F\u65B9\u305D\u306E\u3082\u306E\u304C\u5909\u308F\u308A\u307E\u3059\u3002\u66F2\u5168\u4F53\u3092\u901A\u308B\u300C\u5730\u300D\u306E\u5C64\u304C1\u3064\u3042\u308A\u3001\u6B8B\u308A\u306F\u8DB3\u3059\u5834\u6240\u3092\u7D5E\u308A\u307E\u3059\u3002</li>
|
|
20511
|
+
<li><strong>\u30B5\u30D3\u306E\u91CD\u306D</strong> \u2014 \u4E3B\u65CB\u5F8B\u3092\u3082\u30461\u672C\u306E\u5225\u697D\u5668\uFF08\u30D7\u30EA\u30BB\u30C3\u30C8\u306B\u3088\u3063\u3066\u30D6\u30E9\u30B9\u30FB\u30B9\u30C8\u30EA\u30F3\u30B0\u30B9\u30FB\u30B0\u30ED\u30C3\u30B1\u30F3\u306A\u3069\uFF09\u3067\u91CD\u306D\u307E\u3059\u3002<strong>\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3068\u30E6\u30CB\u30BE\u30F3\u306E\u4E21\u65B9\u3092\u5F15\u304D\u307E\u3059</strong>\u2014\u2014\u540C\u3058\u9AD8\u3055\u3092\u5225\u306E\u697D\u5668\u3067\u91CD\u306D\u308B\u30682\u3064\u306E\u97F3\u8272\u304C\u6EB6\u3051\u3066\u5225\u306E\u97F3\u8272\u306B\u306A\u308B\u306E\u3067\u3001\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3052\u308B\u3088\u308A\u60C5\u5831\u91CF\u304C\u591A\u3044\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\u91CD\u306D\u306A\u3044\u66F2\u3082\u3042\u308A\u307E\u3059\u3002</li>
|
|
20512
|
+
<li><strong>\u9593\u594F\u306E\u30BD\u30ED</strong> \u2014 \u9593\u594F\u306F\u6B4C\u304C\u4F11\u3080\u5834\u6240\u3067\u3042\u3063\u3066\u3001\u97F3\u697D\u304C\u4F11\u3080\u5834\u6240\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u6B4C\u30E1\u30ED\u306E\u4EE3\u308F\u308A\u306B\u5668\u697D\u306E\u30BD\u30ED\u3092\u66F8\u304D\u3001\u5C02\u7528\u306E\u30C8\u30E9\u30C3\u30AF\u3067\u9CF4\u3089\u3057\u307E\u3059\u3002\u30D7\u30EA\u30BB\u30C3\u30C8\u306B\u3088\u3063\u3066\u6B6A\u307F\u30AE\u30BF\u30FC\u30FB\u30B5\u30C3\u30AF\u30B9\u30FB\u5C3A\u516B\u306A\u3069\u306B\u5909\u308F\u308A\u307E\u3059\u3002\u7D20\u6750\u306F\u30B5\u30D3\u3068\u540C\u3058\u306A\u306E\u3067\u3001\u9593\u594F\u304C\u30B5\u30D3\u306E\u4E3B\u984C\u3092\u5F3E\u304F\u5F62\u306B\u306A\u308A\u307E\u3059\u3002</li>
|
|
20513
|
+
<li><strong>\u30A6\u30EF\u30E2\u30CE</strong> \u2014 \u304D\u3089\u3073\u3084\u304B\u306A\u88C5\u98FE\u3092\u3001\u76DB\u308A\u4E0A\u304C\u308B\u30BB\u30AF\u30B7\u30E7\u30F3\u306B\u3060\u3051\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3067\u8DB3\u3057\u307E\u3059\u3002<strong>\u5730\u306E\u4F34\u594F\u3068\u540C\u3058\u594F\u6CD5\u306F\u4F7F\u3044\u307E\u305B\u3093</strong>\u2014\u2014\u540C\u3058\u3082\u306E\u3092\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3052\u305F\u3060\u3051\u306E\u5C64\u306F\u88C5\u98FE\u3067\u306F\u306A\u304F\u5199\u3057\u3060\u304B\u3089\u3067\u3059\u3002\u30D6\u30ED\u30C3\u30AF\u3082\u5916\u3057\u307E\u3059\uFF08\u548C\u97F3\u3092\u4E38\u3054\u3068\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3067\u9CF4\u3089\u3059\u306E\u306F\u88C5\u98FE\u3067\u306F\u306A\u304F\u58C1\u306B\u306A\u308A\u307E\u3059\uFF09\u3002</li>
|
|
20514
|
+
</ul>
|
|
20515
|
+
<p><strong>\u697D\u5668\u306E\u97F3\u57DF\u306B\u5408\u308F\u305B\u3066\u30AA\u30AF\u30BF\u30FC\u30D6\u3092\u4E0B\u3052\u307E\u3059\u3002</strong>1\u30C8\u30E9\u30C3\u30AF1\u697D\u5668\u3067\u3001\u3057\u304B\u3082\u5C64\u3054\u3068\u306B\u30AA\u30AF\u30BF\u30FC\u30D6\u3092\u5909\u3048\u308B\u306E\u3067\u3001\u6C7A\u3081\u305F\u30AA\u30AF\u30BF\u30FC\u30D6\u304C\u305D\u306E\u697D\u5668\u306E\u51FA\u305B\u306A\u3044\u9AD8\u3055\u306B\u306A\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\u5B9F\u6E2C\u3059\u308B\u3068\u3001\u30B5\u30D3\u306E\u91CD\u306D\u30921\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3052\u308B\u6307\u5B9A\u306F\u30DF\u30E5\u30FC\u30C8\u30C8\u30E9\u30F3\u30DA\u30C3\u30C8\u3084\u30C8\u30E9\u30F3\u30DA\u30C3\u30C8\u306714\u534A\u97F3\u3076\u3093\u3001\u30B3\u30FC\u30C9\u30D1\u30C3\u30C9\uFF08\u5B9F\u97F377\u301C93\uFF09\u306F\u30CA\u30A4\u30ED\u30F3\u30AE\u30BF\u30FC\u306710\u534A\u97F3\u30FB\u30AB\u30EA\u30F3\u30D0\u30679\u534A\u97F3\u3076\u3093\u97F3\u57DF\u3092\u7A81\u304D\u629C\u3051\u3066\u3044\u307E\u3057\u305F\u3002\u30B5\u30F3\u30D7\u30EB\u304C\u5F15\u304D\u4F38\u3070\u3055\u308C\u3066<strong>\u91D1\u5207\u308A\u97F3</strong>\u306B\u306A\u308A\u3001\u8074\u304D\u624B\u306B\u306F\u300C\u8033\u304C\u75DB\u3044\u300D\u3068\u3057\u304B\u611F\u3058\u3089\u308C\u307E\u305B\u3093\u3002\u305D\u3053\u3067\u3001\u9CF4\u3089\u3059\u97F3\u57DF\u304C\u305D\u306E\u697D\u5668\u306E\u5B9F\u7528\u4E0A\u9650\u306B\u53CE\u307E\u308B\u3068\u3053\u308D\u307E\u3067<strong>\u30AA\u30AF\u30BF\u30FC\u30D6\u3092\u4E0B\u3052\u3066\u304B\u3089</strong>\u7F6E\u304D\u307E\u3059\uFF08\u30C8\u30E9\u30C3\u30AF\u306E\u30AA\u30AF\u30BF\u30FC\u30D6\u8A2D\u5B9A\u306F\u3001\u307E\u3055\u306B\u3053\u3046\u3044\u3046\u300C\u5F97\u610F\u306A\u97F3\u57DF\u304C\u504F\u3063\u305F\u97F3\u6E90\u300D\u3092\u4F7F\u3048\u308B\u3088\u3046\u306B\u3059\u308B\u305F\u3081\u306B\u5728\u308B\u3082\u306E\u3067\u3059\uFF09\u3002<strong>\u4E0B\u3052\u308B\u65B9\u5411\u306B\u3057\u304B\u52D5\u304B\u3057\u307E\u305B\u3093</strong>\u2014\u2014\u4E0A\u3052\u308B\u5074\u304C\u75DB\u307F\u3092\u4F5C\u308B\u5074\u306A\u306E\u3067\u3002</p>
|
|
20516
|
+
<p>\u5B9F\u7269\u306E\u97F3\u57DF\u306B\u53CE\u307E\u3063\u3066\u3044\u3066\u3082\u75DB\u304F\u306A\u308B\u97F3\u8272\u304C\u3042\u308A\u307E\u3059\u3002\u30B0\u30ED\u30C3\u30B1\u30F3\u306F\u5B9F\u7269\u306E\u97F3\u57DF\u304CG5\u301CC8\u306A\u306E\u3067\u3001\u65CB\u5F8B\u306E\u97F3\u57DF\uFF08\u301CC6\uFF09\u306F\u300C\u4F59\u88D5\u3067\u7BC4\u56F2\u5185\u300D\u3067\u3059\u304C\u3001\u91D1\u5C5E\u4F53\u306E\u500D\u97F3\u306F\u4EBA\u306E\u8033\u304C\u3044\u3061\u3070\u3093\u654F\u611F\u306A2\u301C4kHz\u306B\u96C6\u307E\u308B\u305F\u3081\u3001\u305D\u306E\u9AD8\u3055\u3067\u9CF4\u3089\u3057\u7D9A\u3051\u308B\u3068\u523A\u3055\u308A\u307E\u3059\u3002\u3053\u3046\u3044\u3046\u97F3\u8272\u306B\u306F\u97F3\u57DF\u3068\u306F\u5225\u306B<strong>\u660E\u308B\u3055\u306E\u4E0A\u9650</strong>\u3092\u6301\u305F\u305B\u3066\u3042\u308A\u3001\u30B0\u30ED\u30C3\u30B1\u30F3\u306A\u3089C5\u3088\u308A\u4E0A\u3067\u9CF4\u3089\u306A\u3044\u3068\u3053\u308D\u307E\u3067\u4E0B\u3052\u307E\u3059\u3002<strong>\u5019\u88DC\u304B\u3089\u5916\u3059\u306E\u3067\u306F\u306A\u304F\u7F6E\u304D\u5834\u6240\u3092\u5909\u3048\u307E\u3059</strong>\u2014\u2014\u5916\u3059\u3068\u97F3\u8272\u306E\u5E45\u304C\u305D\u306E\u3076\u3093\u6E1B\u308B\u3060\u3051\u3067\u3001\u4F4E\u304F\u9CF4\u3089\u3057\u305F\u30B0\u30ED\u30C3\u30B1\u30F3\u306F\u30DD\u30C3\u30D7\u30B9\u3067\u666E\u901A\u306B\u4F7F\u308F\u308C\u308B\u67D4\u3089\u304B\u3044\u97F3\u3067\u3059\u3002</p>
|
|
20517
|
+
<p><strong>\u30AA\u30AF\u30BF\u30FC\u30D6\u306E\u91CD\u306D\u3092\u4E3B\u5F79\u306B\u3057\u3066\u3044\u307E\u305B\u3093\u3002</strong>\u300C\u65E2\u306B\u3042\u308B\u30C8\u30E9\u30C3\u30AF\u30921\u30AA\u30AF\u30BF\u30FC\u30D6\u52D5\u304B\u3057\u3066\u5225\u30C8\u30E9\u30C3\u30AF\u3078\u5199\u3059\u300D\u5C64\u306F\u3001\u97F3\u697D\u7684\u306A\u4FA1\u5024\u304C\u9AD8\u304F\u3042\u308A\u307E\u305B\u3093\u3002\u4EBA\u306E\u8033\u306F\u30AA\u30AF\u30BF\u30FC\u30D6\u9055\u3044\u3092<strong>\u540C\u3058\u97F3</strong>\u3068\u3057\u3066\u805E\u304F\u306E\u3067\uFF08\u30AA\u30AF\u30BF\u30FC\u30D6\u7B49\u4FA1\uFF09\u3001\u5199\u3057\u305F\u5C64\u306F\u65B0\u3057\u3044\u58F0\u90E8\u306B\u306A\u3089\u305A\u3001\u97F3\u91CF\u3068\u97F3\u8272\u304C\u308F\u305A\u304B\u306B\u5909\u308F\u308B\u3060\u3051\u3067\u3059\u3002\u5F37\u8ABF\u3068\u3057\u3066\u306E\u610F\u5473\u306F\u3042\u308B\u306E\u3067\u4F7F\u3044\u306F\u3057\u307E\u3059\u304C\u3001\u5E38\u8A2D\u306B\u306F\u3057\u307E\u305B\u3093\u3002\u30D9\u30FC\u30B9\u306E\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0B\u306E\u91CD\u306D\u306F\u7279\u306B\u300130Hz\u524D\u5F8C\u307E\u3067\u843D\u3061\u3066\u8F2A\u90ED\u304C\u6FC1\u308B\u306E\u3067\u65E2\u5B9A\u3067\u306F\u51FA\u3057\u307E\u305B\u3093\uFF08\u51FA\u3059\u3068\u304D\u3082\u4E0A\u306E\u30AA\u30AF\u30BF\u30FC\u30D6\u3078\u3001\u76DB\u308A\u4E0A\u304C\u308B\u5834\u6240\u3060\u3051\u306B\u7F6E\u304D\u307E\u3059\uFF09\u3002</p>
|
|
20518
|
+
<p>\u300C\u4F5C\u66F2\u300D\u304C\u6C7A\u3081\u305F\u3053\u308C\u3089\u306E\u697D\u5668\u306F\u3001\u304A\u307E\u304B\u305B\u30DE\u30B9\u30BF\u30EA\u30F3\u30B0\u306E\u5F79\u5272\u63A8\u5B9A\u3088\u308A\u512A\u5148\u3055\u308C\u307E\u3059\uFF08\u6F14\u594F\u5185\u5BB9\u3060\u3051\u3092\u898B\u308B\u3068\u3001\u9593\u594F\u306E\u30BD\u30ED\u3082\u30B5\u30D3\u306E\u91CD\u306D\u3082\u300C\u97F3\u306E\u5C11\u306A\u3044\u5358\u65CB\u5F8B\u300D\u3067\u3001\u4E3B\u65CB\u5F8B\u3068\u533A\u5225\u304C\u4ED8\u304B\u306A\u3044\u305F\u3081\u3067\u3059\uFF09\u3002\u697D\u5668\u3092\u624B\u3067\u9078\u3073\u76F4\u3057\u305F\u30C8\u30E9\u30C3\u30AF\u306F\u3001\u4EE5\u5F8C\u3069\u3061\u3089\u306B\u3082\u4E0A\u66F8\u304D\u3055\u308C\u307E\u305B\u3093\u3002</p>
|
|
18686
20519
|
<h4>\u305D\u306E\u307B\u304B</h4>
|
|
18687
20520
|
<ul>
|
|
20521
|
+
<li><strong>\u66F2\u306E\u9014\u4E2D\u3067\u8EE2\u8ABF\u3057\u307E\u3059</strong>\uFF08\u304A\u3088\u305D\u534A\u5206\u306E\u66F2\uFF09\u3002\u4E94\u5EA6\u570F\u3067\u8FD1\u3044\u5C5E\u8ABF\u30FB\u4E0B\u5C5E\u8ABF\u3078\u306F\u5171\u901A\u3059\u308B\u548C\u97F3\uFF08\u30D4\u30DC\u30C3\u30C8\u30B3\u30FC\u30C9\uFF09\u304B\u65B0\u3057\u3044\u8ABF\u306E\u30C9\u30DF\u30CA\u30F3\u30C8\u3067\u6A4B\u6E21\u3057\u3057\u3001\u30E9\u30B9\u30B5\u30D3\u306E\u534A\u97F3\u4E0A\u3052\u306F\u6E96\u5099\u306A\u3057\u306E\u76F4\u63A5\u8EE2\u8ABF\u306B\u3057\u307E\u3059\u3002\u8ABF\u53F7\u3092\u5909\u3048\u305A\u306B\u660E\u6697\u3060\u3051\u5165\u308C\u66FF\u3048\u308B<strong>\u5E73\u884C\u8ABF</strong>\uFF08\u30CF\u9577\u8ABF\u2194\u30A4\u77ED\u8ABF\uFF09\u3068\u3001\u4E3B\u97F3\u3092\u4FDD\u3063\u305F\u307E\u307E\u6697\u304F\u3059\u308B<strong>\u540C\u4E3B\u8ABF</strong>\uFF08\u30CF\u9577\u8ABF\u2192\u30CF\u77ED\u8ABF\uFF09\u3082\u5F15\u304D\u307E\u3059\u30021\u5272\u5F37\u306E\u66F2\u306F\u4E3B\u548C\u97F3\u3092\u907F\u3051\u3066\u300C\u660E\u308B\u3044\u306E\u304B\u6697\u3044\u306E\u304B\u5206\u304B\u3089\u306A\u3044\u300D\u6D6E\u904A\u611F\u3067\u901A\u3057\u307E\u3059\u3002</li>
|
|
18688
20522
|
<li>\u8ABF\u306F\u30CF\u9577\u8ABF\uFF08\u307E\u305F\u306F\u30A4\u77ED\u8ABF\uFF09\u3067\u56FA\u5B9A\u3067\u3059\u3002\u5225\u306E\u8ABF\u306B\u3057\u305F\u3044\u3068\u304D\u306F\u3001\u3053\u306E\u4E0B\u306E\u300C\u79FB\u8ABF\u300D\u3067\u52D5\u304B\u3057\u3066\u304F\u3060\u3055\u3044\u3002</li>
|
|
18689
20523
|
<li>31\u5E73\u5747\u5F8B\u306E\u66F2\u3067\u3082\u4F7F\u3048\u307E\u3059\u3002\u548C\u97F3\u30FB\u30E1\u30ED\u30C7\u30A3\u3068\u308231\u5E73\u5747\u5F8B\u306E\u683C\u5B50\u306B\u4E57\u305B\u3066\u751F\u6210\u3057\u307E\u3059\u3002</li>
|
|
18690
20524
|
<li><strong>\u30C9\u30E9\u30E0\u3082\u66F2\u306B\u5408\u308F\u305B\u3066\u7D44\u307F\u7ACB\u3066\u307E\u3059</strong>\u3002\u30C6\u30F3\u30DD\u3068\u30E1\u30ED\u30C7\u30A3\u306E\u523B\u307F\u304B\u30898\u30D3\u30FC\u30C8\uFF0F16\u30D3\u30FC\u30C8\uFF0F4\u3064\u6253\u3061\uFF0F\u30B7\u30E3\u30C3\u30D5\u30EB\uFF0F\u30D0\u30E9\u30FC\u30C9\uFF0F\u30ED\u30C3\u30AF\u306E\u3069\u308C\u304B\u3092\u9078\u3073\u3001A\u30FBA'\u30FB\u30B5\u30D3\u30FBA'' \u3067\u523B\u307F\u306E\u5F37\u3055\u3092\u5909\u3048\u30014\u5C0F\u7BC0\u3054\u3068\u306B\u30D5\u30A3\u30EB\u3001\u30BB\u30AF\u30B7\u30E7\u30F3\u306E\u982D\u306B\u30AF\u30E9\u30C3\u30B7\u30E5\u3092\u7F6E\u304D\u307E\u3059\u3002\u6C17\u306B\u5165\u3089\u306A\u3051\u308C\u3070\u300C\u30C9\u30E9\u30E0\u8A2D\u5B9A\u300D\u304B\u3089\u4ED6\u306E\u30EA\u30BA\u30E0\u3078\u5207\u308A\u66FF\u3048\u3089\u308C\u307E\u3059\u3002</li>
|
|
@@ -18948,19 +20782,128 @@ var pickComposeVocal = (exclude) => {
|
|
|
18948
20782
|
const list = pool.length > 0 ? pool : COMPOSE_VOCAL_POOL;
|
|
18949
20783
|
return list[Math.floor(Math.random() * list.length)] ?? "klatt";
|
|
18950
20784
|
};
|
|
18951
|
-
var
|
|
18952
|
-
{
|
|
18953
|
-
|
|
18954
|
-
|
|
18955
|
-
|
|
18956
|
-
|
|
18957
|
-
|
|
18958
|
-
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
20785
|
+
var buildAdvancedLayers = (song, config) => {
|
|
20786
|
+
const { edo, stepsPerBar, preset } = config;
|
|
20787
|
+
const semitoneRange = (notes) => {
|
|
20788
|
+
if (notes.length === 0) return null;
|
|
20789
|
+
let lo = Number.POSITIVE_INFINITY;
|
|
20790
|
+
let hi = Number.NEGATIVE_INFINITY;
|
|
20791
|
+
for (const n of notes) {
|
|
20792
|
+
const semi = n.pitchUnits / UNITS_PER_SEMITONE;
|
|
20793
|
+
if (semi < lo) lo = semi;
|
|
20794
|
+
if (semi > hi) hi = semi;
|
|
20795
|
+
}
|
|
20796
|
+
return [Math.round(lo), Math.round(hi)];
|
|
20797
|
+
};
|
|
20798
|
+
const fit = (notes, slot, wanted) => fitInstrumentOctave(semitoneRange(notes), preset[slot], wanted);
|
|
20799
|
+
const kindAtBar = (bar) => song.sections.find(
|
|
20800
|
+
(sec) => bar >= sec.startBar && bar < sec.startBar + sec.bars
|
|
20801
|
+
)?.kind ?? null;
|
|
20802
|
+
const onlyIn = (notes, kinds) => {
|
|
20803
|
+
if (!kinds) return notes;
|
|
20804
|
+
const want = new Set(kinds);
|
|
20805
|
+
return notes.filter((n) => {
|
|
20806
|
+
const kind = kindAtBar(Math.floor(n.startStep / stepsPerBar));
|
|
20807
|
+
return kind !== null && want.has(kind);
|
|
20808
|
+
});
|
|
20809
|
+
};
|
|
20810
|
+
const chordNotes = (pattern, velocityShift = 0) => buildChordPlacements({
|
|
20811
|
+
edo,
|
|
20812
|
+
chordStr: song.chordProgression,
|
|
20813
|
+
patternType: pattern,
|
|
20814
|
+
rootShift: song.rootShift,
|
|
20815
|
+
bpm: song.bpm,
|
|
20816
|
+
stepsPerBar
|
|
20817
|
+
}).map((p) => ({
|
|
20818
|
+
startStep: p.startStep,
|
|
20819
|
+
pitchUnits: p.pitchUnits,
|
|
20820
|
+
durationSteps: p.durationSteps,
|
|
20821
|
+
velocity: Math.max(30, p.velocity + velocityShift)
|
|
20822
|
+
}));
|
|
20823
|
+
const plan = song.arrange;
|
|
20824
|
+
const leadNotes = plan.lead ? onlyIn(song.melody, plan.lead.sections) : [];
|
|
20825
|
+
const leadOctave = fit(leadNotes, "chorusLead", plan.lead?.octave ?? 0);
|
|
20826
|
+
const leadLayer = {
|
|
20827
|
+
index: 1,
|
|
20828
|
+
notes: leadNotes,
|
|
20829
|
+
octave: leadOctave,
|
|
20830
|
+
// ユニゾンで重ねるときは、オクターブ上より前に出やすいので少し引く。
|
|
20831
|
+
volume: leadOctave === 0 ? 54 : 62,
|
|
20832
|
+
slot: "chorusLead"
|
|
20833
|
+
};
|
|
20834
|
+
const bassNotes = plan.bassLayer ? onlyIn(song.bass, plan.bassLayer.sections) : [];
|
|
20835
|
+
const bassOctave = fit(bassNotes, "bass", plan.bassLayer?.octave ?? 0);
|
|
20836
|
+
const bassLayer = {
|
|
20837
|
+
index: 5,
|
|
20838
|
+
notes: bassOctave === 0 ? [] : bassNotes,
|
|
20839
|
+
octave: bassOctave,
|
|
20840
|
+
volume: 58,
|
|
20841
|
+
slot: "bass"
|
|
20842
|
+
};
|
|
20843
|
+
const padNotes = onlyIn(song.pad, plan.padSections);
|
|
20844
|
+
const layers = [
|
|
20845
|
+
{ index: 0, notes: song.melody, octave: 0, volume: 104, slot: "melody" },
|
|
20846
|
+
leadLayer,
|
|
20847
|
+
{ index: 2, notes: song.harmony, octave: 0, volume: 82 },
|
|
20848
|
+
{
|
|
20849
|
+
index: 3,
|
|
20850
|
+
notes: song.submelody,
|
|
20851
|
+
octave: 0,
|
|
20852
|
+
volume: 86,
|
|
20853
|
+
slot: "submelody"
|
|
20854
|
+
},
|
|
20855
|
+
{ index: 4, notes: song.bass, octave: 0, volume: 92, slot: "bass" },
|
|
20856
|
+
bassLayer,
|
|
20857
|
+
// **パッドは伴奏用の楽器で、伴奏より1.5オクターブ高いところを鳴らす。**
|
|
20858
|
+
// そのまま置くとナイロンギターで10半音、カリンバで9半音、尺八で7半音ぶん
|
|
20859
|
+
// 音域を突き抜ける。楽器に合わせて下げる。
|
|
20860
|
+
{
|
|
20861
|
+
index: 6,
|
|
20862
|
+
notes: padNotes,
|
|
20863
|
+
octave: fit(padNotes, "chord", 0),
|
|
20864
|
+
volume: 64,
|
|
20865
|
+
slot: "chord"
|
|
20866
|
+
}
|
|
20867
|
+
];
|
|
20868
|
+
const backingVolumes = [62, 54, 50];
|
|
20869
|
+
for (let i2 = 0; i2 < 3; i2++) {
|
|
20870
|
+
const layer = plan.backing[i2];
|
|
20871
|
+
layers.push({
|
|
20872
|
+
index: 7 + i2,
|
|
20873
|
+
notes: layer ? onlyIn(chordNotes(layer.pattern), layer.sections) : [],
|
|
20874
|
+
octave: layer?.octave ?? 0,
|
|
20875
|
+
volume: backingVolumes[i2],
|
|
20876
|
+
slot: "chord"
|
|
20877
|
+
});
|
|
20878
|
+
}
|
|
20879
|
+
const sparkleNotes = plan.sparkle ? onlyIn(chordNotes(plan.sparkle.pattern, -14), plan.sparkle.sections) : [];
|
|
20880
|
+
layers.push(
|
|
20881
|
+
{
|
|
20882
|
+
index: 10,
|
|
20883
|
+
notes: sparkleNotes,
|
|
20884
|
+
octave: fit(sparkleNotes, "chord", plan.sparkle?.octave ?? 0),
|
|
20885
|
+
volume: 56,
|
|
20886
|
+
slot: "chord"
|
|
20887
|
+
},
|
|
20888
|
+
// 掛け合い(デュエット)の相手。**歌入り作曲のときだけ**中身が入る。
|
|
20889
|
+
{ index: 11, notes: [], octave: 0, volume: 104, slot: "melody" },
|
|
20890
|
+
// 2声目のハモリ(主旋律を上下から挟む3声)と、主旋律のオクターブ下の重ね。
|
|
20891
|
+
// どちらも曲ごとに出るかどうかが決まる(`song.vocal`)。
|
|
20892
|
+
{ index: 12, notes: song.harmony2, octave: 0, volume: 74 },
|
|
20893
|
+
{ index: 13, notes: song.octave, octave: -1, volume: 56, slot: "melody" },
|
|
20894
|
+
// **間奏のソロ。** 音が入るのは間奏の小節だけなので、この1本だけを
|
|
20895
|
+
// 別の楽器にしても他のセクションの鳴りは変わらない。歌の音域をそのまま
|
|
20896
|
+
// 渡すと管楽器が上へ抜ける(テナーサックスで10半音)ので、ここも合わせる。
|
|
20897
|
+
{
|
|
20898
|
+
index: 14,
|
|
20899
|
+
notes: song.solo,
|
|
20900
|
+
octave: fit(song.solo, "solo", 0),
|
|
20901
|
+
volume: 100,
|
|
20902
|
+
slot: "solo"
|
|
20903
|
+
}
|
|
20904
|
+
);
|
|
20905
|
+
return layers;
|
|
20906
|
+
};
|
|
18964
20907
|
var LYRIC_MODEL_CATEGORIES = [
|
|
18965
20908
|
{
|
|
18966
20909
|
label: "kusa\u30D7\u30EA\u30BB\u30C3\u30C8",
|
|
@@ -19116,7 +21059,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
19116
21059
|
showChord,
|
|
19117
21060
|
showMidiSearch,
|
|
19118
21061
|
// 「作曲」は simple では役割固定の4トラックへ、advanced では15トラックへ
|
|
19119
|
-
// 編曲を展開する({@link
|
|
21062
|
+
// 編曲を展開する({@link buildAdvancedLayers})。どちらでも出す。
|
|
19120
21063
|
showCompose: true
|
|
19121
21064
|
});
|
|
19122
21065
|
refs.masterVolume.value = String(options.masterVolume ?? 50);
|
|
@@ -19239,6 +21182,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
19239
21182
|
let currentDrumPattern = refs.drumSelect.value;
|
|
19240
21183
|
const recentComposeFingerprints = [];
|
|
19241
21184
|
let autoComposeVocal = null;
|
|
21185
|
+
const autoComposeVocalTracks = /* @__PURE__ */ new Map();
|
|
19242
21186
|
let currentDrumFont = options.drumFont ?? "FluidR3_GM_sf2_file:0";
|
|
19243
21187
|
refs.drumFontSelect.value = currentDrumFont;
|
|
19244
21188
|
const applyDrumPatternFont = (name) => {
|
|
@@ -19309,6 +21253,14 @@ var mountDAW = (target, options = {}) => {
|
|
|
19309
21253
|
while (customVocalsMap.has(`custom${n}`)) n++;
|
|
19310
21254
|
return `custom${n}`;
|
|
19311
21255
|
};
|
|
21256
|
+
const getVocalIconSrc = (lyricModel) => {
|
|
21257
|
+
if (!lyricModel) return void 0;
|
|
21258
|
+
const customDef = customVocalsMap.get(lyricModel);
|
|
21259
|
+
if (customDef !== void 0)
|
|
21260
|
+
return customDef.iconUrl || FALLBACK_VOCAL_ICON;
|
|
21261
|
+
const imgKey = VOICE_IMAGE_KEY[lyricModel.toLowerCase()];
|
|
21262
|
+
return imgKey ? VOICE_IMAGES[imgKey] : void 0;
|
|
21263
|
+
};
|
|
19312
21264
|
let selectedNotes = [];
|
|
19313
21265
|
let selectionRect = null;
|
|
19314
21266
|
let copiedNotes = [];
|
|
@@ -19442,6 +21394,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
19442
21394
|
vocalTension: t1?.vocalTension ?? 50,
|
|
19443
21395
|
vocalOctaveUnison: t1?.vocalOctaveUnison ?? "none",
|
|
19444
21396
|
trackInstrument: t1?.trackInstrument ?? "",
|
|
21397
|
+
composeSlot: null,
|
|
19445
21398
|
trackCompression: t1?.trackCompression ?? 0,
|
|
19446
21399
|
trackWidth: t1?.trackWidth ?? 100,
|
|
19447
21400
|
trackReverbSend: t1?.trackReverbSend ?? 0,
|
|
@@ -20493,25 +22446,38 @@ var mountDAW = (target, options = {}) => {
|
|
|
20493
22446
|
refs.undoBtn.disabled = !core.canUndo();
|
|
20494
22447
|
refs.redoBtn.disabled = !core.canRedo();
|
|
20495
22448
|
};
|
|
20496
|
-
const
|
|
22449
|
+
const updateTrackTabs = () => {
|
|
20497
22450
|
refs.trackTabs.innerHTML = "";
|
|
20498
22451
|
trackPillEls.clear();
|
|
20499
22452
|
for (const [i2, t] of trackStates.entries()) {
|
|
20500
22453
|
const [r, g, b] = t.config.color;
|
|
20501
22454
|
const isActive = t.config.id === activeTrackId;
|
|
20502
22455
|
const btn = document.createElement("button");
|
|
20503
|
-
|
|
22456
|
+
const vocalIconSrc = getVocalIconSrc(t.lyricModel);
|
|
22457
|
+
btn.className = `dtm-pill ${isActive ? "dtm-pill--active" : ""} ${vocalIconSrc ? "dtm-pill--vocal" : ""}`;
|
|
20504
22458
|
btn.style.setProperty("--dtm-pill-color", `rgb(${r},${g},${b})`);
|
|
22459
|
+
if (vocalIconSrc) {
|
|
22460
|
+
btn.style.setProperty(
|
|
22461
|
+
"--dtm-pill-icon",
|
|
22462
|
+
`url(${JSON.stringify(vocalIconSrc)})`
|
|
22463
|
+
);
|
|
22464
|
+
}
|
|
20505
22465
|
btn.title = `Track ${i2 + 1}: ${t.config.name}`;
|
|
20506
22466
|
btn.setAttribute(
|
|
20507
22467
|
"aria-label",
|
|
20508
|
-
`Track ${i2 + 1}: ${t.config.name}${isActive ? " (\u9078\u629E\u4E2D)" : ""}`
|
|
22468
|
+
`Track ${i2 + 1}: ${t.config.name}${isActive ? " (\u9078\u629E\u4E2D)" : ""}${vocalIconSrc ? "\uFF08\u30DC\u30FC\u30AB\u30EB\u9078\u629E\u4E2D\uFF09" : ""}`
|
|
20509
22469
|
);
|
|
20510
|
-
|
|
22470
|
+
const labelEl = document.createElement("span");
|
|
22471
|
+
labelEl.className = "dtm-pill__label";
|
|
22472
|
+
labelEl.textContent = String(i2 + 1);
|
|
22473
|
+
btn.appendChild(labelEl);
|
|
20511
22474
|
btn.addEventListener("click", () => switchTrack(t.config.id));
|
|
20512
22475
|
refs.trackTabs.appendChild(btn);
|
|
20513
22476
|
trackPillEls.set(t.config.id, btn);
|
|
20514
22477
|
}
|
|
22478
|
+
};
|
|
22479
|
+
const updateTrackPanel = () => {
|
|
22480
|
+
updateTrackTabs();
|
|
20515
22481
|
const active = getActive();
|
|
20516
22482
|
const activeIndex = trackStates.findIndex(
|
|
20517
22483
|
(t) => t.config.id === activeTrackId
|
|
@@ -20828,6 +22794,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
20828
22794
|
syncInstDisabled();
|
|
20829
22795
|
instSel.addEventListener("change", () => {
|
|
20830
22796
|
active.trackInstrument = instSel.value;
|
|
22797
|
+
active.composeSlot = null;
|
|
20831
22798
|
const trackIndex = trackStates.indexOf(active);
|
|
20832
22799
|
options.onTrackInstrumentChange?.(trackIndex, active.trackInstrument);
|
|
20833
22800
|
persistTrack1(active);
|
|
@@ -21231,6 +23198,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
21231
23198
|
redrawAll();
|
|
21232
23199
|
fireLyricsChange(active);
|
|
21233
23200
|
reloadVoicesForModel(active.lyricModel);
|
|
23201
|
+
updateTrackTabs();
|
|
21234
23202
|
});
|
|
21235
23203
|
lyricCustomGuide.addEventListener("click", () => {
|
|
21236
23204
|
showModal("\u30AB\u30B9\u30BF\u30E0\u97F3\u58F0(.koe)\u306E\u4F7F\u3044\u65B9", KOE_INFO_HTML);
|
|
@@ -21764,6 +23732,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
21764
23732
|
}
|
|
21765
23733
|
trackStates.forEach((t, i2) => {
|
|
21766
23734
|
if (applyActiveOnly && i2 !== activeTrackIndex) return;
|
|
23735
|
+
t.composeSlot = null;
|
|
21767
23736
|
const name = normalizeInstrumentName(meta.trackInstruments?.[i2] ?? "");
|
|
21768
23737
|
if (t.trackInstrument !== name) {
|
|
21769
23738
|
t.trackInstrument = name;
|
|
@@ -22006,16 +23975,32 @@ var mountDAW = (target, options = {}) => {
|
|
|
22006
23975
|
updateTrackPanel();
|
|
22007
23976
|
updateUndoRedo();
|
|
22008
23977
|
};
|
|
22009
|
-
const exportMIDI2 = () =>
|
|
22010
|
-
|
|
22011
|
-
|
|
22012
|
-
|
|
22013
|
-
|
|
22014
|
-
|
|
22015
|
-
|
|
22016
|
-
|
|
22017
|
-
|
|
22018
|
-
|
|
23978
|
+
const exportMIDI2 = () => {
|
|
23979
|
+
const autoPreset = INSTRUMENT_PRESETS[currentInstrument] ?? INSTRUMENT_PRESETS.piano;
|
|
23980
|
+
return exportMIDI({
|
|
23981
|
+
tracks: trackStates.map((t) => {
|
|
23982
|
+
let program;
|
|
23983
|
+
if (t.trackInstrument) {
|
|
23984
|
+
const p = programOfInstrumentName(t.trackInstrument);
|
|
23985
|
+
if (p !== null) program = p;
|
|
23986
|
+
} else if (!t.lyricModel) {
|
|
23987
|
+
const role = t.composeSlot ?? DECLARED_ROLE[t.config.id] ?? "melody";
|
|
23988
|
+
const instName = autoPreset[role] ?? autoPreset.melody;
|
|
23989
|
+
const p = programOfInstrumentName(instName);
|
|
23990
|
+
if (p !== null) program = p;
|
|
23991
|
+
}
|
|
23992
|
+
return {
|
|
23993
|
+
notes: playableNotes(t),
|
|
23994
|
+
volume: t.volume,
|
|
23995
|
+
program
|
|
23996
|
+
};
|
|
23997
|
+
}),
|
|
23998
|
+
getDrumPattern: (currentBar) => resolveDrumPattern(currentDrumPattern, drumPatterns, currentBar),
|
|
23999
|
+
drumVolume,
|
|
24000
|
+
bpm,
|
|
24001
|
+
stepsPerBar: renderConfig.stepsPerBar
|
|
24002
|
+
});
|
|
24003
|
+
};
|
|
22019
24004
|
const setBpm = (value) => {
|
|
22020
24005
|
bpm = value;
|
|
22021
24006
|
refs.bpmInput.value = String(value);
|
|
@@ -22368,7 +24353,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
22368
24353
|
if (!stats) continue;
|
|
22369
24354
|
const role = DECLARED_ROLE[t.config.id] ?? classifyTrackRole(stats, t.config.id === topSingleVoiceId);
|
|
22370
24355
|
roleByTrackId.set(t.config.id, role);
|
|
22371
|
-
const instName = autoPreset[role];
|
|
24356
|
+
const instName = autoPreset[t.composeSlot ?? role] ?? autoPreset[role];
|
|
22372
24357
|
t.trackInstrument = instName;
|
|
22373
24358
|
const trackIndex = trackStates.indexOf(t);
|
|
22374
24359
|
options.onTrackInstrumentChange?.(trackIndex, instName);
|
|
@@ -22519,6 +24504,15 @@ var mountDAW = (target, options = {}) => {
|
|
|
22519
24504
|
refs.composeKey.value = savedKey;
|
|
22520
24505
|
}
|
|
22521
24506
|
}
|
|
24507
|
+
const savedScale = readMacroSetting("scale");
|
|
24508
|
+
if (savedScale && refs.composeScale) {
|
|
24509
|
+
const hasOption = Array.from(refs.composeScale.options).some(
|
|
24510
|
+
(opt) => opt.value === savedScale
|
|
24511
|
+
);
|
|
24512
|
+
if (hasOption) {
|
|
24513
|
+
refs.composeScale.value = savedScale;
|
|
24514
|
+
}
|
|
24515
|
+
}
|
|
22522
24516
|
const savedShift = readMacroSetting("shift");
|
|
22523
24517
|
if (savedShift && refs.shiftSelect) {
|
|
22524
24518
|
const hasOption = Array.from(refs.shiftSelect.options).some(
|
|
@@ -22581,6 +24575,20 @@ var mountDAW = (target, options = {}) => {
|
|
|
22581
24575
|
});
|
|
22582
24576
|
updateComposeKeyHint();
|
|
22583
24577
|
}
|
|
24578
|
+
const updateComposeScaleHint = () => {
|
|
24579
|
+
if (!refs.composeScale || !refs.composeScaleHint) return;
|
|
24580
|
+
const desc = getComposeScaleDescription(refs.composeScale.value);
|
|
24581
|
+
refs.composeScaleHint.textContent = desc;
|
|
24582
|
+
refs.composeScaleHint.title = desc;
|
|
24583
|
+
};
|
|
24584
|
+
const composeScale = refs.composeScale;
|
|
24585
|
+
if (composeScale) {
|
|
24586
|
+
composeScale.addEventListener("change", () => {
|
|
24587
|
+
writeMacroSetting("scale", composeScale.value);
|
|
24588
|
+
updateComposeScaleHint();
|
|
24589
|
+
});
|
|
24590
|
+
updateComposeScaleHint();
|
|
24591
|
+
}
|
|
22584
24592
|
if (refs.shiftSelect) {
|
|
22585
24593
|
refs.shiftSelect.addEventListener("change", () => {
|
|
22586
24594
|
writeMacroSetting("shift", refs.shiftSelect.value);
|
|
@@ -22601,6 +24609,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
22601
24609
|
sections: selectedComposeSections(),
|
|
22602
24610
|
template: tmpl,
|
|
22603
24611
|
baseKey: refs.composeKey?.value ?? "any",
|
|
24612
|
+
scale: refs.composeScale?.value ?? "auto",
|
|
22604
24613
|
// 直近に作った曲の特徴を渡すと、それらから離れた候補に加点される。
|
|
22605
24614
|
// 「作曲」を続けて押したときに似た曲が並ぶのを防ぐ。
|
|
22606
24615
|
recent: recentComposeFingerprints
|
|
@@ -22634,45 +24643,39 @@ var mountDAW = (target, options = {}) => {
|
|
|
22634
24643
|
}
|
|
22635
24644
|
track.core.endBatch();
|
|
22636
24645
|
};
|
|
24646
|
+
const shouldAutoInstrument = !currentInstrument || currentInstrument === "auto" || currentInstrument === autoComposeInstrument;
|
|
24647
|
+
if (shouldAutoInstrument && song.instrument) {
|
|
24648
|
+
currentInstrument = song.instrument;
|
|
24649
|
+
autoComposeInstrument = song.instrument;
|
|
24650
|
+
options.onInstrumentChange?.(song.instrument);
|
|
24651
|
+
}
|
|
22637
24652
|
if (isAdvanced) {
|
|
22638
|
-
|
|
24653
|
+
const layers = buildAdvancedLayers(song, {
|
|
24654
|
+
edo: renderConfig.edo,
|
|
24655
|
+
stepsPerBar: renderConfig.stepsPerBar,
|
|
24656
|
+
preset: INSTRUMENT_PRESETS[currentInstrument] ?? INSTRUMENT_PRESETS.piano
|
|
24657
|
+
});
|
|
24658
|
+
for (const layer of layers) {
|
|
22639
24659
|
const track = trackStates[layer.index];
|
|
22640
24660
|
if (!track) continue;
|
|
22641
|
-
|
|
22642
|
-
edo: renderConfig.edo,
|
|
22643
|
-
chordStr: song.chordProgression,
|
|
22644
|
-
patternType: "arpeggio",
|
|
22645
|
-
rootShift: song.rootShift,
|
|
22646
|
-
bpm: song.bpm,
|
|
22647
|
-
stepsPerBar: renderConfig.stepsPerBar
|
|
22648
|
-
}).map((p) => ({
|
|
22649
|
-
startStep: p.startStep,
|
|
22650
|
-
pitchUnits: p.pitchUnits,
|
|
22651
|
-
durationSteps: p.durationSteps,
|
|
22652
|
-
velocity: Math.max(30, p.velocity - 14)
|
|
22653
|
-
})) : buildChordPlacements({
|
|
22654
|
-
edo: renderConfig.edo,
|
|
22655
|
-
chordStr: song.chordProgression,
|
|
22656
|
-
patternType: layer.part,
|
|
22657
|
-
rootShift: song.rootShift,
|
|
22658
|
-
bpm: song.bpm,
|
|
22659
|
-
stepsPerBar: renderConfig.stepsPerBar
|
|
22660
|
-
}).map((p) => ({
|
|
22661
|
-
startStep: p.startStep,
|
|
22662
|
-
pitchUnits: p.pitchUnits,
|
|
22663
|
-
durationSteps: p.durationSteps,
|
|
22664
|
-
velocity: p.velocity
|
|
22665
|
-
}));
|
|
22666
|
-
writeTrackAt(layer.index, notes);
|
|
24661
|
+
writeTrackAt(layer.index, layer.notes);
|
|
22667
24662
|
track.trackOctave = layer.octave;
|
|
22668
24663
|
track.volume = layer.volume;
|
|
22669
24664
|
track.core.setVolume(layer.volume);
|
|
24665
|
+
track.composeSlot = layer.notes.length > 0 ? layer.slot ?? null : null;
|
|
24666
|
+
if (layer.notes.length === 0 && track.trackInstrument) {
|
|
24667
|
+
track.trackInstrument = "";
|
|
24668
|
+
options.onTrackInstrumentChange?.(layer.index, "");
|
|
24669
|
+
}
|
|
22670
24670
|
}
|
|
22671
24671
|
for (let i2 = 0; i2 < trackStates.length; i2++) {
|
|
22672
|
-
if (
|
|
24672
|
+
if (layers.some((l) => l.index === i2)) continue;
|
|
22673
24673
|
writeTrackAt(i2, []);
|
|
24674
|
+
const t = trackStates[i2];
|
|
24675
|
+
if (t) t.composeSlot = null;
|
|
22674
24676
|
}
|
|
22675
24677
|
} else {
|
|
24678
|
+
for (const t of trackStates) t.composeSlot = null;
|
|
22676
24679
|
writeTrack("melody", song.melody);
|
|
22677
24680
|
writeTrack("submelody", song.submelody);
|
|
22678
24681
|
writeTrack("bass", song.bass);
|
|
@@ -22689,13 +24692,8 @@ var mountDAW = (target, options = {}) => {
|
|
|
22689
24692
|
refs.drumSelect.value = song.drum;
|
|
22690
24693
|
options.onDrumChange?.(song.drum);
|
|
22691
24694
|
applyDrumPatternFont(song.drum);
|
|
22692
|
-
const shouldAutoInstrument = !currentInstrument || currentInstrument === "auto" || currentInstrument === autoComposeInstrument;
|
|
22693
|
-
if (shouldAutoInstrument && song.instrument) {
|
|
22694
|
-
currentInstrument = song.instrument;
|
|
22695
|
-
autoComposeInstrument = song.instrument;
|
|
22696
|
-
options.onInstrumentChange?.(song.instrument);
|
|
22697
|
-
}
|
|
22698
24695
|
if (withVocal) {
|
|
24696
|
+
autoComposeVocalTracks.clear();
|
|
22699
24697
|
const melodyTrack = isAdvanced ? trackStates[0] : trackStates.find((t) => t.config.id === "melody");
|
|
22700
24698
|
if (melodyTrack) {
|
|
22701
24699
|
const current = melodyTrack.lyricModel.trim();
|
|
@@ -22705,12 +24703,85 @@ var mountDAW = (target, options = {}) => {
|
|
|
22705
24703
|
}
|
|
22706
24704
|
melodyTrack.lyricModel = pickComposeVocal(autoComposeVocal);
|
|
22707
24705
|
autoComposeVocal = melodyTrack.lyricModel;
|
|
24706
|
+
autoComposeVocalTracks.set(melodyTrack, melodyTrack.lyricModel);
|
|
22708
24707
|
}
|
|
22709
24708
|
melodyTrack.lyrics = composeLyrics(song.melody, {
|
|
22710
24709
|
stepsPerBar: renderConfig.stepsPerBar
|
|
22711
24710
|
});
|
|
22712
24711
|
fireLyricsChange(melodyTrack);
|
|
22713
24712
|
}
|
|
24713
|
+
if (isAdvanced && melodyTrack) {
|
|
24714
|
+
const stepsPerBar = renderConfig.stepsPerBar;
|
|
24715
|
+
const spans = song.vocal.duetSpans;
|
|
24716
|
+
const inDuet = (n) => spans.some(([a, b]) => n.startStep >= a && n.startStep < b);
|
|
24717
|
+
const sing = (track, lyrics, voice) => {
|
|
24718
|
+
if (!track) return;
|
|
24719
|
+
track.lyricModel = voice;
|
|
24720
|
+
autoComposeVocalTracks.set(track, voice);
|
|
24721
|
+
if (track.vocalOctave === 0) track.vocalOctave = -1;
|
|
24722
|
+
track.lyrics = lyrics;
|
|
24723
|
+
fireLyricsChange(track);
|
|
24724
|
+
};
|
|
24725
|
+
const partnerVoice = pickComposeVocal(melodyTrack.lyricModel);
|
|
24726
|
+
const duetting = spans.length > 0;
|
|
24727
|
+
if (duetting) {
|
|
24728
|
+
const mine = song.melody.filter((n) => !inDuet(n));
|
|
24729
|
+
const yours = song.melody.filter((n) => inDuet(n));
|
|
24730
|
+
writeTrackAt(0, mine);
|
|
24731
|
+
writeTrackAt(11, yours);
|
|
24732
|
+
const full = melodyTrack.lyrics;
|
|
24733
|
+
sing(
|
|
24734
|
+
melodyTrack,
|
|
24735
|
+
alignLyrics(song.melody, full, mine, { stepsPerBar }),
|
|
24736
|
+
melodyTrack.lyricModel
|
|
24737
|
+
);
|
|
24738
|
+
sing(
|
|
24739
|
+
trackStates[11],
|
|
24740
|
+
alignLyrics(song.melody, full, yours, { stepsPerBar }),
|
|
24741
|
+
partnerVoice
|
|
24742
|
+
);
|
|
24743
|
+
}
|
|
24744
|
+
const harmonyTrack = trackStates[2];
|
|
24745
|
+
if (song.harmony.length > 0 && harmonyTrack) {
|
|
24746
|
+
sing(
|
|
24747
|
+
harmonyTrack,
|
|
24748
|
+
alignLyrics(song.melody, melodyTrack.lyrics, song.harmony, {
|
|
24749
|
+
stepsPerBar
|
|
24750
|
+
}),
|
|
24751
|
+
duetting ? partnerVoice : melodyTrack.lyricModel
|
|
24752
|
+
);
|
|
24753
|
+
}
|
|
24754
|
+
if (!duetting) {
|
|
24755
|
+
if (song.harmony2.length > 0)
|
|
24756
|
+
sing(
|
|
24757
|
+
trackStates[12],
|
|
24758
|
+
alignLyrics(song.melody, melodyTrack.lyrics, song.harmony2, {
|
|
24759
|
+
stepsPerBar
|
|
24760
|
+
}),
|
|
24761
|
+
melodyTrack.lyricModel
|
|
24762
|
+
);
|
|
24763
|
+
const octaveTrack = trackStates[13];
|
|
24764
|
+
if (song.octave.length > 0 && octaveTrack) {
|
|
24765
|
+
sing(
|
|
24766
|
+
octaveTrack,
|
|
24767
|
+
alignLyrics(song.melody, melodyTrack.lyrics, song.octave, {
|
|
24768
|
+
stepsPerBar
|
|
24769
|
+
}),
|
|
24770
|
+
melodyTrack.lyricModel
|
|
24771
|
+
);
|
|
24772
|
+
octaveTrack.vocalOctave = -2;
|
|
24773
|
+
}
|
|
24774
|
+
}
|
|
24775
|
+
}
|
|
24776
|
+
} else {
|
|
24777
|
+
for (const [track, voice] of autoComposeVocalTracks) {
|
|
24778
|
+
if (track.lyricModel === voice) {
|
|
24779
|
+
track.lyrics = "";
|
|
24780
|
+
track.lyricModel = "";
|
|
24781
|
+
fireLyricsChange(track);
|
|
24782
|
+
}
|
|
24783
|
+
}
|
|
24784
|
+
autoComposeVocalTracks.clear();
|
|
22714
24785
|
}
|
|
22715
24786
|
applyAutoMastering();
|
|
22716
24787
|
if (refs.composeKeyHint) {
|
|
@@ -23857,6 +25928,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
23857
25928
|
if (!t) return;
|
|
23858
25929
|
const name = normalizeInstrumentName(instrumentName);
|
|
23859
25930
|
t.trackInstrument = name;
|
|
25931
|
+
t.composeSlot = null;
|
|
23860
25932
|
if (t.config.id === activeTrackId) updateTrackPanel();
|
|
23861
25933
|
},
|
|
23862
25934
|
noteToCanvas: (step, pitch) => {
|
|
@@ -26126,10 +28198,13 @@ var createDtmStudio = async (options = {}) => {
|
|
|
26126
28198
|
0 && (module.exports = {
|
|
26127
28199
|
A4_HZ,
|
|
26128
28200
|
A4_UNITS,
|
|
28201
|
+
BLUES_SCALE,
|
|
26129
28202
|
BREATH_MARK,
|
|
26130
28203
|
CENTS_PER_UNIT,
|
|
26131
28204
|
COMPOSE_KEYS,
|
|
26132
28205
|
COMPOSE_MOOD_GROUPS,
|
|
28206
|
+
COMPOSE_SCALES,
|
|
28207
|
+
COMPOSE_SCALE_IDS,
|
|
26133
28208
|
CORPUS_BANDS,
|
|
26134
28209
|
CORPUS_SIZE,
|
|
26135
28210
|
DAW_CSS,
|
|
@@ -26149,7 +28224,11 @@ var createDtmStudio = async (options = {}) => {
|
|
|
26149
28224
|
FADE_IN_MARK,
|
|
26150
28225
|
FADE_OUT_MARK,
|
|
26151
28226
|
GLOBAL_STORAGE_KEYS,
|
|
28227
|
+
GM_BRIGHT_CEILING,
|
|
26152
28228
|
GM_INSTRUMENT_NAMES,
|
|
28229
|
+
GM_INSTRUMENT_RANGE,
|
|
28230
|
+
HARMONIC_MINOR_SCALE,
|
|
28231
|
+
HUNGARIAN_SCALE,
|
|
26153
28232
|
INSTRUMENT_PRESETS,
|
|
26154
28233
|
KEY_COUNT,
|
|
26155
28234
|
KOE_BASE_URL,
|
|
@@ -26159,6 +28238,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
26159
28238
|
LinkedList,
|
|
26160
28239
|
MACRO_STORAGE_KEYS,
|
|
26161
28240
|
MAJOR_KEY_IDS,
|
|
28241
|
+
MAJOR_SCALE,
|
|
26162
28242
|
MAX_VOCAL_VOLUME,
|
|
26163
28243
|
MICRO_STEP,
|
|
26164
28244
|
MINOR_KEY_IDS,
|
|
@@ -26227,10 +28307,12 @@ var createDtmStudio = async (options = {}) => {
|
|
|
26227
28307
|
featureVector,
|
|
26228
28308
|
fifthToStep,
|
|
26229
28309
|
fifthToUnits,
|
|
28310
|
+
fitInstrumentOctave,
|
|
26230
28311
|
formatMmlMeta,
|
|
26231
28312
|
freqFromPitch,
|
|
26232
28313
|
generateRandomPattern,
|
|
26233
28314
|
getComposeKeyDescription,
|
|
28315
|
+
getComposeScaleDescription,
|
|
26234
28316
|
getDrumPatternKeys,
|
|
26235
28317
|
getMidiBPM,
|
|
26236
28318
|
icon,
|
|
@@ -26260,14 +28342,19 @@ var createDtmStudio = async (options = {}) => {
|
|
|
26260
28342
|
playNote,
|
|
26261
28343
|
playPlacements,
|
|
26262
28344
|
playSingingMML,
|
|
28345
|
+
programOfInstrumentName,
|
|
26263
28346
|
readGlobalBool,
|
|
26264
28347
|
readGlobalNumber,
|
|
26265
28348
|
readGlobalSetting,
|
|
26266
28349
|
readMacroSections,
|
|
26267
28350
|
readMacroSetting,
|
|
28351
|
+
resolveCenter,
|
|
26268
28352
|
resolveComposeKey,
|
|
28353
|
+
resolveComposeScale,
|
|
26269
28354
|
resolveDrumPattern,
|
|
26270
28355
|
resolveLoopPoint,
|
|
28356
|
+
scaleDegrees,
|
|
28357
|
+
scaleSize,
|
|
26271
28358
|
semitonesToUnits,
|
|
26272
28359
|
shiftNotes,
|
|
26273
28360
|
showLoadingOverlay,
|