
#Region " Compiler Options "

Option Strict On
Option Explicit On
Option Compare Binary

#End Region

#Region " Library Imports "

Imports Un4seen.Bass
Imports System.ComponentModel
Imports System.Runtime.InteropServices

#End Region

' Template version 1.2.0.0. Code developed for framework v2.0.50727.312
' This code is copyright (c) 2007 ActiveAsp Software. All rights reserved.
Namespace BassLib

    ''' <summary>
    ''' Bass library helper class for version 2.4 of the bass sound system
    ''' </summary>
    ''' <remarks>
    ''' -- Change Log --------------------------------------------------------
    ''' 02/08/2007 11:42:25 PM by Rick - Initial Creation
    ''' 
    ''' </remarks>
    Public Class BassLibrary

#Region " Constructor / Deconstructor "

        ''' <summary>
        ''' The shared starting point for this class
        ''' </summary>
        ''' <remarks></remarks>
        Shared Sub New()
            ' Enter Shared Class Creation Code Here

        End Sub

        ''' <summary>
        ''' The starting point for this class
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
            ' Enter Class Creation Code Here

        End Sub

        ''' <summary>
        ''' The end point for this class
        ''' </summary>
        ''' <remarks></remarks>
        Protected Overrides Sub Finalize()
            MyBase.Finalize()

        End Sub

#End Region

#Region " Private "

#Region " Private Variable Declarations "

        Private Shared loadedPlugIns As Hashtable = Nothing

        ' Audio Formats
        Private Shared _AudioFormats As String = ".mp3 .ogg .wav .mp2 .mp1 .aiff .m2a .mpa .m1a .swa .aif .mp3pro " + _
        ".mod .mo3 .s3m .xm .it .mtm .umx .mdz .s3z .itz .xmz .aac .mp4 .m4a .m4b .flac .ofr .ofs .ape .apl " + _
        ".spx .m4a .aac .mp4 .ac3 .mpc .mpp .mp+ .midi .mid .rmi .kar .tta .wv .wma"

        'Video formats
        Private Shared _VideoFormats As String = ".cdg .zip .kgz .mov .cda .mpg .mpeg .flv .avi .asf .wmv .vob .wm " + _
        ".dvr-ms .mpe .m1v"

        'Video formats
        Private Shared _KaraokeFormats As String = ".cdg .zip .kgz"

#End Region

