262 lines
12 KiB
JavaScript
262 lines
12 KiB
JavaScript
const PromptTemplateManager = (function() {
|
|
const DEFAULT_PRESETS = [
|
|
{
|
|
id: "preset_epic_orchestra_intro",
|
|
name: "Epic Orchestra Intro (8 Bars)",
|
|
keywords: ["epic orchestra", "epic orchestral", "hoành tráng", "nhạc phim epic"],
|
|
category: "Orchestral / Film Score",
|
|
default_bars: 8,
|
|
default_bpm: 130,
|
|
default_scale: "C Minor",
|
|
system_instruction_template: "You are a professional film composer. Create a powerful, dramatic 8-bar orchestral intro. Write notes continuously across all 8 bars (from beat 0.0 to 32.0) for every track. Use whole notes, half notes, or quarter notes to maintain a clean layout without overloading the sequence. The required structure to return via the `generate_multitrack_midi` tool consists of 3 tracks: 1. Strings: plays smooth legato chord changes (one chord per 1 or 2 bars continuously). 2. Brass Theme: plays a swelling simple melodic line in the C3-C5 range spanning all 8 bars. 3. Epic Percussion: hits heavily on beats 1 and 3 throughout the entire 8 bars.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-23T16:00:00Z"
|
|
},
|
|
{
|
|
id: "preset_pop_piano_chords",
|
|
name: "Pop Piano Chords (4 Bars)",
|
|
keywords: ["pop piano", "piano chords", "ballad piano", "hợp âm piano"],
|
|
category: "Pop / Ballad",
|
|
default_bars: 4,
|
|
default_bpm: 90,
|
|
default_scale: "C Major",
|
|
system_instruction_template: "You are a professional Pop Piano player. Generate a beautiful 4-bar piano chord progression (e.g. C - G - Am - F) with pleasant chord voicing and simple accompaniment. Return the MIDI notes via the `generate_multitrack_midi` function on a track named 'Pop Piano'. Write notes continuously across all 4 bars (from beat 0.0 to 16.0). Use whole/half/quarter notes continuously to ensure every bar has piano chords playing.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-23T16:00:00Z"
|
|
},
|
|
{
|
|
id: "preset_cyberpunk_synth",
|
|
name: "Cyberpunk Synthwave (8 Bars)",
|
|
keywords: ["cyberpunk synth", "synthwave", "cyberpunk", "futuristic synth"],
|
|
category: "Electronic / Synthwave",
|
|
default_bars: 8,
|
|
default_bpm: 120,
|
|
default_scale: "A Minor",
|
|
system_instruction_template: "You are a Synthwave producer. Generate a driving 8-bar cyberpunk synth theme. Return MIDI notes via `generate_multitrack_midi` containing: 1. Synth Bass: plays eighth notes on pitch A1, C2, G1 continuously across all 8 bars (from beat 0.0 to 32.0). 2. Synth Lead: plays a simple, melodic line in the high register (C4-E5) continuously across all 8 bars (from beat 0.0 to 32.0).",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-23T16:00:00Z"
|
|
},
|
|
// ── Rearrange & Variation Scenarios ──
|
|
{
|
|
id: "preset_rearrange_arpeggio",
|
|
name: "Arpeggio Variation",
|
|
keywords: ["arpeggio", "arp", "broken chord", "arpeggiate"],
|
|
category: "Rearrange / Variation",
|
|
default_bars: 8,
|
|
default_bpm: 120,
|
|
default_scale: "C Major",
|
|
system_instruction_template: "You are a professional arranger. Rearrange the source MIDI notes into an arpeggiated variation. Subdivide sustained chord notes into sequential 0.25-beat arpeggiated steps with octave/triad jumps. Create a driving, shimmering sequence while preserving the underlying chord progression.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-28T11:00:00Z"
|
|
},
|
|
{
|
|
id: "preset_rearrange_harmonies",
|
|
name: "Add 3rd/4th Harmonies",
|
|
keywords: ["harmony", "harmonize", "harmonies", "3rd", "duet", "chord voicing"],
|
|
category: "Rearrange / Variation",
|
|
default_bars: 8,
|
|
default_bpm: 120,
|
|
default_scale: "C Major",
|
|
system_instruction_template: "You are a professional arranger. Add parallel harmonizing notes to the source melody. For each source pitch P, insert notes at P+3 or P+4 (Major/Minor 3rds) at the same start_beat. Create a richer, fuller texture resembling two instruments playing in duet.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-28T11:00:00Z"
|
|
},
|
|
{
|
|
id: "preset_rearrange_syncopation",
|
|
name: "Syncopation / Off-beat",
|
|
keywords: ["syncopation", "syncopate", "syncopated", "off-beat", "off beat", "funk", "latin"],
|
|
category: "Rearrange / Variation",
|
|
default_bars: 8,
|
|
default_bpm: 120,
|
|
default_scale: "C Major",
|
|
system_instruction_template: "You are a professional arranger. Apply syncopation to the source melody. Shift start_beat alignment off strong beats (0.0, 1.0, 2.0, 3.0) onto off-beats (0.5, 1.5, 2.5, 3.5). Preserve the core melodic outline while creating a rhythmic, syncopated feel.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-28T11:00:00Z"
|
|
},
|
|
{
|
|
id: "preset_rearrange_walking_bass",
|
|
name: "Walking Bass Line",
|
|
keywords: ["walking bass", "bassline", "walking"],
|
|
category: "Rearrange / Variation",
|
|
default_bars: 8,
|
|
default_bpm: 120,
|
|
default_scale: "C Major",
|
|
system_instruction_template: "You are a professional arranger. Transform the source melody into a walking bass line. Lower pitches to bass register (36-48 range). Build continuous quarter-note steps following the chord outline. Create an improvisational walking bassline matching the original chord progression.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-28T11:00:00Z"
|
|
},
|
|
{
|
|
id: "preset_rearrange_jazz",
|
|
name: "Jazz Swing Rearrangement",
|
|
keywords: ["jazz", "swing", "jazz swing", "bebop"],
|
|
category: "Rearrange / Variation",
|
|
default_bars: 8,
|
|
default_bpm: 120,
|
|
default_scale: "C Major",
|
|
system_instruction_template: "You are a professional Jazz arranger. Rearrange the source melody into a rhythmic Jazz Swing style. Apply: off-beat syncopation, 7th/9th chord extensions, swung eighth notes (triplet feel), and rhythmic variations while preserving the core melodic outline.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-28T11:00:00Z"
|
|
},
|
|
{
|
|
id: "preset_rearrange_synthwave",
|
|
name: "Synthwave / 80s Style",
|
|
keywords: ["synthwave", "80s", "retro", "synth wave", "retrowave", "outrun"],
|
|
category: "Rearrange / Variation",
|
|
default_bars: 8,
|
|
default_bpm: 120,
|
|
default_scale: "A Minor",
|
|
system_instruction_template: "You are a Synthwave producer. Transform the source melody into an 80s Synthwave style. Apply: driving 8th-note bass arpeggios, analog synth lead with portamento, pulsating chord pads, and octave jumps in the bass.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-28T11:00:00Z"
|
|
},
|
|
{
|
|
id: "preset_rearrange_cinematic",
|
|
name: "Cinematic Orchestral",
|
|
keywords: ["cinematic", "orchestral", "epic", "film score", "symphonic", "hollywood"],
|
|
category: "Rearrange / Variation",
|
|
default_bars: 8,
|
|
default_bpm: 130,
|
|
default_scale: "C Minor",
|
|
system_instruction_template: "You are a cinematic composer. Transform the source melody into a dramatic Cinematic Orchestral arrangement. Apply: swelling dynamics, brass stabs on downbeats, string ostinato patterns, taiko percussion hits. Layer multiple octaves for epic width.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-28T11:00:00Z"
|
|
},
|
|
{
|
|
id: "preset_rearrange_simplify",
|
|
name: "Simplify / Strip Down",
|
|
keywords: ["simplify", "minimal", "strip down", "sparse", "reduce"],
|
|
category: "Rearrange / Variation",
|
|
default_bars: 8,
|
|
default_bpm: 120,
|
|
default_scale: "C Major",
|
|
system_instruction_template: "You are a professional arranger. Simplify the source melody: keep only downbeat notes (start_beat at 0.0, 1.0, 2.0, 3.0). Strip out embellishments, passing tones, and grace notes. Reduce chord voicings to root and 5th only.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-28T11:00:00Z"
|
|
},
|
|
{
|
|
id: "preset_rearrange_chromatic",
|
|
name: "Passing Tones & Chromaticism",
|
|
keywords: ["passing tone", "chromatic", "chromaticism", "smooth", "approach note"],
|
|
category: "Rearrange / Variation",
|
|
default_bars: 8,
|
|
default_bpm: 120,
|
|
default_scale: "C Major",
|
|
system_instruction_template: "You are a professional arranger. Add passing tones and chromatic approach notes to the source melody. Insert half-step and whole-step approach notes targeting chord tones on strong beats. Smooth out the melodic progression while preserving the harmonic framework.",
|
|
is_user_defined: false,
|
|
is_favorite: false,
|
|
created_at: "2026-07-28T11:00:00Z"
|
|
}
|
|
];
|
|
|
|
const STORAGE_KEY = 'daw_ai_prompt_presets';
|
|
|
|
function PromptTemplateManager() {
|
|
this.presets = [];
|
|
this.loadPresets();
|
|
}
|
|
|
|
PromptTemplateManager.prototype.loadPresets = function() {
|
|
try {
|
|
const localData = localStorage.getItem(STORAGE_KEY);
|
|
if (localData) {
|
|
const parsed = JSON.parse(localData);
|
|
const userPresets = parsed.filter(p => p.is_user_defined);
|
|
this.presets = [...DEFAULT_PRESETS, ...userPresets];
|
|
} else {
|
|
this.presets = [...DEFAULT_PRESETS];
|
|
this.savePresets();
|
|
}
|
|
} catch (_) {
|
|
this.presets = [...DEFAULT_PRESETS];
|
|
}
|
|
};
|
|
|
|
PromptTemplateManager.prototype.savePresets = function() {
|
|
const userData = this.presets.filter(p => p.is_user_defined);
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(userData));
|
|
};
|
|
|
|
PromptTemplateManager.prototype.getPresets = function() {
|
|
return this.presets;
|
|
};
|
|
|
|
PromptTemplateManager.prototype.matchPreset = function(userQuery) {
|
|
if (!userQuery) return null;
|
|
const queryLower = userQuery.toLowerCase();
|
|
let bestMatch = null;
|
|
let bestScore = 0;
|
|
|
|
for (const preset of this.presets) {
|
|
for (const kw of preset.keywords) {
|
|
const kwLower = kw.toLowerCase();
|
|
if (queryLower === kwLower) {
|
|
if (3 > bestScore) {
|
|
bestScore = 3;
|
|
bestMatch = { preset, score: 3 };
|
|
}
|
|
} else if (queryLower.includes(kwLower)) {
|
|
if (2 > bestScore) {
|
|
bestScore = 2;
|
|
bestMatch = { preset, score: 2 };
|
|
}
|
|
} else if (kwLower.includes(queryLower)) {
|
|
if (1 > bestScore) {
|
|
bestScore = 1;
|
|
bestMatch = { preset, score: 1 };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return bestMatch;
|
|
};
|
|
|
|
PromptTemplateManager.prototype.saveUserPreset = function(presetObject) {
|
|
const index = this.presets.findIndex(p => p.id === presetObject.id);
|
|
if (index >= 0) {
|
|
this.presets[index] = presetObject;
|
|
} else {
|
|
this.presets.push(presetObject);
|
|
}
|
|
this.savePresets();
|
|
};
|
|
|
|
PromptTemplateManager.prototype.deletePreset = function(id) {
|
|
this.presets = this.presets.filter(p => p.id !== id);
|
|
this.savePresets();
|
|
};
|
|
|
|
PromptTemplateManager.prototype.getContextualSuggestions = function(hasSelectedItem) {
|
|
if (hasSelectedItem) {
|
|
return this.presets.filter(p => p.category === 'Rearrange / Variation' || p.is_favorite);
|
|
} else {
|
|
return this.presets.filter(p => p.category !== 'Rearrange / Variation');
|
|
}
|
|
};
|
|
|
|
PromptTemplateManager.prototype.toggleFavorite = function(id) {
|
|
const preset = this.presets.find(p => p.id === id);
|
|
if (preset) {
|
|
preset.is_favorite = !preset.is_favorite;
|
|
if (preset.is_user_defined) {
|
|
this.savePresets();
|
|
}
|
|
}
|
|
};
|
|
|
|
return PromptTemplateManager;
|
|
})();
|
|
|
|
window.PromptTemplateManager = PromptTemplateManager;
|
|
window.DEFAULT_PRESETS = (new PromptTemplateManager()).getPresets();
|