DryWetMIDI

repository·develop·Indexed 20 days ago

https://github.com/melanchall/drywetmidi

A comprehensive .NET library for handling MIDI data, MIDI devices, and musical composition. It provides tools for reading and writing Standard MIDI Files (SMF) and RMID files, device communication, playback, and recording. The library includes a dedicated Music Theory API and a fluent PatternBuilder for programmatic composition using musical concepts like octaves, intervals, and musical time spans. It also supports advanced operations such as quantization and virtual MIDI device management on macOS.

Tokens
61K
Snippets
153
Records
210
Agent score
71%

What's inside DryWetMIDI

  1. Overview of DryWetMIDI tools

    develop

    DryWetMIDI includes several specialized tools designed to handle complex MIDI manipulation tasks. These tools can be used to process MIDI files or individual MIDI objects directly:

    • Splitter: Splits objects or MIDI files using various criteria.
    • Quantizer: Quantizes MIDI objects to a specific grid or timing.
    • Merger: Merges nearby objects or combines multiple MIDI files.
    • Resizer: Resizes groups of objects or MIDI files.
    • Repeater: Repeats groups of objects or MIDI files.
    • Sanitizer: Cleans MIDI files by removing redundant events and other inconsistencies.
    • CSV serializer: Converts MIDI objects to a CSV representation and allows reading them back.
  2. Overview of DryWetMIDI capabilities

    develop

    DryWetMIDI is a .NET library designed for working with MIDI data and MIDI devices. It provides a comprehensive suite of tools for MIDI manipulation, device communication, and musical composition.

    Key capabilities include:

    • MIDI File Management: Read, write, and create Standard MIDI Files (SMF) and RMID files. It supports fine-grained control over the reading/writing process (e.g., repairing corrupted files), custom meta events, and custom chunks. Error handling is robust, with specific exception classes for different file errors.
    • Device Communication: Send MIDI events to output devices and receive them from input devices.
    • Playback and Recording: Play MIDI data and record incoming MIDI data.
    • Data Management: Manage MIDI data using both low-level objects (like MidiEvent) and high-level objects (like Note) with various time and length representations.
    • Composition and Music Theory: Build musical compositions using Pattern and utilize a dedicated Music Theory API.
    • Advanced Tools: Perform complex operations such as quantizing, splitting notes, or converting MIDI files to CSV representation.
  3. Merge MIDI objects and files using the Merger class

    develop

    The Melanchall.DryWetMidi.Tools.Merger class provides extension methods to combine MIDI data. You can merge different types of MIDI objects or entire MIDI files.

    Available merging strategies include:

    • Objects merging: Combining individual MIDI objects (like tracks or events).
    • MIDI files merging: Combining multiple MIDI files into a single output.

    For a complete list of all available methods and their specific configuration settings, refer to the official API documentation for the Melanchall.DryWetMidi.Tools.Merger class.

  4. Split MIDI objects and files using the Splitter class

    develop

    The Melanchall.DryWetMidi.Tools.Splitter class provides extension methods to divide MIDI data into smaller parts. You can split MIDI objects (such as MidiFile or specific MIDI tracks/events) or entire MIDI files based on various criteria.

    Available splitting strategies include:

    • Objects splitting: Dividing specific MIDI objects or collections of objects.
    • MIDI file splitting: Dividing a complete MIDI file into multiple files.

    For a complete list of all available methods and their specific configuration settings, refer to the official Splitter API documentation.

  5. What is a TempoMap and why use it?

    develop

    A TempoMap is a collection of tempo and time signature changes. It is a core object used for high-level MIDI management, specifically for converting between different time and length representations (e.g., converting between MIDI ticks and real-world time).

    Key characteristics:

    • It does not reflect original MIDI events directly; instead, it holds the actual tempo and time signature changes.
    • Default values (120 BPM and 4/4 time signature) are not stored as changes unless they are explicitly modified.
    • Repeated values are ignored to keep the map efficient.
  6. Configure chord detection with ChordDetectionSettings

    develop

    Use ChordDetectionSettings to adjust how chords are built from notes.

    Key properties include:

    • NotesTolerance: Defines the maximum distance (time) of notes from the start of the first note in a chord. Notes within this tolerance are included in the chord. Default is 0.
    • NotesMinCount: Defines the minimum number of notes required to form a chord. If the count of simultaneous notes is less than this value, they will not be grouped into a chord. Default is 1.

    Note that chord building is hierarchical: ChordDetectionSettings can use NoteDetectionSettings to control note construction, which in turn can use TimedEventDetectionSettings to control event construction.

  7. Understand time and length representations in DryWetMIDI

    develop

    In DryWetMIDI, all time and length values are stored as long numbers in units defined by the MIDI file's time division. To work with human-readable formats, the library provides several ITimeSpan implementations.

    Note that 'time' (position from start) and 'length' (duration) are treated interchangeably as 'time spans'.

    Available representations:

    • MetricTimeSpan: Time in microseconds.
    • BarBeatTicksTimeSpan: Time in bars, beats, and ticks.
    • BarBeatFractionTimeSpan: Time in bars and fractional beats (e.g., 0.5 beats).
    • MusicalTimeSpan: Time as a fraction of a whole note length.
    • MidiTimeSpan: A wrapper for the raw long value in MIDI ticks.
  8. How the Resizer tool works

    develop

    The Resizer tool allows you to resize a group of objects or an entire MIDI file. When resizing a group, the tool treats all passed objects as a single unit and scales them to the new length while preserving all time-to-length ratios. This ensures that the relative positioning of events remains consistent (e.g., an event at the midpoint of a group will remain at the midpoint after resizing).

    You can resize using two primary approaches:

    1. Specified New Length: Setting the group or file to a specific duration.
    2. Ratio: Multiplying all distances from the start of the group by a factor (e.g., a ratio of 2 doubles the size, while 0.5 halves it).
  9. How Traces work in DryWetMIDI

    develop

    When building with the Debug or ReleaseTestFull configurations and running tests that utilize playback functionality, the library generates diagnostic files.

    Output Location: Files are stored in your machine's temporary folder (retrievable via Path.GetTempPath()).

    Directory Structure:

    • A root folder named PlaybackTraces and SysExTraces will be created in the temp directory.
    • Inside these, subfolders corresponding to individual tests will be created.
    • Diagnostic files are located within each specific test folder.
  10. How GetObjects handles unassigned events

    develop

    The GetObjects method is designed to ensure no data is lost when extracting high-level MIDI abstractions.

    When you request multiple types (e.g., ObjectType.Note | ObjectType.TimedEvent), the engine attempts to form as many Note objects as possible. Any MIDI events that are not part of a completed Note (such as a Note On without a Note Off, or a TextEvent) are automatically returned as TimedEvent objects. This allows you to process the musical structure while still having access to the underlying raw event stream.