How to Play Two Audio Files at the Same Time in VB 6.0 and VB.NET

Click Star to Rate Post
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
 

How you can easily Play 2 or more Audio files Simultaneously using Visual Basic 6.0 and Visual Basic.NET

This article will be using the MCISendString function via the ‘winmm.dll’ library to control the playback and properties of multiple audio files independently from one another. You can mix and match file types like .mp3, .wav, .wma, and .midi files or clips as well.

If you’ve never worked with the Windows Multimedia Command Interface before I suggest you check out my beginner tutorial at this link for an easy step by step guide. It should get you started with a good understanding of the basics on sending Command Strings with the MCISendString function.

Note: The .NET code in this article is compatible with the original versions as well as the 2005, 2008, VB 2010, and newer versions.


This is the API function and variables being used.

VB 6.0 Declare

'The retVal's value is not used for anything specific in this article.
Dim retVal as Long

'Will hold the file path
Dim filename as String

Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long

Visual Basic .NET Declare

'The retVal's value is not used for anything specific in this article.
Dim retVal as Integer

'Will hold the file path
Dim filename as String

Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Integer, ByVal hwndCallback As Intptr) As Integer

OR if you want to use DllImport instead for .NET

'The retVal's value is not used for anything specific in this article.
Dim retVal as Integer

'Will hold the file path
Dim filename as String

<DllImport("winmm.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function mciSendString(commandString As String, returnString As String, _
    returnStringLength As Integer, mciCallback As IntPtr) As Int32
End Function

If you already know the basics of using the Multimedia Command Interface this should pretty much be straightforward. You have one thing to know and one thing to remember.

The one thing you need to know is each time you Open a new music or audio file, set the Alias to a unique name or ID. For instance, look at the code below…

'Replace the path and filename with your .mp3, .wav, etc.

'The chr(34) code add quotes around the path.
fileName = Chr(34) & "C:\Music\mySound1.mp3" & Chr(34)

retVal = mciSendString("open " & fileName & " type mpegvideo alias songNumber1", vbNullString, 0, 0)

That source code opened a new device with an Alias name of: songNumber1.

Now all you need to do for a 2nd file you want to play is Open the device with a different name for the Alias like below…

'Replace the path and filename with your .mp3, .wav, etc.

'The chr(34) code add quotes around the path.
fileName = Chr(34) & "C:\Music\mySound2.mp3" & Chr(34)

retVal = mciSendString("open " & fileName & " type mpegvideo alias songNumber2", vbNullString, 0, 0)

Except for changing the filename, the source code above is exactly like the previous but with a different Alias name or ID. This device is being opened with the Alias songNumber2 instead of songNumber1. You can pretty much use any id or name you want and open as many files as you want.


Ok, the the audio or music files has been opened with the code above. To control each file separately,  you need to remember to use the Alias name you opened it with.

For instance, the code below will change the Left Channel volume to 50% for the songNumber1 file only and not affect any other file.

MCISendString "setaudio songNumber1 left volume to 500", vbNullString, 0, 0

Now this code below will change the Right Channel volume to 50% for songNumber2 only and will not affect songNumber1 or any other file.

MCISendString "setaudio songNumber2 right volume to 500", vbNullString, 0, 0

That’s really all there is to it. Simply remember anytime you want to manipulate one of the audio files you’ve opened, use that files Alias name.

One last thing, if your done with one of the files you’ve opened and want to release its resources, execute the Close command and simply supply the Alias for the file as usual like below…

'Closes only the specified device.

mciSendString("close songNumber1", vbNullString, 0, 0)

That code closed songNumber1 without affecting any other media file, song, or whatever your playing.


I made two example projects for this article. One in VB 2010 and the other in VB 6.0. They use code in this article and will show how to Open and Play 3 songs or clips and control their volume independently of one other.

VB 6 Play Multiple Files

VB 6.0 Example: Download Here

VB.NET Example: Download Here


I guess that’s all for now. If you are playing Movies or Videos, you can use the same process in this article to successfully play more than one video or movie. Pretty much the basics for playing audio and video files are similar using MCI.

Take care,

Jason 🙂

