By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,292 Members | 1,354 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,292 IT Pros & Developers. It's quick & easy.

Playing a sound

P: n/a
I just want quick and easy way to play a .wav file out the
standard sound device. It could even be as simple as
activating a sound assigned to an existing windows sound
event.

Any suggestions?

Thanks in advance.

-Lee
Nov 20 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
* "Lee Moody" <an*******@discussions.microsoft.com> scripsit:
I just want quick and easy way to play a .wav file out the
standard sound device. It could even be as simple as
activating a sound assigned to an existing windows sound
event.


<http://www.google.com/groups?selm=exQuKMjfDHA.1712%40TK2MSFTNGP11.phx.gb l>

--
Herfried K. Wagner
MVP VB Classic, VB.NET
<http://www.mvps.org/dotnet>
Nov 20 '05 #2

P: n/a
Here is a little class to play wav files

Public Class WaveFile

Inherits System.ComponentModel.Component

'<API-DECLARES>

Private Const CALLBACK_WINDOW As Integer = &H10000

Private Const CALLBACK_FUNCTION As Integer = &H30000

Private Const MMIO_READ As Integer = &H0

Private Const MMIO_FINDCHUNK As Integer = &H10

Private Const MMIO_FINDRIFF As Integer = &H20

Private Const MM_WOM_DONE As Integer = &H3BD

Private Const MMSYSERR_NOERROR As Integer = 0

Private Const SEEK_CUR As Integer = 1

Private Const SEEK_END As Integer = 2

Private Const SEEK_SET As Integer = 0

Private Const TIME_BYTES As Integer = &H4

Private Const WHDR_DONE As Integer = &H1

Private Const NUM_BUFFERS As Integer = 5

Private Const BUFFER_SECONDS As Single = 0.1

<StructLayout(LayoutKind.Sequential)> _

Private Structure MMIOINFO

Public dwFlags As Integer

Public fccIOProc As Integer

Public pIOProc As Integer

Public wErrorRet As Integer

Public htask As Integer

Public cchBuffer As Integer

Public pchBuffer As String

Public pchNext As String

Public pchEndRead As String

Public pchEndWrite As String

Public lBufOffset As Integer

Public lDiskOffset As Integer

Public adwInfo1 As Integer

Public adwInfo2 As Integer

Public adwInfo3 As Integer

Public adwInfo4 As Integer

Public dwReserved1 As Integer

Public dwReserved2 As Integer

Public hmmio As Integer

End Structure

<StructLayout(LayoutKind.Sequential)> _

Private Structure WAVEHDR

Public lpData As Integer

Public dwBufferLength As Integer

Public dwBytesRecorded As Integer

Public dwUser As Integer

Public dwFlags As Integer

Public dwLoops As Integer

Public lpNext As Integer

Public Reserved As Integer

End Structure

<StructLayout(LayoutKind.Sequential)> _

Private Structure WAVEINCAPS

Public wMid As Short

Public wPid As Short

Public vDriverVersion As Integer

Public szPname As String

Public dwFormats As Integer

Public wChannels As Short

End Structure

<StructLayout(LayoutKind.Sequential)> _

Private Structure WAVEFORMAT

Public wFormatTag As Short

Public nChannels As Short

Public nSamplesPerSec As Integer

Public nAvgBytesPerSec As Integer

Public nBlockAlign As Short

Public wBitsPerSample As Short

Public cbSize As Short

End Structure

<StructLayout(LayoutKind.Sequential)> _

Private Structure MMCKINFO

Public ckid As Integer

Public ckSize As Integer

Public fccType As Integer

Public dwDataOffset As Integer

Public dwFlags As Integer

End Structure

<StructLayout(LayoutKind.Sequential)> _

Private Structure MMTIME

Public wType As Integer

Public u As Integer

Public x As Integer

End Structure

Private Declare Function waveOutGetPosition Lib "winmm.dll" (ByVal hWaveOut
As IntPtr, ByRef lpInfo As MMTIME, ByVal uSize As Integer) As Integer

