• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
Question by nathanthesnooper · Sep 25, 2016 at 05:50 AM · parsemidi

Parse a midi file!

I've been having trouble with this for a while now... I can't find any answers that lead me to much.

Is it possible for me to parse a midi file to something like these items

 class {
 
 int InstrumentNumber;
 float TimeCalled;
 float Length;
 int Pitch; //Any Format is Okay for Pitch
 
 }

and have an array for them?

Comment
afgenovese
JamesSThomas
ilyavitek
CDKML

People who like this

4 Show 0
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

  • Sort: 
avatar image

Answer by melanchall · Aug 04, 2017 at 04:27 AM

@nathanthesnooper,

If you write in C# you can use DryWetMIDI. It's open source .NET library to work with MIDI files. With the library your task can be solved with this code:

     public sealed class NoteInfo
     {
         public int? ProgramNumber { get; set; }
         public long Time { get; set; }
         public long Length { get; set; }
         public int NoteNumber { get; set; }
     }
 
     private static IEnumerable<NoteInfo> GetNotesInfo(string filePath)
     {
         var midiFile = MidiFile.Read(filePath);
 
         // build the program changes map
 
         var programChanges = new Dictionary<FourBitNumber, Dictionary<long, SevenBitNumber>>();
         foreach (var timedEvent in midiFile.GetTimedEvents())
         {
             var programChangeEvent = timedEvent.Event as ProgramChangeEvent;
             if (programChangeEvent == null)
                 continue;
 
             var channel = programChangeEvent.Channel;
 
             Dictionary<long, SevenBitNumber> changes;
             if (!programChanges.TryGetValue(channel, out changes))
                 programChanges.Add(channel, changes = new Dictionary<long, SevenBitNumber>());
 
             changes[timedEvent.Time] = programChangeEvent.ProgramNumber;
         }
 
         // collect notes info
 
         return midiFile.GetNotes()
                        .Select(n => new NoteInfo
                        {
                            ProgramNumber = GetProgramNumber(n.Channel, n.Time, programChanges),
                            Time = n.Time,
                            Length = n.Length,
                            NoteNumber = n.NoteNumber
                        });
     }
 
     private static int? GetProgramNumber(FourBitNumber channel, long time, Dictionary<FourBitNumber, Dictionary<long, SevenBitNumber>> programChanges)
     {
         Dictionary<long, SevenBitNumber> changes;
         if (!programChanges.TryGetValue(channel, out changes))
             return null;
 
         var times = changes.Keys.Where(t => t <= time).ToArray();
         return times.Any()
             ? (int?)changes[times.Max()]
             : null;
     }

ProgramNumber is defined as int? since Program Change event can be missed in a file so in this case you should decide by yourself which instrument to use.

Time and Length defined as long because all timing in a MIDI file presented as integer numbers meaning of which defined by the time division of a file. In 99.9% files times and lengths expressed in ticks. If you want to get time as hours, minutes, seconds or fraction of the whole note's length you can use TimeAs method on Note class:

 TempoMap tempoMap = midiFile.GetTempoMap();

 MetricTimeSpan metricTime = n.TimeAs<MetricTimeSpan>(tempoMap);
 MusicalTimeSpan musicalTime = n.TimeAs<MusicalTimeSpan>(tempoMap);

For Length there is the LengthAs method:

 MetricTimeSpan metricLength = n.LengthAs<MetricTimeSpan>(tempoMap);
 MusicalTimeSpan musicalLength = n.LengthAs<MusicalTimeSpan>(tempoMap);

Comment
speedything
tbriz

People who like this

2 Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Giovannino82 · Sep 13, 2017 at 11:19 AM 0
Share

DryWetMIDI looks to be a higher than .NET 3.5 library. How did you manage to use it in Unity?

avatar image CDKML Giovannino82 · Nov 23, 2017 at 05:55 PM 0
Share

Hi Giovanni, it seems that the new Unity 2017.1 update is supporting .NET 4.6, so since DryWetMidi is built on .NET 4.6 you technically can use the library now. I haven't tried it yet because i'm not quite sure how to integrate the library with Unity, but i'll try and see how it goes. If you try to update Unity and integrate DryWetMidi to your project i'd love to hear how has it gone. Greetings :)

avatar image Giovannino82 CDKML · Nov 24, 2017 at 11:06 AM 0
Share

Thanks much, good to know! I dodged the issue using a web service for parsing and Unity-Midi (https://github.com/n-yoda/unity-midi) for playing. It should work also for parsing, but I have not tried yet. :-)

avatar image erasmolbj · Jan 07, 2019 at 11:49 PM 0
Share

Hello, how can i add this lib on Unity? Sorry for the dumb question.

avatar image melanchall erasmolbj · Jan 08, 2019 at 03:10 PM 0
Share

Hi,

I suppose you need to take the code of the library and place to your project's folder (for example, Assets/Scripts). So you will build the library along with entire project build. Note that you need only files placed in DryWetMidi folder (other folders contain files for developer of the library, not for end user).

Please take the code from master branch which contains stable release: DryWetMIDI master.

Unity Answers is in Read-Only mode

Unity Answers content will be migrated to a new Community platform and we are aiming to launch a public beta on June 13. Please note, Unity Answers is now in read-only so we can prepare for the final data migration.

For more information and updates, please read our full announcement thread in the Unity Forum.

Follow this Question

Answers Answers and Comments

74 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Monodevelop .Tostring() 0 Answers

ParseUser.CurrentUser.FetchAsync() not working 0 Answers

Changing icon for Android Push Notifications on Server-side 2 Answers

How can I convert the TextMeshPro text to an int? 2 Answers

Unity3D - Parse Migration 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges