Virtual Developer Workshop: Containerized Development with Docker
I dare to say that no one loves music more than I. Music is literally my life and my job is my hobby. That is just how serious I am about music. Now, as an avid music lover, I always try to find new things to do to a song, and with Visual Basic, hence this article. In today's article, I will demonstrate how to extract audio segments from a song. It sounds fun, doesn't it? Well then, let us get started!
Microsoft Expression Encoder
Before you can start creating the project, you fist need to know about Microsoft Expression Encoder. Microsoft Expression Encoder is an advanced audio/video-encoding and live-broadcasting application suited for generating content. You can generate Windows Media video and audio files that are optimized for web playback scenarios, or playback on portable devices.
- High performance multi-core encoding
- Crop/scale/de-interlace operation
- Multi-clip editing
- A/B compares
- Live encoding
- Up to 10 minutes of screen capture
- Smart encoding
- Silverlight templates
- Multi-channel capability
- Audio import and export
You can download Microsoft Expression Encoder here.
Once downloaded, you can run the setup file. Once it is finished, as in Figure 1, you need to a Reference to it by following these steps:
- Click Project.
- Click Add Reference.
- Navigate to Microsoft Expression Encoder.
- Click the checkbox next to it.
- Click OK.
Figure 1: Microsoft Expression Encoder
Today's Sample Project
The sample project you will create today will be a little tool to extract an audio segment from an existing song, or sound clip being played with the Windows Media Player control.
Design your form to resemble Figure 2. Please note that my object naming might differ from yours, so keep that in mind when referring to the objects in code.
Figure 2: Our design
If you are not familiar with the Windows Media Player control, and how to add it, I suggest you have a look through these links:
With a decent design, you can already form the code in your head, and what each object's purpose is.
Open the code window for the Form, and add the following Namespaces:
Imports System.IO Imports System.Security.Permissions
These allow us to access any file.
Add the following code behind the "Open…" button:
Private Sub btnOpen_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles btnOpen.Click If ofdOpen.ShowDialog() = DialogResult.OK Then lblFile.Text = ofdOpen.FileName End If End Sub
This simply produces an Open File Dialog that allows for file selection. If a selection has been made, the label will show the file's location. Add this code behind the "Browse…" button:
Private Sub btnOutput_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles btnOutput.Click If fbdFolders.ShowDialog() = DialogResult.OK Then tbOutputFolder.Text = fbdFolders.SelectedPath End If End Sub
The preceding code simply shows a Folder Browser dialog to specify in which folder you'd like to save your audio clip into. Add this code to the "Set Start Point" button:
Private Sub btnSetPoints_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles btnSetPoints.Click If Not String.IsNullOrEmpty(Me.wmpMusic.URL) Then If btnSetPoints.Text.Equals("Set Start Point") Then txtStart.Text = (wmpMusic.Ctlcontrols.currentPosition * _ 1000).ToString("0") txtEnd.Text = "" btnSetPoints.Text = "Set End Point" ElseIf btnSetPoints.Text.Equals("Set End Point") Then Dim intEnd As Integer = CInt(Fix(wmpMusic.Ctlcontrols. _ currentPosition * 1000)) If intEnd <= Integer.Parse(Me.txtStart.Text) Then MessageBox.Show("Audio endpoint overlapped.") Else txtEnd.Text = intEnd.ToString() btnSetPoints.Text = "Set Start Point" End If End If End If End Sub
Here, I simply do a test based on the current button's Text, or caption, rather. If the button's text is "Set Start Point", it will determine where we have stopped the media player's song being played. If the text is "Set End Point", it basically does the same, but calculates the audio clip's ending point.
Let the games begin!
Add this code behind the "Extract" button:
Private Sub btnExtract_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles btnExtract.Click Try Dim strSourceFile As String = Me.wmpMusic.URL Dim strOutput As String = Me.tbOutputFolder.Text Dim strStart As String = Me.txtStart.Text Dim strEnd As String = Me.txtEnd.Text ' Extract the audio file. Dim atOutput As AudioType = CType(Me.cmbOutputAudioType.SelectedValue, _ AudioType) Dim strFile As String = ExtractAudioWrapper.Extract(strSourceFile, _ strOutput, atOutput, Double.Parse(strStart), Double.Parse(strEnd)) MessageBox.Show("Audio file is successfully extracted: " & strFile) Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub
At first glance, it looks pretty straightforward. There are, however, some terms you may not know about; they are these two:
I will explain these in detail now.
Add the ExtractAudioWrapper class by following these steps:
- Click Project.
- Click Add Class…
- Supply the name of ExtractAudioWrapper and click Add.
This class serves as a wrapper to the Microsoft Expression Encoding object(s). For more information regarding wrapper classes, have a look here.
Add these Namespaces:
Imports Microsoft.Expression.Encoder Imports Microsoft.Expression.Encoder.Profiles Imports System.Collections.ObjectModel
This imports the necessary objects and methods for us to do any audio processing.
Add the Extract function:
Public Shared Function Extract(ByVal strSource As String, _ ByVal strOutput As String, ByVal atOutPut As AudioType, _ ByVal dblStart As Double, ByVal dblEnd As Double) As String Using [job] As New Job() Dim miSource As New MediaItem(strSource) Select Case outputType Case OutputAudioType.MP4 miSource.OutputFormat = New MP4OutputFormat() miSource.OutputFormat.AudioProfile = New AacAudioProfile() miSource.OutputFormat.AudioProfile.Codec = AudioCodec.AAC miSource.OutputFormat.AudioProfile.BitsPerSample = 24 Case OutputAudioType.WMA miSource.OutputFormat = New WindowsMediaOutputFormat() miSource.OutputFormat.AudioProfile = New WmaAudioProfile() miSource.OutputFormat.AudioProfile.Bitrate = _ New VariableConstrainedBitrate(128, 192) miSource.OutputFormat.AudioProfile.Codec = _ AudioCodec.WmaProfessional smiSourcerc.OutputFormat.AudioProfile.BitsPerSample = 24 End Select Dim tsStart As TimeSpan = TimeSpan.FromMilliseconds(dblStart) miSource.Sources(0).Clips(0).StartTime = tsStart Dim tsEnd As TimeSpan = TimeSpan.FromMilliseconds(dblEnd) miSource.Sources(0).Clips(0).EndTime = tsEnd [job].MediaItems.Add(miSource) [job].OutputDirectory = strOutput [job].Encode() Return [job].MediaItems(0).ActualOutputFileFullPath End Using End Function
The purpose of this function is to determine what type of file you are dealing with. If it is a valid audio file, it will determine its start and end values (as supplied through the functions parameters), then it will produce the file according to your choice of file. This is, unfortunately, only a choice of two: MP4 and WMA. Whichever format it has to work with, it formats it in the desired way. Obviously, you can play around with the BitRate and those types of properties until you get your desired sound.
After the End Class statement, add the AudioType Enum:
Public Enum AudioType WMA MP4 End Enum
These two formats are the only two formats supported by Microsoft Expression Encoder 3.0.
I am including a working sample.
I hope you have learned from this article. Don't be afraid to experiment a little. Cheers!
About the Author
Hannes du Preez is a Microsoft MVP for Visual Basic for the seventh year in a row.