Private Declare Ansi Function waveOutOpen Lib "winmm.dll" (ByRef hWaveOut As
IntPtr, ByVal uDeviceID As Integer, ByVal format() As Byte, ByVal dwCallback
As WaveDelegate, ByRef fPlaying As Integer, ByVal dwFlags As Integer) As
Integer

Private Declare Function waveOutPrepareHeader Lib "winmm.dll" (ByVal hWaveIn
As IntPtr, ByRef lpWaveInHdr As WAVEHDR, ByVal uSize As Integer) As Integer

Private Declare Function waveOutPrepareHeaderPtr Lib "winmm.dll" (ByVal
hWaveIn As IntPtr, ByVal lpWaveInHdr As Integer, ByVal uSize As Integer) As
Integer

Private Declare Function waveOutReset Lib "winmm.dll" (ByVal hWaveIn As
IntPtr) As Integer

Private Declare Function waveOutUnprepareHeader Lib "winmm.dll" (ByVal
hWaveIn As IntPtr, ByRef lpWaveInHdr As WAVEHDR, ByVal uSize As Integer) As
Integer

Private Declare Function waveOutClose Lib "winmm.dll" (ByVal hWaveIn As
IntPtr) As Integer

Private Declare Function waveOutWrite Lib "winmm.dll" (ByVal hWaveOut As
IntPtr, ByRef lpWaveOutHdr As WAVEHDR, ByVal uSize As Integer) As Integer

Private Declare Function waveOutPause Lib "winmm.dll" (ByVal hWaveOut As
IntPtr) As Integer

Private Declare Function waveOutRestart Lib "winmm.dll" (ByVal hWaveOut As
IntPtr) As Integer

Private Declare Function waveOutSetVolume Lib "winmm.dll" (ByVal uDeviceID
As IntPtr, ByVal dwVolume As UInt32) As Integer

Private Declare Function waveOutGetVolume Lib "winmm.dll" (ByVal uDeviceID
As IntPtr, ByRef lpdwVolume As Integer) As Integer

Private Declare Function mmioClose Lib "winmm.dll" (ByVal hmmio As IntPtr,
ByVal uFlags As Integer) As Integer

Private Declare Function mmioDescend Lib "winmm.dll" (ByVal hmmio As IntPtr,
ByRef lpck As MMCKINFO, ByRef lpckParent As MMCKINFO, ByVal uFlags As
Integer) As Integer

Private Declare Function mmioDescendParent Lib "winmm.dll" Alias
"mmioDescend" (ByVal hmmio As IntPtr, ByRef lpck As MMCKINFO, ByVal x As
Integer, ByVal uFlags As Integer) As Integer

Private Declare Ansi Function mmioOpen Lib "winmm.dll" Alias "mmioOpenA"
(ByVal szFileName As String, ByRef lpmmioinfo As MMIOINFO, ByVal dwOpenFlags
As Integer) As IntPtr

Private Declare Function mmioRead Lib "winmm.dll" (ByVal hmmio As IntPtr,
ByVal pch As Integer, ByVal cch As Integer) As Integer

Private Declare Function mmioReadString Lib "winmm.dll" Alias "mmioRead"
(ByVal hmmio As IntPtr, ByVal pch() As Byte, ByVal cch As Integer) As
Integer

Private Declare Function mmioSeek Lib "winmm.dll" (ByVal hmmio As IntPtr,
ByVal lOffset As Integer, ByVal iOrigin As Integer) As Integer

Private Declare Ansi Function mmioStringToFOURCC Lib "winmm.dll" Alias
"mmioStringToFOURCCA" (ByVal sz As String, ByVal uFlags As Integer) As
Integer

Private Declare Function mmioAscend Lib "winmm.dll" (ByVal hmmio As IntPtr,
ByRef lpck As MMCKINFO, ByVal uFlags As Integer) As Integer

Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As
Integer, ByVal dwBytes As Integer) As IntPtr

Private Declare Function GlobalLock Lib "kernel32" (ByVal hmem As IntPtr) As
IntPtr

Private Declare Function GlobalFree Lib "kernel32" (ByVal hmem As IntPtr) As
Integer

