使用n音讯从MIDI文件读书笔记

使用n音讯从MIDI文件读书笔记

本文介绍了使用n音讯从MIDI文件读书笔记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的任务是让使用n音讯库从MIDI文件中的所有笔记和他们的时间。到目前为止我从文件中的所有笔记,但我不能让他们的时间

 注意noteOn =新的注(); //自定义类注
MidiFile MIDI =新MidiFile(open.FileName);
名单,LT; TempoEvent>速度=新的List< TempoEvent>();

的for(int i = 0; I< midi.Events.Count();我++)
{
的foreach(注的MidiEvent在midi.Events [I])
{
TempoEvent tempoE;

尝试{tempoE =(TempoEvent)注; tempo.Add(tempoE); }
赶上{}

如果(note.CommandCode == MidiCommandCode.NoteOn)
{
VAR t_note =(NoteOnEvent)注;

VAR noteOffEvent = t_note.OffEvent;

noteOn.NoteName.Add(t_note.NoteName);
noteOn.NoteNumber.Add(t_note.NoteNumber);
noteOn.NoteVelocity.Add(t_note.Velocity);
noteOn.NoteLenght.Add(t_note.NoteLength);

双D =(t_note.AbsoluteTime / midi.DeltaTicksPerQuarterNote)* TEMPO [tempo.Count() - 1] .Tempo;

noteOn.StartTime.Add(TimeSpan.FromSeconds(d)条);
}

}
}



问题:



1)把笔记只列出我只是在看 NoteOnEvents 或不?如果我理解这个正确的,每一个音符都有'开始'和'结束',开始由 NoteOnEvent 定义和结束由 NoteOffEvent 。如果我看在这两个事件( NoteOn NoteOff )我会得到重复的说明。我说得对不对?



2)如何获得注释的时间呢?根据,我得到一些价值观,但似乎第一个音符的时间是正确的,但别人不一样。同样在这个帖子,有说其计算公式时必须是评论:

 ((note.AbsTime  -  lastTempoEvent .AbsTime)/ midi.ticksPerQuarterNote)*节奏+ lastTempoEvent.RealTime。 



我不知道参数 lastTempoEvent.RealTime 速度。这是它的节奏最后速度事件或?



3)读MIDI文件,它是非常缓慢的,对于较小的文件,这一点是确定的,但对于一个大的文件没有。这个小文件有〜150 NoteOnEvents 这更大的文件有〜1250 NoteOnEvents ,这是不那么重 。为什么这么慢?


解决方案

  1. 在MIDI文件,记有独立的注意 - 并留意断事件。
    n音讯已经搜索相应的音符关事件,并计算长度为你,所以你不需要自己处理音符关事件。
    (但节奏可能会在与音符的变化,并注意关闭事件,所以你必须单独计算两次。)


  2. 这些值,而不是实际的字段名称的描述。
    速度是最后一个速度事件的 MicrosecondsPerQuarterNote 值。
    lastTempoEvent.RealTime 是计算最后速度事件的时间(微秒)。



    最后一个速度事件与最大的绝对时间仍是本次活动的绝对时间前的速度事件。
    这速度事件很可能是在另一条轨道,所以它可能是之前合并所有曲目(集 midi.Events.MidiFileType 零)一个好主意处理事件。



Task is to get all notes and their time from MIDI file using NAudio library. So far I get all notes from file but I can't get their time.

            Note noteOn = new Note(); //custom class Note
            MidiFile midi = new MidiFile(open.FileName);
            List<TempoEvent> tempo = new List<TempoEvent>();

            for (int i = 0; i < midi.Events.Count(); i++)
            {
                foreach (MidiEvent note in midi.Events[i])
                {
                    TempoEvent tempoE;

                    try { tempoE = (TempoEvent)note; tempo.Add(tempoE); }
                    catch { }

                    if (note.CommandCode == MidiCommandCode.NoteOn)
                    {
                        var t_note = ( NoteOnEvent)note;

                        var noteOffEvent = t_note.OffEvent;

                        noteOn.NoteName.Add(t_note.NoteName);
                        noteOn.NoteNumber.Add(t_note.NoteNumber);
                        noteOn.NoteVelocity.Add(t_note.Velocity);
                        noteOn.NoteLenght.Add(t_note.NoteLength);

                        double d = (t_note.AbsoluteTime / midi.DeltaTicksPerQuarterNote) * tempo[tempo.Count() - 1].Tempo;

                        noteOn.StartTime.Add(TimeSpan.FromSeconds(d));
                    }

                }
            }

Questions:

1) To get just list of notes I just look in NoteOnEvents or not? If I understand this correctly, each note has 'start' and 'end', start is defined by NoteOnEvent and 'end' is defined by NoteOffEvent. If I look in both events (NoteOn and NoteOff) I would get duplicate notes. Am I right?

2) How to get note's time? According to this post , I get some values but it seems that the first note's time is correct, but others don't. Also in this post, there is a comment which says the formula for calculating time must be:

((note.AbsTime - lastTempoEvent.AbsTime) / midi.ticksPerQuarterNote) * tempo + lastTempoEvent.RealTime.

I don't know parameters lastTempoEvent.RealTime and tempo. It's it tempo of last tempo event or?

3) Reading MIDI file it's very slow, for a smaller files it's ok, but for a big files don't. This small files have ~150 NoteOnEvents and this bigger files have ~1250 NoteOnEvents, which isn't so 'heavy'. Why is so slow?

解决方案
  1. In MIDI files, a note has separate note-on and note-off events.NAudio already searches for the corresponding note-off event and calculates the length for you, so you don't need to handle note-off events yourself.(However, the tempo might change between the note-on and note-off events, so you have to compute the two times separately.)

  2. These are descriptions of the values, not the actual field names.tempo is the MicrosecondsPerQuarterNote value of the last tempo event.lastTempoEvent.RealTime is the time (in microseconds) that you computed for the last tempo event.

    The last tempo event is the tempo event with the largest absolute time that is still before this event's absolute time.That tempo event is likely to be in another track, so it might be a good idea to merge all tracks (set midi.Events.MidiFileType to zero) before handling the events.

这篇关于使用n音讯从MIDI文件读书笔记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 15:32