Results 1 to 16 of 16

Thread: Playing wav files

  1. #1

    Thread Starter
    Member
    Join Date
    Sep 2000
    Posts
    55
    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
    Beres

  2. #2
    Lively Member
    Join Date
    Jul 2000
    Location
    Sydney, Australia
    Posts
    74
    using an API call "PlaySound" is probly your best bet if you only want to play a wav file

  3. #3

    Thread Starter
    Member
    Join Date
    Sep 2000
    Posts
    55

    API?

    What's an API?
    Beres

  4. #4
    Guest
    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

  5. #5

    Thread Starter
    Member
    Join Date
    Sep 2000
    Posts
    55

    HELP ME!!!!

    BLAST!!! Doesn't work.??
    Beres

  6. #6
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    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

  7. #7
    Guest
    Try placing the PlaySound api function in the form declarations rather than the module.

  8. #8
    Guest
    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.

  9. #9
    Guest

    Post 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:

    Code:
        playex yoursndfile

  10. #10
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    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

  11. #11
    Hyperactive Member CyberSurfer's Avatar
    Join Date
    Aug 2000
    Location
    Old London Town
    Posts
    425
    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")

  12. #12
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    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

  13. #13
    Guest
    Also, sndPlaySound has been superseded by PlaySound.

  14. #14
    Hyperactive Member Warmaster199's Avatar
    Join Date
    Aug 2000
    Location
    Canada
    Posts
    306
    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)

  15. #15
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    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

  16. #16
    Hyperactive Member Warmaster199's Avatar
    Join Date
    Aug 2000
    Location
    Canada
    Posts
    306
    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
  •  



Click Here to Expand Forum to Full Width