Code: Select all
; Many thanks to Tic for gdip library and Toralf for bass wrapper
; NEEDS: bass.dll download and info www.un4seen
;you will need gdip.ahk library http://www.autohotkey.com/forum/topic32238.html
;if you do not have gdip.ahk in your standard lib directory uncomment the #include line please
#include gdip.ahk ; or gdip_all.ahk
RecordCallback := RegisterCallback("RecordFunction" )
SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1
OnExit, Exit_bye
;Menu, tray, add, create playlist, createplaylist
FileEncoding,UTF-8
IfNotExist, i_player.ini
{
data=200|200|0
FileAppend,%data%,%a_scriptdir%\i_player.ini
Sleep 1000
}
BASS_Load()
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus Error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
font=tahoma
If !hFamily := Gdip_FontFamilyCreate(Font)
{
MsgBox, font Tahoma does not Exist on this system ExitApp
ExitApp
}
Fontfile=%a_scriptdir%\loisann.ttf
FontName:="lois ann"
FileRead, parameters,%a_scriptdir%\i_player.ini
StringSplit,par,parameters,|
posx:=par1
posy:=par2
Status_dock:=par3
file_playlist:=par4
moveleft_x:=a_Screenwidth-68
moveleft_y:=Floor(a_Screenheight*0.3)
Status_play:=0
Status_stop:=1
Status_Pause:=0
Status_Single:=0
Status_ontop:=0
Status_auto:=0
Status_Random:=1
Status_loop:=1
Status_over_time=0
Status_Mouseover:=0
Status_volume:=0
default_folder_playlist=%a_scriptdir%\playlist
;---------------- values for drawing circles for level indicator
x0:=38
y0:=52
d:=60
r:=d/2
;---------------- ---------------- ----------------
sFile=BackgRound_bl.png
pBitmap:=Gdip_CreateBitmapFromFile(sFile)
Gdip_GetDimensions(pBitmap, w,h )
Gui, 1: -Caption +E0x80000 +Hwndhwnd_p +Owner +AlwaysOnTop
Gui, 1:Color, Black, Black
Gui, 1: Show, NA, minimal player
hbm := CreateDIBSection(w,h)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
pGraphics := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(pGraphics, 4)
Gdip_SetInterpolationMode(pGraphics, 7)
Gdip_DrawImage(pGraphics, pBitmap, 0, 0, w,h , 0, 0, w,h )
UpdateLayeredWindow(hwnd_p, hdc, (A_ScreenWidth-w)//2, (A_ScreenHeight-h)//2, w,h )
OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x232, "WM_EXITSIZEMOVE") ;for autosaving the position of the clock
OnMessage(0x200,"OnMouseMove")
OnMessage(0x2A3,"OnMouseLeave")
OnMessage(0x4a, "Receive_WM_COPYDATA") ; 0x4a is WM_COPYDATA
VarSetCapacity(tme,16,0), NumPut(16,tme,0), NumPut(2,tme,4), NumPut(hwnd_p,tme,8)
SetTimer,Redraw,50
If Status_dock
WinMove, ahk_id %hwnd_p%,,moveleft_x,moveleft_y
Else
WinMove, ahk_id %hwnd_p%,,posx,posy
goto play_ ;added to automatically start the EQ.
Return
redraw:
;---------------- check if play has ended ----------------
If !BASS_IsPlaying(hStream) and Status_play and !Status_stop ;song has finished play next
{
delay++ ;to prevent occasionly double start of same file
If (delay=10)
Goto play_
}
;---------------- ---------------- ---------------- ------
Gosub level ;get level for level indication
Gosub time_info
Gdip_GraphicsClear(pGraphics, 0x00000000)
Gdip_DrawImage(pGraphics, pBitmap, 0, 0, w,h , 0, 0, w,h )
If Status_play
{
pPen:=Gdip_CreatePen(0xffc0c0c0,2)
Gdip_DrawArc(pGraphics, pPen, x0-r,y0-r, r*2,r*2, 8, level_l)
Gdip_DrawArc(pGraphics, pPen, x0-r,y0-r, r*2,r*2, 350,-level_r)
Gdip_DeletePen(pPen)
timeline:=67+Floor(real_pos*198)
pPen:=Gdip_CreatePen(0xaffffffff,2)
if !Status_over_time
{
If (timeline<72)
Gdip_DrawLine(pGraphics, pPen, timeline, 50, timeline, 54)
Else
Gdip_DrawLine(pGraphics, pPen, timeline, 47, timeline, 57)
}
Gdip_DeletePen(pPen)
;---------------- time display ----------------
Options = x240 y56 w40 cff808080 Right Bold r4 s8 ;draw total time
Gdip_TextToGraphics(pGraphics, display_total_time, Options, Font)
Options = x75 y60 w200 cffc0c0c0 Center Bold r4 s12 ;draw time left
if !status_over_time
Gdip_TextToGraphics(pGraphics, display_time_left, Options, Font)
;---------------- ---------------- --------------
Counter_move++
If (Counter_move>text_width)
Counter_move:=1
If (!Status_dock and !status_over_time)
Gdip_DrawImage(pGraphics, pBitmap_t, 63,23, 200, 24, Counter_move,0, 200, 24)
If Status_over_time
{
Gosub mouse_over_time
Options = x65 y20 cff7698FC Center r4 s10
rc:=Gdip_TextToGraphics(pGraphics, real_time, Options,"tahoma",,,1)
StringSplit, rc,rc,|
x_time:=x_bar_pos-rc3//2
y_time:=40-rc4-2
w_time:=rc3*2
Options = x%x_time% y%y_time% cff808080 Bold r4 s10
Gdip_TextToGraphics(pGraphics, real_time, Options,"tahoma")
pPen:=Gdip_CreatePen(0xaffffffff,1)
Gdip_DrawLine(pGraphics, pPen, x_bar_pos, 40, x_bar_pos, 51)
Gdip_DeletePen(pPen)
}
}
If (Status_volume and Status_Mouseover)
{
SoundGet,volume_
volume_:=Floor(volume_)
Options = x25 y42 w30 cff000000 Center Bold r4 s16
Gdip_TextToGraphics(pGraphics, volume_, Options, "tahoma")
}
If (!Status_dock and Status_play )
{
pPen:=Gdip_CreatePen(0xffB803D1, 1)
VarSetCapacity(buf,128*4) ;Float = 4 bytes
DllCall("BASS\BASS_ChannelGetData", UInt,hStream, Ptr,&buf,UInt,0x80000000)
if DllCall(A_ScriptDir "\bass.dll\BASS_ErrorGetCode")
msgbox % "Bass Error : " DllCall(A_ScriptDir "\bass.dll\BASS_ErrorGetCode")
cc:=0
Loop 45
{
cc += 4
if cc not between 0 and 200 ; *** as cc tends to become a weird string sometimes? ***
cc := 0
t:=88-Sqrt(NumGet(buf,4*(A_Index-1),"Float"))*80
If (t>85)
Continue
Gdip_DrawLine(pGraphics, pPen, cc+80, t, cc+80, t+2)
}
Gdip_DeletePen(pPen)
}
If Status_link
{
pPen:=Gdip_CreatePen(0xffff5500,2)
Gdip_DrawArc(pGraphics, pPen, x0-r,y0-r, r*2,r*2, 0, 360)
Gdip_DeletePen(pPen)
}
UpdateLayeredWindow(hwnd_p, hdc )
Return
mouse_over_time:
byte_total_len:=BASS_GetLen(hStream)
BytePos:=Floor(byte_total_len*(x_bar_pos-65)/200)
time_pos:=Floor(BASS_Bytes2Seconds(hStream,BytePos))
real_time:=FormatSeconds(time_pos)
Return
set_byte_pos:
byte_total_len:=BASS_GetLen(hStream)
BytePos:=Floor(byte_total_len*(x_bar_pos-65)/200)
BASS_SetPos(hStream,BytePos)
Exit
Return
time_info:
len:=BASS_GetLen(hStream)
pos:=BASS_GetPos(hStream)
real_pos:=pos/len
time_all:=Floor(BASS_Bytes2Seconds(hStream,len))
time_past:=time_all-Floor(BASS_Bytes2Seconds(hStream,pos))
display_time_left:=FormatSeconds(time_past)
display_total_time:=FormatSeconds(time_all)
Return
play_:
/*
If !array_mp3.MaxIndex()
{
Gosub get_playlist
Exit
}
If Status_play and BASS_IsPlaying(hStream) and !Status_Pause ;Click start While playing will stop
{
Gosub stop_
Exit
}
*/
DllCall("LoadLibrary", "str", A_ScriptDir "\bass.dll")
varsetcapacity(info,16,0)
device:=0
z:=BASS_RecordGetDeviceInfo(device,info)
DllCall(A_ScriptDir "\bass.dll\BASS_RecordInit", Int,device)
DllCall(A_ScriptDir "\bass.dll\BASS_ErrorGetCode")
hStream := DllCall(A_ScriptDir "\bass.dll\BASS_RecordStart", UInt, 44100, UInt, 2, UInt, 0, UInt, RecordCallback, UInt, 0) ;UInt
;DllCall(A_ScriptDir . "\bass.dll\BASS_ChannelPlay", "UInt", hStream, "Int", 1)
if DllCall(A_ScriptDir "\bass.dll\BASS_ErrorGetCode")
msgbox % DllCall(A_ScriptDir "\bass.dll\BASS_ErrorGetCode")
delay:=0
Status_play:=1
Status_stop:=0
Status_Pause:=0
/*
If BASS_IsPlaying(hStream) ;when new playlist is selected While one is playing stop it
BASS_Stop()
If !Status_Single
Gosub get_mp3
SetTimer, sendto,-500
hstream:=BASS_Play(file_to_play)
If (hstream=-1)
Exit
*/
Return
get_playlist:
If GetKeyState( "Shift" )
{
FileSelectFolder, folder_playlist
Loop ,%folder_playlist%\*.mp3
playlist .=A_LoopFileFullPath "`n"
FileAppend, %playlist%,%a_scriptdir%\playlist\playlist_%a_now%.txt
file_playlist_new=%a_scriptdir%\playlist\playlist_%a_now%.txt
Sleep 2000
}
Else
{
FileSelectFile, file_playlist_new,,%a_scriptdir%\playlist,,playerfiles (*.txt; *.mp3)
If Errorlevel or (file_playlist_new="")
Exit
}
file_playlist:=file_playlist_new ;to prevent Breaking off play when nothing is selected
Status_play:=0
Status_stop:=1
Status_Single:=0
If RegExMatch(file_playlist,"\.mp3$")
{
file_to_play:=file_playlist
Gosub play_single
Exit
}
If RegExMatch(file_playlist,"\.txt$")
{
Gosub create_playlist
Gosub play_
Exit
}
Return
get_mp3:
z++
If (z=array_mp3.MaxIndex()+1) and (z!=1)
If Status_loop
Gosub create_playlist
Else
Gosub stop_
z:=(z=0 ? 1 : z)
file_to_play:=RegExReplace(array_mp3[z],"\s+$")
Gosub bitmap_title
gosub create_editor_sendto
Return
create_editor_sendto:
StringToSend:="song_"
for k,v in array_mp3
if (k >=z)
StringToSend .=array_mp3[k] "`n"
return
sendto:
TargetScriptTitle:="minimal editor"
Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
exit
return
play_single:
/*
BASS_Stop()
delay=0 ;reset delay end of song detection
Status_play=1
Status_stop=0
Status_Pause=0
Status_Single=1
Status_Menu=0
Gosub bitmap_title
If BASS_IsPlaying(hStream)
Exit
hstream:=BASS_Play(file_to_play)
If (hstream=-1)
Exit
*/
Return
stop_:
Status_play:=0
Status_stop:=1
Status_Pause:=0
BASS_Stop()
Exit
Return
pause_:
SoundBeep
BASS_Pause()
Status_Pause:=!Status_Pause
Exit
Return
GuiContextMenu:
If (a_Guievent="RightClick")
Gosub get_playlist
Exit
Return
link:
status_link:=0
return
createplaylist:
list=
counter:=0
FileSelectFolder, myfolder
Loop, %myfolder%\*.mp3
{
list .=A_LoopFileFullPath "`n"
counter++
}
fileappend,%list%,%a_scriptdir%\playlist\playlist_default.txt
msgbox ok %counter% saved in playlist_default.txt
return
editor_run:
settimer,link,-3000
status_link:=1
file_playlist:="E:\_player\playlist\playlist_auto.txt"
Status_play:=0
Status_stop:=1
Status_Single:=0
Gosub create_playlist
Gosub play_
Exit
Return
create_playlist:
file_list=
z:=0
FileRead, data,%file_playlist%
Loop,Parse,data,`n
{
IfInString, A_LoopField,mp3
file_list .=RegExReplace(A_LoopField,"\s+$") "`n"
}
file_list:=RegExReplace(file_list,"\s+$")
If Status_Random
Sort, file_list,Random
array_mp3:=[]
Loop,Parse,file_list,`n
array_mp3.Insert(A_LoopField)
Return
level:
LevelDWord := DllCall("BASS\BASS_ChannelGetLevel", UInt,hStream)
leftlevel := LevelDWord & 0xffff
Rightlevel := (LevelDWord>>16) & 0xffff
level_l:=Floor(leftlevel*0.004)
level_r:=Floor(Rightlevel*0.004)
Return
bitmap_title:
SplitPath, file_to_play,,,,filename
text_banner:=" " filename
Options = x100 y0 c74000000 Bold r4 s16
rc_text:=Gdip_PrivateFontToGraphics(pGraphics, text_banner, Options, Fontfile,FontName,,,1)
StringSplit,rc_text,rc_text,|
text_width:=rc_text3 , text_height:=rc_text4
pBitmap_t := Gdip_CreateBitmap(text_width, text_height)
pGraphics_t := Gdip_GraphicsFromImage(pBitmap_t)
Options = x0 y0 cffc0c0c0 r4 s16
Gdip_PrivateFontToGraphics(pGraphics_t, text_banner, Options, Fontfile,FontName)
Gdip_DeleteGraphics(pGraphics_t)
Counter_move:=0
Return
FormatSeconds(NumberOfSeconds)
{
time = 19990101
time += %NumberOfSeconds%, Seconds
FormatTime, mmss, %time%, mm:ss
Hours:=NumberOfSeconds//3600
Hours:=(Hours ? Hours ":" : "")
Return Hours mmss
}
WM_LBUTTONDOWN(wParam,lParam,msg,hwnd)
{
global hwnd_p ,Status_play ,Status_Pause , Status_over_time
X := lParam & 0xFFFF
Y := lParam >> 16
if (x>270 and y<30)
exitapp
If (x>26 and x<50 and y>40 and y<64)
{
KeyWait, LButton,t0.6
If Errorlevel
{
SetTimer,stop_,-10
Exit
}
If !Status_play and !Status_Pause
{
Gosub play_
Exit
}
If Status_play and !Status_Pause
{
Gosub pause_
Exit
}
If Status_play and Status_Pause
{
Gosub pause_
Exit
}
If Status_stop and Status_Pause
{
Gosub stop_
Exit
}
}
If (Status_over_time and Status_play)
SetTimer,set_byte_pos,-10
PostMessage, 0xA1, 2
}
#if (status_mouseover=1)
wheelup::
SoundSet +2
SetTimer, volume_set,-5000
Status_volume:=1
Return
wheeldown::
SoundSet -4
SetTimer, volume_set,-5000
Status_volume:=1
Return
volume_set:
Status_volume:=0
Exit
Return
MButton::
If !Status_dock
{
WinMove, ahk_id %hwnd_p%,,moveleft_x,moveleft_y
Status_dock:=1
}
Else
{
WinMove, ahk_id %hwnd_p%,,posx,posy
Status_dock:=0
}
Gosub update_inifile
Return
#if
GuiDropFiles:
Loop, parse, A_GuiEvent, `n
FileAppend, `n%A_LoopField%,%a_scriptdir%\playlist\playlist_drop.txt
return
+PgUp::
Status_hide:= WinVisible("minimal player")
If !Status_hide
WinShow ,minimal player
Else
WinHide ,minimal player
Return
WinVisible(Title) {
DetectHiddenWindows Off ; Force to not detect Hidden windows
Return WinExist(Title) ; Return 0 for Hidden windows or the ahk_id
DetectHiddenWindows On ; Return to "Normal" state
}
OnMouseMove( wParam, lParam, Msg ) {
global tme , Status_over_time , Status_Mouseover , Status_over_time
global x_bar_pos , y_bar_pos
x_bar_pos:=lParam &0xFFFF, y_bar_pos:=lParam>>16
If (y_bar_pos>47 and y_bar_pos<56 and x_bar_pos>65 and x_bar_pos<265)
Status_over_time=1
Else
Status_over_time=0
DllCall( "TrackMouseEvent","uint",&tme )
Status_Mouseover=1
}
OnMouseLeave(){
global Status_Mouseover
Status_Mouseover=0
}
WM_EXITSIZEMOVE(wParam,lParam,msg,hwnd) ;to autosave position when moving gui
{
SetTimer,update_inifile,-2000
}
update_inifile:
If Status_dock
data=%posx%|%posy%|%Status_dock%
Else
{
WinGetPos, posx,posy,,,ahk_id %hwnd_p%
data=%posx%|%posy%|%Status_dock%
}
FileDelete,%a_scriptdir%\i_player.ini
FileAppend,%data%,%a_scriptdir%\i_player.ini
Return
exit_bye:
Gdip_DeletePen(pPen)
Gdip_DisposeImage(pBitmap)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(pGraphics)
Gdip_Shutdown(pToken)
ExitApp
Return
Receive_WM_COPYDATA(wParam, lParam)
{
StringAddress := NumGet(lParam + 2*A_PtrSize)
CopyOfData := StrGet(StringAddress)
ifinstring,CopyOfData,label
label:=regexreplace(CopyOfData,"label")
SetTimer,%label%,-1000
return true
}
Send_WM_COPYDATA( StringToSend, TargetScriptTitle){
VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0)
SizeInBytes := (StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1)
NumPut(SizeInBytes, CopyDataStruct, A_PtrSize)
NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize)
Prev_DetectHiddenWindows := A_DetectHiddenWindows
Prev_TitleMatchMode := A_TitleMatchMode
DetectHiddenWindows On
SetTitleMatchMode 2
SendMessage, 0x4a, 0, &CopyDataStruct,, %TargetScriptTitle%
DetectHiddenWindows %Prev_DetectHiddenWindows%
SetTitleMatchMode %Prev_TitleMatchMode%
return ErrorLevel
}
;endofcode
; Wrapper for bass.dll (2.4.5.0)
; www.autohotkey.com/forum/topic55454.html
; for AHK 1.0.48.05
; by toralf
; Version 0.1 (2010-02-20)
; based on BASS Library by k3ph
; NEEDS: bass.dll www.un4seen
; ################################
; ## List of public functions ##
; ################################
; BASS_Load([DLLPath, Device, PlugIns]) ;loads BASS wrapper, must be called before any other function
; BASS_Free() ;frees BASS wrapper, must be called at end of script
; BASS_IsPlaying(hStream) ;returns playback status: 0=Stopped, 1=Playing, 2=Stalled, 3=Paused
; BASS_Play([File]) ;plays a file or restarts it when paused and no file is specified
; (returns hStream on success, otherwise -1)
; BASS_Stop() ;stop playback of file (returns hStream="" on success, otherwise -1)
; BASS_Pause() ;toogles pause of playback of file (returns hStream on success, otherwise -1)
; BASS_Volume([Volume]) ;sets or gets master volume: 0 (silent) to 1 (max)
; BASS_GetDevice(hStream) ;returns device number, otherwise -1
; BASS_Seconds2Bytes(hStream,SecPos) ;converts a position from seconds to bytes,
; returns on Error negative value
; BASS_Bytes2Seconds(hStream,BytePos) ;converts a position from bytes to seconds,
; returns on Error negative value
; BASS_GetLen(hStream) ;returns playback length in bytes, returns on Error -1
; BASS_GetPos(hStream) ;returns playback position in bytes, returns on Error -1
; BASS_SetPos(hStream,BytePos) ;sets playback position in bytes, returns 1, otherwise 0
; BASS_GetLevel(hStream, ByRef LeftLevel, ByRef RightLevel) ;returns level (peak amplitude) of a stream, returns on Error -1
; BASS_GetLevel(hStream) ;returns level (peak amplitude 0-32768) of a stream, returns on Error -1 or 0 when stream is stalled
; BASS_IsSliding(hStream,Attrib) ;returns 1 if attribute is sliding, otherwise 0,
; Attributes: 1=Freq, 2=Vol, 3=Pan, 4=EAXMix
; BASS_SetSliding(hStream,Attrib,NewValue,TimeMS) ;set attribute from its current value to slide to new value in time period
; BASS_GetCPU() ;returns CPU usage of BASS
; BASS_GetVersion() ;returns version of BASS that is loaded
; BASS_ProgressMeter_Add([x, y, Width, Height, Color, Bgcolor, ControlID, GuiID]) ;adds a progress meter to a gui
; BASS_ProgressMeter_Update(hStream [, ControlID, GuiID]) ;updates a progress meter for a stream
; BASS_PluginLoad(File) ;loads a plugin of BASS
; BASS_PluginFree([hPlugin]) ;frees a plugin of BASS ("" or 0 = All Plugins)
; BASS_ErrorGetCode() ;Return the error message as code and description
;
; #################################
; ## List of private functions ##
; #################################
; BASS_InitFree([Modus, DLLPath, Device, Plugins])
; BASS_StreamFileToChannel(Modus [, File])
; BASS_ProgressMeter(GuiID, ControlID, WidthOrhStream, Height [, Color, Bgcolor, X, Y])
;set Include directory for plugins
#Include %A_ScriptDir%\
;include effects & handlers
#Include *i basstags.ahk
#Include *i bassfx.ahk
#Include *i bassvfx.ahk
#Include *i bassenc.ahk
#Include *i bassmix.ahk
#Include *i bassvis.ahk
#Include *i bassvst.ahk
#Include *i basswadsp.ahk
#Include *i bassvideo.ahk
;include format plugins
#Include *i basscd.ahk
#Include *i bassmidi.ahk
#Include *i bassflac.ahk
#Include *i basswma.ahk
#Include *i basswv.ahk
#Include *i bassaac.ahk
#Include *i bassape.ahk
#Include *i bassmpc.ahk
#Include *i bassac3.ahk
#Include *i bassalac.ahk
#Include *i bassspx.ahk
#Include *i basstta.ahk
#Include *i bassofr.ahk
BASS_Load(DLLPath="", Device=-1, PlugIns="ALL"){ ;loads BASS wrapper, must be called before any other function
Return BASS_InitFree("Load", DLLPath, Device, Plugins)
}
BASS_Free(){ ;frees BASS wrapper, must be called at end of script
Return BASS_InitFree("Free")
}
BASS_InitFree(Modus="", DLLPath="", Device="", Plugins=""){
static
DLLName = bass.dll
If (Modus = "Load"){ ;load dll to memory
If (!hBassDll := DllCall("LoadLibrary", Str,DLLPath . DLLName)){
MsgBox, 48, BASS Error!,
(Ltrim
Failed to start %DLLName%
Please ensure you have %DLLName% in the correct path %DLLPath%
)
Return 0
}
local Freq=44100,Flags=0,Win=0,Clsid=0 ;initialize output device
If !DllCall("BASS\BASS_Init", Int,Device, Int,Freq, Int,Flags, UInt,Win, UInt,Clsid){
ErrorLevel := BASS_ErrorGetCode()
MsgBox, 48, BASS Error!,
(Ltrim
Failed to initialize BASS
Error: %ErrorLevel%
)
Return 0
}
;Load plugins
PlugIns := PlugIns = "All"
? "tags,fx,vfx,enc,mix,vis,vst,wadsp,video,cd,midi,flac,wma,wv,aac,ape,mpc,ac3,alac,spx,tta,ofr"
: PlugIns
Loop, Parse, PlugIns, `,
If IsFunc("BASS_" A_LoopField "_Load")
BASS_%A_LoopField%_Load(DLLPath)
}Else If (Modus = "Free"){
If !BASS_PluginFree() ;free all Plugins
MsgBox, 48, BASS Error!, Failed to free all plugins.`nError: %ErrorLevel%
DllCall("BASS\BASS_Free") ;free all resources used by the output device
DllCall("FreeLibrary", UInt,hBassDll) ;free dll from memory
}
Return 1
}
BASS_IsPlaying(hStream){ ;returns playback status: 0=Stopped, 1=Playing, 2=Stalled, 3=Paused
;BASS_ChannelIsActive return values
; BASS_ACTIVE_STOPPED := 0 ;
; BASS_ACTIVE_PLAYING := 1 ;
; BASS_ACTIVE_STALLED := 2 ; Playback of the stream has been stalled due to a lack of sample data. The playback will automatically resume once there is sufficient data to do so.
; BASS_ACTIVE_PAUSED := 3 ;
Return DllCall("BASS\BASS_ChannelIsActive", UInt,hStream)
}
BASS_Play(File=""){ ;plays a file or restarts it when paused and no file is specified (returns hStream on success, otherwise -1)
Return BASS_StreamFileToChannel("Play",File)
}
BASS_Stop(){ ;stop playback of file (returns hStream="" on success, otherwise -1)
Return BASS_StreamFileToChannel("Stop")
}
BASS_Pause(){ ;toogles pause of playback of file (returns hStream on success, otherwise -1)
Return BASS_StreamFileToChannel("Pause")
}
BASS_StreamFileToChannel(Modus,File=""){
static
If (File AND !FileExist(File)){ ;Check if file Exists when specified
MsgBox, 48, BASS Error!,
(Ltrim
File does not exist:
%File%
)
Return -1
}
If (Modus = "Play" And File){ ;play file from beginning
If !(hStream := DllCall("BASS\BASS_StreamCreateFile", UInt,FromMem:=0
, UInt,&File, UInt64,Offset:=0, UInt64,Length:=0
, UInt,(A_IsUnicode ? 0x80000000 : 0x40000))){
ErrorLevel := BASS_ErrorGetCode()
MsgBox, 48, BASS Error!,
(Ltrim
Failed to create a stream from file:
%File%
Error: %ErrorLevel%
)
Return -1
}
If !DllCall("BASS\BASS_ChannelPlay", UInt,hStream, Int,Restart:=1){
ErrorLevel := BASS_ErrorGetCode()
MsgBox, 48, BASS Error!,
(Ltrim
Failed to play stream from file:
%File%
Error: %ErrorLevel%
)
Return -1
}
}Else If (Modus = "Play" And !File And hStream){ ;restart playback (when Paused)
If !DllCall("BASS\BASS_ChannelPlay", UInt,hStream, Int,Restart:=0){
ErrorLevel := BASS_ErrorGetCode()
MsgBox, 48, BASS Error!,
(Ltrim
Failed to restart stream from file:
%File%
Error: %ErrorLevel%
)
Return -1
}
}Else If (Modus = "Stop" And hStream){ ;stop playback
If BASS_IsPlaying(hStream)
If !DllCall("BASS\BASS_ChannelStop", UInt,hStream){
ErrorLevel := BASS_ErrorGetCode()
MsgBox, 48, BASS Error!,
(Ltrim
Failed to stop stream from file:
%File%
Error: %ErrorLevel%
)
Return -1
}
hStream = ;clear hStream
}Else If (Modus = "Pause" And hStream){ ;toogle Pause of playback
local IsPlaying
IsPlaying := BASS_IsPlaying(hStream) ;get Status
If (IsPlaying = 3) ;stream is Paused
hStream := BASS_Play() ;restart playback
Else If (IsPlaying = 1){ ;stream is playing
If !DllCall("BASS\BASS_ChannelPause", UInt,hStream){ ;Pause playback
ErrorLevel := BASS_ErrorGetCode()
MsgBox, 48, BASS Error!,
(Ltrim
Failed to pause stream from file:
%File%
Error: %ErrorLevel%
)
Return -1
}
}
}
Return hStream
}
BASS_Volume(Volume=""){ ;sets or gets master volume: 0 (silent) to 1 (max)
If Volume is Float
Return DllCall("BASS\BASS_SetVolume", Float,Volume)
Else
Return DllCall("BASS\BASS_GetVolume", Float)
}
BASS_GetDevice(hStream){ ;returns device number, otherwise -1
Return DllCall("BASS\BASS_ChannelGetDevice", UInt,hStream)
}
BASS_Seconds2Bytes(hStream,SecPos){ ;converts a position from seconds to bytes, returns on Error negative value
Return DllCall("BASS\BASS_ChannelSeconds2Bytes", UInt,hStream, Double,SecPos, UInt64)
}
BASS_Bytes2Seconds(hStream,BytePos){ ;converts a position from bytes to seconds, returns on Error negative value
Return DllCall("BASS\BASS_ChannelBytes2Seconds", UInt,hStream, UInt64,BytePos, Double)
}
BASS_GetLen(hStream){ ;returns playback length in bytes, returns on Error -1
Return DllCall("BASS\BASS_ChannelGetLength", UInt,hStream, UInt,BASS_POS_BYTE := 0, UInt64)
}
BASS_GetPos(hStream){ ;returns playback position in bytes, returns on Error -1
Return DllCall("BASS\BASS_ChannelGetPosition", UInt,hStream, UInt,BASS_POS_BYTE := 0, UInt64)
}
BASS_SetPos(hStream,BytePos){ ;sets playback position in bytes, returns 1, otherwise 0
Return DllCall("BASS\BASS_ChannelSetPosition", UInt,hStream, UInt64,Bytepos, UInt,BASS_POS_BYTE := 0)
}
BASS_GetLevel(WidthOrhStream, Byref LeftLevel,Byref RightLevel){ ;returns level (peak amplitude 0-32768) of a stream, returns on Error -1 or 0 when stream is stalled
If ((LevelDWord := DllCall("BASS\BASS_ChannelGetLevel", UInt,hStream)) = -1)
ErrorLevel := BASS_ErrorGetCode()
If (LevelDWord > 0) { ;the level of the ...
LeftLevel := LevelDWord & 0xffff ;left channel is Returned in the low word (low 16-bits)
RightLevel := (LevelDWord>>16) & 0xffff ;Right channel is Returned in the high word (high 16-bits)
}Else{
LeftLevel = 0
RightLevel = 0
}
;Return LevelDWord
Return LeftLevel
}
BASS_IsSliding(hStream,Attrib){ ;returns 1 if attribute is sliding, otherwise 0, Attributes: 1=Freq, 2=Vol, 3=Pan, 4=EAXMix
; BASS_ATTRIB_FREQ := 1 ; 100 (min) to 100000 (max), 0 = original rate
; BASS_ATTRIB_VOL := 2 ; 0 (silent) to 1 (full).
; BASS_ATTRIB_PAN := 3 ; -1 (full left) to +1 (full right), 0 = centre
; BASS_ATTRIB_EAXMIX := 4 ; 0 (full dry) to 1 (full wet), -1 = automatically calculate the mix based on the distance (the default).
If Attrib is not Number
{
If InStr(Attrib,"Freq")
Attrib = 1
Else If InStr(Attrib,"Vol")
Attrib = 2
Else If InStr(Attrib,"Pan")
Attrib = 3
Else If InStr(Attrib,"EAX")
Attrib = 4
}
If Attrib not Between 1 and 4
Return 0
Return DllCall("BASS\BASS_ChannelIsSliding", UInt,hStream, UInt,Attrib)
}
BASS_SetSliding(hStream,Attrib,NewValue,TimeMS){ ;set attribute from its current value to slide to new value in time period
; BASS_ATTRIB_FREQ := 1 ; 100 (min) to 100000 (max), 0 = original rate
; BASS_ATTRIB_VOL := 2 ; 0 (silent) to 1 (full).
; BASS_ATTRIB_PAN := 3 ; -1 (full left) to +1 (full right), 0 = centre
; BASS_ATTRIB_EAXMIX := 4 ; 0 (full dry) to 1 (full wet), -1 = automatically calculate the mix based on the distance (the default).
If Attrib is not Number
{
If InStr(Attrib,"Freq")
Attrib = 1
Else If InStr(Attrib,"Vol")
Attrib = 2
Else If InStr(Attrib,"Pan")
Attrib = 3
Else If InStr(Attrib,"EAX")
Attrib = 4
}
If Attrib not Between 1 and 4
Return 0
If NewValue is not Float
Return 0
If TimeMS is not Number
Return 0
Return DllCall("BASS\BASS_ChannelSlideAttribute", UInt,hStream, UInt,Attrib, Float,NewValue, UInt,TimeMS)
}
BASS_GetCPU(){ ;returns CPU usage of BASS
Return DllCall("BASS\BASS_GetCPU", Float)
}
BASS_GetVersion(){ ;returns version of BASS that is loaded
Return DllCall("BASS\BASS_GetVersion")
}
; BASS_ProgressMeter
; based on idea by zed gecko (StreamGUI, which comes with bass lib)
; adds a progress meter to a gui
BASS_ProgressMeter_Add(x = "", y = "", Width=300, Height=100, Color="green", Bgcolor="gray", ControlID="", GuiID=1){
Return BASS_ProgressMeter(GuiID, ControlID, Width, Height//2, Color, BgColor, X, Y)
}
; updates a progress meter for a stream
BASS_ProgressMeter_Update(hStream, ControlID="", GuiID=1){
Return BASS_ProgressMeter(GuiID, ControlID, hStream, "???????????")
}
BASS_ProgressMeter(GuiID, ControlID, WidthOrhStream, Height, Color="", Bgcolor="", X="", Y=""){
global
local SegmentSpace,SegmentSize,TransferVar,PrevSegment,NOS,LeftLevel,RightLevel
If (Height = "???????????"){
SetControlDelay, -1
Loop, % NOS := NumberOfProgressMeterSegments%ControlID% {
PrevSegment := A_Index - 1
GuiControlGet, TransferVar, %GuiID%:, ProgressMeterL%ControlID%%A_Index%
GuiControl,%GuiID%:, ProgressMeterL%ControlID%%PrevSegment%, %TransferVar%
GuiControlGet, TransferVar, %GuiID%:, ProgressMeterR%ControlID%%A_Index%
GuiControl,%GuiID%:, ProgressMeterR%ControlID%%PrevSegment%, %TransferVar%
}
BASS_GetLevel(WidthOrhStream, LeftLevel, RightLevel)
GuiControl,%GuiID%:, ProgressMeterL%ControlID%%NOS%, %LeftLevel%
GuiControl,%GuiID%:, ProgressMeterR%ControlID%%NOS%, % 32768 - RightLevel
}Else{
SegmentSpace = 2 ;Visible size of one segment in Pixel
SegmentSize := SegmentSpace + 1
NumberOfProgressMeterSegments%ControlID% := (WidthOrhStream // SegmentSize) - 1
Gui, %GuiID%:Add, Progress, Range0-32768 vProgressMeterL%ControlID%0 w%SegmentSize% h%Height% %X% %Y% c%Color% BackgRound%BgColor% Vertical,
Gui, %GuiID%:Add, Progress, Range0-32768 vProgressMeterR%ControlID%0 w%SegmentSize% h%Height% y+0 c%BgColor% BackgRound%Color% Vertical, 32769
Loop, % NumberOfProgressMeterSegments%ControlID%{
Gui, %GuiID%:Add, Progress, Range0-32768 vProgressMeterL%ControlID%%A_Index% w%SegmentSize% h%Height% xp+%SegmentSpace% yp-%Height% c%Color% BackgRound%BgColor% Vertical,
Gui, %GuiID%:Add, Progress, Range0-32768 vProgressMeterR%ControlID%%A_Index% w%SegmentSize% h%Height% y+0 c%BgColor% BackgRound%Color% Vertical, 32769
}
}
Return 1
}
BASS_PluginLoad(File){ ;loads a plugin of BASS
;With any combination of these flags
; BASS_UNICODE = 0x80000000 ;file is unicode
Flags = 0
If !hPlugin := DllCall("BASS\BASS_PluginLoad", UInt,&File, UInt,Flags)
ErrorLevel := BASS_ErrorGetCode()
Return hPlugin
}
BASS_PluginFree(hPlugin=0){ ;frees a plugin of BASS (0 = All Plugins)
If !(Ret := DllCall("BASS\BASS_PluginFree", UInt,hPlugin))
ErrorLevel := BASS_ErrorGetCode()
Return Ret
}
BASS_ErrorGetCode(){ ;Return the error message as code and description
static ErrorCodes :=
(LTrim
";error codes returned by BASS_ErrorGetCode
0 BASS_OK all is OK
1 BASS_ERROR_MEM memory error
2 BASS_ERROR_FILEOPEN can't open the file
3 BASS_ERROR_DRIVER can't find a free sound driver
4 BASS_ERROR_BUFLOST the sample buffer was lost
5 BASS_ERROR_HANDLE invalid handle
6 BASS_ERROR_FORMAT unsupported sample format
7 BASS_ERROR_POSITION invalid position
8 BASS_ERROR_INIT BASS_Init has not been successfully called
9 BASS_ERROR_START BASS_Start has not been successfully called
14 BASS_ERROR_ALREADY already initialized/paused/whatever
18 BASS_ERROR_NOCHAN can't get a free channel
19 BASS_ERROR_ILLTYPE an illegal type was specified
20 BASS_ERROR_ILLPARAM an illegal parameter was specified
21 BASS_ERROR_NO3D no 3D support
22 BASS_ERROR_NOEAX no EAX support
23 BASS_ERROR_DEVICE illegal device number
24 BASS_ERROR_NOPLAY not playing
25 BASS_ERROR_FREQ illegal sample rate
27 BASS_ERROR_NOTFILE the stream is not a file stream
29 BASS_ERROR_NOHW no hardware voices available
31 BASS_ERROR_EMPTY the MOD music has no sequence data
32 BASS_ERROR_NONET no internet connection could be opened
33 BASS_ERROR_CREATE couldn't create the file
34 BASS_ERROR_NOFX effects are not enabled
37 BASS_ERROR_NOTAVAIL requested data is not available
38 BASS_ERROR_DECODE the channel is a decoding channel
39 BASS_ERROR_DX a sufficient DirectX version is not installed
40 BASS_ERROR_TIMEOUT connection timedout
41 BASS_ERROR_FILEFORM unsupported file format
42 BASS_ERROR_SPEAKER unavailable speaker
43 BASS_ERROR_VERSION invalid BASS version (used by add-ons)
44 BASS_ERROR_CODEC codec is not available/supported
45 BASS_ERROR_ENDED the channel/file has ended
-1 BASS_ERROR_UNKNOWN some other mystery problem"
)
Error := DllCall("BASS\BASS_ErrorGetCode", Int)
Needle := "m`n)^" Error " +\w*\s*(?P<Value>.*)$"
RegExMatch(ErrorCodes, Needle, Return)
Return Error " = " ReturnValue
}
Gdip_PrivateFontToGraphics(pGraphics, Text, Options, Fontfile,FontName, Width="", Height="", Measure=0)
{
IWidth := Width, IHeight:= Height
RegExMatch(Options, "i)X([\-\d\.]+)(p*)", xpos)
RegExMatch(Options, "i)Y([\-\d\.]+)(p*)", ypos)
RegExMatch(Options, "i)W([\-\d\.]+)(p*)", Width)
RegExMatch(Options, "i)H([\-\d\.]+)(p*)", Height)
RegExMatch(Options, "i)C(?!(entre|Enter))([a-f\d]+)", Colour)
RegExMatch(Options, "i)Top|Up|Bottom|Down|vCentre|vCenter", vPos)
RegExMatch(Options, "i)NoWrap", NoWrap)
RegExMatch(Options, "i)R(\d)", Rendering)
RegExMatch(Options, "i)S(\d+)(p*)", Size)
If !Gdip_DeleteBrush(Gdip_CloneBrush(Colour2))
PassBrush := 1, pBrush := Colour2
If !(IWidth && IHeight) && (xpos2 || ypos2 || Width2 || Height2 || Size2)
Return -1
Style := 0, Styles := "Regular|Bold|italic|Bolditalic|underline|strikeout"
Loop, Parse, Styles, |
{
If RegExMatch(Options, "\b" A_loopField)
Style |= (A_LoopField != "strikeOut") ? (A_Index-1) : 8
}
Align := 0, Alignments := "Near|Left|Centre|Center|Far|Right"
Loop, Parse, Alignments, |
{
If RegExMatch(Options, "\b" A_loopField)
Align |= A_Index//2.1 ; 0|0|1|1|2|2
}
xpos := (xpos1 != "") ? xpos2 ? IWidth*(xpos1/100) : xpos1 : 0
ypos := (ypos1 != "") ? ypos2 ? IHeight*(ypos1/100) : ypos1 : 0
Width := Width1 ? Width2 ? IWidth*(Width1/100) : Width1 : IWidth
Height := Height1 ? Height2 ? IHeight*(Height1/100) : Height1 : IHeight
If !PassBrush
Colour := "0x" (Colour2 ? Colour2 : "ff000000")
Rendering := ((Rendering1 >= 0) && (Rendering1 <= 5)) ? Rendering1 : 4
Size := (Size1 > 0) ? Size2 ? IHeight*(Size1/100) : Size1 : 12
If !A_IsUnicode
{
nSize:=DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &Fontfile, "int", -1, "Uint", 0, "int", 0)
VarSetCapacity(wFontfile, nSize * 2 + 1)
DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &Fontfile, "int", -1, "Uint", &wFontfile, "int", nSize + 1)
nSize:=DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &FontName, "int", -1, "Uint", 0, "int", 0)
VarSetCapacity(wFontName, nSize * 2 + 1)
DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &FontName, "int", -1, "Uint", &wFontName, "int", nSize + 1)
DllCall("gdiplus\GdipNewPrivateFontCollection", "uint*", hcollection)
DllCall("gdiplus\GdipPrivateAddFontFile", "uint", hcollection, "uint", &wFontfile)
DllCall("gdiplus\GdipCreateFontFamilyFromName", "uint", &wFontName, "uint", hcollection, "uint*", hFamily)
}
Else
{
DllCall("gdiplus\GdipNewPrivateFontCollection", "uint*", hcollection)
DllCall("gdiplus\GdipPrivateAddFontFile", "uint", hcollection, "uint", &FontFile)
DllCall("gdiplus\GdipCreateFontFamilyFromName", "uint", &FontName, "uint", hcollection, "uint*", hFamily)
}
hFont := Gdip_FontCreate(hFamily, Size, Style)
FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
hFormat := Gdip_StringFormatCreate(FormatStyle)
pBrush := PassBrush ? pBrush : Gdip_BrushCreateSolid(Colour)
If !(hFamily && hFont && hFormat && pBrush && pGraphics)
Return !pGraphics ? -2 : !hFamily ? -3 : !hFont ? -4 : !hFormat ? -5 : !pBrush ? -6 : 0
CreateRectF(RC, xpos, ypos, Width, Height)
Gdip_SetStringFormatAlign(hFormat, Align)
Gdip_SetTextRenderingHint(pGraphics, Rendering)
ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)
If vPos
{
StringSplit, ReturnRC, ReturnRC, |
If (vPos = "vCentre") || (vPos = "vCenter")
ypos += (Height-ReturnRC4)//2
Else If (vPos = "Top") || (vPos = "Up")
ypos := 0
Else If (vPos = "Bottom") || (vPos = "Down")
ypos := Height-ReturnRC4
CreateRectF(RC, xpos, ypos, Width, ReturnRC4)
ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)
}
If !Measure
E := Gdip_DrawString(pGraphics, Text, hFont, hFormat, pBrush, RC)
If !PassBrush
Gdip_DeleteBrush(pBrush)
Gdip_DeleteStringFormat(hFormat)
Gdip_DeleteFont(hFont)
Gdip_DeleteFontFamily(hFamily)
DllCall("gdiplus\GdipDeletePrivateFontCollection", "uint*", hcollection)
Return E ? E : ReturnRC
}
BASS_GetDeviceInfo(device,ByRef info){
global
Return DllCall("BASS\BASS_GetDeviceInfo", UInt, device, UInt, &info)
}
BASS_RecordGetDeviceInfo(device,ByRef info){
global
Return DllCall("BASS\BASS_RecordGetDeviceInfo", UInt, device, UInt, &info)
}
RecordFunction(handle, buffer, length, user)
{
/*
global file , t
global datasize
if t
{
;file.rawwrite(buffer+0,length)
datasize += length
}
*/
return true
}