locked
Win32 MCI API for playing media

    General discussion


  • Hi all
    We often see questions in here regarding how do I play so and so media. Very often I recommend the WIn32 MCI API. The following declarations for SendString etc. can play most media in Windows - you send it the device type, then the name of the file, then send the command to open the file, then the command to play the file etc.
    Below in an example for playing two or more audio files (waves) simultaneously. I might add more about the Win32 MCI API later.
    Allan


    In a code module put the Win32 API declarations (such as):

    Public Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As Integer, ByVal uMessage As String, ByVal dwParam1 As Integer, ByVal dwParam2 As Object) As Integer

    Public Declare Function mciGetErrorString Lib "winmm.dll" Alias "mciGetErrorStringA" (ByVal dwError As Integer, ByVal lpstrBuffer As String, ByVal uLength As Integer) As Integer

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


    Then in your program, you can play as many sounds as you like simulataneously using API calls such as:

    ret = mciSendString("Open " & Chr(34) & FileName & Chr(34) & " alias audio", CStr(0), 0, 0)

    ret = mciSendString("play audio", CStr(0), 0, 0)

    ret = mciSendString("pause audio", CStr(0), 0, 0)

    ret = mciSendString("resume audio", CStr(0), 0, 0)

    ret = mciSendString("stop audio", CStr(0), 0, 0)

    ret = mciSendString("close audio", CStr(0), 0, 0)

    etc.etc.,
    Points:
    1) 'ret' is an integer (long in vb6) holding the return code: - 0 means success, non-zero is an appropriate MCI error code.
    2) Use a different alias in mciSendString for each sound file - e.g. alias audio1, alias audio2, alias audio3, etc. - if you are playing multiple files on the same form (as it avoids clashes).
    3) The MCI command set is a very rich one - see the MSDN documentation of the 100's of commands and permutations possible.
    4) There are numerous Get and Set MCI commands for querying and setting various things - such as volume, balance, position in the file, status (i.e. playing, paused, stopped), etc.
    5) You will be stepping out of the .Net environment and will be using the Win32 MCI API instead.

    Thursday, August 21, 2008 6:06 PM

