|
| 1 | + |
| 2 | +Imports System.Runtime.InteropServices |
| 3 | +Imports NAudio.CoreAudioApi.Interfaces |
| 4 | +Imports VBAudioRouter.Interop |
| 5 | + |
| 6 | +Namespace Controls |
| 7 | + |
| 8 | + Public NotInheritable Class AudioSessionControl |
| 9 | + Inherits UserControl |
| 10 | + Implements IAudioEndpointVolumeCallback, IAudioSessionEvents |
| 11 | + |
| 12 | + Public ReadOnly Property VolumeManager As IAudioEndpointVolume |
| 13 | + Public ReadOnly Property MeterInformation As IAudioMeterInformation |
| 14 | + Public ReadOnly Property AudioSession As IAudioSessionControl |
| 15 | + |
| 16 | + Public ReadOnly SpeakerControlPageInstance As SpeakerControlPage |
| 17 | + |
| 18 | + Friend Sub New(parent As SpeakerControlPage, audioSession As IAudioSessionControl) |
| 19 | + InitializeComponent() |
| 20 | + |
| 21 | + Me.SpeakerControlPageInstance = parent |
| 22 | + Me.AudioSession = audioSession |
| 23 | + |
| 24 | + VolumeManager = DirectCast(audioSession, IAudioEndpointVolume) |
| 25 | + MeterInformation = DirectCast(audioSession, IAudioMeterInformation) |
| 26 | + |
| 27 | + VolumeManager.RegisterControlChangeNotify(Me) |
| 28 | + OnNotify(IntPtr.Zero) |
| 29 | + |
| 30 | + Dim timer As New Timers.Timer() |
| 31 | + timer.Interval = 30 |
| 32 | + AddHandler timer.Elapsed, Sub() |
| 33 | + Dim unused = Dispatcher.RunIdleAsync(Sub() |
| 34 | + Dim meters As Single() = New Single(MeterInformation.GetMeteringChannelCount() - 1) {} |
| 35 | + Dim metersRef = GCHandle.Alloc(meters, GCHandleType.Pinned) |
| 36 | + MeterInformation.GetChannelsPeakValues(meters.Length, metersRef.AddrOfPinnedObject) |
| 37 | + metersRef.Free() |
| 38 | + LeftMeter.ScaleY = meters(0) |
| 39 | + RightMeter.ScaleY = meters(1) |
| 40 | + End Sub) |
| 41 | + End Sub |
| 42 | + timer.Enabled = True |
| 43 | + |
| 44 | + audioSession.RegisterAudioSessionNotification(Me) |
| 45 | + End Sub |
| 46 | + |
| 47 | + Private Sub AudioSessionControl_Unloaded(sender As Object, e As RoutedEventArgs) Handles Me.Unloaded |
| 48 | + VolumeManager?.UnregisterControlChangeNotify(Me) |
| 49 | + AudioSession?.UnregisterAudioSessionNotification(Me) |
| 50 | + End Sub |
| 51 | + |
| 52 | + Dim oldValue As Double = -1 |
| 53 | + Private Sub VolumeSlider_ValueChanged(sender As Object, e As RangeBaseValueChangedEventArgs) |
| 54 | + If VolumeManager Is Nothing Or oldValue = VolumeSlider.Value Then Exit Sub |
| 55 | + oldValue = VolumeSlider.Value |
| 56 | + VolumeManager.SetMasterVolumeLevelScalar(Convert.ToSingle(VolumeSlider.Value / 100), Guid.Empty) |
| 57 | + End Sub |
| 58 | + |
| 59 | + Dim isMuted As Boolean = False |
| 60 | + Private Sub MuteButton_Click(sender As Object, e As RoutedEventArgs) |
| 61 | + If VolumeManager Is Nothing Then Exit Sub |
| 62 | + |
| 63 | + If sender IsNot Nothing Then |
| 64 | + isMuted = Not isMuted |
| 65 | + VolumeManager.SetMute(isMuted, Guid.Empty) |
| 66 | + End If |
| 67 | + |
| 68 | + If isMuted Then |
| 69 | + MuteButton.Icon = New SymbolIcon(Symbol.Mute) |
| 70 | + Else |
| 71 | + MuteButton.Icon = New SymbolIcon(Symbol.Volume) |
| 72 | + End If |
| 73 | + End Sub |
| 74 | + |
| 75 | + Public Sub OnNotify(notifyData As IntPtr) Implements IAudioEndpointVolumeCallback.OnNotify |
| 76 | + Dim unused = Dispatcher.RunIdleAsync(Sub() |
| 77 | + VolumeSlider.Value = VolumeManager.GetMasterVolumeLevelScalar() * 100 |
| 78 | + isMuted = VolumeManager.GetMute() |
| 79 | + MuteButton_Click(Nothing, Nothing) |
| 80 | + End Sub) |
| 81 | + End Sub |
| 82 | + |
| 83 | + Public Function OnDisplayNameChanged(displayName As String, ByRef eventContext As Guid) As Integer Implements IAudioSessionEvents.OnDisplayNameChanged |
| 84 | + |
| 85 | + End Function |
| 86 | + |
| 87 | + Public Function OnIconPathChanged(iconPath As String, ByRef eventContext As Guid) As Integer Implements IAudioSessionEvents.OnIconPathChanged |
| 88 | + |
| 89 | + End Function |
| 90 | + |
| 91 | + Public Function OnSimpleVolumeChanged(volume As Single, isMuted As Boolean, ByRef eventContext As Guid) As Integer Implements IAudioSessionEvents.OnSimpleVolumeChanged |
| 92 | + |
| 93 | + End Function |
| 94 | + |
| 95 | + Public Function OnChannelVolumeChanged(channelCount As UInteger, newVolumes As IntPtr, channelIndex As UInteger, ByRef eventContext As Guid) As Integer Implements IAudioSessionEvents.OnChannelVolumeChanged |
| 96 | + |
| 97 | + End Function |
| 98 | + |
| 99 | + Public Function OnGroupingParamChanged(ByRef groupingId As Guid, ByRef eventContext As Guid) As Integer Implements IAudioSessionEvents.OnGroupingParamChanged |
| 100 | + |
| 101 | + End Function |
| 102 | + |
| 103 | + Public Function OnStateChanged(state As AudioSessionState) As Integer Implements IAudioSessionEvents.OnStateChanged |
| 104 | + |
| 105 | + End Function |
| 106 | + |
| 107 | + Public Function OnSessionDisconnected(disconnectReason As AudioSessionDisconnectReason) As Integer Implements IAudioSessionEvents.OnSessionDisconnected |
| 108 | + SpeakerControlPageInstance.AudioSessions.Remove(Me) |
| 109 | + End Function |
| 110 | + End Class |
| 111 | + |
| 112 | +End Namespace |
0 commit comments