-
Notifications
You must be signed in to change notification settings - Fork 1
/
VolumeMixer.cs
145 lines (130 loc) · 6.72 KB
/
VolumeMixer.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using CSCore.CoreAudioAPI;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace Audio_Dynamic_Range_Compressor
{
class VolumeMixer : VolumeMeterReader
{
public VolumeMixer(int memory) : base(memory)
{}
[ComImport]
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDeviceEnumerator
{
void _VtblGap1_1();
int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice ppDevice);
}
private static class MMDeviceEnumeratorFactory
{
public static IMMDeviceEnumerator CreateInstance()
{
return (IMMDeviceEnumerator)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"))); // a MMDeviceEnumerator
}
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDevice
{
int Activate([MarshalAs(UnmanagedType.LPStruct)] Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
}
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioEndpointVolume
{
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE RegisterControlChangeNotify(/* [in] */__in IAudioEndpointVolumeCallback *pNotify) = 0;
int RegisterControlChangeNotify(IntPtr pNotify);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UnregisterControlChangeNotify(/* [in] */ __in IAudioEndpointVolumeCallback *pNotify) = 0;
int UnregisterControlChangeNotify(IntPtr pNotify);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetChannelCount(/* [out] */ __out UINT *pnChannelCount) = 0;
int GetChannelCount(ref uint pnChannelCount);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMasterVolumeLevel( /* [in] */ __in float fLevelDB,/* [unique][in] */ LPCGUID pguidEventContext) = 0;
int SetMasterVolumeLevel(float fLevelDB, Guid pguidEventContext);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMasterVolumeLevelScalar( /* [in] */ __in float fLevel,/* [unique][in] */ LPCGUID pguidEventContext) = 0;
int SetMasterVolumeLevelScalar(float fLevel, Guid pguidEventContext);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMasterVolumeLevel(/* [out] */ __out float *pfLevelDB) = 0;
int GetMasterVolumeLevel(ref float pfLevelDB);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMasterVolumeLevelScalar( /* [out] */ __out float *pfLevel) = 0;
int GetMasterVolumeLevelScalar(ref float pfLevel);
}
public static void SetVol(int Level)
{
try
{
IMMDeviceEnumerator deviceEnumerator = MMDeviceEnumeratorFactory.CreateInstance();
IMMDevice speakers;
const int eRender = 0;
const int eMultimedia = 1;
deviceEnumerator.GetDefaultAudioEndpoint(eRender, eMultimedia, out speakers);
object aepv_obj;
speakers.Activate(typeof(IAudioEndpointVolume).GUID, 0, IntPtr.Zero, out aepv_obj);
IAudioEndpointVolume aepv = (IAudioEndpointVolume)aepv_obj;
Guid ZeroGuid = new Guid();
int res = aepv.SetMasterVolumeLevelScalar(Level / 100f, ZeroGuid);
MMDevice defaultDevice = new MMDeviceEnumerator().GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
}
catch { Console.WriteLine("VolumeMixer.SetVol casting issue");
}
}
}
class VolumeMeterReader
{
private float bbuffer = 0;
public CircularFloat bufferMemory;
public VolumeMeterReader(int memory )
{
bufferMemory = new CircularFloat(memory);
}
//reads media, could condense and clean
private static AudioSessionManager2 GetDefaultAudioSessionManager2(DataFlow dataFlow)
{
using (var enumerator = new MMDeviceEnumerator())
{
using (var device = enumerator.GetDefaultAudioEndpoint(dataFlow, Role.Multimedia))
{
//Debug.WriteLine("DefaultDevice: " + device.FriendlyName);
var sessionManager = AudioSessionManager2.FromMMDevice(device);
return sessionManager;
}
}
}
private void SetMediaManager()
{
try
{
using (var sessionManager = GetDefaultAudioSessionManager2(DataFlow.Render))
{
using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
{
//TODO: Currently, this app is only intended to work with one audio stream. Could expand to have multiple audio stream controls.
//If n audio streams are found, the data will be stored as if n samples of a single audio stream were taken.
//The net effect is that the uaveraged value will only take data from the nth audiostream
//...however, the averaged value will be an average of all audio streams which will be corrupt data where a loud stream
//...and a silent stream will average out to a medium volume stream. A medium and a loud stream will average out to
//...a loud stream giving the louder stream the control provided the quieter stream is not too quiet.
foreach (var session in sessionEnumerator)
{
if (session.QueryInterface<AudioMeterInformation>() != null)
{
using (var myMedia = session.QueryInterface<AudioMeterInformation>())
{
bbuffer = myMedia.GetPeakValue();
if ((bbuffer > 0) && (bbuffer <= 1)) bufferMemory.Add(bbuffer);
}
}
}
}
}
}
catch
{
Debug.WriteLine("MTA error on volume mixer setmediamanager");
}
}
public void ReadToBuffer()
{
Thread t = new Thread(SetMediaManager);
t.SetApartmentState(ApartmentState.MTA);
t.Start();
}
}
}