-
-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
948b577
commit c468caf
Showing
17 changed files
with
646 additions
and
23 deletions.
There are no files selected for viewing
168 changes: 168 additions & 0 deletions
168
DryWetMidi.Tests/Core/Lazy/MidiTokensReaderUtilitiesTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
using Melanchall.DryWetMidi.Common; | ||
using Melanchall.DryWetMidi.Core; | ||
using Melanchall.DryWetMidi.Tests.Common; | ||
using Melanchall.DryWetMidi.Tests.Utilities; | ||
using NUnit.Framework; | ||
using System; | ||
using System.Linq; | ||
|
||
namespace Melanchall.DryWetMidi.Tests.Core | ||
{ | ||
[TestFixture] | ||
public sealed class MidiTokensReaderUtilitiesTests | ||
{ | ||
#region Test methods | ||
|
||
[Test] | ||
public void EnumerateEvents_NoEvents() => EnumerateEvents( | ||
initReader: ReadUntilTrackChunk, | ||
midiFile: new MidiFile(), | ||
expectedEvents: Array.Empty<MidiEvent>()); | ||
|
||
[Test] | ||
public void EnumerateEvents_SingleTrackChunk_SingleEvent() => EnumerateEvents( | ||
initReader: ReadUntilTrackChunk, | ||
midiFile: new MidiFile( | ||
new TrackChunk( | ||
new TextEvent("A"))), | ||
expectedEvents: new MidiEvent[] | ||
{ | ||
new TextEvent("A"), | ||
new EndOfTrackEvent() | ||
}, | ||
format: MidiFileFormat.SingleTrack); | ||
|
||
[Test] | ||
public void EnumerateEvents_SingleTrackChunk_MultipleEvents() => EnumerateEvents( | ||
initReader: ReadUntilTrackChunk, | ||
midiFile: new MidiFile( | ||
new TrackChunk( | ||
new TextEvent("A"), | ||
new ProgramChangeEvent((SevenBitNumber)70) { DeltaTime = 30 })), | ||
expectedEvents: new MidiEvent[] | ||
{ | ||
new TextEvent("A"), | ||
new ProgramChangeEvent((SevenBitNumber)70) { DeltaTime = 30 }, | ||
new EndOfTrackEvent() | ||
}, | ||
format: MidiFileFormat.SingleTrack); | ||
|
||
[Test] | ||
public void EnumerateEvents_MultipleTrackChunks_SingleEvent_ReadFirst() => EnumerateEvents( | ||
initReader: ReadUntilTrackChunk, | ||
midiFile: new MidiFile( | ||
new TrackChunk( | ||
new TextEvent("A")), | ||
new TrackChunk( | ||
new ProgramChangeEvent((SevenBitNumber)70) { DeltaTime = 30 })), | ||
expectedEvents: new MidiEvent[] | ||
{ | ||
new TextEvent("A"), | ||
new EndOfTrackEvent() | ||
}); | ||
|
||
[Test] | ||
public void EnumerateEvents_MultipleTrackChunks_SingleEvent_ReadSecond() => EnumerateEvents( | ||
initReader: reader => | ||
{ | ||
ReadUntilTrackChunk(reader); | ||
ReadUntilTrackChunk(reader); | ||
}, | ||
midiFile: new MidiFile( | ||
new TrackChunk( | ||
new TextEvent("A")), | ||
new TrackChunk( | ||
new ProgramChangeEvent((SevenBitNumber)70) { DeltaTime = 30 })), | ||
expectedEvents: new MidiEvent[] | ||
{ | ||
new ProgramChangeEvent((SevenBitNumber)70) { DeltaTime = 30 }, | ||
new EndOfTrackEvent() | ||
}); | ||
|
||
[Test] | ||
public void EnumerateEvents_MultipleTrackChunks_MultipleEvents_ReadFirst() => EnumerateEvents( | ||
initReader: ReadUntilTrackChunk, | ||
midiFile: new MidiFile( | ||
new TrackChunk( | ||
new TextEvent("A"), | ||
new NoteOnEvent((SevenBitNumber)50, SevenBitNumber.MaxValue) { DeltaTime = 20 }, | ||
new NoteOffEvent((SevenBitNumber)50, SevenBitNumber.MinValue)), | ||
new TrackChunk( | ||
new ProgramChangeEvent((SevenBitNumber)70) { DeltaTime = 30 }, | ||
new NoteOnEvent((SevenBitNumber)40, SevenBitNumber.MaxValue), | ||
new NoteOffEvent((SevenBitNumber)40, SevenBitNumber.MinValue) { DeltaTime = 20 })), | ||
expectedEvents: new MidiEvent[] | ||
{ | ||
new TextEvent("A"), | ||
new NoteOnEvent((SevenBitNumber)50, SevenBitNumber.MaxValue) { DeltaTime = 20 }, | ||
new NoteOffEvent((SevenBitNumber)50, SevenBitNumber.MinValue), | ||
new EndOfTrackEvent() | ||
}); | ||
|
||
[Test] | ||
public void EnumerateEvents_MultipleTrackChunks_MultipleEvents_ReadSecond() => EnumerateEvents( | ||
initReader: reader => | ||
{ | ||
ReadUntilTrackChunk(reader); | ||
ReadUntilTrackChunk(reader); | ||
}, | ||
midiFile: new MidiFile( | ||
new TrackChunk( | ||
new TextEvent("A"), | ||
new NoteOnEvent((SevenBitNumber)50, SevenBitNumber.MaxValue) { DeltaTime = 20 }, | ||
new NoteOffEvent((SevenBitNumber)50, SevenBitNumber.MinValue)), | ||
new TrackChunk( | ||
new ProgramChangeEvent((SevenBitNumber)70) { DeltaTime = 30 }, | ||
new NoteOnEvent((SevenBitNumber)40, SevenBitNumber.MaxValue), | ||
new NoteOffEvent((SevenBitNumber)40, SevenBitNumber.MinValue) { DeltaTime = 20 })), | ||
expectedEvents: new MidiEvent[] | ||
{ | ||
new ProgramChangeEvent((SevenBitNumber)70) { DeltaTime = 30 }, | ||
new NoteOnEvent((SevenBitNumber)40, SevenBitNumber.MaxValue), | ||
new NoteOffEvent((SevenBitNumber)40, SevenBitNumber.MinValue) { DeltaTime = 20 }, | ||
new EndOfTrackEvent() | ||
}); | ||
|
||
#endregion | ||
|
||
#region Private methods | ||
|
||
private void EnumerateEvents( | ||
Action<MidiTokensReader> initReader, | ||
MidiFile midiFile, | ||
MidiEvent[] expectedEvents, | ||
MidiFileFormat format = MidiFileFormat.MultiTrack) | ||
{ | ||
var filePath = FileOperations.GetTempFilePath(); | ||
|
||
try | ||
{ | ||
midiFile.Write(filePath, true, format); | ||
|
||
using (var reader = MidiFile.ReadLazy(filePath)) | ||
{ | ||
initReader(reader); | ||
|
||
var actualEvents = reader.EnumerateEvents().Events.ToArray(); | ||
MidiAsserts.AreEqual(expectedEvents, actualEvents, true, "Invalid events."); | ||
} | ||
} | ||
finally | ||
{ | ||
FileOperations.DeleteFile(filePath); | ||
} | ||
} | ||
|
||
private void ReadUntilTrackChunk(MidiTokensReader reader) | ||
{ | ||
while (true) | ||
{ | ||
var token = reader.ReadToken(); | ||
if (token == null || (token is ChunkHeaderToken chunkHeaderToken && chunkHeaderToken.ChunkId == TrackChunk.Id)) | ||
return; | ||
} | ||
} | ||
|
||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Melanchall.DryWetMidi.Core.Lazy | ||
{ | ||
/// <summary> | ||
/// Represents a result of the <see cref="MidiTokensReaderUtilities.EnumerateEvents(MidiTokensReader)"/> | ||
/// method. | ||
/// </summary> | ||
public sealed class EnumerateEventsResult | ||
{ | ||
#region Properties | ||
|
||
/// <summary> | ||
/// Gets a lazy collection of MIDI events. | ||
/// </summary> | ||
public IEnumerable<MidiEvent> Events { get; internal set; } | ||
|
||
/// <summary> | ||
/// Gets a MIDI token following the last MIDI event iterated by the | ||
/// <see cref="MidiTokensReaderUtilities.EnumerateEvents(MidiTokensReader)"/> method. | ||
/// </summary> | ||
public MidiToken NextToken { get; internal set; } | ||
|
||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,29 @@ | ||
namespace Melanchall.DryWetMidi.Core | ||
{ | ||
/// <summary> | ||
/// The type of a MIDI token. | ||
/// </summary> | ||
/// <seealso cref="MidiTokensReader"/> | ||
public enum MidiTokenType | ||
{ | ||
/// <summary> | ||
/// A chunk's header. See <see cref="ChunkHeaderToken"/>. | ||
/// </summary> | ||
ChunkHeader, | ||
HeaderChunkData, | ||
|
||
/// <summary> | ||
/// The data of a header chunk of a MIDI file. See <see cref="FileHeaderToken"/>. | ||
/// </summary> | ||
FileHeader, | ||
|
||
/// <summary> | ||
/// A MIDI event. See <see cref="MidiEventToken"/>. | ||
/// </summary> | ||
MidiEvent, | ||
|
||
/// <summary> | ||
/// A bytes packet. See <see cref="BytesPacketToken"/>. | ||
/// </summary> | ||
BytesPacket | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.