initial public release.

This commit is contained in:
Xiaohan-Tian
2025-08-11 18:37:21 -07:00
commit de51967b49
186 changed files with 32322 additions and 0 deletions
+98
View File
@@ -0,0 +1,98 @@
export const DB_CONSTANTS = {
// Database constants
DB_NAME: 'KGStudioDB',
PROJECTS_STORE_NAME: 'projects',
CONFIG_STORE_NAME: 'config',
DB_VERSION: 2, // Incremented to trigger upgrade for existing databases to add config store
};
export const TIME_CONSTANTS = {
DEFAULT_BPM: 125,
DEFAULT_TIME_SIGNATURE: {
numerator: 4,
denominator: 4,
},
MIN_BPM: 1,
MAX_BPM: 299,
AVAILABLE_TIME_SIGNATURE_DENOMINATORS: [2, 4, 8, 16],
AVAILABLE_TIME_SIGNATURE_NUMERATORS: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
};
export const KEY_SIGNATURE_MAP = {
"C major": { sharps: 0, flats: 0, accidentals: [], relative: "A minor", type: "major", abcNotationKeySignature: "C" },
"G major": { sharps: 1, flats: 0, accidentals: ["F#"], relative: "E minor", type: "major", abcNotationKeySignature: "G" },
"D major": { sharps: 2, flats: 0, accidentals: ["F#", "C#"], relative: "B minor", type: "major", abcNotationKeySignature: "D" },
"A major": { sharps: 3, flats: 0, accidentals: ["F#", "C#", "G#"], relative: "F# minor", type: "major", abcNotationKeySignature: "A" },
"E major": { sharps: 4, flats: 0, accidentals: ["F#", "C#", "G#", "D#"], relative: "C# minor", type: "major", abcNotationKeySignature: "E" },
"B major": { sharps: 5, flats: 0, accidentals: ["F#", "C#", "G#", "D#", "A#"], relative: "G# minor", type: "major", abcNotationKeySignature: "B" },
"F# major": { sharps: 6, flats: 0, accidentals: ["F#", "C#", "G#", "D#", "A#", "E#"], relative: "D# minor", type: "major", abcNotationKeySignature: "F#" },
"C# major": { sharps: 7, flats: 0, accidentals: ["F#", "C#", "G#", "D#", "A#", "E#", "B#"], relative: "A# minor", type: "major", abcNotationKeySignature: "C#" },
"F major": { sharps: 0, flats: 1, accidentals: ["Bb"], relative: "D minor", type: "major", abcNotationKeySignature: "F" },
"Bb major": { sharps: 0, flats: 2, accidentals: ["Bb", "Eb"], relative: "G minor", type: "major", abcNotationKeySignature: "Bb" },
"Eb major": { sharps: 0, flats: 3, accidentals: ["Bb", "Eb", "Ab"], relative: "C minor", type: "major", abcNotationKeySignature: "Eb" },
"Ab major": { sharps: 0, flats: 4, accidentals: ["Bb", "Eb", "Ab", "Db"], relative: "F minor", type: "major", abcNotationKeySignature: "Ab" },
"Db major": { sharps: 0, flats: 5, accidentals: ["Bb", "Eb", "Ab", "Db", "Gb"], relative: "Bb minor", type: "major", abcNotationKeySignature: "Db" },
"Gb major": { sharps: 0, flats: 6, accidentals: ["Bb", "Eb", "Ab", "Db", "Gb", "Cb"], relative: "Eb minor", type: "major", abcNotationKeySignature: "Gb" },
"Cb major": { sharps: 0, flats: 7, accidentals: ["Bb", "Eb", "Ab", "Db", "Gb", "Cb", "Fb"], relative: "Ab minor", type: "major", abcNotationKeySignature: "Cb" },
"A minor": { sharps: 0, flats: 0, accidentals: [], relative: "C major", type: "minor", abcNotationKeySignature: "Am" },
"E minor": { sharps: 1, flats: 0, accidentals: ["F#"], relative: "G major", type: "minor", abcNotationKeySignature: "Em" },
"B minor": { sharps: 2, flats: 0, accidentals: ["F#", "C#"], relative: "D major", type: "minor", abcNotationKeySignature: "Bm" },
"F# minor": { sharps: 3, flats: 0, accidentals: ["F#", "C#", "G#"], relative: "A major", type: "minor", abcNotationKeySignature: "F#m" },
"C# minor": { sharps: 4, flats: 0, accidentals: ["F#", "C#", "G#", "D#"], relative: "E major", type: "minor", abcNotationKeySignature: "C#m" },
"G# minor": { sharps: 5, flats: 0, accidentals: ["F#", "C#", "G#", "D#", "A#"], relative: "B major", type: "minor", abcNotationKeySignature: "G#m" },
"D# minor": { sharps: 6, flats: 0, accidentals: ["F#", "C#", "G#", "D#", "A#", "E#"], relative: "F# major", type: "minor", abcNotationKeySignature: "D#m" },
"A# minor": { sharps: 7, flats: 0, accidentals: ["F#", "C#", "G#", "D#", "A#", "E#", "B#"], relative: "C# major", type: "minor", abcNotationKeySignature: "A#m" },
"D minor": { sharps: 0, flats: 1, accidentals: ["Bb"], relative: "F major", type: "minor", abcNotationKeySignature: "Dm" },
"G minor": { sharps: 0, flats: 2, accidentals: ["Bb", "Eb"], relative: "Bb major", type: "minor", abcNotationKeySignature: "Gm" },
"C minor": { sharps: 0, flats: 3, accidentals: ["Bb", "Eb", "Ab"], relative: "Eb major", type: "minor", abcNotationKeySignature: "Cm" },
"F minor": { sharps: 0, flats: 4, accidentals: ["Bb", "Eb", "Ab", "Db"], relative: "Ab major", type: "minor", abcNotationKeySignature: "Fm" },
"Bb minor": { sharps: 0, flats: 5, accidentals: ["Bb", "Eb", "Ab", "Db", "Gb"], relative: "Db major", type: "minor", abcNotationKeySignature: "Bbm" },
"Eb minor": { sharps: 0, flats: 6, accidentals: ["Bb", "Eb", "Ab", "Db", "Gb", "Cb"], relative: "Gb major", type: "minor", abcNotationKeySignature: "Ebm" },
"Ab minor": { sharps: 0, flats: 7, accidentals: ["Bb", "Eb", "Ab", "Db", "Gb", "Cb", "Fb"], relative: "Cb major", type: "minor", abcNotationKeySignature: "Abm" }
} as const;
// Deprecated: Legacy instrument enum kept for backward compatibility in persisted data
// New code should use keys of FLUIDR3_INSTRUMENT_MAP as instrument identifiers
// export const INSTRUMENTS = {
// PIANO: 'acoustic_grand_piano',
// GUITAR: 'acoustic_guitar_nylon',
// BASS: 'electric_bass_finger',
// DRUMS: 'standard',
// };
export const AUDIO_INTERFACE_CONSTANTS = {
DEFAULT_MASTER_VOLUME: 0.8,
DEFAULT_TRACK_VOLUME: 0.8,
};
export const SAMPLER_CONSTANTS = {
TONE_SAMPLERS: {
// FLUID: { // obsolete: missing some instruments
// name: 'Fluid Soundfont',
// url: 'https://gleitz.github.io/midi-js-soundfonts/FluidR3_GM/',
// instruments: 'https://gleitz.github.io/midi-js-soundfonts/FluidR3_GM/names.json',
// instrumentMap: new Map<string, string>([
// ['PIANO', 'acoustic_grand_piano'],
// ['GUITAR', 'acoustic_guitar_nylon'],
// ['BASS', 'acoustic_bass'],
// ['DRUMS', 'synth_drum'],
// ]),
// },
FLUID: {
name: 'Fluid Soundfont',
url: 'https://cdn.jsdelivr.net/npm/soundfont-for-samplers/FluidR3_GM/',
instruments: 'https://cdn.jsdelivr.net/npm/soundfont-for-samplers/FluidR3_GM/names.json',
// instrumentRangeMap: new Map<string, number[]>([
// ['acoustic_grand_piano', [21, 108]],
// ['acoustic_guitar_nylon', [21, 108]],
// ['acoustic_bass', [21, 108]],
// ['standard', [27, 87]],
// ]),
},
},
};
export const URL_CONSTANTS = {
DEFAULT_OPENAI_BASE_URL: 'https://api.openai.com/v1',
};
+347
View File
@@ -0,0 +1,347 @@
export const STANDARD_MIDI_INSTRUMENT: { [key: number]: string } = {
1: "Acoustic Grand Piano",
2: "Bright Acoustic Piano",
3: "Electric Grand Piano",
4: "Honky-tonk Piano",
5: "Electric Piano 1",
6: "Electric Piano 2",
7: "Harpsichord",
8: "Clavinet",
9: "Celesta",
10: "Glockenspiel",
11: "Music Box",
12: "Vibraphone",
13: "Marimba",
14: "Xylophone",
15: "Tubular Bells",
16: "Dulcimer",
17: "Drawbar Organ",
18: "Percussive Organ",
19: "Rock Organ",
20: "Church Organ",
21: "Reed Organ",
22: "Accordion",
23: "Harmonica",
24: "Bandoneon",
25: "Acoustic Guitar (nylon)",
26: "Acoustic Guitar (steel)",
27: "Electric Guitar (jazz)",
28: "Electric Guitar (clean)",
29: "Electric Guitar (muted)",
30: "Electric Guitar (overdrive)",
31: "Electric Guitar (distortion)",
32: "Electric Guitar (harmonics)",
33: "Acoustic Bass",
34: "Electric Bass (finger)",
35: "Electric Bass (picked)",
36: "Electric Bass (fretless)",
37: "Slap Bass 1",
38: "Slap Bass 2",
39: "Synth Bass 1",
40: "Synth Bass 2",
41: "Violin",
42: "Viola",
43: "Cello",
44: "Contrabass",
45: "Tremolo Strings",
46: "Pizzicato Strings",
47: "Orchestral Harp",
48: "Timpani",
49: "String Ensemble 1",
50: "String Ensemble 2",
51: "Synth Strings 1",
52: "Synth Strings 2",
53: "Choir Aahs",
54: "Voice Oohs",
55: "Synth Voice",
56: "Orchestra Hit",
57: "Trumpet",
58: "Trombone",
59: "Tuba",
60: "Muted Trumpet",
61: "French Horn",
62: "Brass Section",
63: "Synth Brass 1",
64: "Synth Brass 2",
65: "Soprano Sax",
66: "Alto Sax",
67: "Tenor Sax",
68: "Baritone Sax",
69: "Oboe",
70: "English Horn",
71: "Bassoon",
72: "Clarinet",
73: "Piccolo",
74: "Flute",
75: "Recorder",
76: "Pan Flute",
77: "Blown Bottle",
78: "Shakuhachi",
79: "Whistle",
80: "Ocarina",
81: "Lead 1 (square)",
82: "Lead 2 (sawtooth)",
83: "Lead 3 (calliope)",
84: "Lead 4 (chiff)",
85: "Lead 5 (charang)",
86: "Lead 6 (voice)",
87: "Lead 7 (fifths)",
88: "Lead 8 (bass + lead)",
89: "Pad 1 (new age)",
90: "Pad 2 (warm)",
91: "Pad 3 (polysynth)",
92: "Pad 4 (choir)",
93: "Pad 5 (bowed glass)",
94: "Pad 6 (metallic)",
95: "Pad 7 (halo)",
96: "Pad 8 (sweep)",
97: "FX 1 (rain)",
98: "FX 2 (soundtrack)",
99: "FX 3 (crystal)",
100: "FX 4 (atmosphere)",
101: "FX 5 (brightness)",
102: "FX 6 (goblins)",
103: "FX 7 (echoes)",
104: "FX 8 (sci-fi)",
105: "Sitar",
106: "Banjo",
107: "Shamisen",
108: "Koto",
109: "Kalimba",
110: "Bagpipe",
111: "Fiddle",
112: "Shanai",
113: "Tinkle Bell",
114: "Agogo",
115: "Steel Drums",
116: "Woodblock",
117: "Taiko Drum",
118: "Melodic Tom",
119: "Synth Drum",
120: "Reverse Cymbal",
121: "Guitar Fret Noise",
122: "Breath Noise",
123: "Seashore",
124: "Bird Tweet",
125: "Telephone Ring",
126: "Helicopter",
127: "Applause",
128: "Gunshot"
};
export const INSTRUMENT_GROUPS = {
PIANO_AND_KEYBOARDS: "Piano and Keyboards",
GUITAR: "Guitar",
BASS: "Bass",
STRINGS: "Strings",
BRASS: "Brass",
WOODWIND: "Woodwind",
PERCUSSION_KIT: "Percussion Kit",
SYNTH: "Synthesizer",
};
export const FLUIDR3_INSTRUMENT_MAP: {
[key: string]: { displayName: string; midiInstrument: number; image: string; group: string; pitchRange: [number, number] }
} = {
// group: piano and keyboards
acoustic_grand_piano: { displayName: "Acoustic Grand Piano", midiInstrument: 1, image: "piano.png", group: "PIANO_AND_KEYBOARDS", pitchRange: [21, 108] },
electric_piano_1: { displayName: "Electric Piano 1", midiInstrument: 5, image: "electric_piano.png", group: "PIANO_AND_KEYBOARDS", pitchRange: [21, 108] },
electric_piano_2: { displayName: "Electric Piano 2", midiInstrument: 6, image: "electric_piano.png", group: "PIANO_AND_KEYBOARDS", pitchRange: [21, 108] },
drawbar_organ: { displayName: "Drawbar Organ", midiInstrument: 17, image: "drawbar_organ.png", group: "PIANO_AND_KEYBOARDS", pitchRange: [21, 108] },
clavinet: { displayName: "Clavinet", midiInstrument: 8, image: "drawbar_organ.png", group: "PIANO_AND_KEYBOARDS", pitchRange: [21, 108] },
harpsichord: { displayName: "Harpsichord", midiInstrument: 7, image: "drawbar_organ.png", group: "PIANO_AND_KEYBOARDS", pitchRange: [21, 108] },
// group: guitar
acoustic_guitar_nylon: { displayName: "Acoustic Guitar (nylon)", midiInstrument: 25, image: "guitar.png", group: "GUITAR", pitchRange: [21, 108] },
acoustic_guitar_steel: { displayName: "Acoustic Guitar (steel)", midiInstrument: 26, image: "guitar.png", group: "GUITAR", pitchRange: [21, 108] },
electric_guitar_clean: { displayName: "Electric Guitar (clean)", midiInstrument: 28, image: "electric_guitar.png", group: "GUITAR", pitchRange: [21, 108] },
overdriven_guitar: { displayName: "Electric Guitar (overdrive)", midiInstrument: 30, image: "electric_guitar.png", group: "GUITAR", pitchRange: [21, 108] },
distortion_guitar: { displayName: "Electric Guitar (distortion)", midiInstrument: 31, image: "electric_guitar.png", group: "GUITAR", pitchRange: [21, 108] },
// group: bass
electric_bass_finger: { displayName: "Electric Bass (finger)", midiInstrument: 34, image: "bass.png", group: "BASS", pitchRange: [21, 108] },
electric_bass_pick: { displayName: "Electric Bass (picked)", midiInstrument: 35, image: "bass.png", group: "BASS", pitchRange: [21, 108] },
slap_bass_1: { displayName: "Slap Bass", midiInstrument: 37, image: "bass.png", group: "BASS", pitchRange: [21, 108] },
// group: strings
violin: { displayName: "Violin", midiInstrument: 41, image: "violin.png", group: "STRINGS", pitchRange: [21, 108] },
viola: { displayName: "Viola", midiInstrument: 42, image: "viola.png", group: "STRINGS", pitchRange: [21, 108] },
cello: { displayName: "Cello", midiInstrument: 43, image: "cello.png", group: "STRINGS", pitchRange: [21, 108] },
contrabass: { displayName: "Contrabass", midiInstrument: 44, image: "contrabass.png", group: "STRINGS", pitchRange: [21, 108] },
string_ensemble_1: { displayName: "String Ensemble", midiInstrument: 49, image: "string_ensemble.png", group: "STRINGS", pitchRange: [21, 108] },
pizzicato_strings: { displayName: "Pizzicato Strings", midiInstrument: 46, image: "string_ensemble.png", group: "STRINGS", pitchRange: [21, 108] },
tremolo_strings: { displayName: "Tremolo Strings", midiInstrument: 45, image: "string_ensemble.png", group: "STRINGS", pitchRange: [21, 108] },
orchestral_harp: { displayName: "Orchestral Harp", midiInstrument: 47, image: "harp.png", group: "STRINGS", pitchRange: [21, 108] },
// group: brass
trumpet: { displayName: "Trumpet", midiInstrument: 57, image: "trumpet.png", group: "BRASS", pitchRange: [21, 108] },
trombone: { displayName: "Trombone", midiInstrument: 58, image: "trombone.png", group: "BRASS", pitchRange: [21, 108] },
french_horn: { displayName: "French Horn", midiInstrument: 61, image: "french_horn.png", group: "BRASS", pitchRange: [21, 108] },
brass_section: { displayName: "Brass Section", midiInstrument: 62, image: "brass_ensemble.png", group: "BRASS", pitchRange: [21, 108] },
// group: woodwind
alto_sax: { displayName: "Alto Sax", midiInstrument: 66, image: "sax.png", group: "WOODWIND", pitchRange: [21, 108] },
tenor_sax: { displayName: "Tenor Sax", midiInstrument: 67, image: "sax.png", group: "WOODWIND", pitchRange: [21, 108] },
flute: { displayName: "Flute", midiInstrument: 74, image: "flute.png", group: "WOODWIND", pitchRange: [21, 108] },
clarinet: { displayName: "Clarinet", midiInstrument: 72, image: "clarinet.png", group: "WOODWIND", pitchRange: [21, 108] },
// group: percussion_kit
// Note: Drum kits are selected by channel 10 in GM; program numbers are typically ignored
standard: { displayName: "Standard Drum Kit", midiInstrument: 0, image: "drums.png", group: "PERCUSSION_KIT", pitchRange: [27, 87] },
orchestra_kit: { displayName: "Orchestra Drum Kit", midiInstrument: 0, image: "orchestra_percussion_kit.png", group: "PERCUSSION_KIT", pitchRange: [27, 88] },
timpani: { displayName: "Timpani", midiInstrument: 48, image: "orchestra_percussion_kit.png", group: "PERCUSSION_KIT", pitchRange: [21, 108] },
taiko_drum: { displayName: "Taiko Drum", midiInstrument: 117, image: "orchestra_percussion_kit.png", group: "PERCUSSION_KIT", pitchRange: [21, 108] },
woodblock: { displayName: "Woodblock", midiInstrument: 116, image: "orchestra_percussion_kit.png", group: "PERCUSSION_KIT", pitchRange: [21, 108] },
// group: synth
lead_1_square: { displayName: "Lead 1 (square)", midiInstrument: 81, image: "synth.png", group: "SYNTH", pitchRange: [21, 108] },
lead_2_sawtooth: { displayName: "Lead 2 (sawtooth)", midiInstrument: 82, image: "synth.png", group: "SYNTH", pitchRange: [21, 108] },
pad_1_new_age: { displayName: "Pad 1 (new age)", midiInstrument: 89, image: "synth.png", group: "SYNTH", pitchRange: [21, 108] },
pad_2_warm: { displayName: "Pad 2 (warm)", midiInstrument: 90, image: "synth.png", group: "SYNTH", pitchRange: [21, 108] },
pad_3_polysynth: { displayName: "Pad 3 (polysynth)", midiInstrument: 91, image: "synth.png", group: "SYNTH", pitchRange: [21, 108] },
fx_4_atmosphere: { displayName: "FX 4 (atmosphere)", midiInstrument: 100, image: "synth.png", group: "SYNTH", pitchRange: [21, 108] },
};
// In case if we need to do sanity check:
// for (const key in FLUIDR3_INSTRUMENT_MAP) {
// const value = FLUIDR3_INSTRUMENT_MAP[key];
// // value.midiInstrument is 1-based, STANDARD_MIDI_INSTRUMENT is 1-based
// console.log(`${key}: ${STANDARD_MIDI_INSTRUMENT[value.midiInstrument]}`);
// }
export const STANDARD_MIDI_INSTRUMENT_MAP: {
[program: number]: {
midiInstrumentName: string;
fluidR3InstrumentName: keyof typeof FLUIDR3_INSTRUMENT_MAP;
exactMap: boolean;
};
} = {
1: { midiInstrumentName: "Acoustic Grand Piano", fluidR3InstrumentName: "acoustic_grand_piano", exactMap: true },
2: { midiInstrumentName: "Bright Acoustic Piano", fluidR3InstrumentName: "acoustic_grand_piano", exactMap: false },
3: { midiInstrumentName: "Electric Grand Piano", fluidR3InstrumentName: "electric_piano_1", exactMap: false },
4: { midiInstrumentName: "Honky-tonk Piano", fluidR3InstrumentName: "electric_piano_1", exactMap: false },
5: { midiInstrumentName: "Electric Piano 1", fluidR3InstrumentName: "electric_piano_1", exactMap: true },
6: { midiInstrumentName: "Electric Piano 2", fluidR3InstrumentName: "electric_piano_2", exactMap: true },
7: { midiInstrumentName: "Harpsichord", fluidR3InstrumentName: "harpsichord", exactMap: true },
8: { midiInstrumentName: "Clavinet", fluidR3InstrumentName: "clavinet", exactMap: true },
9: { midiInstrumentName: "Celesta", fluidR3InstrumentName: "electric_piano_1", exactMap: false },
10: { midiInstrumentName: "Glockenspiel", fluidR3InstrumentName: "electric_piano_1", exactMap: false },
11: { midiInstrumentName: "Music Box", fluidR3InstrumentName: "electric_piano_1", exactMap: false },
12: { midiInstrumentName: "Vibraphone", fluidR3InstrumentName: "electric_piano_2", exactMap: false },
13: { midiInstrumentName: "Marimba", fluidR3InstrumentName: "electric_piano_1", exactMap: false },
14: { midiInstrumentName: "Xylophone", fluidR3InstrumentName: "electric_piano_1", exactMap: false },
15: { midiInstrumentName: "Tubular Bells", fluidR3InstrumentName: "electric_piano_2", exactMap: false },
16: { midiInstrumentName: "Dulcimer", fluidR3InstrumentName: "harpsichord", exactMap: false },
17: { midiInstrumentName: "Drawbar Organ", fluidR3InstrumentName: "drawbar_organ", exactMap: true },
18: { midiInstrumentName: "Percussive Organ", fluidR3InstrumentName: "drawbar_organ", exactMap: false },
19: { midiInstrumentName: "Rock Organ", fluidR3InstrumentName: "drawbar_organ", exactMap: false },
20: { midiInstrumentName: "Church Organ", fluidR3InstrumentName: "drawbar_organ", exactMap: false },
21: { midiInstrumentName: "Reed Organ", fluidR3InstrumentName: "drawbar_organ", exactMap: false },
22: { midiInstrumentName: "Accordion", fluidR3InstrumentName: "drawbar_organ", exactMap: false },
23: { midiInstrumentName: "Harmonica", fluidR3InstrumentName: "clarinet", exactMap: false },
24: { midiInstrumentName: "Bandoneon", fluidR3InstrumentName: "drawbar_organ", exactMap: false },
25: { midiInstrumentName: "Acoustic Guitar (nylon)", fluidR3InstrumentName: "acoustic_guitar_nylon", exactMap: true },
26: { midiInstrumentName: "Acoustic Guitar (steel)", fluidR3InstrumentName: "acoustic_guitar_steel", exactMap: true },
27: { midiInstrumentName: "Electric Guitar (jazz)", fluidR3InstrumentName: "electric_guitar_clean", exactMap: false },
28: { midiInstrumentName: "Electric Guitar (clean)", fluidR3InstrumentName: "electric_guitar_clean", exactMap: true },
29: { midiInstrumentName: "Electric Guitar (muted)", fluidR3InstrumentName: "electric_guitar_clean", exactMap: false },
30: { midiInstrumentName: "Electric Guitar (overdrive)", fluidR3InstrumentName: "overdriven_guitar", exactMap: true },
31: { midiInstrumentName: "Electric Guitar (distortion)", fluidR3InstrumentName: "distortion_guitar", exactMap: true },
32: { midiInstrumentName: "Electric Guitar (harmonics)", fluidR3InstrumentName: "electric_guitar_clean", exactMap: false },
33: { midiInstrumentName: "Acoustic Bass", fluidR3InstrumentName: "electric_bass_finger", exactMap: false },
34: { midiInstrumentName: "Electric Bass (finger)", fluidR3InstrumentName: "electric_bass_finger", exactMap: true },
35: { midiInstrumentName: "Electric Bass (picked)", fluidR3InstrumentName: "electric_bass_pick", exactMap: true },
36: { midiInstrumentName: "Electric Bass (fretless)", fluidR3InstrumentName: "electric_bass_finger", exactMap: false },
37: { midiInstrumentName: "Slap Bass 1", fluidR3InstrumentName: "slap_bass_1", exactMap: true },
38: { midiInstrumentName: "Slap Bass 2", fluidR3InstrumentName: "slap_bass_1", exactMap: false },
39: { midiInstrumentName: "Synth Bass 1", fluidR3InstrumentName: "lead_2_sawtooth", exactMap: false },
40: { midiInstrumentName: "Synth Bass 2", fluidR3InstrumentName: "lead_1_square", exactMap: false },
41: { midiInstrumentName: "Violin", fluidR3InstrumentName: "violin", exactMap: true },
42: { midiInstrumentName: "Viola", fluidR3InstrumentName: "viola", exactMap: true },
43: { midiInstrumentName: "Cello", fluidR3InstrumentName: "cello", exactMap: true },
44: { midiInstrumentName: "Contrabass", fluidR3InstrumentName: "contrabass", exactMap: true },
45: { midiInstrumentName: "Tremolo Strings", fluidR3InstrumentName: "tremolo_strings", exactMap: true },
46: { midiInstrumentName: "Pizzicato Strings", fluidR3InstrumentName: "pizzicato_strings", exactMap: true },
47: { midiInstrumentName: "Orchestral Harp", fluidR3InstrumentName: "orchestral_harp", exactMap: true },
48: { midiInstrumentName: "Timpani", fluidR3InstrumentName: "timpani", exactMap: true },
49: { midiInstrumentName: "String Ensemble 1", fluidR3InstrumentName: "string_ensemble_1", exactMap: true },
50: { midiInstrumentName: "String Ensemble 2", fluidR3InstrumentName: "string_ensemble_1", exactMap: false },
51: { midiInstrumentName: "Synth Strings 1", fluidR3InstrumentName: "pad_3_polysynth", exactMap: false },
52: { midiInstrumentName: "Synth Strings 2", fluidR3InstrumentName: "pad_2_warm", exactMap: false },
53: { midiInstrumentName: "Choir Aahs", fluidR3InstrumentName: "pad_2_warm", exactMap: false },
54: { midiInstrumentName: "Voice Oohs", fluidR3InstrumentName: "pad_1_new_age", exactMap: false },
55: { midiInstrumentName: "Synth Voice", fluidR3InstrumentName: "pad_1_new_age", exactMap: false },
56: { midiInstrumentName: "Orchestra Hit", fluidR3InstrumentName: "brass_section", exactMap: false },
57: { midiInstrumentName: "Trumpet", fluidR3InstrumentName: "trumpet", exactMap: true },
58: { midiInstrumentName: "Trombone", fluidR3InstrumentName: "trombone", exactMap: true },
59: { midiInstrumentName: "Tuba", fluidR3InstrumentName: "trombone", exactMap: false },
60: { midiInstrumentName: "Muted Trumpet", fluidR3InstrumentName: "trumpet", exactMap: false },
61: { midiInstrumentName: "French Horn", fluidR3InstrumentName: "french_horn", exactMap: true },
62: { midiInstrumentName: "Brass Section", fluidR3InstrumentName: "brass_section", exactMap: true },
63: { midiInstrumentName: "Synth Brass 1", fluidR3InstrumentName: "brass_section", exactMap: false },
64: { midiInstrumentName: "Synth Brass 2", fluidR3InstrumentName: "brass_section", exactMap: false },
65: { midiInstrumentName: "Soprano Sax", fluidR3InstrumentName: "alto_sax", exactMap: false },
66: { midiInstrumentName: "Alto Sax", fluidR3InstrumentName: "alto_sax", exactMap: true },
67: { midiInstrumentName: "Tenor Sax", fluidR3InstrumentName: "tenor_sax", exactMap: true },
68: { midiInstrumentName: "Baritone Sax", fluidR3InstrumentName: "tenor_sax", exactMap: false },
69: { midiInstrumentName: "Oboe", fluidR3InstrumentName: "clarinet", exactMap: false },
70: { midiInstrumentName: "English Horn", fluidR3InstrumentName: "clarinet", exactMap: false },
71: { midiInstrumentName: "Bassoon", fluidR3InstrumentName: "clarinet", exactMap: false },
72: { midiInstrumentName: "Clarinet", fluidR3InstrumentName: "clarinet", exactMap: true },
73: { midiInstrumentName: "Piccolo", fluidR3InstrumentName: "flute", exactMap: false },
74: { midiInstrumentName: "Flute", fluidR3InstrumentName: "flute", exactMap: true },
75: { midiInstrumentName: "Recorder", fluidR3InstrumentName: "flute", exactMap: false },
76: { midiInstrumentName: "Pan Flute", fluidR3InstrumentName: "flute", exactMap: false },
77: { midiInstrumentName: "Blown Bottle", fluidR3InstrumentName: "flute", exactMap: false },
78: { midiInstrumentName: "Shakuhachi", fluidR3InstrumentName: "flute", exactMap: false },
79: { midiInstrumentName: "Whistle", fluidR3InstrumentName: "flute", exactMap: false },
80: { midiInstrumentName: "Ocarina", fluidR3InstrumentName: "flute", exactMap: false },
81: { midiInstrumentName: "Lead 1 (square)", fluidR3InstrumentName: "lead_1_square", exactMap: true },
82: { midiInstrumentName: "Lead 2 (sawtooth)", fluidR3InstrumentName: "lead_2_sawtooth", exactMap: true },
83: { midiInstrumentName: "Lead 3 (calliope)", fluidR3InstrumentName: "lead_1_square", exactMap: false },
84: { midiInstrumentName: "Lead 4 (chiff)", fluidR3InstrumentName: "lead_2_sawtooth", exactMap: false },
85: { midiInstrumentName: "Lead 5 (charang)", fluidR3InstrumentName: "lead_2_sawtooth", exactMap: false },
86: { midiInstrumentName: "Lead 6 (voice)", fluidR3InstrumentName: "pad_1_new_age", exactMap: false },
87: { midiInstrumentName: "Lead 7 (fifths)", fluidR3InstrumentName: "lead_2_sawtooth", exactMap: false },
88: { midiInstrumentName: "Lead 8 (bass + lead)", fluidR3InstrumentName: "lead_2_sawtooth", exactMap: false },
89: { midiInstrumentName: "Pad 1 (new age)", fluidR3InstrumentName: "pad_1_new_age", exactMap: true },
90: { midiInstrumentName: "Pad 2 (warm)", fluidR3InstrumentName: "pad_2_warm", exactMap: true },
91: { midiInstrumentName: "Pad 3 (polysynth)", fluidR3InstrumentName: "pad_3_polysynth", exactMap: true },
92: { midiInstrumentName: "Pad 4 (choir)", fluidR3InstrumentName: "pad_2_warm", exactMap: false },
93: { midiInstrumentName: "Pad 5 (bowed glass)", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
94: { midiInstrumentName: "Pad 6 (metallic)", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
95: { midiInstrumentName: "Pad 7 (halo)", fluidR3InstrumentName: "pad_1_new_age", exactMap: false },
96: { midiInstrumentName: "Pad 8 (sweep)", fluidR3InstrumentName: "pad_1_new_age", exactMap: false },
97: { midiInstrumentName: "FX 1 (rain)", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
98: { midiInstrumentName: "FX 2 (soundtrack)", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
99: { midiInstrumentName: "FX 3 (crystal)", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
100: { midiInstrumentName: "FX 4 (atmosphere)", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: true },
101: { midiInstrumentName: "FX 5 (brightness)", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
102: { midiInstrumentName: "FX 6 (goblins)", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
103: { midiInstrumentName: "FX 7 (echoes)", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
104: { midiInstrumentName: "FX 8 (sci-fi)", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
105: { midiInstrumentName: "Sitar", fluidR3InstrumentName: "harpsichord", exactMap: false },
106: { midiInstrumentName: "Banjo", fluidR3InstrumentName: "acoustic_guitar_steel", exactMap: false },
107: { midiInstrumentName: "Shamisen", fluidR3InstrumentName: "acoustic_guitar_nylon", exactMap: false },
108: { midiInstrumentName: "Koto", fluidR3InstrumentName: "acoustic_guitar_nylon", exactMap: false },
109: { midiInstrumentName: "Kalimba", fluidR3InstrumentName: "electric_piano_1", exactMap: false },
110: { midiInstrumentName: "Bagpipe", fluidR3InstrumentName: "clarinet", exactMap: false },
111: { midiInstrumentName: "Fiddle", fluidR3InstrumentName: "violin", exactMap: false },
112: { midiInstrumentName: "Shanai", fluidR3InstrumentName: "clarinet", exactMap: false },
113: { midiInstrumentName: "Tinkle Bell", fluidR3InstrumentName: "electric_piano_2", exactMap: false },
114: { midiInstrumentName: "Agogo", fluidR3InstrumentName: "woodblock", exactMap: false },
115: { midiInstrumentName: "Steel Drums", fluidR3InstrumentName: "electric_piano_2", exactMap: false },
116: { midiInstrumentName: "Woodblock", fluidR3InstrumentName: "woodblock", exactMap: true },
117: { midiInstrumentName: "Taiko Drum", fluidR3InstrumentName: "taiko_drum", exactMap: true },
118: { midiInstrumentName: "Melodic Tom", fluidR3InstrumentName: "taiko_drum", exactMap: false },
119: { midiInstrumentName: "Synth Drum", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
120: { midiInstrumentName: "Reverse Cymbal", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
121: { midiInstrumentName: "Guitar Fret Noise", fluidR3InstrumentName: "electric_guitar_clean", exactMap: false },
122: { midiInstrumentName: "Breath Noise", fluidR3InstrumentName: "flute", exactMap: false },
123: { midiInstrumentName: "Seashore", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
124: { midiInstrumentName: "Bird Tweet", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
125: { midiInstrumentName: "Telephone Ring", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
126: { midiInstrumentName: "Helicopter", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
127: { midiInstrumentName: "Applause", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
128: { midiInstrumentName: "Gunshot", fluidR3InstrumentName: "fx_4_atmosphere", exactMap: false },
};
+7
View File
@@ -0,0 +1,7 @@
/**
* Constants index file
* Re-exports all constants from the constants folder
*/
export * from './uiConstants';
export * from './coreConstants';
+220
View File
@@ -0,0 +1,220 @@
/**
* MIDI file format constants for Standard MIDI File conversion
*/
// MIDI file header constants
export const MIDI_HEADER = {
// Header chunk identifier
CHUNK_TYPE: new Uint8Array([0x4D, 0x54, 0x68, 0x64]), // "MThd"
// Header chunk size (always 6 bytes)
HEADER_SIZE: new Uint8Array([0x00, 0x00, 0x00, 0x06]),
// MIDI file formats
FORMAT_0: new Uint8Array([0x00, 0x00]), // Single track
FORMAT_1: new Uint8Array([0x00, 0x01]), // Multi-track, synchronous
FORMAT_2: new Uint8Array([0x00, 0x02]), // Multi-track, asynchronous
};
// Track chunk constants
export const MIDI_TRACK = {
// Track chunk identifier
CHUNK_TYPE: new Uint8Array([0x4D, 0x54, 0x72, 0x6B]), // "MTrk"
// End of track meta event
END_OF_TRACK: new Uint8Array([0x00, 0xFF, 0x2F, 0x00]),
};
// Timing constants
export const MIDI_TIMING = {
// Ticks Per Quarter Note (TPQN) - 480 provides good resolution
TPQN: 480,
TPQN_BYTES: new Uint8Array([0x01, 0xE0]), // 480 in big-endian 16-bit
};
// MIDI event types
export const MIDI_EVENTS = {
// Channel voice messages (status bytes)
NOTE_OFF: 0x80,
NOTE_ON: 0x90,
POLY_PRESSURE: 0xA0,
CONTROL_CHANGE: 0xB0,
PROGRAM_CHANGE: 0xC0,
CHANNEL_PRESSURE: 0xD0,
PITCH_BEND: 0xE0,
// System exclusive
SYSEX: 0xF0,
// Meta events
META_EVENT: 0xFF,
META_SEQUENCE_NUMBER: 0x00,
META_TEXT: 0x01,
META_COPYRIGHT: 0x02,
META_TRACK_NAME: 0x03,
META_INSTRUMENT_NAME: 0x04,
META_LYRIC: 0x05,
META_MARKER: 0x06,
META_CUE_POINT: 0x07,
META_CHANNEL_PREFIX: 0x20,
META_END_OF_TRACK: 0x2F,
META_TEMPO: 0x51,
META_SMPTE_OFFSET: 0x54,
META_TIME_SIGNATURE: 0x58,
META_KEY_SIGNATURE: 0x59,
META_SEQUENCER_SPECIFIC: 0x7F,
};
// MIDI channels (0-based)
export const MIDI_CHANNELS = {
PIANO: 0,
GUITAR: 1,
BASS: 2,
DRUMS: 9, // Channel 10 (0-based = 9) is reserved for percussion
};
// General MIDI instrument program numbers (0-based)
export const GM_INSTRUMENTS = {
PIANO: 0, // Acoustic Grand Piano
GUITAR: 24, // Acoustic Guitar (nylon)
BASS: 32, // Acoustic Bass
DRUMS: 0, // Not used for drums (uses channel 10)
};
// MIDI velocity constants
export const MIDI_VELOCITY = {
MIN: 1,
MAX: 127,
DEFAULT: 64,
};
// MIDI note constants
export const MIDI_NOTES = {
MIN: 0,
MAX: 127,
MIDDLE_C: 60, // C4
};
// Time signature constants
export const MIDI_TIME_SIGNATURE = {
// Denominator values for MIDI (power of 2)
DENOMINATOR_MAP: {
2: 1, // 2 = 2^1
4: 2, // 4 = 2^2
8: 3, // 8 = 2^3
16: 4, // 16 = 2^4
} as const,
// Default values
DEFAULT_METRONOME_PULSE: 24, // MIDI clocks per quarter note
DEFAULT_32ND_NOTES_PER_QUARTER: 8,
};
// Key signature constants (for MIDI key signature meta event)
export const MIDI_KEY_SIGNATURE = {
// Sharp keys (positive values)
SHARP_KEYS: {
'C major': 0,
'G major': 1,
'D major': 2,
'A major': 3,
'E major': 4,
'B major': 5,
'F# major': 6,
'C# major': 7,
},
// Flat keys (negative values)
FLAT_KEYS: {
'F major': -1,
'Bb major': -2,
'Eb major': -3,
'Ab major': -4,
'Db major': -5,
'Gb major': -6,
'Cb major': -7,
},
// Minor keys
MINOR_KEYS: {
'A minor': 0,
'E minor': 1,
'B minor': 2,
'F# minor': 3,
'C# minor': 4,
'G# minor': 5,
'D# minor': 6,
'A# minor': 7,
'D minor': -1,
'G minor': -2,
'C minor': -3,
'F minor': -4,
'Bb minor': -5,
'Eb minor': -6,
'Ab minor': -7,
},
} as const;
// Utility functions for MIDI data conversion
export const MIDI_UTILS = {
/**
* Convert a 32-bit integer to big-endian byte array
*/
int32ToBytes: (value: number): Uint8Array => {
return new Uint8Array([
(value >> 24) & 0xFF,
(value >> 16) & 0xFF,
(value >> 8) & 0xFF,
value & 0xFF,
]);
},
/**
* Convert a 16-bit integer to big-endian byte array
*/
int16ToBytes: (value: number): Uint8Array => {
return new Uint8Array([
(value >> 8) & 0xFF,
value & 0xFF,
]);
},
/**
* Convert a variable-length quantity (VLQ) to bytes
* Used for MIDI delta times
*/
encodeVLQ: (value: number): Uint8Array => {
const bytes: number[] = [];
// Handle zero case
if (value === 0) {
return new Uint8Array([0]);
}
// Convert to VLQ format
let temp = value & 0x7F;
while ((value >>= 7) > 0) {
temp <<= 8;
temp |= ((value & 0x7F) | 0x80);
}
// Extract bytes
while (true) {
bytes.push(temp & 0xFF);
if (temp & 0x80) {
temp >>= 8;
} else {
break;
}
}
return new Uint8Array(bytes);
},
/**
* Calculate microseconds per quarter note from BPM
*/
bpmToMicrosecondsPerQuarter: (bpm: number): number => {
return Math.round(60000000 / bpm);
},
};
+53
View File
@@ -0,0 +1,53 @@
/**
* UI Constants for KGSP
* Contains values used across the UI components
*/
// Debug constants
export const DEBUG_MODE = {
CORE: true,
TOOLBAR: true,
MAIN_CONTENT: true,
TRACK_INFO: true,
TRACK_GRID_PANEL: true,
TRACK_GRID_ITEM: true,
REGION_ITEM: true,
PIANO_ROLL: true,
MIDI_IMPORT: true,
};
// Toolbar related constants
export const TOOLBAR_CONSTANTS = {
};
// Region related constants
export const REGION_CONSTANTS = {
// Edge detection threshold for region resizing (in pixels)
EDGE_THRESHOLD: 10,
// Minimum region length in bars
MIN_REGION_LENGTH: 1.0,
};
// Piano roll related constants
export const PIANO_ROLL_CONSTANTS = {
// Default height of the piano roll in pixels
PIANO_ROLL_HEIGHT: 500,
// offsets
PIANO_KEY_CLICK_Y_OFFSET: -2,
// notes
NOTE_EDGE_OFFSET: 5,
// Minimum note length in beats (1/64 beat)
MIN_NOTE_LENGTH: 1/64,
// Dragging threshold for note selection
DRAG_THRESHOLD: 5,
};
// Playing/playback related constants
export const PLAYING_CONSTANTS = {
// Update rate for playback (10 FPS for performance evaluation)
UPDATE_INTERVAL_MS: 100, // 1000ms / 10fps = 100ms
};