diff --git a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.EventPlayed.cs b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.EventPlayed.cs index bdea181ee..2949a45d3 100644 --- a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.EventPlayed.cs +++ b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.EventPlayed.cs @@ -79,6 +79,7 @@ public void EventPlayed_InterruptNotesOnStop() stopPeriod: stopPeriod, setupPlayback: (context, playback) => { + playback.TrackNotes = false; playback.InterruptNotesOnStop = true; }, afterStart: NoPlaybackAction, @@ -117,7 +118,7 @@ public void EventPlayed_MoveToStart(double speed) eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: NoPlaybackAction, + setupPlayback: (context, playback) => playback.TrackNotes = false, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveToStart(), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.Zero, "stopped"), @@ -211,7 +212,7 @@ public void EventPlayed_MoveForward_BeyondDuration() eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: NoPlaybackAction, + setupPlayback: (context, playback) => playback.TrackNotes = false, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveForward((MetricTimeSpan)stepAfterStop), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.FromSeconds(4), "stopped"), @@ -300,7 +301,7 @@ public void EventPlayed_MoveBack_BeyondZero() eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: NoPlaybackAction, + setupPlayback: (context, playback) => playback.TrackNotes = false, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveBack((MetricTimeSpan)stepAfterStop), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.Zero, "stopped"), @@ -338,7 +339,7 @@ public void EventPlayed_MoveToTime() eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: NoPlaybackAction, + setupPlayback: (context, playback) => playback.TrackNotes = false, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveToTime(new MetricTimeSpan(0, 0, 1)), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.FromSeconds(1), "stopped"), @@ -375,7 +376,7 @@ public void EventPlayed_MoveToTime_BeyondDuration() eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: NoPlaybackAction, + setupPlayback: (context, playback) => playback.TrackNotes = false, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveToTime(new MetricTimeSpan(0, 0, 10)), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.FromSeconds(4), "stopped"), diff --git a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Metadata.cs b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Metadata.cs index 08fa2238e..f36e80d2f 100644 --- a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Metadata.cs +++ b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Metadata.cs @@ -1546,6 +1546,7 @@ public void CheckPlaybackMetadata_NoteCallback_InterruptNotesOnStop() }, setupPlayback: playback => { + playback.TrackNotes = false; playback.InterruptNotesOnStop = true; playback.NoteCallback = NoteCallback; }); @@ -1611,6 +1612,7 @@ public void CheckPlaybackMetadata_NoteCallback_MoveToStart() }, setupPlayback: playback => { + playback.TrackNotes = false; playback.InterruptNotesOnStop = false; playback.NoteCallback = NoteCallback; }); @@ -1722,6 +1724,7 @@ public void CheckPlaybackMetadata_NoteCallback_MoveForward_BeyondDuration() }, setupPlayback: playback => { + playback.TrackNotes = false; playback.InterruptNotesOnStop = false; playback.NoteCallback = NoteCallback; }); @@ -1851,6 +1854,7 @@ public void CheckPlaybackMetadata_NoteCallback_MoveBack_BeyondZero() }, setupPlayback: playback => { + playback.TrackNotes = false; playback.InterruptNotesOnStop = false; playback.NoteCallback = NoteCallback; }); @@ -1947,6 +1951,7 @@ public void CheckPlaybackMetadata_NoteCallback_MoveToTime_BeyondDuration() }, setupPlayback: playback => { + playback.TrackNotes = false; playback.InterruptNotesOnStop = false; playback.NoteCallback = NoteCallback; }); diff --git a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Misc.cs b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Misc.cs index 9a5a0141e..f92e51315 100644 --- a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Misc.cs +++ b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Misc.cs @@ -732,7 +732,11 @@ public void InterruptNotesOnStop() }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: (context, playback) => playback.InterruptNotesOnStop = true, + setupPlayback: (context, playback) => + { + playback.TrackNotes = false; + playback.InterruptNotesOnStop = true; + }, afterStart: NoPlaybackAction, afterStop: NoPlaybackAction, afterResume: NoPlaybackAction); diff --git a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.NoteCallback.cs b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.NoteCallback.cs index 73bc986fe..dbf8c2cee 100644 --- a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.NoteCallback.cs +++ b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.NoteCallback.cs @@ -176,6 +176,7 @@ public void NoteCallback_InterruptNotesOnStop() stopPeriod: stopPeriod, setupPlayback: (context, playback) => { + playback.TrackNotes = false; playback.InterruptNotesOnStop = true; playback.NoteCallback = NoteCallback; }, @@ -215,7 +216,11 @@ public void NoteCallback_MoveToStart(double speed) eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: (context, playback) => playback.NoteCallback = NoteCallback, + setupPlayback: (context, playback) => + { + playback.TrackNotes = false; + playback.NoteCallback = NoteCallback; + }, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveToStart(), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.Zero, "stopped"), @@ -309,7 +314,11 @@ public void NoteCallback_MoveForward_BeyondDuration() eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: (context, playback) => playback.NoteCallback = NoteCallback, + setupPlayback: (context, playback) => + { + playback.TrackNotes = false; + playback.NoteCallback = NoteCallback; + }, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveForward((MetricTimeSpan)stepAfterStop), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.FromSeconds(4), "stopped"), @@ -398,7 +407,11 @@ public void NoteCallback_MoveBack_BeyondZero() eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: (context, playback) => playback.NoteCallback = NoteCallback, + setupPlayback: (context, playback) => + { + playback.TrackNotes = false; + playback.NoteCallback = NoteCallback; + }, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveBack((MetricTimeSpan)stepAfterStop), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.Zero, "stopped"), @@ -473,7 +486,11 @@ public void NoteCallback_MoveToTime_BeyondDuration() eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: (context, playback) => playback.NoteCallback = NoteCallback, + setupPlayback: (context, playback) => + { + playback.TrackNotes = false; + playback.NoteCallback = NoteCallback; + }, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveToTime(new MetricTimeSpan(0, 0, 10)), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.FromSeconds(4), "stopped"), diff --git a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Snapping.cs b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Snapping.cs index e05df2447..37bdd0810 100644 --- a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Snapping.cs +++ b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Snapping.cs @@ -792,6 +792,8 @@ public void SnapToNotesStarts() stopPeriod: stopPeriod, setupPlayback: (context, playback) => { + playback.TrackNotes = false; + snapPointsGroup = playback.Snapping.SnapToNotesStarts(); var snapPointsGroup2 = playback.Snapping.SnapToNotesStarts(); Assert.That(playback.Snapping.SnapPoints, Has.Count.EqualTo(2), "Count of snap points is invalid."); @@ -852,6 +854,8 @@ public void SnapToNotesEnds() stopPeriod: stopPeriod, setupPlayback: (context, playback) => { + playback.TrackNotes = false; + snapPointsGroup = playback.Snapping.SnapToNotesEnds(); var snapPointsGroup2 = playback.Snapping.SnapToNotesEnds(); Assert.That(playback.Snapping.SnapPoints, Has.Count.EqualTo(2), "Count of snap points is invalid."); diff --git a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.TimeManagement.cs b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.TimeManagement.cs index f7c4bf113..a78080a23 100644 --- a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.TimeManagement.cs +++ b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.TimeManagement.cs @@ -40,7 +40,7 @@ public void MoveToStart(double speed) eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: NoPlaybackAction, + setupPlayback: (context, playback) => playback.TrackNotes = false, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveToStart(), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.Zero, "stopped"), @@ -163,7 +163,7 @@ public void MoveForward_BeyondDuration() eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: NoPlaybackAction, + setupPlayback: (context, playback) => playback.TrackNotes = false, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveForward((MetricTimeSpan)stepAfterStop), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.FromSeconds(4), "stopped"), @@ -252,7 +252,7 @@ public void MoveBack_BeyondZero() eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: NoPlaybackAction, + setupPlayback: (context, playback) => playback.TrackNotes = false, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveBack((MetricTimeSpan)stepAfterStop), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.Zero, "stopped"), @@ -327,7 +327,7 @@ public void MoveToTime_BeyondDuration() eventsWillBeSent: new EventToSend[] { }, stopAfter: stopAfter, stopPeriod: stopPeriod, - setupPlayback: NoPlaybackAction, + setupPlayback: (context, playback) => playback.TrackNotes = false, afterStart: NoPlaybackAction, afterStop: (context, playback) => playback.MoveToTime(new MetricTimeSpan(0, 0, 10)), afterResume: (context, playback) => CheckCurrentTime(playback, TimeSpan.FromSeconds(4), "stopped"), diff --git a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.TrackNotes.cs b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.TrackNotes.cs index ea582ecdb..b62f14248 100644 --- a/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.TrackNotes.cs +++ b/DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.TrackNotes.cs @@ -1,6 +1,11 @@ using System; +using System.Collections.Generic; +using System.Linq; using Melanchall.DryWetMidi.Common; using Melanchall.DryWetMidi.Core; +using Melanchall.DryWetMidi.Interaction; +using Melanchall.DryWetMidi.Multimedia; +using Melanchall.DryWetMidi.Tests.Utilities; using NUnit.Framework; namespace Melanchall.DryWetMidi.Tests.Multimedia @@ -11,9 +16,8 @@ public sealed partial class PlaybackTests #region Test methods [Retry(RetriesNumber)] - [TestCase(true)] - [TestCase(false)] - public void TrackNotes_MoveForwardToNote(bool useOutputDevice) + [Test] + public void TrackNotes_MoveForwardToNote() { var noteNumber = (SevenBitNumber)60; var noteOnDelay = TimeSpan.FromSeconds(1); @@ -24,28 +28,30 @@ public void TrackNotes_MoveForwardToNote(bool useOutputDevice) var moveFrom = TimeSpan.FromMilliseconds(500); var moveTo = TimeSpan.FromMilliseconds(1500); - CheckTrackNotes( - eventsToSend: new[] + CheckNotesTracking( + initialTimedObjects: new[] + { + new TimedEvent(new NoteOnEvent(noteNumber, noteOnVelocity)) + .SetTime((MetricTimeSpan)noteOnDelay, TempoMap.Default), + new TimedEvent(new NoteOffEvent(noteNumber, noteOffVelocity)) + .SetTime((MetricTimeSpan)(noteOnDelay + noteOffDelay), TempoMap.Default), + }, + expectedReceivedEvents: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOffDelay) + new ReceivedEvent(new NoteOnEvent(noteNumber, noteOnVelocity), moveFrom), + new ReceivedEvent(new NoteOffEvent(noteNumber, noteOffVelocity), noteOnDelay + noteOffDelay - moveTo + moveFrom) }, - eventsWillBeSent: new[] + actions: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), moveFrom), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOnDelay + noteOffDelay - moveTo) + new PlaybackChangerBase(moveFrom, p => p.MoveToTime((MetricTimeSpan)moveTo)), }, - moveFrom: moveFrom, - moveTo: moveTo, notesWillBeStarted: new[] { 0 }, - notesWillBeFinished: new[] { 0 }, - useOutputDevice: useOutputDevice); + notesWillBeFinished: new[] { 0 }); } [Retry(RetriesNumber)] - [TestCase(true)] - [TestCase(false)] - public void TrackNotes_MoveBackToNote(bool useOutputDevice) + [Test] + public void TrackNotes_MoveBackToNote() { var noteNumber = (SevenBitNumber)60; var noteOnDelay = TimeSpan.Zero; @@ -57,32 +63,35 @@ public void TrackNotes_MoveBackToNote(bool useOutputDevice) var moveFrom = TimeSpan.FromSeconds(1); var moveTo = TimeSpan.FromMilliseconds(500); - CheckTrackNotes( - eventsToSend: new[] + CheckNotesTracking( + initialTimedObjects: new[] + { + new TimedEvent(new NoteOnEvent(noteNumber, noteOnVelocity)) + .SetTime((MetricTimeSpan)noteOnDelay, TempoMap.Default), + new TimedEvent(new NoteOffEvent(noteNumber, noteOffVelocity)) + .SetTime((MetricTimeSpan)(noteOnDelay + noteOffDelay), TempoMap.Default), + new TimedEvent(new PitchBendEvent()) + .SetTime((MetricTimeSpan)(noteOnDelay + noteOffDelay + pitchBendDelay), TempoMap.Default), + }, + actions: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOffDelay), - new EventToSend(new PitchBendEvent(), pitchBendDelay) + new PlaybackChangerBase(moveFrom, p => p.MoveToTime((MetricTimeSpan)moveTo)), }, - eventsWillBeSent: new[] + expectedReceivedEvents: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOffDelay), - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), moveFrom - (noteOnDelay + noteOffDelay)), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOnDelay + noteOffDelay - moveTo), - new EventToSend(new PitchBendEvent(), pitchBendDelay) + new ReceivedEvent(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), + new ReceivedEvent(new NoteOffEvent(noteNumber, noteOffVelocity), noteOnDelay + noteOffDelay), + new ReceivedEvent(new NoteOnEvent(noteNumber, noteOnVelocity), moveFrom), + new ReceivedEvent(new NoteOffEvent(noteNumber, noteOffVelocity), noteOnDelay + noteOffDelay - moveTo + moveFrom), + new ReceivedEvent(new PitchBendEvent(), noteOnDelay + noteOffDelay - moveTo + moveFrom + pitchBendDelay) }, - moveFrom: moveFrom, - moveTo: moveTo, notesWillBeStarted: new[] { 0, 0 }, - notesWillBeFinished: new[] { 0, 0 }, - useOutputDevice: useOutputDevice); + notesWillBeFinished: new[] { 0, 0 }); } [Retry(RetriesNumber)] - [TestCase(true)] - [TestCase(false)] - public void TrackNotes_MoveForwardFromNote(bool useOutputDevice) + [Test] + public void TrackNotes_MoveForwardFromNote() { var noteNumber = (SevenBitNumber)60; var noteOnDelay = TimeSpan.Zero; @@ -94,30 +103,33 @@ public void TrackNotes_MoveForwardFromNote(bool useOutputDevice) var moveFrom = TimeSpan.FromMilliseconds(500); var moveTo = TimeSpan.FromMilliseconds(1000); - CheckTrackNotes( - eventsToSend: new[] + CheckNotesTracking( + initialTimedObjects: new[] + { + new TimedEvent(new NoteOnEvent(noteNumber, noteOnVelocity)) + .SetTime((MetricTimeSpan)noteOnDelay, TempoMap.Default), + new TimedEvent(new NoteOffEvent(noteNumber, noteOffVelocity)) + .SetTime((MetricTimeSpan)(noteOnDelay + noteOffDelay), TempoMap.Default), + new TimedEvent(new PitchBendEvent()) + .SetTime((MetricTimeSpan)(noteOnDelay + noteOffDelay + pitchBendDelay), TempoMap.Default), + }, + actions: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOffDelay), - new EventToSend(new PitchBendEvent(), pitchBendDelay) + new PlaybackChangerBase(moveFrom, p => p.MoveToTime((MetricTimeSpan)moveTo)), }, - eventsWillBeSent: new[] + expectedReceivedEvents: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), moveFrom - noteOnDelay), - new EventToSend(new PitchBendEvent(), noteOnDelay + noteOffDelay + pitchBendDelay - moveTo) + new ReceivedEvent(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), + new ReceivedEvent(new NoteOffEvent(noteNumber, noteOffVelocity), moveFrom), + new ReceivedEvent(new PitchBendEvent(), noteOnDelay + noteOffDelay + pitchBendDelay - moveTo + moveFrom) }, - moveFrom: moveFrom, - moveTo: moveTo, notesWillBeStarted: new[] { 0 }, - notesWillBeFinished: new[] { 0 }, - useOutputDevice: useOutputDevice); + notesWillBeFinished: new[] { 0 }); } [Retry(RetriesNumber)] - [TestCase(true)] - [TestCase(false)] - public void TrackNotes_MoveBackFromNote(bool useOutputDevice) + [Test] + public void TrackNotes_MoveBackFromNote() { var noteNumber = (SevenBitNumber)60; var noteOnDelay = TimeSpan.FromSeconds(1); @@ -128,30 +140,32 @@ public void TrackNotes_MoveBackFromNote(bool useOutputDevice) var moveFrom = TimeSpan.FromMilliseconds(1200); var moveTo = TimeSpan.FromMilliseconds(700); - CheckTrackNotes( - eventsToSend: new[] + CheckNotesTracking( + initialTimedObjects: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOffDelay) + new TimedEvent(new NoteOnEvent(noteNumber, noteOnVelocity)) + .SetTime((MetricTimeSpan)noteOnDelay, TempoMap.Default), + new TimedEvent(new NoteOffEvent(noteNumber, noteOffVelocity)) + .SetTime((MetricTimeSpan)(noteOnDelay + noteOffDelay), TempoMap.Default), }, - eventsWillBeSent: new[] + actions: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), moveFrom - noteOnDelay), - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay - moveTo), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOffDelay) + new PlaybackChangerBase(moveFrom, p => p.MoveToTime((MetricTimeSpan)moveTo)), + }, + expectedReceivedEvents: new[] + { + new ReceivedEvent(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), + new ReceivedEvent(new NoteOffEvent(noteNumber, noteOffVelocity), moveFrom), + new ReceivedEvent(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay - moveTo + moveFrom), + new ReceivedEvent(new NoteOffEvent(noteNumber, noteOffVelocity), noteOffDelay + noteOnDelay - moveTo + moveFrom) }, - moveFrom: moveFrom, - moveTo: moveTo, notesWillBeStarted: new[] { 0, 0 }, - notesWillBeFinished: new[] { 0, 0 }, - useOutputDevice: useOutputDevice); + notesWillBeFinished: new[] { 0, 0 }); } [Retry(RetriesNumber)] - [TestCase(true)] - [TestCase(false)] - public void TrackNotes_MoveForwardToSameNote(bool useOutputDevice) + [Test] + public void TrackNotes_MoveForwardToSameNote() { var noteNumber = (SevenBitNumber)60; var noteOnDelay = TimeSpan.Zero; @@ -162,28 +176,30 @@ public void TrackNotes_MoveForwardToSameNote(bool useOutputDevice) var moveFrom = TimeSpan.FromMilliseconds(200); var moveTo = TimeSpan.FromMilliseconds(700); - CheckTrackNotes( - eventsToSend: new[] + CheckNotesTracking( + initialTimedObjects: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOffDelay) + new TimedEvent(new NoteOnEvent(noteNumber, noteOnVelocity)) + .SetTime((MetricTimeSpan)noteOnDelay, TempoMap.Default), + new TimedEvent(new NoteOffEvent(noteNumber, noteOffVelocity)) + .SetTime((MetricTimeSpan)(noteOnDelay + noteOffDelay), TempoMap.Default), }, - eventsWillBeSent: new[] + actions: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOnDelay + noteOffDelay - moveTo + moveFrom) + new PlaybackChangerBase(moveFrom, p => p.MoveToTime((MetricTimeSpan)moveTo)), + }, + expectedReceivedEvents: new[] + { + new ReceivedEvent(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), + new ReceivedEvent(new NoteOffEvent(noteNumber, noteOffVelocity), noteOnDelay + noteOnDelay + noteOffDelay - moveTo + moveFrom) }, - moveFrom: moveFrom, - moveTo: moveTo, notesWillBeStarted: new[] { 0 }, - notesWillBeFinished: new[] { 0 }, - useOutputDevice: useOutputDevice); + notesWillBeFinished: new[] { 0 }); } [Retry(RetriesNumber)] - [TestCase(true)] - [TestCase(false)] - public void TrackNotes_MoveBackToSameNote(bool useOutputDevice) + [Test] + public void TrackNotes_MoveBackToSameNote() { var noteNumber = (SevenBitNumber)60; var noteOnDelay = TimeSpan.Zero; @@ -194,28 +210,30 @@ public void TrackNotes_MoveBackToSameNote(bool useOutputDevice) var moveFrom = TimeSpan.FromMilliseconds(700); var moveTo = TimeSpan.FromMilliseconds(400); - CheckTrackNotes( - eventsToSend: new[] + CheckNotesTracking( + initialTimedObjects: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOffDelay) + new TimedEvent(new NoteOnEvent(noteNumber, noteOnVelocity)) + .SetTime((MetricTimeSpan)noteOnDelay, TempoMap.Default), + new TimedEvent(new NoteOffEvent(noteNumber, noteOffVelocity)) + .SetTime((MetricTimeSpan)(noteOnDelay + noteOffDelay), TempoMap.Default), }, - eventsWillBeSent: new[] + actions: new[] { - new EventToSend(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), - new EventToSend(new NoteOffEvent(noteNumber, noteOffVelocity), noteOnDelay + noteOffDelay - moveTo + moveFrom) + new PlaybackChangerBase(moveFrom, p => p.MoveToTime((MetricTimeSpan)moveTo)), + }, + expectedReceivedEvents: new[] + { + new ReceivedEvent(new NoteOnEvent(noteNumber, noteOnVelocity), noteOnDelay), + new ReceivedEvent(new NoteOffEvent(noteNumber, noteOffVelocity), noteOnDelay + noteOnDelay + noteOffDelay - moveTo + moveFrom) }, - moveFrom: moveFrom, - moveTo: moveTo, notesWillBeStarted: new[] { 0 }, - notesWillBeFinished: new[] { 0 }, - useOutputDevice: useOutputDevice); + notesWillBeFinished: new[] { 0 }); } [Retry(RetriesNumber)] - [TestCase(true)] - [TestCase(false)] - public void TrackNotes_MoveForwardFromNoteToNote(bool useOutputDevice) + [Test] + public void TrackNotes_MoveForwardFromNoteToNote() { var noteNumber1 = (SevenBitNumber)60; var noteOnDelay1 = TimeSpan.Zero; @@ -232,32 +250,36 @@ public void TrackNotes_MoveForwardFromNoteToNote(bool useOutputDevice) var moveFrom = TimeSpan.FromMilliseconds(500); var moveTo = TimeSpan.FromMilliseconds(1400); - CheckTrackNotes( - eventsToSend: new[] + CheckNotesTracking( + initialTimedObjects: new[] + { + new TimedEvent(new NoteOnEvent(noteNumber1, noteOnVelocity1)) + .SetTime((MetricTimeSpan)noteOnDelay1, TempoMap.Default), + new TimedEvent(new NoteOffEvent(noteNumber1, noteOffVelocity1)) + .SetTime((MetricTimeSpan)(noteOnDelay1 + noteOffDelay1), TempoMap.Default), + new TimedEvent(new NoteOnEvent(noteNumber2, noteOnVelocity2)) + .SetTime((MetricTimeSpan)(noteOnDelay1 + noteOffDelay1 + noteOnDelay2), TempoMap.Default), + new TimedEvent(new NoteOffEvent(noteNumber2, noteOffVelocity2)) + .SetTime((MetricTimeSpan)(noteOnDelay1 + noteOffDelay1 + noteOnDelay2 + noteOffDelay2), TempoMap.Default), + }, + actions: new[] { - new EventToSend(new NoteOnEvent(noteNumber1, noteOnVelocity1), noteOnDelay1), - new EventToSend(new NoteOffEvent(noteNumber1, noteOffVelocity1), noteOffDelay1), - new EventToSend(new NoteOnEvent(noteNumber2, noteOnVelocity2), noteOnDelay2), - new EventToSend(new NoteOffEvent(noteNumber2, noteOffVelocity2), noteOffDelay2) + new PlaybackChangerBase(moveFrom, p => p.MoveToTime((MetricTimeSpan)moveTo)), }, - eventsWillBeSent: new[] + expectedReceivedEvents: new[] { - new EventToSend(new NoteOnEvent(noteNumber1, noteOnVelocity1), noteOnDelay1), - new EventToSend(new NoteOffEvent(noteNumber1, noteOffVelocity1), moveFrom), - new EventToSend(new NoteOnEvent(noteNumber2, noteOnVelocity2), TimeSpan.Zero), - new EventToSend(new NoteOffEvent(noteNumber2, noteOffVelocity2), noteOnDelay1 + noteOffDelay1 + noteOnDelay2 + noteOffDelay2 - moveTo) + new ReceivedEvent(new NoteOnEvent(noteNumber1, noteOnVelocity1), noteOnDelay1), + new ReceivedEvent(new NoteOffEvent(noteNumber1, noteOffVelocity1), noteOnDelay1 + moveFrom), + new ReceivedEvent(new NoteOnEvent(noteNumber2, noteOnVelocity2), noteOnDelay1 + moveFrom), + new ReceivedEvent(new NoteOffEvent(noteNumber2, noteOffVelocity2), noteOnDelay1 + moveFrom + noteOnDelay1 + noteOffDelay1 + noteOnDelay2 + noteOffDelay2 - moveTo) }, - moveFrom: moveFrom, - moveTo: moveTo, notesWillBeStarted: new[] { 0, 1 }, - notesWillBeFinished: new[] { 0, 1 }, - useOutputDevice: useOutputDevice); + notesWillBeFinished: new[] { 0, 1 }); } [Retry(RetriesNumber)] - [TestCase(true)] - [TestCase(false)] - public void TrackNotes_MoveBackFromNoteToNote(bool useOutputDevice) + [Test] + public void TrackNotes_MoveBackFromNoteToNote() { var noteNumber1 = (SevenBitNumber)60; var noteOnDelay1 = TimeSpan.Zero; @@ -274,30 +296,35 @@ public void TrackNotes_MoveBackFromNoteToNote(bool useOutputDevice) var moveFrom = TimeSpan.FromMilliseconds(1400); var moveTo = TimeSpan.FromMilliseconds(500); - CheckTrackNotes( - eventsToSend: new[] + CheckNotesTracking( + initialTimedObjects: new[] { - new EventToSend(new NoteOnEvent(noteNumber1, noteOnVelocity1), noteOnDelay1), - new EventToSend(new NoteOffEvent(noteNumber1, noteOffVelocity1), noteOffDelay1), - new EventToSend(new NoteOnEvent(noteNumber2, noteOnVelocity2), noteOnDelay2), - new EventToSend(new NoteOffEvent(noteNumber2, noteOffVelocity2), noteOffDelay2) + new TimedEvent(new NoteOnEvent(noteNumber1, noteOnVelocity1)) + .SetTime((MetricTimeSpan)noteOnDelay1, TempoMap.Default), + new TimedEvent(new NoteOffEvent(noteNumber1, noteOffVelocity1)) + .SetTime((MetricTimeSpan)(noteOnDelay1 + noteOffDelay1), TempoMap.Default), + new TimedEvent(new NoteOnEvent(noteNumber2, noteOnVelocity2)) + .SetTime((MetricTimeSpan)(noteOnDelay1 + noteOffDelay1 + noteOnDelay2), TempoMap.Default), + new TimedEvent(new NoteOffEvent(noteNumber2, noteOffVelocity2)) + .SetTime((MetricTimeSpan)(noteOnDelay1 + noteOffDelay1 + noteOnDelay2 + noteOffDelay2), TempoMap.Default), }, - eventsWillBeSent: new[] - { - new EventToSend(new NoteOnEvent(noteNumber1, noteOnVelocity1), noteOnDelay1), - new EventToSend(new NoteOffEvent(noteNumber1, noteOffVelocity1), noteOffDelay1), - new EventToSend(new NoteOnEvent(noteNumber2, noteOnVelocity2), noteOnDelay2), - new EventToSend(new NoteOffEvent(noteNumber2, noteOffVelocity2), moveFrom - (noteOnDelay1 + noteOffDelay1 + noteOnDelay2)), - new EventToSend(new NoteOnEvent(noteNumber1, noteOnVelocity1), TimeSpan.Zero), - new EventToSend(new NoteOffEvent(noteNumber1, noteOffVelocity1), noteOnDelay1 + noteOffDelay1 - moveTo), - new EventToSend(new NoteOnEvent(noteNumber2, noteOnVelocity2), noteOnDelay2), - new EventToSend(new NoteOffEvent(noteNumber2, noteOffVelocity2), noteOffDelay2) + actions: new[] + { + new PlaybackChangerBase(moveFrom, p => p.MoveToTime((MetricTimeSpan)moveTo)), + }, + expectedReceivedEvents: new[] + { + new ReceivedEvent(new NoteOnEvent(noteNumber1, noteOnVelocity1), noteOnDelay1), + new ReceivedEvent(new NoteOffEvent(noteNumber1, noteOffVelocity1), noteOnDelay1 + noteOffDelay1), + new ReceivedEvent(new NoteOnEvent(noteNumber2, noteOnVelocity2), noteOnDelay1 + noteOffDelay1 + noteOnDelay2), + new ReceivedEvent(new NoteOffEvent(noteNumber2, noteOffVelocity2), moveFrom), + new ReceivedEvent(new NoteOnEvent(noteNumber1, noteOnVelocity1), moveFrom), + new ReceivedEvent(new NoteOffEvent(noteNumber1, noteOffVelocity1), noteOnDelay1 + noteOffDelay1 - moveTo + moveFrom), + new ReceivedEvent(new NoteOnEvent(noteNumber2, noteOnVelocity2), noteOnDelay1 + noteOffDelay1 - moveTo + moveFrom + noteOnDelay2), + new ReceivedEvent(new NoteOffEvent(noteNumber2, noteOffVelocity2), noteOnDelay1 + noteOffDelay1 - moveTo + moveFrom + noteOnDelay2 + noteOffDelay2) }, - moveFrom: moveFrom, - moveTo: moveTo, notesWillBeStarted: new[] { 0, 1, 0, 1 }, - notesWillBeFinished: new[] { 0, 1, 0, 1 }, - useOutputDevice: useOutputDevice); + notesWillBeFinished: new[] { 0, 1, 0, 1 }); } [Retry(RetriesNumber)] @@ -310,29 +337,32 @@ public void TrackNotes_StopStart_InterruptNotesOnStop() var stopAfter = TimeSpan.FromSeconds(1); var stopPeriod = TimeSpan.Zero; - CheckPlaybackStop( - eventsToSend: new[] + CheckPlayback( + useOutputDevice: false, + initialPlaybackObjects: new[] + { + new TimedEvent(new NoteOnEvent()) + .SetTime((MetricTimeSpan)noteOnDelay, TempoMap.Default), + new TimedEvent(new NoteOffEvent()) + .SetTime((MetricTimeSpan)(noteOnDelay + noteOffDelay), TempoMap.Default), + }, + actions: new[] { - new EventToSend(new NoteOnEvent(), noteOnDelay), - new EventToSend(new NoteOffEvent(), noteOffDelay) + new PlaybackChangerBase(stopAfter, p => p.Stop()), + new PlaybackChangerBase(stopPeriod, p => p.Start()), }, - eventsWillBeSent: new[] + expectedReceivedEvents: new[] { - new EventToSend(new NoteOnEvent(), noteOnDelay), - new EventToSend(new NoteOffEvent(), stopAfter), - new EventToSend(new NoteOnEvent(), TimeSpan.Zero), - new EventToSend(new NoteOffEvent(), noteOnDelay + noteOffDelay - stopAfter) + new ReceivedEvent(new NoteOnEvent(), noteOnDelay), + new ReceivedEvent(new NoteOffEvent(), noteOnDelay + stopAfter), + new ReceivedEvent(new NoteOnEvent(), noteOnDelay + stopAfter), + new ReceivedEvent(new NoteOffEvent(), noteOnDelay + noteOffDelay + noteOnDelay) }, - stopAfter: stopAfter, - stopPeriod: stopPeriod, - setupPlayback: (context, playback) => + setupPlayback: playback => { playback.InterruptNotesOnStop = true; playback.TrackNotes = true; - }, - afterStart: NoPlaybackAction, - afterStop: NoPlaybackAction, - afterResume: NoPlaybackAction); + }); } [Retry(RetriesNumber)] @@ -345,27 +375,64 @@ public void TrackNotes_StopStart_DontInterruptNotesOnStop() var stopAfter = TimeSpan.FromSeconds(1); var stopPeriod = TimeSpan.Zero; - CheckPlaybackStop( - eventsToSend: new[] + CheckPlayback( + useOutputDevice: false, + initialPlaybackObjects: new[] { - new EventToSend(new NoteOnEvent(), noteOnDelay), - new EventToSend(new NoteOffEvent(), noteOffDelay) + new TimedEvent(new NoteOnEvent()) + .SetTime((MetricTimeSpan)noteOnDelay, TempoMap.Default), + new TimedEvent(new NoteOffEvent()) + .SetTime((MetricTimeSpan)(noteOnDelay + noteOffDelay), TempoMap.Default), }, - eventsWillBeSent: new[] + actions: new[] { - new EventToSend(new NoteOnEvent(), noteOnDelay), - new EventToSend(new NoteOffEvent(), noteOffDelay) + new PlaybackChangerBase(stopAfter, p => p.Stop()), + new PlaybackChangerBase(stopPeriod, p => p.Start()), }, - stopAfter: stopAfter, - stopPeriod: stopPeriod, - setupPlayback: (context, playback) => + expectedReceivedEvents: new[] + { + new ReceivedEvent(new NoteOnEvent(), noteOnDelay), + new ReceivedEvent(new NoteOffEvent(), noteOnDelay + noteOffDelay), + }, + setupPlayback: playback => { playback.InterruptNotesOnStop = false; playback.TrackNotes = true; - }, - afterStart: NoPlaybackAction, - afterStop: NoPlaybackAction, - afterResume: NoPlaybackAction); + }); + } + + #endregion + + #region Private methods + + private void CheckNotesTracking( + ITimedObject[] initialTimedObjects, + PlaybackChangerBase[] actions, + ICollection expectedReceivedEvents, + IEnumerable notesWillBeStarted, + IEnumerable notesWillBeFinished, + Action setupPlayback = null) + { + var notes = initialTimedObjects.GetObjects(ObjectType.Note).Cast().ToArray(); + var notesStarted = new List(); + var notesFinished = new List(); + + CheckPlayback( + useOutputDevice: false, + initialPlaybackObjects: initialTimedObjects, + actions: actions, + expectedReceivedEvents: expectedReceivedEvents, + setupPlayback: playback => + { + setupPlayback?.Invoke(playback); + + playback.TrackNotes = true; + playback.NotesPlaybackStarted += (_, e) => notesStarted.AddRange(e.Notes); + playback.NotesPlaybackFinished += (_, e) => notesFinished.AddRange(e.Notes); + }); + + MidiAsserts.AreEqual(notesStarted, notesWillBeStarted.Select(i => notes[i]), "Invalid notes started."); + MidiAsserts.AreEqual(notesFinished, notesWillBeFinished.Select(i => notes[i]), "Invalid notes finished."); } #endregion diff --git a/DryWetMidi/Multimedia/Playback/Playback.cs b/DryWetMidi/Multimedia/Playback/Playback.cs index 7e730a55b..cefa462b7 100644 --- a/DryWetMidi/Multimedia/Playback/Playback.cs +++ b/DryWetMidi/Multimedia/Playback/Playback.cs @@ -223,21 +223,21 @@ public Playback(IEnumerable timedObjects, TempoMap tempoMap, IOutp /// /// Gets or sets a value indicating whether currently playing notes must be stopped - /// on playback stop or not. + /// on playback stop or not. The default value is true. /// public bool InterruptNotesOnStop { get; set; } = true; /// /// Gets or sets a value indicating whether notes must be tracked or not. If false, notes - /// will be treated as just Note On/Note Off events. The default value is false. More info in the + /// will be treated as just Note On/Note Off events. The default value is true. More info in the /// Data tracking: Notes tracking article. /// - public bool TrackNotes { get; set; } + public bool TrackNotes { get; set; } = true; /// /// Gets or sets a value indicating whether program must be tracked or not. If true, any jump /// in time will force playback send corresponding to the program at new time, - /// if needed. The default value is false. More info in the + /// if needed. The default value is true. More info in the /// Data tracking: MIDI parameters values tracking /// article. /// @@ -259,7 +259,7 @@ public bool TrackProgram /// /// Gets or sets a value indicating whether pitch value must be tracked or not. If true, any jump /// in time will force playback send corresponding to the pitch value at new time, - /// if needed. The default value is false. More info in the + /// if needed. The default value is true. More info in the /// Data tracking: MIDI parameters values tracking /// article. /// @@ -281,7 +281,7 @@ public bool TrackPitchValue /// /// Gets or sets a value indicating whether controller values must be tracked or not. If true, any jump /// in time will force playback send corresponding to the controller value at new time, - /// if needed. The default value is false. More info in the + /// if needed. The default value is true. More info in the /// Data tracking: MIDI parameters values tracking /// article. ///