How to use ALSA library ???
How to use ALSA library ???
Hi,
Can anyone help with using the ALSA library (goal is to use it on the Raspberry Pi, but that should also be a Linux part).
https://www.alsa-project.org/alsa-doc/a ... index.html
I've been searching, looking, looking and looking for source examples, but not one in PB (all in C or equivalent, which is not very helpfull to me).
I know that the ALSA library is very extensive, but I have no experience whatsoever with programming on Linux (but APIs on Windows).
There are basic commands that can be called in the terminal, such as aplay, amidi, amixer and so on.
How do you use these in PB or for example, the one below from that RawMidi interface API ?
snd_rawmidi_info_get_subdevices_count()
Do these functions and commands become part of the PB program when compiling or does the ALSA library have to be installed separately (by the end user) ?
Do I need this :
Result = OpenLibrary(#Library, Filename$)
Or do you do this with:
ImportC : .... : EndImport
Thanks
Can anyone help with using the ALSA library (goal is to use it on the Raspberry Pi, but that should also be a Linux part).
https://www.alsa-project.org/alsa-doc/a ... index.html
I've been searching, looking, looking and looking for source examples, but not one in PB (all in C or equivalent, which is not very helpfull to me).
I know that the ALSA library is very extensive, but I have no experience whatsoever with programming on Linux (but APIs on Windows).
There are basic commands that can be called in the terminal, such as aplay, amidi, amixer and so on.
How do you use these in PB or for example, the one below from that RawMidi interface API ?
snd_rawmidi_info_get_subdevices_count()
Do these functions and commands become part of the PB program when compiling or does the ALSA library have to be installed separately (by the end user) ?
Do I need this :
Result = OpenLibrary(#Library, Filename$)
Or do you do this with:
ImportC : .... : EndImport
Thanks
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: How to use ALSA library ???
Nothing for the ALSA problem, but ...
OpenLibrary() is for DynamicLinkedLibrarie (.dll) or SharedObject (.so) files.
Import is for static .lib or .a files.
SInce ALSA is delivered as .so file, you need to write a wrapper with LoadLibrary()
OpenLibrary() is for DynamicLinkedLibrarie (.dll) or SharedObject (.so) files.
Import is for static .lib or .a files.
SInce ALSA is delivered as .so file, you need to write a wrapper with LoadLibrary()
Re: How to use ALSA library ???
Something like that:
Code: Select all
Enumeration
#SND_RAWMIDI_STREAM_OUTPUT
#SND_RAWMIDI_STREAM_INPUT
EndEnumeration
PrototypeC.l Prototype_snd_card_next(*card)
PrototypeC.l Prototype_snd_rawmidi_info_alloca(*info)
PrototypeC.l Prototype_snd_rawmidi_info_set_stream(*info, device.l)
PrototypeC.l Prototype_snd_ctl_rawmidi_info (*ctl, *info)
PrototypeC.l Prototype_snd_rawmidi_info_get_subdevices_count(*info)
PrototypeC.l Prototype_snd_ctl_open(*ctl, name.p-utf8, mode.l)
PrototypeC Prototype_snd_ctl_close(*ctl)
Global AlsaLib.i
Global snd_card_next.Prototype_snd_card_next
Global snd_rawmidi_info_alloca.Prototype_snd_rawmidi_info_alloca
Global snd_rawmidi_info_set_stream.Prototype_snd_rawmidi_info_set_stream
Global snd_rawmidi_info_get_subdevices_count.Prototype_snd_rawmidi_info_get_subdevices_count
Global snd_ctl_open.Prototype_snd_ctl_open
Global snd_ctl_close.Prototype_snd_ctl_close
Procedure.i LoadAlsaLib()
If AlsaLib = 0
AlsaLib = OpenLibrary(#PB_Any, "libasound.so.2")
If AlsaLib
snd_card_next = GetFunction(AlsaLib, "snd_card_next")
snd_rawmidi_info_alloca = GetFunction(AlsaLib, "snd_rawmidi_info_alloca")
snd_rawmidi_info_set_stream = GetFunction(AlsaLib, "snd_rawmidi_info_set_stream")
snd_rawmidi_info_get_subdevices_count = GetFunction(AlsaLib, "snd_rawmidi_info_get_subdevices_count")
snd_ctl_open = GetFunction(AlsaLib, "snd_ctl_open")
snd_ctl_close = GetFunction(AlsaLib, "snd_ctl_close")
EndIf
EndIf
ProcedureReturn AlsaLib
EndProcedure
Procedure CloseAlsaLib()
If AlsaLib
CloseLibrary(AlsaLib)
AlsaLib = 0
EndIf
EndProcedure
Define *Info, *Ctl
Define.l card, err, iSub
Define name$
If LoadAlsaLib()
card = -1
err = snd_card_next(@card)
If Not err
If card >= 0
name$ = "hw:" + Str(card)
Debug "Name: " + name$
err = snd_ctl_open(@*ctl, name$, 0)
If err = 0
Debug "Ok"
EndIf
; snd_rawmidi_info_alloca(@*Info)
; snd_rawmidi_info_set_stream(*Info, #SND_RAWMIDI_STREAM_INPUT)
; iSub = snd_rawmidi_info_get_subdevices_count(*Info)
; If iSub > 0
; ;Debug Info\
; EndIf
Else
Debug "No soundcard found"
EndIf
EndIf
EndIf
Re: How to use ALSA library ???
infratec, great.
Yet, one question where do you get that name : "libasound.so.2"
In different folders (lib etc.) on my PI, I didn't find anything like alsa.so extention.
I need to start learning using those Prototypes (I remember GFA basic' had something similar... years ago).
At least I have a starting point now.
Thanks a thousand times infratec.
Yet, one question where do you get that name : "libasound.so.2"
In different folders (lib etc.) on my PI, I didn't find anything like alsa.so extention.
I need to start learning using those Prototypes (I remember GFA basic' had something similar... years ago).
At least I have a starting point now.
Thanks a thousand times infratec.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: How to use ALSA library ???
First you get the path of, for example, alsamixer:
Then you can use ldd to find against which libs it is linked:
Result:
Since all this libs are inthe searchpath, you don't need a path before the name.
Code: Select all
which alsamixer
Code: Select all
ldd /usr/bin/alsamixer
The only lib which has to do with 'a' or 'sound' was: libasound.so.2linux-vdso.so.1 (0x00007ffe007de000)
libformw.so.6 => /usr/lib/x86_64-linux-gnu/libformw.so.6 (0x00007f0bbcc76000)
libmenuw.so.6 => /usr/lib/x86_64-linux-gnu/libmenuw.so.6 (0x00007f0bbcc6a000)
libpanelw.so.6 => /usr/lib/x86_64-linux-gnu/libpanelw.so.6 (0x00007f0bbcc63000)
libncursesw.so.6 => /lib/x86_64-linux-gnu/libncursesw.so.6 (0x00007f0bbcc29000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f0bbcbfb000)
libasound.so.2 => /usr/lib/x86_64-linux-gnu/libasound.so.2 (0x00007f0bbcafa000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0bbc975000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f0bbc970000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0bbc94f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0bbc78e000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f0bbc784000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0bbccb7000)
Since all this libs are inthe searchpath, you don't need a path before the name.
Re: How to use ALSA library ???
And so I come (very close) to that result you posted before.
Yet, these naming is different from the ones listed in the alsa-help (and debugged) ?
snd_rawmidi_info (snd_rawmidi_t *rmidi, snd_rawmidi_info_t *info)
PrototypeC.l Prototype_snd_ctl_rawmidi_info (*ctl, *info)
???
PrototypeC.l Prototype_snd_card_next(*card)
What about that ?
(do prototypes don't have to 'map a function') ?
Else if correct, how do they then ?
Or maybe it's just a difference by the alsa version ?
Thanks again infratec.
Code: Select all
AlsaLib = OpenLibrary(#PB_Any, "libasound.so.2")
If ExamineLibraryFunctions(AlsaLib)
While NextLibraryFunction()
Debug LibraryFunctionName()
Wend
EndIf
snd_rawmidi_info (snd_rawmidi_t *rmidi, snd_rawmidi_info_t *info)
PrototypeC.l Prototype_snd_ctl_rawmidi_info (*ctl, *info)
???
PrototypeC.l Prototype_snd_card_next(*card)
What about that ?
(do prototypes don't have to 'map a function') ?
Else if correct, how do they then ?
Or maybe it's just a difference by the alsa version ?
Thanks again infratec.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: How to use ALSA library ???
I don't know what you mean with 'map'.
A prototype is something which declares the return value and the parameters of a function.
The name has nothing to do with the real function name.
You create a variable of the type of a prototype and assign the address of the wanted function.
Also the name of this variable has nothing to do with the name of the real function.
But it makes sense to use the same name
Look at the code above and the help about prototypes.
A prototype is something which declares the return value and the parameters of a function.
The name has nothing to do with the real function name.
You create a variable of the type of a prototype and assign the address of the wanted function.
Also the name of this variable has nothing to do with the name of the real function.
But it makes sense to use the same name
Look at the code above and the help about prototypes.
Re: How to use ALSA library ???
The PB-helpfile says : "Prototype allows to declare a type which will map a function."
If the name is not according the function, how does it assign the address of the wanted function ?
Thanks again.
If the name is not according the function, how does it assign the address of the wanted function ?
Thanks again.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: How to use ALSA library ???
A prototype does not assign something.
The 'assigning' is done by:
You don't look long enough at my code above.
The process is:
The 'assigning' is done by:
Code: Select all
snd_card_next = GetFunction(AlsaLib, "snd_card_next")
The process is:
Code: Select all
PrototypeC.l Prototype_snd_card_next(*card)
Global snd_card_next.Prototype_snd_card_next
snd_card_next = GetFunction(AlsaLib, "snd_card_next")
Then you can use it:
Debug snd_card_next(*APointer)
Re: How to use ALSA library ???
I understand now how to set it up. Thanks for learning me this.
Only have to figure out what kind of variables and structeres have to be used in those prototypes.
I saw someone here had once made a parser for ALSA, but that download is gone. A pitty.
infratec thanks again.
Only have to figure out what kind of variables and structeres have to be used in those prototypes.
I saw someone here had once made a parser for ALSA, but that download is gone. A pitty.
infratec thanks again.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: How to use ALSA library ???
infratec (or anyone else),
Figuring out the kind of variables and structeres...
How do I convert this in a PB version : snd_card_get_longname(int card, char ** name)
I tried it compared to other functions you already gave in the sample above like :
snd_ctl_open (snd_ctl_t ** ctlp, const char * name, int mode)
Became this :
PrototypeC.l Prototype_snd_ctl_open(*ctl, name.p-utf8, mode.l)
So I tried this one :
PrototypeC.l Prototype_snd_card_get_longname(idx.l, name.p-utf8)
But I don't get it good, as to me, I should be able to read the name with Peeks() thus it should be a adress not a character.
Those definitions in C++ are always so confusing : "why making it simple if it can be made difficult ?"
More of those confusing things :
typedef struct _snd_rawmidi_info snd_rawmidi_info_t
What kind of structure is that ? Where or what are those fileds ?
Yeah "why making it simple if... ?"
Thanks
Figuring out the kind of variables and structeres...
How do I convert this in a PB version : snd_card_get_longname(int card, char ** name)
I tried it compared to other functions you already gave in the sample above like :
snd_ctl_open (snd_ctl_t ** ctlp, const char * name, int mode)
Became this :
PrototypeC.l Prototype_snd_ctl_open(*ctl, name.p-utf8, mode.l)
So I tried this one :
PrototypeC.l Prototype_snd_card_get_longname(idx.l, name.p-utf8)
But I don't get it good, as to me, I should be able to read the name with Peeks() thus it should be a adress not a character.
Those definitions in C++ are always so confusing : "why making it simple if it can be made difficult ?"
More of those confusing things :
typedef struct _snd_rawmidi_info snd_rawmidi_info_t
What kind of structure is that ? Where or what are those fileds ?
Yeah "why making it simple if... ?"
Thanks
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Re: How to use ALSA library ???
The parameter is a pointer to a pointer.
This is not directly doable in PB.
You can try this:
I use a help procedure to get the name.
But I can not test it. It is 'programmed' blind.
This is not directly doable in PB.
You can try this:
Code: Select all
PrototypeC.l Prototype_snd_card_get_longname(card.l, *namePtr)
Global snd_card_get_longname_.Prototype_snd_card_get_longname
snd_card_get_longname_ = GetFunction(AlsaLib, "snd_card_get_longname")
Procedure.s snd_card_get_longname(card.l)
Protected *Ptr, Result$
If snd_card_get_longname_(card, @*ptr) = 0
Result$ = PeekS(*Ptr, -1, #PB_UTF8)
FreeMemory(*Ptr) ; maybe this is not working
EndIf
ProcedureReturn Result$
EndProcedure
But I can not test it. It is 'programmed' blind.
Re: How to use ALSA library ???
Perhaps so ...
Code: Select all
PrototypeC.l Prototype_snd_card_get_longname(card.l, *namePtr)
Global snd_card_get_longname_.Prototype_snd_card_get_longname
snd_card_get_longname_ = GetFunction(AlsaLib, "snd_card_get_longname")
Procedure.s snd_card_get_longname(card.l)
Protected *Ptr.integer, Result$
If snd_card_get_longname_(card, *ptr) = 0
Result$ = PeekS(*Ptr\i, -1, #PB_UTF8)
;FreeMemory(*Ptr\i) ; This not working
EndIf
ProcedureReturn Result$
EndProcedure
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: How to use ALSA library ???
Hi infratec and mk-soft,
Tried both source, but both give an error at the same position :
If snd_card_get_longname_(card, @*ptr) = 0 ;===> [ERROR] Invalid memory access.
If snd_card_get_longname_(card, *ptr) = 0 ;===> [ERROR] Invalid memory access.
debug snd_card_get_longname(0) ;1
The same error with 1.
Before I had tried by myself this :
If snd_card_get_longname(0, lname$)=0 ;===>no error
Debug lname$ :===> this gave me a number
;Debug PeekS(@lname$) ;===> I don't know if this is the correct manner, nothing useable.
EndIf
I hope someone can find this out, I'll keep on experimenting a while.
Thanks
Tried both source, but both give an error at the same position :
If snd_card_get_longname_(card, @*ptr) = 0 ;===> [ERROR] Invalid memory access.
If snd_card_get_longname_(card, *ptr) = 0 ;===> [ERROR] Invalid memory access.
debug snd_card_get_longname(0) ;1
The same error with 1.
Before I had tried by myself this :
If snd_card_get_longname(0, lname$)=0 ;===>no error
Debug lname$ :===> this gave me a number
;Debug PeekS(@lname$) ;===> I don't know if this is the correct manner, nothing useable.
EndIf
I hope someone can find this out, I'll keep on experimenting a while.
Thanks
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.