All replies

  • Win32 MCI API Device Types (taken from MSDN documentation):

    Devices are considered to be of two types: simple and compound. Simple multimedia devices do not require a data file for playback. For example, when Videodisc and CD audio players are opened, you play, rewind, or forward through 'tracks'. Compound devices, however, require a data file for playback.

    The following table lists some of the devices supported by the Multimedia control and the string required by the DeviceType 'property' to use the device. Those listing an accompanying file type are compound devices.

    Device type                 String          File Type     Description
    CD audio                  CDAudio                           CD audio player
    Digital Audio Tape    DAT                                  Digital audio tape player
    Digital video             DigitalVideo                      Digital video in a window (not GDI-based)
    Other                       Other                               Undefined MCI device
    Overlay                    Overlay                            Overlay device 
    Scanner                   Scanner                            Image scanner
    Sequencer               Sequencer     .mid            Musical Instrument Digital Interface  (MIDI) sequencer
    Vcr                           VCR                                  Video cassette recorder or player
    AVI                          AVIVideo        .avi             Audio Visual Interleaved video. 
    Mpeg Video               MPEGVideo   .mpg          MPEG Video in its own window
    Videodisc                Videodisc                          Videodisc player
    Wave audio           Waveaudio      .wav           Wave device that plays digitized waveform files.

    Thursday, August 21, 2008 6:33 PM
  • Typical MCI commands are:

    Command Description
    Open   Opens a MCI device.
    Close   Closes a MCI device.
    Play   Plays a MCI device.
    Pause  PAUSE or  RESUME Pauses playing or recording.
    Stop   Stops a MCI device.
    Back   Steps backward through available tracks.
    Step   Steps forward through available tracks.
    Prev   Goes to the beginning of the current track using the Seek command. If executed within three seconds of the previous Prev command, goes to the beginning of the previous track or to the beginning of the first track if at the first track.
    Next   Goes to the beginning of the next track (if at last track, goes to the beginning of the last track) using the Seek command.
    Seek   Seeks track forward or backward.
    Record   Records MCI device input.
    Eject   Ejects Audio CD from CD drive (opens/closes door)
    Save   Saves an open file.
    Thursday, August 21, 2008 6:41 PM
  • Congratulations! The code you provided is very interesting...


    Thank you!
    Thursday, August 21, 2008 8:09 PM
  • Some examples (taken from a VB6 program I wote):

    ret = mciSendString(ByVal "C:\Media\mymovie.avi type AVIVideo alias media", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)
    ret = mciSendString(ByVal "play media wait", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)
    ret = mciSendString(ByVal "stop media ", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)
    ret = mciSendString(ByVal "close media ", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)

    -----------------------------------------------------------

    ret = mciSendString(ByVal "open CDAudio alias media ", ByVal lpszReturnString,ByVal lstrlen(lpszReturnString), ByVal 0)
    ret = mciSendString(ByVal "set media time format tmsf", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)
    ret = mciSendString(ByVal "play media from 1 to 2 wait", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)
    ret = mciSendString(ByVal "stop media ", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)
    ret = mciSendString(ByVal "close media ", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)

    -----------------------------------------------------------
    ret = mciSendString(ByVal "open C:\Media\halsorry.wav type WaveAudio alias media", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)
    ret = mciSendString(ByVal "play media wait", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)
    ret = mciSendString(ByVal "close media", ByVal lpstrReturnString, ByVal Len(lpstrReturnString), ByVal 0)

    -----------------------------------------------------------

    Should be enough to start people off.
    Allan

    Note:
    I defined lpstrReturnString as a fixed length of 128 chars in the vb6 prog.
    In vb.Net you'd just do:

    Dim lpstrReturnString As String = Space(128) 'or something like that

    • Edited by bigamee Thursday, August 21, 2008 8:45 PM added note
    Thursday, August 21, 2008 8:34 PM
  • Angelos Sfakianakis said:

    Congratulations! The code you provided is very interesting...


    Thank you!



    Your welcome - I'm surprised that .Net seemingly has no substitute for the MCI API declarations.
    Allan
    Thursday, August 21, 2008 9:07 PM
  • A quick example (took about 20 minutes to write) of using the WIn32 MCI API from vb.net to play mp3 files.

    Create a new project, and double-click the blank form and paste the following code into the form, modify the path in the code to your Mp3s, and run it.
    Select an mp3 file from the drop-down combo, click the Open button, then the play button. Note the file has to be closed beore the Exit button is active.
    Please note it's just a bit of quick and ready code to play mp3s to illustrate playing Mp3s using the Win32 MCI API. A lot of work would be needed to make it a really useful and robust Mp3 player.
    Allan

    Imports System.Windows.Forms  
     
    Public Class Form1  
        Public Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As IntegerByVal uMessage As StringByVal dwParam1 As IntegerByVal dwParam2 As ObjectAs Integer 
        Public Declare Function mciGetErrorString Lib "winmm.dll" Alias "mciGetErrorStringA" (ByVal dwError As IntegerByVal lpstrBuffer As StringByVal uLength As IntegerAs Integer 
        Public Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As StringByVal lpstrReturnString As StringByVal uReturnLength As IntegerByVal hwndCallback As IntegerAs Integer 
     
        Dim btnExit As New Button  
        Dim cmbMP3 As New ComboBox  
        Dim lblMP3 As New Label  
        Dim btnOpen As New Button  
        Dim btnPlay As New Button  
        Dim btnStop As New Button  
        Dim btnClose As New Button  
        Dim Opened As Boolean = False 
        Dim Status As Boolean = False 
        Dim whatdir As String 
     
        Private Sub Form1_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load  
            Me.DoubleBuffered = True 
            Me.Text = "Media Player" 
            Me.Width = 800  
            Me.Height = 480  
            Me.StartPosition = FormStartPosition.CenterScreen  
            btnExit = New Button With {.Text = "E&xit", .Width = 34, .Height = 29, .Top = Me.Height - 75, .Left = Me.Width - 65, .Anchor = AnchorStyles.Right + AnchorStyles.Bottom}  
            cmbMP3 = New ComboBox With {.Text = "", .Width = 600, .Height = 100, .Top = 100, .Left = 50}  
            lblMP3 = New Label With {.Text = "", .Width = 600, .Height = 100, .Top = 70, .Left = 50}  
            btnOpen = New Button With {.Text = "&Open", .Width = 50, .Height = 29, .Top = 200, .Left = 50, .Enabled = False}  
            btnPlay = New Button With {.Text = "&Play", .Width = 50, .Height = 29, .Top = 200, .Left = 100, .Enabled = False}  
            btnStop = New Button With {.Text = "&Stop", .Width = 50, .Height = 29, .Top = 200, .Left = 150, .Enabled = False}  
            btnClose = New Button With {.Text = "&Close", .Width = 50, .Height = 29, .Top = 200, .Left = 200, .Enabled = False}  
            Me.Controls.Add(btnExit)  
            AddHandler btnExit.Click, AddressOf btnExit_Click  
            Me.Controls.Add(btnOpen)  
            AddHandler btnOpen.Click, AddressOf btnOpen_Click  
            Me.Controls.Add(btnPlay)  
            AddHandler btnPlay.Click, AddressOf btnPlay_Click  
            Me.Controls.Add(btnStop)  
            AddHandler btnStop.Click, AddressOf btnStop_Click  
            Me.Controls.Add(btnClose)  
            AddHandler btnClose.Click, AddressOf btnClose_Click  
            Me.Controls.Add(cmbMP3)  
            AddHandler cmbMP3.Click, AddressOf cmbMP3_click  
            AddHandler cmbMP3.TextChanged, AddressOf cmbMP3_TextChanged  
            Call populateCmbMp3("C:\mp3s")  
            Me.Controls.Add(lblMP3)  
        End Sub 
     
        Private Sub btnExit_Click()  
            Me.Close()  
            Application.Exit()  
        End Sub 
     
        Private Sub cmbMP3_click()  
            Dim itemtext As String 
            itemtext = cmbMP3.Text  
            lblMP3.Text = itemtext  
            lblMP3.Refresh()  
        End Sub 
     
        Private Sub cmbMP3_TextChanged()  
            Dim itemtext As String 
            itemtext = cmbMP3.Text  
            lblMP3.Text = itemtext  
            lblMP3.Refresh()  
            btnOpen.Enabled = True 
            btnClose.Enabled = False 
            btnPlay.Enabled = False 
            btnStop.Enabled = False 
        End Sub 
     
     
        Private Sub Form1_Resize(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Resize  
            If Me.Width < 600 Then 
                Me.Width = 600  
            End If 
            If Me.Height < 400 Then 
                Me.Height = 400  
            End If 
            Me.Refresh()  
        End Sub 
     
        Private Sub populateCmbMp3(ByVal Filepath)  
            Dim FoundFile As String 
            Dim FileName As String 
     
            ' Clear the list box.  
            Me.cmbMP3.Items.Clear()  
     
            ' Add each file in the Documents folder to list box.  
            For Each FoundFile In My.Computer.FileSystem.GetFiles( _  
                Filepath, FileIO.SearchOption.SearchAllSubDirectories)  
                'Get directory  
                FileName = My.Computer.FileSystem.GetDirectoryInfo(FoundFile).ToString 'Add full path to the combo box  
                ' Note: if you want to add only the name of each found file to the combo box, uncomment next line ad modify open  
                ' FileName = My.Computer.FileSystem.GetName(FoundFile)  
                If FileName.Substring(Len(FileName) - 4) = ".mp3" Then 
                    Me.cmbMP3.Items.Add(FileName)  
                End If 
            Next 
            If Me.cmbMP3.Items.Count > 0 Then 
                Me.cmbMP3.SelectedIndex = 0  
            End If 
        End Sub 
     
        Private Sub btnOpen_Click()  
            Dim ret As Integer 
            If lblMP3.Text = "" Then 
                Exit Sub 
            End If 
            ret = mciSendString("Open " & Chr(34) & lblMP3.Text & Chr(34) & " alias audio"CStr(0), 0, 0)  
            If ret = 0 Then 
                Opened = True 
                btnOpen.Enabled = False 
                btnClose.Enabled = True 
                btnPlay.Enabled = True 
                btnStop.Enabled = True 
                cmbMP3.Enabled = False 
                btnExit.Enabled = False 
            Else 
                MsgBox("Error opening file")  
                Opened = False 
                btnOpen.Enabled = False 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnStop.Enabled = False 
                btnExit.Enabled = True 
            End If 
        End Sub 
     
        Private Sub btnPlay_Click()  
            Dim ret As Integer 
            If lblMP3.Text = "" Or Opened = False Then 
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnStop.Enabled = True 
                Exit Sub 
            End If 
            ret = mciSendString("play audio"CStr(0), 0, 0)  
            If ret <> 0 Then 
                MsgBox("Error playing file")  
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnStop.Enabled = False 
                btnExit.Enabled = False 
            End If 
        End Sub 
     
        Private Sub btnStop_Click()  
            Dim ret As Integer 
            If lblMP3.Text = "" And Opened = True Then 
                Exit Sub 
            End If 
            ret = mciSendString("stop audio"CStr(0), 0, 0)  
            If ret <> 0 Then 
                MsgBox("Error stopping file")  
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnStop.Enabled = False 
                btnExit.Enabled = False 
            End If 
        End Sub 
     
        Private Sub btnClose_Click()  
            Dim ret As Integer 
            ret = mciSendString("close audio"CStr(0), 0, 0)  
            Opened = False 
            btnOpen.Enabled = True 
            btnClose.Enabled = False 
            btnPlay.Enabled = False 
            btnStop.Enabled = False 
            btnExit.Enabled = True 
            cmbMP3.Enabled = True 
            If ret <> 0 Then 
                MsgBox("Error closing file")  
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnStop.Enabled = False 
                btnExit.Enabled = False 
                cmbMP3.Enabled = False 
            End If 
        End Sub 
    End Class 
     
    • Edited by bigamee Sunday, September 28, 2008 12:15 PM added a couple of lines
    Sunday, September 28, 2008 10:26 AM
  • Hi all
    I've just spent the last couple of hours tidying up the Win32 MCI API mp3 player - added some more controls and a bit more functionality and made it a lot better. It should suffice now as a kind of blueprint for using the Win32 MCI API from vb.net.
    Just copy and paste the following code into a blank form on a new project. Change the path in the code to where your MP3s are and run the program. Everything is done for you - it will create the controls etc.
    Allan

    Dam the listing is now too big - just a sec while I post it in a separate post or two.
    • Edited by bigamee Tuesday, September 30, 2008 7:04 PM spelling
    Tuesday, September 30, 2008 6:40 PM
  • The listing part one:
    Option Strict On 
    Option Explicit On 
    Option Infer On 
    Imports System.Windows.Forms  
     
    Public Class Form1  
        Public Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As IntegerByVal uMessage As StringByVal dwParam1 As IntegerByVal dwParam2 As ObjectAs Integer 
        Public Declare Function mciGetErrorString Lib "winmm.dll" Alias "mciGetErrorStringA" (ByVal dwError As IntegerByVal lpstrBuffer As StringByVal uLength As IntegerAs Integer 
        Public Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As StringByVal lpstrReturnString As StringByVal uReturnLength As IntegerByVal hwndCallback As IntegerAs Integer 
     
        Dim btnExit As New Button  
        Dim cmbMP3 As New ComboBox  
        Dim lblMP3 As New Label  
        Dim btnOpen As New Button  
        Dim btnPlay As New Button  
        Dim btnPause As New Button  
        Dim btnResume As New Button  
        Dim btnMute As New Button  
        Dim btnStop As New Button  
        Dim btnClose As New Button  
        Dim playlist As New ListBox  
        Dim lblmutelight As New Label  
        Dim lblMute As New Label  
        Dim lblVolume As New Label  
        Dim lblVolumeValue As New Label  
        Dim sldVolume As New HScrollBar  
        Dim Opened As Boolean = False 
        Dim Status As Boolean = False 
        Dim muted As Boolean = False 
        Dim whatdir As String 
     
        Private Sub Form1_FormClosing(ByVal sender As ObjectByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing  
            Dim reply As Integer, ret As Integer 
            reply = MsgBox("Are you sure that you want to quit?", MsgBoxStyle.YesNoCancel Or MsgBoxStyle.Question)  
            If reply = vbYes Then 
                'Note: - we are not really concerned if the file is already stopped and/or closed or not (i.e. if ret = true or false on on return)  
                'since we are telling the MCI API to do it anyways so it's safe to exit  
                ret = mciSendString("stop audio"CStr(0), 0, 0) 'Just to be on the safe side  
                ret = mciSendString("close audio"CStr(0), 0, 0) 'Just to be on the safe side  
                sldVolume.Enabled = False 'Just to be safe  
                muted = False 'Just to be safe  
                lblmutelight.BackColor = Color.Black 'Just to be safe  
                e.Cancel = False 'Application should now end gracefully here  
            Else 
                e.Cancel = True 
            End If 
        End Sub 
     
        Private Sub Form1_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load  
            Dim ret As Integer 
            Me.DoubleBuffered = True 
            Me.Text = "Media Player" 
            Me.Width = 800  
            Me.Height = 480  
            Me.StartPosition = FormStartPosition.CenterScreen  
            btnExit = New Button With {.Text = "E&xit", .Width = 34, .Height = 29, .Top = 400, .Left = Me.Width - 65, .Anchor = AnchorStyles.Right Or AnchorStyles.Bottom, .Enabled = True}  
            cmbMP3 = New ComboBox With {.Text = "", .Width = 600, .Height = 20, .Top = 50, .Left = 50}  
            lblMP3 = New Label With {.Text = "", .Width = 600, .Height = 20, .Top = 30, .Left = 50}  
            btnOpen = New Button With {.Text = "&Open", .Width = 70, .Height = 29, .Top = 400, .Left = 50, .Enabled = False}  
            btnPlay = New Button With {.Text = "&Play", .Width = 70, .Height = 29, .Top = 400, .Left = 120, .Enabled = False}  
            btnPause = New Button With {.Text = "P&ause", .Width = 70, .Height = 29, .Top = 400, .Left = 190, .Enabled = False}  
            btnResume = New Button With {.Text = "&Resume", .Width = 70, .Height = 29, .Top = 400, .Left = 260, .Enabled = False}  
            btnStop = New Button With {.Text = "&Stop", .Width = 70, .Height = 29, .Top = 400, .Left = 330, .Enabled = False}  
            btnMute = New Button With {.Text = "&Mute", .Width = 70, .Height = 29, .Top = 400, .Left = 400, .Enabled = False}  
            btnClose = New Button With {.Text = "&Close", .Width = 70, .Height = 29, .Top = 400, .Left = 480, .Enabled = False}  
            playlist = New ListBox With {.Text = "", .Width = 600, .Height = 300, .Top = 90, .Left = 50}  
            lblmutelight = New Label With {.Text = "", .Width = 10, .Height = 10, .Top = 410, .Left = 560, .BorderStyle = BorderStyle.Fixed3D, .BackColor = Color.Black}  
            lblMute = New Label With {.Text = "Muted:", .Width = 40, .Height = 20, .Top = 390, .Left = 550, .BorderStyle = BorderStyle.None}  
            sldVolume = New HScrollBar With {.Width = 125, .Height = 20, .Top = 410, .Left = 600, .Minimum = 0, .Maximum = 1000, .Value = 500, .Enabled = False}  
            lblVolume = New Label With {.Text = "Volume:", .Width = 50, .Height = 20, .Top = 390, .Left = 600, .BorderStyle = BorderStyle.None}  
            lblVolumeValue = New Label With {.Text = "500", .Width = 35, .Height = 20, .Top = 390, .Left = 650, .BorderStyle = BorderStyle.FixedSingle, .TextAlign = ContentAlignment.MiddleRight}  
            Me.Controls.Add(btnExit)  
            AddHandler btnExit.Click, AddressOf btnExit_Click  
            Me.Controls.Add(btnOpen)  
            AddHandler btnOpen.Click, AddressOf btnOpen_Click  
            Me.Controls.Add(btnPlay)  
            AddHandler btnPlay.Click, AddressOf btnPlay_Click  
            Me.Controls.Add(btnPause)  
            AddHandler btnPause.Click, AddressOf btnPause_Click  
            Me.Controls.Add(btnResume)  
            AddHandler btnResume.Click, AddressOf btnResume_click  
            Me.Controls.Add(btnMute)  
            AddHandler btnMute.Click, AddressOf btnMute_click  
            Me.Controls.Add(btnStop)  
            AddHandler btnStop.Click, AddressOf btnStop_Click  
            Me.Controls.Add(btnClose)  
            AddHandler btnClose.Click, AddressOf btnClose_Click  
            Me.Controls.Add(cmbMP3)  
            AddHandler cmbMP3.Click, AddressOf cmbMP3_click  
            AddHandler cmbMP3.TextChanged, AddressOf cmbMP3_TextChanged  
            Call populateCmbMp3("C:\mp3s")  
            Me.Controls.Add(lblMP3)  
            Me.Controls.Add(lblmutelight)  
            Me.Controls.Add(lblMute)  
            Me.Controls.Add(playlist)  
            AddHandler playlist.Click, AddressOf playlist_click  
            AddHandler playlist.TextChanged, AddressOf playlist_TextChanged  
            Me.Controls.Add(sldVolume)  
            Me.Controls.Add(lblVolume)  
            Me.Controls.Add(lblVolumeValue)  
            AddHandler sldVolume.Scroll, AddressOf sldVolume_Scroll  
            muted = False 
            lblmutelight.BackColor = Color.Black  
            ret = mciSendString("setaudio audio volume to " & CStr(sldVolume.Value), CStr(0), 0, 0) 'We assume that this ret will be zero  
        End Sub 
     
        Private Sub sldVolume_Scroll(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim ret As Integer 
            If Opened = False Then 
                Exit Sub 'Nothing open  
            End If 
            ret = mciSendString("setaudio audio volume to " & CStr(sldVolume.Value), CStr(0), 0, 0) 'We assume that this ret will be zero  
            If ret <> 0 Then 
                MsgBox("Unable to set volume")  
            Else 
                lblVolumeValue.Text = CStr(sldVolume.Value)  
            End If 
        End Sub 
     
    Tuesday, September 30, 2008 6:44 PM
  • The listing part two:
     
        Private Sub btnExit_Click(ByVal sender As ObjectByVal e As System.EventArgs)  
            Application.Exit()  
        End Sub 
     
        Private Sub cmbMP3_click(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim itemtext As String 
            Dim ret As Integer 
            'Note: - we are not really concerned if the file is already stopped and/or closed or not (i.e. if ret = true or false on on return)  
            'since we are telling the MCI API to do it anyways so it's safe to exit  
            ret = mciSendString("stop audio"CStr(0), 0, 0) 'Just to be on the safe side  
            ret = mciSendString("close audio"CStr(0), 0, 0) 'Just to be on the safe side  
            muted = False 
            lblmutelight.BackColor = Color.Black  
            itemtext = cmbMP3.Text  
            lblMP3.Text = itemtext  
            lblMP3.Refresh()  
            playlist.Text = itemtext  
            playlist.Refresh()  
        End Sub 
     
        Private Sub cmbMP3_TextChanged(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim itemtext As String 
            Dim ret As Integer 
            'Note: - we are not really concerned if the file is already stopped and/or closed or not (i.e. if ret = true or false on on return)  
            'since we are telling the MCI API to do it anyways so it's safe to exit  
            ret = mciSendString("stop audio"CStr(0), 0, 0) 'Just to be on the safe side  
            ret = mciSendString("close audio"CStr(0), 0, 0) 'Just to be on the safe side  
            muted = False 
            lblmutelight.BackColor = Color.Black  
            itemtext = cmbMP3.Text  
            lblMP3.Text = itemtext  
            lblMP3.Refresh()  
            playlist.Text = itemtext  
            playlist.Refresh()  
            btnOpen.Enabled = True 
            btnPlay.Enabled = False 
            btnPause.Enabled = False 
            btnResume.Enabled = False 
            btnStop.Enabled = False 
            btnClose.Enabled = False 
        End Sub 
     
        Private Sub playlist_click(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim itemtext As String 
            Dim ret As Integer 
            'Note: - we are not really concerned if the file is already stopped and/or closed or not (i.e. if ret = true or false on on return)  
            'since we are telling the MCI API to do it anyways so it's safe to exit  
            ret = mciSendString("stop audio"CStr(0), 0, 0) 'Just to be on the safe side  
            ret = mciSendString("close audio"CStr(0), 0, 0) 'Just to be on the safe side  
            muted = False 
            lblmutelight.BackColor = Color.Black  
            itemtext = playlist.Text  
            playlist.Text = itemtext  
            playlist.Refresh()  
            lblMP3.Text = itemtext  
            lblMP3.Refresh()  
            cmbMP3.Text = itemtext  
            cmbMP3.Refresh()  
        End Sub 
     
        Private Sub playlist_TextChanged(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim itemtext As String 
            Dim ret As Integer 
            'Note: - we are not really concerned if the file is already stopped and/or closed or not (i.e. if ret = true or false on on return)  
            'since we are telling the MCI API to do it anyways so it's safe to exit  
            ret = mciSendString("stop audio"CStr(0), 0, 0) 'Just to be on the safe side  
            ret = mciSendString("close audio"CStr(0), 0, 0) 'Just to be on the safe side  
            muted = False 
            lblmutelight.BackColor = Color.Black  
            itemtext = playlist.Text  
            playlist.Text = itemtext  
            playlist.Refresh()  
            lblMP3.Text = itemtext  
            lblMP3.Refresh()  
            cmbMP3.Text = itemtext  
            cmbMP3.Refresh()  
            btnOpen.Enabled = True 
            btnPlay.Enabled = False 
            btnPause.Enabled = False 
            btnResume.Enabled = False 
            btnStop.Enabled = False 
            btnClose.Enabled = False 
        End Sub 
     
        Private Sub Form1_Resize(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Resize  
            If Me.Width < 600 Then 
                Me.Width = 600  
            End If 
            If Me.Height < 400 Then 
                Me.Height = 400  
            End If 
            Me.Refresh()  
        End Sub 
     
        Private Sub populateCmbMp3(ByVal Filepath As String)  
            Dim FoundFile As String 
            Dim FileName As String 
     
            ' Clear the list box.  
            Me.cmbMP3.Items.Clear()  
            Me.playlist.Items.Clear()  
            Me.playlist.BeginUpdate()  
            ' Add each file in the Documents folder to list box.  
            For Each FoundFile In My.Computer.FileSystem.GetFiles(Filepath.ToString, FileIO.SearchOption.SearchAllSubDirectories)  
                'Get directory  
                FileName = My.Computer.FileSystem.GetDirectoryInfo(FoundFile).ToString 'Add full path to the combo box  
                ' Note: if you want to add only the name of each found file to the combo box, uncomment the next line and modify the open routine  
                ' FileName = My.Computer.FileSystem.GetName(FoundFile)  
                If FileName.Substring(Len(FileName) - 4) = ".mp3" Then 
                    Me.cmbMP3.Items.Add(FileName)  
                    Me.playlist.Items.Add(FileName)  
                End If 
            Next 
            Me.playlist.EndUpdate()  
            If Me.cmbMP3.Items.Count > 0 Then 
                Me.cmbMP3.SelectedIndex = 0  
                Me.playlist.SelectedIndex = 0  
            End If 
        End Sub 
     
        Private Sub btnOpen_Click(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim ret As Integer 
            If lblMP3.Text = "" Then 
                Exit Sub 
            End If 
            ret = mciSendString("Open " & Chr(34) & lblMP3.Text & Chr(34) & " alias audio"CStr(0), 0, 0)  
            If ret = 0 Then 
                Opened = True 
                btnOpen.Enabled = False 
                btnPlay.Enabled = True 
                btnPause.Enabled = False 
                btnResume.Enabled = False 
                btnStop.Enabled = False 
                btnClose.Enabled = True 
                sldVolume.Enabled = True 
            Else 
                MsgBox("Error opening file")  
                Opened = False 
                btnOpen.Enabled = False 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnPause.Enabled = False 
                btnResume.Enabled = False 
                btnStop.Enabled = False 
                btnExit.Enabled = True 
                sldVolume.Enabled = False 
            End If 
        End Sub 
     
        Private Sub btnPlay_Click(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim ret As Integer 
            If lblMP3.Text = "" Or Opened = False Then 
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnPause.Enabled = False 
                btnResume.Enabled = False 
                btnMute.Enabled = False 
                lblmutelight.BackColor = Color.Black  
                btnStop.Enabled = True 
                Exit Sub 
            End If 
            ret = mciSendString("play audio"CStr(0), 0, 0)  
            If ret <> 0 Then 
                MsgBox("Error playing file")  
                btnOpen.Enabled = False 
                btnPlay.Enabled = False 
                btnPause.Enabled = False 
                btnResume.Enabled = False 
                btnMute.Enabled = False 
                btnStop.Enabled = False 
                btnClose.Enabled = True 
                btnExit.Enabled = True 
            Else 
                'Playing ok  
                btnOpen.Enabled = False 
                btnPlay.Enabled = False 
                btnPause.Enabled = True 
                btnResume.Enabled = False 
                btnMute.Enabled = True 
                btnStop.Enabled = True 
                btnClose.Enabled = True 
                btnExit.Enabled = True 
            End If 
        End Sub 
     
     
        Private Sub btnPause_click(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim ret As Integer 
            If lblMP3.Text = "" Or Opened = False Then 
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnStop.Enabled = True 
                Exit Sub 
            End If 
            ret = mciSendString("pause audio"CStr(0), 0, 0)  
            If ret <> 0 Then 
                MsgBox("Error pausing file")  
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnStop.Enabled = False 
                btnExit.Enabled = True 
            Else 
                'Paused ok  
                btnOpen.Enabled = False 
                btnPlay.Enabled = True 
                btnPause.Enabled = False 
                btnResume.Enabled = True 
                btnStop.Enabled = True 
                btnClose.Enabled = True 
            End If 
        End Sub 
     
        Private Sub btnResume_click(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim ret As Integer 
            If lblMP3.Text = "" Or Opened = False Then 
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnStop.Enabled = True 
                Exit Sub 
            End If 
            ret = mciSendString("resume audio"CStr(0), 0, 0)  
            If ret <> 0 Then 
                MsgBox("Error resuming file")  
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnStop.Enabled = False 
                btnExit.Enabled = True 
            Else 
                'Resumed ok  
                btnOpen.Enabled = False 
                btnPlay.Enabled = False 
                btnPause.Enabled = True 
                btnResume.Enabled = False 
                btnStop.Enabled = True 
                btnClose.Enabled = True 
            End If 
        End Sub 
     
    Tuesday, September 30, 2008 6:56 PM
  • The listing part three (hopefully the last bit):
    Allan

     
        Private Sub btnMute_Click(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim ret As Integer 
            If lblMP3.Text = "" And Opened = True Then 
                Exit Sub 
            End If 
            If muted = False Then 
                ret = mciSendString("setaudio audio off"CStr(0), 0, 0)  
                lblmutelight.BackColor = Color.Green  
                muted = True 
            Else 
                ret = mciSendString("setaudio audio on"CStr(0), 0, 0)  
                lblmutelight.BackColor = Color.Black  
    5:          muted = False 
            End If 
            If ret <> 0 Then 
                MsgBox("Error muting file")  
                btnMute.Enabled = False 
                lblmutelight.BackColor = Color.Black  
            Else 
                'Muted/Unmuted ok  
                btnMute.Enabled = True 
            End If 
        End Sub 
     
        Private Sub btnStop_Click(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim ret As Integer 
            If lblMP3.Text = "" And Opened = True Then 
                Exit Sub 
            End If 
            ret = mciSendString("stop audio"CStr(0), 0, 0)  
            If ret <> 0 Then 
                MsgBox("Error stopping file")  
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnStop.Enabled = False 
                btnExit.Enabled = True 
            Else 
                'Stopped ok  
                btnOpen.Enabled = False 
                btnPlay.Enabled = True 
                btnPause.Enabled = False 
                btnResume.Enabled = False 
                btnStop.Enabled = False 
                btnClose.Enabled = True 
            End If 
        End Sub 
     
        Private Sub btnClose_Click(ByVal sender As ObjectByVal e As System.EventArgs)  
            Dim ret As Integer 
            ret = mciSendString("close audio"CStr(0), 0, 0)  
            Opened = False 
            btnOpen.Enabled = True 
            btnPlay.Enabled = False 
            btnPause.Enabled = False 
            btnResume.Enabled = False 
            btnMute.Enabled = False 
            muted = False 
            lblmutelight.BackColor = Color.Black  
            btnStop.Enabled = False 
            btnClose.Enabled = False 
            btnExit.Enabled = True 
            cmbMP3.Enabled = True 
            sldVolume.Enabled = False 
            If ret <> 0 Then 
                MsgBox("Error closing file")  
                btnOpen.Enabled = True 
                btnClose.Enabled = False 
                btnPlay.Enabled = False 
                btnPause.Enabled = False 
                btnResume.Enabled = False 
                btnStop.Enabled = False 
                btnExit.Enabled = True 
                btnMute.Enabled = False 
                lblmutelight.BackColor = Color.Black  
                cmbMP3.Enabled = False 
                sldVolume.Enabled = False 
            End If 
        End Sub 
    End Class 
     
    Tuesday, September 30, 2008 6:59 PM
  • Thank you so much for this, it's a great help.

    I was using DirectX to play audio, but I now need to do much more complicated things, and I'd been struggling though MCI, so its good to see it clearly laid out here.

    One thing that's foxing me at the moment though is:

    Public Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As Integer, ByVal uMessage As String, ByVal dwParam1 As Integer, ByVal dwParam2 As Object) As Integer

    Because what I've been trying to do, is select which soundcard audio should be played though. True, I can do it with DirectSound, and select which one of the four (!) soundcards in my system with something like:

            SoundDevice = New Device(devList(ComboBox1.SelectedIndex).DriverGuid)
            SoundDevice.SetCooperativeLevel(Me.Handle, CooperativeLevel.Priority)
            Buff = New SecondaryBuffer(soundfile, BuffDesc, SoundDevice)
            Buff.Play(0, BufferPlayFlags.Default)

    which all works fine, but I'm struggling to do it with mci in VB.NET.

    Now http://support.microsoft.com/kb/180032 makes it clear how to use mciSendCommand to change the soundcard. Except, of course, things in the VB world have moved on. So it no longer works.

    I've changed the types to Structures of course, as in:

        Public Const MCI_SET As Long = &H80D
        Public Const MCI_WAVE_OUTPUT As Long = &H800000

        Public Structure MCI_WAVE_SET_PARMS
            Public dwCallback As Integer
            Public dwTimeFormat As Integer
            Public dwAudio As Integer
            Public wInput As Integer
            Public wOutput As Integer
            Public wFormatTag As Integer
            Public wReserved2 As Integer
            Public nChannels As Integer
            Public wReserved3 As Integer
            Public nSamplesPerSec As Long
            Public nAvgBytesPerSec As Long
            Public nBlockAlign As Integer
            Public wReserved4 As Integer
            Public wBitsPerSample As Integer
            Public wReserved5 As Integer
        End Structure

    But then when I try and change the soundcard with something simple like:

            fileName = "C:\PFM.wav"
            retVal = mciSendString("Open " & Chr(34) & fileName & Chr(34) & " alias oursong", CStr(0), 0, 0)
            wDeviceID = mciGetDeviceID("oursong")
            Dim parms As MCI_WAVE_SET_PARMS
            parms.wOutput = 1
            retVal = mciSendCommand(wDeviceID, MCI_SET, MCI_WAVE_OUTPUT, parms)

    The whole thing falls over if I leave mciSendCommand as
    Public Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As Integer, ByVal uMessage As String, ByVal dwParam1 As Integer, ByVal dwParam2 As Object) As Integer

    It does however run if I change it to:
    Public Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As Integer, ByVal uMessage As String, ByVal dwParam1 As Integer, ByVal dwParam2 As MCI_WAVE_SET_PARMS) As Integer

    But then it doesn't change the soundcard.

    So... could you help me... how does mciSendCommand work to achieve this?







    Tuesday, October 21, 2008 2:47 PM
  • Hi Lorks
    You are right - selecting the soundcard appears to be a pain in the .... in vb.net

    I tried thw following:

    Public Class Form1  
        Public Declare Function waveOutGetNumDevs Lib "winmm" () As Integer 
        Public Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As IntegerByVal uMessage As StringByVal dwParam1 As IntegerByVal dwParam2 As ObjectAs Integer 
        Public Declare Function mciGetErrorString Lib "winmm.dll" Alias "mciGetErrorStringA" (ByVal dwError As IntegerByVal lpstrBuffer As StringByVal uLength As IntegerAs Integer 
        Public Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As StringByVal lpstrReturnString As StringByVal uReturnLength As IntegerByVal hwndCallback As IntegerAs Integer 
        Public Declare Function mciGetDeviceID Lib "winmm.dll" Alias "mciGetDeviceIDA" (ByVal lpstrName As StringAs Integer 
        Dim ofd As OpenFileDialog  
     
     
        Private Sub Form1_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load  
     
        End Sub 
     
        Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click  
            Dim i As Integer 
            i = waveOutGetNumDevs()  
            If i > 0 Then         ' There is at least one device.  
                MsgBox("You Can Play Wave Data - you have " & i & "Devices")  
            Else 
                MsgBox("Cannot Play Wave Data")  
            End If 
        End Sub 
     
        Public Const MMSYSERR_NOERROR = 0  
        Public Const MCI_SET = &H80D  
        Public Const MCI_WAVE_OUTPUT = &H800000  
        Public Structure MCI_WAVE_SET_PARMS  
            Dim dwCallback As Integer 
            Dim dwTimeFormat As Integer 
            Dim dwAudio As Integer 
            Dim wInput As Integer 
            Dim wOutput As Integer 
            Dim wFormatTag As Short 
            Dim wReserved2 As Short 
            Dim nChannels As Short 
            Dim wReserved3 As Short 
            Dim nSamplesPerSec As Integer 
            Dim nAvgBytesPerSec As Integer 
            Dim nBlockAlign As Short 
            Dim wReserved4 As Short 
            Dim wBitsPerSample As Short 
            Dim wReserved5 As Short 
        End Structure 
     
        Private Sub Button2_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button2.Click  
            Dim parms As MCI_WAVE_SET_PARMS  
            Dim wDeviceID As Integer 
            Dim ret As Integer 
     
            ' Specify the soundcard. This specifies the soundcard with a deviceID  
            ' of 0. If you have a single soundcard, then this will open it. If you  
            ' have multiple soundcards, the deviceIDs will be 0, 1, 2, etc.  
            parms.wOutput = 0  
     
            wDeviceID = mciGetDeviceID("waveaudio"'Can't use alias cos we not opened file yet  
     
            ' Send the MCI command to set the output device.  
            ret = mciSendCommand(wDeviceID, MCI_SET, MCI_WAVE_OUTPUT, parms)  
     
            If (ret <> MMSYSERR_NOERROR) Then 
                ' The command failed.  
                Stop 
            End If 
     
            If ofd.ShowDialog Then 
                ret = mciSendString("Open " & Chr(34) & ofd.FileName & Chr(34) & " alias audio"CStr(0), 0, 0)  
                ret = mciSendString("Open audio"CStr(0), 0, 0)  
            End If 
        End Sub 
     
        Private Sub Button3_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button3.Click  
            Dim ret As Integer 
            ret = mciSendString("Close audio"CStr(0), 0, 0)  
            Application.Exit()  
        End Sub 
    End Class 
     

    Ok it gets the number of devices ok - but trying to select one throws an error. I guess we're just going to have to stick with the default sound device using MCI under Net :(
    Allan
    Tuesday, October 21, 2008 8:53 PM