Visual
  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