Differenze tra le versioni di "Modificare il volume generale mediante le funzioni esterne del API di PulseAudio"

Da Gambas-it.org - Wikipedia.
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 in questo caso avere installata nel proprio sistema e richiamare in Gambas la libreria condivisa: "libpulse.so.0.21.2"  
+
E' necessario in questo caso avere installata nel proprio sistema e richiamare in Gambas la libreria condivisa: "libpulse.so.0.24.1"  
  
 
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.
Riga 15: Riga 15:
 
   
 
   
 
   
 
   
  Library "libpulse:0.21.2"
+
  Library "libpulse:0.24.1"
 
   
 
   
 
  <FONT Color=gray>' ''pa_threaded_mainloop *pa_threaded_mainloop_new(void)''
 
  <FONT Color=gray>' ''pa_threaded_mainloop *pa_threaded_mainloop_new(void)''
Riga 170: Riga 170:
 
    
 
    
 
  '''End'''
 
  '''End'''
 
  
  

Versione delle 07:27, 30 mar 2023

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.1"

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.


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.1"

' 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(Dial1)
   
  With Dial1
    .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(Dial1)
   
  sink = Lista_Sink()
  exemplum = Replace(Split(sink, ">")[0], "\tname: <", Null)
  dispositivo = InputBox("Immettere il sorgente output audio:", Null, exemplum)
  
End


Public Sub Dial1_Change()
 
 Dim vlm As Long
 Dim canali As Integer = 2
  
  vlm = CLong(Dial1.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


Riferimenti