Radio Stations v0.61 build 2023-06-17 beta [Windows only]

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Radio Stations v0.61 build 2023-06-17 beta [Windows only]

Post by UEZ »

If you are a C64 / Amiga music enthusiast then this might be something for you. It is a simple player using Bass.dll to connect to remix.kwed.org / amigaremix.com and play a random song from that site.

Image

Image


Readme.txt -> see next post

Examples:
"Radio Station remix.kwed.org.exe" /cfg 7 /cbg 1 /order 1 /glass
"Radio Station remix.kwed.org.exe" /top50 /number 50 /top50dir -1


For Windows 7 users: TLS 1.1 and TLS 1.2 must be enabled to run this program properly (WinHTTP) (see Update to enable TLS 1.1 and TLS 1.2 as default secure protocols in WinHTTP in Windows)


Radio Station remix.kwed.org.bas

Code: Select all

'Version 0.60 build 2021-07-19 beta
'Coded by UEZ
'Information: 100 downloads per IP per hour allowed!

#Ifdef __Fb_64bit__
	#Inclib "gdiplus"
	#Include Once "win\gdiplus-c.bi"
	Const GCL_HICON = -14, GCL_HICONSM = -34
#Else
	#Include Once "win\gdiplus.bi"
	Using Gdiplus
#Endif
#Include "String.bi"
#Include "fbthread.bi"
#Include "win\tlhelp32.bi"
#Include "win\commctrl.bi"
#Include "win\shellapi.bi"
#Include "Bass2.bi"
#Include "WinHTTP.bi"

Declare Function RtlGetVersion Lib "NtDll.dll" Alias "RtlGetVersion" (OsVersionInformation As RTL_OSVERSIONINFOW) As Long

Dim Shared As RTL_OSVERSIONINFOW OS
OS.dwOSVersionInfoSize = Sizeof(RTL_OSVERSIONINFOW)
RtlGetVersion(OS)

If OS.dwBuildNumber < 7600 Then
	? "This operating system is NOT supported! Win7+ is required!"
	Sleep(2500)
	End
Endif

Dim As String sCoder = "Coded by UEZ v0.60 build 2021-07-19 beta "
Dim Shared As String sRadioSite
sRadioSite = "remix.kwed.org"

#Define DirExists(sPath)	(GetFileAttributes(sPath) = FILE_ATTRIBUTE_DIRECTORY)
#Define _Round(x) 			(Int(x + 0.5))


Dim Shared gdipToken As ULONG_PTR
Dim Shared GDIp As GdiplusStartupInput 
Dim Shared As QWORD iBytesLen, iEnd, iFilePosStart, iFilePos, iFileSize, iSongs
Dim Shared As String sRedirectURL, SOUNDFILE, sPlaying, sRating, sOriginal, sReleaseDate, sAllTimeRank
Dim Shared As Ubyte iCounter = 0, iFGCol = 15, iBGCol = 5, bShowLevel = 1, bAutoSwitchDevice = 1, bOneTime = 0, bEndless = 0, bExit = 0, bLimitReached = False, bTop50 = False, iTop50Items = 50
Dim Shared As Double length
Dim Shared As Single vol = 0.15, iW, iH, fBitrate, fDPI_ratio
Dim Shared As Ubyte iOrder = 0, iDLFinished, iTop50Pos = 1
Dim Shared As Byte iTop50PosDir = 1
Dim Shared As Short iNumber = -1, iPosCursor, iSongsreal = 0
Dim Shared As Integer iConsoleW, iConsoleH, iCsW = 100, iCsH = 12, iFsW = 0, iFsH = 14
Dim Shared As Any Ptr hSession, hConnect, hImage, hConsole, hSysMenu
Dim Shared As HBITMAP hBitmap
Dim Shared As HWND hGUI_logo, hPic_logo
Dim Shared As Ulong iPicBGColor
Dim Shared As HHOOK hMouseHook
Dim Shared As Handle hStdOut, hStdIn
Dim Shared As Long iCtrlPosX, iCtrlPosY, aTop50Titles(100)
Dim Shared As CONSOLE_FONT_INFOEX fsc
Dim Shared As CONSOLE_SCREEN_BUFFER_INFOEX buffinfoex, savebuffinfoex



Const WM_DPICHANGED = &h02E0, WM_DPICHANGED_BEFOREPARENT = &h02E2, WM_DPICHANGED_AFTERPARENT = &h02E3, ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4, id_Exit = 5200, id_About = 5201
Randomize

Function SearchInCMDArgument(sSearchFor As String) As Ubyte
	Dim As Ubyte i = 1
	Do
		If Lcase(Command(i)) = Lcase(sSearchFor) Then Return i
		i += 1
	Loop While Len(Command(i)) > 0
	Return 0
End Function

Function GetFontInfo() As _CONSOLE_FONT_INFOEX
	Dim As _CONSOLE_FONT_INFOEX fi
	fi.cbSize = Sizeof(CONSOLE_FONT_INFOEX)
	GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), False, @fi)
	Return fi
End Function

Sub SetFontSize(w As Long, h As Long, ftype As String = "Consolas", nfont As DWORD = 0, nFontWeight As Uinteger = FW_BOLD, nFontFamily As Uinteger = FF_DONTCARE)
    Dim As _CONSOLE_FONT_INFOEX  x
    With x
        .cbsize = Sizeof(_CONSOLE_FONT_INFOEX)
        .nfont = nFont
        .dwfontsize = Type(w, h)
        .fontfamily = nFontFamily
        .fontweight = nFontWeight
        .facename = ftype
    End With
    SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), 1, @x)
End Sub

Sub GetConsoleSize(Byref w As Integer, Byref h As Integer)
	Dim As CONSOLE_SCREEN_BUFFER_INFO info
	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), @info)
	w = info.srWindow.Right - info.srWindow.Left
	h = info.srWindow.Bottom - info.srWindow.Top
End Sub

Sub SetConsoleSize(cols As Long, lines As Long)
    Shell "MODE CON: COLS=" + Str(cols) + "LINES=" + Str(lines)
End Sub

Sub ClrConsole(iSleep As Ushort = 100)
	Shell "Cls"
	Sleep(iSleep)
End Sub

Sub ClrConsole2(hConsole As HANDLE, x1 As Ushort = 0, y1 As Ushort = 0, x2 As Ushort = 0, y2 As Ushort = 0, cPosX As Ushort = 0, cPosY As Ushort = 0, ClrChar As Ubyte = 32) 	 	'https://docs.microsoft.com/en-us/windows/console/clearing-the-screen example 2
	Dim As CONSOLE_SCREEN_BUFFER_INFO csbi
	Dim As SMALL_RECT scrollRect
	Dim As COORD scrollTarget
	Dim As CHAR_INFO fill
	GetConsoleScreenBufferInfo(hConsole, @csbi)
	scrollRect.Left = x1
    scrollRect.Top = y1
    scrollRect.Right = Iif(x2 = 0, csbi.dwSize.X, x2 - 1)
    scrollRect.Bottom = Iif(y2 = 0, csbi.dwSize.Y, y2 -1)
	scrollTarget.X = 0
	scrollTarget.Y = (0 - csbi.dwSize.Y)
	fill.Char.UnicodeChar = ClrChar 'Asc(" ")
	fill.Attributes = csbi.wAttributes
	ScrollConsoleScreenBuffer(hConsole, @scrollRect, NULL, scrollTarget, @fill)
    csbi.dwCursorPosition.X = cPosX
    csbi.dwCursorPosition.Y = cPosY
	SetConsoleCursorPosition(hConsole, csbi.dwCursorPosition)
End Sub

Function Replace (Byval buffer As String, Byval oldstring As String, Byval newstring As String) As String
    If Instr(buffer, oldstring) = 0 Then Return buffer   
    buffer = Chr(32) + buffer + Chr(32)
    
    Dim rep As Ubyte
    Dim SS As Integer
    Dim SE As Integer
    
    Do
        rep = 0
        If Instr(buffer, oldstring) > 0 Then
            rep = 1
            
            SS = Instr(buffer, oldstring) - 1
            SE = SS + Len(oldstring) + 1
            
            SS = Iif (SS < 1, 1, SS)
            SE = Iif (SE > Len(buffer), Len(buffer), SE)
            
            buffer = Mid(buffer, 1, SS) + newstring + Mid(buffer, SE, Len(buffer) - (SE - 1))
        End If

    Loop While rep = 1
    
    Return Trim(buffer)
End Function

Function _WinAPI_GetProcessName(iPid As DWORD) As String
	Dim As HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, iPid)
	If hSnapshot = 0 Then Return ""
	Dim As PROCESSENTRY32W tPROCESSENTRY32W
	tPROCESSENTRY32W.dwSize = Sizeof(PROCESSENTRY32W)
	Process32FirstW(hSnapshot, @tPROCESSENTRY32W)
	While True
		If tPROCESSENTRY32W.th32ProcessID = iPid Then Exit While
		If Process32NextW(hSnapshot,  @tPROCESSENTRY32W) = 0 Then Exit While
	Wend
	CloseHandle(hSnapshot)
	Return tPROCESSENTRY32W.szExeFile
End Function

Function _WinAPI_GetParentProcess() As Integer
	Dim As DWORD pid = GetCurrentProcessId(), pid_parent = 0
	Dim As HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
	Dim As PROCESSENTRY32 tPROCESSENTRY32
	tPROCESSENTRY32.dwSize = Sizeof(tPROCESSENTRY32)
	Process32First(hSnapshot, @tPROCESSENTRY32)
	While TRUE
		If tPROCESSENTRY32.th32ProcessID = pid Then
			pid_parent = tPROCESSENTRY32.th32ParentProcessID
			Exit While
		End If
		Process32Next(hSnapshot, @tPROCESSENTRY32)
	Wend
	CloseHandle(hSnapshot)
	Return pid_parent
End Function

Function _WinAPI_DwmIsCompositionEnabled() As Bool 'Windows Vista+ / Server 2008+ required
	Dim As Any Ptr pLib = Dylibload("Dwmapi.dll")
	If pLib = NULL Then Exit Function
	Dim pDwmIsCompositionEnabled As Function (Byval pfEnabled As Any Ptr) As Integer
	Dim As Bool pfEnabled = False
	pDwmIsCompositionEnabled = Dylibsymbol(pLib, "DwmIsCompositionEnabled")
	If pDwmIsCompositionEnabled Then pDwmIsCompositionEnabled(@pfEnabled)
	Dylibfree(pLib)
	Return pfEnabled
End Function

Function _WinAPI_EnableBlurBehindWindow(hWND As HWND, bSet As Bool = True) As Integer 'Windows Vista+ / Server 2008+ required
	Dim As Any Ptr pLib = Dylibload("Dwmapi.dll")
	If pLib = NULL Then Exit Function
	Type tagDWM_BLURBEHIND
		Dim As DWORD dwFlags
		Dim As BOOL fEnable
		Dim As HRGN hRgnBlur
		Dim As BOOL fTransitionOnMaximized
	End Type
	Dim pEnableBlurBehind As Function (Byval hWND As HWND, Byval pDWM_BLURBEHIND As Any Ptr) As Integer
	Const DWM_BB_ENABLE = 1, DWM_BB_BLURREGION = 2, DWM_BB_TRANSITIONONMAXIMIZED = 4
	Dim As tagDWM_BLURBEHIND tDWM_BLURBEHIND
	tDWM_BLURBEHIND.dwFlags = DWM_BB_ENABLE Or DWM_BB_BLURREGION
	tDWM_BLURBEHIND.fEnable = bSet
	tDWM_BLURBEHIND.hRgnBlur = Null
	tDWM_BLURBEHIND.fTransitionOnMaximized = bSet
	pEnableBlurBehind = Dylibsymbol(pLib, "DwmEnableBlurBehindWindow")
	If pEnableBlurBehind Then Function = pEnableBlurBehind(hWND, @tDWM_BLURBEHIND)
	Dylibfree(pLib)
End Function

Type tagAccentPolicy
	As Long AccentState, AccentFlags, AnimationId
	As Ulong GradientColor
End Type

Type tagAttrData
	As Dword Attribute
	As PVOID pDataBuffer
	As SIZE_T Size
End Type

Enum AccentState
	ACCENT_DISABLED = 0
	ACCENT_ENABLE_GRADIENT = 1
	ACCENT_ENABLE_TRANSPARENTGRADIENT = 2
	ACCENT_ENABLE_BLURBEHIND = 3
	ACCENT_ENABLE_ACRYLICBLURBEHIND = 4
	ACCENT_ENABLE_HOSTBACKDROP = 5
	ACCENT_INVALID_STATE = 6
End Enum

Enum WINDOWCOMPOSITIONATTRIB
	WCA_UNDEFINED = 0
	WCA_NCRENDERING_ENABLED = 1
	WCA_NCRENDERING_POLICY = 2
	WCA_TRANSITIONS_FORCEDISABLED = 3
	WCA_ALLOW_NCPAINT = 4
	WCA_CAPTION_BUTTON_BOUNDS = 5
	WCA_NONCLIENT_RTL_LAYOUT = 6
	WCA_FORCE_ICONIC_REPRESENTATION = 7
	WCA_EXTENDED_FRAME_BOUNDS = 8
	WCA_HAS_ICONIC_BITMAP = 9
	WCA_THEME_ATTRIBUTES = 10
	WCA_NCRENDERING_EXILED = 11
	WCA_NCADORNMENTINFO = 12
	WCA_EXCLUDED_FROM_LIVEPREVIEW = 13
	WCA_VIDEO_OVERLAY_ACTIVE = 14
	WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15
	WCA_DISALLOW_PEEK = 16
	WCA_CLOAK = 17
	WCA_CLOAKED = 18
	WCA_ACCENT_POLICY = 19
	WCA_FREEZE_REPRESENTATION = 20
	WCA_EVER_UNCLOAKED = 21
	WCA_VISUAL_OWNER = 22
	WCA_HOLOGRAPHIC = 23
	WCA_EXCLUDED_FROM_DDA = 24
	WCA_PASSIVEUPDATEMODE = 25
	WCA_USEDARKMODECOLORS = 26
	WCA_LAST = 27
End Enum

Function _WinAPI_SetWindowCompositionAttribute(hWnd As HWND, bEnable As Bool = True, iAccentState As Long = ACCENT_ENABLE_BLURBEHIND, iAttribute As Long = WCA_ACCENT_POLICY, iAccentFlags As Long = 0, iGradientColor As Ulong = 0) As Bool
	Dim As Any Ptr hLib = Dylibload("User32.dll")
	If hLib = 0 Then Return False
	Dim pSetWindowCompositionAttribute As Function (Byval hWnd As HWND, Byval pAttrData As PVOID) As Bool
	pSetWindowCompositionAttribute = Dylibsymbol(hLib, "SetWindowCompositionAttribute")
	Dim As Bool iReturn
	Dim As tagAccentPolicy tAccentPolicy
	Dim As tagAttrData tAttrData
	tAccentPolicy.AccentState = Iif(bEnable, iAccentState, ACCENT_DISABLED)
	tAccentPolicy.AccentFlags = iAccentFlags 'DRAWALLBORDERS
	tAccentPolicy.GradientColor = iGradientColor
	tAttrData.Attribute = iAttribute
	tAttrData.pDataBuffer = @tAccentPolicy
	tAttrData.Size = Sizeof(tAccentPolicy)
	iReturn = pSetWindowCompositionAttribute(hWnd, @tAttrData)
	Dylibfree(hLib)
	Return iReturn
End Function

Function _GDIPlus_Startup() As Bool
	GDIp.GdiplusVersion = 1
	If GdiplusStartup(@gdipToken, @GDIp, NULL) <> 0 Then
		Return False
	Endif
	Return True
End Function

Sub _GDIPlus_Shutdown()
	GdiplusShutdown(gdipToken)
End Sub

