Hello all, hope everyone enjoyed the holidays.

I'm currently using VB and attempting to create an app that will detect when audio is playing through the speakers (specifically google chrome), and then recording that audio once it does. When the audio is completed, the app will wait a few seconds to ensure it's over and then stop the recording, name and save the file as a wav or MP3 (preferred).

I stumbled on this sound meter code that can detect the audio (it may be more than I actually need for detection), and I notice it creates a buffer for the sound, I'm assuming this can somehow be saved at this point. How would I go about recording and then stopping after a few seconds after it's done? I assume I need to use a different thread so the detection loop can keep running. Anyway, I've never coded anything regarding sound capture, so am hoping someone can point me in the right direction.

If anybody is wondering, I'm recording HF radio chatter through a SDR website. Instead of having to sit there and monitor the communications, waiting in between chatter, it'd be nicer if I can start the app, let it record when there is chatter, and then I can listen to it all at once the next day. I'd like it separated into files because I may later include a mechanism that automatically records each section of chatter, log each into a MySQL database and upload them to a http server for the public domain. This chatter will contain primarily public service transmissions. BTW, I'm FCC licensed, so no legal issues there (not that there is any).

I would also like to track statistics on how active the channels are, this would also be recorded in the database. I can do all this once I figure a way to detect, stop and save the recordings...finding trigger points for each in between operations. If there's a better or easier way to doing this than my current approach, then I'm open for ideas.

Thanks in advance.

Imports Microsoft.DirectX.DirectSound
Imports System.Threading
Imports System.Collections.Specialized

