Imports System
Imports System.Runtime.InteropServices
Imports System.Resources
Imports System.IO

''' <summary>
''' Audio class helps to play audio files, resources, and sustem sounds.
''' </summary>
Public Class Audio

    ''' <summary>
    ''' A windows API from winmm.dll.
    ''' </summary>
    ''' <param name="name">A name as string.</param>
    ''' <param name="hmod">Usaually 0 or 0&amp;</param>
    ''' <param name="flags">The falgs. How do you want to play it.</param>
    ''' <returns>Returns integer value.</returns>
    Public Declare Auto Function PlaySound Lib "winmm.dll" (ByVal name _
      As String, ByVal hmod As Integer, ByVal flags As Integer) As Integer

    ''' <summary>
    ''' A windows API from winmm.dll.
    ''' </summary>
    ''' <param name="name">A name as byte array.</param>
    ''' <param name="hmod">Usaually 0 or 0&amp;</param>
    ''' <param name="flags">The falgs. How do you want to play it.</param>
    ''' <returns>Returns integer value.</returns>
    Public Declare Auto Function PlaySound Lib "winmm.dll" (ByVal name _
      As Byte(), ByVal hmod As Integer, ByVal flags As Integer) As Integer

    ''' <summary>
    ''' suspend execution until sound is finished
    ''' </summary>
    Private Const SND_SYNC As Integer = &H0

    ''' <summary>
    ''' continue executing code even if sound isn't finished
    ''' </summary>
    Public Const SND_ASYNC As Integer = &H1

    ''' <summary>
    ''' if file name is not found, don't play default sound
    ''' </summary>
    Public Const SND_NODEFAULT As Integer = &H2

    ''' <summary>
    ''' Play wav in memory
    ''' </summary>
    Public Const SND_MEMORY As Integer = &H4

    ''' <summary>
    ''' loop the sound until next call to the function
    ''' </summary>
    Public Const SND_LOOP As Integer = &H8

    ''' <summary>
    ''' don't stop any currently playing sound
    ''' </summary>
    Public Const SND_NOSTOP As Integer = &H10

    ''' <summary>
    ''' return immediately if driver is busy
    ''' </summary>
    Public Const SND_NOWAIT As Integer = &H2000

    ''' <summary>
    ''' Play system alias wav 
    ''' </summary>
    Public Const SND_ALIAS As Integer = &H10000

    ''' <summary>
    ''' name is a file name
    ''' </summary>
    Public Const SND_FILENAME As Integer = &H20000

    ''' <summary>
    ''' name is resource name or atom 
    ''' </summary>
    Public Const SND_RESOURCE As Integer = &H40004

    ''' <summary>
    ''' Plays the wave file.
    ''' </summary>
    ''' <param name="fileWaveFullPath">The full path of wave file.</param>
    ''' <returns>
    ''' If successful then returns the return value of PlaySound API otherwise returns -1.
    ''' </returns>
    Public Shared Function PlayWaveFile(ByVal fileWaveFullPath As String) As Integer
        Dim l_retval As Integer
        Try
            'Flags indicate that sound is a file, to play asynchrounously, 
            'not to stop any currently playing sound, and not to play the 
            'default sound (and return false) if file
            'is not found.  See declarations for other options.
            l_retval = PlaySound(fileWaveFullPath, 0, SND_FILENAME + SND_ASYNC + SND_NOSTOP + SND_NODEFAULT)
        Catch
            l_retval = -1
        End Try
        Return l_retval
    End Function

    ''' <summary>
    ''' Plays the wave resource.
    ''' </summary>
    ''' <param name="WaveResourceName">Name of the wave resource.</param>
    ''' <returns>
    ''' If successful then returns the return value of PlaySound API otherwise returns -1.
    ''' </returns>
    Public Shared Function PlayWaveResource(ByVal WaveResourceName As String) As Integer
        Dim l_retval As Integer

        ' get the namespace 
        Dim strNameSpace As String = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name.ToString()

        ' get the resource into a stream
        Dim resourceStream As Stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(strNameSpace + "." + WaveResourceName)
        If resourceStream Is Nothing Then Return -1

        ' bring stream into a byte array
        Dim wavData As Byte()
        ReDim wavData(CInt(resourceStream.Length))
        resourceStream.Read(wavData, 0, CInt(resourceStream.Length))

        ' play the resource
        Try
            l_retval = PlaySound(wavData, 0, SND_MEMORY + SND_ASYNC + SND_NOSTOP + SND_NODEFAULT)
        Catch ex As Exception
            l_retval = -1
        End Try
        Return l_retval
    End Function

    ''' <summary>
    ''' Plays the system sound.
    ''' </summary>
    ''' <param name="SystemWaveName">Name of the system sound.</param>
    ''' <returns>
    ''' If successful then returns the return value of PlaySound API otherwise returns -1.
    ''' </returns>
    Public Shared Function PlayWaveSystem(ByVal SystemWaveName As String) As Integer
        Dim l_retval As Integer
        Try
            l_retval = PlaySound(SystemWaveName, 0&, SND_ALIAS + SND_ASYNC + SND_NOSTOP + SND_NODEFAULT)
        Catch ex As Exception
            l_retval = -1
        End Try
        Return l_retval
    End Function
End Class
