|
-
Sep 17th, 2000, 09:05 PM
#1
Thread Starter
Member
I have a command button named cmdPlay
What code do I type in to get it to play a wav file?
I need HELP!!! Any would be appreciated.
Thanks
-
Sep 17th, 2000, 09:11 PM
#2
Lively Member
using an API call "PlaySound" is probly your best bet if you only want to play a wav file
-
Sep 17th, 2000, 09:12 PM
#3
Thread Starter
Member
-
Sep 17th, 2000, 09:14 PM
#4
Try this:
Code:
Private Declare Function PlaySound Lib "winmm.dll" _
Alias "PlaySoundA" (ByVal lpszName As String, ByVal _
hModule As Long, ByVal dwFlags As Long) As Long
Private Sub Command1_Click()
PlaySound "C:\MyFile.wav", 0&, &H1
End Sub
-
Sep 17th, 2000, 09:18 PM
#5
Thread Starter
Member
-
Sep 18th, 2000, 02:40 AM
#6
Ok put the following code in a module
Code:
'declares for playing sounds
Public Declare Function PlaySound Lib "winmm.dll" Alias "PlaySoundA" (ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As Long) As Long
Public Const SND_ALIAS_START = 0
Public Const SND_ASYNC = &H1
Public Sub PlayWavSound(FName as string)
If FName= "" Then
Beep
Else
Result = PlaySound(FName, 0, SND_ASYNC)
If Result = 0 Then
MsgBox "Error Playing Event Sound", vbCritical, "Error"
End If
End If
End Sub
Then when you want to play the wave in your program use this code:
Code:
PlayWavSound PathToWaveFileWithName
Only put the path and filename of the wave in the PathToWaveFileName spot
-
Sep 18th, 2000, 02:17 PM
#7
Try placing the PlaySound api function in the form declarations rather than the module.
-
Sep 18th, 2000, 02:25 PM
#8
If it's Public that it has to be in a module.
If you want to put it in a Form then change public to Private.
-
Sep 18th, 2000, 07:32 PM
#9
Of course, you could always...
<?>
You might also want to try a more complicated API, which probably will help you on larger sounds.
Code:
'You might also try:
Option Explicit
'_______________________REMOVE THIS_______________________'
[Scope] Declare Function waveOutWrite Lib "winmm.dll" Alias "waveOutWrite" (ByVal hWaveOut As Long, lpWaveOutHdr As WAVEHDR, ByVal uSize As Long) As Long
Public Declare Function waveOutPrepareHeader Lib "winmm.dll" Alias "waveOutPrepareHeader" (ByVal hWaveOut As Long, lpWaveOutHdr As WAVEHDR, ByVal uSize As Long) As Long
Public Type WAVEHDR
lpData As String
dwBufferLength As Long
dwBytesRecorded As Long
dwUser As Long
dwFlags As Long
dwLoops As Long
lpNext As Long
Reserved As Long
End Type
Public Const WHDR_BEGINLOOP = &H4
Private Sub Playex(Devicehdc as Long, Addressn as String, Bufferlength as Long, Loops as Long, Size as long)
'DIM the varibles
dim temp as wavehdr, cs as variant
'Set the varible's attributes
temp.lpdata = Addressn
temp.dwBufferLength = BufferLength
temp.dwLoops = Loops
'Prepare it for use.
cs = waveOutPrepareHeader(Devicehdc, temp, Size)
'Set it for looping
temp.dwflags=WHDR_BEGINLOOP
' CS used for error handling code, which goes here.
'Write it to the Device
cs = waveOutWrite(Devicshdc, temp, Size)
' Error Handelors Here...
Exit Sub
' Any GOTO Handlers Here...
End Sub
That's about all. I think that can handle larger wavs, but you can set ANY speckers and use other properties to change the behavior. To play a sound use:
-
Sep 19th, 2000, 01:02 PM
#10
Monday Morning Lunatic
I really don't get that code...there wasn't anything about opening the file/looping/whatever!
For a better example, look at the DirectSound VB samples in the Platform SDK.
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Sep 19th, 2000, 01:15 PM
#11
Hyperactive Member
Here ia a faaaar easier way to play wav files.
Put this in the ceclarations section:
Code:
Const SND_ASYNC = &H1
Const SND_NODEFAULT = &H2
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long 'dimensions variables necessary to play sound effects.
then include this in sub form_load:
Code:
Dim SoundName As String
Dim wFlags As Integer
Dim X As Integer
then make this procedure:
Code:
Sub playwav(file) 'procedure that controls how sound effects are played.
SoundName = file
wFlags = SND_ASYNC Or SND_NODEFAULT
X = sndPlaySound(SoundName, wFlags)
then you can play wav files by typing this:
Code:
playwav ("FilePath")
-
Sep 19th, 2000, 01:37 PM
#12
Monday Morning Lunatic
Two things:
1. It's already been mentioned.
2. It can't be used for large files, since it tries to load the whole thing into memory. So huge 500meg wave files will kill it, and your program. This is why you need to stream it, and that's demonstrated in the DX sample.
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Sep 19th, 2000, 02:36 PM
#13
Also, sndPlaySound has been superseded by PlaySound.
-
Sep 19th, 2000, 04:42 PM
#14
Hyperactive Member
Try using DirectSound. You can play sounds easily, and you can play huge sounds too. If memory is an problem for big sounds, then you could try Streaming the sound(playing sound from HDD, not loading to memory) using DirectSound. But of course, there will be some problems with this.
1) I don't have any samples, so you will have to d/l the MS DirectX SDK(125MB). Or, you can look on the net for samples. Try http://www.vbexplorer.com/DirectX4vb
2) If you plan to distibute this program, there is yet another runtime file package that needs to be delivered(DirectX7). This is usually installed by Graphically Intensive programs(games).
3) DirectX is not easy to learn, although DirectSound is one of the easiest parts.
Designer/Programmer of the Comtech Operating System(CTOS)
-
Sep 19th, 2000, 04:45 PM
#15
Monday Morning Lunatic
Let me save people the effort - this is the StreamFrom sample from the PSDK:
Code:
VERSION 5.00
Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "comdlg32.ocx"
Begin VB.Form Form1
BorderStyle = 3 'Fixed Dialog
Caption = "Stream From File"
ClientHeight = 2430
ClientLeft = 45
ClientTop = 330
ClientWidth = 2430
Icon = "form1.frx":0000
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 2430
ScaleWidth = 2430
StartUpPosition = 2 'CenterScreen
Begin VB.CommandButton cmdStop
Caption = "Stop"
Enabled = 0 'False
Height = 420
Left = 600
TabIndex = 2
Top = 1740
Width = 1185
End
Begin MSComDlg.CommonDialog cdlgLoad
Left = 1920
Top = 1200
_ExtentX = 847
_ExtentY = 847
_Version = 393216
End
Begin VB.CommandButton cmdPlay
Caption = "Play File"
Enabled = 0 'False
Height = 420
Left = 600
TabIndex = 1
Top = 1200
Width = 1185
End
Begin VB.CommandButton cmdLoad
Caption = "Load File"
Height = 420
Left = 600
TabIndex = 0
Top = 660
Width = 1185
End
Begin VB.Label lblTitle
Alignment = 2 'Center
BackColor = &H00FFFFC0&
BorderStyle = 1 'Fixed Single
Caption = "None"
ForeColor = &H00800000&
Height = 255
Left = 120
TabIndex = 3
Top = 240
Width = 2175
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
'''''''''''''''''''''''''''''''''''''''''''''
'This sample shows how to stream from a file.
'''''''''''''''''''''''''''''''''''''''''''''
'Initialize variables, constants, and user-defined types.
Implements DirectXEvent 'This enables the form to receive events from DirectX.
Const NUM_POSITIONS = 16 'Used for making 16 (0 based) notification positions.
Private Declare Sub RtlZeroMemory Lib "kernel32" (dest As Any, ByVal cbSize As Long)
Private Type FileHeader 'File header structure for wave files.
dwRiff As Long
dwFileSize As Long
dwWave As Long
dwFormat As Long
dwFormatLength As Long
End Type
Private Type FileFormat 'File format structure for wave files
wFormatTag As Integer
nChannels As Integer
nSamplesPerSec As Long
nAvgBytesPerSec As Long
nBlockAlign As Integer
wBitsPerSample As Integer
End Type
Private Type HeaderChunk 'Header chunk format for wave files
dwType As Long
dwLen As Long
End Type
Dim dx As New DirectX7 'DirectX object.
Dim ds As DirectSound 'Direct Sound object.
Dim dsb As DirectSoundBuffer 'Direct sound buffer object.
Dim dsbPrimary As DirectSoundBuffer 'Primary direct sound buffer object.
Dim dsbd As DSBUFFERDESC 'Direct sound buffer description.
Dim Format As WAVEFORMATEX 'Wave format EX structure.
Dim Header As FileHeader 'Wave file header variable.
Dim HdrFormat As FileFormat
Dim hEvent(1) As Long 'Array to hold the event handle.
Dim psa(1) As DSBPOSITIONNOTIFY 'Notify position array.
Dim FileFree As Long 'Holds the handle to the file.
Dim Buffer() As Byte 'Dynamic byte array for the wave data buffer.
Dim lngNotificationSize As Long
Dim lngLastBit As Long
Dim fEnd As Long
Dim dwDataLength As Long
Dim m_bLoop As Boolean
Private Sub cmdPlay_Click()
'This is where the buffers are initialized for playback.
If CreateStreamingBuffer Then 'Call the function that creates the streaming buffer. If it succeeds, continue.
fEnd = 0
dsb.SetCurrentPosition 0
If m_bLoop Then
dsb.Play DSBPLAY_LOOPING 'Start the secondary buffer, and keep it looping as well.
cmdLoad.Enabled = False 'Disable the load button during playback.
cmdPlay.Enabled = False 'Disable the play button during playback.
cmdStop.Enabled = True 'Enable the stop button.
Else
dsb.Play DSBPLAY_DEFAULT 'Start the secondary buffer
End If
End If
End Sub
Private Sub cmdStop_Click()
dsb.Stop 'Stop the direct sound buffer.
cmdLoad.Enabled = True 'Enable the load button.
cmdStop.Enabled = False 'Disable the stop button.
cmdPlay.Enabled = True 'Enable the play button.
End Sub
Private Sub Form_Load()
'Sets up the primary buffer & DX events.
On Local Error GoTo ErrOut
Dim dsbdPrimary As DSBUFFERDESC 'Used to initialize the primary buffer.
Dim WavFormat As WAVEFORMATEX 'Also used to init the primary buffer.
Me.Show 'Make sure that the loading of the form is complete.
cmdLoad.Enabled = True 'Enable the load button.
cmdPlay.Enabled = False 'Disable the play button.
cmdStop.Enabled = False 'Disable the stop button.
hEvent(0) = dx.CreateEvent(Me) 'Create an event handle, and attach it to this form.
hEvent(1) = dx.CreateEvent(Me) 'Create an event handle, and attach it to this form.
Set ds = dx.DirectSoundCreate(vbNullString) 'Create the direct sound object using the default driver.
ds.SetCooperativeLevel Me.hWnd, DSSCL_PRIORITY
'Set the cooperative level to the forms window handle.
'Create the primary buffer.
Exit Sub
ErrOut:
MsgBox "Cannot create the primary sound device. Exiting this application.", vbOKOnly Or vbCritical, "Cannot create"
End
End Sub
Private Sub cmdLoad_Click()
'This begins the loading process for the wave file to be played back.
On Local Error GoTo ErrorHandler 'Make sure to handle if cancel is pressed.
With cdlgLoad 'Set the flags for the common dialog box.
.CancelError = True 'Make sure canel will be detected if it is clicked.
.Filter = "(*.WAV)|*.WAV" 'Set the filters for the dialog box.
.flags = cdlOFNHideReadOnly Or cdlOFNFileMustExist
'Hide the read only checkbox, and the user has to enter a file that already exists.
.ShowOpen 'Show the common dialog box.
End With
cmdPlay.Enabled = True 'Enable the play button.
'Display the selected wave file.
Dim l_d As Long
l_d = 1
Do While InStr(l_d, cdlgLoad.FileName, "\", vbBinaryCompare) <> 0
l_d = l_d + 1 'Loop until the last \ is found
Loop
lblTitle = Right(cdlgLoad.FileName, Len(cdlgLoad.FileName) - (l_d - 1))
Exit Sub 'Exit the subroutine.
ErrorHandler: 'Set up error handling for a cancel error.
If Err.Number = cdlCancel Then 'If cancel was selected,
Exit Sub 'Exit the sub.
End If
End Sub
Private Function CreateStreamingBuffer() As Boolean
'This sub sets up the streaming buffer.
Dim lngCount As Long 'Standard count variable.
Close #FileFree 'Close the file in case it is open.
Set dsb = Nothing 'Set the secondary buffer to nothing.
Format = FillFormat() 'Fill the format structure by calling the FillFormat function.
If Format.nFormatTag <> WAVE_FORMAT_PCM Then
'If an unsupported format is attempting to load,
MsgBox "Unsupported format" 'display this message.
Close #FileFree 'Close the open file.
Exit Function 'Exit the sub.
End If
lngNotificationSize = (Format.lSamplesPerSec * 2) \ 2
dsbd.lBufferBytes = lngNotificationSize * 2
lngLastBit = (dwDataLength \ dsbd.lBufferBytes) * dsbd.lBufferBytes
'Create a half second buffer.
dsbd.lFlags = DSBCAPS_GETCURRENTPOSITION2 Or DSBCAPS_CTRLPOSITIONNOTIFY
'Set the flags for the buffer. Flags needed are DSBCAPS_GLOBALFOCUS,
'DSBCAPS_GETCURRENTPOSITION2 for accurate notification position tracking,
'and DSBCAPS_CTRLPOSITIONNOTIFY to let Direct Sound know we are keeping
'track of the position during playback.
Set dsb = ds.CreateSoundBuffer(dsbd, Format)
'Create the buffer with the above structures.
If dwDataLength >= dsbd.lBufferBytes Then
psa(0).lOffset = (dsbd.lBufferBytes) \ 2
psa(0).hEventNotify = hEvent(0)
psa(1).lOffset = (dsbd.lBufferBytes - 1)
psa(1).hEventNotify = hEvent(1)
dsb.SetNotificationPositions 2, psa() 'Set the notification positions for the buffer.
'Set the playback position to the middle of the buffer to trigger the first event.
End If
ReDim Buffer(dsbd.lBufferBytes - 1) 'Resize the wave data buffer to the size of the direct sound buffer
cmdPlay.Enabled = True 'Enable the play button.
CreateStreamingBuffer = True 'The function succeeded.
m_bLoop = True
If dwDataLength < dsbd.lBufferBytes Then
ReDim Buffer(dwDataLength - 1)
m_bLoop = False
End If
'get our first chunk of data
Get #FileFree, , Buffer 'Read the wave data into the buffer array.
dsb.WriteBuffer 0, UBound(Buffer), Buffer(0), DSBLOCK_DEFAULT
End Function
Private Function FillFormat() As WAVEFORMATEX
Dim chunk As HeaderChunk
Dim by As Byte
Dim i As Long
'This reads the header info from a wave file, and returns a filled WAVEFORMATEX structure from this info.
Close #FileFree
FileFree = FreeFile 'Get a free file handle.
Open cdlgLoad.FileName For Binary Access Read As #FileFree
'Open the selected wave file for binary input.
Get #FileFree, , Header 'Get the wave header data, and fill the header structure with the info.
If Header.dwRiff <> &H46464952 Then 'This is not a valid Riff
Exit Function
End If
If Header.dwWave <> &H45564157 Then 'This is not a valid Wave
Exit Function
End If
Dim lCount As Long
If Header.dwFormatLength < 16 Then 'We will only handle formats that are 16 bytes or greater
Exit Function
End If
Get #FileFree, , HdrFormat 'Get the wave format data
'get rid of extra format bytes
For i = 1 To Header.dwFormatLength - 16
Get #FileFree, , by
Next
Get #FileFree, , chunk
Do While chunk.dwType <> &H61746164 'DATA chunck
For i = 1 To chunk.dwLen
Get #FileFree, , by
Next
Get #FileFree, , chunk
Loop
dwDataLength = chunk.dwLen
With FillFormat 'Fill the WAVEFORMATEX structure with the info from the file header.
.lAvgBytesPerSec = HdrFormat.nAvgBytesPerSec
.lExtra = 0
.lSamplesPerSec = HdrFormat.nSamplesPerSec
.nBitsPerSample = HdrFormat.wBitsPerSample
.nBlockAlign = HdrFormat.nBlockAlign
.nChannels = HdrFormat.nChannels
.nFormatTag = HdrFormat.wFormatTag
End With
'The file is left open to keep the file read position at the start of the wave file data.
End Function
Private Sub DirectXEvent_DXCallback(ByVal eventid As Long)
'This is the callback sub for the DirectX event. The buffer data is written to the direct sound buffer here.
Select Case eventid
Case hEvent(0) 'Event 0 has fired.
If Loc(FileFree) > lngLastBit Then 'This is the last section of the buffer
fEnd = fEnd + 1
Get #FileFree, , Buffer 'Read in the buffer
Dim dwStartSilence As Long
Dim dwLenSilence As Long
dwStartSilence = dwDataLength - lngLastBit
dwLenSilence = dsbd.lBufferBytes - dwStartSilence
Call RtlZeroMemory(Buffer(dwStartSilence), dwLenSilence) 'Zero the buffer out
Else
Get #FileFree, , Buffer 'Read the wave data into the buffer array.
End If
Dim j As Long
j = ((UBound(Buffer) + 1) \ 2)
j = j + j Mod 2
dsb.WriteBuffer 0, j, Buffer(0), DSBLOCK_DEFAULT
'Write to the buffer, using half of the data contained
'in the wave data buffer, give it the starting element of the buffer,
'and use the default flag for the buffer.
Case hEvent(1)
'Event 1 has fired.
Dim h As Long
h = ((UBound(Buffer) + 1) \ 2)
dsb.WriteBuffer h, h, Buffer(0), DSBLOCK_DEFAULT
If fEnd = 2 Then
cmdPlay.Enabled = True
cmdLoad.Enabled = True
cmdStop.Enabled = False
dsb.Stop
End If
End Select
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
'Make sure that everything is stopped and reset before exiting.
Set dsb = Nothing 'Set the secondary buffer to nothing.
Set dsbPrimary = Nothing 'Set the primary buffer object to nothing.
If hEvent(0) <> 0 Then 'If event handle zero exists,
dx.DestroyEvent hEvent(0) 'destroy it.
End If
If hEvent(1) <> 0 Then 'If event handle one exists,
dx.DestroyEvent hEvent(1) 'destroy it.
End If
Set dx = Nothing 'Set the DirectX object to nothing.
End Sub
Just open notepad, put this in, and save as a .frm file.
I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
-- Linus Torvalds
-
Sep 19th, 2000, 05:03 PM
#16
Hyperactive Member
Good job parksie... But, you still need DirectX7. That should stream from a file and preserve your computer's system memory. But how's the newbies supposed to understand how that's supposed to work?
Newbies: Keep that code, if you want to learn how to actually do this, go to http://www.vbexplorer.com/DirectX4VB
They will have more DirectX samples there.
Designer/Programmer of the Comtech Operating System(CTOS)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|