-
Notifications
You must be signed in to change notification settings - Fork 2
/
AudioPlaybackEngine.cs
117 lines (95 loc) · 3.66 KB
/
AudioPlaybackEngine.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System;
using System.Collections.Generic;
using NAudio.Wave;
using NAudio.Wave.SampleProviders;
using System.Linq;
using System.Windows.Forms;
namespace AudioHotkeySoundboard
{
class AudioPlaybackEngine : IDisposable
{
public static readonly AudioPlaybackEngine Primary = new AudioPlaybackEngine(44100, 2);
public static readonly AudioPlaybackEngine Secondary = new AudioPlaybackEngine(44100, 2);
private IWavePlayer outputDevice;
private readonly MixingSampleProvider mixer;
public static IDictionary<string, CachedSound> cachedSounds = new Dictionary<string, CachedSound>();
public AudioPlaybackEngine(int sampleRate = 44100, int channelCount = 2)
{
mixer = new MixingSampleProvider(WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channelCount));
mixer.ReadFully = true;
mixer.MixerInputEnded += OnMixerInputEnded;
}
public event EventHandler AllInputEnded;
private void OnMixerInputEnded(object sender, SampleProviderEventArgs e)
{
// check if there are any inputs left
// OnMixerInputEnded gets invoked before the corresponding source is removed from the List so there should be exactly one source left
if (mixer.MixerInputs.Count() == 1)
{
AllInputEnded?.Invoke(this, EventArgs.Empty);
}
}
public void Init(int deviceNumber)
{
if (outputDevice != null) outputDevice.Dispose();
WaveOutEvent output = new WaveOutEvent();
output.DeviceNumber = deviceNumber;
output.Init(mixer);
output.Play();
outputDevice = output;
}
public void PlaySound(string fileName)
{
//AudioFileReader input = new AudioFileReader(fileName);
// potentially useless?
CachedSound cachedSound = null;
if (!cachedSounds.TryGetValue(fileName, out cachedSound))
{
cachedSound = new CachedSound(fileName);
cachedSounds.Add(fileName, cachedSound);
}
PlaySound(cachedSound);
}
public void PlaySound(CachedSound sound)
{
AddMixerInput(new CachedSoundSampleProvider(sound));
}
public void StopAllSounds()
{
mixer.RemoveAllMixerInputs();
}
private ISampleProvider ConvertToRightChannelCount(ISampleProvider input)
{
MainForm mainForm = Application.OpenForms[0] as MainForm;
float boost = mainForm.GetGain();
if (boost != 0f)
{
var boostedInput = new BoostedSampleProvider(input);
boostedInput.boost = mainForm.GetGain();
input = boostedInput;
}
if (input.WaveFormat.Channels == mixer.WaveFormat.Channels)
{
return input;
}
if (input.WaveFormat.Channels == 1 && mixer.WaveFormat.Channels == 2)
{
return new MonoToStereoSampleProvider(input);
}
throw new NotImplementedException("Not yet implemented this channel count conversion");
}
private void AddMixerInput(ISampleProvider input)
{
var resampled = new WdlResamplingSampleProvider(input, mixer.WaveFormat.SampleRate);
mixer.AddMixerInput(ConvertToRightChannelCount(resampled));
}
public void Dispose()
{
if (outputDevice != null)
{
outputDevice.Dispose();
outputDevice = null;
}
}
}
}