Skip to content

Commit

Permalink
Discard high resolution timer request on playback stop #106
Browse files Browse the repository at this point in the history
  • Loading branch information
melanchall committed Dec 19, 2020
1 parent 81c0354 commit 1882141
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 15 deletions.
61 changes: 58 additions & 3 deletions DryWetMidi.Tests/Devices/Playback/PlaybackTests.TickGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
using Melanchall.DryWetMidi.Core;
using NUnit.Framework;
using System.Diagnostics;
using Melanchall.DryWetMidi.Interaction;
using System.IO;
using Melanchall.DryWetMidi.Tests.Common;

namespace Melanchall.DryWetMidi.Tests.Devices
{
Expand All @@ -22,9 +25,6 @@ private sealed class ThreadTickGenerator : TickGenerator

protected override void Start(TimeSpan interval)
{
if (_thread != null)
return;

_thread = new Thread(() =>
{
var stopwatch = new Stopwatch();
Expand All @@ -47,6 +47,11 @@ protected override void Start(TimeSpan interval)
_thread.Start();
}

protected override void Stop()
{
_isRunning = false;
}

protected override void Dispose(bool disposing)
{
if (_disposed)
Expand All @@ -72,6 +77,32 @@ public void CheckPlayback_HighPrecisionTickGenerator()
CheckPlayback_TickGenerator(() => new HighPrecisionTickGenerator(), TimeSpan.FromMilliseconds(30));
}

[Retry(RetriesNumber)]
[Test]
public void CheckPlayback_HighPrecisionTickGenerator_DiscardResolutionIncreasingOnStop()
{
var processId = Process.GetCurrentProcess().Id;

using (var playback = new Playback(new MidiEvent[] { new NoteOnEvent(), new NoteOffEvent { DeltaTime = 100000 } }, TempoMap.Default))
{
Assert.IsFalse(IsProcessIdInPowerCfgReport(processId), "Process ID is in PowerCfg report before playback started.");

playback.Start();
Assert.IsTrue(IsProcessIdInPowerCfgReport(processId), "Process ID isn't in PowerCfg report after playback started.");

playback.Stop();
Assert.IsFalse(IsProcessIdInPowerCfgReport(processId), "Process ID is in PowerCfg report after playback stopped.");

playback.Start();
Assert.IsTrue(IsProcessIdInPowerCfgReport(processId), "Process ID isn't in PowerCfg report after playback started again.");

playback.Stop();
Assert.IsFalse(IsProcessIdInPowerCfgReport(processId), "Process ID is in PowerCfg report after playback stopped again.");
}

Assert.IsFalse(IsProcessIdInPowerCfgReport(processId), "Process ID is in PowerCfg report after playback disposed.");
}

[Retry(RetriesNumber)]
[Test]
public void CheckPlayback_RegularPrecisionTickGenerator()
Expand Down Expand Up @@ -143,6 +174,30 @@ public void CheckPlayback_ManualTicking()

#region Private methods

private bool IsProcessIdInPowerCfgReport(int processId)
{
var reportFilePath = Path.Combine(Path.GetTempPath(), "powercfg_report.html");

try
{
var process = Process.Start(new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/C powercfg /energy /output \"{reportFilePath}\" /duration 3"
});
Assert.IsNotNull(process, "PowerCfg process is null.");

process.WaitForExit();

var report = FileOperations.ReadAllFileText(reportFilePath);
return report.Contains(processId.ToString());
}
finally
{
FileOperations.DeleteFile(reportFilePath);
}
}

private void CheckPlayback_TickGenerator(Func<TickGenerator> createTickGeneratorCallback, TimeSpan maximumEventSendReceiveDelay)
{
var eventsToSend = new[]
Expand Down
14 changes: 7 additions & 7 deletions DryWetMidi/Devices/Clock/MidiClock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ public sealed class MidiClock : IDisposable

private double _speed = DefaultSpeed;

private bool _started;

private readonly TickGenerator _tickGenerator;

#endregion
Expand Down Expand Up @@ -136,15 +134,11 @@ public void Start()
if (IsRunning)
return;

if (!_started)
_tickGenerator?.TryStart(Interval);

_tickGenerator?.TryStart(Interval);
_stopwatch.Start();

if (_startImmediately)
OnTicked();

_started = true;
}

/// <summary>
Expand All @@ -156,6 +150,7 @@ public void Stop()
EnsureIsNotDisposed();

_stopwatch.Stop();
_tickGenerator?.TryStop();
}

/// <summary>
Expand Down Expand Up @@ -208,6 +203,11 @@ public void Tick()
OnTicked();
}

internal void StopShortly()
{
_stopwatch.Stop();
}

private void OnTickGenerated(object sender, EventArgs e)
{
Tick();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ protected override void Start(TimeSpan interval)
}
}

protected override void Stop()
{
MidiTimerWinApi.timeEndPeriod(_resolution);
MidiTimerWinApi.timeKillEvent(_timerId);
}

#endregion

#region Methods
Expand Down Expand Up @@ -130,10 +136,7 @@ protected override void Dispose(bool disposing)
}

if (IsRunning)
{
MidiTimerWinApi.timeEndPeriod(_resolution);
MidiTimerWinApi.timeKillEvent(_timerId);
}
Stop();

_disposed = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ protected override void Start(TimeSpan interval)
_timer.Start();
}

protected override void Stop()
{
_timer.Stop();
}

#endregion

#region Methods
Expand Down
11 changes: 11 additions & 0 deletions DryWetMidi/Devices/Clock/TickGenerator/TickGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ internal void TryStart(TimeSpan interval)
IsRunning = true;
}

internal void TryStop()
{
if (!IsRunning)
return;

Stop();
IsRunning = false;
}

/// <summary>
/// Generates a tick firing the <see cref="TickGenerated"/> event.
/// </summary>
Expand All @@ -47,6 +56,8 @@ protected void GenerateTick()
/// <param name="interval">Interval between ticks.</param>
protected abstract void Start(TimeSpan interval);

protected abstract void Stop();

#endregion

#region IDisposable
Expand Down
2 changes: 1 addition & 1 deletion DryWetMidi/Devices/Playback/Playback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ private void OnClockTicked(object sender, EventArgs e)
return;
}

_clock.Stop();
_clock.StopShortly();
_clock.ResetCurrentTime();
_eventsEnumerator.Reset();
_eventsEnumerator.MoveNext();
Expand Down

0 comments on commit 1882141

Please sign in to comment.