I am currently trying to parse MIDI files to create note events using the NAudio MIDI library, that can be used to allow a virtual piano to play along with a MIDI track. I have a class that should do this, however, there is an error that I can't figure out. Here is the class in its current form:
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);
}
Currently, when trying to build this code there is an error in the Start method at the line
midi = new MidiFile(s, true);
The error is "cannot convert from system.io.stream to string"
Parsing s as a string midi = new MidiFile(s.ToString(), true);
allows the code to build, however, when running the Unity project the same line gives this error: "Could not find file "D:\USER PROFILE\Documents\Unity Projects\New Unity Project\System.IO.MemoryStream"
Does anyone have any idea how to fix either of these errors to allow this code to run in Unity?
Looking in the source code you can find a constructor that satisfies the Stream, bool
signature:
/// <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)
{
}
It seems you're using an old version of the library. Back in 2013, NAudio did not support playing MIDIs from a stream.
Looking into the history, it seems that Stream support was added on 2017-04-15.
You should try to find a newer version, e.g. install a newer NuGet package.
s.ToString()
will definitely not help you, because:
Stream
object into its human readable format. Except for some special objects, it will usually be the class name. In your case, the class name is System.IO.MemoryStream
(that's the type of s
).System.IO.memoryStream
in the current directory. The current directory is D:\User\...\New Unity Project
.