Private Declare Sub CopyWaveFormatFromBytes Lib "kernel32" Alias
"RtlMoveMemory" (ByRef dest As WAVEFORMAT, ByVal source() As Byte, ByVal cb
As Integer)

Private Declare Sub CopyWaveHeaderFromPointer Lib "kernel32" Alias
"RtlMoveMemory" (ByRef dest As WAVEHDR, ByVal source As Integer, ByVal cb As
Integer)

Private Declare Function IsBadWritePtr Lib "kernel32" (ByVal lp As Integer,
ByVal ucb As Integer) As Integer

'</API-DECLARES>

Private Delegate Sub WaveDelegate(ByVal hwo As IntPtr, ByVal uMsg As
Integer, ByVal dwInstance As Integer, ByRef wavhdr As WAVEHDR, ByVal
dwParam2 As Integer)

'/// <summary>Creates a new WaveFile object.</summary>

'/// <param name="Filename">Specifies the file to play.<param>

'/// <exceptions cref="MediaException">Thrown when there was an error
opening the file or allocating the necessary buffers.</exceptions>

'/// <exceptions cref="FileNotFoundException">Thrown when the specified file
could not be found.</exceptions>

'/// <exceptions cref="ArgumentException">Thrown when the specified
parameter is Nothing (C#,VC++: NULL).</exceptions>

Public Sub New(ByVal Filename As String)

If Filename Is Nothing Then Throw New ArgumentException

m_Filename = Filename

OpenFile()

End Sub

'/// <summary>Starts playing the wave file.</summary>

'/// <exceptions cref="MediaException">Thrown when an error occured while
reading from the file.</exceptions>

Public Sub Play()

If m_Paused Then

m_Paused = False

waveOutRestart(WaveOutHandle)

Exit Sub

End If

If m_Playing Then Exit Sub

Dim rc, i As Integer

m_Callback = AddressOf WaveCallBack

rc = waveOutOpen(m_WaveOut, 0, m_FormatBuffer, m_Callback, Nothing,
CALLBACK_FUNCTION)

If (rc <> MMSYSERR_NOERROR) Then

Throw New MediaException("Unable to open the WAVE file.")

End If

hHdr = GCHandle.Alloc(hdr, GCHandleType.Pinned)

For i = 0 To NUM_BUFFERS - 1

hdr(i).lpData = pmem(i).ToInt32

hdr(i).dwBufferLength = m_BufferSize

hdr(i).dwFlags = 0

hdr(i).dwLoops = 0

rc = waveOutPrepareHeader(WaveOutHandle, hdr(i), Len(hdr(i)))

If (rc <> MMSYSERR_NOERROR) Then

Throw New MediaException("Unable to prepare the WAVE buffers.")

End If

Next

m_Playing = True

m_Paused = False

m_StartPos = mmioSeek(InputHandle, 0, SEEK_CUR) - m_DataOffset

For i = 0 To NUM_BUFFERS - 1

WaveCallBack(InputHandle, MM_WOM_DONE, 0, hdr(i), 0)

Next i

End Sub

'/// <summary>Stops the playback of the wave file.</summary>

Public Sub StopPlay()

Dim i As Integer

m_Playing = False

waveOutReset(WaveOutHandle)

For i = 0 To NUM_BUFFERS - 1

waveOutUnprepareHeader(WaveOutHandle, hdr(i), Len(hdr(i)))

Next

waveOutClose(WaveOutHandle)

Position = 0

End Sub

'/// <summary>Specifies whether the WAVE file is currently paused or
not.</summary>

'/// <value>True when the file is paused, False otherwise.</value>

Public Property Paused() As Boolean

Get

Return m_Paused

End Get

Set(ByVal Value As Boolean)

If m_Playing Then

m_Paused = Value

If m_Paused Then

waveOutPause(WaveOutHandle)

Else

waveOutRestart(WaveOutHandle)

End If

End If

End Set

End Property

'/// <summary>Gets the name of the WAVE file.</summary>

'/// <value>The name of the WAVE file.</value>

Public ReadOnly Property Filename() As String

Get

Return m_Filename

End Get

End Property

'/// <summary>Gets the length of the WAVE file.</summary>

'/// <value>The length of the WAVE file.</value>

Public ReadOnly Property Length() As Integer

Get

Return m_AudioLength \ m_Format.nBlockAlign

End Get

End Property

'/// <summary>Specifies whether the WAVE file is currently
playing.</summary>

'/// <remarks>This property is only influenced by the methods 'Play' and
'StopPlay'. If you pause a file, Playing will still be True.</remarks>

'/// <value>True if the WAVE file is currently playing, False
otherwise.</value>

Public ReadOnly Property Playing() As Boolean

Get

Dim tm As MMTIME

tm.wType = TIME_BYTES

Return (waveOutGetPosition(WaveOutHandle, tm, Len(tm)) = MMSYSERR_NOERROR)

End Get

End Property

'/// <summary>Specifies the output volume.</summary>

'/// <remarks>This value must be between 0 and 65535.</remarks>

'/// <value>The output volume.</value>

Public Property Volume() As Integer

Get

waveOutGetVolume(WaveOutHandle, Volume)

Volume = CType(Volume And &HFFFF&, Integer)

End Get

Set(ByVal Value As Integer)

If Value < &H0 OrElse Value > &HFFFF Then Throw New ArgumentException

waveOutSetVolume(WaveOutHandle, UInt32.Parse((Value + 2 ^ 16 *
Value).ToString))

End Set

End Property

'/// <summary>Specifies the position in the WAVE file.</summary>

'/// <value>The position in the WAVE file.</value>

Public Property Position() As Integer

Get

Dim tm As MMTIME

tm.wType = TIME_BYTES

If (waveOutGetPosition(WaveOutHandle, tm, Len(tm)) = MMSYSERR_NOERROR) Then

Position = (m_StartPos + tm.u) \ m_Format.nBlockAlign

Else

Position = (mmioSeek(InputHandle, 0, SEEK_CUR) - m_DataOffset + m_BufferSize
* NUM_BUFFERS) \ m_Format.nBlockAlign

End If

End Get

Set(ByVal Value As Integer)

If Not m_Initialized Then Exit Property

Dim bytepos As Integer = Value * m_Format.nBlockAlign

mmioSeek(InputHandle, bytepos + m_DataOffset, SEEK_SET)

End Set

End Property

'/// <summary>Returns the handle of the input device.</summary>

'/// <value>The handle of the input device.</value>

Private ReadOnly Property InputHandle() As IntPtr

Get

Return m_MmioIn

End Get

End Property

'/// <summary>Returns the handle of the output device.</summary>

'/// <value>The handle of the output device.</value>

Private ReadOnly Property WaveOutHandle() As IntPtr

Get

Return m_WaveOut

End Get

End Property

'/// <summary>Called when the class gets GCed.</summary>

Protected Overrides Sub Finalize()

CloseFile()

MyBase.Finalize()

End Sub

'/// <summary>Used internally to open a wave file and initializing the
required memory.</summary>

'/// <exceptions cref="MediaException">Thrown when there was an error
opening the file or allocating the necessary buffers.</exceptions>

'/// <exceptions cref="FileNotFoundException">Thrown when the specified file
could not be found.</exceptions>

Protected Sub OpenFile()

'Make sure the file exists

If Not File.Exists(Filename) Then

Throw New FileNotFoundException

Exit Sub

End If

Dim mmckinfoParentIn As MMCKINFO

Dim mmckinfoSubchunkIn As MMCKINFO

Dim mmioinf As MMIOINFO

Dim rc, i As Integer

'Open the input file

m_MmioIn = mmioOpen(Filename, mmioinf, MMIO_READ)

If (InputHandle.ToInt64 = 0) Then

Throw New MediaException("Error while opening the input file.")

End If

'Check if this is a wave file

mmckinfoParentIn.fccType = mmioStringToFOURCC("WAVE", 0)

rc = mmioDescendParent(InputHandle, mmckinfoParentIn, 0, MMIO_FINDRIFF)

If (rc <> MMSYSERR_NOERROR) Then

CloseFile()

Throw New MediaException("Invalid file type.")

End If

'Get format info

mmckinfoSubchunkIn.ckid = mmioStringToFOURCC("fmt", 0)

rc = mmioDescend(InputHandle, mmckinfoSubchunkIn, mmckinfoParentIn,
MMIO_FINDCHUNK)

If (rc <> MMSYSERR_NOERROR) Then

CloseFile()

Throw New MediaException("Couldn't find format chunk.")

End If

rc = mmioReadString(InputHandle, m_FormatBuffer, mmckinfoSubchunkIn.ckSize)

If (rc = -1) Then

CloseFile()

Throw New MediaException("Couldn't read from WAVE file.")

End If

rc = mmioAscend(InputHandle, mmckinfoSubchunkIn, 0)

CopyWaveFormatFromBytes(m_Format, m_FormatBuffer, Len(m_Format))

'Find the data subchunk

mmckinfoSubchunkIn.ckid = mmioStringToFOURCC("data", 0)

rc = mmioDescend(InputHandle, mmckinfoSubchunkIn, mmckinfoParentIn,
MMIO_FINDCHUNK)

If (rc <> MMSYSERR_NOERROR) Then

CloseFile()

Throw New MediaException("Unable to find the data chunk.")

End If

m_DataOffset = mmioSeek(InputHandle, 0, SEEK_CUR)

'Get the length of the audio

m_AudioLength = mmckinfoSubchunkIn.ckSize

'Allocate audio buffers

m_BufferSize = CType(m_Format.nSamplesPerSec * m_Format.nBlockAlign *
m_Format.nChannels * BUFFER_SECONDS, Integer)

m_BufferSize = m_BufferSize - (m_BufferSize Mod m_Format.nBlockAlign)

For i = 0 To NUM_BUFFERS - 1

GlobalFree(hmem(i))

hmem(i) = GlobalAlloc(0, m_BufferSize)

pmem(i) = GlobalLock(hmem(i))

Next

'The class in successfully initialized

m_Initialized = True

End Sub

'/// <summary>Used internally to close a wave file and free the used
memory.</summary>

Protected Sub CloseFile()

Dim i As Integer

If Playing Then waveOutReset(WaveOutHandle)

mmioClose(InputHandle, 0)

For i = 0 To NUM_BUFFERS - 1

GlobalFree(hmem(i))

Next i

If hHdr.IsAllocated Then hHdr.Free()

End Sub

'/// <summary>The callback function.</summary>

Private Sub WaveCallBack(ByVal hwo As IntPtr, ByVal uMsg As Integer, ByVal
dwInstance As Integer, ByRef wavhdr As WAVEHDR, ByVal dwParam2 As Integer)

If uMsg = MM_WOM_DONE AndAlso m_Playing Then

Dim rc As Integer

m_DataRemaining = (m_DataOffset + m_AudioLength - mmioSeek(InputHandle, 0,
SEEK_CUR))

If (m_BufferSize < m_DataRemaining) Then

rc = mmioRead(InputHandle, wavhdr.lpData, m_BufferSize)

Else

rc = mmioRead(InputHandle, wavhdr.lpData, m_DataRemaining)

m_Playing = False

End If

If rc <> -1 Then

wavhdr.dwBufferLength = rc

rc = waveOutWrite(WaveOutHandle, wavhdr, Len(wavhdr))

End If

End If

End Sub

'Private variables

Private m_Tel As Integer

Private m_Filename As String

Private m_Initialized As Boolean = False

Private m_MmioIn As IntPtr = IntPtr.Zero

Private m_DataOffset As Integer = 0

Private m_AudioLength As Integer = 0

Private m_BufferSize As Integer = 0

Private hmem(NUM_BUFFERS - 1) As IntPtr ' memory handles

Private pmem(NUM_BUFFERS - 1) As IntPtr ' memory pointers

Private hdr(NUM_BUFFERS - 1) As WAVEHDR ' wave headers

Private m_Format As WAVEFORMAT ' waveformat structure

Private m_WaveOut As IntPtr = IntPtr.Zero

Private m_Playing As Boolean = False

Private m_StartPos As Integer = 0

Private m_DataRemaining As Integer = 0

Private m_FormatBuffer(49) As Byte

Private m_Callback As WaveDelegate

Private m_Paused As Boolean

Private hHdr As GCHandle

End Class

"Lee Moody" <an*******@discussions.microsoft.com> wrote in message
news:00****************************@phx.gbl...
I just want quick and easy way to play a .wav file out the
standard sound device. It could even be as simple as
activating a sound assigned to an existing windows sound
event.

Any suggestions?

Thanks in advance.

-Lee

Nov 20 '05 #3

P: n/a
"David Ricker" <da***@vanamatic.com> wrote
Here is a little class to play wav files


Next time you redistribute someone else's code, make sure you keep the
license header intact.
http://www.allapi.net/classlib/class.php?id=7

Regards,
Pieter Philippaerts
Managed SSL/TLS: http://www.mentalis.org/go.php?sl
Nov 20 '05 #4

P: n/a
I appreciate the help. Unfortunately neither option will
work for me. New Information: I need this to run on a
Pocket PC. The provided options work great for a regular
Windows 2000 machine.

Any ideas how I can get something to play on a Pocket PC
with the stripped down version of the .NET Framework?

-Lee
-----Original Message-----
I just want quick and easy way to play a .wav file out thestandard sound device. It could even be as simple as
activating a sound assigned to an existing windows sound
event.

Any suggestions?

Thanks in advance.

-Lee
.

Nov 20 '05 #5

P: n/a
* "Lee Moody" <an*******@discussions.microsoft.com> scripsit:
I appreciate the help. Unfortunately neither option will
work for me. New Information: I need this to run on a
Pocket PC. The provided options work great for a regular
Windows 2000 machine.


..NET Compact Framework newsgroup:

<news://msnews.microsoft.com/microsoft.public.dotnet.framework.compactframework >

Web interface:

<http://msdn.microsoft.com/newsgroups/default.asp?url=/newsgroups/loadframes.asp?icp=msdn&slcid=us&newsgroup=microso ft.public.dotnet.framework.compactframework>

--
Herfried K. Wagner
MVP VB Classic, VB.NET
<http://www.mvps.org/dotnet>
Nov 20 '05 #6

P: n/a
Thank you Herfried. I did post a message on that
newsgroup and got my answer!

-Lee
-----Original Message-----
* "Lee Moody" <an*******@discussions.microsoft.com> scripsit:
I appreciate the help. Unfortunately neither option will work for me. New Information: I need this to run on a
Pocket PC. The provided options work great for a regular Windows 2000 machine.


..NET Compact Framework newsgroup:

<news://msnews.microsoft.com/microsof...c.dotnet.frame

work.compactframework>
Web interface:

<http://msdn.microsoft.com/newsgroups/default.asp? url=/newsgroups/loadframes.asp?
icp=msdn&slcid=us&newsgroup=microsoft.public.dotne t.framewo
rk.compactframework>
--
Herfried K. Wagner
MVP VB Classic, VB.NET
<http://www.mvps.org/dotnet>
.

Nov 20 '05 #7

P: n/a
Sorry about that,
I had found this a long time ago. And I don't think that it was on your
site. Anywho, I still have the original file that I downloaded and there is
no licence header on it. So sorry for the confusion, I'll gladly add your
license header to the copy that I have.
Also would like to say thanks for distributing this code in the first
place... it works perfectly.

Thanks,
David J. Ricker II
"Pieter Philippaerts" <Pi****@nospam.mentalis.org> wrote in message
news:eY**************@tk2msftngp13.phx.gbl...
"David Ricker" <da***@vanamatic.com> wrote
Here is a little class to play wav files


Next time you redistribute someone else's code, make sure you keep the
license header intact.
http://www.allapi.net/classlib/class.php?id=7

Regards,
Pieter Philippaerts
Managed SSL/TLS: http://www.mentalis.org/go.php?sl

Nov 20 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.