Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / System

Logarithmic PPM sound meters

Rate me:
Please Sign up or sign in to vote.
4.80/5 (5 votes)
9 Aug 2010CPOL2 min read 76K   8.6K   27   14
A simple stereo sound volume meter with audio capture card selection.

VUMeter.jpg

Introduction

This a simple logarithmic stereo peak sound volume meter. Measurement is in decibels (dB). It would be useful to use in sound recording or mixing applications.

Background

This is part of another project where I am attempting to create a Morse code control panel to transmit and receive through the sound card. I originally used Jacob Klint's VolumeMeter (Managed DirectX), but found it crashed, and did not track the peak sound fast enough for my application. Morse code is measured in tens of milliseconds.

I have reused some of Jacob's code for the audio capture.

Prerequisite

It may be necessary to install the DirectX 9.0 SDK first.

Using the Code

On form load, the audio capture devices are listed into a combo box and the first in the list selected. The audio buffer reading and progress bars update start automatically using a threaded routine.

The meter response can be adjusted by altering the FrameDelay value. A value between 10 and 30 gives a good result.

The sound capture is two channels of 16 bit samples, giving values +/-32768. Eight samples are taken each time. The capture code is described by Jacob here: http://www.codeproject.com/KB/directx/volumemeter.aspx.

I use threading to read the capture buffer and update the progress bars in the background.

To convert values to dBs, use Volume (dB) = 20*(log10 (average sample / 32768)). The average sample has to be the RMS (Root/Mean/Square) value, and will result in values between 0 and -90dB. Since the progress bars only accept positive values, an offset is added of 100. By limiting the progress bar values to 74-100, only the top 26dBs are viewed.

VB
// Imports required
Imports Microsoft.DirectX.DirectSound
Imports System.Threading
Imports System.Collections.Specialized

// Detecting the Sound Cards
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
        ComboBox1.Items.Add(audioDevices.Item(x).Description)
        x = x + 1
    End While
    ComboBox1.SelectedIndex = 0
    Start()
End Sub

// Reading the capture buffer and convert to decibels
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)
    Else
        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)
    Else
        rightGoal += CType(samples__1.GetValue(i, 1, 0), Int16)
    End If
Next

//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)))

// Updating the progress bars so

// If the measured value is larger than the 
// progress bar value then it is the peak

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

// If the measured value is smaller than the progress bar value
// step reduce the bar

If ProgressBar2.Value > rightGoal Then ' decrement the value
    If absStepSize2 < Math.Abs(rightGoal - ProgressBar2.Value) Then
        exactValue2 += stepSize2
        ProgressBar2.Value = Math.Truncate(exactValue2)
    Else
        ProgressBar2.Value = rightGoal
    End If
End If
Thread.Sleep(m_frameDelay)

Points of Interest

This is my first time using threading. I found that if you did not add the line Control.CheckForIllegalCrossThreadCalls = False before starting the thread, the form does not update.

History

  • Version 1.0.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer BBC News
United Kingdom United Kingdom
I do a little programming in VB2010 and for PIC controllers. I wouldn't call myself an expert as it always takes me a long time and I'm constantly learning. I enjoy what I do.

I've completed a few projects.

Tide calculator for the UK
Sony LANC camera remote control - serial and Pic controllers
PIC Pulse Induction Metal Detector
Morse Code through the sound card
Home Maintenance Log

I also do a little web design and maintain my diving club's web site at http://www.esac.org.uk/.

Comments and Discussions

 
QuestionCan you help me Pin
michael diaz25-Mar-15 5:02
michael diaz25-Mar-15 5:02 
QuestionTry to get this working with VB2010 and DXSDK11 Pin
pa3akp18-May-13 7:57
pa3akp18-May-13 7:57 
AnswerRe: Try to get this working with VB2010 and DXSDK11 Pin
pa3akp18-May-13 7:59
pa3akp18-May-13 7:59 
GeneralMy vote of 5 Pin
Dr Bob18-Jan-12 9:47
Dr Bob18-Jan-12 9:47 
GeneralMy vote of 5 Pin
FlavioAR11-Dec-11 3:23
FlavioAR11-Dec-11 3:23 
Questiondeleted Pin
User 58060515-Jul-11 14:50
User 58060515-Jul-11 14:50 
AnswerRe: Error on Win 7 64 bits Pin
Nigel Ealand6-Jul-11 3:15
Nigel Ealand6-Jul-11 3:15 
QuestionVista/win7? Pin
dragonrose18-Feb-11 13:18
dragonrose18-Feb-11 13:18 
AnswerRe: Vista/win7? Pin
Nigel Ealand18-Feb-11 23:32
Nigel Ealand18-Feb-11 23:32 
Questionhow to work the vumeter with image capture Pin
macgyvertiras21-Aug-10 2:02
macgyvertiras21-Aug-10 2:02 
GeneralDelay refresh Pin
Passion_Knight18-Aug-10 0:05
Passion_Knight18-Aug-10 0:05 
GeneralRe: Delay refresh Pin
Nigel Ealand18-Aug-10 7:54
Nigel Ealand18-Aug-10 7:54 
Generalwebcam capture + volume meter [modified] Pin
macgyvertiras15-Aug-10 16:05
macgyvertiras15-Aug-10 16:05 
i can't work the two codes in the same program
the volume meter :
http://www.codeproject.com/KB/vb/macgyver.aspx

and the image capture of : (the actual capture ,the webcam image display works)
http://www.youtube.com/watch?v=-dMQNlrkGWQ

modified on Sunday, August 15, 2010 10:21 PM

Generaltesting report Pin
macgyvertiras18-Jul-10 14:16
macgyvertiras18-Jul-10 14:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.