Overview
MIDI clips contain note data, timing information, and control events. They can be created from scratch, imported from MIDI files, or recorded in real-time.
Creating MIDI Clips
From Scratch
Double-click on a MIDI track to create an empty clip at the cursor position:
public MidiClip ( MidiTrack parent , long startingTime = 0 )
{
Track = parent ;
Color = parent . Color ;
_midiClipData = new MidiClipData ();
_pianoRollEditor = new PianoRoll ( this , Track as MidiTrack );
StartTick = startingTime ;
}
From Time Selection
Create a clip with a specific duration based on a time selection:
public MidiClip ( MidiTrack parent , TimeSelection time )
{
Track = parent ;
Color = parent . Color ;
_midiClipData = new MidiClipData ( time );
_pianoRollEditor = new PianoRoll ( this , Track as MidiTrack );
StartTick = TimeLineV2 . MusicalTimeToTicks ( time . Start , true );
}
From MIDI File
Import existing MIDI files:
public MidiClip ( MidiTrack parent , string filePath , long startingTime = 0 )
{
Track = parent ;
Name = Path . GetFileNameWithoutExtension ( filePath );
Color = parent . Color ;
var midiFile = MidiFile . Read ( filePath );
_midiClipData = new MidiClipData ( midiFile );
_pianoRollEditor = new PianoRoll ( this , Track as MidiTrack );
StartTick = startingTime ;
}
MIDI Clip Data Structure
The MidiClipData class manages the underlying MIDI file and note collection:
public class MidiClipData
{
public MidiFile MidiFile { get ; set ; }
public List < PNote > Notes { get ; set ; } = new ();
public TempoMap TempoMap { get ; set ; }
public MidiClipData ( MidiFile midiFile )
{
MidiFile = midiFile ;
foreach ( var note in midiFile . GetNotes ())
{
Notes . Add ( new PNote ( note ));
}
TempoMap = midiFile . GetTempoMap ();
}
}
Note Representation
Each note is wrapped in a PNote object:
public class PNote
{
/// < summary >
/// Note data like time, length, velocity, pitch
/// </ summary >
public Note Data { get ; set ; }
/// < summary >
/// Note state (enabled/disabled)
/// </ summary >
public bool Enabled { get ; set ; } = true ;
}
Clip Properties
Duration and Timing
Clip duration is calculated from the MIDI data:
protected override long GetClipDuration ()
{
return TimeLineV2 . SecondsToTicks (
_midiClipData . MidiFile . GetDuration < MetricTimeSpan >(). TotalSeconds ,
false
);
}
Width Calculation
Clip width adapts to zoom level:
protected override float GetClipWidth ()
{
return TimeLineV2 . SecondsToTicks (
_midiClipData . MidiFile . GetDuration < MetricTimeSpan >(). TotalSeconds ,
false
) * TimeLineV2 . PixelsPerTick ;
}
Editing MIDI Clips
Opening the Piano Roll
Double-click a clip to open it in the piano roll editor:
protected override void OnClipDoubleClickLeft ()
{
ArrangementView . SelectedClips . Clear ();
MidiClipView . SelectedMidiClip = this ;
_pianoRollEditor . _notes = _midiClipData . Notes . ToList ();
BottomView . RenderedWindow = BottomViewWindows . MidiClipView ;
}
Updating Clip Data
Modify clip data programmatically:
public void UpdateClipData ( MidiClipData newdata )
{
_midiClipData = newdata ;
}
Visual Rendering
Clips display MIDI notes in the arrangement view:
protected override void RenderClipContent ( float menuBarHeight , float clipHeight )
{
MidiRenderer . RenderMidiData (
_midiClipData ,
ImGui . GetWindowPos () + new Vector2 ( 0 , menuBarHeight ),
ClipWidth ,
clipHeight ,
Track . Enabled
);
}
MIDI Clip Operations
Clip View Panel
The MIDI Clip View provides advanced editing features:
public static class MidiClipView
{
public enum MidiClipViewTabs
{
Notes ,
Envelopes
}
public static MidiClip SelectedMidiClip { get ; set ; }
}
Available Features
Note Editing Full piano roll editor with note drawing, selection, and modification.
Time Operations Resize, reverse, and time-stretch MIDI data.
Velocity Control Adjust velocity ranges for all notes or selected notes.
Envelopes Automate MIDI CC parameters with envelope curves.
View timing information in musical notation:
string start = $" { SelectedMidiClip . StartMusicalTime . Bars } : { SelectedMidiClip . StartMusicalTime . Beats } : { SelectedMidiClip . StartMusicalTime . Ticks } " ;
string end = $" { SelectedMidiClip . EndMusicalTime . Bars } : { SelectedMidiClip . EndMusicalTime . Beats } : { SelectedMidiClip . EndMusualTime . Ticks } " ;
var length = SelectedMidiClip . EndMusicalTime - SelectedMidiClip . StartMusicalTime ;
string duration = $" { length . Bars } : { length . Beats } : { length . Ticks } " ;
Working with Notes
Note Properties
Each note contains:
Pitch : MIDI note number (0-127)
Velocity : Note intensity (0-127)
Time : Start position in ticks
Length : Duration in ticks
Channel : MIDI channel (0-15)
Note States
Notes can be enabled or disabled:
// Disable notes (mute without deleting)
note . Enabled = false ;
// Re-enable notes
note . Enabled = true ;
Disabled notes appear dimmed in the piano roll and won’t play during playback.
When updating clip data, always ensure the tempo map is synchronized to maintain correct timing.
Files with thousands of notes may cause slowdowns in the piano roll. Consider splitting into smaller clips or quantizing dense data.
The clip view updates in real-time as you edit. For complex operations, edits are batched to maintain smooth performance.
Each clip maintains its own copy of MIDI data. Use linked clips (future feature) to share data between instances.
Lumix supports standard MIDI file formats:
Type 0 : Single track
Type 1 : Multiple tracks (merged on import)
Type 2 : Multiple independent patterns
Imported MIDI files preserve tempo maps, time signatures, and control change events.
See Also