Bass Library Documentation

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Janusz
Posts: 89
Joined: 18 Dec 2020, 17:47

Re: Bass Library Documentation

Post by Janusz » 22 Mar 2021, 11:12

Dear specialists,
I would like to kindly ask you, if is it possible to use downloadproc callback to record live Internet stream which is being actually plaied by bass.dll. This callback downloadproc should return a special byte buffer, it is necessary to specify its syze and other variable should return every byte of Internet live stream. But The question is, if Autohotkey can be used for this task, if developer is not being forced to use some WIN32 API calls related to copy or read from memory. Because I do not know, if Autohotkey buil in commands to write file can be used to write special buffer, which downloadproc callback uses. If some advanced is 100 % sure, that it is impossible to use this callback in conjunction with file operation to write bytes to The file from Autohotkey, what about experimenting with special APi functions from kernel32.dll. Sure, I would rather not try to use special APi calls to manipulate with file handlers and write data to files, it is really good for experts to use those low level APi calls. But there are some functions for working with memory. Or do you think, that fortunately, it is possible to use downloadproc callback without such issues?
Author of streambar player has helped Me a lot thanks to his code. But The following bass function declaration

Code: Select all

hStream := DllCall("bass.dll\BASS_StreamCreateURL", "Str","","UInt", 0, "UInt", A_IsUnicode ? BASS_UNICODE := 0x80000000 : 0, Ptr", 0, "Ptr", 0, "UInt")
do not contain downloadproc argument.
Does somebody of us would have A good will to find A solution how to use downloadproc callback with autohotkey?
I Am even ready to debug some experiment based on using Kernel32.dll or other Windows API calls if it would be necessary.

I AM guessing that downloadproc can be used only after I will execute

Code: Select all

DllCall("bass.dll\BASS_ChannelPlay", "UInt", hStream, "Int", 0)   
;
I want to develop freeware Internet radio player for severely physically impaired woman who do not see at all. Because she is suffering of severe motoric issues, todays Internet radio players based on buttons and many TAB presses or arrow keys presses are not good for her. This is The reason why I AM using excellent Autohotkey to develop a new player for her. AIM of my attempt is to base my work only on up or down arrow keys or only one letter combination. By other words, GUI should be usable by only using one finger and not many TAB presses. Simplicity and usability.
I have achieved this goal by using Listbox and special code which has monitored focused Listbox item index. So I did not used buttons or other GUI elements. It have been possible to use arrow keys to tune The stations. And I have assigned
S::
hot key to stop The playback.

Autohotkey can even improve lifes of physically handicapped users.
I would like to also implement recording feature. After pressing R letter.

The perfect feature of Autohotkey, its fully accessible GUI is making this programming language as A ideal platform not only for visually impaired programmers. Memory allocations are more than super. Only 22 MB and if user uses directive #maxmem
Some special routines are doing its best to automatically optimise allocated memory while autohotkey interpreter run its C language threads in background. So memory allocation will not raise The set limit. Sure, common sense is needed. Do not se it to 10 MB, ETC.
But setting it for example to 40 or 50 MB for program, which do not dynamically work with many bytes of data itself, if app only monitor key strokes, buttons, it should not cause instability I believe it.
I only hope, that value is in MB.
By The way I AM congratulating Autohotkey developers for this build in memory optimizer, which is something similar like The bargage collector in Dalvik. Sure, we are in Windows world, but I AM meaning it as An example.


swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Bass Library Documentation

Post by swagfag » 22 Mar 2021, 12:10

http://www.un4seen.com/doc/#bass/BASS_StreamCreateURL.html

Code: Select all

HSTREAM BASS_StreamCreateURL(
    char *url,
    DWORD offset,
    DWORD flags,
    DOWNLOADPROC *proc,
    void *user
);
the function BASS_StreamCreateURL accepts a pointer to a DOWNLOADPROC.
a DOWNLOADPROC is a function with the following signature:
http://www.un4seen.com/doc/#bass/DOWNLOADPROC.html

Code: Select all

void CALLBACK DownloadProc(
    const void *buffer,
    DWORD length,
    void *user
);
in ahk, to obtain a pointer to a function, define the function and use RegisterCallback() on it. u can then use that pointer and pass it to ur other functions:

Code: Select all

proc := RegisterCallback("DownloadProc")

...

hStream := DllCall("bass.dll\BASS_StreamCreateURL", "Str","","UInt", 0, "UInt", A_IsUnicode ? BASS_UNICODE := 0x80000000 : 0, "Ptr", proc, "Ptr", 0, "UInt")
;                                                                                                                                    ^^^^

...

DownloadProc(buffer, length, user) {
	; ???
}

now what to put in the body? http://www.un4seen.com/doc/#bass/DOWNLOADPROC.html

Code: Select all

FILE *file = NULL;
...
void CALLBACK MyDownloadProc(const void *buffer, DWORD length, void *user)
{
    if (!file) file = fopen("afile.mp3", "wb"); // create the file
    if (!buffer) fclose(file); // finished downloading
    else fwrite(buffer, 1, length, file);
}
...
HSTREAM stream = BASS_StreamCreateURL("http://www.asite.com/afile.mp3", 0, 0, MyDownloadProc, 0);

Code: Select all

DownloadProc(buffer, length, user) {
	if !file
		file := FileOpen("afile.mp3", "w") ; u dont have to specify "b", because there is no "b" in ahk

	; from the docs: "buffer	Pointer to the downloaded data... NULL = finished downloading."
	if !buffer
		file := 0 ; FileObj.Close() invoked automatically by the destructor
	else
	{
		numBytesWritten := file.RawWrite(buffer+0, length)
		;                                      ^^ - necessary if "the variable itself doesnt contain the data 
		;                                           but rather the address of the data". this is a v1 quirk
		
		if !numBytesWritten
			throw "wrote 0 bytes, there was some problem"
	}
}

Janusz
Posts: 89
Joined: 18 Dec 2020, 17:47

Re: Bass Library Documentation

Post by Janusz » 22 Mar 2021, 13:30

Dear Malcev,
You are really Autohotkey programmers elite! It have been too task task for Me as A autohotkey beginner and without yours help, I would have A zero chance to achieve. Thank you very very much for yours fast and professional code with tutorial. I AM very glad, that it have not been necessary to use API functions for working with memory. That Autohotkey itself have register callback support for pointers. As I Am exploring Autohotkey, I AM finding newer aand newer surprices. I have a last plea not only for you.
Does somebody of you have a latest up to date bass.ahk Bass library wrapper? I have got one older release without createurl function so I have used a declaration from Streambar radio player.
Thank you very very much. Some older posts on other related forum threads have expired Dropbox direct download links. So this is The reason why I AM asking you.

Janusz
Posts: 89
Joined: 18 Dec 2020, 17:47

Re: Bass Library Documentation

Post by Janusz » 23 Mar 2021, 04:23

Autohotkey refuses to execute The code. I have very probably mixed some lines from Bass documentation or I do not know.
Error at line 15.
Specifically: FILE *file = NULL; ...

Error: This line does not contain a recognized action.

OK

Here is The code

Code: Select all

Record:
proc := RegisterCallback("DownloadProc")

hStream := DllCall("bass.dll\BASS_StreamCreateURL", "Str","","UInt", 0, "UInt", A_IsUnicode ? BASS_UNICODE := 0x80000000 : 0, "Ptr", proc, "Ptr", 0, "UInt")
                                                                                                                                    ^^^^


DownloadProc(buffer, length, user) {
}
 FILE *file = NULL;
void CALLBACK MyDownloadProc(const void *buffer, DWORD length, void *user)
{
    if (!file) file = fopen("afile.mp3", "wb"); // create the file
    if (!buffer) fclose(file); // finished downloading
    else fwrite(buffer, 1, length, file);
}
HSTREAM stream = BASS_StreamCreateURL("http icecast8.play.cz /cro1-128.mp3",  Broken Link for safety 0, 0, MyDownloadProc, 0);
DownloadProc(buffer, length, user) {
	if !file
		file := FileOpen("afile.mp3", "w") ; u dont have to specify "b", because there is no "b" in ahk
	if !buffer
		file := 0 ; FileObj.Close() 
        	else
{
		numBytesWritten := file.RawWrite(buffer+0, length)
		if !numBytesWritten
			throw "wrote 0 bytes, there was some problem"
}
}
return
Last edited by BoBo on 23 Mar 2021, 07:30, edited 1 time in total.
Reason: Added [code][/code]-tags.

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Bass Library Documentation

Post by swagfag » 23 Mar 2021, 12:06

u copied C code into ur ahk script. please at least visit the links im posting. theyre there for a reason. u wont get anywhere without the documentation

Janusz
Posts: 89
Joined: 18 Dec 2020, 17:47

Re: Bass Library Documentation

Post by Janusz » 28 Apr 2021, 11:37

I have tried The code but file was not created. There is some hydden issue. It is very strange. Sure, I have added real direct link to a live Stream. But I believe, that code can be created.

Janusz
Posts: 89
Joined: 18 Dec 2020, 17:47

Re: Bass Library Documentation

Post by Janusz » 03 Mar 2022, 08:36

Dear MR Malcev and others,
So I have done my best to construct The code according to your example. Really. It do not record and play at The same time. It do not record also.
Please, could somebody of you repair this non functioning code? I have really done my best to put some lines together.

Thank you very much.

Code: Select all

; Generated by Auto-GUI 3.0.1
#SingleInstance Force
#NoEnv
SetWorkingDir %A_ScriptDir%
SetBatchLines -1
proc := RegisterCallback("DownloadProc")
hStream := DllCall("bass.dll\BASS_StreamCreateURL", "Str","","UInt", 0, "UInt", A_IsUnicode ? BASS_UNICODE := 0x80000000 : 0, "Ptr", proc, "Ptr", 0, "UInt")
DownloadProc(buffer, length, user) 
{
	if !file
		file := FileOpen("afile.mp3", "w") 
	if !buffer
		file := 0 ; FileObj.Close() invoked automatically by the destructor
	else
	{
		numBytesWritten := file.RawWrite(buffer+0, length)
		if !numBytesWritten
			throw "wrote 0 bytes, there was some problem"
}


}



Gui Font, s9, Segoe UI
Gui Add, Button, gStart x3 y3 w80 h23, &Record and play

Gui Show, w620 h420, Live stream recorder
Return

Start:
DllCall("LoadLibrary", "Str", A_ScriptDir . "\bass.dll")
	DllCall("bass.dll\BASS_Free")
	if (DllCall("bass.dll\BASS_Init", "Int", -1, "UInt", 44100, "UInt", 0, "Ptr", A_ScriptHwnd, "Ptr", 0))
Hstream := DllCall("bass.dll\BASS_StreamCreateURL", "Str","http://icecast8.play.cz/cro1-128.mp3","UInt", 0, "UInt", A_IsUnicode ? BASS_UNICODE := 0x80000000 : 0, "Ptr", 0, "Ptr", 0, "UInt")
Hstream = BASS_StreamCreateURL("", 0, 0, MyDownloadProc, 0);

Return

GuiEscape:
GuiClose:
ExitApp

Post Reply

Return to “Ask for Help (v1)”