All Projects → melanchall → Drywetmidi

melanchall / Drywetmidi

Licence: mit
.NET library to read, write, process MIDI files and to work with MIDI devices

Projects that are alternatives of or similar to Drywetmidi

amanuensis
The Amanuensis is an automated songwriting and recording system aimed at ridding the process of anything left-brained, so one need never leave a creative, spontaneous and improvisational state of mind, from the inception of the song until its final master. See the README for instructions and feel free to message me at soundcloud.com/to_the_sun.
Stars: ✭ 30 (-85.29%)
Mutual labels:  midi, recording
Tlog
Terminal I/O logger
Stars: ✭ 170 (-16.67%)
Mutual labels:  recording, playback
midi-recorder
🎹 The easiest way to record MIDI. No install. Automatically records.
Stars: ✭ 38 (-81.37%)
Mutual labels:  midi, recording
TBbard
Automated FFXIV Bard Performer (Now with MIDI support!)
Stars: ✭ 38 (-81.37%)
Mutual labels:  midi, playback
MIDITapeRecorder
AUv3 MIDI Tape Recorder
Stars: ✭ 91 (-55.39%)
Mutual labels:  midi, recording
Miniaudio
Single file audio playback and capture library written in C.
Stars: ✭ 1,889 (+825.98%)
Mutual labels:  recording, playback
termbacktime
Terminal recording and playback.
Stars: ✭ 33 (-83.82%)
Mutual labels:  playback, recording
Managedbass
.Net Wrapper for 'Bass' Audio Library
Stars: ✭ 131 (-35.78%)
Mutual labels:  recording, playback
Avfoundationrecorder
Swift audio recorder using AVFoundation
Stars: ✭ 174 (-14.71%)
Mutual labels:  recording
Omnimidi
A software MIDI synthesizer for professional use.
Stars: ✭ 181 (-11.27%)
Mutual labels:  midi
Jamtaba
Jamtaba is a software to play online music jam sessions.
Stars: ✭ 174 (-14.71%)
Mutual labels:  midi
Shaden
🎧 A modular audio synthesizer.
Stars: ✭ 175 (-14.22%)
Mutual labels:  midi
Mixxx
Mixxx is Free DJ software that gives you everything you need to perform live mixes.
Stars: ✭ 2,510 (+1130.39%)
Mutual labels:  midi
Opencast
The free and open source solution for automated video capture and distribution at scale.
Stars: ✭ 194 (-4.9%)
Mutual labels:  recording
Horizonsdk Ios
Horizon SDK for iOS
Stars: ✭ 171 (-16.18%)
Mutual labels:  recording
Libatm
Library for generating and working with MIDI files
Stars: ✭ 171 (-16.18%)
Mutual labels:  midi
Midiplayerjs
♬ Midi parser & player engine for browser or Node. As a parser converts MIDI events into JSON. Works well with single or multitrack MIDI files.
Stars: ✭ 199 (-2.45%)
Mutual labels:  midi
Python Rtmidi
Python bindings for the cross-platform MIDI I/O library RtMidi
Stars: ✭ 189 (-7.35%)
Mutual labels:  midi
Arduino Applemidi Library
Send and receive MIDI messages over Ethernet (rtpMIDI or AppleMIDI)
Stars: ✭ 177 (-13.24%)
Mutual labels:  midi
Scrcast
Drop-in Android Screen Recording Library
Stars: ✭ 178 (-12.75%)
Mutual labels:  recording

DryWetMIDI Logo

NuGet

DryWetMIDI is the .NET library to work with MIDI files and MIDI devices. Visit Documentation to learn how to use the DryWetMIDI. The library was tested on 113,270 files taken from here. Thanks midi-man for this great collection. You can get the latest version via NuGet.

Status

Windows (.NET Framework) Windows (.NET Core) macOS (.NET Core) Linux (.NET Core)
Core Build Status Build Status Build Status Build Status
Devices Build Status Build Status Not supported Not supported

Features