Function _GDIPlus_BitmapCreateFromMemory3(aBinImage As Ubyte Ptr, iLen As Ulong, bBitmap_GDI As Bool = False, iCol_GDI As Ulong = &hFF000000) As Any Ptr
	Dim As HGLOBAL hGlobal
	Dim As LPSTREAM hStream
	Dim As Any Ptr hImage_Stream
	Dim As Any Ptr hMemory = GlobalAlloc(GMEM_MOVEABLE, iLen)
	Dim As Any Ptr lpMemory = GlobalLock(hMemory)
	RtlCopyMemory(lpMemory, @aBinImage[0], iLen)
	GlobalUnlock(hMemory)
	CreateStreamOnHGlobal(hMemory, False, @hStream)
	GdipCreateBitmapFromStream(hStream, @hImage_Stream)
	IUnknown_Release(hStream)
	GlobalFree(hGlobal)
	
	If bBitmap_GDI = True Then
		Dim hImage_GDI As Any Ptr
		GdipCreateHBITMAPFromBitmap(hImage_Stream, @hImage_GDI, iCol_GDI)
		GdipDisposeImage(hImage_Stream)
		Return hImage_GDI
	Endif

	Return hImage_Stream
End Function

Function _WinAPI_SetWindowTitleIcon(hImage As Any Ptr, hHWND As Any Ptr, iBGColor As ULong = 0) As Boolean
	Dim As any Ptr hImageBg, hGfx, hIcon
	If iBGColor > 0 Then
		GdipCreateBitmapFromScan0(16, 16, 0, PixelFormat32bppARGB, 0, @hImageBg)
		GdipGetImageGraphicsContext(hImageBg, @hGfx)
		GdipSetInterpolationMode(hGfx, InterpolationModeHighQualityBicubic)
		GdipGraphicsClear(hGfx, iBGColor)
		GdipDrawImageRect(hGfx, hImage, 0, 0, 16, 16)
		GdipCreateHICONFromBitmap(hImageBg, @hIcon)
		GdipDeleteGraphics(hGfx)
		GdipDisposeImage(hImageBg)
	Else
		GdipCreateHICONFromBitmap(hImage, @hIcon)
	EndIf
	SendMessageW(hHWND, WM_SETICON, Iif(OS.dwBuildNumber < 9200, 1, 0), Cast(LParam, hIcon))
	Return 1
End Function


Function _WinAPI_FileExtractIcon(sFilename As String, iFlag As Uinteger = SHGFI_SMALLICON) As HICON
	Dim As SHFILEINFO tSHFILEINFO
	If SHGetFileInfo(sFilename, FILE_ATTRIBUTE_READONLY, @tSHFILEINFO, Sizeof(SHFILEINFO), iFlag) Then Return tSHFILEINFO.hIcon
	Return 0
End Function

Function _WinAPI_GetDpiForWindow(hWND As HWND) As Integer 'Windows 10, version 1607 [desktop apps only]
	Dim As Any Ptr pLib = Dylibload("User32.dll")
	If pLib = NULL Then Exit Function
	Dim pGetDpiForWindow As Function (Byval hWND As HWND) As Integer
	pGetDpiForWindow = Dylibsymbol(pLib, "GetDpiForWindow")
	If pGetDpiForWindow Then Function = pGetDpiForWindow(hWND)
	Dylibfree(pLib)
End Function

Function WndProc(hWnd As HWND,uMsg As UINT,wParam As WPARAM,lParam As LPARAM) As Integer
	Select Case uMsg
		Case WM_CLOSE
			PostQuitMessage(0)	
		Case WM_PAINT, WM_NCPAINT
			SendMessage(hPic_logo, STM_SETIMAGE, IMAGE_BITMAP, Cast(LPARAM, hBitmap))
			Return 1
		Case WM_ERASEBKGND
			SendMessage(hPic_logo, STM_SETIMAGE, IMAGE_BITMAP, Cast(LPARAM, hBitmap))
			Return 0
		Case WM_DPICHANGED_AFTERPARENT 'WM_DPICHANGED, WM_DPICHANGED_BEFOREPARENT
			Dim As RECT tRECT
			Dim As Long cw, ch
			GetClientRect(hConsole, @tRECT)
			cw = (tRECT.right - tRECT.left)
			ch = (tRECT.bottom - tRECT.top)
			SetWindowPos(hGUI_logo, HWND_TOP, _
						 (cw - iW * 1.20), (ch - iH * 1.20), _
						 iW, iH, _
						 SWP_NOACTIVATE Or SWP_SHOWWINDOW)
	End Select
	Return DefWindowProc(hWnd, uMsg, wParam, lParam)
End Function

Sub ChildGUIThread(param As Any Ptr)
	Dim szAppName As ZString * 10 => "FB GUI"
	Dim As String sTitle = "Radio Station by UEZ"
	Dim wc As WNDCLASSEX
	Dim msg As MSG
	With wc
		.cbSize		   = SizeOf(WNDCLASSEX)
		.style         = CS_HREDRAW Or CS_VREDRAW
		.lpfnWndProc   = @WndProc
		.cbClsExtra    = NULL
		.cbWndExtra    = NULL
		.hInstance     = GetModuleHandle(NULL)
		.hIcon         = LoadIcon(NULL, IDI_APPLICATION)
		.hCursor       = LoadCursor(NULL, IDC_ARROW)
		.hbrBackground = GetStockObject(COLOR_WINDOW)
		.lpszMenuName  = NULL
		.lpszClassName = Cast(LPCSTR, @szAppName)
	End With
	 
	RegisterClassEx(@wc)
	
	Dim As Long iDpi = _WinAPI_GetDpiForWindow(hConsole)
	iDpi = IIf(iDpi = 0, 96, iDpi)
	
	Dim As RECT tRECT
	Dim As Long cw, ch
	GetClientRect(hConsole, @tRECT)
	cw = (tRECT.right - tRECT.left) * iDpi / 96
	ch = (tRECT.bottom - tRECT.top) * iDpi / 96
	If cw = 0 Or ch = 0 Then
		Dim As CONSOLE_FONT_INFOEX fsc
		fsc.cbSize = Sizeof(CONSOLE_FONT_INFOEX)
		GetCurrentConsoleFontEx(hStdOut, 0, @fsc)
		cw = fsc.dwFontSize.X * (iCsW - 1) * iDpi / 96
		ch = fsc.dwFontSize.Y * (iCsH - 1) * iDpi / 96
	End If
	
	iCtrlPosX = (cw - iW * 1.20)
	iCtrlPosY = (ch - iH * 1.20)	

	hGUI_logo = CreateWindowEx(WS_EX_TRANSPARENT Or WS_EX_TOPMOST Or WS_EX_NOACTIVATE, wc.lpszClassName, sTitle, _
							   WS_VISIBLE Or WS_POPUP Or WS_CLIPCHILDREN, _
							   iCtrlPosX, iCtrlPosY, _
							   iW, iH, _
							   NULL, NULL, wc.hInstance, NULL)

	hPic_logo = CreateWindowEx(WS_EX_TRANSPARENT, "Static", "", WS_CHILD Or WS_VISIBLE Or SS_BITMAP Or WS_CLIPSIBLINGS, 0, 0, iW, iH, hGUI_logo, NULL, NULL, NULL)
	SetParent(hGUI_logo, hConsole)
	SetWindowPos(hGUI_logo, HWND_TOP, iCtrlPosX, iCtrlPosY, iW, iH, SWP_NOACTIVATE Or SWP_SHOWWINDOW)
	SetWindowPos(hPic_logo, HWND_TOPMOST, 0, 0, iW, iH, SWP_NOACTIVATE Or SWP_NOMOVE Or SWP_SHOWWINDOW)
	SendMessage(hPic_logo, STM_SETIMAGE, IMAGE_BITMAP, Cast(LPARAM, hBitmap))
	SetLayeredWindowAttributes(hGUI_logo, 0, 255, LWA_ALPHA)
	ShowWindow(hGUI_logo, SW_SHOWNOACTIVATE)

	SetActiveWindow(hConsole)
	SetFocus(hConsole)
	SetForegroundWindow(hConsole)
	
	While GetMessage(@msg, 0, 0, 0)
		TranslateMessage(@msg)
		DispatchMessage(@msg)
		Sleep(50)
	Wend	
End Sub

Function Base64Decode(sString As String, Byref iBase64Len as Uinteger) As Ubyte Ptr
	#Define P0(p) InStr(B64, Chr(sString[n + p])) - 1
	Dim As String*64 B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	Dim As String sDecoded
	Dim As Long nChars = Len(sString) - 1
	If nChars < 0 Then Return 0
	For n As Long = 0 To nChars Step 4
		Var b = P0(1), c = P0(2), d = P0(3)
		If b >-1 Then
			Var a = P0(0)
			sDecoded += Chr((a Shl 2 + b Shr 4))
		End If
		If c > -1 Then sDecoded += Chr((b Shl 4 + c Shr 2))
		If d > -1 Then sDecoded += Chr((c Shl 6 + d      ))
	Next
	iBase64Len = Len(sDecoded)

    Static As Ubyte aReturn(0 To iBase64Len - 1)
    Redim aReturn(0 To iBase64Len - 1) As Ubyte
	
	For i As ULong = 0 to Len(sDecoded) - 1 'convert result string to ascii code values
		aReturn(i) = Asc(sDecoded, i + 1)
	Next
	Return @aReturn(0) 'return pointer to the array
End Function

Function DecompressImage(sLabel As String, bGDI As BOOL = False) As Any Ptr
	Dim As Ulong iLines, bCompressed, iFileSize, iCompressedSize
	Dim As String sBaseType, sBase64, aB64(1)
	select Case sLabel
		Case "Label0"
			Restore __Label0:
	End Select
	Read iLines
	Read bCompressed
	Read iFileSize
	Read iCompressedSize
	Read sBaseType
	For i As Ushort = 0 To iLines - 1
	   Read aB64(0)
	   sBase64 &= aB64(0)
	Next

	Dim As Uinteger iLenB64
	Static As Ubyte Ptr aBinary
	aBinary = Base64Decode(sBase64, iLenB64)

	Dim As Any Ptr hBitmap = _GDIPlus_BitmapCreateFromMemory3(aBinary, iLenB64, bGDI)
	aBinary = 0
	sBase64 = ""

	Return hBitmap		
End Function

Function GetLatestNumber(iAccessType As Long = WINHTTP_ACCESS_TYPE_NO_PROXY, sUserAgent As String = "FB_WinHTTP/1.0", sProxyName As String = WINHTTP_NO_PROXY_NAME) As Ushort
	Dim As Any Ptr hSession, hConnect, hRequest
	Dim As String sRead	
	hSession = _WinHttpOpen(iAccessType, sUserAgent, sProxyName)
	If hSession = 0 Then ? "hSession = " & hSession
	hConnect = _WinHttpConnect(hSession, Wstr(sRadioSite))
	If hConnect = 0 Then ? "hConnect = " & hConnect
	hRequest = _WinHttpSimpleSendRequest(hConnect, "")
	If hRequest = 0 Then ? "hRequest = " & hRequest
	sRead = _WinHttpSimpleReadData(hRequest)
	_WinHttpCloseHandle(hRequest)
	_WinHttpCloseHandle(hConnect)
	_WinHttpCloseHandle(hSession)
	Dim As String sSearch = "<a class=" & Chr(34) & "date" & Chr(34) & " href=" & Chr(34) & "/remix/"
	Dim As Long iLen = Len(sSearch), iPos = Instr(sRead, sSearch) + iLen, iLatestNumber = Valint(Mid(sRead, iPos, Instr(iPos, sRead, Chr(34)) - iPos))
	iSongsreal = Valint(Mid(sRead, Instr(sRead, " tunes" & Chr(10)) - 4, 4))
	If iSongsreal = 0 Then iSongsreal = iLatestNumber
	Return iLatestNumber
End Function

Sub GetSongInfo(iSongNumer As Ushort, iAccessType As Long = WINHTTP_ACCESS_TYPE_NO_PROXY, sUserAgent As String = "FB_WinHTTP/1.0", sProxyName As String = WINHTTP_NO_PROXY_NAME)
	Dim As Any Ptr hSession, hConnect, hRequest
	Dim As String sRead	
	hSession = _WinHttpOpen(iAccessType, sUserAgent, sProxyName)
	If hSession = 0 Then ? "hSession = " & hSession
	hConnect = _WinHttpConnect(hSession, "www.remix64.com")
	If hConnect = 0 Then ? "hConnect = " & hConnect
	hRequest = _WinHttpSimpleSendRequest(hConnect, "box.php?id=" & Str(iSongNumer) & "00")
	If hRequest = 0 Then ? "hRequest = " & hRequest
	sRead = _WinHttpSimpleReadData(hRequest)
			  
	_WinHttpCloseHandle(hRequest)
	_WinHttpCloseHandle(hConnect)
	_WinHttpCloseHandle(hSession)

	Dim As Ushort iPosStart1 = Instr(sRead, "Rating<br><b>") + Len("Rating<br><b>"), iPosEnd1 = Instr(Iif(iPosStart1 > 0, iPosStart1, 1), sRead, "%</b> (") + 1, _
				  iPosStart2 = Instr(sRead, "%</b> (") + 6, iPosEnd2 = Instr(Iif(iPosStart2 > 0, iPosStart2, 1), sRead, "votes)</td>") - 1
	
	Dim As String sPosStart3 = "            <td class=""tabCell3"">Original by:</td>" & Chr(10) & "            <td class=""tabCell3""><b>", _
				  sPosStart4 = "            <td class=""tabCell3"">Release Date:</td>" & Chr(10) & "            <td class=""tabCell3""><b>", _
				  sPosStart5 = "            <td class=""tabCell3"">All-Time Rank:</td>" & Chr(10) & "            <td class=""tabCell3""><b>"
				  
	Dim As Ushort iPosStart3 = Instr(sRead, sPosStart3), iLenPS3 = Len(sPosStart3), _
				  iPosEnd3 = Instr(Iif(iPosStart3 > 0, iPosStart3, 1), sRead, "</b></td>" & Chr(10) & "        </tr>" & Chr(10) & "        <tr>" & Chr(10) & "            <td class=""tabCell3"">Release Date:</td>"), _
				  iPosStart4 = Instr(sRead, sPosStart4), iLenPS4 = Len(sPosStart4), _
				  iPosEnd4 = Instr(Iif(iPosStart4 > 0, iPosStart4, 1), sRead, "</b></td>" & Chr(10) & "        </tr>" & Chr(10) & "        <tr>" & Chr(10) & "            <td class=""tabCell3"">All-Time Rank:</td>"), _
				  iPosStart5 = Instr(sRead, sPosStart5), iPosEnd5 = Instr(Iif(iPosStart5 > 0, iPosStart5, 1), sRead, ".</b></td>" & Chr(10))
		
	sRating = Str("???% (??? votes)")
	sReleaseDate = Str("???")
	sOriginal = Str("???")
	sAllTimeRank = Str("???")
	If Instr(sRead, "Rating<br><b>") > 0 Then sRating = Mid(sRead, iPosStart1, iPosEnd1 - iPosStart1) & " " & Mid(sRead, iPosStart2, iPosEnd2 - iPosStart2) & " votes)" 
	If iPosStart3 > 0 And iPosEnd3 > 0 Then sOriginal = Mid(sRead, iPosStart3 + iLenPS3, iPosEnd3 - iPosStart3 - iLenPS3)
	If iPosStart4 > 0 And iPosEnd4 > 0 Then 
		sReleaseDate = Mid(sRead, iPosStart4 + iLenPS4, iPosEnd4 - iPosStart4 - iLenPS4)
		sReleaseDate = Iif(Len(sReleaseDate) > 10, Str("???"), sReleaseDate)
	Endif
	If iPosStart5 > 0 And iPosEnd5 > 0 Then 
		sAllTimeRank = Mid(sRead, iPosStart5 + Len(sPosStart5), iPosEnd5 - iPosStart5 - Len(sPosStart5))
		sAllTimeRank = Iif(Len(sAllTimeRank) > 5, Str("???"), sAllTimeRank)
	Endif
