@onjmin/dtm 0.1.30 → 0.1.32
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 +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +173 -48
- package/dist/index.mjs +170 -48
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1118,7 +1118,7 @@ declare const parseMmlMeta: (mml: string) => MmlMeta;
|
|
|
1118
1118
|
/** MMLからトップレベル宣言を取り除く(ノート解析が誤解釈しないように) */
|
|
1119
1119
|
declare const stripMmlMeta: (mml: string) => string;
|
|
1120
1120
|
/** メタ情報を `#inst=… #drum=… #volume=… #mode=…` のMML宣言文字列へ直列化する(空なら空文字) */
|
|
1121
|
-
declare const formatMmlMeta: (meta: MmlMeta) => string;
|
|
1121
|
+
declare const formatMmlMeta: (meta: MmlMeta, space?: string) => string;
|
|
1122
1122
|
type MMLNotePlacement = {
|
|
1123
1123
|
/** 0:melody 1:submelody 2:bass 3:chord */
|
|
1124
1124
|
trackIndex: number;
|
|
@@ -1226,6 +1226,8 @@ type MmlPlayerInstance = {
|
|
|
1226
1226
|
isPlaying: () => boolean;
|
|
1227
1227
|
destroy: () => void;
|
|
1228
1228
|
};
|
|
1229
|
+
declare const encodeMml: (mml: string) => Promise<string>;
|
|
1230
|
+
declare const decodeMml: (payload: string) => Promise<string>;
|
|
1229
1231
|
/**
|
|
1230
1232
|
* MML文字列を再生専用ビューとして target にマウントする。
|
|
1231
1233
|
*/
|
|
@@ -1612,4 +1614,6 @@ declare const DAW_CSS = "\n@font-face {\n font-family: 'k8x12';\n src: url('ht
|
|
|
1612
1614
|
*/
|
|
1613
1615
|
declare const injectStyles: (doc?: Document) => void;
|
|
1614
1616
|
|
|
1615
|
-
|
|
1617
|
+
declare const VOICE_IMAGES: Record<string, string>;
|
|
1618
|
+
|
|
1619
|
+
export { type AddNoteOptions, type ApplyChordOptions, type ChordPatternType, type ChordPlacement, type ConsumedSyllable, type CoreEventHandlers, DAW_CSS, DEFAULT_BPM, DEFAULT_GATE, DEFAULT_PAN, DEFAULT_PLAYBACK_VELOCITY, DEFAULT_STEPS_PER_BAR, DEFAULT_VELOCITY, DEFAULT_VOCAL_VOLUME, DRUM_FONT, DRUM_KEYS, DRUM_PATTERNS, type DawInstance, type DawMode, type DawOptions, type DawViewState, type DrumPattern, type DtmStudio, type DtmStudioEngines, type DtmStudioOptions, type ExportMidiOptions, INSTRUMENT_PRESETS, type InstrumentPreset, KOE_BASE_URL, KOE_VOICEBANKS, KOE_VOICEBANK_LABELS, KOE_VOICEBANK_TERMS, type KoeVoiceOptions, LinkedList, type LoopConfig, type LoopPoint, type LyricSyllable, type LyricTrack, type LyricsConductor, MAX_VOCAL_VOLUME, MMLCore, type MMLDisplayToken, type MMLNotePlacement, MML_END_MARKER, type MidiExtraction, type MidiNotePlacement, type MidiTrackAnalysis, type MmlMeta, type MmlPlayback, type MmlPlayerInstance, type MmlPlayerOptions, type ModeSwitchInstance, type ModeSwitchOptions, type MountEditorOptions, type MountPlayerOptions, type Note, PITCH_MAP, PREWARM_NOTES, type ParseMMLOptions, type ParseMidiFn, type ParsedMML, type PianoRollInstance, type PianoRollOptions, type PitchToken, type PlayDrumEvent, type PlayMmlOptions, type PlayNoteEvent, type PlaySingingMmlOptions, type PlaybackCue, type PlaybackState, type PresetSelectInstance, type PresetSelectOptions, type PreviewSoundCallback, type RenderConfig, type Sequencer, type SequencerOptions, type SequencerTrack, type SingingVoices, type SingingVoicesOptions, type StreamPlaybackOptions, type StreamVoiceNote, type StreamVoiceTrack, type Synth, TRACKS_ADVANCED, TRACKS_SIMPLE, type ToolMode, type TrackConfig, VOICE_IMAGES, VOICE_IMAGE_KEY, type VoiceModel, type VoiceRegistry, analyzeMidiTracks, applyHarmonicFilter, applyMonophonic, buildChordPlacements, buildNameToKeyMapping, collectPitchTokens, createAudioContext, createDtmStudio, createKlattVoice, createKoeVoice, createLyricsConductor, createPianoRoll, createSequencer, createSingingVoices, createSynth, createVoiceRegistry, decodeMml, decomposeToMonophonic, drawGrid, drawHeader, drawKeyboard, drawNotes, drawSelectedNotes, drawSelectionRect, encodeMml, exportMIDI, extractMidiPlacements, extractMidiPlacementsByTrack, fetchSoundFontList, formatMmlMeta, freqFromPitch, generateRandomPattern, getDrawOffset, getGridCanvas, getGridContext, getGridPosition, getHeaderCanvas, getMidiBPM, getRenderConfig, getXY, icon, init, injectStyles, isChordHeavyTrack, koeUrl, mountDAW, mountMmlPlayer, normalizeLyrics, onClick, panToStereo, parseLyrics, parseMML, parseMmlMeta, playMML, playSingingMML, setDrawOffset, shiftNotes, stripLyrics, stripMmlMeta, vocalVolumeToGain };
|
package/dist/index.d.ts
CHANGED
|
@@ -1118,7 +1118,7 @@ declare const parseMmlMeta: (mml: string) => MmlMeta;
|
|
|
1118
1118
|
/** MMLからトップレベル宣言を取り除く(ノート解析が誤解釈しないように) */
|
|
1119
1119
|
declare const stripMmlMeta: (mml: string) => string;
|
|
1120
1120
|
/** メタ情報を `#inst=… #drum=… #volume=… #mode=…` のMML宣言文字列へ直列化する(空なら空文字) */
|
|
1121
|
-
declare const formatMmlMeta: (meta: MmlMeta) => string;
|
|
1121
|
+
declare const formatMmlMeta: (meta: MmlMeta, space?: string) => string;
|
|
1122
1122
|
type MMLNotePlacement = {
|
|
1123
1123
|
/** 0:melody 1:submelody 2:bass 3:chord */
|
|
1124
1124
|
trackIndex: number;
|
|
@@ -1226,6 +1226,8 @@ type MmlPlayerInstance = {
|
|
|
1226
1226
|
isPlaying: () => boolean;
|
|
1227
1227
|
destroy: () => void;
|
|
1228
1228
|
};
|
|
1229
|
+
declare const encodeMml: (mml: string) => Promise<string>;
|
|
1230
|
+
declare const decodeMml: (payload: string) => Promise<string>;
|
|
1229
1231
|
/**
|
|
1230
1232
|
* MML文字列を再生専用ビューとして target にマウントする。
|
|
1231
1233
|
*/
|
|
@@ -1612,4 +1614,6 @@ declare const DAW_CSS = "\n@font-face {\n font-family: 'k8x12';\n src: url('ht
|
|
|
1612
1614
|
*/
|
|
1613
1615
|
declare const injectStyles: (doc?: Document) => void;
|
|
1614
1616
|
|
|
1615
|
-
|
|
1617
|
+
declare const VOICE_IMAGES: Record<string, string>;
|
|
1618
|
+
|
|
1619
|
+
export { type AddNoteOptions, type ApplyChordOptions, type ChordPatternType, type ChordPlacement, type ConsumedSyllable, type CoreEventHandlers, DAW_CSS, DEFAULT_BPM, DEFAULT_GATE, DEFAULT_PAN, DEFAULT_PLAYBACK_VELOCITY, DEFAULT_STEPS_PER_BAR, DEFAULT_VELOCITY, DEFAULT_VOCAL_VOLUME, DRUM_FONT, DRUM_KEYS, DRUM_PATTERNS, type DawInstance, type DawMode, type DawOptions, type DawViewState, type DrumPattern, type DtmStudio, type DtmStudioEngines, type DtmStudioOptions, type ExportMidiOptions, INSTRUMENT_PRESETS, type InstrumentPreset, KOE_BASE_URL, KOE_VOICEBANKS, KOE_VOICEBANK_LABELS, KOE_VOICEBANK_TERMS, type KoeVoiceOptions, LinkedList, type LoopConfig, type LoopPoint, type LyricSyllable, type LyricTrack, type LyricsConductor, MAX_VOCAL_VOLUME, MMLCore, type MMLDisplayToken, type MMLNotePlacement, MML_END_MARKER, type MidiExtraction, type MidiNotePlacement, type MidiTrackAnalysis, type MmlMeta, type MmlPlayback, type MmlPlayerInstance, type MmlPlayerOptions, type ModeSwitchInstance, type ModeSwitchOptions, type MountEditorOptions, type MountPlayerOptions, type Note, PITCH_MAP, PREWARM_NOTES, type ParseMMLOptions, type ParseMidiFn, type ParsedMML, type PianoRollInstance, type PianoRollOptions, type PitchToken, type PlayDrumEvent, type PlayMmlOptions, type PlayNoteEvent, type PlaySingingMmlOptions, type PlaybackCue, type PlaybackState, type PresetSelectInstance, type PresetSelectOptions, type PreviewSoundCallback, type RenderConfig, type Sequencer, type SequencerOptions, type SequencerTrack, type SingingVoices, type SingingVoicesOptions, type StreamPlaybackOptions, type StreamVoiceNote, type StreamVoiceTrack, type Synth, TRACKS_ADVANCED, TRACKS_SIMPLE, type ToolMode, type TrackConfig, VOICE_IMAGES, VOICE_IMAGE_KEY, type VoiceModel, type VoiceRegistry, analyzeMidiTracks, applyHarmonicFilter, applyMonophonic, buildChordPlacements, buildNameToKeyMapping, collectPitchTokens, createAudioContext, createDtmStudio, createKlattVoice, createKoeVoice, createLyricsConductor, createPianoRoll, createSequencer, createSingingVoices, createSynth, createVoiceRegistry, decodeMml, decomposeToMonophonic, drawGrid, drawHeader, drawKeyboard, drawNotes, drawSelectedNotes, drawSelectionRect, encodeMml, exportMIDI, extractMidiPlacements, extractMidiPlacementsByTrack, fetchSoundFontList, formatMmlMeta, freqFromPitch, generateRandomPattern, getDrawOffset, getGridCanvas, getGridContext, getGridPosition, getHeaderCanvas, getMidiBPM, getRenderConfig, getXY, icon, init, injectStyles, isChordHeavyTrack, koeUrl, mountDAW, mountMmlPlayer, normalizeLyrics, onClick, panToStereo, parseLyrics, parseMML, parseMmlMeta, playMML, playSingingMML, setDrawOffset, shiftNotes, stripLyrics, stripMmlMeta, vocalVolumeToGain };
|
package/dist/index.js
CHANGED
|
@@ -44,6 +44,7 @@ __export(index_exports, {
|
|
|
44
44
|
PREWARM_NOTES: () => PREWARM_NOTES,
|
|
45
45
|
TRACKS_ADVANCED: () => TRACKS_ADVANCED,
|
|
46
46
|
TRACKS_SIMPLE: () => TRACKS_SIMPLE,
|
|
47
|
+
VOICE_IMAGES: () => VOICE_IMAGES,
|
|
47
48
|
VOICE_IMAGE_KEY: () => VOICE_IMAGE_KEY,
|
|
48
49
|
analyzeMidiTracks: () => analyzeMidiTracks,
|
|
49
50
|
applyHarmonicFilter: () => applyHarmonicFilter,
|
|
@@ -61,6 +62,7 @@ __export(index_exports, {
|
|
|
61
62
|
createSingingVoices: () => createSingingVoices,
|
|
62
63
|
createSynth: () => createSynth,
|
|
63
64
|
createVoiceRegistry: () => createVoiceRegistry,
|
|
65
|
+
decodeMml: () => decodeMml,
|
|
64
66
|
decomposeToMonophonic: () => decomposeToMonophonic,
|
|
65
67
|
drawGrid: () => drawGrid,
|
|
66
68
|
drawHeader: () => drawHeader,
|
|
@@ -68,6 +70,7 @@ __export(index_exports, {
|
|
|
68
70
|
drawNotes: () => drawNotes,
|
|
69
71
|
drawSelectedNotes: () => drawSelectedNotes,
|
|
70
72
|
drawSelectionRect: () => drawSelectionRect,
|
|
73
|
+
encodeMml: () => encodeMml,
|
|
71
74
|
exportMIDI: () => exportMIDI,
|
|
72
75
|
extractMidiPlacements: () => extractMidiPlacements,
|
|
73
76
|
extractMidiPlacementsByTrack: () => extractMidiPlacementsByTrack,
|
|
@@ -2163,7 +2166,7 @@ var normalizeLyricLines = (lines) => {
|
|
|
2163
2166
|
}
|
|
2164
2167
|
return { syllables, lineBreaks };
|
|
2165
2168
|
};
|
|
2166
|
-
var LYRIC_LINE = /^@@(\d+)\s
|
|
2169
|
+
var LYRIC_LINE = /^@@(\d+)\s*(.*)$/;
|
|
2167
2170
|
var isLyricContinuation = (seg) => !/^[@#]/.test(seg);
|
|
2168
2171
|
var splitSegments = (mml) => mml.split(/[;\n\r]+/).map((s) => s.trim()).filter((s) => s.length > 0);
|
|
2169
2172
|
var clamp = (value, lo, hi) => Math.min(hi, Math.max(lo, value));
|
|
@@ -2181,38 +2184,56 @@ var parseLyrics = (mml) => {
|
|
|
2181
2184
|
const m = segments[i].match(LYRIC_LINE);
|
|
2182
2185
|
if (!m) continue;
|
|
2183
2186
|
const trackId = Number.parseInt(m[1], 10);
|
|
2184
|
-
|
|
2185
|
-
const modelToken = tokens.shift() ?? "";
|
|
2187
|
+
let rest = m[2].trim();
|
|
2186
2188
|
let volume = DEFAULT_VOCAL_VOLUME;
|
|
2187
2189
|
let gate = 100;
|
|
2188
2190
|
let pan = 64;
|
|
2189
2191
|
let octave = 0;
|
|
2190
|
-
const
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
const q2 = /^q(\d+)$/.exec(tokens[0]);
|
|
2200
|
-
const p = /^p(\d+)$/.exec(tokens[0]);
|
|
2201
|
-
const o = /^o(-?\d+)$/.exec(tokens[0]);
|
|
2202
|
-
if (v) {
|
|
2203
|
-
volume = clamp(Number.parseInt(v[1], 10), 0, MAX_VOCAL_VOLUME);
|
|
2204
|
-
} else if (q2) {
|
|
2205
|
-
gate = clamp(Number.parseInt(q2[1], 10), 0, 100);
|
|
2206
|
-
} else if (p) {
|
|
2207
|
-
pan = clamp(Number.parseInt(p[1], 10), 0, 127);
|
|
2208
|
-
} else if (o) {
|
|
2209
|
-
octave = clamp(Number.parseInt(o[1], 10), -2, 2);
|
|
2210
|
-
} else {
|
|
2211
|
-
break;
|
|
2192
|
+
const modelMatch = rest.match(
|
|
2193
|
+
/^([a-z_]+?)(?=(?:[vqpo]-?\d)|[^a-z_]|$)(?::(\d+))?/i
|
|
2194
|
+
);
|
|
2195
|
+
let model = "";
|
|
2196
|
+
const metaTokens = [];
|
|
2197
|
+
if (modelMatch) {
|
|
2198
|
+
model = modelMatch[1].toLowerCase();
|
|
2199
|
+
if (modelMatch[2]) {
|
|
2200
|
+
volume = clamp(Number.parseInt(modelMatch[2], 10), 0, MAX_VOCAL_VOLUME);
|
|
2212
2201
|
}
|
|
2213
|
-
metaTokens.push(
|
|
2202
|
+
metaTokens.push(modelMatch[0]);
|
|
2203
|
+
rest = rest.substring(modelMatch[0].length).trim();
|
|
2214
2204
|
}
|
|
2215
|
-
|
|
2205
|
+
while (true) {
|
|
2206
|
+
const vMatch = rest.match(/^v(\d+)/i);
|
|
2207
|
+
if (vMatch) {
|
|
2208
|
+
volume = clamp(Number.parseInt(vMatch[1], 10), 0, MAX_VOCAL_VOLUME);
|
|
2209
|
+
metaTokens.push(vMatch[0]);
|
|
2210
|
+
rest = rest.substring(vMatch[0].length).trim();
|
|
2211
|
+
continue;
|
|
2212
|
+
}
|
|
2213
|
+
const qMatch = rest.match(/^q(\d+)/i);
|
|
2214
|
+
if (qMatch) {
|
|
2215
|
+
gate = clamp(Number.parseInt(qMatch[1], 10), 0, 100);
|
|
2216
|
+
metaTokens.push(qMatch[0]);
|
|
2217
|
+
rest = rest.substring(qMatch[0].length).trim();
|
|
2218
|
+
continue;
|
|
2219
|
+
}
|
|
2220
|
+
const pMatch = rest.match(/^p(\d+)/i);
|
|
2221
|
+
if (pMatch) {
|
|
2222
|
+
pan = clamp(Number.parseInt(pMatch[1], 10), 0, 127);
|
|
2223
|
+
metaTokens.push(pMatch[0]);
|
|
2224
|
+
rest = rest.substring(pMatch[0].length).trim();
|
|
2225
|
+
continue;
|
|
2226
|
+
}
|
|
2227
|
+
const oMatch = rest.match(/^o(-?\d+)/i);
|
|
2228
|
+
if (oMatch) {
|
|
2229
|
+
octave = clamp(Number.parseInt(oMatch[1], 10), -2, 2);
|
|
2230
|
+
metaTokens.push(oMatch[0]);
|
|
2231
|
+
rest = rest.substring(oMatch[0].length).trim();
|
|
2232
|
+
continue;
|
|
2233
|
+
}
|
|
2234
|
+
break;
|
|
2235
|
+
}
|
|
2236
|
+
const lyricLines = [rest];
|
|
2216
2237
|
while (i + 1 < segments.length && isLyricContinuation(segments[i + 1])) {
|
|
2217
2238
|
lyricLines.push(segments[++i]);
|
|
2218
2239
|
}
|
|
@@ -4276,7 +4297,7 @@ var parseMmlMeta = (mml) => {
|
|
|
4276
4297
|
return meta;
|
|
4277
4298
|
};
|
|
4278
4299
|
var stripMmlMeta = (mml) => mml.replace(META_DIRECTIVE, "");
|
|
4279
|
-
var formatMmlMeta = (meta) => {
|
|
4300
|
+
var formatMmlMeta = (meta, space = "") => {
|
|
4280
4301
|
const parts = [];
|
|
4281
4302
|
if (meta.instrument) parts.push(`#inst=${meta.instrument}`);
|
|
4282
4303
|
if (meta.drum) parts.push(`#drum=${meta.drum}`);
|
|
@@ -4284,7 +4305,7 @@ var formatMmlMeta = (meta) => {
|
|
|
4284
4305
|
if (meta.drumVolume !== void 0)
|
|
4285
4306
|
parts.push(`#drumvolume=${meta.drumVolume}`);
|
|
4286
4307
|
if (meta.mode) parts.push(`#mode=${meta.mode}`);
|
|
4287
|
-
return parts.join(
|
|
4308
|
+
return parts.join(space);
|
|
4288
4309
|
};
|
|
4289
4310
|
var parseMML = (mml, options = {}) => {
|
|
4290
4311
|
const stepsPerBar = options.stepsPerBar ?? DEFAULT_STEPS_PER_BAR;
|
|
@@ -6236,6 +6257,9 @@ var customEncode = (str) => {
|
|
|
6236
6257
|
const bytes = [];
|
|
6237
6258
|
for (let i = 0; i < str.length; i++) {
|
|
6238
6259
|
const code = str.charCodeAt(i);
|
|
6260
|
+
if (code === 32) {
|
|
6261
|
+
continue;
|
|
6262
|
+
}
|
|
6239
6263
|
if (code <= 127) {
|
|
6240
6264
|
bytes.push(code);
|
|
6241
6265
|
} else if (code === PROLONGED_MARK) {
|
|
@@ -6267,6 +6291,82 @@ var encodeMml = async (mml) => {
|
|
|
6267
6291
|
}
|
|
6268
6292
|
return `u.${encodeURIComponent(mml)}`;
|
|
6269
6293
|
};
|
|
6294
|
+
var fromBase64Url = (s) => {
|
|
6295
|
+
let normalized = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
6296
|
+
while (normalized.length % 4 !== 0) {
|
|
6297
|
+
normalized += "=";
|
|
6298
|
+
}
|
|
6299
|
+
const bin = atob(normalized);
|
|
6300
|
+
const bytes = new Uint8Array(bin.length);
|
|
6301
|
+
for (let i = 0; i < bin.length; i++) {
|
|
6302
|
+
bytes[i] = bin.charCodeAt(i);
|
|
6303
|
+
}
|
|
6304
|
+
return bytes;
|
|
6305
|
+
};
|
|
6306
|
+
var customDecode = (bytes) => {
|
|
6307
|
+
let str = "";
|
|
6308
|
+
let i = 0;
|
|
6309
|
+
while (i < bytes.length) {
|
|
6310
|
+
const byte = bytes[i];
|
|
6311
|
+
if (byte <= 127) {
|
|
6312
|
+
str += String.fromCharCode(byte);
|
|
6313
|
+
i++;
|
|
6314
|
+
} else if (byte === VALUE_PROLONGED) {
|
|
6315
|
+
str += String.fromCharCode(PROLONGED_MARK);
|
|
6316
|
+
i++;
|
|
6317
|
+
} else if (byte >= 128 && byte <= 222) {
|
|
6318
|
+
str += String.fromCharCode(HIRAGANA_START + (byte - 128));
|
|
6319
|
+
i++;
|
|
6320
|
+
} else if (byte === SHIFT_KATAKANA) {
|
|
6321
|
+
if (i + 1 < bytes.length) {
|
|
6322
|
+
const nextByte = bytes[i + 1];
|
|
6323
|
+
if (nextByte >= 128 && nextByte <= 222) {
|
|
6324
|
+
str += String.fromCharCode(HIRAGANA_START + 96 + (nextByte - 128));
|
|
6325
|
+
}
|
|
6326
|
+
i += 2;
|
|
6327
|
+
} else {
|
|
6328
|
+
i++;
|
|
6329
|
+
}
|
|
6330
|
+
} else {
|
|
6331
|
+
i++;
|
|
6332
|
+
}
|
|
6333
|
+
}
|
|
6334
|
+
return str;
|
|
6335
|
+
};
|
|
6336
|
+
var gunzipCustom = async (bytes) => {
|
|
6337
|
+
const ds = new DecompressionStream("gzip");
|
|
6338
|
+
const writer = ds.writable.getWriter();
|
|
6339
|
+
writer.write(bytes);
|
|
6340
|
+
writer.close();
|
|
6341
|
+
const buf = await new Response(ds.readable).arrayBuffer();
|
|
6342
|
+
return customDecode(new Uint8Array(buf));
|
|
6343
|
+
};
|
|
6344
|
+
var gunzip = async (bytes) => {
|
|
6345
|
+
const ds = new DecompressionStream("gzip");
|
|
6346
|
+
const writer = ds.writable.getWriter();
|
|
6347
|
+
writer.write(bytes);
|
|
6348
|
+
writer.close();
|
|
6349
|
+
const buf = await new Response(ds.readable).arrayBuffer();
|
|
6350
|
+
return new TextDecoder().decode(buf);
|
|
6351
|
+
};
|
|
6352
|
+
var decodeMml = async (payload) => {
|
|
6353
|
+
if (!payload) return "";
|
|
6354
|
+
try {
|
|
6355
|
+
if (payload.startsWith("z.")) {
|
|
6356
|
+
return await gunzipCustom(fromBase64Url(payload.slice(2)));
|
|
6357
|
+
}
|
|
6358
|
+
if (payload.startsWith("g.")) {
|
|
6359
|
+
return await gunzip(fromBase64Url(payload.slice(2)));
|
|
6360
|
+
}
|
|
6361
|
+
if (payload.startsWith("u.")) {
|
|
6362
|
+
return decodeURIComponent(payload.slice(2));
|
|
6363
|
+
}
|
|
6364
|
+
return decodeURIComponent(payload);
|
|
6365
|
+
} catch (e) {
|
|
6366
|
+
console.error("[dtm] failed to decode MML payload", e);
|
|
6367
|
+
return "";
|
|
6368
|
+
}
|
|
6369
|
+
};
|
|
6270
6370
|
var mountMmlPlayer = (target, mml, options = {}) => {
|
|
6271
6371
|
injectStyles(target.ownerDocument ?? document);
|
|
6272
6372
|
const {
|
|
@@ -8165,7 +8265,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
8165
8265
|
redrawAll();
|
|
8166
8266
|
};
|
|
8167
8267
|
const togglePlay = () => {
|
|
8168
|
-
if (playbackState === "playing")
|
|
8268
|
+
if (playbackState === "playing") stop();
|
|
8169
8269
|
else play();
|
|
8170
8270
|
};
|
|
8171
8271
|
const updateTransport = () => {
|
|
@@ -8434,13 +8534,26 @@ var mountDAW = (target, options = {}) => {
|
|
|
8434
8534
|
const barLimitBars = Number(refs.barLimitSelect.value);
|
|
8435
8535
|
const limitSteps = barLimitBars > 0 ? barLimitBars * renderConfig.stepsPerBar : Infinity;
|
|
8436
8536
|
const clipNotes = (notes) => limitSteps === Infinity ? notes : notes.filter((n) => n.startStep < limitSteps);
|
|
8437
|
-
const
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8537
|
+
const metaLineFull = formatMmlMeta(
|
|
8538
|
+
{
|
|
8539
|
+
instrument: currentInstrument || void 0,
|
|
8540
|
+
drum: currentDrumPattern !== "none" ? currentDrumPattern : void 0,
|
|
8541
|
+
volume: masterVolume,
|
|
8542
|
+
drumVolume,
|
|
8543
|
+
mode
|
|
8544
|
+
},
|
|
8545
|
+
" "
|
|
8546
|
+
);
|
|
8547
|
+
const metaLineMini = formatMmlMeta(
|
|
8548
|
+
{
|
|
8549
|
+
instrument: currentInstrument || void 0,
|
|
8550
|
+
drum: currentDrumPattern !== "none" ? currentDrumPattern : void 0,
|
|
8551
|
+
volume: masterVolume,
|
|
8552
|
+
drumVolume,
|
|
8553
|
+
mode
|
|
8554
|
+
},
|
|
8555
|
+
""
|
|
8556
|
+
);
|
|
8444
8557
|
if (refs.decomposeChordToggle.checked) {
|
|
8445
8558
|
const ignoreHeavy = refs.ignoreChordHeavyToggle.checked;
|
|
8446
8559
|
const targetStates = ignoreHeavy ? trackStates.filter((t) => !isChordHeavyTrack(t.core.getNotes())) : trackStates;
|
|
@@ -8456,8 +8569,8 @@ var mountDAW = (target, options = {}) => {
|
|
|
8456
8569
|
const decomposedMini = monoTracks.map(
|
|
8457
8570
|
(notes, i) => `@${i}${refCore.getMMLFromNotes(notes, bpm, 100).trim().replace(/\s+/g, "")}`
|
|
8458
8571
|
);
|
|
8459
|
-
const full2 = [
|
|
8460
|
-
const minified2 = [
|
|
8572
|
+
const full2 = [metaLineFull, ...decomposedFull, MML_END_MARKER].filter((s) => s.length > 0).join(";\n");
|
|
8573
|
+
const minified2 = [metaLineMini, ...decomposedMini, MML_END_MARKER].filter((s) => s.length > 0).join(";");
|
|
8461
8574
|
return {
|
|
8462
8575
|
full: full2,
|
|
8463
8576
|
minified: minified2,
|
|
@@ -8497,9 +8610,9 @@ var mountDAW = (target, options = {}) => {
|
|
|
8497
8610
|
const head = params ? `${x.model} ${params}` : x.model;
|
|
8498
8611
|
return `@@${x.i} ${head} ${x.text}`;
|
|
8499
8612
|
});
|
|
8500
|
-
const full = [
|
|
8613
|
+
const full = [metaLineFull, ...trackLines, ...lyricLines, MML_END_MARKER].filter((s) => s.length > 0).join(";\n");
|
|
8501
8614
|
const minified = [
|
|
8502
|
-
|
|
8615
|
+
metaLineMini,
|
|
8503
8616
|
...trackLinesMini,
|
|
8504
8617
|
...lyricLines,
|
|
8505
8618
|
MML_END_MARKER
|
|
@@ -8678,6 +8791,14 @@ var mountDAW = (target, options = {}) => {
|
|
|
8678
8791
|
stop();
|
|
8679
8792
|
clearAll();
|
|
8680
8793
|
for (const t of trackStates) t.core.setLoadMode(true);
|
|
8794
|
+
for (const t of trackStates) {
|
|
8795
|
+
t.lyrics = "";
|
|
8796
|
+
t.lyricModel = "";
|
|
8797
|
+
t.vocalVolume = DEFAULT_VOCAL_VOLUME;
|
|
8798
|
+
t.vocalGate = 100;
|
|
8799
|
+
t.vocalPan = 64;
|
|
8800
|
+
t.vocalOctave = 0;
|
|
8801
|
+
}
|
|
8681
8802
|
const { placements, bpm: parsedBpm } = isAdvanced ? extractMidiPlacementsByTrack(
|
|
8682
8803
|
midi,
|
|
8683
8804
|
selectedIndices,
|
|
@@ -8705,6 +8826,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
8705
8826
|
setDrawOffset(currentOffsetX, currentOffsetY);
|
|
8706
8827
|
}
|
|
8707
8828
|
redrawAll();
|
|
8829
|
+
updateTrackPanel();
|
|
8708
8830
|
updateUndoRedo();
|
|
8709
8831
|
};
|
|
8710
8832
|
const exportMIDI2 = () => exportMIDI({
|
|
@@ -9003,13 +9125,13 @@ var mountDAW = (target, options = {}) => {
|
|
|
9003
9125
|
);
|
|
9004
9126
|
if (showMidi) wireMidi();
|
|
9005
9127
|
document.addEventListener("keydown", onKeyDown);
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
}
|
|
9128
|
+
refs.root.addEventListener("keydown", (e) => {
|
|
9129
|
+
const t = e.target;
|
|
9130
|
+
if (t.tagName !== "TEXTAREA" && t.tagName !== "INPUT") return;
|
|
9131
|
+
const ke = e;
|
|
9132
|
+
if ((ke.ctrlKey || ke.metaKey) && ["KeyZ", "KeyY", "KeyV", "KeyC", "KeyX"].includes(ke.code))
|
|
9133
|
+
e.stopPropagation();
|
|
9134
|
+
});
|
|
9013
9135
|
};
|
|
9014
9136
|
let pendingMidi = null;
|
|
9015
9137
|
let detectedTracks = [];
|
|
@@ -10285,6 +10407,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10285
10407
|
PREWARM_NOTES,
|
|
10286
10408
|
TRACKS_ADVANCED,
|
|
10287
10409
|
TRACKS_SIMPLE,
|
|
10410
|
+
VOICE_IMAGES,
|
|
10288
10411
|
VOICE_IMAGE_KEY,
|
|
10289
10412
|
analyzeMidiTracks,
|
|
10290
10413
|
applyHarmonicFilter,
|
|
@@ -10302,6 +10425,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10302
10425
|
createSingingVoices,
|
|
10303
10426
|
createSynth,
|
|
10304
10427
|
createVoiceRegistry,
|
|
10428
|
+
decodeMml,
|
|
10305
10429
|
decomposeToMonophonic,
|
|
10306
10430
|
drawGrid,
|
|
10307
10431
|
drawHeader,
|
|
@@ -10309,6 +10433,7 @@ var createDtmStudio = async (options = {}) => {
|
|
|
10309
10433
|
drawNotes,
|
|
10310
10434
|
drawSelectedNotes,
|
|
10311
10435
|
drawSelectionRect,
|
|
10436
|
+
encodeMml,
|
|
10312
10437
|
exportMIDI,
|
|
10313
10438
|
extractMidiPlacements,
|
|
10314
10439
|
extractMidiPlacementsByTrack,
|
package/dist/index.mjs
CHANGED
|
@@ -2055,7 +2055,7 @@ var normalizeLyricLines = (lines) => {
|
|
|
2055
2055
|
}
|
|
2056
2056
|
return { syllables, lineBreaks };
|
|
2057
2057
|
};
|
|
2058
|
-
var LYRIC_LINE = /^@@(\d+)\s
|
|
2058
|
+
var LYRIC_LINE = /^@@(\d+)\s*(.*)$/;
|
|
2059
2059
|
var isLyricContinuation = (seg) => !/^[@#]/.test(seg);
|
|
2060
2060
|
var splitSegments = (mml) => mml.split(/[;\n\r]+/).map((s) => s.trim()).filter((s) => s.length > 0);
|
|
2061
2061
|
var clamp = (value, lo, hi) => Math.min(hi, Math.max(lo, value));
|
|
@@ -2073,38 +2073,56 @@ var parseLyrics = (mml) => {
|
|
|
2073
2073
|
const m = segments[i].match(LYRIC_LINE);
|
|
2074
2074
|
if (!m) continue;
|
|
2075
2075
|
const trackId = Number.parseInt(m[1], 10);
|
|
2076
|
-
|
|
2077
|
-
const modelToken = tokens.shift() ?? "";
|
|
2076
|
+
let rest = m[2].trim();
|
|
2078
2077
|
let volume = DEFAULT_VOCAL_VOLUME;
|
|
2079
2078
|
let gate = 100;
|
|
2080
2079
|
let pan = 64;
|
|
2081
2080
|
let octave = 0;
|
|
2082
|
-
const
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
const q2 = /^q(\d+)$/.exec(tokens[0]);
|
|
2092
|
-
const p = /^p(\d+)$/.exec(tokens[0]);
|
|
2093
|
-
const o = /^o(-?\d+)$/.exec(tokens[0]);
|
|
2094
|
-
if (v) {
|
|
2095
|
-
volume = clamp(Number.parseInt(v[1], 10), 0, MAX_VOCAL_VOLUME);
|
|
2096
|
-
} else if (q2) {
|
|
2097
|
-
gate = clamp(Number.parseInt(q2[1], 10), 0, 100);
|
|
2098
|
-
} else if (p) {
|
|
2099
|
-
pan = clamp(Number.parseInt(p[1], 10), 0, 127);
|
|
2100
|
-
} else if (o) {
|
|
2101
|
-
octave = clamp(Number.parseInt(o[1], 10), -2, 2);
|
|
2102
|
-
} else {
|
|
2103
|
-
break;
|
|
2081
|
+
const modelMatch = rest.match(
|
|
2082
|
+
/^([a-z_]+?)(?=(?:[vqpo]-?\d)|[^a-z_]|$)(?::(\d+))?/i
|
|
2083
|
+
);
|
|
2084
|
+
let model = "";
|
|
2085
|
+
const metaTokens = [];
|
|
2086
|
+
if (modelMatch) {
|
|
2087
|
+
model = modelMatch[1].toLowerCase();
|
|
2088
|
+
if (modelMatch[2]) {
|
|
2089
|
+
volume = clamp(Number.parseInt(modelMatch[2], 10), 0, MAX_VOCAL_VOLUME);
|
|
2104
2090
|
}
|
|
2105
|
-
metaTokens.push(
|
|
2091
|
+
metaTokens.push(modelMatch[0]);
|
|
2092
|
+
rest = rest.substring(modelMatch[0].length).trim();
|
|
2106
2093
|
}
|
|
2107
|
-
|
|
2094
|
+
while (true) {
|
|
2095
|
+
const vMatch = rest.match(/^v(\d+)/i);
|
|
2096
|
+
if (vMatch) {
|
|
2097
|
+
volume = clamp(Number.parseInt(vMatch[1], 10), 0, MAX_VOCAL_VOLUME);
|
|
2098
|
+
metaTokens.push(vMatch[0]);
|
|
2099
|
+
rest = rest.substring(vMatch[0].length).trim();
|
|
2100
|
+
continue;
|
|
2101
|
+
}
|
|
2102
|
+
const qMatch = rest.match(/^q(\d+)/i);
|
|
2103
|
+
if (qMatch) {
|
|
2104
|
+
gate = clamp(Number.parseInt(qMatch[1], 10), 0, 100);
|
|
2105
|
+
metaTokens.push(qMatch[0]);
|
|
2106
|
+
rest = rest.substring(qMatch[0].length).trim();
|
|
2107
|
+
continue;
|
|
2108
|
+
}
|
|
2109
|
+
const pMatch = rest.match(/^p(\d+)/i);
|
|
2110
|
+
if (pMatch) {
|
|
2111
|
+
pan = clamp(Number.parseInt(pMatch[1], 10), 0, 127);
|
|
2112
|
+
metaTokens.push(pMatch[0]);
|
|
2113
|
+
rest = rest.substring(pMatch[0].length).trim();
|
|
2114
|
+
continue;
|
|
2115
|
+
}
|
|
2116
|
+
const oMatch = rest.match(/^o(-?\d+)/i);
|
|
2117
|
+
if (oMatch) {
|
|
2118
|
+
octave = clamp(Number.parseInt(oMatch[1], 10), -2, 2);
|
|
2119
|
+
metaTokens.push(oMatch[0]);
|
|
2120
|
+
rest = rest.substring(oMatch[0].length).trim();
|
|
2121
|
+
continue;
|
|
2122
|
+
}
|
|
2123
|
+
break;
|
|
2124
|
+
}
|
|
2125
|
+
const lyricLines = [rest];
|
|
2108
2126
|
while (i + 1 < segments.length && isLyricContinuation(segments[i + 1])) {
|
|
2109
2127
|
lyricLines.push(segments[++i]);
|
|
2110
2128
|
}
|
|
@@ -4168,7 +4186,7 @@ var parseMmlMeta = (mml) => {
|
|
|
4168
4186
|
return meta;
|
|
4169
4187
|
};
|
|
4170
4188
|
var stripMmlMeta = (mml) => mml.replace(META_DIRECTIVE, "");
|
|
4171
|
-
var formatMmlMeta = (meta) => {
|
|
4189
|
+
var formatMmlMeta = (meta, space = "") => {
|
|
4172
4190
|
const parts = [];
|
|
4173
4191
|
if (meta.instrument) parts.push(`#inst=${meta.instrument}`);
|
|
4174
4192
|
if (meta.drum) parts.push(`#drum=${meta.drum}`);
|
|
@@ -4176,7 +4194,7 @@ var formatMmlMeta = (meta) => {
|
|
|
4176
4194
|
if (meta.drumVolume !== void 0)
|
|
4177
4195
|
parts.push(`#drumvolume=${meta.drumVolume}`);
|
|
4178
4196
|
if (meta.mode) parts.push(`#mode=${meta.mode}`);
|
|
4179
|
-
return parts.join(
|
|
4197
|
+
return parts.join(space);
|
|
4180
4198
|
};
|
|
4181
4199
|
var parseMML = (mml, options = {}) => {
|
|
4182
4200
|
const stepsPerBar = options.stepsPerBar ?? DEFAULT_STEPS_PER_BAR;
|
|
@@ -6128,6 +6146,9 @@ var customEncode = (str) => {
|
|
|
6128
6146
|
const bytes = [];
|
|
6129
6147
|
for (let i = 0; i < str.length; i++) {
|
|
6130
6148
|
const code = str.charCodeAt(i);
|
|
6149
|
+
if (code === 32) {
|
|
6150
|
+
continue;
|
|
6151
|
+
}
|
|
6131
6152
|
if (code <= 127) {
|
|
6132
6153
|
bytes.push(code);
|
|
6133
6154
|
} else if (code === PROLONGED_MARK) {
|
|
@@ -6159,6 +6180,82 @@ var encodeMml = async (mml) => {
|
|
|
6159
6180
|
}
|
|
6160
6181
|
return `u.${encodeURIComponent(mml)}`;
|
|
6161
6182
|
};
|
|
6183
|
+
var fromBase64Url = (s) => {
|
|
6184
|
+
let normalized = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
6185
|
+
while (normalized.length % 4 !== 0) {
|
|
6186
|
+
normalized += "=";
|
|
6187
|
+
}
|
|
6188
|
+
const bin = atob(normalized);
|
|
6189
|
+
const bytes = new Uint8Array(bin.length);
|
|
6190
|
+
for (let i = 0; i < bin.length; i++) {
|
|
6191
|
+
bytes[i] = bin.charCodeAt(i);
|
|
6192
|
+
}
|
|
6193
|
+
return bytes;
|
|
6194
|
+
};
|
|
6195
|
+
var customDecode = (bytes) => {
|
|
6196
|
+
let str = "";
|
|
6197
|
+
let i = 0;
|
|
6198
|
+
while (i < bytes.length) {
|
|
6199
|
+
const byte = bytes[i];
|
|
6200
|
+
if (byte <= 127) {
|
|
6201
|
+
str += String.fromCharCode(byte);
|
|
6202
|
+
i++;
|
|
6203
|
+
} else if (byte === VALUE_PROLONGED) {
|
|
6204
|
+
str += String.fromCharCode(PROLONGED_MARK);
|
|
6205
|
+
i++;
|
|
6206
|
+
} else if (byte >= 128 && byte <= 222) {
|
|
6207
|
+
str += String.fromCharCode(HIRAGANA_START + (byte - 128));
|
|
6208
|
+
i++;
|
|
6209
|
+
} else if (byte === SHIFT_KATAKANA) {
|
|
6210
|
+
if (i + 1 < bytes.length) {
|
|
6211
|
+
const nextByte = bytes[i + 1];
|
|
6212
|
+
if (nextByte >= 128 && nextByte <= 222) {
|
|
6213
|
+
str += String.fromCharCode(HIRAGANA_START + 96 + (nextByte - 128));
|
|
6214
|
+
}
|
|
6215
|
+
i += 2;
|
|
6216
|
+
} else {
|
|
6217
|
+
i++;
|
|
6218
|
+
}
|
|
6219
|
+
} else {
|
|
6220
|
+
i++;
|
|
6221
|
+
}
|
|
6222
|
+
}
|
|
6223
|
+
return str;
|
|
6224
|
+
};
|
|
6225
|
+
var gunzipCustom = async (bytes) => {
|
|
6226
|
+
const ds = new DecompressionStream("gzip");
|
|
6227
|
+
const writer = ds.writable.getWriter();
|
|
6228
|
+
writer.write(bytes);
|
|
6229
|
+
writer.close();
|
|
6230
|
+
const buf = await new Response(ds.readable).arrayBuffer();
|
|
6231
|
+
return customDecode(new Uint8Array(buf));
|
|
6232
|
+
};
|
|
6233
|
+
var gunzip = async (bytes) => {
|
|
6234
|
+
const ds = new DecompressionStream("gzip");
|
|
6235
|
+
const writer = ds.writable.getWriter();
|
|
6236
|
+
writer.write(bytes);
|
|
6237
|
+
writer.close();
|
|
6238
|
+
const buf = await new Response(ds.readable).arrayBuffer();
|
|
6239
|
+
return new TextDecoder().decode(buf);
|
|
6240
|
+
};
|
|
6241
|
+
var decodeMml = async (payload) => {
|
|
6242
|
+
if (!payload) return "";
|
|
6243
|
+
try {
|
|
6244
|
+
if (payload.startsWith("z.")) {
|
|
6245
|
+
return await gunzipCustom(fromBase64Url(payload.slice(2)));
|
|
6246
|
+
}
|
|
6247
|
+
if (payload.startsWith("g.")) {
|
|
6248
|
+
return await gunzip(fromBase64Url(payload.slice(2)));
|
|
6249
|
+
}
|
|
6250
|
+
if (payload.startsWith("u.")) {
|
|
6251
|
+
return decodeURIComponent(payload.slice(2));
|
|
6252
|
+
}
|
|
6253
|
+
return decodeURIComponent(payload);
|
|
6254
|
+
} catch (e) {
|
|
6255
|
+
console.error("[dtm] failed to decode MML payload", e);
|
|
6256
|
+
return "";
|
|
6257
|
+
}
|
|
6258
|
+
};
|
|
6162
6259
|
var mountMmlPlayer = (target, mml, options = {}) => {
|
|
6163
6260
|
injectStyles(target.ownerDocument ?? document);
|
|
6164
6261
|
const {
|
|
@@ -8057,7 +8154,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
8057
8154
|
redrawAll();
|
|
8058
8155
|
};
|
|
8059
8156
|
const togglePlay = () => {
|
|
8060
|
-
if (playbackState === "playing")
|
|
8157
|
+
if (playbackState === "playing") stop();
|
|
8061
8158
|
else play();
|
|
8062
8159
|
};
|
|
8063
8160
|
const updateTransport = () => {
|
|
@@ -8326,13 +8423,26 @@ var mountDAW = (target, options = {}) => {
|
|
|
8326
8423
|
const barLimitBars = Number(refs.barLimitSelect.value);
|
|
8327
8424
|
const limitSteps = barLimitBars > 0 ? barLimitBars * renderConfig.stepsPerBar : Infinity;
|
|
8328
8425
|
const clipNotes = (notes) => limitSteps === Infinity ? notes : notes.filter((n) => n.startStep < limitSteps);
|
|
8329
|
-
const
|
|
8330
|
-
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
|
|
8335
|
-
|
|
8426
|
+
const metaLineFull = formatMmlMeta(
|
|
8427
|
+
{
|
|
8428
|
+
instrument: currentInstrument || void 0,
|
|
8429
|
+
drum: currentDrumPattern !== "none" ? currentDrumPattern : void 0,
|
|
8430
|
+
volume: masterVolume,
|
|
8431
|
+
drumVolume,
|
|
8432
|
+
mode
|
|
8433
|
+
},
|
|
8434
|
+
" "
|
|
8435
|
+
);
|
|
8436
|
+
const metaLineMini = formatMmlMeta(
|
|
8437
|
+
{
|
|
8438
|
+
instrument: currentInstrument || void 0,
|
|
8439
|
+
drum: currentDrumPattern !== "none" ? currentDrumPattern : void 0,
|
|
8440
|
+
volume: masterVolume,
|
|
8441
|
+
drumVolume,
|
|
8442
|
+
mode
|
|
8443
|
+
},
|
|
8444
|
+
""
|
|
8445
|
+
);
|
|
8336
8446
|
if (refs.decomposeChordToggle.checked) {
|
|
8337
8447
|
const ignoreHeavy = refs.ignoreChordHeavyToggle.checked;
|
|
8338
8448
|
const targetStates = ignoreHeavy ? trackStates.filter((t) => !isChordHeavyTrack(t.core.getNotes())) : trackStates;
|
|
@@ -8348,8 +8458,8 @@ var mountDAW = (target, options = {}) => {
|
|
|
8348
8458
|
const decomposedMini = monoTracks.map(
|
|
8349
8459
|
(notes, i) => `@${i}${refCore.getMMLFromNotes(notes, bpm, 100).trim().replace(/\s+/g, "")}`
|
|
8350
8460
|
);
|
|
8351
|
-
const full2 = [
|
|
8352
|
-
const minified2 = [
|
|
8461
|
+
const full2 = [metaLineFull, ...decomposedFull, MML_END_MARKER].filter((s) => s.length > 0).join(";\n");
|
|
8462
|
+
const minified2 = [metaLineMini, ...decomposedMini, MML_END_MARKER].filter((s) => s.length > 0).join(";");
|
|
8353
8463
|
return {
|
|
8354
8464
|
full: full2,
|
|
8355
8465
|
minified: minified2,
|
|
@@ -8389,9 +8499,9 @@ var mountDAW = (target, options = {}) => {
|
|
|
8389
8499
|
const head = params ? `${x.model} ${params}` : x.model;
|
|
8390
8500
|
return `@@${x.i} ${head} ${x.text}`;
|
|
8391
8501
|
});
|
|
8392
|
-
const full = [
|
|
8502
|
+
const full = [metaLineFull, ...trackLines, ...lyricLines, MML_END_MARKER].filter((s) => s.length > 0).join(";\n");
|
|
8393
8503
|
const minified = [
|
|
8394
|
-
|
|
8504
|
+
metaLineMini,
|
|
8395
8505
|
...trackLinesMini,
|
|
8396
8506
|
...lyricLines,
|
|
8397
8507
|
MML_END_MARKER
|
|
@@ -8570,6 +8680,14 @@ var mountDAW = (target, options = {}) => {
|
|
|
8570
8680
|
stop();
|
|
8571
8681
|
clearAll();
|
|
8572
8682
|
for (const t of trackStates) t.core.setLoadMode(true);
|
|
8683
|
+
for (const t of trackStates) {
|
|
8684
|
+
t.lyrics = "";
|
|
8685
|
+
t.lyricModel = "";
|
|
8686
|
+
t.vocalVolume = DEFAULT_VOCAL_VOLUME;
|
|
8687
|
+
t.vocalGate = 100;
|
|
8688
|
+
t.vocalPan = 64;
|
|
8689
|
+
t.vocalOctave = 0;
|
|
8690
|
+
}
|
|
8573
8691
|
const { placements, bpm: parsedBpm } = isAdvanced ? extractMidiPlacementsByTrack(
|
|
8574
8692
|
midi,
|
|
8575
8693
|
selectedIndices,
|
|
@@ -8597,6 +8715,7 @@ var mountDAW = (target, options = {}) => {
|
|
|
8597
8715
|
setDrawOffset(currentOffsetX, currentOffsetY);
|
|
8598
8716
|
}
|
|
8599
8717
|
redrawAll();
|
|
8718
|
+
updateTrackPanel();
|
|
8600
8719
|
updateUndoRedo();
|
|
8601
8720
|
};
|
|
8602
8721
|
const exportMIDI2 = () => exportMIDI({
|
|
@@ -8895,13 +9014,13 @@ var mountDAW = (target, options = {}) => {
|
|
|
8895
9014
|
);
|
|
8896
9015
|
if (showMidi) wireMidi();
|
|
8897
9016
|
document.addEventListener("keydown", onKeyDown);
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
8903
|
-
|
|
8904
|
-
}
|
|
9017
|
+
refs.root.addEventListener("keydown", (e) => {
|
|
9018
|
+
const t = e.target;
|
|
9019
|
+
if (t.tagName !== "TEXTAREA" && t.tagName !== "INPUT") return;
|
|
9020
|
+
const ke = e;
|
|
9021
|
+
if ((ke.ctrlKey || ke.metaKey) && ["KeyZ", "KeyY", "KeyV", "KeyC", "KeyX"].includes(ke.code))
|
|
9022
|
+
e.stopPropagation();
|
|
9023
|
+
});
|
|
8905
9024
|
};
|
|
8906
9025
|
let pendingMidi = null;
|
|
8907
9026
|
let detectedTracks = [];
|
|
@@ -10175,6 +10294,7 @@ export {
|
|
|
10175
10294
|
PREWARM_NOTES,
|
|
10176
10295
|
TRACKS_ADVANCED,
|
|
10177
10296
|
TRACKS_SIMPLE,
|
|
10297
|
+
VOICE_IMAGES,
|
|
10178
10298
|
VOICE_IMAGE_KEY,
|
|
10179
10299
|
analyzeMidiTracks,
|
|
10180
10300
|
applyHarmonicFilter,
|
|
@@ -10192,6 +10312,7 @@ export {
|
|
|
10192
10312
|
createSingingVoices,
|
|
10193
10313
|
createSynth,
|
|
10194
10314
|
createVoiceRegistry,
|
|
10315
|
+
decodeMml,
|
|
10195
10316
|
decomposeToMonophonic,
|
|
10196
10317
|
drawGrid,
|
|
10197
10318
|
drawHeader,
|
|
@@ -10199,6 +10320,7 @@ export {
|
|
|
10199
10320
|
drawNotes,
|
|
10200
10321
|
drawSelectedNotes,
|
|
10201
10322
|
drawSelectionRect,
|
|
10323
|
+
encodeMml,
|
|
10202
10324
|
exportMIDI,
|
|
10203
10325
|
extractMidiPlacements,
|
|
10204
10326
|
extractMidiPlacementsByTrack,
|
package/package.json
CHANGED