#Region " Private Methods "

        Private Shared Function BASS_GetErrorDescription(ByRef errorCode As Integer) As String
            Dim text1 As String = ""
            Select Case errorCode
                Case Un4seen.Bass.BASSError.BASS_OK
                    Return "All is OK"
                Case Un4seen.Bass.BASSError.BASS_ERROR_MEM
                    Return "Memory error"
                Case Un4seen.Bass.BASSError.BASS_ERROR_FILEOPEN
                    Return "Can't open the file"
                Case Un4seen.Bass.BASSError.BASS_ERROR_DRIVER
                    Return "Can't find a free/valid driver"
                Case Un4seen.Bass.BASSError.BASS_ERROR_BUFLOST
                    Return "The sample buffer was lost"
                Case Un4seen.Bass.BASSError.BASS_ERROR_HANDLE
                    Return "Invalid handle"
                Case Un4seen.Bass.BASSError.BASS_ERROR_FORMAT
                    Return "Unsupported sample format"
                Case Un4seen.Bass.BASSError.BASS_ERROR_POSITION
                    Return "Invalid playback position"
                Case Un4seen.Bass.BASSError.BASS_ERROR_INIT
                    Return "BASS_Init has not been successfully called"
                Case Un4seen.Bass.BASSError.BASS_ERROR_START
                    Return "BASS_Start has not been successfully called"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NOCD
                    Return "No CD in drive"
                Case Un4seen.Bass.BASSError.BASS_ERROR_CDTRACK
                    Return "Invalid track number"
                Case Un4seen.Bass.BASSError.BASS_ERROR_ALREADY
                    Return "Already initialized/paused/whatever"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NOPAUSE
                    Return "Not paused"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NOTAUDIO
                    Return "Not an audio track"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NOCHAN
                    Return "Can't get a free channel"
                Case Un4seen.Bass.BASSError.BASS_ERROR_ILLTYPE
                    Return "An illegal type was specified"
                Case Un4seen.Bass.BASSError.BASS_ERROR_ILLPARAM
                    Return "An illegal parameter was specified"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NO3D
                    Return "No 3D support"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NOEAX
                    Return "No EAX support"
                Case Un4seen.Bass.BASSError.BASS_ERROR_DEVICE
                    Return "Illegal device number"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NOPLAY
                    Return "Not playing"
                Case Un4seen.Bass.BASSError.BASS_ERROR_FREQ
                    Return "Illegal sample rate"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NOTFILE
                    Return "The stream is not a file stream"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NOHW
                    Return "No hardware voices available"
                Case Un4seen.Bass.BASSError.BASS_ERROR_EMPTY
                    Return "The MOD music has no sequence data"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NONET
                    Return "No internet connection could be opened"
                Case Un4seen.Bass.BASSError.BASS_ERROR_CREATE
                    Return "Couldn't create the file"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NOFX
                    Return "Effects are not available"
                Case Un4seen.Bass.BASSError.BASS_ERROR_PLAYING
                    Return "The channel is playing"
                Case Un4seen.Bass.BASSError.BASS_ERROR_NOTAVAIL
                    Return "Requested data is not available"
                Case Un4seen.Bass.BASSError.BASS_ERROR_DECODE
                    Return "The channel is a 'decoding channel'"
                Case Un4seen.Bass.BASSError.BASS_ERROR_DX
                    Return "A sufficient DirectX version is not installed"
                Case Un4seen.Bass.BASSError.BASS_ERROR_TIMEOUT
                    Return "Connection timeout"
                Case Un4seen.Bass.BASSError.BASS_ERROR_FILEFORM
                    Return "Unsupported file format"
                Case Un4seen.Bass.BASSError.BASS_ERROR_SPEAKER
                    Return "Unavailable speaker"
                Case Un4seen.Bass.BASSError.BASS_ERROR_VERSION
                    Return "Invalid BASS version (used by add-ons)"
                Case Un4seen.Bass.BASSError.BASS_ERROR_CODEC
                    Return "Codec is not available/supported"
                Case Un4seen.Bass.BASSError.BASS_ERROR_UNKNOWN
                    Return "Some mystery error"
                Case Un4seen.Bass.BASSError.BASS_FX_ERROR_NODECODE
                    Return "BassFx: Not a decoding channel"
                Case Un4seen.Bass.BASSError.BASS_FX_ERROR_BPMINUSE
                    Return "BassFx: BPM detection is in use"
                Case Un4seen.Bass.BASSError.BASS_ERROR_WMA_LICENSE
                    Return "BassWma: the file is protected"
                Case Un4seen.Bass.BASSError.BASS_ERROR_WMA_WM9
                    Return "BassWma: WM9 is required"
                Case Un4seen.Bass.BASSError.BASS_ERROR_WMA_DENIED
                    Return "BassWma: Access denied (user/pass is invalid)"
                Case Un4seen.Bass.BASSError.BASS_ERROR_WMA_CODEC
                    Return "BassWma: No appropriate codec is installed"
                Case Un4seen.Bass.BASSError.BASS_ERROR_WMA_INDIVIDUAL
                    Return "BassWma: Individualization is needed"
                Case Un4seen.Bass.BASSError.BASS_ERROR_ACM_CANCEL
                    Return "BassEnc: ACM codec selection cancelled"
                Case Un4seen.Bass.BASSError.BASS_ERROR_CAST_DENIED
                    Return "BassEnc: Access denied (invalid password)"
                Case Un4seen.Bass.BASSError.BASS_VST_ERROR_NOINPUTS
                    Return "BassVst: The given effect has no inputs and is probably a VST instrument and no effect"
                Case Un4seen.Bass.BASSError.BASS_VST_ERROR_NOOUTPUTS
                    Return "BassVst:  The given effect has no outputs"
                Case Un4seen.Bass.BASSError.BASS_VST_ERROR_NOREALTIME
                    Return "BassVst: The given effect does not support realtime processing"
                Case Else
                    text1 = ""
            End Select
            Return text1
        End Function

        Private Shared Sub ThrowBassErrorException()
            Dim ErrorCode As Integer = Un4seen.Bass.Bass.BASS_ErrorGetCode()
            If ErrorCode <> 0 Then
                Throw New Exception(BASS_GetErrorDescription(ErrorCode))
            End If
        End Sub

        Private Shared Sub ThrowBassErrorMessageBox()
            Dim ErrorCode As Integer = Un4seen.Bass.Bass.BASS_ErrorGetCode()
            If ErrorCode <> 0 Then
                System.Windows.Forms.MessageBox.Show(BASS_GetErrorDescription(ErrorCode), My.Application.Info.Title, Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Stop, Windows.Forms.MessageBoxDefaultButton.Button1, Windows.Forms.MessageBoxOptions.DefaultDesktopOnly, False)
            End If
        End Sub

        Private Shared Function FixFileFilter(ByVal filter As String) As String
            Dim tmp As String = filter

            tmp = tmp.Replace("All Supported Files|", "All Supported Files|*.cdg;*.zip;*.kgz;")
            tmp = tmp.Replace("Windows Media Audio (", "Windows Media Audio/Video (")
            tmp += "|Karaoke Files (*.cdg;*.zip;*.kgz)|*.cdg;*.zip;*.kgz"
            tmp += "|All Files (*.*)|*.*"

            Return tmp
        End Function

