Skip to content

Commit 14063d7

Browse files
committed
Merge branch 'dev' into main
2 parents 11b3ca7 + 3370d85 commit 14063d7

File tree

9 files changed

+257
-234
lines changed

9 files changed

+257
-234
lines changed

VRCOSC.Desktop/VRCOSC.Desktop.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
<ApplicationIcon>game.ico</ApplicationIcon>
77
<ApplicationManifest>app.manifest</ApplicationManifest>
88
<Version>0.0.0</Version>
9-
<FileVersion>2023.429.0</FileVersion>
9+
<FileVersion>2023.430.0</FileVersion>
1010
<Title>VRCOSC</Title>
1111
<Authors>VolcanicArts</Authors>
1212
<Company>VolcanicArts</Company>
1313
<Nullable>enable</Nullable>
14-
<AssemblyVersion>2023.429.0</AssemblyVersion>
14+
<AssemblyVersion>2023.430.0</AssemblyVersion>
1515
</PropertyGroup>
1616
<ItemGroup Label="Project References">
1717
<ProjectReference Include="..\VRCOSC.Game\VRCOSC.Game.csproj" />

VRCOSC.Game/Extensions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,13 @@ public static class TimeSpanExtensions
4545
{
4646
public static string Format(this TimeSpan timeSpan) => string.Format(timeSpan.TotalHours >= 1 ? @"{0:hh\:mm\:ss}" : @"{0:mm\:ss}", timeSpan);
4747
}
48+
49+
public static class ArrayExtensions
50+
{
51+
public static T[] NewCopy<T>(this T[] source, int length)
52+
{
53+
var destination = new T[length];
54+
Array.Copy(source, destination, length);
55+
return destination;
56+
}
57+
}

