Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Select Sound Card with BASS 2.4

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • PBWin Select Sound Card with BASS 2.4

    This is a sample player I made which can use any of your sound cards without unloading (and with a little more code, at the same time). This used BASS.DLL from www.un4seen.com and the PowerBASIC include files from Jose Roca's site:
    www.jose.it-berater.org

    One item has to change in the BASS.INC file.. BASS_CHANNELGETLENGTH takes two parameters and only one is shown in the include file. *(Now correct on the web site)

    This program uses both bass.inc (which on my system is PB24BASS.INC) and BASSWMA.INC (BASSWMA.DLL has to be downloaded from www.un4seen.com)

    If you have more than one sound card, this allows you to change the active one. In this program, that change happens when you sucessfully load a file. If there is no message box with an error when you change the sound device, this will become the device on the next Load File execution. The button is not visible if you do not have more than one sound card.

    For PB9:
    Code:
    #PBFORMS CREATED V1.51
    '------------------------------------------------------------------------------
    ' The first line in this file is a PB/Forms metastatement.
    ' It should ALWAYS be the first line of the file. Other
    ' PB/Forms metastatements are placed at the beginning and
    ' end of "Named Blocks" of code that should be edited
    ' with PBForms only. Do not manually edit or delete these
    ' metastatements or PB/Forms will not be able to reread
    ' the file correctly.  See the PB/Forms documentation for
    ' more information.
    ' Named blocks begin like this:    #PBFORMS BEGIN ...
    ' Named blocks end like this:      #PBFORMS END ...
    ' Other PB/Forms metastatements such as:
    '     #PBFORMS DECLARATIONS
    ' are used by PB/Forms to insert additional code.
    ' Feel free to make changes anywhere else in the file.
    '------------------------------------------------------------------------------
    'by Barry Erick
    #COMPILE EXE
    #DIM ALL
    #DEBUG ERROR ON
    '------------------------------------------------------------------------------
    '   ** Includes **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN INCLUDES
    %USEMACROS = 1
    #IF NOT %DEF(%WINAPI)
        #INCLUDE "WIN32API.INC"
    #ENDIF
    #IF NOT %DEF(%COMMCTRL_INC)
        #INCLUDE "COMMCTRL.INC"
    #ENDIF
    #INCLUDE "PBForms.INC"
    #PBFORMS END INCLUDES
    
    '------------------------------------------------------------------------------
     #INCLUDE "pb24BASS.INC" '<-- from Jose Roca forums for Headers for PowerBASIC
      ' original title is BASS.INC, but I renamed to keep track of different versions
      ' Note: This also assumes a correction in this .inc file for BASS_CHANNELGETLENGTH
      'as it takes TWO DWORD Parameters and not one. This program uses two as per v2.4
      'documentation (the include file is correct on the website as of 7/20/09)
      ' this calls BASS.DLL version 2.4.xx available from un4seen.com
      #INCLUDE "Basswma.inc" 'ditto but calls BASSWMA.DLL
    '------------------------------------------------------------------------------
    '   ** Constants **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN CONSTANTS
    %IDD_DIALOG1            =  101
    %lst_SoundCards         = 1001
    %IDC_LABEL1             = 1002
    %cmd_GetFile            = 1003
    %cmd_ChangeDevice       = 1004
    %IDC_LABEL2             = 1005
    %lbl_CurrentSoundDevice = 1006
    %cmd_Play               = 1007
    %cmd_Pause              = 1008
    %cmd_stop               = 1009
    %cmd_exit               = 1010
    %IDC_FRAME1             = 1011
    %lbl_elapsedTime        = 1012
    %IDC_FRAME2             = 1013  '*
    %lbl_length             = 1014
    %IDC_LABEL3             = 1015
    %IDC_LABEL4             = 1016
    %prb_Progress           = 1017
    %tb_Volume              = 1018
    %IDC_LABEL5             = 1019
    %IDC_LABEL6             = 1020
    %IDC_FRAME3             = 1021  '*
    %IDC_LABEL7             = 1022
    %lbl_CPU                = 1023
    %IDC_FRAME4             = 1024  '*
    %IDC_LABEL8             = 1025
    %IDC_FRAME5             = 1026
    #PBFORMS END CONSTANTS
    %timer1 = 5001
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Declarations **
    '------------------------------------------------------------------------------
    DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
    DECLARE FUNCTION SampleListBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL _
        lCount AS LONG) AS LONG
    DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
    #PBFORMS DECLARATIONS
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Main Application Entry Point **
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN()
        PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR %ICC_INTERNET_CLASSES)
    
        GLOBAL wmahndl AS DWORD
        wmahndl = BASS_PLUGINLOAD ("BASSWMA.DLL",0)      'load the plugin
        ShowDIALOG1 %HWND_DESKTOP
        BASS_PLUGINFREE wmahndl                          'unload the plugin
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION Byte2Time(BYVAL N AS DWORD,ShowTenths AS LONG) AS STRING
        LOCAL cc,ss,mm,dd,hh AS LONG
        LOCAL l AS STRING
        N = FIX(N * 0.0005659)
        CC& = N MOD 100
        N = N \ 100
        SS& = FIX(N)
        MM& = SS& \ 60
        HH& = MM& \ 60
        DD& = HH& \ 24
        SS& = SS& - MM& * 60
        MM& = MM& - HH& * 60
        HH& = HH& - DD& * 24
    
        L$ = ":"
        IF showTenths<>0 THEN
            FUNCTION  = RIGHT$("" + LTRIM$(STR$(HH&)), 2) + L$ + _
                        RIGHT$("00" + LTRIM$(STR$(MM&)), 2) + L$ + _
                        RIGHT$("00" + LTRIM$(STR$(SS&)), 2) + "." + _
                        LEFT$("" + LTRIM$(STR$(CC&)), 1)
        ELSE
            FUNCTION  = RIGHT$("" + LTRIM$(STR$(HH&)), 2) + L$ + _
                        RIGHT$("00" + LTRIM$(STR$(MM&)), 2) + L$ + _
                        RIGHT$("00" + LTRIM$(STR$(SS&)), 2)
        END IF
    END FUNCTION
    
    '------------------------------------------------------------------------------
    '   ** CallBacks **
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowDIALOG1Proc()
        STATIC num_cards AS LONG
        GLOBAL DidInitBass,ThisOneInit() AS LONG
        STATIC filename AS ASCIIZ * %max_path
        LOCAL res AS STRING
        STATIC streamhandle AS LONG
        STATIC tbv_hndl AS DWORD
        STATIC SetDevice AS LONG
        LOCAL UseThisSoundCard AS LONG
        LOCAL i,r AS LONG
        LOCAL di AS BASS_DEVICEINFO
        LOCAL vol AS DOUBLE
        LOCAL j,k AS DWORD
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                ' Initialization handler
                'the BASS version must be the same as we expect to insure the .inc file matches the .dll
                IF HI(WORD,bass_GetVersion) <> %BASSVERSION THEN
                    ? "The incorrect version of BASS found. Found  Bass.dll v " & _
                    HEX$(HI(WORD,Bass_GetVersion)) & $CRLF & _
                    "The program will terminate. Fix the problem and retry.." , _
                    %MB_ICONERROR,"Bass_Demo"
                    DIALOG END CB.HNDL
                END IF
                'fill listbox with sound devicenames
                LISTBOX RESET CB.HNDL,%lst_soundcards 'clear out anything pbforms puts in there
                 num_cards=0
                 FOR i = 1 TO 20 'who has more than 20 cards? 'start at 1 to bypass the "no Sound" device
                     r=bass_GetDeviceInfo (i,di)
                     IF r = 0 THEN  '0 if successful.. else we must have run out of cards
                         EXIT FOR
                     ELSEIF di.flags AND %BASS_DEVICE_ENABLED THEN
                         num_cards +=1
                         LISTBOX ADD CB.HNDL,%lst_SoundCards,[email protected]
                     END IF
                 NEXT
    
                 ' get the default or current card
                 'init the bass system
                 UseThisSoundCard = BASS_GetDevice 'the next items will leave the last card set.
                 REDIM ThisOneInit(1:Num_Cards)
                  IF NOT DidInitBass THEN 'init the num_cards
                      FOR i = 1 TO num_cards
                          'BASS_INIT is card number (default is -1, 0 is no sound),freq, flags, win hndl,class id
                       didInitBass = Bass_Init(i,44100,0,CB.HNDL,BYVAL 0)'we initialize all so we can change sound cards
                       thisOneInit(i)=1 'since not all found may be good
                      NEXT
                  END IF
                  'check for anything being available
                   FOR i = 1 TO UBOUND(ThisOneInit)
                       IF ThisOneInit(i)= 1 THEN
                          DidInitBass = %True
                          EXIT FOR
                       ELSE
                           DidInitBass = %False
                       END IF
                   NEXT
                  IF  DidInitBass = %FALSE THEN
                      ? FORMAT$(bass_ErrorGetCode)
                      DIALOG END CB.HNDL
                  END IF
    
                  'now set the device in the dialog
                  i = UseThisSoundCard 'make sure we select the default at this point.
                  IF ThisOneInit(i) = 0 THEN 'we have a problem
                      'find what we can use
                      FOR i = 1 TO Num_Cards
                          IF ThisOneInit(i) = 1 THEN
                              bass_SetDevice i
                              EXIT FOR
                          END IF
                      NEXT
                  ELSE
                        bass_SetDevice i
                  END IF
                  i=bass_GetDevice'make sure we agree...
                  LISTBOX GET TEXT CB.HNDL, %lst_SoundCards,i TO res
                  CONTROL SET TEXT CB.HNDL, %lbl_CurrentSoundDevice,res
                  CONTROL DISABLE CB.HNDL,%cmd_Play
                  CONTROL DISABLE CB.HNDL,%cmd_Pause
                  CONTROL DISABLE CB.HNDL,%cmd_Stop
                  settimer CB.HNDL,%timer1,100,0
                  PROGRESSBAR SET RANGE CB.HNDL,%prb_Progress,0,100
                  PROGRESSBAR SET STEP CB.HNDL, %prb_Progress,1
                  CONTROL HANDLE CB.HNDL,%tb_Volume TO tbv_hndl
    
                  CONTROL SEND CB.HNDL,%tb_Volume,%tbm_Setrange,0,MAKLNG(0,100)
                  vol=bass_GetVolume  'volume returned 0-1
                  CONTROL SEND CB.HNDL,%tb_Volume,%tbm_setPos,1,100-(vol*100)'fir the scale
                  IF Num_Cards<2 THEN  'if only one card, we can't change them
                      CONTROL SHOW STATE CB.HNDL,%cmd_ChangeDevice,%SW_HIDE
                  END IF
                  setdevice = 0
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CBWPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
            CASE %WM_VSCROLL
                SELECT CASE CB.LPARAM
                    CASE tbv_hndl
                       CONTROL SEND CB.HNDL,%tb_Volume,%tbm_GetPos,0,0 TO i'vol
                       vol=100-i   'fix scal so it runs from bottom to top
                       bass_SetVolume (vol/100) 'fix scale so it fits BASS 0-1 parameter
                END SELECT
            CASE %WM_TIMER
                SELECT CASE AS LONG CB.CTL
                    CASE %timer1
                        IF streamhandle <>0 THEN
                            LOCAL t AS DWORD
                            t = bass_channelgetposition(streamHandle,%bass_pos_byte)
                            CONTROL SET TEXT CB.HNDL,%lbl_elapsedtime,Byte2Time(t,1)
                            j=bass_getDevice
                            CONTROL SET TEXT CB.HNDL, %idc_Label6,STR$(j)
                            k=BASS_CHANNELGETLENGTH(StreamHandle,%bass_pos_byte)
                            j = (t/k)*100
                            PROGRESSBAR SET POS CB.HNDL,%prb_Progress,j
                        END IF
                        IF bass_channelisActive(streamHandle) <>%BASS_Active_Stopped THEN
                            CONTROL DISABLE CB.HNDL,%cmd_GetFile
                        ELSE
                            CONTROL ENABLE CB.HNDL,%cmd_GetFile
                       END IF
                       CONTROL SET TEXT CB.HNDL,%lbl_CPU,FORMAT$(Bass_GetCPU,"#0%")
    
                END SELECT
            CASE %WM_COMMAND
                ' Process control notifications
                SELECT CASE AS LONG CBCTL
                    CASE %lst_SoundCards
    
                    CASE %IDC_LABEL1
    
                    CASE %cmd_GetFile
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            LOCAL filter AS STRING
                            LOCAL ofnflags AS DWORD
                            streamhandle = 0
                            ofnflags = %OFN_FILEMUSTEXIST OR %OFN_PATHMUSTEXIST
                            filter = CHR$("Streamable files (wav/aif/mp3/mp2/mp1/ogg)",0,"*.wav;" &  _
                                "*.aif;*.mp3;*.mp2;*.mp1;*.ogg",0,"All Files (*.*)",0,"*.*",0)
                            DISPLAY OPENFILE ,,,"Get a Music File","",filter,"","",ofnFlags _
                                TO Filename
                        END IF
                        IF SetDevice <> 0 THEN
                            bass_SetDevice setdevice
                            i = BASS_GetDevice
                            LISTBOX GET TEXT CB.HNDL,%lst_SoundCards,i TO res
                            CONTROL SET TEXT CB.HNDL,%lbl_CurrentSoundDevice,res
                        END IF
                        StreamHandle = BASS_StreamCreateFile(%FALSE,Filename,0,0,0)
                        IF Streamhandle = 0 THEN
                            ? "Failed to open stream " & filename,%MB_ICONERROR,"Bass Demo"
                            EXIT FUNCTION
                            ELSE
                                i = PARSECOUNT(filename,"\")
                                res=filename
                                res = PARSE$(res,i)
                                DIALOG SET TEXT CB.HNDL,PARSE$(filename,"\",i)
                                CONTROL ENABLE CB.HNDL,%cmd_Play
                                LOCAL flength,timeTotalLength AS DWORD
                                LOCAL mytime AS STRING
                                flength = bass_CHANNELGETLENGTH(StreamHandle,%bass_pos_byte)
                                CONTROL SET TEXT CB.HNDL,%lbl_length,Byte2Time(flength,0)
                                'timetotallength = bass_channelBytes2Seconds(StreamHandle,flength)
                                'flength = timetotallength\60
                               ' mytime = format$(flength,"#.##")'& format$(((TimeTotalLength MOD 60)/60),"00")
                        END IF
                    CASE %cmd_ChangeDevice
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            LISTBOX  GET SELCOUNT CB.HNDL,%lst_Soundcards TO i
                            IF i <> 1 THEN
                                ? "One sound card must be selected. Select and try again", _
                                %MB_ICONERROR,"error"
                                EXIT FUNCTION
                            END IF
                            LISTBOX GET SELECT CB.HNDL,%lst_Soundcards TO i
                            CONTROL SET TEXT CB.HNDL, %idc_Label7, STR$(i)
                            setdevice = 0
                            IF i <> bass_GetDevice  THEN 'not currently in use
                                SetDevice= i
                            END IF
                        END IF
    
                    CASE %IDC_LABEL2
    
                    CASE %lbl_CurrentSoundDevice
    
                    CASE %cmd_Play
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            IF streamhandle <> 0 THEN
                                IF  bass_ChannelisActive(streamHandle) = %BASS_Active_Paused THEN
                                    BASS_CHANNELPLAY(StreamHandle,%False) 'resume
                                ELSE
                                    BASS_CHANNELPLAY(streamhandle,%TRue)
                                END IF
                                CONTROL ENABLE CB.HNDL,%cmd_Pause
                                CONTROL ENABLE CB.HNDL,%cmd_Stop
                                CONTROL DISABLE CB.HNDL,%cmd_play
                            END IF
                        END IF
    
                    CASE %cmd_Pause
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            BASS_CHANNELPAUSE(StreamHandle)
                            CONTROL ENABLE CB.HNDL,%cmd_Play
                            CONTROL DISABLE CB.HNDL, %cmd_Stop
                            CONTROL DISABLE CB.HNDL, %cmd_Pause
                        END IF
    
                    CASE %cmd_stop
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            BASS_CHANNELSTOP StreamHandle
                                CONTROL ENABLE CB.HNDL,%cmd_Play
                                CONTROL DISABLE CB.HNDL,%cmd_Pause
                                CONTROL DISABLE CB.HNDL,%cmd_Stop
                         END IF
    
                    CASE %cmd_exit
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            IF StreamHandle>0 THEN
                                Bass_StreamFree streamhandle
                           END IF
                            DIALOG END CB.HNDL
                        END IF
    
                END SELECT
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Sample Code **
    '------------------------------------------------------------------------------
    FUNCTION SampleListBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount _
        AS LONG) AS LONG
        LOCAL i AS LONG
    
        FOR i = 1 TO lCount
            LISTBOX ADD hDlg, lID, USING$("Test Item #", i)
        NEXT i
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Dialogs **
    '------------------------------------------------------------------------------
    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
    
    #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
        LOCAL hDlg  AS DWORD
    
        DIALOG NEW hParent, "Dialog1", 92, 153, 236, 164, TO hDlg
        CONTROL ADD LISTBOX, hDlg, %lst_SoundCards, , 10, 65, 100, 25, %WS_CHILD _
            OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %LBS_NOTIFY, _
            %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
            %WS_EX_RIGHTSCROLLBAR
        CONTROL ADD BUTTON,  hDlg, %cmd_GetFile, "Get File", 5, 5, 50, 15
        CONTROL ADD BUTTON,  hDlg, %cmd_ChangeDevice, "Change Sound Device", 10, _
            95, 100, 15
        CONTROL ADD LABEL,   hDlg, %lbl_CurrentSoundDevice, "", 15, 125, 85, 10, _
            %WS_CHILD OR %WS_VISIBLE OR %SS_CENTER, %WS_EX_LEFT OR _
            %WS_EX_LTRREADING
        CONTROL ADD BUTTON,  hDlg, %cmd_Play, "Play", 38, 22, 50, 15
        CONTROL ADD BUTTON,  hDlg, %cmd_Pause, "Pause", 88, 22, 50, 15
        CONTROL ADD BUTTON,  hDlg, %cmd_stop, "Stop", 138, 22, 50, 15
        CONTROL ADD BUTTON,  hDlg, %cmd_exit, "E&xit", 185, 145, 50, 15
        CONTROL ADD FRAME,   hDlg, %IDC_FRAME1, "Current Sound Device", 10, 115, _
            100, 23, %WS_CHILD OR %WS_VISIBLE OR %BS_CENTER OR %BS_TOP OR _
            %BS_GROUPBOX, %WS_EX_LEFT OR %WS_EX_LTRREADING
        CONTROL ADD LABEL,   hDlg, %lbl_elapsedTime, "0:00", 65, 10, 45, 10, _
            %WS_CHILD OR %WS_VISIBLE OR %SS_RIGHT, %WS_EX_LEFT OR _
            %WS_EX_LTRREADING
        CONTROL ADD LABEL,   hDlg, %lbl_length, "0:00", 130, 10, 50, 10, _
            %WS_CHILD OR %WS_VISIBLE OR %SS_RIGHT, %WS_EX_LEFT OR _
            %WS_EX_LTRREADING
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL3, "Elapsed Time", 82, 0, 44, 10
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL4, "Total Time", 144, 0, 34, 10
        CONTROL ADD "msctls_trackbar32", hDlg, %tb_Volume, "msctls_trackbar32_1", _
            175, 50, 25, 65, %WS_CHILD OR %WS_VISIBLE OR %TBS_VERT OR _
            %TBS_BOTTOM
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL5, "Master Volume", 160, 115, 49, 10
        CONTROL ADD LABEL,   hDlg, %lbl_CPU, "", 199, 9, 19, 10
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL8, "CPU Time", 188, 0, 34, 10
        CONTROL ADD FRAME,   hDlg, %IDC_FRAME5, "Sound Devices", 6, 52, 110, 95
    #PBFORMS END DIALOG
         CONTROL ADD PROGRESSBAR, hdlg, %prb_Progress,"", _
                50,40,120,10,%WS_CHILD OR %WS_VISIBLE OR %PBS_SMOOTH
        SampleListBox  hDlg, %lst_SoundCards, 30
    
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
    
    #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
    #PBFORMS END CLEANUP
    
        FUNCTION = lRslt
    END FUNCTION
    '------------------------------------------------------------------------------
    Last edited by Barry Erick; 21 Jul 2009, 12:20 AM.
    Barry

  • #2
    The previous version only would change sound cards on file load. This does that, plus anytime the play button is pressed. Click on change Sound Card and at the next Play or load, the change will be made.
    Code:
    #PBFORMS CREATED V1.51
    '------------------------------------------------------------------------------
    ' The first line in this file is a PB/Forms metastatement.
    ' It should ALWAYS be the first line of the file. Other
    ' PB/Forms metastatements are placed at the beginning and
    ' end of "Named Blocks" of code that should be edited
    ' with PBForms only. Do not manually edit or delete these
    ' metastatements or PB/Forms will not be able to reread
    ' the file correctly.  See the PB/Forms documentation for
    ' more information.
    ' Named blocks begin like this:    #PBFORMS BEGIN ...
    ' Named blocks end like this:      #PBFORMS END ...
    ' Other PB/Forms metastatements such as:
    '     #PBFORMS DECLARATIONS
    ' are used by PB/Forms to insert additional code.
    ' Feel free to make changes anywhere else in the file.
    '------------------------------------------------------------------------------
    
    #COMPILE EXE
    #DIM ALL
    #DEBUG ERROR ON
    '------------------------------------------------------------------------------
    '   ** Includes **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN INCLUDES
    %USEMACROS = 1
    #IF NOT %DEF(%WINAPI)
        #INCLUDE "WIN32API.INC"
    #ENDIF
    #IF NOT %DEF(%COMMCTRL_INC)
        #INCLUDE "COMMCTRL.INC"
    #ENDIF
    #INCLUDE "PBForms.INC"
    #PBFORMS END INCLUDES
    
    '------------------------------------------------------------------------------
     #INCLUDE "pb24BASS.INC" '<-- from Jose Roca forums for Headers for PowerBASIC
      ' original title is BASS.INC, but I renamed to keep track of different versions
      ' Note: This also assumes a correction in this .inc file for BASS_CHANNELGETLENGTH
      'as it takes TWO DWORD Parameters and not one. This program uses two as per v2.4
      'documentation
      ' this calls BASS.DLL version 2.4.xx available from un4seen.com
      #INCLUDE "Basswma.inc" 'ditto but calls BASSWMA.DLL
    '------------------------------------------------------------------------------
    '   ** Constants **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN CONSTANTS
    %IDD_DIALOG1            =  101
    %lst_SoundCards         = 1001
    %IDC_LABEL1             = 1002
    %cmd_GetFile            = 1003
    %cmd_ChangeDevice       = 1004
    %IDC_LABEL2             = 1005
    %lbl_CurrentSoundDevice = 1006
    %cmd_Play               = 1007
    %cmd_Pause              = 1008
    %cmd_stop               = 1009
    %cmd_exit               = 1010
    %IDC_FRAME1             = 1011
    %lbl_elapsedTime        = 1012
    %IDC_FRAME2             = 1013  '*
    %lbl_length             = 1014
    %IDC_LABEL3             = 1015
    %IDC_LABEL4             = 1016
    %prb_Progress           = 1017
    %tb_Volume              = 1018
    %IDC_LABEL5             = 1019
    %IDC_LABEL6             = 1020
    %IDC_FRAME3             = 1021  '*
    %IDC_LABEL7             = 1022
    %lbl_CPU                = 1023
    %IDC_FRAME4             = 1024  '*
    %IDC_LABEL8             = 1025
    %IDC_FRAME5             = 1026
    %IDC_LABEL9             = 1027
    #PBFORMS END CONSTANTS
    %timer1 = 5001
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Declarations **
    '------------------------------------------------------------------------------
    DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
    DECLARE FUNCTION SampleListBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL _
        lCount AS LONG) AS LONG
    DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
    #PBFORMS DECLARATIONS
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Main Application Entry Point **
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN()
        PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR %ICC_INTERNET_CLASSES)
    
        GLOBAL wmahndl AS DWORD
        wmahndl = BASS_PLUGINLOAD ("BASSWMA.DLL",0)      'load the plugin
        ShowDIALOG1 %HWND_DESKTOP
        BASS_PLUGINFREE wmahndl                          'unload the plugin
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION Byte2Time(BYVAL N AS DWORD,ShowTenths AS LONG) AS STRING
        LOCAL cc,ss,mm,dd,hh AS LONG
        LOCAL l AS STRING
        N = FIX(N * 0.0005659)
        CC& = N MOD 100
        N = N \ 100
        SS& = FIX(N)
        MM& = SS& \ 60
        HH& = MM& \ 60
        DD& = HH& \ 24
        SS& = SS& - MM& * 60
        MM& = MM& - HH& * 60
        HH& = HH& - DD& * 24
    
        L$ = ":"
        IF showTenths<>0 THEN
            FUNCTION  = RIGHT$("" + LTRIM$(STR$(HH&)), 2) + L$ + _
                        RIGHT$("00" + LTRIM$(STR$(MM&)), 2) + L$ + _
                        RIGHT$("00" + LTRIM$(STR$(SS&)), 2) + "." + _
                        LEFT$("" + LTRIM$(STR$(CC&)), 1)
        ELSE
            FUNCTION  = RIGHT$("" + LTRIM$(STR$(HH&)), 2) + L$ + _
                        RIGHT$("00" + LTRIM$(STR$(MM&)), 2) + L$ + _
                        RIGHT$("00" + LTRIM$(STR$(SS&)), 2)
        END IF
    END FUNCTION
    
    '------------------------------------------------------------------------------
    '   ** CallBacks **
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowDIALOG1Proc()
        STATIC num_cards AS LONG
        GLOBAL DidInitBass,ThisOneInit() AS LONG
        STATIC filename AS ASCIIZ * %max_path
        LOCAL res AS STRING
        STATIC streamhandle AS LONG
        STATIC tbv_hndl AS DWORD
        STATIC SetDevice AS LONG
        LOCAL UseThisSoundCard AS LONG
        LOCAL i,r AS LONG
        LOCAL di AS BASS_DEVICEINFO
        LOCAL vol AS DOUBLE
        LOCAL j,k AS DWORD
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                ' Initialization handler
                'the BASS version must be the same as we expect to insure the .inc file matches the .dll
                IF HI(WORD,bass_GetVersion) <> %BASSVERSION THEN
                    ? "The incorrect version of BASS found. Found  Bass.dll v " & _
                    HEX$(HI(WORD,Bass_GetVersion)) & $CRLF & _
                    "The program will terminate. Needed is Bass Version  2.04. Fix the problem and retry.." , _
                    %MB_ICONERROR,"Bass_Demo"
                    DIALOG END CB.HNDL
                END IF
                'fill listbox with sound devicenames
                LISTBOX RESET CB.HNDL,%lst_soundcards 'clear out anything pbforms puts in there
                 num_cards=0
                 FOR i = 1 TO 20 'who has more than 20 cards? 'start at 1 to bypass the "no Sound" device
                     r=bass_GetDeviceInfo (i,di)
                     IF r = 0 THEN  '0 if successful.. else we must have run out of cards
                         EXIT FOR
                     ELSEIF di.flags AND %BASS_DEVICE_ENABLED THEN
                         num_cards +=1
                         LISTBOX ADD CB.HNDL,%lst_SoundCards,[email protected]
                     END IF
                 NEXT
    
                 ' get the default or current card
                 'init the bass system
                 UseThisSoundCard = BASS_GetDevice 'the next items will leave the last card set.
                 REDIM ThisOneInit(1:Num_Cards)
                  IF NOT DidInitBass THEN 'init the num_cards
                      FOR i = 1 TO num_cards
                          'BASS_INIT is card number (default is -1, 0 is no sound),freq, flags, win hndl,class id
                       didInitBass = Bass_Init(i,44100,0,CB.HNDL,BYVAL 0)'we initialize all so we can change sound cards
                       thisOneInit(i)=1 'since not all found may be good
                      NEXT
                  END IF
                  'check for anything being available
                   FOR i = 1 TO UBOUND(ThisOneInit)
                       IF ThisOneInit(i)= 1 THEN
                          DidInitBass = %True
                          EXIT FOR
                       ELSE
                           DidInitBass = %False
                       END IF
                   NEXT
                  IF  DidInitBass = %FALSE THEN
                      ? FORMAT$(bass_ErrorGetCode)
                      DIALOG END CB.HNDL
                  END IF
    
                  'now set the device in the dialog
                  i = UseThisSoundCard 'make sure we select the default at this point.
                  IF ThisOneInit(i) = 0 THEN 'we have a problem
                      'find what we can use
                      FOR i = 1 TO Num_Cards
                          IF ThisOneInit(i) = 1 THEN
                              bass_SetDevice i
                              EXIT FOR
                          END IF
                      NEXT
                  ELSE
                        bass_SetDevice i
                  END IF
                  i=bass_GetDevice'make sure we agree...
                  LISTBOX GET TEXT CB.HNDL, %lst_SoundCards,i TO res
                  CONTROL SET TEXT CB.HNDL, %lbl_CurrentSoundDevice,res
                  CONTROL DISABLE CB.HNDL,%cmd_Play
                  CONTROL DISABLE CB.HNDL,%cmd_Pause
                  CONTROL DISABLE CB.HNDL,%cmd_Stop
                  settimer CB.HNDL,%timer1,100,0
                  PROGRESSBAR SET RANGE CB.HNDL,%prb_Progress,0,100
                  PROGRESSBAR SET STEP CB.HNDL, %prb_Progress,1
                  CONTROL HANDLE CB.HNDL,%tb_Volume TO tbv_hndl
    
                  CONTROL SEND CB.HNDL,%tb_Volume,%tbm_Setrange,0,MAKLNG(0,100)
                  vol=bass_GetVolume  'volume returned 0-1
                  CONTROL SEND CB.HNDL,%tb_Volume,%tbm_setPos,1,100-(vol*100)'fir the scale
                  IF Num_Cards<2 THEN  'if only one card, we can't change them
                      CONTROL SHOW STATE CB.HNDL,%cmd_ChangeDevice,%SW_HIDE
                  END IF
                  setdevice = 0
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CBWPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
            CASE %WM_DESTROY
                IF StreamHandle <>0 THEN
                    BASS_STREAMFREE StreamHandle
                END IF
            CASE %WM_VSCROLL
                SELECT CASE CB.LPARAM
                    CASE tbv_hndl
                       CONTROL SEND CB.HNDL,%tb_Volume,%tbm_GetPos,0,0 TO i'vol
                       vol=100-i   'fix scal so it runs from bottom to top
                       bass_SetVolume (vol/100) 'fix scale so it fits BASS 0-1 parameter
                END SELECT
            CASE %WM_TIMER
                SELECT CASE AS LONG CB.CTL
                    CASE %timer1
                        IF streamhandle <>0 THEN
                            LOCAL t AS DWORD
                            t = bass_channelgetposition(streamHandle,%bass_pos_byte)
                            CONTROL SET TEXT CB.HNDL,%lbl_elapsedtime,Byte2Time(t,1)
                            j=bass_getDevice
                            CONTROL SET TEXT CB.HNDL, %idc_Label6,STR$(j)
                            k=BASS_CHANNELGETLENGTH(StreamHandle,%bass_pos_byte)
                            j = (t/k)*100
                            PROGRESSBAR SET POS CB.HNDL,%prb_Progress,j
                        END IF
                        IF bass_channelisActive(streamHandle) <>%BASS_Active_Stopped THEN
                            CONTROL DISABLE CB.HNDL,%cmd_GetFile
                        ELSE
                            CONTROL ENABLE CB.HNDL,%cmd_GetFile
                            CONTROL ENABLE CB.HNDL,%cmd_Play
                            CONTROL DISABLE CB.HNDL, %cmd_Pause
                            CONTROL DISABLE CB.HNDL,%cmd_Stop
                       END IF
                       CONTROL SET TEXT CB.HNDL,%lbl_CPU,FORMAT$(Bass_GetCPU,"#0%")
    
                END SELECT
            CASE %WM_COMMAND
                ' Process control notifications
                SELECT CASE AS LONG CBCTL
                    CASE %lst_SoundCards
    
                    CASE %IDC_LABEL1
    
                    CASE %cmd_GetFile
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            LOCAL filter AS STRING
                            LOCAL ofnflags AS DWORD
                            streamhandle = 0
                            ofnflags = %OFN_FILEMUSTEXIST OR %OFN_PATHMUSTEXIST
                            filter = CHR$("Streamable files (wav/aif/mp3/mp2/mp1/ogg)",0,"*.wav;" &  _
                                "*.aif;*.mp3;*.mp2;*.mp1;*.ogg",0,"All Files (*.*)",0,"*.*",0)
                            DISPLAY OPENFILE ,,,"Get a Music File","",filter,"","",ofnFlags _
                                TO Filename
                        END IF
                        IF SetDevice <> 0 THEN    'we want to change the device
                            bass_SetDevice setdevice
                            i = BASS_GetDevice
                            LISTBOX GET TEXT CB.HNDL,%lst_SoundCards,i TO res
                            CONTROL SET TEXT CB.HNDL,%lbl_CurrentSoundDevice,res
                            SetDevice = 0
                        END IF
                        StreamHandle = BASS_StreamCreateFile(%FALSE,Filename,0,0,0)
                        IF Streamhandle = 0 THEN
                            ? "Failed to open stream " & filename,%MB_ICONERROR,"Bass Demo"
                            EXIT FUNCTION
                            ELSE
                                i = PARSECOUNT(filename,"\")
                                res=filename
                                res = PARSE$(res,i)
                                DIALOG SET TEXT CB.HNDL,PARSE$(filename,"\",i)
                                CONTROL ENABLE CB.HNDL,%cmd_Play
                                LOCAL flength,timeTotalLength AS DWORD
                                LOCAL mytime AS STRING
                                flength = bass_CHANNELGETLENGTH(StreamHandle,%bass_pos_byte)
                                CONTROL SET TEXT CB.HNDL,%lbl_length,Byte2Time(flength,0)
                                'timetotallength = bass_channelBytes2Seconds(StreamHandle,flength)
                                'flength = timetotallength\60
                               ' mytime = format$(flength,"#.##")'& format$(((TimeTotalLength MOD 60)/60),"00")
                        END IF
                    CASE %cmd_ChangeDevice
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            LISTBOX  GET SELCOUNT CB.HNDL,%lst_Soundcards TO i
                            IF i <> 1 THEN
                                ? "One sound card must be selected. Select and try again", _
                                %MB_ICONERROR,"error"
                                EXIT FUNCTION
                            END IF
                            LISTBOX GET SELECT CB.HNDL,%lst_Soundcards TO i
                            CONTROL SET TEXT CB.HNDL, %idc_Label7, STR$(i)
                            setdevice = 0
                            IF i <> bass_GetDevice  THEN 'not currently in use
                                SetDevice= i
                            END IF
                        END IF
    
                    CASE %IDC_LABEL2
    
                    CASE %lbl_CurrentSoundDevice
    
                    CASE %cmd_Play
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            IF SetDevice<>0 THEN
                                IF Streamhandle <> 0 THEN
                                    'free the handle
                                    Bass_StreamFree StreamHandle
                                END IF
                                Bass_SetDevice SetDevice
                                i = Bass_GetDevice
                                LISTBOX GET TEXT CB.HNDL,%lst_Soundcards,i TO res
                                CONTROL SET TEXT CB.HNDL,%lbl_CurrentSoundDevice,res
                                StreamHandle = BASS_StreamCreateFile(%False,Filename,0,0,0)
                                SetDevice = 0
                           END IF
                           IF streamhandle <> 0 THEN
                               IF  bass_ChannelisActive(streamHandle) = %BASS_Active_Paused THEN
                                   BASS_CHANNELPLAY(StreamHandle,%False) 'resume
                               ELSE
                                   BASS_CHANNELPLAY(streamhandle,%TRue)
                               END IF
                               CONTROL ENABLE CB.HNDL,%cmd_Pause
                               CONTROL ENABLE CB.HNDL,%cmd_Stop
                               CONTROL DISABLE CB.HNDL,%cmd_play
                           END IF
                       END IF
    
                    CASE %cmd_Pause
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            BASS_CHANNELPAUSE(StreamHandle)
                            CONTROL ENABLE CB.HNDL,%cmd_Play
                            CONTROL DISABLE CB.HNDL, %cmd_Stop
                            CONTROL DISABLE CB.HNDL, %cmd_Pause
                        END IF
    
                    CASE %cmd_stop
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            BASS_CHANNELSTOP StreamHandle
                                CONTROL ENABLE CB.HNDL,%cmd_Play
                                CONTROL DISABLE CB.HNDL,%cmd_Pause
                                CONTROL DISABLE CB.HNDL,%cmd_Stop
                         END IF
    
                    CASE %cmd_exit
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            IF StreamHandle>0 THEN
                                Bass_StreamFree streamhandle
                           END IF
                            DIALOG END CB.HNDL
                        END IF
    
                END SELECT
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Sample Code **
    '------------------------------------------------------------------------------
    FUNCTION SampleListBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount _
        AS LONG) AS LONG
        LOCAL i AS LONG
    
        FOR i = 1 TO lCount
            LISTBOX ADD hDlg, lID, USING$("Test Item #", i)
        NEXT i
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Dialogs **
    '------------------------------------------------------------------------------
    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
    
    #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
        LOCAL hDlg  AS DWORD
    
        DIALOG NEW hParent, "Dialog1", 92, 153, 236, 164, TO hDlg
        CONTROL ADD LISTBOX, hDlg, %lst_SoundCards, , 10, 65, 100, 25, %WS_CHILD _
            OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %LBS_NOTIFY, _
            %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
            %WS_EX_RIGHTSCROLLBAR
        CONTROL ADD BUTTON,  hDlg, %cmd_GetFile, "Get File", 5, 5, 50, 15
        CONTROL ADD BUTTON,  hDlg, %cmd_ChangeDevice, "Change Sound Device", 10, _
            94, 100, 15
        CONTROL ADD LABEL,   hDlg, %lbl_CurrentSoundDevice, "", 15, 138, 85, 10, _
            %WS_CHILD OR %WS_VISIBLE OR %SS_CENTER, %WS_EX_LEFT OR _
            %WS_EX_LTRREADING
        CONTROL ADD BUTTON,  hDlg, %cmd_Play, "Play", 38, 22, 50, 15
        CONTROL ADD BUTTON,  hDlg, %cmd_Pause, "Pause", 88, 22, 50, 15
        CONTROL ADD BUTTON,  hDlg, %cmd_stop, "Stop", 138, 22, 50, 15
        CONTROL ADD BUTTON,  hDlg, %cmd_exit, "E&xit", 185, 145, 50, 15
        CONTROL ADD FRAME,   hDlg, %IDC_FRAME1, "Current Sound Device", 10, 128, _
            100, 23, %WS_CHILD OR %WS_VISIBLE OR %BS_CENTER OR %BS_TOP OR _
            %BS_GROUPBOX, %WS_EX_LEFT OR %WS_EX_LTRREADING
        CONTROL ADD LABEL,   hDlg, %lbl_elapsedTime, "0:00", 65, 10, 45, 10, _
            %WS_CHILD OR %WS_VISIBLE OR %SS_RIGHT, %WS_EX_LEFT OR _
            %WS_EX_LTRREADING
        CONTROL ADD LABEL,   hDlg, %lbl_length, "0:00", 130, 10, 50, 10, _
            %WS_CHILD OR %WS_VISIBLE OR %SS_RIGHT, %WS_EX_LEFT OR _
            %WS_EX_LTRREADING
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL3, "Elapsed Time", 82, 0, 44, 10
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL4, "Total Time", 144, 0, 34, 10
        CONTROL ADD "msctls_trackbar32", hDlg, %tb_Volume, "msctls_trackbar32_1", _
            175, 50, 25, 65, %WS_CHILD OR %WS_VISIBLE OR %TBS_VERT OR _
            %TBS_BOTTOM
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL5, "Master Volume", 160, 115, 49, 10
        CONTROL ADD LABEL,   hDlg, %lbl_CPU, "", 199, 9, 19, 10
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL8, "CPU Time", 188, 0, 34, 10
        CONTROL ADD FRAME,   hDlg, %IDC_FRAME5, "Sound Devices", 6, 52, 110, 103
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL9, "Change made at next Load or " + _
            "Play", 18, 110, 77, 18, %WS_CHILD OR %WS_VISIBLE OR %SS_CENTER, _
            %WS_EX_LEFT OR %WS_EX_LTRREADING
    #PBFORMS END DIALOG
         CONTROL ADD PROGRESSBAR, hdlg, %prb_Progress,"", _
                50,40,120,10,%WS_CHILD OR %WS_VISIBLE OR %PBS_SMOOTH
        SampleListBox  hDlg, %lst_SoundCards, 30
    
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
    
    #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
    #PBFORMS END CLEANUP
    
        FUNCTION = lRslt
    END FUNCTION
    '------------------------------------------------------------------------------
    Barry

    Comment

    Working...
    X