#End Region

#End Region

#Region " Public "

#Region " Public Property Declarations "

        Private Shared _DeviceLatencyMs As Integer = 0
        ''' <summary>
        ''' The delay (rounded up to the nearest millisecond) for playback of HSTREAM/HMUSIC channels to start and be heard. 
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        <Description("The delay (rounded up to the nearest millisecond) for playback of HSTREAM/HMUSIC channels to start and be heard."), Browsable(True), EditorBrowsable(EditorBrowsableState.Always), [ReadOnly](False)> _
        Public Shared Property DeviceLatencyMs() As Integer
            Get
                Return _DeviceLatencyMs
            End Get
            Set(ByVal value As Integer)
                _DeviceLatencyMs = value
            End Set
        End Property ' DeviceLatencyMs


        Private Shared _ThrowErrorsAsException As Boolean = False
        ''' <summary>
        ''' Decides whether errors are thrown as exceptions or messageboxes
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        <Description("Decides whether errors are thrown as exceptions or messageboxes"), Browsable(True), EditorBrowsable(EditorBrowsableState.Always), [ReadOnly](False)> _
        Public Shared Property ThrowErrorsAsException() As Boolean
            Get
                Return _ThrowErrorsAsException
            End Get
            Set(ByVal value As Boolean)
                _ThrowErrorsAsException = value
            End Set
        End Property ' ThrowErrorsAsException


        Private Shared _FileFilter As String = "All Files (*.*)|*.*"
        ''' <summary>
        ''' Returns a file filter which can be used in a standard OpenFileDialog.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        <Description("Returns a file filter which can be used in a standard OpenFileDialog."), Browsable(True), EditorBrowsable(EditorBrowsableState.Always), [ReadOnly](True)> _
        Public Shared ReadOnly Property FileFilter() As String
            Get
                If _FileFilter = "All Files (*.*)|*.*" Then
                    _FileFilter = FixFileFilter(Un4seen.Bass.Utils.BASSAddOnGetSupportedFileFilter(loadedPlugIns, "All Supported Files", True))
                End If
                Return _FileFilter
            End Get
        End Property

        Private Shared _SupportedFileExtensions As String = ""
        ''' <summary>
        ''' Returns a list of file extensions that are supported.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        <Description("Returns a file filter which can be used in a standard OpenFileDialog."), Browsable(True), EditorBrowsable(EditorBrowsableState.Always), [ReadOnly](True)> _
        Public Shared ReadOnly Property SupportedFileExtensions() As String
            Get
                If _SupportedFileExtensions = "" Then
                    _SupportedFileExtensions = Un4seen.Bass.Utils.BASSAddOnGetSupportedFileExtensions(Nothing)
                    _SupportedFileExtensions += " .cdg .kgz .wmv .dvr-ms"
                End If
                Return _SupportedFileExtensions
            End Get
        End Property

