5 Development Team Productivity Killers3 Reasons Why VB6 is Dead

Extending My.Computer.Audio To Play MP3’s

July 17th, 2007

Extending My.Computer.Audio To Play MP3’sThe My.Computer namespace in VB.NET 2005 provides several ’speed dials’ to various system functions. For example, it can be used to play WAV audio files. Unfortunately, it can’t play other media types like MP3, WMA or MIDI so that limits its usefulness. However, you can extend this, or any other My namespace class, by using partial classes. That’s what I’ll be demonstrating in this article.

For this demo, I used the “PlayingSounds” project from the 101 Visual Basic Samples for WinForms examples from MSDN. These little demo programs are great quick examples on how to do a number of things in VB although they often need a few loose ends tied up to make them work their best.

To get started, we open up the Application Events module. This module exposes the My namespace where we can add functionality to our applications. I covered using it in this earlier article: Tip Sheet: Application Events. Now we need to add a Partial Class to the My namespace to overload the Audio property, like so:

Partial Class MyComputer

Overloads ReadOnly Property Audio() As Audio
    Get
        Return New Audio
    End Get
End Property

End Class

This returns our own Audio object rather than the built in one. Now we are ready to create our own Audio class to play the additional sound files.

First, we need to load a reference to Windows Media Player. So, we go to My Project and the References tab and select “Add Reference”. WMP is a COM object so we select that tab and pick Windows Media Player (wmp.dll) from the list.

Next, we start our own Audio class by inheriting the base Audio class:

Public Class Audio
    Inherits Microsoft.VisualBasic.Devices.Audio

The next part of our code contains a shared reference to the Windows Media Player as well as a indicator of the type of sound we’re playing, if any. Since we only want to play one sound file at a time we use a shared variable here. Also an enum for the sound types is added. We want to keep track of which type of sound is loaded into our audio object since system sounds will use the original Audio class. Here’s the code:

Private Enum SoundTypes
    NoSoundLoaded
    WmpSound
    WavAudioSound
End Enum

Private Shared SoundType As SoundTypes = SoundTypes.NoSoundLoaded
Private Shared WMP As New WMPLib.WindowsMediaPlayer

Now we want to create our overloads for the Play function. The first one has no parameters:

Public Overloads Sub Play()
    If SoundType = SoundTypes.WmpSound AndAlso _
                WMP.playState = WMPLib.WMPPlayState.wmppsPaused Then
                    WMP.controls.play()
    End If
End Sub

In this routine we want to continue playing the currently loaded sound if we’re playing a sound using Windows Media Player and the player is paused. Otherwise, we want to ignore this command. Note that the AndAlso ’short circuits’ the If..Then so if the type is not WMP the state of the player isn’t checked.

Our next two Play overloads allows us to pass in a file location to play. Note that this can be either a local file location or even a URL on a web site. The first only accepts a file location and sends the actual processing to the second play routine which also accepts the Microsoft.VisualBasic.AudioPlayMode.

Public Overloads Sub Play(ByVal fileLocation As String)
    Play(fileLocation, AudioPlayMode.Background)
End Sub

Public Overloads Sub Play(ByVal fileLocation As String, _
                                   ByVal playmode As Microsoft.VisualBasic.AudioPlayMode)
    If SoundType <> SoundTypes.NoSoundLoaded Then
        Me.Stop()
    End If
    Select Case New FileInfo(fileLocation).Extension.ToLower
        Case ".wma", ".mp3", ".mid", ".wav"
            WMP.URL = fileLocation
            Select Case playmode
                Case AudioPlayMode.BackgroundLoop
                    WMP.settings.setMode("loop", True)
                    WMP.controls.play()
                Case Else
                    WMP.settings.setMode("loop", False)
                    WMP.controls.play()
            End Select
            SoundType = SoundTypes.WmpSound
        Case Else
            Throw New Exception("Invalid File Type")
    End Select
End Sub

We want to stop any sound that is currently playing first and then load the new sound into Windows Media Player and play it. If the file extension isn’t a recognized type, we throw an exception. Another approach would be to try to play anything passed to the player and capture any exceptions raised by the player object or to simply ignore any invalid file names without raising an exception. If the second parameter passed in to the routine is AudioPlayMode.BackgroundLoop then we want to play the file over and over until it is stopped. Otherwise, we only want to play it once.

