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:
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 '------------------------------------------------------------------------------
Comment