Skip to main content

Overview

The MidiClipData class is a data container that holds all MIDI-related information for a MIDI clip. It wraps the DryWetMidi MidiFile object and provides convenient access to notes and tempo information.

Constructors

MidiClipData(MidiFile)

Creates MIDI clip data from an existing MIDI file.
midiFile
MidiFile
required
The DryWetMidi MidiFile object to wrap.
using Melanchall.DryWetMidi.Core;

// Load a MIDI file and create clip data
var midiFile = MidiFile.Read("path/to/file.mid");
var clipData = new MidiClipData(midiFile);

MidiClipData()

Creates empty MIDI clip data with a default 2-bar length.
// Create empty MIDI clip data with default length
var clipData = new MidiClipData();

MidiClipData(TimeSelection)

Creates MIDI clip data with a specified duration based on a time selection.
time
TimeSelection
required
Time selection defining the clip’s length in musical time.
// Create clip data with 4-bar length
var selection = new TimeSelection
{
    Start = new MusicalTime(1, 1, 0),
    End = new MusicalTime(5, 1, 0)
};
var clipData = new MidiClipData(selection);

Properties

MidiFile

MidiFile
MidiFile
required
The underlying DryWetMidi MidiFile object containing all MIDI events and data.
// Access the MIDI file
var midiFile = clipData.MidiFile;

// Get MIDI file properties
var chunks = midiFile.GetTrackChunks();
var originalFormat = midiFile.OriginalFormat;

Notes

Notes
List<PNote>
required
List of all notes (PNote objects) in the MIDI clip.
// Access all notes in the clip
foreach (var note in clipData.Notes)
{
    Console.WriteLine($"Note: {note.NoteName}, Velocity: {note.Velocity}");
}

// Get note count
int noteCount = clipData.Notes.Count;
Console.WriteLine($"Total notes: {noteCount}");

TempoMap

TempoMap
TempoMap
required
The tempo map containing tempo and time signature information for the MIDI data.
// Access the tempo map
var tempoMap = clipData.TempoMap;

// Get tempo information
var tempo = tempoMap.GetTempoAtTime(new MetricTimeSpan());
Console.WriteLine($"Tempo: {tempo.BeatsPerMinute} BPM");

Constructor Behavior

Default Constructor

When using the parameterless constructor:
  • Creates a new MIDI file with a single track chunk
  • Sets default length to 2 bars (using BarBeatTicksTimeSpan(2, 0, 0))
  • Initializes with TempoMap.Default
  • Extracts all notes from the MIDI file into the Notes list

MidiFile Constructor

When creating from an existing MIDI file:
  • Wraps the provided MIDI file
  • Extracts all notes using midiFile.GetNotes()
  • Converts DryWetMidi notes to PNote objects
  • Extracts the tempo map using midiFile.GetTempoMap()

TimeSelection Constructor

When creating from a time selection:
  • Creates a new MIDI file with empty track
  • Sets length based on the time selection’s duration
  • Calculates length in bars, beats, and ticks from the selection
  • Initializes with TempoMap.Default

Usage Examples

Creating Empty MIDI Data

// Create an empty MIDI clip with default 2-bar length
var emptyData = new MidiClipData();

Console.WriteLine($"Note count: {emptyData.Notes.Count}");
Console.WriteLine($"Tempo: {emptyData.TempoMap.GetTempoAtTime(new MetricTimeSpan()).BeatsPerMinute} BPM");

Loading from MIDI File

using Melanchall.DryWetMidi.Core;
using Melanchall.DryWetMidi.Interaction;

// Load an existing MIDI file
var midiFile = MidiFile.Read("path/to/melody.mid");
var clipData = new MidiClipData(midiFile);

// Inspect the loaded data
Console.WriteLine($"Loaded {clipData.Notes.Count} notes");

// Get duration
var duration = clipData.MidiFile.GetDuration<MetricTimeSpan>();
Console.WriteLine($"Duration: {duration.TotalSeconds} seconds");

// Access individual notes
foreach (var note in clipData.Notes)
{
    Console.WriteLine($"Note: {note.NoteName} at {note.Time}");
}

Creating with Specific Duration

// Create clip data with an 8-bar duration
var timeSelection = new TimeSelection();
timeSelection.SetStart(new MusicalTime(1, 1, 0));
timeSelection.SetEnd(new MusicalTime(9, 1, 0));

var clipData = new MidiClipData(timeSelection);

var duration = clipData.MidiFile.GetDuration<MetricTimeSpan>();
Console.WriteLine($"Created clip with duration: {duration.TotalSeconds:F2} seconds");

Modifying Notes

using Melanchall.DryWetMidi.Interaction;
using Melanchall.DryWetMidi.MusicTheory;

// Create empty clip data
var clipData = new MidiClipData();

// Add notes programmatically to the MIDI file
using (var notesManager = clipData.MidiFile.ManageNotes())
{
    var note1 = new Note(NoteName.C, 4, length: 480, time: 0);
    var note2 = new Note(NoteName.E, 4, length: 480, time: 480);
    var note3 = new Note(NoteName.G, 4, length: 480, time: 960);
    
    notesManager.Notes.Add(note1);
    notesManager.Notes.Add(note2);
    notesManager.Notes.Add(note3);
}

// Refresh the Notes list
clipData.Notes.Clear();
foreach (var note in clipData.MidiFile.GetNotes())
{
    clipData.Notes.Add(new PNote(note));
}

Console.WriteLine($"Added {clipData.Notes.Count} notes");

Working with Tempo

using Melanchall.DryWetMidi.Interaction;

// Create clip data
var clipData = new MidiClipData();

// Access tempo information
var tempo = clipData.TempoMap.GetTempoAtTime(new MetricTimeSpan());
Console.WriteLine($"Current tempo: {tempo.BeatsPerMinute} BPM");

// The tempo map can be used for time conversions
var timeConverter = new TimeConverter(clipData.TempoMap);
var musicalTime = new BarBeatTicksTimeSpan(2, 0, 0);
var metricsTime = TimeConverter.ConvertTo<MetricTimeSpan>(musicalTime, clipData.TempoMap);
Console.WriteLine($"2 bars = {metricsTime.TotalSeconds} seconds");

Saving MIDI Data

// Create and populate MIDI clip data
var clipData = new MidiClipData();

// ... add notes and events ...

// Save to file
clipData.MidiFile.Write("output.mid");

// Save with overwrite
clipData.MidiFile.Write("output.mid", overwriteFile: true);

Integration with MidiClip

// Create a MIDI track
var track = new MidiTrack("Piano");

// Create clip data from a file
var midiFile = MidiFile.Read("melody.mid");
var clipData = new MidiClipData(midiFile);

// Create a clip with the data
var clip = new MidiClip(track, clipData, 0);
track.Clips.Add(clip);

// Access the clip data later
var notes = clip.MidiClipData.Notes;
var tempoMap = clip.MidiClipData.TempoMap;

Console.WriteLine($"Clip has {notes.Count} notes");

Notes

  • MidiClipData uses the DryWetMidi library for MIDI file handling
  • PNote is a wrapper around DryWetMidi’s Note class used for piano roll editing
  • The default constructor creates a 2-bar clip using BarBeatTicksTimeSpan(2, 0, 0)
  • When loading from a MIDI file, all notes are automatically extracted and converted to PNote objects
  • The TempoMap property provides access to tempo and time signature information
  • Changes to the MidiFile property should be followed by updating the Notes list if note data changed
  • The class is primarily used internally by MidiClip but can be used independently for MIDI data manipulation

Build docs developers (and LLMs) love