Our remaining Play overloads call the base class. In addition to this call, we add code to stop the currently playing file and an indicator of the file type being played. For the system sounds overloads we add an overload to the standard Play method for this purpose as well as overloading the base PlaySystemSound method.

Public Overloads Sub Play(ByVal systemSound As System.Media.SystemSound)
    If SoundType <> SoundTypes.NoSoundLoaded Then
        Me.Stop()
    End If
    MyBase.PlaySystemSound(systemSound)
    SoundType = SoundTypes.WavAudioSound
End Sub
Public Overloads Sub PlaySystemSound(ByVal systemSound As System.Media.SystemSound)
    If SoundType <> SoundTypes.NoSoundLoaded Then
        Me.Stop()
    End If
    MyBase.PlaySystemSound(systemSound)
    SoundType = SoundTypes.WavAudioSound
End Sub
Public Overloads Sub Play(ByVal mediaData() As Byte, _
                                             ByVal playMode As Microsoft.VisualBasic.AudioPlayMode)
    If SoundType <> SoundTypes.NoSoundLoaded Then
        Me.Stop()
    End If
    MyBase.Play(mediaData, playMode)
    SoundType = SoundTypes.WavAudioSound
End Sub
Public Overloads Sub Play(ByVal mediaStream As System.IO.Stream, _
                                             ByVal playMode As Microsoft.VisualBasic.AudioPlayMode)
    If SoundType <> SoundTypes.NoSoundLoaded Then
        Me.Stop()
    End If
    MyBase.Play(mediaStream, playMode)
    SoundType = SoundTypes.WavAudioSound
End Sub

Now that we have all the play routines taken care of, we’re ready to stop the playing.

Public Overloads Sub [Stop]()
    Select Case SoundType
        Case SoundTypes.WmpSound
            WMP.controls.stop()
        Case SoundTypes.WavAudioSound
            MyBase.Stop()
        Case Else
            'do nothing - if desired, add code to throw an exception here
    End Select
    SoundType = SoundTypes.NoSoundLoaded
End Sub

In this routine we use our sound type enum to determine which method we should use to stop the sound. Note that the Stop routine name is in brackets so that the compiler won’t get it confused with the base VB command of the same name.

Lastly, we add a Pause method. This isn’t in the base class but we’re extending this base to add new functionality.

Public Sub Pause()
    Select Case SoundType
        Case SoundTypes.WmpSound
            WMP.controls.pause()
        Case Else
            'do nothing - if desired, add code to throw an exception here
    End Select
End Sub

Files being played in the base Audio class can only be stopped and started but by using WMP we can pause them as well. This adds another useful function to our new inherited class.

The rest of the application is simply a few improvements to the example program. I added in a pause button checkbox and made a few other enhancements to the program, such as adding in XML comments and improving the file lookup. The code should be fairly self-explanitory but feel free to ask any questions about it here in the comments section. Also, if you notice any bugs or have suggestions for enhancements, please leave a comment.

You can download the code for this project here: PlayingSoundsPlus Code Example

Share This Article: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • DotNetKicks
  • DZone

Entry Filed under: Code Examples


Rate This Article:

Not That GoodCould Be BetterOKGoodGreat (No Ratings Yet)
Loading ... Loading ...

3 Comments Add your own

  • 1. Baruch Berkovits  |  January 5th, 2008 at 2:32 pm

    Great article and great code !!!
    Thanks very much.

  • 2. Amino  |  October 5th, 2008 at 11:07 pm

    Very cool article.

    Is it possible to loop through the songs automatically using this code?

  • 3. Mike B  |  November 4th, 2008 at 6:58 pm

    So, what if you wanted to play an mp3 file from an embedded resource? I can’t find a way to do that… I would stream it from the resource, but the overload for playing a stream seems to work for wav files only.

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Most Popular Articles

Highest Rated Articles

Categories

Most Recent Articles

Feeds

 Subscribe in a reader

To subscribe by e-mail
Enter your address here

Delivered by FeedBurner

VB Opportunities

Archives