C++ API Reference
This document covers the C++ API for native applications and the C API for FFI/WASM bindings.
MidiSketch Class
Constructor
#include "midisketch.h"
midisketch::MidiSketch sketch;Header Files
midisketch.h- C++ class APImidisketch_c.h- C API for FFI/WASM bindingscore/types.h- Type definitions (includes all core types)
generateFromConfig(config)
Generate MIDI from a SongConfig object.
SongConfig config;
config.style_preset_id = 0; // Style preset ID (0-16)
config.key = Key::C; // Key (C=0 through B=11)
config.bpm = 120; // Tempo (0=use style default)
config.seed = 12345; // Random seed (0=random)
config.chord_progression_id = 0; // Chord progression ID (0-21)
config.form = StructurePattern::StandardPop; // Form/structure (0-17)
config.vocal_attitude = VocalAttitude::Clean; // 0=Clean, 1=Expressive, 2=Raw
config.drums_enabled = true; // Enable drums track
// Arpeggio settings
config.arpeggio_enabled = false;
config.arpeggio.pattern = ArpeggioPattern::Up;
config.arpeggio.speed = ArpeggioSpeed::Sixteenth;
config.arpeggio.octave_range = 2;
config.arpeggio.gate = 0.8f;
config.arpeggio.sync_chord = true;
// Vocal settings
config.vocal_low = 60; // Vocal range lower bound (MIDI note, default C4)
config.vocal_high = 79; // Vocal range upper bound (MIDI note, default G5)
config.skip_vocal = false; // Skip vocal generation (for BGM-first workflow)
// Vocal style settings
config.vocal_style = VocalStylePreset::Auto;
config.melody_template = MelodyTemplateId::Auto;
config.melodic_complexity = MelodicComplexity::Standard;
config.hook_intensity = HookIntensity::Normal;
config.vocal_groove = VocalGrooveFeel::Straight;
// Humanization
config.humanize = true;
config.humanize_timing = 0.5f; // 0.0-1.0
config.humanize_velocity = 0.5f; // 0.0-1.0
// Chord extensions
config.chord_extension.enable_sus = false;
config.chord_extension.enable_7th = false;
config.chord_extension.enable_9th = false;
// Composition style
config.composition_style = CompositionStyle::MelodyLead;
// Modulation settings
config.modulation_timing = ModulationTiming::None;
config.modulation_semitones = 2; // +1 to +4
// Call/SE settings (for idol-style music)
config.se_enabled = true;
config.call_setting = CallSetting::Auto; // 0=Auto, 1=Enabled, 2=Disabled
config.call_notes_enabled = true;
config.intro_chant = IntroChant::None;
config.mix_pattern = MixPattern::None;
config.call_density = CallDensity::Standard;
// Blueprint
config.blueprint_id = 0; // 0=Traditional, 1-9=specific, 255=random
// Guitar
config.guitar_enabled = true; // Enable guitar track
// Arrangement
config.motif_repeat_scope = 0; // 0=FullSong, 1=Section
config.arrangement_growth = 0; // 0=LayerAdd, 1=RegisterAdd
config.target_duration_seconds = 0; // 0 = use formId
// Mood
config.mood = 0; // 0-23 (used when mood_explicit=true)
config.mood_explicit = false; // Use explicit mood vs derive from style
// Feel & Expression
config.drive_feel = 50; // 0=laid-back, 50=neutral, 100=aggressive
config.enable_syncopation = false;
config.energy_curve = 0; // 0=GradualBuild, 1=FrontLoaded, 2=WavePattern, 3=SteadyState
config.mora_rhythm_mode = 2; // 0=Standard, 1=MoraTimed, 2=Auto
config.addictive_mode = false; // Enable Behavioral Loop mode
sketch.generateFromConfig(config);Parameter Dependencies
Many parameters depend on parent options being enabled. For example, arpeggio.pattern has no effect if arpeggio_enabled=false. See Option Relationships for the full dependency tree.
regenerateVocal(config)
Regenerate only the vocal track (and Aux track). Keeps the same chord progression and structure. Use after generateVocal() for vocal-first trial-and-error, or after generateFromConfig() with skip_vocal=true for BGM-first workflow.
// With seed only
sketch.regenerateVocal(12345);
// With full configuration
VocalConfig vocal_config;
vocal_config.seed = 0; // Random seed (0=new random)
vocal_config.vocal_low = 60; // Vocal range lower bound (C4)
vocal_config.vocal_high = 79; // Vocal range upper bound (G5)
vocal_config.vocal_attitude = VocalAttitude::Expressive;
vocal_config.vocal_style = VocalStylePreset::Auto;
vocal_config.melody_template = MelodyTemplateId::Auto;
vocal_config.melodic_complexity = MelodicComplexity::Standard;
vocal_config.hook_intensity = HookIntensity::Normal;
vocal_config.vocal_groove = VocalGrooveFeel::Straight;
sketch.regenerateVocal(vocal_config);getMidi()
Returns the generated MIDI data as std::vector<uint8_t>.
std::vector<uint8_t> midi_data = sketch.getMidi();
// Save to file
std::ofstream out("output.mid", std::ios::binary);
out.write(reinterpret_cast<const char*>(midi_data.data()), midi_data.size());getEventsJson()
Returns the event data as JSON string for visualization/playback.
std::string events_json = sketch.getEventsJson();
// { "sections": [...], "tracks": [...], "bpm": 120, "duration_ticks": ... }generateVocal(config)
Generate only the vocal track without accompaniment. Use for trial-and-error workflow: generate vocal, preview, regenerate if needed. Call generateAccompanimentForVocal() when satisfied with the vocal.
SongConfig config;
config.style_preset_id = 0;
config.key = Key::C;
config.bpm = 120;
config.vocal_attitude = VocalAttitude::Expressive;
sketch.generateVocal(config);generateAccompanimentForVocal(config?)
Generate accompaniment tracks for existing vocal. Must be called after generateVocal() or setVocalNotes(). Generates: Aux -> Bass -> Chord -> Guitar -> Arpeggio -> Drums -> SE (adapting to vocal).
// Simple: use default settings
sketch.generateAccompanimentForVocal();
// With configuration
AccompanimentConfig acc_config;
acc_config.seed = 12345;
acc_config.drums_enabled = true;
acc_config.arpeggio_enabled = false;
acc_config.humanize = true;
acc_config.humanize_timing = 50;
acc_config.humanize_velocity = 50;
sketch.generateAccompanimentForVocal(acc_config);regenerateAccompaniment(seedOrConfig)
Regenerate accompaniment tracks with a new seed or configuration. Keeps current vocal, regenerates all accompaniment tracks (Aux, Bass, Chord, Drums, etc.).
// With seed only
sketch.regenerateAccompaniment(12345);
// With full configuration
AccompanimentConfig acc_config;
acc_config.seed = 12345;
acc_config.drums_enabled = true;
acc_config.arpeggio_enabled = true;
sketch.regenerateAccompaniment(acc_config);generateWithVocal(config)
Generate all tracks with vocal-first priority. Generation order: Vocal -> Aux -> Bass -> Chord -> Guitar -> Arpeggio -> Drums -> SE. Accompaniment adapts to vocal melody.
SongConfig config;
config.style_preset_id = 0;
config.key = Key::C;
config.bpm = 120;
sketch.generateWithVocal(config);setVocalNotes(config, notes)
Set custom vocal notes for accompaniment generation. Initializes the song structure and chord progression from config, then replaces the vocal track with the provided notes. Call generateAccompanimentForVocal() after this.
SongConfig config;
config.style_preset_id = 0;
config.key = Key::C;
config.bpm = 120;
std::vector<NoteEvent> notes = {
NoteEvent(0, 480, 60, 100), // C4 at tick 0, duration 480
NoteEvent(480, 480, 62, 100), // D4 at tick 480
NoteEvent(960, 960, 64, 100), // E4 at tick 960, duration 960
};
sketch.setVocalNotes(config, notes);
// Generate accompaniment for the custom vocal
sketch.generateAccompanimentForVocal();
// Get the MIDI data
auto midi = sketch.getMidi();getHarmonyContext()
Get harmony context for piano roll safety API.
const IHarmonyContext& harmony = sketch.getHarmonyContext();getMelody() / setMelody(melody)
Get/set melody data for saving/restoring candidates.
// Save current melody
MelodyData melody = sketch.getMelody();
// ... try other melodies ...
// Restore saved melody
sketch.setMelody(melody);setMidiFormat(format) / getMidiFormat()
Set/get MIDI output format.
sketch.setMidiFormat(MidiFormat::SMF1); // Standard MIDI File Type 1
// or
sketch.setMidiFormat(MidiFormat::SMF2); // MIDI 2.0 Container File (default)
MidiFormat format = sketch.getMidiFormat();version()
Get library version string.
const char* version = MidiSketch::version();
// "0.1.0"Generation Workflows
MIDI Sketch supports three generation workflows, each suited to different use cases:
Choosing a Workflow
| Workflow | Use Case |
|---|---|
| BGM-First | Preview accompaniment before adding vocals |
| Vocal-First | Iterate on melody before generating backing tracks |
| Custom Vocal | Import your own melody and generate fitting accompaniment |
BGM-First Workflow
Generate backing track first, then add vocals:
MidiSketch sketch;
// Step 1: Generate BGM only
SongConfig config;
config.style_preset_id = 0;
config.skip_vocal = true;
sketch.generateFromConfig(config);
// Preview BGM...
// Step 2: Add vocals
VocalConfig vocal_config;
vocal_config.seed = 0;
vocal_config.vocal_low = 60;
vocal_config.vocal_high = 79;
vocal_config.vocal_attitude = VocalAttitude::Expressive;
sketch.regenerateVocal(vocal_config);
auto midi_data = sketch.getMidi();Vocal-First Workflow
Generate vocal first, preview, iterate, then generate accompaniment:
MidiSketch sketch;
SongConfig config;
config.style_preset_id = 0;
// Step 1: Generate vocal only
sketch.generateVocal(config);
// Preview and iterate until satisfied...
VocalConfig vocal_config;
vocal_config.seed = 12345;
vocal_config.vocal_attitude = VocalAttitude::Raw;
sketch.regenerateVocal(vocal_config);
// Step 2: Generate accompaniment for the vocal
sketch.generateAccompanimentForVocal();
auto midi_data = sketch.getMidi();Custom Vocal Import Workflow
Import your own melody and generate fitting accompaniment:
MidiSketch sketch;
SongConfig config;
config.style_preset_id = 0;
// Step 1: Set custom vocal notes
std::vector<NoteEvent> notes = {
NoteEvent(0, 480, 60, 100),
NoteEvent(480, 480, 62, 100),
NoteEvent(960, 960, 64, 100),
};
sketch.setVocalNotes(config, notes);
// Step 2: Generate accompaniment
sketch.generateAccompanimentForVocal();
auto midi_data = sketch.getMidi();Core Types
SongConfig
Main configuration structure for MIDI generation.
struct SongConfig {
uint8_t style_preset_id = 0; // Style preset ID (0-16)
uint8_t blueprint_id = 0; // Production blueprint (0-9, 255=random)
Key key = Key::C; // Musical key
uint16_t bpm = 0; // Tempo (0 = use style default)
uint32_t seed = 0; // Random seed (0 = random)
uint8_t chord_progression_id = 0; // Chord progression ID
StructurePattern form; // Song structure (formId 0-17)
bool form_explicit = false; // Use formId exactly vs allow randomization
uint16_t target_duration_seconds = 0; // Target duration (0 = use formId)
VocalAttitude vocal_attitude; // Vocal expression style (0-2)
VocalStylePreset vocal_style = VocalStylePreset::Auto; // Vocal style preset (0-13)
bool drums_enabled = true;
bool drums_enabled_explicit = false; // True if drums setting was explicitly set by user
bool guitar_enabled = true; // Enable guitar track (C++ default=true, JS default=false)
bool arpeggio_enabled = false;
bool skip_vocal = false; // Skip vocal (for BGM-first)
uint8_t vocal_low = 60; // C4
uint8_t vocal_high = 79; // G5
CompositionStyle composition_style; // 0=MelodyLead, 1=BackgroundMotif, 2=SynthDriven
uint8_t motif_repeat_scope = 0; // 0=FullSong, 1=Section
uint8_t arrangement_growth = 0; // 0=LayerAdd, 1=RegisterAdd
// Arpeggio settings
ArpeggioParams arpeggio; // pattern, speed, octave_range, gate, sync_chord
// Chord extensions
ChordExtensionParams chord_extension;
bool chord_ext_prob_explicit = false; // Explicit chord extension probabilities
// Humanization
bool humanize = false;
float humanize_timing = 0.4f; // 0.0-1.0
float humanize_velocity = 0.3f; // 0.0-1.0
// Modulation
ModulationTiming modulation_timing = ModulationTiming::None;
int8_t modulation_semitones = 2; // +1 to +4
// Call/SE settings
bool se_enabled = true;
uint8_t call_setting = 0; // 0=Auto, 1=Enabled, 2=Disabled
bool call_notes_enabled = true; // Output calls as notes
uint8_t intro_chant = 0; // 0=None, 1=Gachikoi, 2=Shouting
uint8_t mix_pattern = 0; // 0=None, 1=Standard, 2=Tiger
uint8_t call_density = 2; // 0=None, 1=Minimal, 2=Standard, 3=Intense
// Vocal style settings
MelodyTemplateId melody_template = MelodyTemplateId::Auto; // 0-7
MelodicComplexity melodic_complexity = MelodicComplexity::Standard; // 0-2
HookIntensity hook_intensity = HookIntensity::Normal; // 0-3 (4=Maximum is internal only)
VocalGrooveFeel vocal_groove = VocalGrooveFeel::Straight; // 0-5
// Mood
uint8_t mood = 0; // Mood preset (0-23, used when mood_explicit=true)
bool mood_explicit = false; // Use explicit mood vs derive from style
// Feel & Expression
uint8_t drive_feel = 50; // Drive feel (0=laid-back, 50=neutral, 100=aggressive)
bool addictive_mode = false; // Enable Behavioral Loop mode
uint8_t mora_rhythm_mode = 2; // Mora rhythm: 0=Standard, 1=MoraTimed, 2=Auto
bool enable_syncopation = false; // Enable syncopation effects
uint8_t energy_curve = 0; // Energy curve: 0=GradualBuild, 1=FrontLoaded,
// 2=WavePattern, 3=SteadyState
// Melody overrides (sentinel values = use preset default)
uint8_t melody_max_leap = 0; // Max melody leap: 0=preset, 1-12=semitones
uint8_t melody_syncopation_prob = 0xFF; // Syncopation probability: 0xFF=preset, 0-100=%
uint8_t melody_phrase_length = 0; // Phrase length: 0=preset, 1-8=bars
uint8_t melody_long_note_ratio = 0xFF; // Long note ratio: 0xFF=preset, 0-100=%
int8_t melody_chorus_register_shift = -128; // Chorus register shift: -128=preset, -12 to +12
uint8_t melody_hook_repetition = 0; // Hook repetition (0=preset, 1=off, 2=on)
uint8_t melody_use_leading_tone = 0; // Leading tone (0=preset, 1=off, 2=on)
// Motif overrides (sentinel values = use preset default)
uint8_t motif_length = 0; // Motif length: 0=auto, 1/2/4=beats
uint8_t motif_note_count = 0; // Motif note count: 0=auto, 3-8
uint8_t motif_motion = 0xFF; // Motif motion: 0xFF=preset, 0-4=MotifMotion
uint8_t motif_register_high = 0; // Motif register: 0=auto, 1=low, 2=high
uint8_t motif_rhythm_density = 0xFF; // Motif rhythm density: 0xFF=preset, 0-2=MotifRhythmDensity
// Motif chord settings
MotifChordParams motif_chord; // fixed_progression (default true), max_chord_count (default 4)
};Full SongConfig Fields
See preset_types.h for the complete structure definition.
VocalConfig
Configuration for vocal regeneration.
struct VocalConfig {
uint32_t seed = 0; // Random seed (0 = new random)
uint8_t vocal_low = 60; // Vocal range lower bound
uint8_t vocal_high = 79; // Vocal range upper bound
VocalAttitude vocal_attitude = VocalAttitude::Clean;
VocalStylePreset vocal_style = VocalStylePreset::Auto;
MelodyTemplateId melody_template = MelodyTemplateId::Auto;
MelodicComplexity melodic_complexity = MelodicComplexity::Standard;
HookIntensity hook_intensity = HookIntensity::Normal;
VocalGrooveFeel vocal_groove = VocalGrooveFeel::Straight;
CompositionStyle composition_style = CompositionStyle::MelodyLead;
};AccompanimentConfig
Configuration for accompaniment generation/regeneration.
struct AccompanimentConfig {
uint32_t seed = 0; // Random seed (0 = auto-generate)
// Drums
bool drums_enabled = true;
// Guitar
bool guitar_enabled = false; // Enable guitar track (JS default=false)
// Arpeggio
bool arpeggio_enabled = false;
uint8_t arpeggio_pattern = 0; // 0=Up, 1=Down, 2=UpDown, 3=Random,
// 4=Pinwheel, 5=PedalRoot, 6=Alberti, 7=BrokenChord
uint8_t arpeggio_speed = 1; // 0=Eighth, 1=Sixteenth, 2=Triplet
uint8_t arpeggio_octave_range = 2;
uint8_t arpeggio_gate = 80; // 0-100
bool arpeggio_sync_chord = true;
// Chord Extensions
bool chord_ext_sus = false;
bool chord_ext_7th = false;
bool chord_ext_9th = false;
bool chord_ext_tritone_sub = false; // Tritone substitution (V7 -> bII7)
uint8_t chord_ext_sus_prob = 20; // 0-100
uint8_t chord_ext_7th_prob = 30; // 0-100
uint8_t chord_ext_9th_prob = 25; // 0-100
uint8_t chord_ext_tritone_sub_prob = 50; // 0-100
// Humanization
bool humanize = false;
uint8_t humanize_timing = 50; // 0-100
uint8_t humanize_velocity = 50; // 0-100
// SE/Call
bool se_enabled = true;
bool call_enabled = false;
uint8_t call_density = 2; // 0-3
uint8_t intro_chant = 0; // 0=None, 1=Gachikoi, 2=Shouting
uint8_t mix_pattern = 0; // 0=None, 1=Standard, 2=Tiger
bool call_notes_enabled = true; // Output calls as notes
};NoteEvent
Note event structure.
struct NoteEvent {
Tick start_tick; // Start time in ticks
Tick duration; // Duration in ticks
uint8_t note; // MIDI note number (0-127)
uint8_t velocity; // MIDI velocity (0-127)
NoteEvent(Tick start, Tick dur, uint8_t n, uint8_t vel);
};Understanding Ticks
MIDI Sketch uses ticks as the time unit (480 ticks per quarter note):
- Quarter note: 480 ticks
- Eighth note: 240 ticks
- Sixteenth note: 120 ticks
- Whole note: 1920 ticks
- One bar (4/4): 1920 ticks
Example: A note at beat 2 (tick 480) lasting one beat:
NoteEvent(480, 480, 60, 100) // C4 at beat 2, duration 1 beatMelodyData
Melody data for saving/restoring candidates.
struct MelodyData {
uint32_t seed; // Random seed used
std::vector<NoteEvent> notes; // Melody notes
};Enums
Key
Musical key (0-11).
enum class Key : uint8_t {
C = 0, Cs, D, Eb, E, F, Fs, G, Ab, A, Bb, B
};VocalAttitude
Vocal expression style.
enum class VocalAttitude : uint8_t {
Clean = 0, // Clean, controlled
Expressive, // Expressive, dynamic
Raw // Raw, emotional
};CompositionStyle
Overall musical approach.
enum class CompositionStyle : uint8_t {
MelodyLead = 0, // Traditional: melody is foreground
BackgroundMotif, // Motif is foreground
SynthDriven // Synth/arpeggio as foreground
};VocalStylePreset
Vocal style presets.
enum class VocalStylePreset : uint8_t {
Auto = 0, // Auto-select based on style
Standard, // Standard pop vocal
Vocaloid, // Vocaloid-style (fast, wide leaps)
UltraVocaloid, // Ultra-fast vocaloid (32nd notes)
Idol, // Idol-style (catchy, hook-heavy)
Ballad, // Ballad (slow, long notes)
Rock, // Rock (powerful, chorus register shift)
CityPop, // City pop (jazzy, syncopated)
Anime, // Anime-style (dynamic, expressive)
BrightKira, // Bright/kira-kira (high, sparkling)
CoolSynth, // Cool synth (electronic, precise)
CuteAffected, // Cute/affected (playful)
PowerfulShout, // Powerful shout (intense)
KPop // K-Pop (tight rhythm, dance-oriented)
};MelodyTemplateId
Melody template patterns.
enum class MelodyTemplateId : uint8_t {
Auto = 0, // Auto-select based on VocalStylePreset
PlateauTalk, // High same-pitch ratio (NewJeans, Billie Eilish)
RunUpTarget, // Ascending toward target (YOASOBI, Ado)
DownResolve, // Descending resolution (B-section)
HookRepeat, // Short repeated hooks (TikTok, K-POP)
SparseAnchor, // Sparse anchor notes (Ballad)
CallResponse, // Duet-style call and response
JumpAccent // Emotional peak jumps
};MelodicComplexity
Melody complexity level.
enum class MelodicComplexity : uint8_t {
Simple = 0, // Simple melodies with minimal intervals
Standard, // Standard melodic complexity
Complex // Complex with larger intervals
};HookIntensity
Hook repetition intensity.
enum class HookIntensity : uint8_t {
Off = 0, // No hook repetition
Light, // Light hook presence
Normal, // Normal hook repetition (default)
Strong // Strong, catchy hook emphasis
};VocalGrooveFeel
Vocal groove/rhythm feel.
enum class VocalGrooveFeel : uint8_t {
Straight = 0, // Straight rhythm
OffBeat, // Off-beat emphasis
Swing, // Swing feel
Syncopated, // Syncopated rhythm
Driving16th, // Driving 16th note feel
Bouncy8th // Bouncy 8th note feel
};ModulationTiming
Key modulation timing.
enum class ModulationTiming : uint8_t {
None = 0, // No modulation
LastChorus, // Modulate at last chorus
AfterBridge, // Modulate after bridge
EachChorus, // Modulate at each chorus
Random // Random modulation timing
};TrackRole
Track role identifier.
enum class TrackRole : uint8_t {
Vocal = 0, // Main melody track
Chord, // Chord voicing track
Bass, // Bass line track
Drums, // Drum pattern track
SE, // Sound effects (calls, chants)
Motif, // Background motif track
Arpeggio, // Synth arpeggio track
Aux, // Auxiliary vocal track
Guitar // Guitar track
};ArpeggioPattern / ArpeggioSpeed
Arpeggio settings.
enum class ArpeggioPattern : uint8_t {
Up, // Ascending notes
Down, // Descending notes
UpDown, // Ascending then descending
Random, // Random order
Pinwheel, // Alternating high/low notes
PedalRoot, // Root pedal with upper voice movement
Alberti, // Classical Alberti bass pattern
BrokenChord // Broken chord voicing
};
enum class ArpeggioSpeed : uint8_t {
Eighth, // 8th notes
Sixteenth, // 16th notes (default)
Triplet // Triplet feel
};EnergyCurve
Energy curve for dynamic progression across the song.
enum class EnergyCurve : uint8_t {
GradualBuild = 0, // Gradual build to climax
FrontLoaded, // High energy from the start
WavePattern, // Alternating energy waves
SteadyState // Consistent energy throughout
};MoraRhythmMode
Mora-based rhythm mode for Japanese lyrics alignment.
enum class MoraRhythmMode : uint8_t {
Standard = 0, // Standard rhythm (ignores mora)
MoraTimed, // Mora-timed rhythm (one note per mora)
Auto // Auto-select based on style (default)
};MotifMotion
Motion style for background motif patterns.
enum class MotifMotion : uint8_t {
Stepwise = 0, // Smooth stepwise motion
GentleLeap, // Gentle leaps (3rds, 4ths)
WideLeap, // Wide leaps (5ths+)
NarrowStep, // Narrow chromatic steps
Disjunct // Disjunct/angular motion
// Ostinato(5) is internal only
};MotifRhythmDensity
Rhythm density for background motif patterns.
enum class MotifRhythmDensity : uint8_t {
Sparse = 0, // Sparse, open rhythm
Medium, // Medium density (default)
Driving // Dense, driving rhythm
};MidiFormat
MIDI file format.
enum class MidiFormat : uint8_t {
SMF1 = 1, // Standard MIDI File Type 1 (legacy)
SMF2 = 2 // MIDI 2.0 Container File (ktmidi format)
};Constants
constexpr Tick TICKS_PER_BEAT = 480; // Ticks per quarter note
constexpr uint8_t BEATS_PER_BAR = 4; // Beats per bar (4/4)
constexpr Tick TICKS_PER_BAR = 1920; // Ticks per bar
constexpr uint8_t MIDI_C4 = 60; // Middle C
constexpr MidiFormat kDefaultMidiFormat = MidiFormat::SMF2;C API (midisketch_c.h)
The C API provides FFI bindings for WASM and other language integrations.
Memory Management
Functions returning pointers (e.g., midisketch_get_midi) allocate memory that must be freed with the corresponding free function (e.g., midisketch_free_midi).
Handle Management
// Create a new MidiSketch instance
MidiSketchHandle midisketch_create(void);
// Destroy a MidiSketch instance
void midisketch_destroy(MidiSketchHandle handle);Generation Functions
// Generate from song config
MidiSketchError midisketch_generate_from_config(
MidiSketchHandle handle,
const MidiSketchSongConfig* config
);
// Generate only vocal
MidiSketchError midisketch_generate_vocal(
MidiSketchHandle handle,
const MidiSketchSongConfig* config
);
// Regenerate vocal with new config
MidiSketchError midisketch_regenerate_vocal(
MidiSketchHandle handle,
const MidiSketchVocalConfig* config
);
// Generate accompaniment
MidiSketchError midisketch_generate_accompaniment(MidiSketchHandle handle);
// Regenerate accompaniment with new seed
MidiSketchError midisketch_regenerate_accompaniment(
MidiSketchHandle handle,
uint32_t new_seed
);
// Generate all tracks with vocal-first priority
MidiSketchError midisketch_generate_with_vocal(
MidiSketchHandle handle,
const MidiSketchSongConfig* config
);
// Set custom vocal notes
MidiSketchError midisketch_set_vocal_notes(
MidiSketchHandle handle,
const MidiSketchSongConfig* config,
const MidiSketchNoteInput* notes,
size_t count
);Output Functions
// Get MIDI data (must free with midisketch_free_midi)
MidiSketchMidiData* midisketch_get_midi(MidiSketchHandle handle);
// Get vocal preview MIDI
MidiSketchMidiData* midisketch_get_vocal_preview_midi(MidiSketchHandle handle);
// Free MIDI data
void midisketch_free_midi(MidiSketchMidiData* data);
// Get event data as JSON (must free with midisketch_free_events)
MidiSketchEventData* midisketch_get_events(MidiSketchHandle handle);
// Free event data
void midisketch_free_events(MidiSketchEventData* data);Preset Information
// Get counts
uint8_t midisketch_style_preset_count(void);
uint8_t midisketch_structure_count(void);
uint8_t midisketch_chord_count(void);
// Get names
const char* midisketch_style_preset_name(uint8_t id);
const char* midisketch_style_preset_display_name(uint8_t id);
// Get compatible progressions/forms for a style (WASM-friendly)
MidiSketchChordCandidates* midisketch_get_progressions_by_style_ptr(uint8_t style_id);
MidiSketchFormCandidates* midisketch_get_forms_by_style_ptr(uint8_t style_id);
// Create default config for a style (WASM-friendly)
MidiSketchSongConfig* midisketch_create_default_config_ptr(uint8_t style_id);
// Validate config
MidiSketchConfigError midisketch_validate_config(const MidiSketchSongConfig* config);Blueprint Information
// Get number of available blueprints
uint8_t midisketch_blueprint_count(void);
// Get blueprint name by ID
const char* midisketch_blueprint_name(uint8_t id);
// Get blueprint paradigm by ID (0=Traditional, 1=RhythmSync, 2=MelodyDriven)
uint8_t midisketch_blueprint_paradigm(uint8_t id);
// Get blueprint riff policy by ID (0=Free, 1=LockedContour, 2=LockedPitch, 3=LockedAll, 4=Evolving)
uint8_t midisketch_blueprint_riff_policy(uint8_t id);
// Get blueprint weight (for auto-selection) by ID
uint8_t midisketch_blueprint_weight(uint8_t id);
// Get resolved blueprint ID after generation
uint8_t midisketch_get_resolved_blueprint_id(MidiSketchHandle handle);JSON Config API (WASM)
The JSON-based API is used by the WASM/JS bindings for configuration exchange.
// Generate from JSON config string
MidiSketchError midisketch_generate_from_json(
MidiSketchHandle handle,
const char* json,
size_t json_length
);
// Validate JSON config
MidiSketchConfigError midisketch_validate_config_json(
const char* json,
size_t json_length
);
// Create default config as JSON string
const char* midisketch_create_default_config_json(uint8_t style_id);
// Generate vocal only from JSON config
MidiSketchError midisketch_generate_vocal_from_json(
MidiSketchHandle handle,
const char* json,
size_t json_length
);
// Generate all tracks with vocal-first priority from JSON config
MidiSketchError midisketch_generate_with_vocal_from_json(
MidiSketchHandle handle,
const char* json,
size_t json_length
);
// Regenerate vocal from JSON config
MidiSketchError midisketch_regenerate_vocal_from_json(
MidiSketchHandle handle,
const char* json,
size_t json_length
);
// Generate accompaniment from JSON config
MidiSketchError midisketch_generate_accompaniment_from_json(
MidiSketchHandle handle,
const char* json,
size_t json_length
);
// Regenerate accompaniment from JSON config
MidiSketchError midisketch_regenerate_accompaniment_from_json(
MidiSketchHandle handle,
const char* json,
size_t json_length
);
// Set custom vocal notes from JSON
MidiSketchError midisketch_set_vocal_notes_from_json(
MidiSketchHandle handle,
const char* json,
size_t json_length
);Piano Roll Safety API
// Get piano roll safety for a range of ticks
MidiSketchPianoRollData* midisketch_get_piano_roll_safety(
MidiSketchHandle handle,
uint32_t start_tick,
uint32_t end_tick,
uint32_t step
);
// Get piano roll safety at a single tick
MidiSketchPianoRollInfo* midisketch_get_piano_roll_safety_at(
MidiSketchHandle handle,
uint32_t tick
);
// Get piano roll safety with previous pitch context (for leap detection)
MidiSketchPianoRollInfo* midisketch_get_piano_roll_safety_with_context(
MidiSketchHandle handle,
uint32_t tick,
uint8_t prev_pitch
);
// Free piano roll data
void midisketch_free_piano_roll_data(MidiSketchPianoRollData* data);
// Convert reason flags to human-readable string
const char* midisketch_reason_to_string(uint16_t reason);
// Get config error message string
const char* midisketch_config_error_string(uint8_t error_code);Error Codes
typedef enum {
MIDISKETCH_OK = 0,
MIDISKETCH_ERROR_INVALID_PARAM = 1,
MIDISKETCH_ERROR_INVALID_STRUCTURE = 2,
MIDISKETCH_ERROR_INVALID_MOOD = 3,
MIDISKETCH_ERROR_INVALID_CHORD = 4,
MIDISKETCH_ERROR_GENERATION_FAILED = 5,
MIDISKETCH_ERROR_OUT_OF_MEMORY = 6,
} MidiSketchError;C API Structures
// MIDI binary output
typedef struct {
uint8_t* data;
size_t size;
} MidiSketchMidiData;
// Event JSON output
typedef struct {
char* json;
size_t length;
} MidiSketchEventData;
// Note input for custom vocal
typedef struct {
uint32_t start_tick;
uint32_t duration;
uint8_t pitch;
uint8_t velocity;
} MidiSketchNoteInput;Complete Example
C++ Example
#include "midisketch.h"
#include <fstream>
int main() {
using namespace midisketch;
// Create instance
MidiSketch sketch;
// Configure
SongConfig config;
config.style_preset_id = 0; // J-Pop
config.key = Key::C;
config.bpm = 120;
config.seed = 12345;
config.drums_enabled = true;
config.vocal_attitude = VocalAttitude::Expressive;
// Generate
sketch.generateFromConfig(config);
// Get MIDI data
auto midi = sketch.getMidi();
// Save to file
std::ofstream out("output.mid", std::ios::binary);
out.write(reinterpret_cast<const char*>(midi.data()), midi.size());
return 0;
}C Example
#include "midisketch_c.h"
#include <stdio.h>
int main() {
// Create instance
MidiSketchHandle handle = midisketch_create();
// Get default config for J-Pop style
MidiSketchSongConfig* config = midisketch_create_default_config_ptr(0);
config->key = 0; // C
config->bpm = 120;
config->seed = 12345;
// Generate
MidiSketchError err = midisketch_generate_from_config(handle, config);
if (err != MIDISKETCH_OK) {
printf("Generation failed: %d\n", err);
midisketch_destroy(handle);
return 1;
}
// Get MIDI data
MidiSketchMidiData* midi = midisketch_get_midi(handle);
// Save to file
FILE* f = fopen("output.mid", "wb");
fwrite(midi->data, 1, midi->size, f);
fclose(f);
// Cleanup
midisketch_free_midi(midi);
midisketch_destroy(handle);
return 0;
}