14 thoughts on “How to Play Two Audio Files at the Same Time in VB 6.0 and VB.NET

  1. Jason Post author

    Hi, its not possible to do so with MCI. You could only record it to a wave file, but not convert an mp3 to a wav. Lame Encoder library and the FFMPeg library could do that, and also convert a wave to an MP3 file.

    Thanks,
    Jason

    Reply
  2. Ira

    I do appreciate the code snipits, but I had to download the ZIP file to see how to “play” the wav files.
    Not sure why you did not include:

    retVal = mciSendString("play " & AliasName(f), vbNullString, 0, 0)

    Thanks
    Ira

    Reply
  3. Larry

    Love this! Thank you so much. Works perfectly in VB6. One big question, however:
    I want to set up, for example, a 500ms Timer control that would use some form of mciSendString or other method to constantly check when an Alias has finished playing so that I can automatically restart it or play a different music track.
    Is there an mciSendString I can use to find out when a track has finished playing?

    Reply
    1. Larry

      Also, is there a simple way to SEEK backwards or forwards a specific amount of time while the track is playing?

      Thank you again!

      Reply
      1. Larry

        Okay, I figured out I can add the word repeat to the sendstring command to have the track automatically loop.

        But I still don’t know how I can play Track1 and then automatically play Track2 when Track1 ends. What’s the best way to monitor when a track is finished playing?

        Thanks. Still working on the seek command…

        Reply
  4. Larry

    Well, I figured out the following function:

    Function SoundPosition(Alias As String) As Single
    Dim RetVal As Long, Length As Long, Position As Long, ReturnData As String
    ReturnData = Space(128)
    RetVal = mciSendString(“status Background length”, ReturnData, 128, 0)
    Length = Val(ReturnData)
    RetVal = mciSendString(“status Background position”, ReturnData, 128, 0)
    Position = Val(ReturnData)
    If Length > 0 Then
    SoundPosition = Position / Length * 100
    Else
    SoundPosition = -1
    End If
    End Function

    The problem is, this works for shorter tracks, say, 3 minutes. But it fails with longer tracks such as 14 minutes. (In the latter case, Position and Length both return 0.)

    Reply
    1. Larry

      Oh, I’m so stupid. Was fooling around and left a piece of code there that messed up the function. This is the correct function and it works!
      Function SoundPosition(Alias As String) As Single
      Dim RetVal As Long, Length As Long, Position As Long, ReturnData As String
      ReturnData = Space(128)
      ‘RetVal = mciSendString(“Set MediaFile time format milliseconds”, vbNullString, 0, 0)
      RetVal = mciSendString(“status ” & Alias & ” length”, ReturnData, 128, 0)
      Length = Val(ReturnData)
      RetVal = mciSendString(“status ” & Alias & ” position”, ReturnData, 128, 0)
      Position = Val(ReturnData)
      If Length > 0 Then
      SoundPosition = Position / Length * 100
      Else
      SoundPosition = -1
      End If
      End Function

      And with that, I can create a seek routine:

      Function SoundSeek(Alias As String, SeekFraction As Single)
      ‘Try using -.2 or .2 to seek backwards or forwards just a bit
      Dim RetVal As Long, ReturnData As String, Position As Long, NewPosition As Long
      ReturnData = Space(128)
      RetVal = mciSendString(“status ” & Alias & ” position”, ReturnData, 128, 0)
      Position = Val(ReturnData)
      NewPosition = Position + SeekFraction * Position
      Call SoundPause(Alias) ‘It’s necessary to mcisendstring the pause command while seeking
      RetVal = mciSendString(“seek ” & Alias & ” to ” & NewPosition, vbNullString, 0, 0)
      Call SoundResume(Alias) ‘After seek, send mcisendstring play to continue
      End Function

      Reply
  5. Steve

    Hi Jason, That works great.

    I need to use 2 sounds at the same time in my slot machine program I made in VB6 but currently I just cant get it to work, mostly I would need to call one sound and have it loop while some other sounds may have to play over without the original stopping. Is there a way to do this as im not very good with how you have managed it.
    I currently use :
    Private Declare Function sndPlaySound Lib “winmm.dll” Alias “sndPlaySoundA” (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long
    And
    sndPlaySound (App.Path & “\Sound\Featurerun.wav”), SND_ASYNC Or SND_LOOP Or SND_NODEFAULT to call a sound in my program but calling any other sound stops the current one playing using my method.

    Is your way able to do something my method cant?

    Any help would be great.

    Reply
  6. Jason Post author

    Hi Steve, yes the MCISendString method in the post will allow you to play multiple files at the same time and control them. The Playsound API will not allow more than one file to be controlled on the same process.

    Just use the code in the article and you should be fine.

               Jason
    
    Reply
  7. Steve

    Hi Thanks for the quick reply, but being a novice im stuggling to get it to work in the way im used to calling sounds. I have put your code in several times but I cant get it to do what I want and think I might just have to stick with the way I do it now 🙁 which is rubbish compared to your way.

    Any help with this would be greatly received

    Reply
  8. Jason Post author

    Download the example at the bottom of the article. It shows how to play and control up to 3 files at the same time. Then just put the relevant parts of the code in your program. Should work fine after you tell it the files you’re wanting to play.

           Jason
    
    Reply
  9. Steve

    Hi Jason,
    Thanks again, ok I have had another tinker with this today,
    So am I right in these points:-
    1. The sounds have to be pre loaded, you cant just directly play.
    2. You can only play them once.
    3. You have to close and re load before playing again?
    4. Someone mentioned adding the word repeat to have one looping where does that get put?

    Regards,

    Reply

Leave a Reply