Analizzare il valore RMS, il picco e il decay dei dati audio mediante il plugin 'level'usando una linea di pipeline con la funzione 'gst parse launch()': differenze tra le versioni
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| Riga 2: | Riga 2: | ||
<BR>Con la Proprietà "intervall" del plug-in ''level'' è possibile impostare il valore dell'intervallo di tempo riferito ai dati da analizzare. L'impostazione predefinita è 1/10 di secondo. Si suggerisce di non scendere al di sotto di 1 millisecondo, pena la possibilità di un blocco del sistema ! | <BR>Con la Proprietà "intervall" del plug-in ''level'' è possibile impostare il valore dell'intervallo di tempo riferito ai dati da analizzare. L'impostazione predefinita è 1/10 di secondo. Si suggerisce di non scendere al di sotto di 1 millisecondo, pena la possibilità di un blocco del sistema ! | ||
E' necessario avere installata nel proprio sistema e richiamare nel progetto Gambas la libreria condivisa: "''libgstreamer-1.0.so.0. | E' necessario avere installata nel proprio sistema e richiamare nel progetto Gambas la libreria condivisa: "''libgstreamer-1.0.so.0.2410.0'' ". | ||
Mostriamo di seguito un semplice esempio, nel quale verranno analizzati i dati audio di un file WAV. L'intervallo temporale dei dati da analizzare sarà impostato a 1 millisecondo. | Mostriamo di seguito un semplice esempio, nel quale verranno analizzati i dati audio di un file WAV. L'intervallo temporale dei dati da analizzare sarà impostato a 1 millisecondo. | ||
Library "libgstreamer-1.0:0. | Library "libgstreamer-1.0:0.2410.0" | ||
Public Struct GValueArray | Public Struct GValueArray | ||
Versione delle 19:29, 6 dic 2024
Il plug-in Level fornito dalla libreria GStreamer analizza i buffer audio in arrivo e, se la proprietà "message" è vera, esso genera un messaggio denominato "Element", dal quale è possibile estrarre alcuni valori attinente ai dati audio medesimi, come ad esempio il valore RMS, il valore di picco e il valore di decay.
Con la Proprietà "intervall" del plug-in level è possibile impostare il valore dell'intervallo di tempo riferito ai dati da analizzare. L'impostazione predefinita è 1/10 di secondo. Si suggerisce di non scendere al di sotto di 1 millisecondo, pena la possibilità di un blocco del sistema !
E' necessario avere installata nel proprio sistema e richiamare nel progetto Gambas la libreria condivisa: "libgstreamer-1.0.so.0.2410.0 ".
Mostriamo di seguito un semplice esempio, nel quale verranno analizzati i dati audio di un file WAV. L'intervallo temporale dei dati da analizzare sarà impostato a 1 millisecondo.
Library "libgstreamer-1.0:0.2410.0"
Public Struct GValueArray
n_values As Integer
values As Pointer
End Struct
Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
Private Const GST_MESSAGE_ERROR As Integer = 2
Private Const GST_MESSAGE_ELEMENT As Integer = 32768
' gst_init (int *argc, char **argv[])
' Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.
Private Extern gst_init(argc As Pointer, argv As Pointer)
' GMainLoop * g_main_loop_new (GMainContext *context, gboolean is_running)
' Creates a new GMainLoop structure.
Private Extern g_main_loop_new(context As Pointer, is_running As Boolean) As Pointer
' GstElement * gst_parse_launch (const gchar *pipeline_description, GError **error)
' Create a new pipeline based on command line syntax.
Private Extern gst_parse_launch(description As String, gerror As Pointer) As Pointer
' GstBus * gst_pipeline_get_bus (GstPipeline *pipeline)
' Gets the GstBus of pipeline.
Private Extern gst_pipeline_get_bus(pipeline As Pointer) As Pointer
' guint gst_bus_add_watch (GstBus *bus, GstBusFunc func, gpointer user_data)
' Adds a bus watch to the default main context with the default priority.
Private Extern gst_bus_add_watch(bus As Pointer, func As Pointer, user_data As Pointer) As Integer
' GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)
' Sets the state of the element.
Private Extern gst_element_set_state(element As Pointer, state As Integer) As Integer
' void g_main_loop_run (GMainLoop *loop)
' Runs a main loop until g_main_loop_quit() is called on the loop.
Private Extern g_main_loop_run(gloop As Pointer)
' const gchar * gst_structure_get_name (const GstStructure *structure)
' Get the name of structure as a string.
Private Extern gst_structure_get_name(gstructure As Pointer) As String
' const GstStructure * gst_message_get_structure (GstMessage *message)
' Access the structure of the message.
Private Extern gst_message_get_structure(message As Pointer) As Pointer
' gpointer g_value_get_boxed (const GValue *value)
' Get the contents of a G_TYPE_BOXED derived GValue.
Private Extern g_value_get_boxed(value As Pointer) As Pointer
' const GValue * gst_structure_get_value (const GstStructure *structure, const gchar *fieldname)
' Get the value of the field with name fieldname.
Private Extern gst_structure_get_value(gstructure As Pointer, fieldname As String) As Pointer
' GValue * g_value_array_get_nth (GValueArray *value_array, guint index_)
' Return a pointer to the value at index_ containd in value_array.
Private Extern g_value_array_get_nth(value_array As GValueArray, index As Integer) As Pointer
' gdouble g_value_get_double (const GValue *value)
' Get the contents of a G_TYPE_DOUBLE GValue.
Private Extern g_value_get_double(value As Pointer) As Float
' gboolean gst_structure_get_clock_time (const GstStructure *structure, const gchar *fieldname, GstClockTime *value)
' Sets the clock time pointed to by value corresponding to the clock time of the given field.
Private Extern gst_structure_get_clock_time(gstructure As Pointer, fieldname As String, value As Pointer) As Boolean
' void gst_object_unref(gpointer object)
' Decrements the reference count on object.
Private Extern gst_object_unref(gobject As Pointer)
Public Sub Main()
Dim lp, lev, bs As Pointer
Dim fileaudio As String
fileaudio = "/percorso/del/file.wav"
gst_init(0, 0)
lp = g_main_loop_new(0, False)
If lp == 0 Then Error.Raise("Errore !")
' Imposta gli elementi necessari per l'analisi del file audio:
lev = gst_parse_launch("filesrc location=" & fileaudio & " ! wavparse ! audioconvert ! level interval=1000000 ! audio/x-raw,channels=2 ! fakesink", 0)
If lev == 0 Then Error.Raise("Errore !")
' Poiché l'elemento "level" inserisce i propri risultati nel puntatore "GstBus", è necessario estrapolarlo dalla pipeline:
bs = gst_pipeline_get_bus(lev)
If bs == 0 Then Error.Raise("Errore !")
' Resta in osservazione se è pronto un messaggio nel bus, nel qual caso invoca la funzione "Gestione_messaggio_bus()":
Print gst_bus_add_watch(bs, Gestione_messaggio_bus, lp)
' Avvia l'analisi del file audio:
gst_element_set_state(lev, GST_STATE_PLAYING)
' Avvia un loop infinito:
g_main_loop_run(lp)
End
Public Function Gestione_messaggio_bus(bus As Pointer, msg As Pointer, data As Pointer) As Boolean
Dim gst, GValue As Pointer
Dim rms, rms_dB, peak_dB, decay_dB As Float
Dim rms_arr, peak_arr, decay_arr As GValueArray
Dim channels, i As Integer
Dim endtime As Long
Select Case Int@(msg + 64) ' GstMessage->type
Case GST_MESSAGE_ELEMENT
gst = gst_message_get_structure(msg)
If gst_structure_get_name(gst) = "level" Then
rms_arr = g_value_get_boxed(gst_structure_get_value(gst, "rms"))
peak_arr = g_value_get_boxed(gst_structure_get_value(gst, "peak"))
decay_arr = g_value_get_boxed(gst_structure_get_value(gst, "decay"))
channels = rms_arr.n_values
Print "\e[1mNumero canali audio: "; channels
For i = 0 To channels - 1
Print "\e[0m\e[5mCanale: "; i
GValue = g_value_array_get_nth(rms_arr, i)
rms_dB = g_value_get_double(GValue)
GValue = g_value_array_get_nth(peak_arr, i)
peak_dB = g_value_get_double(GValue)
GValue = g_value_array_get_nth(decay_arr, i)
decay_dB = g_value_get_double(GValue)
Print "\e[0m RMS: "; rms_dB; " dB, picco: "; peak_dB; " dB, decay: "; decay_dB; " dB"
' Converte da dB a normale dando un valore compreso tra 0,0 e 1,0:
rms = (10 ^ (rms_dB / 20))
Print " Valore rms normalizzato: "; rms
If gst_structure_get_clock_time(gst, "endtime", VarPtr(endtime)) = False Then
Print "Attenzione: impossibile analizzare 'endtime' !"
Else
Print "endtime: "; CStr(Time(0, 0, 0, CInt(endtime / 1000000)))
Endif
Wait 0.01
Print
Next
Endif
Case GST_MESSAGE_ERROR
Print "Errore durante l'analisi del file audio !"
End Select
Return True
End