Skip to content

Commit

Permalink
Track control value by default in Playback
Browse files Browse the repository at this point in the history
  • Loading branch information
melanchall committed Jan 22, 2025
1 parent 749c7b7 commit 0026090
Show file tree
Hide file tree
Showing 4 changed files with 725 additions and 415 deletions.
142 changes: 0 additions & 142 deletions DryWetMidi.Tests/Multimedia/Playback/PlaybackTests.Asserts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -629,148 +629,6 @@ private void CheckPlaybackStop(
CompareReceivedEvents(playedEvents, expectedPlayedEvents.ToList());
}

private void CheckDataTracking(
Action<Playback> setupTracking,
ICollection<EventToSend> eventsToSend,
ICollection<EventToSend> eventsWillBeSent,
TimeSpan moveFrom,
TimeSpan moveTo,
bool useOutputDevice,
TimeSpan? afterMovePause = null,
Action<Playback> afterMovePlaybackAction = null)
{
if (useOutputDevice)
CheckDataTrackingWithOutputDevice(setupTracking, eventsToSend, eventsWillBeSent, moveFrom, moveTo, afterMovePause, afterMovePlaybackAction);
else
CheckDataTrackingWithoutOutputDevice(setupTracking, eventsToSend, eventsWillBeSent, moveFrom, moveTo, afterMovePause, afterMovePlaybackAction);
}

private void CheckDataTrackingWithOutputDevice(
Action<Playback> setupTracking,
ICollection<EventToSend> eventsToSend,
ICollection<EventToSend> eventsWillBeSent,
TimeSpan moveFrom,
TimeSpan moveTo,
TimeSpan? afterMovePause = null,
Action<Playback> afterMovePlaybackAction = null)
{
var playbackContext = new PlaybackContext();

var receivedEvents = playbackContext.ReceivedEvents;
var sentEvents = playbackContext.SentEvents;
var stopwatch = playbackContext.Stopwatch;
var tempoMap = playbackContext.TempoMap;

var eventsForPlayback = GetEventsForPlayback(eventsToSend, tempoMap);
var notes = eventsForPlayback.GetNotes().ToArray();

using (var outputDevice = OutputDevice.GetByName(SendReceiveUtilities.DeviceToTestOnName))
{
SendReceiveUtilities.WarmUpDevice(outputDevice);
outputDevice.EventSent += (_, e) => sentEvents.Add(new SentEvent(e.Event, stopwatch.Elapsed));

using (var playback = eventsForPlayback.GetPlayback(tempoMap, outputDevice))
{
setupTracking(playback);

using (var inputDevice = InputDevice.GetByName(SendReceiveUtilities.DeviceToTestOnName))
{
inputDevice.EventReceived += (_, e) =>
{
lock (playbackContext.ReceivedEventsLockObject)
{
receivedEvents.Add(new ReceivedEvent(e.Event, stopwatch.Elapsed));
}
};
inputDevice.StartEventsListening();
stopwatch.Start();
playback.Start();

WaitOperations.Wait(() => stopwatch.Elapsed >= moveFrom);
playback.MoveToTime((MetricTimeSpan)moveTo);

if (afterMovePause != null)
{
var currentElapsed = stopwatch.Elapsed;
WaitOperations.Wait(() => stopwatch.Elapsed >= currentElapsed + afterMovePause);

afterMovePlaybackAction(playback);
}

var timeout = TimeSpan.FromTicks(eventsWillBeSent.Sum(e => e.Delay.Ticks)) + SendReceiveUtilities.MaximumEventSendReceiveDelay;
var areEventsReceived = WaitOperations.Wait(() => receivedEvents.Count == eventsWillBeSent.Count, timeout);
Assert.IsTrue(areEventsReceived, $"Events are not received for timeout {timeout}.");

stopwatch.Stop();

var playbackStopped = WaitOperations.Wait(() => !playback.IsRunning, SendReceiveUtilities.MaximumEventSendReceiveDelay);
Assert.IsTrue(playbackStopped, "Playback is running after completed.");
}
}
}

CompareSentReceivedEvents(sentEvents, receivedEvents, eventsWillBeSent.ToList());
}