VRCOSC.Game/OSC/VRChat/VRChatOscClient.cs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ public class VRChatOscClient : OscClient
1212
{
1313
public Action<VRChatOscData>? OnParameterSent;
1414
public Action<VRChatOscData>? OnParameterReceived;
15-
private readonly Dictionary<string, List<object>> valuesCache = new();
1615

1716
public VRChatOscClient()
1817
{
@@ -33,16 +32,6 @@ public VRChatOscClient()
3332
private void sendData(OscData data)
3433
{
3534
data.PreValidate();
36-
37-
if (data.Address.StartsWith(VRChatOscConstants.ADDRESS_AVATAR_PARAMETERS_PREFIX))
38-
{
39-
if (valuesCache.TryGetValue(data.Address, out var previousValue))
40-
{
41-
if (data.Values.SequenceEqual(previousValue)) return;
42-
}
43-
}
44-
45-
valuesCache[data.Address] = data.Values;
4635
SendByteData(data.Encode());
4736
OnParameterSent?.Invoke(new VRChatOscData(data));
4837
}

VRCOSC.Game/Processes/ProcessVolume.cs

Lines changed: 136 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ internal static class ProcessVolume
1515
internal static float? GetApplicationVolume(string processName)
1616
{
1717
ISimpleAudioVolume? volume = getVolumeObject(processName);
18+
1819
if (volume == null)
1920
return null;
2021

@@ -26,6 +27,7 @@ internal static class ProcessVolume
2627
internal static bool? GetApplicationMute(string processName)
2728
{
2829
ISimpleAudioVolume? volume = getVolumeObject(processName);
30+
2931
if (volume == null)
3032
return null;
3133

@@ -37,6 +39,7 @@ internal static class ProcessVolume
3739
internal static void SetApplicationVolume(string processName, float percentage)
3840
{
3941
ISimpleAudioVolume? volume = getVolumeObject(processName);
42+
4043
if (volume == null)
4144
return;
4245

@@ -48,6 +51,7 @@ internal static void SetApplicationVolume(string processName, float percentage)
4851
internal static void SetApplicationMute(string processName, bool mute)
4952
{
5053
ISimpleAudioVolume? volume = getVolumeObject(processName);
54+
5155
if (volume == null)
5256
return;
5357

@@ -58,169 +62,176 @@ internal static void SetApplicationMute(string processName, bool mute)
5862

5963
private static ISimpleAudioVolume? getVolumeObject(string processName)
6064
{
61-
// get the speakers (1st render + multimedia) device
62-
IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)new MMDeviceEnumerator();
63-
deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out var speakers);
64-
65-
// activate the session manager. we need the enumerator
66-
Guid IID_IAudioSessionManager2 = typeof(IAudioSessionManager2).GUID;
67-
speakers.Activate(ref IID_IAudioSessionManager2, 0, IntPtr.Zero, out var o);
68-
IAudioSessionManager2 mgr = (IAudioSessionManager2)o;
65+
try
66+
{
67+
// get the speakers (1st render + multimedia) device
68+
IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)new MMDeviceEnumerator();
69+
deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out var speakers);
6970

70-
// enumerate sessions for on this device
71-
mgr.GetSessionEnumerator(out var sessionEnumerator);
72-
sessionEnumerator.GetCount(out var count);
71+
// activate the session manager. we need the enumerator
72+
Guid IID_IAudioSessionManager2 = typeof(IAudioSessionManager2).GUID;
73+
speakers.Activate(ref IID_IAudioSessionManager2, 0, IntPtr.Zero, out var o);
74+
IAudioSessionManager2 mgr = (IAudioSessionManager2)o;
7375

74-
// search for an audio session with the required name
75-
// NOTE: we could also use the process id instead of the app name (with IAudioSessionControl2)
76-
ISimpleAudioVolume? volumeControl = null;
76+
// enumerate sessions for on this device
77+
mgr.GetSessionEnumerator(out var sessionEnumerator);
78+
sessionEnumerator.GetCount(out var count);
7779

78-
for (int i = 0; i < count; i++)
79-
{
80-
sessionEnumerator.GetSession(i, out var ctl);
81-
ctl.GetSessionIdentifier(out var identifier);
80+
// search for an audio session with the required name
81+
// NOTE: we could also use the process id instead of the app name (with IAudioSessionControl2)
82+
ISimpleAudioVolume? volumeControl = null;
8283

83-
if (identifier.Contains(processName, StringComparison.InvariantCultureIgnoreCase))
84+
for (int i = 0; i < count; i++)
8485
{
85-
volumeControl = ctl as ISimpleAudioVolume;
86-
break;
86+
sessionEnumerator.GetSession(i, out var ctl);
87+
ctl.GetSessionIdentifier(out var identifier);
88+
89+
if (identifier.Contains(processName, StringComparison.InvariantCultureIgnoreCase))
90+
{
91+
volumeControl = ctl as ISimpleAudioVolume;
92+
break;
93+
}
94+
95+
Marshal.ReleaseComObject(ctl);
8796
}
8897

89-
Marshal.ReleaseComObject(ctl);
98+
Marshal.ReleaseComObject(sessionEnumerator);
99+
Marshal.ReleaseComObject(mgr);
100+
Marshal.ReleaseComObject(speakers);
101+
Marshal.ReleaseComObject(deviceEnumerator);
102+
return volumeControl;
103+
}
104+
catch
105+
{
106+
return null;
90107
}
91-
92-
Marshal.ReleaseComObject(sessionEnumerator);
93-
Marshal.ReleaseComObject(mgr);
94-
Marshal.ReleaseComObject(speakers);
95-
Marshal.ReleaseComObject(deviceEnumerator);
96-
return volumeControl;
97108
}
98-
}
99109

100-
[ComImport]
101-
[Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
102-
internal class MMDeviceEnumerator
103-
{
104-
}
110+
[ComImport]
111+
[Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
112+
internal class MMDeviceEnumerator
113+
{
114+
}
105115

106-
internal enum EDataFlow
107-
{
108-
eRender,
109-
eCapture,
110-
eAll,
111-
EDataFlow_enum_count
112-
}
116+
internal enum EDataFlow
117+
{
118+
eRender,
119+
eCapture,
120+
eAll,
121+
EDataFlow_enum_count
122+
}
113123

114-
internal enum ERole
115-
{
116-
eConsole,
117-
eMultimedia,
118-
eCommunications,
119-
ERole_enum_count
120-
}
124+
internal enum ERole
125+
{
126+
eConsole,
127+
eMultimedia,
128+
eCommunications,
129+
ERole_enum_count
130+
}
121131

122-
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
123-
internal interface IMMDeviceEnumerator
124-
{
125-
int NotImpl1();
132+
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
133+
internal interface IMMDeviceEnumerator
134+
{
135+
int NotImpl1();
126136

127-
[PreserveSig]
128-
int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice);
137+
[PreserveSig]
138+
int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice);
129139

130-
// the rest is not implemented
131-
}
140+
// the rest is not implemented
141+
}
132142

133-
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
134-
internal interface IMMDevice
135-
{
136-
[PreserveSig]
137-
int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
143+
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
144+
internal interface IMMDevice
145+
{
146+
[PreserveSig]
147+
int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
138148

139-
// the rest is not implemented
140-
}
149+
// the rest is not implemented
150+
}
141151

142-
[Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
143-
internal interface IAudioSessionManager2
144-
{
145-
int NotImpl1();
146-
int NotImpl2();
152+
[Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
153+
internal interface IAudioSessionManager2
154+
{
155+
int NotImpl1();
156+
int NotImpl2();
147157

148-
[PreserveSig]
149-
int GetSessionEnumerator(out IAudioSessionEnumerator SessionEnum);
158+
[PreserveSig]
159+
int GetSessionEnumerator(out IAudioSessionEnumerator SessionEnum);
150160

151-
// the rest is not implemented
152-
}
161+
// the rest is not implemented
162+
}
153163

154-
[Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
155-
internal interface IAudioSessionEnumerator
156-
{
157-
[PreserveSig]
158-
int GetCount(out int SessionCount);
164+
[Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
165+
internal interface IAudioSessionEnumerator
166+
{
167+
[PreserveSig]
168+
int GetCount(out int SessionCount);
159169

160-
[PreserveSig]
161-
int GetSession(int SessionCount, out IAudioSessionControl2 Session);
162-
}
170+
[PreserveSig]
171+
int GetSession(int SessionCount, out IAudioSessionControl2 Session);
172+
}
163173

164-
[Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
165-
internal interface ISimpleAudioVolume
166-
{
167-
[PreserveSig]
168-
int SetMasterVolume(float fLevel, ref Guid EventContext);
174+
[Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
175+
internal interface ISimpleAudioVolume
176+
{
177+
[PreserveSig]
178+
int SetMasterVolume(float fLevel, ref Guid EventContext);
169179

170-
[PreserveSig]
171-
int GetMasterVolume(out float pfLevel);
180+
[PreserveSig]
181+
int GetMasterVolume(out float pfLevel);
172182

173-
[PreserveSig]
174-
int SetMute(bool bMute, ref Guid EventContext);
183+
[PreserveSig]
184+
int SetMute(bool bMute, ref Guid EventContext);
175185

176-
[PreserveSig]
177-
int GetMute(out bool pbMute);
178-
}
186+
[PreserveSig]
187+
int GetMute(out bool pbMute);
188+
}
179189

180-
[Guid("bfb7ff88-7239-4fc9-8fa2-07c950be9c6d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
181-
internal interface IAudioSessionControl2
182-
{
183-
// IAudioSessionControl
184-
[PreserveSig]
185-
int NotImpl0();
190+
[Guid("bfb7ff88-7239-4fc9-8fa2-07c950be9c6d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
191+
internal interface IAudioSessionControl2
192+
{
193+
// IAudioSessionControl
194+
[PreserveSig]
195+
int NotImpl0();
186196

187-
[PreserveSig]
188-
int GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
197+
[PreserveSig]
198+
int GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
189199

190-
[PreserveSig]
191-
int SetDisplayName([MarshalAs(UnmanagedType.LPWStr)] string Value, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
200+
[PreserveSig]
201+
int SetDisplayName([MarshalAs(UnmanagedType.LPWStr)] string Value, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
192202

193-
[PreserveSig]
194-
int GetIconPath([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
203+
[PreserveSig]
204+
int GetIconPath([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
195205

196-
[PreserveSig]
197-
int SetIconPath([MarshalAs(UnmanagedType.LPWStr)] string Value, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
206+
[PreserveSig]
207+
int SetIconPath([MarshalAs(UnmanagedType.LPWStr)] string Value, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
198208

199-
[PreserveSig]
200-
int GetGroupingParam(out Guid pRetVal);
209+
[PreserveSig]
210+
int GetGroupingParam(out Guid pRetVal);
201211

202-
[PreserveSig]
203-
int SetGroupingParam([MarshalAs(UnmanagedType.LPStruct)] Guid Override, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
212+
[PreserveSig]
213+
int SetGroupingParam([MarshalAs(UnmanagedType.LPStruct)] Guid Override, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
204214

205-
[PreserveSig]
206-
int NotImpl1();
215+
[PreserveSig]
216+
int NotImpl1();
207217

208-
[PreserveSig]
209-
int NotImpl2();
218+
[PreserveSig]
219+
int NotImpl2();
210220

211-
// IAudioSessionControl2
212-
[PreserveSig]
213-
int GetSessionIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
221+
// IAudioSessionControl2
222+
[PreserveSig]
223+
int GetSessionIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
214224

215-
[PreserveSig]
216-
int GetSessionInstanceIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
225+
[PreserveSig]
226+
int GetSessionInstanceIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
217227

218-
[PreserveSig]
219-
int GetProcessId(out int pRetVal);
228+
[PreserveSig]
229+
int GetProcessId(out int pRetVal);
220230

221-
[PreserveSig]
222-
int IsSystemSoundsSession();
231+
[PreserveSig]
232+
int IsSystemSoundsSession();
223233

224-
[PreserveSig]
225-
int SetDuckingPreference(bool optOut);
234+
[PreserveSig]
235+
int SetDuckingPreference(bool optOut);
236+
}
226237
}

VRCOSC.Game/VRCOSC.Game.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2626
</PackageReference>
2727
<PackageReference Include="WebSocket4Net" Version="0.15.2" />
28+
<PackageReference Include="NAudio.Wasapi" Version="2.1.0" />
29+
<PackageReference Include="Vosk" Version="0.3.38" />
2830
<PackageReference Include="VolcanicArts.Libs.OpenVR" Version="1.23.7" />
2931
<PackageReference Include="VolcanicArts.Libs.SRanipalLib" Version="1.0.0" />
3032
</ItemGroup>

0 commit comments

Comments
 (0)