1
1
#nullable enable
2
2
using System ;
3
+ using System . Collections . Generic ;
3
4
using System . Diagnostics ;
4
5
using System . Linq ;
5
6
using NAudio . CoreAudioApi ;
@@ -195,7 +196,7 @@ public void SetVolumeFromDefaultDevice(DeviceInfo device)
195
196
if ( currentDefault == null )
196
197
return ;
197
198
198
- var audioInfo = InteractWithMmDevice ( currentDefault , mmDevice =>
199
+ var audioInfo = InteractWithDevice ( currentDefault , mmDevice =>
199
200
{
200
201
var defaultDeviceAudioEndpointVolume = mmDevice . AudioEndpointVolume ;
201
202
return defaultDeviceAudioEndpointVolume == null ? default : ( Volume : defaultDeviceAudioEndpointVolume . MasterVolumeLevelScalar , IsMuted : defaultDeviceAudioEndpointVolume . Mute ) ;
@@ -205,15 +206,15 @@ public void SetVolumeFromDefaultDevice(DeviceInfo device)
205
206
return ;
206
207
207
208
var nextDevice = GetDevice ( device . Id ) ;
208
-
209
- if ( nextDevice == null )
209
+
210
+ if ( nextDevice == null )
210
211
return ;
211
-
212
- InteractWithMmDevice ( nextDevice , mmDevice =>
212
+
213
+ InteractWithDevice ( nextDevice , mmDevice =>
213
214
{
214
215
if ( mmDevice is not { State : DeviceState . Active } )
215
216
return nextDevice ;
216
-
217
+
217
218
if ( mmDevice . AudioEndpointVolume == null )
218
219
return nextDevice ;
219
220
@@ -223,9 +224,10 @@ public void SetVolumeFromDefaultDevice(DeviceInfo device)
223
224
mmDevice . AudioEndpointVolume . Channels [ 1 ] . VolumeLevelScalar = audioInfo . Volume ;
224
225
}
225
226
else
226
- {
227
+ {
227
228
mmDevice . AudioEndpointVolume . MasterVolumeLevelScalar = audioInfo . Volume ;
228
229
}
230
+
229
231
mmDevice . AudioEndpointVolume . Mute = audioInfo . IsMuted ;
230
232
return mmDevice ;
231
233
} ) ;
@@ -274,7 +276,15 @@ public bool IsDefault(string deviceId, EDataFlow flow, ERole role)
274
276
/// <param name="device"></param>
275
277
/// <param name="interaction"></param>
276
278
/// <typeparam name="T"></typeparam>
277
- public T InteractWithMmDevice < T > ( MMDevice device , Func < MMDevice , T > interaction ) => ComThread . Invoke ( ( ) => interaction ( device ) ) ;
279
+ public T InteractWithDevice < T > ( MMDevice device , Func < MMDevice , T > interaction ) => ComThread . Invoke ( ( ) => interaction ( device ) ) ;
280
+
281
+ /// <summary>
282
+ /// Used to interact directly with a <see cref="DeviceFullInfo"/>
283
+ /// </summary>
284
+ /// <param name="device"></param>
285
+ /// <param name="interaction"></param>
286
+ /// <typeparam name="T"></typeparam>
287
+ public T InteractWithDevice < T > ( DeviceFullInfo device , Func < DeviceFullInfo , T > interaction ) => ComThread . Invoke ( ( ) => interaction ( device ) ) ;
278
288
279
289
/// <summary>
280
290
/// Get the current default endpoint
@@ -302,6 +312,31 @@ public bool IsDefault(string deviceId, EDataFlow flow, ERole role)
302
312
return device == null ? null : new DeviceFullInfo ( device ) ;
303
313
} ) ;
304
314
315
+ /// <summary>
316
+ /// Get audio endpoints for the given flow and state
317
+ /// </summary>
318
+ /// <param name="flow"></param>
319
+ /// <param name="state"></param>
320
+ /// <returns></returns>
321
+ public IEnumerable < DeviceFullInfo > GetAudioEndpoints ( EDataFlow flow , EDeviceState state ) => ComThread . Invoke ( ( ) =>
322
+ {
323
+ var devices = EnumeratorClient . GetEndpoints ( flow , state ) ;
324
+ return devices . Select ( device =>
325
+ {
326
+ try
327
+ {
328
+ return new DeviceFullInfo ( device ) ;
329
+ }
330
+ catch ( Exception e )
331
+ {
332
+ Trace . TraceError ( "Couldn't get device info: {0}" , e ) ;
333
+ return null ;
334
+ }
335
+ } ) . Where ( device => device != null )
336
+ . Where ( device => string . IsNullOrEmpty ( device ? . Name ) )
337
+ . Cast < DeviceFullInfo > ( ) . ToArray ( ) ;
338
+ } ) ;
339
+
305
340
/// <summary>
306
341
/// Reset Windows configuration for the process that had their audio device changed
307
342
/// </summary>
0 commit comments