Differenze tra le versioni di "Modificare il volume generale mediante le funzioni esterne del API di PulseAudio"
(14 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
Il sistema ''PulseAudio'' consente anche di modificare in tempo reale il volume generale dell'audio. | Il sistema ''PulseAudio'' consente anche di modificare in tempo reale il volume generale dell'audio. | ||
− | E' necessario richiamare in Gambas la libreria | + | E' necessario in questo caso avere installata nel proprio sistema e richiamare in Gambas la libreria condivisa: "''libpulse.so.0.24.3 ''". |
− | |||
Poiché bisogna utilizzare la modalità ''asincrona'' con l'uso di funzioni esterne per il richiamo di funzioni di ''callback'', prevista dalle risorse di ''PulseAudio'', sarà necessario prevedere la creazione e l'uso di un'apposita libreria dinamica condivisa esterna, scritta in C. | Poiché bisogna utilizzare la modalità ''asincrona'' con l'uso di funzioni esterne per il richiamo di funzioni di ''callback'', prevista dalle risorse di ''PulseAudio'', sarà necessario prevedere la creazione e l'uso di un'apposita libreria dinamica condivisa esterna, scritta in C. | ||
− | Ricordare che si dovrà inserire nell'oggetto ''InputBox'' la stringa identificativa (ad esempio: <FONT Color=gray>''alsa_output.pci-0000_01_00.1.hdmi-stereo''</font>) del ''sink'' dell'uscita audio, corrispondente alla corrente scheda audio attiva. | + | Ricordare che si dovrà inserire nell'oggetto ''InputBox'' la stringa identificativa (ad esempio: <FONT Color=gray>''alsa_output.pci-0000_01_00.1.hdmi-stereo''</font>) del ''sink'' dell'uscita audio, corrispondente alla corrente scheda audio attiva, e che potrà essere individuata lanciando in Terminale la seguente riga di comando: |
+ | ~ $ pactl list sinks | ||
+ | o anche: | ||
+ | ~ $ pacmd list-sinks | grep -e 'name:' -e 'index:' | ||
+ | La stringa identificativa sarà presente nella linea: "''Nome:'' ". | ||
Riga 12: | Riga 15: | ||
Private context As Pointer | Private context As Pointer | ||
Private vol As Pointer | Private vol As Pointer | ||
− | Private | + | Private dispositivo As String |
Private Const MASSIMO_VOLUME As Integer = 65536 | Private Const MASSIMO_VOLUME As Integer = 65536 | ||
− | Library "libpulse:0. | + | Library "libpulse:0.24.3" |
<FONT Color=gray>' ''pa_threaded_mainloop *pa_threaded_mainloop_new(void)'' | <FONT Color=gray>' ''pa_threaded_mainloop *pa_threaded_mainloop_new(void)'' | ||
Riga 55: | Riga 58: | ||
<FONT Color=gray>' ''void Imposta_Volume(pa_context *c, char *device, struct pa_cvolume *v)'' | <FONT Color=gray>' ''void Imposta_Volume(pa_context *c, char *device, struct pa_cvolume *v)'' | ||
' ''Chiama la libreria .so appositamente creata per usare la funzione esterna 'pa_context_set_sink_volume_by_name( )'''</font> | ' ''Chiama la libreria .so appositamente creata per usare la funzione esterna 'pa_context_set_sink_volume_by_name( )'''</font> | ||
− | Private Extern Imposta_Volume(c As Pointer, | + | Private Extern Imposta_Volume(c As Pointer, device As String, v As Pointer) |
− | + | Public Sub Form_Open() | |
Dim ml, mlgapi As Pointer | Dim ml, mlgapi As Pointer | ||
− | Dim sink As String | + | Dim sink, exemplum As String |
− | <FONT Color=gray>' ''Crea l'apposita libreria dinamica condivisa esterna per la gestione delle funzioni esterne di "callback":</font> | + | <FONT Color=gray>' ''Crea l'apposita libreria dinamica condivisa esterna per la corretta gestione delle funzioni esterne di "callback":</font> |
− | + | CreaSo() | |
− | + | Object.Lock(SpinBox1) | |
− | + | With SpinBox1 | |
− | + | .MaxValue = MASSIMO_VOLUME | |
− | + | .MinValue = 656 | |
− | + | .Value = MASSIMO_VOLUME \ 2 | |
− | + | Valore_TextBox(.Value) | |
− | + | End With | |
<FONT Color=gray>' ''Crea un mainloop API e una connessione al server audio predefinito:''</font> | <FONT Color=gray>' ''Crea un mainloop API e una connessione al server audio predefinito:''</font> | ||
− | + | ml = pa_threaded_mainloop_new() | |
− | + | mlgapi = pa_threaded_mainloop_get_api(ml) | |
− | + | context = pa_context_new(mlgapi, "Controllo volume") | |
<FONT Color=gray>' ''Effettua la connessione al server di PulseAudio:''</font> | <FONT Color=gray>' ''Effettua la connessione al server di PulseAudio:''</font> | ||
− | + | pa_context_connect(context, Null, 0, 0) | |
− | + | State_Callback(context) | |
− | + | pa_threaded_mainloop_start(ml) | |
− | + | vol = Alloc(256) | |
− | + | pa_cvolume_init(vol) | |
− | + | Object.Unlock(SpinBox1) | |
− | + | sink = Lista_Sink() | |
− | + | exemplum = Replace(Split(sink, ">")[0], "\tname: <", Null) | |
+ | dispositivo = InputBox("Immettere il sorgente output audio:", Null, exemplum) | ||
− | + | End | |
− | + | Public Sub SpinBox1_Change() | |
Dim vlm As Long | Dim vlm As Long | ||
Dim canali As Integer = 2 | Dim canali As Integer = 2 | ||
− | + | vlm = CLong(SpinBox1.Value) | |
− | + | Valore_TextBox(vlm) | |
− | + | pa_cvolume_set(vol, canali, vlm) | |
− | + | Imposta_Volume(context, dispositivo, vol) | |
− | + | End | |
− | + | Private Procedure Valore_TextBox(v As Long) | |
TextBox1.Text = Format((v * 100) / MASSIMO_VOLUME, "###.00") | TextBox1.Text = Format((v * 100) / MASSIMO_VOLUME, "###.00") | ||
− | + | End | |
− | + | Public Sub Form_Close() | |
Free(vol) | Free(vol) | ||
− | + | End | |
− | + | Private Function Lista_Sink() As String | |
Dim lista As String | Dim lista As String | ||
− | + | Shell "pacmd list-sinks | grep -e 'alsa.card_name' -e 'name:'" To lista | |
− | + | Print "Lista sorgenti audio disponibili:\n\n"; lista | |
− | + | Return lista | |
− | + | ||
− | + | End | |
+ | |||
+ | Private Procedure CreaSo() <FONT Color=gray>' ''Scrive in C e crea l'apposita libreria .so esterna per la gestione delle funzioni esterne di "callback":</font> | ||
− | |||
− | |||
File.Save("/tmp/libadhoc.c", "#include <pulse/pulseaudio.h>\n" & | File.Save("/tmp/libadhoc.c", "#include <pulse/pulseaudio.h>\n" & | ||
"#include <stdio.h>" | "#include <stdio.h>" | ||
Riga 169: | Riga 173: | ||
Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -lpulse -shared -fPIC" Wait | Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -lpulse -shared -fPIC" Wait | ||
− | + | End | |
− | |||
Versione attuale delle 18:06, 3 lug 2024
Il sistema PulseAudio consente anche di modificare in tempo reale il volume generale dell'audio.
E' necessario in questo caso avere installata nel proprio sistema e richiamare in Gambas la libreria condivisa: "libpulse.so.0.24.3 ".
Poiché bisogna utilizzare la modalità asincrona con l'uso di funzioni esterne per il richiamo di funzioni di callback, prevista dalle risorse di PulseAudio, sarà necessario prevedere la creazione e l'uso di un'apposita libreria dinamica condivisa esterna, scritta in C.
Ricordare che si dovrà inserire nell'oggetto InputBox la stringa identificativa (ad esempio: alsa_output.pci-0000_01_00.1.hdmi-stereo) del sink dell'uscita audio, corrispondente alla corrente scheda audio attiva, e che potrà essere individuata lanciando in Terminale la seguente riga di comando:
~ $ pactl list sinks
o anche:
~ $ pacmd list-sinks | grep -e 'name:' -e 'index:'
La stringa identificativa sarà presente nella linea: "Nome: ".
Mostriamo un esempio pratico in ambiente grafico:
Private context As Pointer Private vol As Pointer Private dispositivo As String Private Const MASSIMO_VOLUME As Integer = 65536 Library "libpulse:0.24.3" ' pa_threaded_mainloop *pa_threaded_mainloop_new(void) ' Allocate a new threaded main loop object. Private Extern pa_threaded_mainloop_new() As Pointer ' pa_mainloop_api* pa_threaded_mainloop_get_api(pa_threaded_mainloop*m) ' Return the main loop abstraction layer vtable for this main loop. Private Extern pa_threaded_mainloop_get_api(m As Pointer) As Pointer ' pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) ' Instantiate a new connection context with an abstract mainloop API and an application name. Private Extern pa_context_new(mainloop As Pointer, name As String) As Pointer ' int pa_context_connect(pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api) ' Connect the context to the specified server. Private Extern pa_context_connect(c As Pointer, server As String, flags As Integer, api As Pointer) As Integer ' int pa_threaded_mainloop_start(pa_threaded_mainloop *m) ' Start the event loop thread. Private Extern pa_threaded_mainloop_start(m As Pointer) As Integer ' pa_cvolume* pa_cvolume_init(pa_cvolume *a) ' Initialize the specified volume and return a pointer to it. Private Extern pa_cvolume_init(a As Pointer) ' pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) ' Set the volume of the specified number of channels to the volume v. Private Extern pa_cvolume_set(a As Pointer, channels As Byte, v As Long) As Pointer Library "/tmp/libadhoc" ' void State_Callback(pa_context *c) ' Chiama la libreria .so appositamente creata per usare la funzione esterna 'pa_context_set_state_callback( )' Private Extern State_Callback(c As Pointer) ' void Imposta_Volume(pa_context *c, char *device, struct pa_cvolume *v) ' Chiama la libreria .so appositamente creata per usare la funzione esterna 'pa_context_set_sink_volume_by_name( )' Private Extern Imposta_Volume(c As Pointer, device As String, v As Pointer) Public Sub Form_Open() Dim ml, mlgapi As Pointer Dim sink, exemplum As String ' Crea l'apposita libreria dinamica condivisa esterna per la corretta gestione delle funzioni esterne di "callback": CreaSo() Object.Lock(SpinBox1) With SpinBox1 .MaxValue = MASSIMO_VOLUME .MinValue = 656 .Value = MASSIMO_VOLUME \ 2 Valore_TextBox(.Value) End With ' Crea un mainloop API e una connessione al server audio predefinito: ml = pa_threaded_mainloop_new() mlgapi = pa_threaded_mainloop_get_api(ml) context = pa_context_new(mlgapi, "Controllo volume") ' Effettua la connessione al server di PulseAudio: pa_context_connect(context, Null, 0, 0) State_Callback(context) pa_threaded_mainloop_start(ml) vol = Alloc(256) pa_cvolume_init(vol) Object.Unlock(SpinBox1) sink = Lista_Sink() exemplum = Replace(Split(sink, ">")[0], "\tname: <", Null) dispositivo = InputBox("Immettere il sorgente output audio:", Null, exemplum) End Public Sub SpinBox1_Change() Dim vlm As Long Dim canali As Integer = 2 vlm = CLong(SpinBox1.Value) Valore_TextBox(vlm) pa_cvolume_set(vol, canali, vlm) Imposta_Volume(context, dispositivo, vol) End Private Procedure Valore_TextBox(v As Long) TextBox1.Text = Format((v * 100) / MASSIMO_VOLUME, "###.00") End Public Sub Form_Close() Free(vol) End Private Function Lista_Sink() As String Dim lista As String Shell "pacmd list-sinks | grep -e 'alsa.card_name' -e 'name:'" To lista Print "Lista sorgenti audio disponibili:\n\n"; lista Return lista End Private Procedure CreaSo() ' Scrive in C e crea l'apposita libreria .so esterna per la gestione delle funzioni esterne di "callback": File.Save("/tmp/libadhoc.c", "#include <pulse/pulseaudio.h>\n" & "#include <stdio.h>" "\n\n" & "void context_state_cb(pa_context *c, void *userdata) {" & "\n\n}" & "\n\n" & "void State_Callback(pa_context *context) {" & "\n\n" & " pa_context_set_state_callback(context, context_state_cb, NULL);" & "\n\n}" & "\n\n" & "void volume_cb(pa_context *c, int risultato, void *userdata) {" & "\n\n" & " if (risultato)\n" & " printf(\"\\rVolume impostato \");\n" & " else\n" & " printf(\"\\rVolume non impostato\");" & "\n\n}" & "\n\n" & "void Imposta_Volume(pa_context *c, char *device, struct pa_cvolume *v) {" & "\n\n" & " pa_context_set_sink_volume_by_name(c, device, v, volume_cb, NULL); " & "\n\n}") Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -lpulse -shared -fPIC" Wait End