Skip to content

Commit

Permalink
fix(Banner): Problem with sound not playing correctly
Browse files Browse the repository at this point in the history
Sometimes the sound wouldn't get to the right device
  • Loading branch information
Belphemur committed Apr 10, 2021
1 parent 889bf40 commit ce90164
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 40 deletions.
15 changes: 9 additions & 6 deletions SoundSwitch/Framework/Banner/BannerData.cs
Expand Up @@ -12,13 +12,9 @@
* GNU General Public License for more details.
********************************************************************/

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NAudio.CoreAudioApi;
using SoundSwitch.Framework.Audio;

namespace SoundSwitch.Framework.Banner
Expand Down Expand Up @@ -46,7 +42,14 @@ public class BannerData
/// <summary>
/// Gets/sets the path for a wav sound to be playedc during the notification, this is optional.
/// </summary>
[AllowNull]
public CachedSound SoundFile { get; internal set; }

/// <summary>
/// On what device to play the <see cref="CachedSound"/>
/// </summary>
[AllowNull]
public MMDevice CurrentDevice { get; internal set; }

/// <summary>
/// Set the priority of the notification
Expand Down
13 changes: 0 additions & 13 deletions SoundSwitch/Framework/Banner/BannerForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 31 additions & 21 deletions SoundSwitch/Framework/Banner/BannerForm.cs
Expand Up @@ -17,6 +17,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using NAudio.CoreAudioApi;
using NAudio.Wave;
using SoundSwitch.Framework.Audio;
using SoundSwitch.Model;
Expand All @@ -32,9 +33,7 @@ public partial class BannerForm : Form
private Timer _timerHide;
private bool _hiding;
private BannerData _currentData;


private WasapiOut _player;
private CancellationTokenSource _cancellationTokenSource = new();

/// <summary>
/// Constructor for the <see cref="BannerForm"/> class
Expand Down Expand Up @@ -113,33 +112,44 @@ internal void SetData(BannerData data)
/// <param name="data"></param>
private void PrepareSound(BannerData data)
{
_player = new WasapiOut();
var task = new Task(() =>
{
using var waveStream = new CachedSoundWaveStream(data.SoundFile);
_player.Init(waveStream);
_player.Play();
while (_player.PlaybackState == PlaybackState.Playing)
{
Thread.Sleep(500);
}
});
task.Start();
var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenSource.Token);
Task.Factory.StartNew(async () => {
using var player = data.CurrentDevice == null ? new WasapiOut() : new WasapiOut(data.CurrentDevice, AudioClientShareMode.Shared, true, 200);
await using var waveStream = new CachedSoundWaveStream(data.SoundFile);
player.Init(waveStream);
player.PlaybackStopped += (_, _) => cancellationTokenSource.Cancel();
player.Play();
await Task.Delay(-1, cancellationTokenSource.Token);
}, cancellationTokenSource.Token);
}

/// <summary>
/// Destroy current sound player (if any)
/// </summary>
private void DestroySound()
{
if (_player != null)
_cancellationTokenSource.Cancel();
_cancellationTokenSource.Dispose();
_cancellationTokenSource = new();
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
_player.Stop();
_player.Dispose();
_player = null;
_timerHide?.Dispose();
_cancellationTokenSource?.Dispose();
components?.Dispose();
}

base.Dispose(disposing);
}


/// <summary>
/// Event handler for the "hiding" timer.
Expand Down Expand Up @@ -176,4 +186,4 @@ private async void FadeOut()
}
}
}
}
}
Expand Up @@ -89,6 +89,7 @@ public void NotifyDefaultChanged(MMDevice audioDevice)
if (Configuration.CustomSound != null && File.Exists(Configuration.CustomSound.FilePath))
{
toastData.SoundFile = Configuration.CustomSound;
toastData.CurrentDevice = audioDevice;
}

toastData.Title = audioDevice.DataFlow switch
Expand Down

0 comments on commit ce90164

Please sign in to comment.