Public Class VU_Sound_Form

    Private Const SAMPLES As Integer = 8
    Private Shared SAMPLE_FORMAT_ARRAY As Integer() = {SAMPLES, 2, 1}
    Public Shared audioDevices As CaptureDevicesCollection
    Private Shared m_deviceNames As StringCollection

    Private deviceIndex As Integer = -1
    Private buffer As Microsoft.DirectX.DirectSound.CaptureBuffer

    Private liveVolumeThread As System.Threading.Thread
    Private m_frameDelay As Integer = 20
    Private Range_Division As Integer = 10

    'FrameDelay - the time in milliseconds between animation frames, measured in milliseconds. 
    'Values between 10 and 30 generally give good results, default is 20.

    Private Sub VU_Sound_Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim audioDevices As New CaptureDevicesCollection
        Dim x As Integer = 0

        While x < audioDevices.Count
            x = x + 1
        End While
        ComboBox1.SelectedIndex = 0
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
    End Sub

    Public Sub Start()

        Dim audioDevices As New CaptureDevicesCollection
        deviceIndex = ComboBox1.SelectedIndex
        If deviceIndex <> -1 Then
            ' initialize the capture buffer and start the animation thread
            Dim cap As New Capture(audioDevices(deviceIndex).DriverGuid)
            Dim desc As New CaptureBufferDescription()
            Dim wf As New WaveFormat()
            wf.BitsPerSample = 16
            wf.SamplesPerSecond = 44100
            wf.Channels = 2
            wf.BlockAlign = CShort(wf.Channels * wf.BitsPerSample / 8)
            wf.AverageBytesPerSecond = wf.BlockAlign * wf.SamplesPerSecond
            wf.FormatTag = WaveFormatTag.Pcm

            desc.Format = wf
            desc.BufferBytes = SAMPLES * wf.BlockAlign

            buffer = New Microsoft.DirectX.DirectSound.CaptureBuffer(desc, cap)

            ' Start a seperate thread to read the buffer and update the progress bars
            liveVolumeThread = New Thread(AddressOf updateProgress)  'Thread starts at updateProgress
            Control.CheckForIllegalCrossThreadCalls = False ' This is needed otherwise the form will not update
            liveVolumeThread.Priority = ThreadPriority.Lowest ' Thread works in the background

        End If
    End Sub

    Public Sub [Stop]()
        If liveVolumeThread IsNot Nothing Then
            liveVolumeThread = Nothing
        End If

        If buffer IsNot Nothing Then
            If buffer.Capturing Then
            End If

            buffer = Nothing
        End If
    End Sub

    Public Sub updateProgress()

        While True
            Dim tempFrameDelay As Integer = m_frameDelay
            Dim samples__1 As Array = buffer.Read(0, GetType(Int16), LockFlag.FromWriteCursor, SAMPLE_FORMAT_ARRAY)

            Dim leftGoal As Integer = 0
            Dim rightGoal As Integer = 0

            ' Convert the 8 samples to positive values and sum them togather 
            For i As Integer = 0 To SAMPLES - 1
                If CType(samples__1.GetValue(i, 0, 0), Int16) < 0 Then
                    leftGoal -= CType(samples__1.GetValue(i, 0, 0), Int16)
                    leftGoal += CType(samples__1.GetValue(i, 0, 0), Int16)
                End If
                If CType(samples__1.GetValue(i, 1, 0), Int16) < 0 Then
                    rightGoal -= CType(samples__1.GetValue(i, 1, 0), Int16)
                    rightGoal += CType(samples__1.GetValue(i, 1, 0), Int16)
                End If

            ' Calculate the average of the 8 samples
            leftGoal = CInt(Math.Abs(leftGoal \ SAMPLES))
            rightGoal = CInt(Math.Abs(rightGoal \ SAMPLES))

            ' Convert values to deecibels
            If leftGoal = 0 Then leftGoal = 1
            If rightGoal = 0 Then rightGoal = 1
            leftGoal = (100 + (20 * Math.Log10(leftGoal / 32768)))
            rightGoal = (100 + (20 * Math.Log10(rightGoal / 32768)))

            'By adding 100 sets the display range from 0 to 100 
            'By limiting the progreess bars to 74-100 gives a viewed range of +10dB to -26dB

            'Trap the range between 74-100, giving a 26dB meter
            If leftGoal < 74 Then leftGoal = 74
            If rightGoal < 74 Then rightGoal = 74 ' Set the display range to minimum -10dB
            If leftGoal > 100 Then leftGoal = 100
            If rightGoal > 100 Then rightGoal = 100

            Dim range1 As Double = leftGoal - ProgressBar1.Value ' calculates the difference between new and the current progress bar value 
            Dim range2 As Double = rightGoal - ProgressBar2.Value

            ' Assign the exact current value of the progress bar
            Dim exactValue1 As Double = ProgressBar1.Value
            Dim exactValue2 As Double = ProgressBar2.Value

            Dim stepSize1 As Double = range1 / Range_Division
            Dim absStepSize1 As Double = Math.Abs(stepSize1)

            Dim stepSize2 As Double = range2 / Range_Division
            Dim absStepSize2 As Double = Math.Abs(stepSize2)

            If ProgressBar1.Value < leftGoal Then    ' Display the peak
                ProgressBar1.Value = leftGoal
            End If

            If ProgressBar1.Value > leftGoal Then ' decrement the value by the Range_Division
                If absStepSize1 < Math.Abs(leftGoal - ProgressBar1.Value) Then
                    exactValue1 += stepSize1
                    ProgressBar1.Value = Math.Truncate(exactValue1)
                    ProgressBar1.Value = leftGoal
                End If
            End If

            If ProgressBar2.Value < rightGoal Then
                ProgressBar2.Value = rightGoal
            End If

            If ProgressBar2.Value > rightGoal Then ' decrement the value by the Range_Division
                If absStepSize2 < Math.Abs(rightGoal - ProgressBar2.Value) Then
                    exactValue2 += stepSize2
                    ProgressBar2.Value = Math.Truncate(exactValue2)
                    ProgressBar2.Value = rightGoal
                End If
            End If
            If (ProgressBar1.Value > 80) Then
                Label10.Text = "Sound Detected"
                ' Thread.Sleep(5000)

                Label10.Text = "No Sound"
                ' MsgBox(ProgressBar1.Value.ToString)
            End If
        End While

    End Sub

End Class