#End Region

#Region " Public Enumerations "

#End Region

#Region " Public Delegates "

#End Region

#Region " Public Callbacks "

#End Region

#Region " Public Events "

#End Region

#Region " Public Methods "

        ''' <summary>
        ''' Determines whether a file uses video or not
        ''' </summary>
        ''' <param name="filename">Filename to check</param>
        ''' <returns>Boolean value</returns>
        ''' <remarks></remarks>
        Public Shared Function IsVideoFile(ByVal filename As String) As Boolean
            Dim ext As String = IO.Path.GetExtension(filename).ToLowerInvariant
            If _VideoFormats.IndexOf(ext) > -1 Then
                Return True
            Else
                Return False
            End If
        End Function

        ''' <summary>
        ''' Determines whether a file uses audio or not
        ''' </summary>
        ''' <param name="filename">Filename to check</param>
        ''' <returns>Boolean value</returns>
        ''' <remarks></remarks>
        Public Shared Function IsAudioFile(ByVal filename As String) As Boolean
            Dim ext As String = IO.Path.GetExtension(filename).ToLowerInvariant
            If _AudioFormats.IndexOf(ext) > -1 Then
                Return True
            Else
                Return False
            End If
        End Function

        ''' <summary>
        ''' Determines whether a file uses karaoke or not
        ''' </summary>
        ''' <param name="filename">Filename to check</param>
        ''' <returns>Boolean value</returns>
        ''' <remarks></remarks>
        Public Shared Function IsKaraokeFile(ByVal filename As String) As Boolean
            Dim ext As String = IO.Path.GetExtension(filename).ToLowerInvariant
            If _KaraokeFormats.IndexOf(ext) > -1 Then
                Return True
            Else
                Return False
            End If
        End Function

        ''' <summary>
        ''' Initializes an output device. User 0 for no sound
        ''' </summary>
        ''' <param name="myHandle"></param>
        ''' <param name="applicationFolder"></param>
        ''' <remarks></remarks>
        Public Shared Sub InitBass(ByVal myHandle As IntPtr, ByVal applicationFolder As String, Optional ByVal device As Integer = -1, Optional ByVal freq As Integer = 44100)
            Dim BB As Boolean = False

            If Un4seen.Bass.Bass.BASS_Init(device, freq, BASSInit.BASS_DEVICE_LATENCY Or BASSInit.BASS_DEVICE_DEFAULT, myHandle, Nothing) Then
                BB = Un4seen.Bass.Bass.BASS_Start()
                ' Get audio device latency
                Dim info As BASS_INFO = New BASS_INFO
                Bass.BASS_GetInfo(info)
                _DeviceLatencyMs = info.latency

                ' Load plugin stuff
                Un4seen.Bass.Bass.LoadMe(applicationFolder)
                loadedPlugIns = Bass.BASS_PluginLoadDirectory(applicationFolder)
            End If


        End Sub

        Public Shared Sub TerminateBass()
            Dim BB As Boolean = False

            BB = Un4seen.Bass.Bass.BASS_Stop()
            BB = Un4seen.Bass.Bass.BASS_Free()
            BB = Un4seen.Bass.Bass.FreeMe()
        End Sub

#Region " Bass Error Codes "

        Public Shared Sub ThrowBassError()
            If _ThrowErrorsAsException Then
                ThrowBassErrorException()
            Else
                ThrowBassErrorMessageBox()
            End If
        End Sub

#End Region

#End Region

#End Region

    End Class

End Namespace