End Sub

Sub GetTop50(sSearch As String = "", iAccessType As Long = WINHTTP_ACCESS_TYPE_NO_PROXY, sUserAgent As String = "FB_WinHTTP/1.0", sProxyName As String = WINHTTP_NO_PROXY_NAME)
	Dim As Any Ptr hSession, hConnect, hRequest
	Dim As String sRead	
	hSession = _WinHttpOpen(iAccessType, sUserAgent, sProxyName)
	If hSession = 0 Then ? "hSession = " & hSession
	hConnect = _WinHttpConnect(hSession, "remix.kwed.org")
	If hConnect = 0 Then ? "hConnect = " & hConnect
	If sSearch  <> "" Then
		hRequest = _WinHttpSimpleSendRequest(hConnect, "search/" & sSearch & "?page=1&chart=&view=rating&search=" & sSearch)
	Else
		hRequest = _WinHttpSimpleSendRequest(hConnect, "?chart=&view=rating&page=1")
	Endif
	If hRequest = 0 Then ? "hRequest = " & hRequest
	sRead = _WinHttpSimpleReadData(hRequest)
	_WinHttpCloseHandle(hRequest)
	_WinHttpCloseHandle(hConnect)
	_WinHttpCloseHandle(hSession)
	Dim As Long iPosStart = 1, iPosEnd, c = 1
	Dim As String s1 = "<a class=""date"" href=""/remix/", s2 = """ title=""Permalink"">"
	While True
		iPosStart = Instr(iPosStart, sRead, s1)
		If iPosStart > 0 Then
			iPosEnd = Instr(iPosStart, sRead, s2)
			If iPosEnd > 0 Then
				aTop50Titles(c) = Clng(Mid(sRead, iPosStart + Len(s1), iPosEnd - iPosStart - Len(s1)))
				c += 1
				iPosStart = iPosEnd
				If c > iTop50Items Then Exit While
			Endif
		Else
			Exit While
		End If
	Wend
	iTop50Items = c - 1
	If c > 1 Then 
		bTop50 = True
		iOrder = 3
	Endif
End Sub

Sub CallBack_Redirect(hInternet As Any Ptr, dwContext As DWORD_PTR, dwInternetStatus As DWORD, lpvStatusInformation As Zstring Ptr, dwStatusInformationLength As DWORD)
	Dim As String sResult
	For i As Ulong = 0 To 2 * dwStatusInformationLength - 1
		sResult &= Str(*(@lpvStatusInformation[i]))
	Next
	iCounter += 1
	If sRedirectURL = "https://remix.kwed.org/download-limit.php" Then
		bLimitReached = True
	Else
		bLimitReached = False
	Endif
	sRedirectURL = Replace(sResult, "%20", " ")
End Sub

Sub GetRedirectedFilename(iNumber As Ushort)
	Dim As Any Ptr hRequest
	_WinHttpSetStatusCallback(hConnect, @CallBack_Redirect, WINHTTP_CALLBACK_STATUS_REDIRECT)
	hRequest = _WinHttpSimpleSendRequest(hConnect, "download.php/" & iNumber)
	_WinHttpCloseHandle(hRequest)
End Sub

Sub Download_CurrentSong(param As Any Ptr)
	Dim As String sSuffixURL = Mid(SOUNDFILE, Instr(SOUNDFILE, sRadioSite) + Len(sRadioSite))
	Dim As HINTERNET hRequest_Dl = _WinHttpOpenRequest(hConnect, "GET", sSuffixURL, "HTTP/1.1", WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_ESCAPE_DISABLE Or WINHTTP_FLAG_SECURE)
	If hRequest_Dl = 0 Then Exit Sub
	_WinHttpSendRequest(hRequest_Dl)
	If _WinHttpReceiveResponse(hRequest_Dl) Then
		Locate iCsH, 1, 0
		Color iFGCol, iBGCol
		? "Downloading...";
		Dim As Ulong iNumberOfBytesRead, i, j = 0, iNumberOfBytesAvailable
		Dim As Ubyte aBinData(iFileSize), aBuffer
		Do
			iNumberOfBytesAvailable = 0
			If _WinHttpQueryDataAvailable(hRequest_Dl, @iNumberOfBytesAvailable) = 0 Then Exit Do
			If iNumberOfBytesAvailable = 0 Then Exit Do
			Redim aBuffer(iNumberOfBytesAvailable - 1)
			WinHttpReadData(hRequest_Dl, @aBuffer(0), iNumberOfBytesAvailable, @iNumberOfBytesRead)
			For i = 0 To Ubound(aBuffer)
				If j <= iFileSize Then aBinData(j) = aBuffer(i)
				j += 1
			Next
		Loop Until iNumberOfBytesAvailable = 0
		Dim As Long hFile = Freefile()
		Open Exepath & "\" & sRadioSite  & "\" & sPlaying For Binary Access Write As #hFile
		Put #hFile, 0, aBinData(0), iFileSize
		Close #hFile
	Endif
	_WinHttpCloseHandle(hRequest_Dl)	
	iDLFinished = 2
End Sub

Function ShortenString(sPlaying As String, txt As String) As String
	Dim As Byte iDiff = (iCsW - 1) - Len(txt) - Len(sPlaying), iDiff1
	If iDiff < 0 Then
		iDiff1 = Len(sPlaying) + iDiff
		sPlaying = Left(sPlaying, iDiff1 \ 2 - 2) & "..." & Right(sPlaying, iDiff1 \ 2 - 1)
	End If
	Return sPlaying
End Function

Function Stream() As hStream
	Select Case iOrder
		Case 0
			If bOneTime Then
				bOneTime = 0
			Else
				iNumber = 1 + Cshort(Rnd * iSongs) '2404
			End If
		Case 1
			iNumber -= 1
			If iNumber = 0 Then iNumber = iSongs + 1
		Case 2
			iNumber += 1
			If iNumber > iSongs + 1 Then iNumber = 1
		Case 3
			If iTop50Pos = 0 Or iTop50Pos > iTop50Items Then
				If iTop50PosDir = -1 Then 
					iTop50Pos = iTop50Items
				Else
					iTop50Pos = 1
				Endif
			Endif
			iNumber = aTop50Titles(iTop50Pos)
			iTop50Pos += 1 * iTop50PosDir
	End Select
	SOUNDFILE = "https://" & sRadioSite & "/download.php/" & Str(iNumber)
	GetRedirectedFilename(iNumber)
	Dim As Double fTimer = Timer
	While sRedirectURL = ""
		Sleep(10)
		If Timer - fTimer > 1 Then Exit While
	Wend
	GetSongInfo(iNumber)
	sPlaying = Mid(sRedirectURL, Instrrev(sRedirectURL, "/") + 1)
	sRedirectURL = ""
	Dim As Byte iDiff = (iCsW - 1) - Len("Playing:      ") - Len(sPlaying), iDiff1
	If iDiff < 0 Then
		iDiff1 = Len(sPlaying) + iDiff
		sPlaying = Left(sPlaying, iDiff1 \ 2 - 2) & "..." & Right(sPlaying, iDiff1 \ 2 - 1)
	End If
	Dim As HSTREAM hStream = _BASS_StreamCreateURL(SOUNDFILE)
	iBytesLen = _BASS_ChannelGetLength(hStream)
	iFileSize = _BASS_StreamGetFilePosition(hStream, BASS_FILEPOS_SIZE)
	_BASS_ChannelGetAttribute(hStream, fBitrate)
	iFilePosStart = _BASS_StreamGetFilePosition(hStream, BASS_FILEPOS_START)
	length = _BASS_ChannelBytes2Seconds(hStream, iBytesLen)
	iEnd = BASS_StreamGetFilePosition(hStream, BASS_FILEPOS_END)
	_BASS_ChannelSetAttribute(hStream, BASS_ATTRIB_VOL, vol)
	_BASS_ChannelPlay(hStream)
	If iFileSize <> -1 Then 
		Color iFGCol, iBGCol
		ClrConsole2(hStdOut) ', 14, 0, iCsW, 8, 0, 0)
		Sleep(50)
		? "URL:          " & SOUNDFILE
		? "Playing:      " & ShortenString(sPlaying, "Playing:      ")
		? "Release Date: " & sReleaseDate
		sOriginal = "Original by:  " & ShortenString(sOriginal, "Original by:  ") & Chr(10)
		WriteConsole(hStdOut, StrPtr(sOriginal), Len(sOriginal), 0, 0)
		? "Rating:       " & sRating & " / All-time rank: " & sAllTimeRank
		? "Bitrate:      " & Wchr(&h00D8) & " " & Int(iFileSize * 8 / length / 1000) & " kbps (" & fBitrate & " kbps)"
		? "Size:         " & iFileSize & " bytes / " & Format(iFileSize / 1024 ^ 2, "##0.00 mib")
		Dim As String sec, mins, hr, ms
		ms = Format(Frac(length) * 1000, "000")
		ms = Iif(ms = "1000", "000", ms)
		sec = Format(length Mod 60, "00")
		mins = Format(length \ 60, "00")
		hr = Format(length \ 3600, "00")
		? "Length:       " & Format(length, "##0.00 s / ") & hr & ":" & mins & ":" & sec & ":" & ms
	Else
		Locate iCsH - 3, 1, 0
	End If
	SendMessage(hPic_logo, STM_SETIMAGE, IMAGE_BITMAP, Cast(LPARAM, hBitmap))
	Return HSTREAM
End Function

Function mouseProc(nCode As Integer, wParam As WPARAM, lParam As LPARAM) As LRESULT
	If nCode >= HC_ACTION And wParam = WM_LBUTTONUP Then
		Dim As MENUITEMINFO tMENUITEMINFO
		tMENUITEMINFO.cbSize = Sizeof(MENUITEMINFO)
		tMENUITEMINFO.fMask = MIIM_STATE Or MIIM_ID Or MIIM_SUBMENU Or MIIM_CHECKMARKS Or MIIM_TYPE Or MIIM_DATA
		GetMenuItemInfo(hSysMenu, id_Exit, False, @tMENUITEMINFO)
		If tMENUITEMINFO.fState And MF_HILITE Then 
			bExit = 1
		Endif
	Endif
	Return CallNextHookEx(hMouseHook, nCode, wParam, lParam)
End Function

Sub ChkMouseThread(param As Any Ptr)
	hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, Cast(HOOKPROC, @mouseProc), GetModuleHandle(NULL), 0)
	Dim As MSG msg
	While GetMessage(@msg, 0, 0, 0)
		TranslateMessage(@msg)
		DispatchMessage(@msg)
		Sleep(50)
	Wend
End Sub

Function Check4TLS() As Long
	Dim As SYSTEM_INFO tSYSTEM_INFO 'https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info
	GetNativeSystemInfo(@tSYSTEM_INFO)
	Dim As Any Ptr hReg, hReg2
	Dim As Long iReturn
	
	Dim As DWORD BinaryType
	GetBinaryType(Command(0), @BinaryType)
	If tSYSTEM_INFO.wProcessorArchitecture = 9 And BinaryType = 0 Then 
		iReturn = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp", 0, KEY_QUERY_VALUE, @hReg)
		If iReturn Then Return -iReturn
		iReturn = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings", 0, KEY_QUERY_VALUE, @hReg2)
		If iReturn Then Return -iReturn
	Else
		iReturn = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp", 0, KEY_QUERY_VALUE, @hReg)
		If iReturn Then Return -iReturn
		iReturn = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings", 0, KEY_QUERY_VALUE, @hReg2)
		If iReturn Then Return -iReturn
	Endif
	
	Dim As DWORD iRegValue, iRegValue2, iRegValueLength = Sizeof(DWORD)
	RegQueryValueEx(hReg, "DefaultSecureProtocols", NULL, NULL, Cast(Byte Ptr, @iRegValue), @iRegValueLength)
	RegQueryValueEx(hReg2, "SecureProtocols", NULL, NULL, Cast(Byte Ptr, @iRegValue2), @iRegValueLength)
	RegCloseKey(hReg)
	RegCloseKey(hReg2)
	If (iRegValue And &h0A00) /'And (iRegValue2 And &h0A00)'/ Then Return 3 'TLS 1.1 and TLS 1.2 supported
	If (iRegValue And &h0800) /'And (iRegValue2 And &h0800)'/ Then Return 2 'TLS 1.2 supported
	If (iRegValue And &h0200) /'And (iRegValue2 And &h0200)'/ Then Return 1 'TLS 1.1 supported
	Return 0							  								'either TLS 1.1 or TLS 1.2 is not supported
End Function

If OS.dwBuildNumber < 9200 And Check4TLS < 1 Then End 5 * MessageBox(0, "TLS 1.1 and TLS 1.2 must be enabled to run Radio Station (see Readme.txt)!", "ERROR", MB_OK Or MB_ICONSTOP Or MB_TOPMOST)

If _GDIPlus_Startup() = False Then End 4

sRedirectURL = ""
AllocConsole()
Dim As Ulong iOldCP = GetConsoleOutputCP()
SetConsoleOutputCP(65001)

hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)
hStdIn = GetStdHandle(STD_INPUT_HANDLE)
hConsole = GetConsoleWindow()

SetConsoleActiveScreenBuffer(hStdOut)

While (GetWindowLong(hConsole, GWL_STYLE) And WS_MINIMIZE) = WS_MINIMIZE
	Sleep(10)
Wend

Dim As DWORD cmode
GetConsoleMode(hStdIn, @cmode)

Dim As _CONSOLE_FONT_INFOEX fi = GetFontInfo()

Dim As Zstring * 255 sTitle
GetConsoleTitle(sTitle, 255)

savebuffinfoex.cbSize = Sizeof(CONSOLE_SCREEN_BUFFER_INFOEX)
GetConsoleScreenBufferInfoEx(hStdOut, @savebuffinfoex)

SetConsoleMode(hStdIn, ENABLE_EXTENDED_FLAGS Or (cmode And (Not ENABLE_MOUSE_INPUT) And (Not ENABLE_QUICK_EDIT_MODE) And (Not ENABLE_PROCESSED_INPUT)))
SetConsoleCtrlHandler(Null, True)

Dim As HDC scr = GetDC(hConsole)
Dim As Long iDPI = GetDeviceCaps (scr, LOGPIXELSX)
ReleaseDC (hConsole, scr)

fDPI_ratio = 96 / iDPI
If OS.dwBuildNumber < 9200 Then fDPI_ratio = iDPI / 96

SetFontSize(iFsW * fDPI_ratio, iFsH * fDPI_ratio)
SetConsoleSize(iCsW, iCsH)

Dim As RECT tRECT
Dim As Long cw, ch
GetClientRect(hConsole, @tRECT)
iConsoleW = tRECT.right - tRECT.left
iConsoleH = tRECT.bottom - tRECT.top

hImage = DecompressImage("Label0")
GdipGetImageDimension(hImage, @iW, @iH)

Dim As HICON hIcon_prev = Cast(HICON, SendMessage(hConsole, WM_GETICON, Cast(LParam, ICON_SMALL2), 0))
If hIcon_prev = 0 Then hIcon_prev = Cast(HICON, SendMessage(hConsole, WM_GETICON, Cast(LParam, ICON_SMALL), 0))
If hIcon_prev = 0 Then hIcon_prev = Cast(HICON, SendMessage(hConsole, WM_GETICON, Cast(LParam, ICON_BIG), 0))
If hIcon_prev = 0 Then hIcon_prev = Cast(HICON, GetClassLongPtr(hConsole, GCL_HICON))
If hIcon_prev = 0 Then hIcon_prev = Cast(HICON, GetClassLongPtr(hConsole, GCL_HICONSM))


If _WinAPI_GetProcessName(_WinAPI_GetParentProcess()) = "cmd.exe" Then
	_WinAPI_SetWindowTitleIcon(hImage, hConsole) 'set new windows icon
Else
	Dim As HICON hIcon = _WinAPI_FileExtractIcon(Exepath)
	SendMessageW(hConsole, WM_SETICON, Iif(OS.dwBuildNumber < 9200, 1, 0), Cast(LParam, hIcon))
Endif

Dim As Ubyte iPos
Dim As String sUserAgent = "FB_WinHTTP/1.0", sProxyName = WINHTTP_NO_PROXY_NAME
Dim As Long iAccessType = WINHTTP_ACCESS_TYPE_NO_PROXY
Dim As Bool bGlass = False, bGlass10 = False, bGlassSet = False, bTopmost = False

? "Initializing WinHTTP..."
If _WinHttpStartup() = False Then ? "Unable To initialize Winhttp.dll! Exiting..." : End 1
? "Initializing Bass.dll..."
If _Bass_Startup(Exepath) = False Then ? "Unable To initialize Bass.dll! Exiting..." : End 2
? "Getting latest song number..."

iPos = SearchInCMDArgument("/proxy") 
If iPos And Len(Command(iPos + 1)) > 0 Then sProxyName = (Command(iPos + 1))
If sProxyName <> "" Then iAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY

hSession = _WinHttpOpen(iAccessType, sUserAgent, sProxyName)
hConnect = _WinHttpConnect(hSession, Wstr(sRadioSite))
iSongs = GetLatestNumber(iAccessType, sUserAgent, sProxyName)
If iSongs = 0 Then ? "Unable To Get latest song number! Exiting..." : End 3

iPos = SearchInCMDArgument("/number") 
If iPos And Len(Command(iPos + 1)) > 0 Then 
	iNumber = ValInt(Command(iPos + 1))
	iNumber = Iif(iNumber < 1, 1, Iif(iNumber > iSongs + 1, iSongs + 1, iNumber))
Endif
If iNumber > 0 Then bOneTime = 1

Dim As String sSearchToken = ""
iPos = SearchInCMDArgument("/search") 
If iPos And Len(Command(iPos + 1)) > 0 Then 
	sSearchToken = Command(iPos + 1)
Endif

If SearchInCMDArgument("/top50") Then 
	GetTop50(sSearchToken)
	If iNumber > 0 Then iTop50Pos = Iif(iNumber > iTop50Items, iTop50Items, iNumber)
	iPos = SearchInCMDArgument("/top50dir") 
	If iPos And Len(Command(iPos + 1)) > 0 Then 
		iTop50PosDir = ValInt(Command(iPos + 1))
		iTop50PosDir = Iif(iTop50PosDir > 1 Or iTop50PosDir = 0, 1, Iif(iTop50PosDir < -1, -1, iTop50PosDir))
	Endif
Endif

iPos = SearchInCMDArgument("/order") 
If iPos And Len(Command(iPos + 1)) > 0 Then 
	iOrder = ValInt(Command(iPos + 1))
	iOrder = Iif(iOrder > 2, 2, Iif(iOrder < 0, 0, iOrder))
Endif

Dim As String sOrder = "Playing songs randomly"
Select Case iOrder
	Case 1 'play from latest to oldest
		If iNumber = -1 Then 
			iNumber = iSongs + 1
		Else
			iNumber += 1
		Endif
		sOrder = "Playing songs from latest to oldest"
	Case 2 'play from oldest to latest
		If iNumber = -1 Then 
			iNumber = 0
		Else
			iNumber -= 1
		Endif
		sOrder = "Playing songs from oldest to latest"
	Case 3 'playing Top50 from 1st place to last place
		sOrder = "Playing Top50 " & Iif(iTop50PosDir = 1, "ascending", "descending")
End Select

If SearchInCMDArgument("/nolevel") Then bShowLevel = 0

If SearchInCMDArgument("/noautoswitchdevice") Then bAutoSwitchDevice = 0

iPos = SearchInCMDArgument("/cfg") 
If iPos And Len(Command(iPos + 1)) > 0 Then 
	iFGCol = ValInt(Command(iPos + 1))
	iFGCol = Iif(iFGCol > 15, 15, Iif(iFGCol < 0, 0, iFGCol))
Endif

iPos = SearchInCMDArgument("/cbg") 
If iPos And Len(Command(iPos + 1)) > 0 Then 
	iBGCol = ValInt(Command(iPos + 1))
	iBGCol = Iif(iBGCol > 15, 15, Iif(iBGCol < 0, 0, iBGCol))
Endif

If SearchInCMDArgument("/glass") Then bGlass = True
If SearchInCMDArgument("/blur10") And OS.dwBuildNumber > 10000 Then bGlass10 = True

If _WinAPI_DwmIsCompositionEnabled() And (bGlass Or bGlass10) Then 
	If bGlass10 Then
		_WinAPI_EnableBlurBehindWindow(hConsole)
		_WinAPI_SetWindowCompositionAttribute(hConsole)
	Else
		_WinAPI_EnableBlurBehindWindow(hConsole)
	Endif
	bGlassSet = True
Endif

If SearchInCMDArgument("/topmost") Then 
	SetWindowPos(hConsole, (HWND_TOPMOST), 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
	bTopmost = True
Endif

SetConsoleTitle("Radio Station " & sRadioSite & " / ~" & iSongsreal & " songs available / " & sOrder)

buffinfoex.cbSize = Sizeof(CONSOLE_SCREEN_BUFFER_INFOEX)
GetConsoleScreenBufferInfoEx(hStdOut, @buffinfoex)
iPicBGColor = Rgba((buffinfoex.ColorTable(iBGCol) And &hFF), (buffinfoex.ColorTable(iBGCol) And &h00FF00) Shr 8, (buffinfoex.ColorTable(iBGCol) And &h00FF0000) Shr 16, 255) 'get console color and convert it to ARGB

Color iFGCol, iBGCol
ClrConsole2(hStdOut)
Sleep(50)

hSysMenu = GetSystemMenu(hConsole, False)
Dim As Integer iOldStyle = GetWindowLong(hConsole, GWL_STYLE), iCount = GetMenuItemCount(hSysMenu)
Dim As HMENU aSave(0 To 3)
Dim As Uinteger aID(0 To Ubound(aSave))
Dim As HBITMAP aBmp(0 To Ubound(aSave))
Dim As ZString * 255 aTxt(0 To Ubound(aSave))

For j As Ubyte = 0 To Ubound(aSave)
	Dim As MENUITEMINFO tMENUITEMINFO
	tMENUITEMINFO.cbSize = Sizeof(MENUITEMINFO)
	tMENUITEMINFO.fMask = &h3F
	GetMenuItemInfo(hSysMenu, iCount - j - 1, True, @tMENUITEMINFO)
	aSave(j) = GetSubMenu(hSysMenu, iCount - j - 1)
	aBmp(j) = Cast(HBITMAP, tMENUITEMINFO.hbmpItem)
	aID(j) = GetMenuItemID(hSysMenu, iCount - j - 1)
	GetMenuString(hSysMenu, iCount - j - 1, Cast(LPSTR, @aTxt(j)), 255, MF_BYPOSITION)
Next

For j As Ubyte = iCount - 1 To iCount - 4 Step - 1 'delete last 4 menu entries
	RemoveMenu(hSysMenu, j, MF_BYPOSITION)
Next

AppendMenu(hSysMenu, MF_STRING, id_Exit, "&Exit Radio Station")

Dim As MENUITEMINFO tMenuItem
With tMenuItem
	.cbsize = Sizeof(tMenuItem)
	.wID = id_Exit
	.fMask = MIIM_BITMAP
	.fType = MFT_OWNERDRAW Or MFT_STRING
	.hbmpItem = Cast(HBITMAP, 8) 'aBmp(3)
End With
SetMenuItemInfo(hSysMenu, id_Exit, False, @tMenuItem)

SetWindowLong(hConsole, GWL_STYLE, iOldStyle And Not WS_MAXIMIZEBOX And Not WS_SIZEBOX) 'grey Out maximize icon And disable resizing

DrawMenuBar(hSysMenu)

? "Please wait while connecting to a song..."

If bAutoSwitchDevice Then _BASS_SetConfig(BASS_CONFIG_DEV_DEFAULT, True) 'This option adds a "Default" entry to the output device list, which maps to the device that is currently the system's default. 
																		 'Its output will automatically switch over when the system's default device setting changes
_Bass_Init()

Dim As HSTREAM hStream = Stream()

Dim As QWORD iCurrentPos
Dim As Double t1, p = 0
Dim As Any Ptr thread, threadGUI, threadMouse
Dim As Integer bPause = 0, r = 1
Dim As BASS_LEVELS Levels
Dim As Ubyte aColorsBg(...) = {iBGCol, iBGCol, 1, 3, 9, 11, 7, 15}, aColorsFg(...) = {15, 15, 15, 14, 14, 13, 5, 1}, iUB = Ubound(aColorsBg), iLevel
Dim As String sec, mins, hr, ms
Dim As Single br

GdipCreateHBITMAPFromBitmap(hImage, @hBitmap, iPicBGColor)

threadGUI = ThreadCreate(@ChildGUIThread, 0)
Sleep(100)
threadMouse = ThreadCreate(@ChkMouseThread, 0)

iPosCursor = Csrlin
Dim As String sWaitChars = "|/-\"
Dim As Ubyte iPosWC = 1

While True
	If bExit Then Exit While
		
	If GetForegroundWindow() = hConsole Then 'https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
		If GetAsyncKeyState(VK_ESCAPE) Or GetAsyncKeyState(&h51) Then Exit While 'ESC or q to exit program
		If (GetAsyncKeyState(VK_SPACE) And &h8000) And bPause = 0 And bEndless = 0 Then 'skip current song and load next one
			While (GetAsyncKeyState(VK_SPACE) And &h8001)
				Sleep(10)
			Wend
			_BASS_ChannelStop(hStream)
			_BASS_StreamFree(hStream)
			hStream = Stream()
			iBytesLen = _BASS_ChannelGetLength(hStream)
		Elseif (GetAsyncKeyState(VK_BACK) And &h8000) Then 'backspace to play again
			While (GetAsyncKeyState(VK_BACK) And &h8001)
				Sleep(10)
			Wend
			_BASS_ChannelSetPosition(hStream, 0, BASS_POS_BYTE Or BASS_POS_SCAN)
		Elseif (GetAsyncKeyState(&h45) And &h8000) Then 'press e to play song endless
			While (GetAsyncKeyState(&h45) And &h8001)
				Sleep(10)
			Wend
			If bEndless = 0 Then 
				bEndless = 1
			Else
				bEndless = 0
			End If
		Elseif (GetAsyncKeyState(&h50) And &h8000) Then 'press p to pause / resume stream
			While (GetAsyncKeyState(&h50) And &h8001)
				Sleep(10)
			Wend
			If bPause = 0 Then 
				_BASS_ChannelPause(hStream)
				bPause = 1
			Else
				_BASS_ChannelPlay(hStream, False)
				bPause = 0
			End If
		Elseif (GetAsyncKeyState(VK_MEDIA_PLAY_PAUSE) And &h8000) Then 'press p to pause / resume stream
			While (GetAsyncKeyState(VK_MEDIA_PLAY_PAUSE) And &h8001)
				Sleep(10)
			Wend
			If bPause = 0 Then 
				_BASS_ChannelPause(hStream)
				bPause = 1
			Else
				_BASS_ChannelPlay(hStream, False)
				bPause = 0
			End If
		Elseif (GetAsyncKeyState(&h47) And &h8000) And bGlass10 = 0 Then 'press g to enable / disable glass effect
			While (GetAsyncKeyState(&h47) And &h8001)
				Sleep(10)
			Wend
			If bGlass = 0 Then 
				If _WinAPI_DwmIsCompositionEnabled() Then 
					_WinAPI_EnableBlurBehindWindow(hConsole)
					bGlass = 1
					bGlassSet = True
				Endif
			Else
				If _WinAPI_DwmIsCompositionEnabled() Then
					_WinAPI_EnableBlurBehindWindow(hConsole, False)
					bGlass = 0
					bGlassSet = False
				Endif
			Endif
		Elseif (GetAsyncKeyState(&h54) And &h8000) Then 'press t to set console topmost or not
			While (GetAsyncKeyState(&h54) And &h8001)
				Sleep(10)
			Wend
			If bTopmost = 0 Then 
				SetWindowPos(hConsole, (HWND_TOPMOST), 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
				bTopmost = 1
			Else
				SetWindowPos(hConsole, (HWND_NOTOPMOST), 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
				bTopmost = 0
			Endif
		Elseif (GetAsyncKeyState(VK_OEM_PLUS) And &h8000) Or (GetAsyncKeyState(VK_ADD) And &h8000) Or (GetAsyncKeyState(VK_UP) And &h8000) Then '+ to increase volume
			Sleep(100, 1)
			If vol <= 1.0 Then 
				vol += 0.05
				_BASS_ChannelSetAttribute(hStream, BASS_ATTRIB_VOL, vol)
			Endif
		Elseif (GetAsyncKeyState(VK_OEM_MINUS) And &h8000) Or (GetAsyncKeyState(VK_SUBTRACT) And &h8000) Or (GetAsyncKeyState(VK_DOWN) And &h8000) Then '- to decrease volume
			Sleep(100, 1)
			If vol > 0.05 Then 
				vol -= 0.05
				_BASS_ChannelSetAttribute(hStream, BASS_ATTRIB_VOL, vol)
			Endif
		Elseif (GetAsyncKeyState(&h30) And &h8000) And bPause = 0 And iOrder <> 0 And bLimitReached = False Then '0 to play randomly a song
			While (GetAsyncKeyState(&h30) And &h8001)
				Sleep(10)
			Wend
			iOrder = 0
			_BASS_ChannelStop(hStream)
			_BASS_StreamFree(hStream)
			hStream = Stream()
			iBytesLen = _BASS_ChannelGetLength(hStream)
			sOrder = "Playing songs randomly"
			SetConsoleTitle("Radio Station " & sRadioSite & " / ~" & iSongsreal & " songs available / " & sOrder)
		Elseif (GetAsyncKeyState(VK_NUMPAD0) And &h8000) And bPause = 0 And iOrder <> 0 And bLimitReached = False Then 'numpad 0 to play randomly a song
			While (GetAsyncKeyState(VK_NUMPAD0) And &h8001)
				Sleep(10)
			Wend
			iOrder = 0
			_BASS_ChannelStop(hStream)
			_BASS_StreamFree(hStream)
			hStream = Stream()
			iBytesLen = _BASS_ChannelGetLength(hStream)
			sOrder = "Playing songs randomly"
			SetConsoleTitle("Radio Station " & sRadioSite & " / ~" & iSongsreal & " songs available / " & sOrder)
		Elseif (GetAsyncKeyState(&h31) And &h8000) And bPause = 0 And iOrder <> 1 And bLimitReached = False Then '1 to play from latest to oldest
			While (GetAsyncKeyState(&h31) And &h8001)
				Sleep(10)
			Wend
			iOrder = 1
			iNumber = iSongs + 1
			_BASS_ChannelStop(hStream)
			_BASS_StreamFree(hStream)
			hStream = Stream()
			iBytesLen = _BASS_ChannelGetLength(hStream)
			sOrder = "Playing songs from latest to oldest"
			SetConsoleTitle("Radio Station " & sRadioSite & " / ~" & iSongsreal & " songs available / " & sOrder)
		Elseif (GetAsyncKeyState(VK_NUMPAD1) And &h8000) And bPause = 0 And iOrder <> 1 And bLimitReached = False Then 'numpad 1 to play from latest to oldest
			While (GetAsyncKeyState(VK_NUMPAD1) And &h8001)
				Sleep(10)
			Wend
			iOrder = 1
			iNumber = iSongs + 1
			_BASS_ChannelStop(hStream)
			_BASS_StreamFree(hStream)
			hStream = Stream()
			iBytesLen = _BASS_ChannelGetLength(hStream)
			sOrder = "Playing songs from latest to oldest"
			SetConsoleTitle("Radio Station " & sRadioSite & " / ~" & iSongsreal & " songs available / " & sOrder)
		Elseif (GetAsyncKeyState(&h44) And &h8000) And bLimitReached = False Then 'd to download current playing song to local disk
			While (GetAsyncKeyState(&h44) And &h8001)
				Sleep(10)
			Wend
			If DirExists(Exepath & "\" & sRadioSite) = 0 Then Mkdir Exepath & "\" & sRadioSite
			If iDLFinished = 0 And iFileSize <> -1 Then
				thread = ThreadCreate(@Download_CurrentSong, 0)
				iDLFinished = 1
			Endif
		Elseif (GetAsyncKeyState(VK_RIGHT) And &h8000) And bPause = 0 Then 'right to forward 5 seconds
			'While (GetAsyncKeyState(VK_RIGHT) And &h8001)
			'	Sleep(10)
			'Wend
			Sleep(100)
			If p + 5 < iBytesLen - 5 Then
				Dim As QWORD iNewPos = _BASS_ChannelSeconds2Bytes(hStream, p + 5)
				_BASS_ChannelSetPosition(hStream, iNewPos, BASS_POS_BYTE)
			Endif
		Elseif (GetAsyncKeyState(VK_LEFT) And &h8000) And bPause = 0  Then 'left to rewind 5 seconds
			'While (GetAsyncKeyState(VK_LEFT) And &h8001)
			'	Sleep(10)
			'Wend
			Sleep(100)
			If p - 5 >= 0 Then
				Dim As QWORD iNewPos = _BASS_ChannelSeconds2Bytes(hStream, p - 5)
				_BASS_ChannelSetPosition(hStream, iNewPos, BASS_POS_BYTE)
			Endif
		Elseif (GetAsyncKeyState(&h46) And &h8000) Then 'press f to play from current song to oldest song
			While (GetAsyncKeyState(&h46) And &h8001)
				Sleep(10)
			Wend
			iOrder = 1
			sOrder = "Playing songs to oldest"
			SetConsoleTitle("Radio Station " & sRadioSite & " / ~" & iSongsreal & " songs available / " & sOrder)
		Elseif (GetAsyncKeyState(&h42) And &h8000) Then 'press b to play from current song to latest song
			While (GetAsyncKeyState(&h42) And &h8001)
				Sleep(10)
			Wend
			iOrder = 2
			sOrder = "Playing songs to latest"
			SetConsoleTitle("Radio Station " & sRadioSite & " / ~" & iSongsreal & " songs available / " & sOrder)
		Endif
	End If

	_BASS_ChannelGetLevelEx(hStream, Levels, 0.02, BASS_LEVEL_MONO)
	iCurrentPos = _BASS_ChannelGetPosition(hStream, BASS_POS_BYTE) 
	p = _BASS_ChannelBytes2Seconds(hStream, iCurrentPos)
	
	Locate iPosCursor, 1, 0
	Color iFGCol, iBGCol

	ms = Format(Frac(p) * 1000, "000")
	ms = Iif(ms = "1000", "000", ms)
	sec = Format(p Mod 60, "00")
	mins = Format(p \ 60, "00")
	hr = Format(p \ 3600, "00")
	If iFileSize = -1 Then
		If bLimitReached Then
			? "Played:       Hourly limit reached! Please try later again. :-("
		Else
			? "Played:       searching for a new song... " & Mid(sWaitChars, 1 + (iPosWC Mod 4), 1) & "                                     "
			iPosWC += 1
		EndIf
	Else
		? "Played:       " & hr & ":" & mins & ":" & sec & ":" & ms & " / " & Format(iCurrentPos / iBytesLen, "00.00 % / ") & Format (length - p, "##0.00 s / ") & "volume: " & Cubyte(vol * 100) & _
		   IIf(bEndless, " (endless)  ", IIf(bPause, " (paused)   ", "            "))
	Endif
	
	Locate iPosCursor + 2, 1, 0
	iLevel = Levels.Left * iUB
	If bShowLevel Then Color aColorsFg(iLevel), aColorsBg(iLevel) ', 6 'aColors(6 - (Levels.Left + Levels.Right) * 6)
	If iFileSize <> -1 Then ? sCoder;
	If (iCurrentPos >= iBytesLen) Or (iFileSize - iFilePosStart - _BASS_StreamGetFilePosition(hStream, BASS_FILEPOS_CURRENT) <= 0) Then
		If bEndless Then
			_BASS_ChannelSetPosition(hStream, 0, BASS_POS_BYTE Or BASS_POS_SCAN)
		Else
			If bLimitReached = False Then
				_BASS_ChannelStop(hStream)
				_BASS_StreamFree(hStream)
				hStream = Stream()
				iBytesLen = _BASS_ChannelGetLength(hStream)
			Endif
		Endif
	End If
	If iDLFinished = 2 Then
		ThreadDetach(thread)
		iDLFinished = 0
		Locate iCsH, 1, 0
		Color iFGCol, iBGCol
		? "                               ";
	End If
		
	Sleep(15)
Wend

DestroyWindow(hGUI_logo)
ThreadDetach(threadGUI)
ThreadDetach(threadMouse)

_BASS_ChannelStop(hStream)
_BASS_StreamFree(hStream)
_Bass_Free()
_Bass_Shutdown()

_WinHttpCloseHandle(hConnect)
_WinHttpCloseHandle(hSession)
_WinHttpShutdown()

DeleteObject(hBitmap)
GdipDisposeImage(hImage)
_GDIPlus_Shutdown()

UnhookWindowsHookEx(hMouseHook)

'Restore console settings
If _WinAPI_GetProcessName(_WinAPI_GetParentProcess()) = "cmd.exe" Then
	If bGlassSet Then
		If OS.dwBuildNumber > 10000 And bGlass10 Then
			_WinAPI_SetWindowCompositionAttribute(hConsole, False)
			_WinAPI_EnableBlurBehindWindow(hConsole, False)
		Else
			_WinAPI_EnableBlurBehindWindow(hConsole, False)
		Endif	
	Endif
	SetWindowPos(hConsole, (HWND_NOTOPMOST), 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
	SendMessageW(hConsole, WM_SETICON, 0, Cast(LParam, hIcon_prev))
	SetWindowLong(hConsole, GWL_STYLE, iOldStyle Or WS_MAXIMIZEBOX Or WS_SIZEBOX)
	
	SetConsoleMode(hStdIn, cmode)
	SetConsoleScreenBufferInfoEx(hStdOut, @savebuffinfoex)
	SetConsoleTitle(sTitle)
	SetFontSize(fi.dwFontSize.x, fi.dwFontSize.y, fi.facename, fi.nFont, fi.FontWeight, fi.FontFamily)
	SetConsoleOutputCP(iOldCP)
	SetConsoleCtrlHandler(Null, False)
	
	DeleteMenu(hSysMenu, id_Exit, MF_BYCOMMAND)
	
	iCount = GetMenuItemCount(hSysMenu)
	Dim As LPSTR pTxt(0 To Ubound(aSave))
	Dim As MENUITEMINFO tMENUITEMINFO
	With tMENUITEMINFO
		.cbSize = Sizeof(MENUITEMINFO)
		.fMask = MIIM_ID Or MIIM_STRING Or MIIM_SUBMENU Or MIIM_BITMAP
		.fType = MFT_STRING	
	End With

	For j As Byte = Ubound(aSave) To 0 Step -1
		Dim As LPSTR pTxt
		pTxt = Allocate(Len(aTxt(j)))
		*pTxt = aTxt(j)	
		With tMENUITEMINFO
			.wID = aID(j)
			.hSubMenu = aSave(j)
			.dwTypeData = pTxt
			.hbmpItem = aBmp(j)
		End With
		InsertMenuItem(hSysMenu, iCount + Ubound(aSave) - j, True, @tMENUITEMINFO)
	Next
	DrawMenuBar(hSysMenu)
	
	EnableMenuItem(hSysMenu, SC_CLOSE, MF_BYCOMMAND)
	
	ClrConsole2(hStdOut)
	UpdateWindow(hConsole)
	Locate(1, 1, 1)
	? "Bye...."
Endif
FreeConsole()
Sleep(100)
End 0

'Code below was generated by: FB File2Bas Code Generator v1.05 build 2020-09-23 beta

'C64_3D_2_82x64.png
__Label0:
Data 9,0,3027,0,"Base64"
Data "iVBORw0KGgoAAAANSUhEUgAAAFIAAABACAMAAAC+7NA5AAACxFBMVEUVADYgHF1KGShjHi0cGl9/Ji6PHCeQHCq4HxWUJjjCIhXBIBocHFWLLj0VETwvGjVTHjMzHTobGEYhH1oUGUIuHDshIVcfHEwfHkgSEjALDSYVCygQCywRES0YGEYeG1ImImEpI2YrJmkjH1SPHCcoIGctJn09NoE+MZN+YshXRqUsI3lJONaFZs0iGI6Md8lvHCWFJUaBb8A3LIknH2kVFVIzGC1pWbIqImkqInM0Ko4cFUYkH38yJ55pJEM9MMpaTJNEOYYsJ3UzHDQVFTEVADIAACAAABxKFSJ3Kj0VCSwICBhdIj1OGis4HzAoJEoWFSoTEyoREy0REi4TFCwLCxwKDiAGCRYHDCMHCxgHBxUDBREDAwcFAQkEAQNHcExSSHNKQXFQSHtPRX8cFWQcFVwVFVgVFU8VFUQrIncsIn4eGVYAABy8IyK7IRs8LpC0"
Data "IhxANI9RQ51eUKkyJ40mHGYpIXA4LY8yJHkrInUVFUkmHHEVADgpIGUtI2y3HBwVAEIiGYUuJ4AwJ4MxJ4gdFW1WSaEoFSMyFSgAJHoAABVcTqUVFVs0K4UAACQABC0iGWAVADy7KirEJyS8IhxoWa+4IhxvXbQVFUE0K5A4K4wVFTy/IQBEN5hIOZtGOpJLP5pZRqccABY7Los5L38VFTZoULWlIh4AAEYAAAB4XcGcJy8AAFArHVqzHBxUQaRLMGxhSq4WAB+DHiCPHCUVADEVADWzLzIrInIwJripKi8uIaknImwmHG6tHA8mHJXEIxxnUbAcFX07LpMcFW81K40VAF92ZLmxIhkfInthU6ZBNJZjU6yTf88ZFSFjTvc/Mb43JW1RPuknGVU0LHVIABhSG0ocFV90IlwcFXWGc8hMPH8VFVMcFWpNPZ+/IhyYHCJHOK0uJ3tlHEYAFVRbRqkcAFCQGBwrIpgsJ3hwVrsAHGm6uEWQAAAA"
Data "ZHRSTlP79v39/v32/f7+/vzl6NnHuq6poJaXj4N0eIWVnrnIv7evzNfl5+zt+/77+v79/vz+/v7++vX2+vb8/Pr5/vP+2Nvd5+zt8vjg2c/Rx5x7ZWdeU0lCOzQrJh0SCQUCAQB6kZ/ANAFUbwAACFpJREFUeNqN2IN75FwbBvCsbRRr47Vtu8Yg58XYrm3btrm27X3t/ax/4nuek06aneTqNXfdpr+9D3omOwyRDqtQwHtZRODaLbtehDw7a8fqoDAZfE+pJDOHkQZZeBcduHWX3pCZmWmYiv7ortUhsYD6Q4pBWegWfUl2dlYmBDDMI4/AR8+sjdGc6T9JS8QG7CppBDBLQEIM+oRH9Amzgmc2GYmKisA9dntXCURMQllPYsyMJiOuGPFNbvteMBtBFJIYIPXl6iCi8JsEUfbV9Zr9jlZ7F5AlUuRRtWq50m8SxPA3r9Rdz3W0ttmlSSyp0kYSpX8kTOMXT/9ypa6mKNfRBiOXJBPUKpU6"
Data "2E8SxC9v3XraSzZCSy5ZmfHx8QYIkm4gVZsJ6w8J4le3nkDxJpCt2DI+NWUEk+LRUxDJchXkudgZajLTIvs1iEhed4Jp707Rph8uKy0tLSsrO1xv9AAJOUlJdShRzExy4je/AHgFSKfT0d5dnlgBST4MSU6uSO5pMuoRTVFhjOF+tGTJ18ABWFd3vaiozd2v09WnpyN56BBFm3p0CQa9xz0XyU1+LI+SBDpfqKmrq6mBjkXd/0xMTORJMJPBrNeBmapCUu3HJoL9mOt0Omtu3nSCeC8dRDCBrEhOxpoMwyQ31Tfp9KmXf8QFVyqUM88liNF7cotyUS1yFqX0a7VaJHW69AoGSVq0Akxjwik3lAyjv6RUsjOQyu1/tDscuR3OIocjZViLpNdMfu/jjcFBwRs+Znqamtx02d2b14ZG05FDW6UkCRPZ0tLa3t4+5hhzpKKIJDWXbwiXES4xIR+/AguESUg4mbJjdUikjDv/IT6kko3d3QJpbQW2"
Data "+7J2mnw3SE4gChpC5LtQRPKRlxLgNE5ZuiUgPJZ467ICkmyNs1pv3LgBapeqWKP5DYLqphjguCspHKZ/hP9Lh3jw7eSszWtDomScy7EMiJElcXFxFy4Aao+fq/aSumBkOI4jtxseJmmQLV+6JTgsRjFVl6ElG+Ig1gtWe/xllZr21OqCHn4sVJKI7wx6SdKTlOQ55caH0AisyyhJVBaSaHa15cAWUWvA1IU8VJFOz18fEZB8EITAh5NuqBsUCeTqBgyol9q6LoP5o7q4ONH3XFCyUVBSkkSO5ln4qO55nyGxj/CkXX8q53eVau5cjejRBf5lLClNcqInyW08PFD4CUPCXFNkQ4n+Ys4pIFVzVxOFb8loPN2kB86ZAB4aGDCZNjFkTQOXSw2GHMjvkKUypajkWrrc0iTGnVgKIGQjo3ibgi6XqyGJI3NUvhOJfw0vQklpkgcLC5EMZqIyEcRko4hZKmfFJQtejY+XIpMQ1BUOFJrwxfRBaQgT"
Data "5PKSWV5yrW9JlpW9/tO9goJrki3LEcQgaSoNZ2AqefLni5i5ogOWJZ9XNtsW/TR+DVQoKyTLKwagoZcs/ThExmwVktRcKieiksvOVlc3Ny8cemr8P1T1NjQmA8indFMYlGHeFpDnf0Z0tW9JBQk5ctZisZgti5ub+576IaWgQI/zetTYIwTf3xhFjwJm9zR5LeM8oBeDfEhWIf+oykJTbTZD2dML/jbyv4LUkUNC8N0gOOboUSQgsw1nMgC9GOZDKkgoLYkkxGy2LGk+/WBOWWcn75lgCvlbbiGZffdMxvmMJBGp/KhqsZeEWGpra82Wq99PIjmAi0OncPoIflvQ8tG7j2c8fi1cSGLJsONYUkhCLP8yceQHGyIJB4pJl+Evd46deTwjzJf81GwRkghCRr/Hkb8bHINbggeR3D5NZmfeuQ9mAPE5eocW86TXozULOz/h1oQ8FMG+pDXvnziz3Ydcaa72JdPwne3DMIUYBHK9gMw23L3z6IlX"
Data "Y1ml8OhddFZEUtSyU07PQBEZnk01jgTz/qMnviACkqyqPGsWk4jaPsMLxaRst5B0ZZ5449huGT8ahTLmKZhJIZmGXFpabdpo2nwcj5gkWwUDBzPrtWPH1kA7CIXXVS6BksKWNhvn2qRrAhlIRY5sxHcNr/070HtyyMJer66CI8NcPRXvqKGozbZwfoy4JpDRBhefxkuYElfJ29sCAtav2bp9T6rxhwPHK6v+FII0SNpGpWoyShg5n7jGqbgan7Hixyxjuaq/88mhSqgK4Sy6gxCE2YwW16S3Bi9jQS5WvEWIA/oZ+p+UBK1GXf7tZOHseUcqqwQl0YPX2qvimvSeaA0tSGPl09WFpFGjKS5Wf5ufZ8qfM3Sk6s+FPAkgZoF4NoFkYx8RgVa7HVRrvJaS6vCwVc9PmmbPO15pXggckl5UXJPeDH7hsnpJek9IY4eUc+QWuDD28xV5prw5i46Y8cjgSETFexNIMAPi9lKOWq2Ylhb4qjtdg2Rx"
Data "OCvHAxGqdkLVIWg5U00kWZhO617oB9ofEPoe3dRhJNU7FKyC0If2mHXv5E/enj2vb1q0iWoiCSa7zeuNeeNwtMGwkQwkyHGnohyq5t3On3OwjxPp3hSTeLViWwtyHXwA/W6YkrNkSGLoSabAqnm3Zz/54CqSo2kHo8AUkWCSwLax/R1jHRNc/tHR4TBqKLlG+BssjlL2xYp8rHqgD1fo9EpJEucz4q2O3t6JiXO9mHMTvb/2U1LtU4KrGjFddeFBvD0Rk7ju8sC3ev/L59zI3ym5xUeE0KWSha7Iz7+dN/tA39WVkiSEjujNusF9kMHBQUe/mpYMg5kUhXsAi6RV8598MoKa0s9tEEX4V2/WDO577LF994Y1vwEpvjMUPisnC8Gq+avEpBAl8sigHeO/jk/NZIC4pHBWuarPywgrTfIjUkYFf/J+WX2iRjMrVkSKLodZjSZKESlSSWzYhuXvPsfvoJmrCi/6P42d5v/ByZJPAAAAAElFTkSu"
Data "QmCC"
See next post for Bass2.bi and WinHTTP.bi!

Please compile it as console (-s console). I used my own bass.bi because built-in cannot handle x64 code.

Download source code and needed files: Radio Stations v0.61 build 2023-06-17 beta.zip (790 kb) or on my OneDrive

Happy listening Image
Last edited by UEZ on Jun 21, 2023 13:00, edited 75 times in total.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Radio Stations v0.35 build 2021-03-13 beta [Windows only]

Post by UEZ »

Readme.txt

Code: Select all

Radio Station remix.kwed.org / amigaremix.com build 2023-02-09 beta

Radio Station remix.kwed.org / amigaremix.com is a simple console app which streams music hosted on remix.kwed.org / amigaremix.com.

By default it plays songs randomly.

Keys:
* Backspace to play current song again
* Space to skip current song
* p to pause or resume current song (toggle)
* e to play current song endless (infinite loop) (toggle)
* g to enable / disable glass effect (only if DWM composition (aka Aero) is enabled) (toggle)
* t to set console window topmost or not (toggle)
* +, -, or up, down to increase / decrease volume level
* 0 to play songs randomly again
* 1 to play from latest to oldest song
* d to download current song to disk (remix.kwed.org folder in current dir)
* b to play from current song to oldest song
* f to play from current song to latest song
* right to forward song for 5 seconds
* left to rewind song for 5 seconds
* ESC or q to exit

Command-line parameter:
/?, /h or /help		-> to display this information
/NoLevel			-> disable sound level color flash
/Order [0-2]		-> plays the songs 0 = random, 1 = from latest to oldest, 2 = from oldest to latest
/Cfg [0-15]			-> set text color
/Cbg [0-15]			-> set background color
/Number [1-max]		-> plays the song hosted with the number, max is the latest song number, can be used with /Top50 or /Top40 (Amiga)
/NoAutoSwitchDevice	-> disable automatically switch over when the system's default audio device setting changes
/Proxy [address]	-> the proxy address to use (either ip adress or DNS name, e.g. /Proxy proxy-demo.com:8080)
/Glass				-> enables glass effect on console window only if DWM composition (aka Aero) is enabled
/Topmost			-> places the console window above all non-topmost windows
/Top50				-> plays the Top50 songs from first to last placed. (for Radio Station amigaremix.com please use /Top40 instead)
/Top50Dir [-1, 1]	-> if 1 (default) plays the titles ascending otherwise descending (for Radio Station amigaremix.com please use /Top40Dir instead)
					   only available when /Top50 or /Top40 is set!
/PU2R [n]           -> plays songs only ranked n or better (available only in random play mode)
					   
Examples: 
"Radio Station remix.kwed.org.exe" /cfg 7 /cbg 1 /order 1 /glass
"Radio Station remix.kwed.org.exe" /top50 /number 50 /top50dir -1

Supported operating systems: Window7+

For Windows 7 users only: 
TLS 1.1 and TLS 1.2 must be enabled to run this program properly (WinHTTP) (see Update to enable TLS 1.1 and TLS 1.2 as default secure protocols in WinHTTP in Windows -> https://support.microsoft.com/en-us/topic/update-to-enable-tls-1-1-and-tls-1-2-as-default-secure-protocols-in-winhttp-in-windows-c4bd73d2-31d7-761e-0178-11268bb10392)
Or you can set it manually to the registry:

Win7 x86:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings]
"SecureProtocols"=dword:00000a80

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp]
"DefaultSecureProtocols"=dword:00000a00

Win7 x64:
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings]
"SecureProtocols"=dword:00000a80

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings]
"SecureProtocols"=dword:00000a80

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp]
"DefaultSecureProtocols"=dword:00000a00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp]
"DefaultSecureProtocols"=dword:00000a00

Happy listening ヽ(⌐■_■)ノ♪♬
UEZ (ت)

Bass2.bi

Code: Select all

'Coded by UEZ build 2021-04-30
#Include Once "windows.bi"
#Include Once "file.bi"

Const BASS_UNICODE = &h80000000, BASS_DEVICE_ENABLED = 1, BASS_DEVICE_DEFAULT = 2, BASS_DEVICE_INIT = 4, BASS_DEVICE_LOOPBACK = 8, BASS_FILEDATA_END = 0, BASS_FILEPOS_START = 3, _
	  BASS_SAMPLE_8BITS = 1, BASS_SAMPLE_FLOAT = 256, BASS_SAMPLE_MONO = 2, BASS_SAMPLE_LOOP = 4, BASS_SAMPLE_3D = 8, BASS_SAMPLE_SOFTWARE = 16, _
	  BASS_SAMPLE_MUTEMAX = 32, BASS_SAMPLE_VAM = 64, BASS_SAMPLE_FX = 128, BASS_STREAM_PRESCAN = &h20000, BASS_STREAM_AUTOFREE = &h400001, _
	  BASS_STREAM_RESTRATE = &h800001, BASS_STREAM_BLOCK = &h100000, BASS_STREAM_DECODE = &h200000, BASS_MUSIC_RAMP = &h200, _
	  BASS_MUSIC_RAMPS = &h400, BASS_MUSIC_SURROUND = &h800, BASS_MUSIC_SURROUND2 = &h1000, BASS_MUSIC_FT2PAN = &h2000, _
	  BASS_MUSIC_FT2MOD = &h2000, BASS_MUSIC_PT1MOD = &h4000, BASS_MUSIC_NONINTER = &h10000, BASS_MUSIC_STOPBACK = &h80000, _
	  BASS_ASYNCFILE = &h40000000, BASS_CTYPE_SAMPLE = 1, BASS_CTYPE_RECORD = 2, BASS_CTYPE_STREAM = &h10000, BASS_CTYPE_STREAM_OGG = &h10002, _
	  BASS_CTYPE_STREAM_MP1 = &h10003, BASS_CTYPE_STREAM_MP2 = &h10004, BASS_CTYPE_STREAM_MP3 = &h10005, BASS_CTYPE_STREAM_AIFF = &h10006, _
	  BASS_CTYPE_STREAM_CA = &h10007, BASS_CTYPE_STREAM_MF = &h10008, BASS_CTYPE_STREAM_AM = &h10009, BASS_CTYPE_STREAM_DUMMY = &h18000, _
	  BASS_CTYPE_STREAM_DEVICE = &h18001, BASS_CTYPE_STREAM_WAV = &h40000, BASS_CTYPE_STREAM_WAV_PCM = &h50001, BASS_CTYPE_STREAM_WAV_FLOAT = &h50003, _
	  BASS_CTYPE_MUSIC_MOD = &h20000, BASS_CTYPE_MUSIC_MTM = &h20001, BASS_CTYPE_MUSIC_S3M = &h20002, BASS_CTYPE_MUSIC_XM = &h20003, _
	  BASS_CTYPE_MUSIC_IT = &h20004, BASS_CTYPE_MUSIC_MO3 = &h00100, BASS_DATA_AVAILABLE = 0, BASS_DATA_FIXED = &h20000000, _
	  BASS_DATA_FLOAT = &h40000000, BASS_DATA_FFT256 = &h80000000, BASS_DATA_FFT512 = &h80000001, BASS_DATA_FFT1024 = &h80000002, _
	  BASS_DATA_FFT2048 = &h80000003, BASS_DATA_FFT4096 = &h80000004, BASS_DATA_FFT8192 = &h80000005, BASS_DATA_FFT16384 = &h80000006, _
	  BASS_DATA_FFT32768 = &h80000007, BASS_DATA_FFT_INDIVIDUAL = &h10, BASS_DATA_FFT_NOWINDOW = &h20, BASS_DATA_FFT_REMOVEDC = &h40, _
	  BASS_DATA_FFT_COMPLEX = &h80, BASS_DATA_FFT_NYQUIST = &h100, BASS_POS_BYTE = 0, BASS_POS_MUSIC_ORDER = 1, BASS_POS_OGG = 3, _
	  BASS_ATTRIB_FREQ = 1, BASS_ATTRIB_VOL = 2, BASS_ATTRIB_PAN = 3, BASS_ATTRIB_EAXMIX = 4, BASS_ATTRIB_NOBUFFER = 5, BASS_ATTRIB_VBR = 6, _
	  BASS_ATTRIB_CPU = 7, BASS_ATTRIB_SRC = 8, BASS_ATTRIB_NET_RESUME = 9, BASS_ATTRIB_SCANINFO = 10, BASS_ATTRIB_NORAMP = 11, _
	  BASS_ATTRIB_BITRATE = 12, BASS_ATTRIB_BUFFER = 13, BASS_ATTRIB_MUSIC_AMPLIFY = &h100, BASS_ATTRIB_MUSIC_PANSEP = &h101, _
	  BASS_ATTRIB_MUSIC_PSCALER = &h102, BASS_ATTRIB_MUSIC_BPM = &h103, BASS_ATTRIB_MUSIC_SPEED = &h104, BASS_ATTRIB_MUSIC_VOL_GLOBAL = &h105, _
	  BASS_ATTRIB_MUSIC_ACTIVE = &h106, BASS_ATTRIB_MUSIC_VOL_CHAN = &h200, BASS_ATTRIB_MUSIC_VOL_INST = &h300, BASS_MUSIC_PRESCAN = BASS_STREAM_PRESCAN, _
	  BASS_LEVEL_STEREO = 2, BASS_FILEPOS_CURRENT = 0, BASS_FILEPOS_DECODE = BASS_FILEPOS_CURRENT, BASS_FILEPOS_DOWNLOAD = 1, BASS_FILEPOS_END = 2, _
	  BASS_FILEPOS_START = 3, BASS_FILEPOS_CONNECTED = 4, BASS_FILEPOS_BUFFER = 5, BASS_FILEPOS_SOCKET = 6, BASS_FILEPOS_ASYNCBUF = 7, BASS_FILEPOS_SIZE = 8, _
	  BASS_FILEPOS_BUFFERING = 9, BASS_TAG_ID3 = 0, BASS_TAG_ID3V2 = 1, BASS_TAG_OGG = 2, BASS_TAG_HTTP = 3, BASS_TAG_ICY = 4, BASS_TAG_META = 5, _
	  BASS_TAG_APE = 6, BASS_TAG_MP4 = 7, BASS_TAG_WMA = 8, BASS_TAG_VENDOR = 9, BASS_TAG_LYRICS3 = 10, BASS_TAG_CA_CODEC = 11, BASS_TAG_MF = 13, _
	  BASS_TAG_WAVEFORMAT = 14, BASS_TAG_AM_MIME = 15, BASS_TAG_AM_NAME = 16, BASS_TAG_RIFF_INFO = &h100, BASS_TAG_RIFF_BEXT = &h101, _
	  BASS_TAG_RIFF_CART = &h102, BASS_TAG_RIFF_DISP = &h103, BASS_TAG_RIFF_CUE = &h104, BASS_TAG_RIFF_SMPL = &h105, BASS_TAG_APE_BINARY = &h1000, _
	  BASS_TAG_MUSIC_NAME = &h10000, BASS_TAG_MUSIC_MESSAGE = &h10001, BASS_TAG_MUSIC_ORDERS = &h10002, BASS_TAG_MUSIC_AUTH = &h10003, _
	  BASS_TAG_MUSIC_INST = &h10100, BASS_TAG_MUSIC_SAMPLE = &h10300, BASS_POS_SCAN	= &h40000000, BASS_LEVEL_MONO = 1, BASS_LEVEL_STEREO = 2, BASS_LEVEL_RMS = 4, _
	  BASS_LEVEL_VOLPAN = 8, BASS_CONFIG_DEV_DEFAULT = 36

Type HSTREAM As DWORD
Type HPLUGIN As DWORD
Type HSAMPLE As DWORD
Type HMUSIC As DWORD
Type QWORD As Longint

Type BASS_DEVICEINFO
	As Zstring Ptr Name, driver
	As DWORD flags
End Type

Type BASS_CHANNELINFO
	As DWORD freq, chans, flags, ctype, origres
	As HPLUGIN plugin
	As HSAMPLE sample
	As Zstring Ptr filename
End Type

Type BASS_INFO
	As DWORD flags, hwsize, hwfree, freesam, free3d, minrate, maxrate
	As BOOL eax
	As DWORD minbuf, dsver, latency, initflags, speakers, freq
end type

Type BASS_LEVELS
	As Single Left, Right
End Type

Type ID3v1
	As Ubyte id(3), title(30), artist(30), album(30), Year(4), comment(30), genre
End Type


Dim Shared BASS_Init As Function Stdcall(Byval As Long, Byval As DWORD, Byval As DWORD, Byval As HWND, Byval As GUID Ptr) As BOOL
Dim Shared BASS_GetDeviceInfo As Function Stdcall(As DWORD, As BASS_DEVICEINFO Ptr) As BOOL
Dim Shared BASS_GetInfo As Function Stdcall(As BASS_INFO) As BOOL
Dim Shared BASS_GetDevice As Function Stdcall() As DWORD
Dim Shared BASS_Free As Function Stdcall() As BOOL
Dim Shared BASS_Stop As Function Stdcall() As BOOL
Dim Shared BASS_SetVolume As Function Stdcall(Byval As Single) As BOOL
Dim Shared BASS_SetDevice As Function Stdcall(Byval As DWORD) As BOOL
Dim Shared BASS_SetConfig As Function Stdcall(Byval As DWORD, Byval As DWORD) As BOOL
Dim Shared BASS_ErrorGetCode As Function Stdcall() As Integer
Dim Shared BASS_StreamGetFilePosition As Function Stdcall(Byval As HSTREAM, As DWORD) As QWORD
Dim Shared BASS_StreamCreateFile As Function Stdcall(Byval As BOOL, Byval As Any Ptr, Byval As QWORD, Byval As QWORD, Byval As DWORD) As HSTREAM
Dim Shared BASS_StreamCreateURL As Function Stdcall(Byval As Any Ptr, Byval As DWORD, Byval As DWORD, Byval As Any Ptr, Byval As Any Ptr) As HSTREAM
Dim Shared BASS_StreamFree As Function Stdcall(Byval As HSTREAM) As BOOL
Dim Shared BASS_ChannelPlay As Function Stdcall(Byval As DWORD, Byval As BOOL) As BOOL
Dim Shared BASS_ChannelStop As Function Stdcall(Byval As DWORD) As BOOL
Dim Shared BASS_ChannelPause As Function Stdcall(Byval As DWORD) As BOOL
Dim Shared BASS_ChannelGetInfo As Function Stdcall(Byval As DWORD, Byval As BASS_CHANNELINFO) As BOOL
Dim Shared BASS_ChannelGetData As Function Stdcall(Byval As DWORD, Byval As Any Ptr, Byval As DWORD) As DWORD
Dim Shared BASS_ChannelGetLevel As Function Stdcall(Byval As DWORD) As DWORD
Dim Shared BASS_ChannelGetLevelEx As Function Stdcall(Byval As DWORD, Byval As Any Ptr, Byval As Single, Byval As DWORD) As BOOL
Dim Shared BASS_ChannelGetPosition As Function Stdcall(Byval As DWORD, Byval As DWORD) As DWORD
Dim Shared BASS_ChannelGetLength As Function Stdcall(Byval As DWORD, Byval As DWORD) As QWORD
Dim Shared BASS_ChannelGetTags As Function Stdcall(Byval As DWORD, Byval As DWORD) As Zstring Ptr
Dim Shared BASS_ChannelGetAttribute As Function Stdcall(Byval As DWORD, Byval As DWORD, Byval As Any Ptr) As BOOL
Dim Shared BASS_ChannelGetDevice As Function Stdcall(Byval As DWORD) As DWORD
Dim Shared BASS_ChannelBytes2Seconds As Function Stdcall(Byval As DWORD, Byval As QWORD) As Double
Dim Shared BASS_ChannelSeconds2Bytes As Function Stdcall(Byval As DWORD, Byval As Double) As QWORD
Dim Shared BASS_ChannelSetAttribute As Function Stdcall(Byval As DWORD, Byval As DWORD, Byval As Single) As BOOL
Dim Shared BASS_ChannelSetPosition As Function Stdcall(Byval As DWORD, Byval As QWORD, Byval As DWORD) As BOOL
Dim Shared BASS_ChannelSetDevice As Function Stdcall(Byval As DWORD, Byval As DWORD) As BOOL
Dim Shared BASS_MusicLoad As Function Stdcall(Byval As BOOL, Byval As Any Ptr, Byval As QWORD, Byval As DWORD, Byval As DWORD, Byval As DWORD) As HMUSIC
Dim Shared BASS_MusicFree As Function Stdcall(Byval As HMUSIC) As BOOL


Dim Shared As Any Ptr _g__hLib_Bass = 0
Dim Shared As BOOL _g__bSound = True

'Init-------------------------------------------------------------------------------------------------------------------------------------------
Function _Bass_Startup(sFolderDLL As String = Curdir) As BOOL
	#Ifdef __Fb_64bit__
		'? "Loading Bass64.dll"
		If Fileexists(sFolderDLL & "\Bass64.dll") = 0 Then
			_g__bSound = False
			Return False
		Else
			_g__hLib_Bass = Dylibload(sFolderDLL & "\Bass64.dll")
		Endif
	#Else
		'? "Loading Bass.dll"
		If Fileexists(sFolderDLL & "\Bass.dll") = 0 Then
			_g__bSound = False
			Return False
		Else
			_g__hLib_Bass = Dylibload(sFolderDLL & "\Bass.dll")
		Endif
	#Endif
	BASS_Init = Dylibsymbol(_g__hLib_Bass, "BASS_Init")
	If BASS_Init = 0 Then Return False
	BASS_Free = Dylibsymbol(_g__hLib_Bass, "BASS_Free")
	If BASS_Free = 0 Then Return False
	BASS_StreamCreateFile = Dylibsymbol(_g__hLib_Bass, "BASS_StreamCreateFile")
	If BASS_StreamCreateFile = 0 Then Return False
	BASS_StreamCreateURL = Dylibsymbol(_g__hLib_Bass, "BASS_StreamCreateURL")
	If BASS_StreamCreateURL = 0 Then Return False	
	BASS_StreamFree = Dylibsymbol(_g__hLib_Bass, "BASS_StreamFree")
	If BASS_StreamFree = 0 Then Return False
	BASS_ChannelPlay = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelPlay")
	If BASS_ChannelPlay = 0 Then Return False
	BASS_ChannelStop = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelStop")
	If BASS_ChannelStop = 0 Then Return False
	BASS_Stop = Dylibsymbol(_g__hLib_Bass, "BASS_Stop")
	If BASS_Stop = 0 Then Return False
	BASS_SetVolume = Dylibsymbol(_g__hLib_Bass, "BASS_SetVolume")
	If BASS_SetVolume = 0 Then Return False
	BASS_SetDevice = Dylibsymbol(_g__hLib_Bass, "BASS_SetDevice")
	If BASS_SetDevice = 0 Then Return False
	BASS_SetConfig = Dylibsymbol(_g__hLib_Bass, "BASS_SetConfig")
	If BASS_SetConfig = 0 Then Return False
	BASS_ErrorGetCode = Dylibsymbol(_g__hLib_Bass, "BASS_ErrorGetCode")
	If BASS_ErrorGetCode = 0 Then Return False
	BASS_GetDeviceInfo = Dylibsymbol(_g__hLib_Bass, "BASS_GetDeviceInfo")
	If BASS_GetDeviceInfo = 0 Then Return False
	BASS_GetDevice = Dylibsymbol(_g__hLib_Bass, "BASS_GetDevice")
	If BASS_GetDevice = 0 Then Return False	
	BASS_StreamGetFilePosition = Dylibsymbol(_g__hLib_Bass, "BASS_StreamGetFilePosition")
	If BASS_StreamGetFilePosition = 0 Then Return False
	BASS_GetInfo = Dylibsymbol(_g__hLib_Bass, "BASS_GetInfo")
	If BASS_GetInfo = 0 Then Return False
	BASS_ChannelGetInfo = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelGetInfo")
	If BASS_ChannelGetInfo = 0 Then Return False
	BASS_ChannelGetData = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelGetData")
	If BASS_ChannelGetData = 0 Then Return False
	BASS_ChannelGetLevel = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelGetLevel")
	If BASS_ChannelGetLevel = 0 Then Return False	
	BASS_ChannelGetLevelEx = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelGetLevelEx")
	If BASS_ChannelGetLevelEx = 0 Then Return False
	BASS_ChannelGetPosition = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelGetPosition")
	If BASS_ChannelGetPosition = 0 Then Return False
	BASS_ChannelPause = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelPause")
	If BASS_ChannelPause = 0 Then Return False
	BASS_ChannelGetLength = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelGetLength")
	If BASS_ChannelGetLength = 0 Then Return False		
	BASS_ChannelGetTags = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelGetTags")
	If BASS_ChannelGetTags = 0 Then Return False		
	BASS_ChannelGetAttribute = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelGetAttribute")
	If BASS_ChannelGetAttribute = 0 Then Return False
	BASS_ChannelGetDevice = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelGetDevice")
	If BASS_ChannelGetDevice = 0 Then Return False	
	BASS_ChannelBytes2Seconds = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelBytes2Seconds")
	If BASS_ChannelBytes2Seconds = 0 Then Return False
	BASS_ChannelSeconds2Bytes = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelSeconds2Bytes")
	If BASS_ChannelSeconds2Bytes = 0 Then Return False
	BASS_ChannelSetAttribute = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelSetAttribute")
	If BASS_ChannelSetAttribute = 0 Then Return False	
	BASS_ChannelSetPosition = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelSetPosition")
	If BASS_ChannelSetPosition = 0 Then Return False
	BASS_ChannelSetDevice = Dylibsymbol(_g__hLib_Bass, "BASS_ChannelSetDevice")
	If BASS_ChannelSetDevice = 0 Then Return False
	BASS_MusicLoad = Dylibsymbol(_g__hLib_Bass, "BASS_MusicLoad")
	If BASS_MusicLoad = 0 Then Return False
	BASS_MusicFree = Dylibsymbol(_g__hLib_Bass, "BASS_MusicFree")
	If BASS_MusicFree = 0 Then Return False	
	Return True
End Function

Function _Bass_Shutdown() As BOOL
	If _g__hLib_Bass > 0 Then 
		Dylibfree(_g__hLib_Bass)
		Return True
	End If
	Return False
 End Function

Function _BASS_ErrorGetCode() As String
	Select Case BASS_ErrorGetCode()
		Case 0 : Return "No Error."
		Case 1 : Return "There Is insufficient memory."
		Case 2 : Return "The file could Not be opened."
		Case 3 : Return "Cannot find a free sound driver."
		Case 4 : Return "The sample buffer was lost."
		Case 5 : Return "Invalid handle."
		Case 6 : Return "Unsupported sample Format."
		Case 7 : Return "Invalid position."
		Case 8 : Return "BASS_Init has Not been successfully called."
		Case 9 : Return "BASS_Start has Not been successfully called."
		Case 10 : Return "SSL/HTTPS support Is Not available."
		Case 14 : Return "Already initialized/paused/whatever."
		Case 17 : Return "The file does Not contain audio, Or it also contains video And videos are disabled."
		Case 18 : Return "Cannot Get a free channel."
		Case 19 : Return "An illegal Type was specified."
		Case 20 : Return "An illegal parameter was specified."
		Case 21 : Return "Could Not initialize 3D support."
		Case 22 : Return "No EAX support."
		Case 23 : Return "Illegal device number."
		Case 24 : Return "Not playing."
		Case 25 : Return "Illegal sample rate."
		Case 27 : Return "The stream Is Not a file stream."
		Case 29 : Return "No hardware voices available."
		Case 31 : Return "The Mod music has no sequence Data."
		Case 32 : Return "No internet connection could be opened."
		Case 33 : Return "Could Not create the file."
		Case 34 : Return "Effects are Not available."
		Case 37 : Return "Requested Data Is Not available."
		Case 38 : Return "The channel Is a decoding channel"
		Case 39 : Return "A sufficient DirectX version Is Not installed."
		Case 40 : Return "Connection timed Out."
		Case 41 : Return "The file's Format Is Not recognised/supported."
		Case 42 : Return "The specified SPEAKER flags are invalid."
		Case 43 : Return "The plugin requires a different BASS version."
		Case 44 : Return "Codec Is Not available/supported."
		Case 45 : Return "The channel/file has ended."
		Case 46 : Return "Something Else has exclusive use of the device."
		Case 47 : Return "The file cannot be streamed Using the buffered file System."
		Case -1 : Return "Some other mystery problem!"
	End Select
	Return "Hmmmm."
End Function

Function _Bass_Init(Device As DWORD = -1, Freq As Dword = 44100, Flags As Dword = 0, Win As HWND = Null, clsid As GUID Ptr = Null) As BOOL
	Return BASS_Init(Device, Freq, Flags, Win, clsid)
End Function

Function _Bass_Free() As BOOL
	Return BASS_Free()
End Function

Function _Bass_Stop() As BOOL
	Return BASS_Stop()
End Function

Function _BASS_SetVolume(Volume As Single) As BOOL
	Return BASS_SetVolume(Iif(Volume < 0, 0, Iif(Volume > 1.0, 1.0, Volume)))
End Function

Function _BASS_SetDevice(Device As DWORD) As BOOL
	Return BASS_SetDevice(Device)
End Function

Function _BASS_SetConfig(Device As DWORD, Value As DWORD) As BOOL
	Return BASS_SetConfig(Device, Value)
End Function

'Device-----------------------------------------------------------------------------------------------------------------------------------------
Function _BASS_GetInfo(bi As BASS_INFO) As BOOL
	Return BASS_GetInfo(bi)
End Function

Function _BASS_GetDevice() As DWORD
	Return BASS_GetDevice()
End Function

Function _BASS_GetDeviceInfo(Device As DWORD, Info As BASS_DEVICEINFO Ptr) As BOOL
	Return BASS_GetDeviceInfo(Device, Info)
End Function

'Stream-----------------------------------------------------------------------------------------------------------------------------------------
Function _BASS_StreamFree(hStream As HSTREAM) As BOOL
	Return BASS_StreamFree(hStream)
End Function

Function _BASS_StreamCreateFile(File As String, Flags As Dword = 0, offset As QWORD = 0, Length As QWORD = 0, Mem As BOOL = False) As HSTREAM
	Return BASS_StreamCreateFile(Mem, Strptr(File), offset, Length, Flags)
End Function

Function _BASS_StreamCreateURL(URL As String, Offset As Dword = 0, Flags As Dword = 0, Proc As Any Ptr = 0, UsrProc As Any Ptr = 0) As HSTREAM
	Return BASS_StreamCreateURL(Strptr(URL), offset, Flags, Proc, UsrProc)
End Function

Function _BASS_StreamCreateMem(pMem As Any Ptr, Length As QWORD = 0, Flags As Dword = 0, offset As QWORD = 0, Mem As BOOL = True) As HSTREAM
	Return BASS_StreamCreateFile(Mem, pMem, offset, Length, Flags Or BASS_UNICODE)
End Function

Function _BASS_StreamGetFilePosition(hStream As HSTREAM, Mode As Dword) As QWORD
	Return BASS_StreamGetFilePosition(hStream, Mode)
End Function

'Music------------------------------------------------------------------------------------------------------------------------------------------
Function _BASS_MusicLoad(File As String, Flags As DWORD = 0, Freq As DWORD = 0, offset As QWORD = 0, Length As DWORD = 0, Mem As BOOL = False) As HMUSIC
	Return BASS_MusicLoad(Mem, Strptr(File), offset, Length, Flags, Freq)
End Function

Function _BASS_MusicLoadMem(pMem As Any Ptr, Flags As DWORD = 0, Freq As DWORD = 0, offset As QWORD = 0, Length As DWORD = 0, Mem As BOOL = True) As HMUSIC
	Return BASS_MusicLoad(Mem, pMem, offset, Length, Flags, Freq)
End Function

Function _BASS_MusicFree(Handle As HMUSIC) As BOOL
	Return BASS_MusicFree(Handle) 
End Function

'Channel----------------------------------------------------------------------------------------------------------------------------------------
Function _BASS_ChannelPlay(Handle As DWORD, Restart As BOOL = True) As BOOL
	Return BASS_ChannelPlay(Handle, Restart)
End Function

Function _BASS_ChannelStop(Handle As DWORD) As BOOL
	Return BASS_ChannelStop(Handle)
End Function

Function _BASS_ChannelPause(Handle As DWORD) As BOOL
	Return BASS_ChannelPause(Handle)
End Function

Function _BASS_ChannelGetInfo(Handle As DWORD, ChanInfo As BASS_CHANNELINFO) As BOOL
	Return BASS_ChannelGetInfo(Handle, ChanInfo)
End Function

Function _BASS_ChannelGetData(Handle As DWORD, Buffer As Any Ptr, Length As DWORD) As DWORD
	Return BASS_ChannelGetData(Handle, Buffer, Length)
End Function

Function _BASS_ChannelGetLevel(Handle As DWORD) As DWORD
	Return BASS_ChannelGetLevel(Handle) 
End Function

Function _BASS_ChannelGetLevelEx(Handle As DWORD, Byref levels As BASS_LEVELS, length As Single = 0.05, Flags As DWORD = BASS_LEVEL_STEREO) As BOOL
	Return BASS_ChannelGetLevelEx(Handle, @levels, length, Flags) 
End Function

Function _BASS_ChannelGetPosition(Handle As DWORD, Mode As DWORD) As QWORD
	Return BASS_ChannelGetPosition(Handle, Mode) 
End Function

Function _BASS_ChannelGetLength(Handle As DWORD, Mode As DWORD = BASS_POS_BYTE) As QWORD
	Return BASS_ChannelGetLength(Handle, Mode) 
End Function

Function _BASS_ChannelGetAttribute(Handle As DWORD, Byref Value As Single, Attrib As DWORD = BASS_ATTRIB_BITRATE) As BOOL
	Return BASS_ChannelGetAttribute(Handle, Attrib, @Value) 
End Function

Function _BASS_ChannelBytes2Seconds(Handle As DWORD, Position As QWORD) As Double
	Return BASS_ChannelBytes2Seconds(Handle, Position) 
End Function

Function _BASS_ChannelSeconds2Bytes(Handle As DWORD, Position As Double) As QWORD
	Return BASS_ChannelSeconds2Bytes(Handle, Position)
End Function

Function _BASS_ChannelSetAttribute(Handle As DWORD, Attrib As DWORD, Value As Single) As BOOL
	Return BASS_ChannelSetAttribute(Handle, Attrib, Value) 
End Function

Function _BASS_ChannelSetDevice(Handle As DWORD, Device As DWORD) As BOOL
	Return _BASS_ChannelSetDevice(Handle, Device) 
End Function

Function _BASS_ChannelSetPosition(Handle As DWORD, Position As QWORD, Mode As DWORD) As BOOL
	Return BASS_ChannelSetPosition(Handle, Position, Mode) 
End Function

Function _BASS_ChannelGetTags(Handle As DWORD, Tags As DWORD) As Any Ptr
	Return BASS_ChannelGetTags(Handle, Tags) 
End Function
'-----------------------------------------------------------------------------------------------------------------------------------------------
WinHTTP.bi

Code: Select all

'Ported from WinHTTP.au3 by trancexx to FB by UEZ
'Build 2021-03-22 Beta

#Include Once "windows.bi"

Type HINTERNET As LPVOID

#Ifndef CRLF
	#Define CRLF	Chr(10, 13)
#Endif

Const WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0, WINHTTP_ACCESS_TYPE_NO_PROXY = 1, WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3, WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY = 4, WINHTTP_FLAG_ESCAPE_DISABLE = &h00000040, _
	  INTERNET_DEFAULT_HTTPS_PORT = 443, INTERNET_DEFAULT_HTTP_PORT = 80, INTERNET_DEFAULT_PORT = 0, WINHTTP_NO_PROXY_NAME = "", WINHTTP_NO_PROXY_BYPASS = "", WINHTTP_NO_REFERER = "", _
	  WINHTTP_DEFAULT_ACCEPT_TYPES = 0, WINHTTP_FLAG_SECURE = &h00800000, WINHTTP_NO_ADDITIONAL_HEADERS = "", WINHTTP_NO_REQUEST_DATA = 0, WINHTTP_CALLBACK_STATUS_REDIRECT = &h00004000

Dim Shared As Any Ptr __hWinHTTPLib = 0
Dim Shared WinHttpOpen As Function(sUserAgent As LPCWSTR, iAccessType As Long, sProxyName As LPCWSTR, sProxyBypass As LPCWSTR, iFlag As Long) As HINTERNET
Dim Shared WinHttpCloseHandle As Function(__hWinHTTPLib As Any Ptr) As Boolean
Dim Shared WinHttpConnect As Function(hSession As HINTERNET, sServerName As LPCWSTR, iServerPort As Long, Reserved As DWORD) As HINTERNET
Dim Shared WinHttpOpenRequest As Function(hConnect As HINTERNET, sVerb As LPCWSTR, sObjectName As LPCWSTR, sVersion As LPCWSTR, sReferrer As LPCWSTR, pAcceptTypes As Any Ptr, iFlags As Long) As HINTERNET
Dim Shared WinHttpSendRequest As Function(hInternet As HINTERNET, sHeader As LPCWSTR, iHeadersLength As Long, pOptionalBuff As HINTERNET, iOptionalLength As Long, iTotalLength As Long, pContext As DWORD_PTR) As Boolean
Dim Shared WinHttpReceiveResponse As Function(hInternet As HINTERNET, iReserved As LPVOID) As Boolean
Dim Shared WinHttpReadData As Function(hRequest As HINTERNET, pBuffer As LPVOID, iNumberOfBytesToRead As Long, pNumberOfBytesRead As LPDWORD) As Boolean
Dim Shared WinHttpQueryDataAvailable As Function(hRequest As HINTERNET, pNumberOfBytesAvailable As LPDWORD) As Boolean
Dim Shared WinHttpSetTimeouts As Function(hInternet As HINTERNET, iResolveTimeout As Integer, iConnectTimeout As Integer, iSendTimeout As Integer, iReceiveTimeout As Integer) As Boolean
Dim Shared WinHttpCheckPlatform As Function() As Boolean
Dim Shared WinHttpSetStatusCallback As Function(hConnect As HINTERNET, lpfnInternetCallback as Any Ptr, dwNotificationFlags as DWORD, dwReserved as DWORD_PTR) As any Ptr


Function _WinHttpStartup() As Boolean
	__hWinHTTPLib = Dylibload("Winhttp.dll")
	If __hWinHTTPLib = 0 Then Return False
	WinHttpOpen = Dylibsymbol(__hWinHTTPLib, "WinHttpOpen")
	WinHttpCloseHandle = Dylibsymbol(__hWinHTTPLib, "WinHttpCloseHandle")
	WinHttpConnect = Dylibsymbol(__hWinHTTPLib, "WinHttpConnect")
	WinHttpOpenRequest = Dylibsymbol(__hWinHTTPLib, "WinHttpOpenRequest")
	WinHttpSendRequest = Dylibsymbol(__hWinHTTPLib, "WinHttpSendRequest")
	WinHttpReceiveResponse = Dylibsymbol(__hWinHTTPLib, "WinHttpReceiveResponse")
	WinHttpReadData = Dylibsymbol(__hWinHTTPLib, "WinHttpReadData")
	WinHttpQueryDataAvailable = Dylibsymbol(__hWinHTTPLib, "WinHttpQueryDataAvailable")
	WinHttpSetTimeouts = Dylibsymbol(__hWinHTTPLib, "WinHttpSetTimeouts")
	WinHttpCheckPlatform = Dylibsymbol(__hWinHTTPLib, "WinHttpCheckPlatform")
	WinHttpSetStatusCallback = Dylibsymbol(__hWinHTTPLib, "WinHttpSetStatusCallback")
	Return WinHttpCheckPlatform()
End Function

Function _WinHttpShutdown() As Boolean
	If __hWinHTTPLib Then 
		Dylibfree(__hWinHTTPLib)
		Return True
	Endif
	Return False
End Function

Function _WinHttpOpen(iAccessType As Long = WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, sUserAgent As String = "FB_WinHTTP/1.0", sProxyName As String = WINHTTP_NO_PROXY_NAME, sProxyBypass As String = WINHTTP_NO_PROXY_BYPASS, iFlag As Long = 0) As HINTERNET
	If __hWinHTTPLib = 0 Then Return 0
	Return WinHttpOpen(Wstr(sUserAgent), iAccessType, Wstr(sProxyName), Wstr(sProxyBypass), iFlag)
End Function

Function _WinHttpCloseHandle(__hInternet As Any Ptr = __hWinHTTPLib) As Boolean
	If __hInternet = 0 Then Return False
	Return WinHttpCloseHandle(__hInternet)
End Function

Function _WinHttpConnect(hSession As HINTERNET, sServerName As String, iServerPort As Long = INTERNET_DEFAULT_PORT) As HINTERNET
	If hSession = 0 Then Return 0
	Return WinHttpConnect(hSession, Wstr(sServerName), iServerPort, 0)	
End Function

Function _WinHttpOpenRequest(hConnect As HINTERNET, sVerb As String = "GET", sObjectName As String = "", sVersion As String = "HTTP/1.1", sReferrer As String = WINHTTP_NO_REFERER, pAcceptTypes As Any Ptr = WINHTTP_DEFAULT_ACCEPT_TYPES, iFlags As Long = WINHTTP_FLAG_ESCAPE_DISABLE) As HINTERNET
	If hConnect = 0 Then Return 0
	Return WinHttpOpenRequest(hConnect, Wstr(Ucase(sVerb)), Wstr(sObjectName), Wstr(Ucase(sVersion)), Wstr(sReferrer), pAcceptTypes, iFlags)
End Function

Function _WinHttpQueryDataAvailable(hRequest As HINTERNET, Byref pNumberOfBytesAvailable As LPDWORD = NULL) As Ulong
	If hRequest = 0 Then Return 0
	Return WinHttpQueryDataAvailable(hRequest, pNumberOfBytesAvailable)
End Function

Function _WinHttpReadData(hRequest As HINTERNET, iNumberOfBytesToRead As Uinteger = 8192) As String
	If hRequest = 0 Then Return ""
	Dim As Ulong iNumberOfBytesRead = 0, i
	Dim As Ubyte aBuffer(iNumberOfBytesToRead)
	WinHttpReadData(hRequest, @aBuffer(0), iNumberOfBytesToRead, @iNumberOfBytesRead)
	If iNumberOfBytesRead = 0 Then Return ""
	Dim As String sHTML
	For i = 0 To iNumberOfBytesRead
		sHTML &= Chr(aBuffer(i))
	Next
	Return sHTML
End Function

Function _WinHttpReceiveResponse(hRequest As HINTERNET) As Boolean
	If hRequest = 0 Then Return False
	Dim as Boolean iResult = WinHttpReceiveResponse(hRequest, 0)
	If iResult = False Then ? "Error " & GetLastError() & " in function _WinHttpReceiveResponse!"
	Return iResult
End Function

Function _WinHttpSendRequest(hRequest As HINTERNET, sHeaders As String = WINHTTP_NO_ADDITIONAL_HEADERS, pOptional As LPVOID = WINHTTP_NO_REQUEST_DATA, iOptionalLength as DWORD = 0, iTotalLength As DWORD = 0, pContext As DWORD_PTR = 0) As Boolean
	If hRequest = 0 Then Return False
	Dim as Boolean iResult = WinHttpSendRequest(hRequest, Wstr(sHeaders), 0, pOptional, iOptionalLength, iTotalLength, pContext)
	If iResult = False Then ? "Error " & GetLastError() & " in function _WinHttpSendRequest!"
	Return iResult
End Function

Function _WinHttpSimpleReadData(hRequest As HINTERNET) As String
	If hRequest = 0 Then Return ""
	If _WinHttpQueryDataAvailable(hRequest) > 0 Then
		Dim As String sData, d
		Do
			d = _WinHttpReadData(hRequest)
			If d = "" Then Exit Do
			sData &= d
		Loop Until False
		Return sData
	End If
	Return ""
End Function

Function _WinHttpSimpleSendRequest(hConnect As HINTERNET, sPath As String = "", sType As String = "GET", sReferrer As String = WINHTTP_NO_REFERER, pData As LPVOID = WINHTTP_NO_REQUEST_DATA, sHeader As String = WINHTTP_NO_ADDITIONAL_HEADERS) As HINTERNET
	If hConnect = 0 Then Return 0
	Dim As HINTERNET hRequest = _WinHttpOpenRequest(hConnect, Ucase(sType), sPath, "HTTP/1.1", sReferrer)
	If hRequest = 0 Then Return 0
	If sType = Ucase("POST") And sHeader = WINHTTP_NO_ADDITIONAL_HEADERS Then sHeader = "Content-Type: application/x-www-form-urlencoded" & CRLF
	If _WinHttpSendRequest(hRequest, sHeader, pData) = False Then Return 0
	If _WinHttpReceiveResponse(hRequest) = False Then Return 0
	Return hRequest
End Function

Function _WinHttpSetStatusCallback(hConnect As HINTERNET, pCallback as Any Ptr, NotificationFlags as Dword) as Any Ptr
	If hConnect = 0 Then Return False
	Return WinHttpSetStatusCallback(hConnect, pCallback, NotificationFlags, 0)
End function
Last edited by UEZ on Feb 11, 2023 16:43, edited 7 times in total.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Radio Stations v0.35 build 2021-03-13 beta [Windows only]

Post by UEZ »

Found the issue with Windows 7

TLS 1.1 and TLS 1.2 must be enabled to run this program (WinHTTP) properly (see Update to enable TLS 1.1 and TLS 1.2 as default secure protocols in WinHTTP in Windows)

Thanks for the German Autoit community for helping me to troubleshoot this proggy. Image
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Radio Stations v0.35 build 2021-03-13 beta [Windows only]

Post by dodicat »

Hi UEZ.
I am having difficulty in getting libpcre.a.
I have googled around without much luck.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Radio Stations v0.35 build 2021-03-13 beta [Windows only]

Post by UEZ »

dodicat wrote:Hi UEZ.
I am having difficulty in getting libpcre.a.
I have googled around without much luck.
Thanks for testing but pcre is not required anymore. Anyhow, here you can download it -> viewtopic.php?f=17&t=19095&start=495#p278794

For running PCRE as x86 you need additionally libpcre-1.dll, x64 has no dependencies. Maybe St_W can have a look and compile it accordingly.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Radio Stations v0.45 build 2021-03-25 beta [Windows only]

Post by UEZ »

Update to v0.45: beside some internal changes I added the feature to download current song by pressing 'd' key.

Check out my 1st post for download / source code.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Radio Stations v0.50 build 2021-04-26 beta [Windows only]

Post by UEZ »

Update to v0.50 build 2021-04-26 beta. See 1st post for code and download link.

Some bugs were fixed and added some command line features. I reached the 600000 character limit in the 1st post and removed the keys / command-line parameters information.

"Radio Station remix.kwed.org.exe" /help:

Radio Station remix.kwed.org v0.61 build 2023-02-09 beta

Radio Station remix.kwed.org is a simple console app that streams music from remix.kwed.org

By default it plays songs randomly.

Keys:
* Backspace to play current song again
* Space to skip current song
* p to pause or resume current song (toggle)
* e to play current song endless (infinite loop) (toggle)
* g to enable / disable glass effect (only if DWM composition (aka Aero) is enabled) (toggle)
* t to set console window topmost or not (toggle)
* +, -, or up, down to increase / decrease volume level
* 0 to play songs randomly again
* 1 to play from latest to oldest song
* d to download current song to disk (remix.kwed.org folder in current dir)
* b to play from current song to oldest song
* f to play from current song to latest song
* right to forward song for 5 seconds
* left to rewind song for 5 seconds
* ESC or q to exit

Command-line parameter:
/NoLevel -> disable sound level color flash
/Order [0-2] -> plays the songs 0 = random, 1 = from latest to oldest, 2 = from oldest to latest
/Cfg [0-15] -> set text color
/Cbg [0-15] -> set background color
/Number [1-max] -> plays the song hosted with the number, max is the latest song number,
can be used with /Top50
/NoAutoSwitchDevice -> disable automatically switch over when the system's default audio device
setting changes
/Proxy [address] -> the proxy address to use (either ip adress or DNS name)
/Glass -> enables glass effect on console window only if DWM composition (aka Aero) is enabled
/Topmost -> places the console window above all non-topmost windows
/Top50 -> plays the Top50 songs from first to last placed
/Top50Dir [-1, 1] -> if 1 (default) plays the titles ascending otherwise descending
only available when /Top50 is set!
/PU2R [n] -> plays songs only ranked n or better (available only in random play mode)

Examples:
"Radio Station remix.kwed.org.exe" /cfg 7 /cbg 1 /order 1 /glass
"Radio Station remix.kwed.org.exe" /top50 /number 50 /top50dir -1

Happy listening ヽ(⌐■_■)ノ♪♬
Last edited by UEZ on Feb 11, 2023 16:44, edited 2 times in total.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Radio Stations v0.61 build 2023-02-09 beta [Windows only]

Post by UEZ »

Updated to Radio Stations v0.61 build 2023-02-09 beta.
  • some bugs fixed
See first post for download option.
Post Reply