1 2 3 Imports Microsoft.DirectX.DirectSound 4 Imports System.Threading 5 Imports System.Collections.Specialized 6 7 Public Class VU_Sound_Form 8 9 Private Const SAMPLES As Integer = 8 10 Private Shared SAMPLE_FORMAT_ARRAY As Integer() = {SAMPLES, 2, 1} 11 Public Shared audioDevices As CaptureDevicesCollection 12 Private Shared m_deviceNames As StringCollection 13 14 Private deviceIndex As Integer = -1 15 Private buffer As Microsoft.DirectX.DirectSound.CaptureBuffer 16 Private liveVolumeThread As System.Threading.Thread 17 Private m_frameDelay As Integer = 20 18 Private Range_Division As Integer = 10 19 20 'FrameDelay - the time in milliseconds between animation frames, measured in milliseconds. 21 'Values between 10 and 30 generally give good results, default is 20. 22 23 24 Private Sub VU_Sound_Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 25 Dim audioDevices As New CaptureDevicesCollection 26 Dim x As Integer = 0 27 28 While x < audioDevices.Count 29 ComboBox1.Items.Add(audioDevices.Item(x).Description) 30 x = x + 1 31 End While 32 ComboBox1.SelectedIndex = 0 33 Start() 34 End Sub 35 36 37 Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged 38 Start() 39 End Sub 40 41 42 Public Sub Start() 43 [Stop]() 44 Dim audioDevices As New CaptureDevicesCollection 45 deviceIndex = ComboBox1.SelectedIndex 46 If deviceIndex <> -1 Then 47 ' initialize the capture buffer and start the animation thread 48 Dim cap As New Capture(audioDevices(deviceIndex).DriverGuid) 49 Dim desc As New CaptureBufferDescription() 50 Dim wf As New WaveFormat() 51 wf.BitsPerSample = 16 52 wf.SamplesPerSecond = 44100 53 wf.Channels = 2 54 wf.BlockAlign = CShort(wf.Channels * wf.BitsPerSample / 8) 55 wf.AverageBytesPerSecond = wf.BlockAlign * wf.SamplesPerSecond 56 wf.FormatTag = WaveFormatTag.Pcm 57 58 desc.Format = wf 59 desc.BufferBytes = SAMPLES * wf.BlockAlign 60 61 buffer = New Microsoft.DirectX.DirectSound.CaptureBuffer(desc, cap) 62 buffer.Start(True) 63 64 ' Start a seperate thread to read the buffer and update the progress bars 65 liveVolumeThread = New Thread(AddressOf updateProgress) 'Thread starts at updateProgress 66 Control.CheckForIllegalCrossThreadCalls = False ' This is needed otherwise the form will not update 67 liveVolumeThread.Priority = ThreadPriority.Lowest ' Thread works in the background 68 liveVolumeThread.Start() 69 70 End If 71 End Sub 72 73 Public Sub [Stop]() 74 If liveVolumeThread IsNot Nothing Then 75 liveVolumeThread.Abort() 76 liveVolumeThread.Join() 77 liveVolumeThread = Nothing 78 End If 79 80 If buffer IsNot Nothing Then 81 If buffer.Capturing Then 82 buffer.[Stop]() 83 End If 84 85 buffer.Dispose() 86 buffer = Nothing 87 End If 88 End Sub 89 90 91 92 Public Sub updateProgress() 93 94 While True 95 Dim tempFrameDelay As Integer = m_frameDelay 96 Dim samples__1 As Array = buffer.Read(0, GetType(Int16), LockFlag.FromWriteCursor, SAMPLE_FORMAT_ARRAY) 97 98 Dim leftGoal As Integer = 0 99 Dim rightGoal As Integer = 0 100 101 ' Convert the 8 samples to positive values and sum them togather 102 For i As Integer = 0 To SAMPLES - 1 103 If CType(samples__1.GetValue(i, 0, 0), Int16) < 0 Then 104 leftGoal -= CType(samples__1.GetValue(i, 0, 0), Int16) 105 Else 106 leftGoal += CType(samples__1.GetValue(i, 0, 0), Int16) 107 End If 108 If CType(samples__1.GetValue(i, 1, 0), Int16) < 0 Then 109 rightGoal -= CType(samples__1.GetValue(i, 1, 0), Int16) 110 Else 111 rightGoal += CType(samples__1.GetValue(i, 1, 0), Int16) 112 End If 113 Next 114 115 ' Calculate the average of the 8 samples 116 leftGoal = CInt(Math.Abs(leftGoal \ SAMPLES)) 117 rightGoal = CInt(Math.Abs(rightGoal \ SAMPLES)) 118 119 ' Convert values to deecibels 120 If leftGoal = 0 Then leftGoal = 1 121 If rightGoal = 0 Then rightGoal = 1 122 leftGoal = (100 + (20 * Math.Log10(leftGoal / 32768))) 123 rightGoal = (100 + (20 * Math.Log10(rightGoal / 32768))) 124 125 'By adding 100 sets the display range from 0 to 100 126 'By limiting the progreess bars to 74-100 gives a viewed range of +10dB to -26dB 127 128 129 130 131 'Trap the range between 74-100, giving a 26dB meter 132 If leftGoal < 74 Then leftGoal = 74 133 If rightGoal < 74 Then rightGoal = 74 ' Set the display range to minimum -10dB 134 If leftGoal > 100 Then leftGoal = 100 135 If rightGoal > 100 Then rightGoal = 100 136 137 Dim range1 As Double = leftGoal - ProgressBar1.Value ' calculates the difference between new and the current progress bar value 138 Dim range2 As Double = rightGoal - ProgressBar2.Value 139 140 ' Assign the exact current value of the progress bar 141 Dim exactValue1 As Double = ProgressBar1.Value 142 Dim exactValue2 As Double = ProgressBar2.Value 143 144 Dim stepSize1 As Double = range1 / Range_Division 145 Dim absStepSize1 As Double = Math.Abs(stepSize1) 146 147 Dim stepSize2 As Double = range2 / Range_Division 148 Dim absStepSize2 As Double = Math.Abs(stepSize2) 149 150 If ProgressBar1.Value < leftGoal Then ' Display the peak 151 ProgressBar1.Value = leftGoal 152 End If 153 154 If ProgressBar1.Value > leftGoal Then ' decrement the value by the Range_Division 155 If absStepSize1 < Math.Abs(leftGoal - ProgressBar1.Value) Then 156 exactValue1 += stepSize1 157 ProgressBar1.Value = Math.Truncate(exactValue1) 158 Else 159 ProgressBar1.Value = leftGoal 160 End If 161 End If 162 163 If ProgressBar2.Value < rightGoal Then 164 ProgressBar2.Value = rightGoal 165 End If 166 167 If ProgressBar2.Value > rightGoal Then ' decrement the value by the Range_Division 168 If absStepSize2 < Math.Abs(rightGoal - ProgressBar2.Value) Then 169 exactValue2 += stepSize2 170 ProgressBar2.Value = Math.Truncate(exactValue2) 171 Else 172 ProgressBar2.Value = rightGoal 173 End If 174 End If 175 Thread.Sleep(m_frameDelay) 176 End While 177 End Sub 178 179 180 Private Sub ProgressBar1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ProgressBar1.Click 181 182 End Sub 183 End Class