With the DryWetMIDI you can:

  • Read, write and create Standard MIDI Files (SMF). It is also possible to read RMID files where SMF wrapped to RIFF chunk.
  • Send MIDI events to/receive them from MIDI devices, play MIDI data and record it.
  • Finely adjust process of reading and writing. It allows, for example, to read corrupted files and repair them, or build MIDI file validators.
  • Implement custom meta events and custom chunks that can be written to and read from MIDI files.
  • Easily catch specific error when reading or writing MIDI file since all possible errors in a MIDI file are presented as separate exception classes.
  • Manage content of a MIDI file either with low-level objects, like event, or high-level ones, like note (read the High-level data managing section of the library docs).
  • Build musical compositions (see Pattern page of the library docs).
  • Perform complex tasks like quantizing, notes splitting or converting MIDI file to CSV representation (see Tools page of the library docs).

Documentation

Complete documentation including API reference is available on https://melanchall.github.io/drywetmidi.

Projects using DryWetMIDI

Here the list of noticeable projects that use DryWetMIDI:

  • Clone Hero
    Free rhythm game, which can be played with any 5 or 6 button guitar controller, game controllers, or just your standard computer keyboard. The game is a clone of Guitar Hero.
  • Electrophonics
    A collection of virtual musical instruments that features real MIDI output.
  • Rustissimo
    Using Rustissimo you can create a concert with your friends and play instruments with synchronization.

Getting Started

There are several articles that can help you dive into API provided by DryWetMIDI:

Let's see some examples of what you can do with DryWetMIDI.

To read a MIDI file you have to use Read static method of the MidiFile:

var midiFile = MidiFile.Read("Some Great Song.mid");

or, in more advanced form (visit Reading settings page on the library docs to learn more about how to adjust process of reading)

var midiFile = MidiFile.Read(
    "Some Great Song.mid",
    new ReadingSettings
    {
        NoHeaderChunkPolicy = NoHeaderChunkPolicy.Abort,
        CustomChunkTypes = new ChunkTypesCollection
        {
            { typeof(MyCustomChunk), "Cstm" }
        }
    });

To write MIDI data to a file you have to use Write method of the MidiFile:

midiFile.Write("My Great Song.mid");

or, in more advanced form (visit Writing settings page on the library docs to learn more about how to adjust process of writing)

midiFile.Write(
    "My Great Song.mid",
    true,
    MidiFileFormat.SingleTrack,
    new WritingSettings
    {
        CompressionPolicy = CompressionPolicy.Default
    });

Of course you can create a MIDI file from scratch by creating an instance of the MidiFile and writing it:

var midiFile = new MidiFile(
    new TrackChunk(
        new SetTempoEvent(500000)),
    new TrackChunk(
        new TextEvent("It's just single note track..."),
        new NoteOnEvent((SevenBitNumber)60, (SevenBitNumber)45),
        new NoteOffEvent((SevenBitNumber)60, (SevenBitNumber)0)
        {
            DeltaTime = 400
        }));

midiFile.Write("My Future Great Song.mid");

or

var midiFile = new MidiFile();
TempoMap tempoMap = midiFile.GetTempoMap();

var trackChunk = new TrackChunk();
using (var notesManager = trackChunk.ManageNotes())
{
    NotesCollection notes = notesManager.Notes;
    notes.Add(new Note(
        NoteName.A,
        4,
        LengthConverter.ConvertFrom(
            new MetricTimeSpan(hours: 0, minutes: 0, seconds: 10),
            0,
            tempoMap)));
}

midiFile.Chunks.Add(trackChunk);
midiFile.Write("My Future Great Song.mid");

If you want to speed up playing back a MIDI file by two times you can do it with this code:

foreach (var trackChunk in midiFile.Chunks.OfType<TrackChunk>())
{
    foreach (var setTempoEvent in trackChunk.Events.OfType<SetTempoEvent>())
    {
        setTempoEvent.MicrosecondsPerQuarterNote /= 2;
    }
}

Of course this code is simplified. In practice a MIDI file may not contain SetTempo event which means it has the default one (500,000 microseconds per beat).

Instead of modifying a MIDI file you can use Playback class:

