解析MIDI文件以记录事件

时间:2018-01-11 23:02:11

标签: c# unity3d naudio

我目前正在尝试解析MIDI文件以使用NAudio MIDI库创建音符事件,可用于允许虚拟钢琴与MIDI音轨一起播放。我有一个类应该这样做,但是,有一个我无法弄清楚的错误。以下是目前形式的课程:

public MidiFile midi;

public float ticks;
public float offset;

// Use this for initialization
void Start () {
    //Loading midi file "mainSong.bytes" from resources folder
    //Its a midi file, extension has been changed to .bytes manually
    TextAsset asset = Resources.Load("mainSong") as TextAsset;
    Stream s = new MemoryStream(asset.bytes);
    //Read the file
    midi = new MidiFile(s, true);
    //Ticks needed for timing calculations
    ticks = midi.DeltaTicksPerQuarterNote;
}

public void StartPlayback()
{
    foreach (MidiEvent note in midi.Events)
    {
        //If its the start of the note event
        if (note.CommandCode == MidiCommandCode.NoteOn)
        {
            //Cast to note event and process it
            NoteOnEvent noe = (NoteOnEvent)note;
            NoteEvent(noe);
        }
    }
}

public void NoteEvent(NoteOnEvent noe)
{
    //The bpm(tempo) of the track
    float bpm = 150;

    //Time until the start of the note in seconds
    float time = (60 * noe.AbsoluteTime) / (bpm * ticks);

    int noteNumber = noe.NoteNumber;

    //Start coroutine for each note at the start of the playback
    StartCoroutine(CreateAction(time, noteNumber, noe.NoteLength));
}

IEnumerator CreateAction(float t, int noteNumber, float length)
{
    //Wait for the start of the note
    yield return new WaitForSeconds(t);
    //The note is about to play, do stuff here
    Debug.Log("Playing note: "+noteNumber);
}

目前,在尝试构建此代码时,该行的Start方法中存在错误 midi = new MidiFile(s, true); 错误“无法从system.io.stream转换为字符串”

解析 s 作为字符串midi = new MidiFile(s.ToString(), true);允许代码构建,但是,在运行Unity项目时,相同的行会出现此错误:“找不到文件”D :\ USER PROFILE \ Documents \ Unity Projects \ New Unity Project \ System.IO.MemoryStream“

有没有人知道如何修复这些错误中的任何一个以允许此代码在Unity中运行?

1 个答案:

答案 0 :(得分:0)

查看source code,您可以找到满足Stream, bool签名的构造函数:

/// <summary>
/// Opens a MIDI file stream for reading
/// </summary>
/// <param name="inputStream">The input stream containing a MIDI file</param>
/// <param name="strictChecking">If true will error on non-paired note events</param>
public MidiFile(Stream inputStream, bool strictChecking) :
    this(inputStream, strictChecking, false)
{
}

您似乎正在使用旧版本的库。早在2013年,NAudio就不支持从流媒体播放MIDI。

查看历史记录,似乎在2017-04-15上添加了Stream支持。

您应该尝试找到更新的版本,例如安装一个较新的NuGet包。

s.ToString()绝对不会帮助你,因为:

  • 它将Stream对象转换为人类可读的格式。除了一些特殊对象,它通常是类名。在您的情况下,班级名称为System.IO.MemoryStreams的类型)。
  • 然后会在当前目录中查找名为System.IO.memoryStream文件。当前目录为D:\User\...\New Unity Project
  • 当然没有文件,因为你有资源,而不是文件。