Win32 MCI API for playing media
-
Thursday, August 21, 2008 6:06 PM
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.
All Replies
-
Thursday, August 21, 2008 6:33 PMWin32 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:41 PMTypical 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 8:09 PM
Congratulations! The code you provided is very interesting...
Thank you! -
Thursday, August 21, 2008 8:34 PMSome 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 9:07 PMAngelos 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 -
Sunday, September 28, 2008 10:26 AM
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 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 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.Object, ByVal 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 Object, ByVal 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
-
Tuesday, September 30, 2008 6:40 PM
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:44 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 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 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 Object, ByVal 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.Object, ByVal 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 Object, ByVal 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:56 PM
The listing part two:
Private Sub btnExit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Application.Exit() End Sub Private Sub cmbMP3_click(ByVal sender As Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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:59 PM
The listing part three (hopefully the last bit):
Allan
Private Sub btnMute_Click(ByVal sender As Object, ByVal 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 Object, ByVal 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 Object, ByVal 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, October 21, 2008 2:47 PMThank 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 IntegerBecause 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 = &H800000Public 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 8:53 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 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 Public Declare Function mciGetDeviceID Lib "winmm.dll" Alias "mciGetDeviceIDA" (ByVal lpstrName As String) As Integer Dim ofd As OpenFileDialog Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal 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.Object, ByVal 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.Object, ByVal 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

