{"id":16141671,"url":"https://github.com/kermalis/kmidi","last_synced_at":"2025-04-06T18:44:03.731Z","repository":{"id":162299699,"uuid":"620127960","full_name":"Kermalis/KMIDI","owner":"Kermalis","description":"A simple library for reading and writing MIDI files!","archived":false,"fork":false,"pushed_at":"2023-05-17T03:55:14.000Z","size":47,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-27T04:33:45.386Z","etag":null,"topics":["csharp","midi","midi-file","midi-files","music"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kermalis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-28T04:43:57.000Z","updated_at":"2023-05-17T03:56:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"7534892e-347a-45ad-bdea-f681c68505fb","html_url":"https://github.com/Kermalis/KMIDI","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kermalis%2FKMIDI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kermalis%2FKMIDI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kermalis%2FKMIDI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kermalis%2FKMIDI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kermalis","download_url":"https://codeload.github.com/Kermalis/KMIDI/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247535175,"owners_count":20954571,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","midi","midi-file","midi-files","music"],"created_at":"2024-10-09T23:56:24.579Z","updated_at":"2025-04-06T18:44:03.706Z","avatar_url":"https://github.com/Kermalis.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# 📖 KMIDI\n\n[![NuGet](https://img.shields.io/nuget/v/KMIDI.svg)](https://www.nuget.org/packages/KMIDI)\n[![NuGet downloads](https://img.shields.io/nuget/dt/KMIDI)](https://www.nuget.org/packages/KMIDI)\n\nThis .NET library allows you to simply read and write MIDI files.\nThere is no functionality for playing or listening to MIDIs, so it's purely for handling the file data itself.\nYou can even add custom chunks to the MIDI file!\nYou can read MIDIs and then edit them slightly before saving them again.\n\nIt handles all MIDI formats because it tries to adhere to the MIDI specification.\nThe specification isn't fully respected because some invalid MIDIs are not detected at the moment.\nHowever, the library will catch most invalid MIDIs!\n\n----\n## 🚀 Usage:\nAdd the [KMIDI](https://www.nuget.org/packages/KMIDI) NuGet package to your project or download the .dll from [the releases tab](https://github.com/Kermalis/KMIDI/releases).\n\n----\n## Examples:\n\n### Reading MIDI:\n```cs\nMIDIFile inMIDI;\nusing (FileStream fs = File.OpenRead(@\"C:\\Folder\\PathToMIDI.mid\"))\n{\n\tinMIDI = new MIDIFile(fs);\n}\n\n\nMIDIFormat format = inMIDI.HeaderChunk.Format;\nushort numTracks = inMIDI.HeaderChunk.NumTracks;\nTimeDivisionValue timeDiv = inMIDI.HeaderChunk.TimeDivision;\n\n\nforeach (MIDITrackChunk track in inMIDI.EnumerateTrackChunks())\n{\n\tfor (IMIDIEvent? e = track.First; e is not null; e = e.Next)\n\t{\n\t\tswitch (ev)\n\t\t{\n\t\t\tcase IMIDIEvent\u003cNoteOnMessage\u003e note:\n\t\t\t{\n\t\t\t\tNoteOnMessage msg = note.Msg;\n\t\t\t\tConsole.WriteLine(\"Note on @{0} ticks: Channel {1}, Note {2}, Velocity {3}\",\n\t\t\t\t\te.Ticks, msg.Channel, msg.Note, msg.Velocity);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t{\n\t\t\t\tMIDIMessage msg = e.Msg;\n\t\t\t\tConsole.WriteLine(\"Other message @{0} ticks: {1}\",\n\t\t\t\t\te.Ticks, msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n### Writing MIDI:\n```cs\nushort ticksPerQuarterNote = 48;\nint tracksInitialCapacity = 2;\nvar newMIDI = new MIDIFile(MIDIFormat.Format1, TimeDivisionValue.CreatePPQN(ticksPerQuarterNote), tracksInitialCapacity);\n\nvar metaTrack = new MIDITrackChunk();\nnewMIDI.AddChunk(metaTrack);\n\ndecimal bpm = 180;\nmetaTrack.InsertMessage(0, MetaMessage.CreateTempoMessage(bpm));\nmetaTrack.InsertMessage(480, MetaMessage.CreateTextMessage(MetaMessageType.Marker, \"Halfway!\"));\nmetaTrack.InsertMessage(960, new MetaMessage(MetaMessageType.EndOfTrack, Array.Empty\u003cbyte\u003e()));\n\nvar chanTrack = new MIDITrackChunk();\nnewMIDI.AddChunk(chanTrack);\n\nbyte chan = 0;\nchanTrack.InsertMessage(0, MetaMessage.CreateTextMessage(MetaMessageType.TrackName, \"First Track\"));\nchanTrack.InsertMessage(0, new ProgramChangeMessage(chan, MIDIProgram.FrenchHorn));\nchanTrack.InsertMessage(0, new ControllerMessage(chan, ControllerType.Pan, 80));\n\nchanTrack.InsertMessage(0, new NoteOnMessage(chan, MIDINote.C_4, 110));\nchanTrack.InsertMessage(48, new NoteOffMessage(chan, MIDINote.C_4, 0));\n\nchanTrack.InsertMessage(96, new NoteOnMessage(chan, MIDINote.D_4, 120));\nchanTrack.InsertMessage(480, new NoteOffMessage(chan, MIDINote.D_4, 0));\n\nchanTrack.InsertMessage(480, new NoteOnMessage(chan, MIDINote.G_4, 127));\nchanTrack.InsertMessage(480, new NoteOnMessage(chan, MIDINote.C_5, 127));\nchanTrack.InsertMessage(960, new NoteOffMessage(chan, MIDINote.G_4, 0));\nchanTrack.InsertMessage(960, new NoteOffMessage(chan, MIDINote.C_5, 0));\n\nchanTrack.InsertMessage(960, new MetaMessage(MetaMessageType.EndOfTrack, Array.Empty\u003cbyte\u003e()));\n\nusing (FileStream fs = File.Create(@\"C:\\Folder\\PathToMIDI.mid\"))\n{\n\tnewMIDI.Save(fs);\n}\n```\n\n----\n## KMIDI Uses:\n* [EndianBinaryIO](https://github.com/Kermalis/EndianBinaryIO)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkermalis%2Fkmidi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkermalis%2Fkmidi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkermalis%2Fkmidi/lists"}