private void CheckDataTrackingWithoutOutputDevice(
Action<Playback> setupTracking,
ICollection<EventToSend> eventsToSend,
ICollection<EventToSend> eventsWillBeSent,
TimeSpan moveFrom,
TimeSpan moveTo,
TimeSpan? afterMovePause = null,
Action<Playback> afterMovePlaybackAction = null)
{
var playbackContext = new PlaybackContext();

var receivedEvents = playbackContext.ReceivedEvents;
var sentEvents = playbackContext.SentEvents;
var stopwatch = playbackContext.Stopwatch;
var tempoMap = playbackContext.TempoMap;

var eventsForPlayback = GetEventsForPlayback(eventsToSend, tempoMap);
var notes = eventsForPlayback.GetNotes().ToArray();

using (var playback = eventsForPlayback.GetPlayback(tempoMap))
{
setupTracking(playback);

playback.EventPlayed += (_, e) =>
{
lock (playbackContext.ReceivedEventsLockObject)
{
receivedEvents.Add(new ReceivedEvent(e.Event, stopwatch.Elapsed));
sentEvents.Add(new SentEvent(e.Event, stopwatch.Elapsed));
}
};

stopwatch.Start();
playback.Start();

WaitOperations.Wait(() => stopwatch.Elapsed >= moveFrom);
playback.MoveToTime((MetricTimeSpan)moveTo);

if (afterMovePause != null)
{
var currentElapsed = stopwatch.Elapsed;
WaitOperations.Wait(() => stopwatch.Elapsed >= currentElapsed + afterMovePause);

afterMovePlaybackAction(playback);
}

var timeout = TimeSpan.FromTicks(eventsWillBeSent.Sum(e => e.Delay.Ticks)) + SendReceiveUtilities.MaximumEventSendReceiveDelay;
var areEventsReceived = WaitOperations.Wait(() => receivedEvents.Count == eventsWillBeSent.Count, timeout);
Assert.IsTrue(areEventsReceived, $"Events are not received for timeout {timeout}.");

stopwatch.Stop();

var playbackStopped = WaitOperations.Wait(() => !playback.IsRunning, SendReceiveUtilities.MaximumEventSendReceiveDelay);
Assert.IsTrue(playbackStopped, "Playback is running after completed.");
}

CompareSentReceivedEvents(sentEvents, receivedEvents, eventsWillBeSent.ToList());
}

private static IEnumerable<MidiEvent> GetEventsForPlayback(IEnumerable<EventToSend> eventsToSend, TempoMap tempoMap)
{
var eventsForPlayback = new List<MidiEvent>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,8 @@ public void CheckPlaybackDataChangesOnTheFly_AddAndRemoveAtAdvanceByOne(
[Values(0, 10)] int gapMs,
[Values] bool viaChangeCollection)
{
var noteLengthMs = 20;
var lastEventTime = notesCount * noteLengthMs + 20 + notesCount * gapMs;
var noteLengthMs = 40;
var lastEventTime = notesCount * noteLengthMs + 40 + notesCount * gapMs;

var initialObjects = new ITimedObject[]
{
Expand All @@ -382,7 +382,7 @@ public void CheckPlaybackDataChangesOnTheFly_AddAndRemoveAtAdvanceByOne(
.Values
.Take(notesCount)
.Select(n => new Note(n)
.SetTime(new MetricTimeSpan(0, 0, 0, n * noteLengthMs + 10 + n * gapMs), OnTheFlyChecksTempoMap)
.SetTime(new MetricTimeSpan(0, 0, 0, n * noteLengthMs + 20 + n * gapMs), OnTheFlyChecksTempoMap)
.SetLength(new MetricTimeSpan(0, 0, 0, noteLengthMs), OnTheFlyChecksTempoMap))
.ToArray();

Expand Down
Loading

0 comments on commit 0026090

Please sign in to comment.