解析 MIDI 文件以记录事件
Parsing MIDI file to note events
我目前正在尝试解析 MIDI 文件以使用 NAudio MIDI 库创建音符事件,该库可用于让虚拟钢琴与 MIDI 音轨一起演奏。我有一个 class 应该这样做,但是,有一个我无法弄清楚的错误。这是当前形式的 class:
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);
错误是"cannot convert from system.io.stream to string"
将 s 解析为字符串 midi = new MidiFile(s.ToString(), true);
允许构建代码,但是,当 运行 将 Unity 项目设置为同一行时会出现此错误: "Could not find file "D:\USER PROFILE\Documents\Unity Projects\New Unity Project\System.IO.MemoryStream"
有谁知道如何修复这些错误中的任何一个以允许此代码在 Unity 中 运行?
查看 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
对象转换为人类可读的格式。除了一些特殊的对象,它通常是 class 名称。在您的例子中,class 名称是 System.IO.MemoryStream
(即 s
的类型)。
- 然后它将在当前目录中查找 一个名为
System.IO.memoryStream
的文件。当前目录是 D:\User\...\New Unity Project
.
- 当然不会有文件,因为你有的是资源,不是文件。
我目前正在尝试解析 MIDI 文件以使用 NAudio MIDI 库创建音符事件,该库可用于让虚拟钢琴与 MIDI 音轨一起演奏。我有一个 class 应该这样做,但是,有一个我无法弄清楚的错误。这是当前形式的 class:
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);
错误是"cannot convert from system.io.stream to string"
将 s 解析为字符串 midi = new MidiFile(s.ToString(), true);
允许构建代码,但是,当 运行 将 Unity 项目设置为同一行时会出现此错误: "Could not find file "D:\USER PROFILE\Documents\Unity Projects\New Unity Project\System.IO.MemoryStream"
有谁知道如何修复这些错误中的任何一个以允许此代码在 Unity 中 运行?
查看 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
对象转换为人类可读的格式。除了一些特殊的对象,它通常是 class 名称。在您的例子中,class 名称是System.IO.MemoryStream
(即s
的类型)。 - 然后它将在当前目录中查找 一个名为
System.IO.memoryStream
的文件。当前目录是D:\User\...\New Unity Project
. - 当然不会有文件,因为你有的是资源,不是文件。