using (var outputDevice = OutputDevice.GetByName("Microsoft GS Wavetable Synth"))
using (var playback = midiFile.GetPlayback(outputDevice))
{
    playback.Speed = 2.0;
    playback.Play();
}

To get duration of a MIDI file as TimeSpan use this code:

TempoMap tempoMap = midiFile.GetTempoMap();
TimeSpan midiFileDuration = midiFile
    .GetTimedEvents()
    .LastOrDefault(e => e.Event is NoteOffEvent)
    ?.TimeAs<MetricTimeSpan>(tempoMap) ?? new MetricTimeSpan();

or simply:

TimeSpan midiFileDuration = midiFile.GetDuration<MetricTimeSpan>();

Suppose you want to remove all C# notes from a MIDI file. It can be done with this code:

foreach (var trackChunk in midiFile.GetTrackChunks())
{
    using (var notesManager = trackChunk.ManageNotes())
    {
        notesManager.Notes.RemoveAll(n => n.NoteName == NoteName.CSharp);
    }
}

or

midiFile.RemoveNotes(n => n.NoteName == NoteName.CSharp);

To get all chords of a MIDI file at 20 seconds from the start of the file write this:

TempoMap tempoMap = midiFile.GetTempoMap();
IEnumerable<Chord> chordsAt20seconds = midiFile
    .GetChords()
    .AtTime(
        new MetricTimeSpan(0, 0, 20),
        tempoMap,
        LengthedObjectPart.Entire);

To create a MIDI file with single note which length will be equal to length of two triplet eighth notes you can use this code:

var midiFile = new MidiFile();
var tempoMap = midiFile.GetTempoMap();

var trackChunk = new TrackChunk();
using (var notesManager = trackChunk.ManageNotes())
{
    var length = LengthConverter.ConvertFrom(
        2 * MusicalTimeSpan.Eighth.Triplet(),
        0,
        tempoMap);
    var note = new Note(NoteName.A, 4, length);
    notesManager.Notes.Add(note);
}

midiFile.Chunks.Add(trackChunk);
midiFile.Write("Single note great song.mid");

You can even build a musical composition:

Pattern pattern = new PatternBuilder()
     
    // Insert a pause of 5 seconds
    .StepForward(new MetricTimeSpan(0, 0, 5))

    // Insert an eighth C# note of the 4th octave
    .Note(Octave.Get(4).CSharp, MusicalTimeSpan.Eighth)

    // Set default note length to triplet eighth and default octave to 5
    .SetNoteLength(MusicalTimeSpan.Eighth.Triplet())
    .SetOctave(Octave.Get(5))

    // Now we can add triplet eighth notes of the 5th octave in a simple way
    .Note(NoteName.A)
    .Note(NoteName.B)
    .Note(NoteName.GSharp)

    // Get pattern
    .Build();

MidiFile midiFile = pattern.ToFile(TempoMap.Default);

DryWetMIDI provides devices API allowing to send MIDI events to and receive them from MIDI devices. Following example shows how to send events to MIDI device and handle them as they are received by the device:

using System;
using Melanchall.DryWetMidi.Devices;
using Melanchall.DryWetMidi.Core;

// ...

using (var outputDevice = OutputDevice.GetByName("MIDI Device"))
{
    outputDevice.EventSent += OnEventSent;

    using (var inputDevice = InputDevice.GetByName("MIDI Device"))
    {
        inputDevice.EventReceived += OnEventReceived;
        inputDevice.StartEventsListening();

        outputDevice.SendEvent(new NoteOnEvent());
        outputDevice.SendEvent(new NoteOffEvent());
    }
}

// ...

private void OnEventReceived(object sender, MidiEventReceivedEventArgs e)
{
    var midiDevice = (MidiDevice)sender;
    Console.WriteLine($"Event received from '{midiDevice.Name}' at {DateTime.Now}: {e.Event}");
}

private void OnEventSent(object sender, MidiEventSentEventArgs e)
{
    var midiDevice = (MidiDevice)sender;
    Console.WriteLine($"Event sent to '{midiDevice.Name}' at {DateTime.Now}: {e.Event}");
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].