Differenze tra le versioni di "Eseguire i file audio mediante il componente gb.media"

Da Gambas-it.org - Wikipedia.
 
(11 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Di seguito vedremo due Classi principali, fornite dal Componente ''gb.media'', con le quali è possibile attraverso varie modalità eseguire i file audio.
+
* [[Duplicare il flusso dei dati audio di una pipeline della Classe ''MediaPipeline'' del componente gb.media]]
  
 +
* [[Eseguire due o più file audio contemporaneamente mediante la Classe ''MediaPipeline'' del componente gb.media]]
  
=La classe MediaPlayer=
+
* [[Eseguire i file audio mediante la Classe ''MediaPipeline'' del componente gb.media]]
La classe ''MediaPlayer'' del componente ''gb.media'' consente di gestire uno o più file audio anche contemporaneamente.
 
  
 +
* [[Eseguire i file audio mediante la Classe ''MediaPlayer'' del componente gb.media]]
  
===Uso di applicazione grafica===
+
* [[Eseguire un file audio e un file MIDI contemporaneamente mediante la Classe ''MediaPipeline'' del componente gb.media]]
Vediamo un semplicissimo codice per lanciare ed ascoltare un file audio in un'applicazione grafica utilizzando un ''Timer''.
 
<BR>Porremo sul ''Form'' del progetto:
 
* tre ''Button'' per avviare, mettere in pausa ed arrestare l'esecuzione del file audio;
 
* un ''Timer'' che ci consentirà di calcolare il tempo trascorso;
 
* un ''RadioButton'' per far ripetere a volontà il medesimo file audio:
 
Private mp As New <FONT color=#B22222>MediaPlayer</font>
 
 
 
'''Public''' Sub Form_Open()
 
 
<FONT color=gray>' ''Carica un file audio:''</font>
 
  mp.URL = Media.URL("<FONT color=gray>''/percorso/del/file/audio''</font>")
 
 
<FONT color=gray>' ''Facciamo in modo che il "Timer", alla sua prima attivazione, parta senza alcun ritardo:''</font>
 
  Timer1.Delay = 1
 
 
'''End'''
 
 
 
 
'''Public''' Sub Button1_Click()
 
 
  suona()
 
 
'''End'''
 
 
'''Public''' Sub suona()
 
 
 
<FONT color=gray>' ''Avvia l'ascolto del file audio:''</font>
 
  mp.<FONT color=#B22222>Play</font>
 
 
  With Timer1
 
    .Start
 
<FONT color=gray>' ''Il "Timer" si attiva ogni 70 millesimi di secondo:''</font>
 
    .Delay = 70
 
  End With
 
 
'''End'''
 
 
'''Public''' Sub Button2_Click()
 
 
<FONT color=gray>' ''Mette in "pausa" l'ascolto del file audio.''
 
' ''(Per continuare l'ascolto del file, si dovrà nuovamente attivare la proprietà ".Play"):</font>
 
  mp.<FONT color=#B22222>Pause</font>
 
 
'''End'''
 
 
'''Public''' Sub Button3_Click()
 
 
  RadioButton1.Value = False
 
 
<FONT color=gray>' ''Chiama la funzione per arrestare l'esecuzione del file audio:''</font>
 
  arresta()
 
 
'''End'''
 
 
 
'''Public''' Sub arresta()
 
 
<FONT color=gray>' ''Arresta l'ascolto del file audio:''</font>
 
  mp.<FONT color=#B22222>Stop</font>
 
 
  Timer1.Stop
 
 
<FONT color=gray>' ''Se è stato cliccato sul "RadioButton", verrà ripetuta l'esecuzione del file audio:''</font>
 
  If RadioButton1.Value Then
 
    mp.Position = 0
 
    suona()
 
  Else
 
<FONT color=gray>' ''Arresta l'ascolto del file audio:''</font>
 
    mp.Stop
 
  Endif
 
 
'''End'''
 
 
 
'''Public''' Sub Timer1_Timer()
 
 
<FONT color=gray>' ''Mostra in console la posizione, espressa in secondi, all'interno dei dati processati:''</font>
 
  Write #File.Out, "\rDurata del brano: " & CStr(Date(0, 0, 0, 0, 0, 0, mp.Duration * 1000)) & "  -  Tempo trascorso: " & CStr(Date(0, 0, 0, 0, 0, 0, mp.Position * 1000))
 
 
<FONT color=gray>' ''Se la posizione corrente è uguale o maggiore della durata complessiva del file audio,''
 
' ''allora arresta l'esecuzione del file audio (altrimenti non sarà possibile riavviarlo semplicemente ri-clkiccando sul "Button1"):''</font>
 
  If mp.Position >= mp.Duration Then arresta()
 
 
 
'''End'''
 
 
 
 
 
In quest'altro esempio, simile al precedente, verrà utilizzato un ciclo al posto di un oggetto ''Timer''. Si porrà anche un oggetto ''Dial'' per poter modificare il volume.
 
Private mp As New MediaPlayer
 
Private bo As Boolean
 
 
 
'''Public''' Sub Form_Open()
 
 
  With Dial1
 
    .MinValue = 0
 
    .MaxValue = 100
 
    .Value = 50
 
  End With
 
 
 
<FONT color=gray>' ''Carica un file audio:''</font>
 
  mp.URL = Media.URL("<FONT color=gray>''/percorso/del/file/audio''</font>")
 
 
'''End'''
 
 
 
 
'''Public''' Sub Button1_Click()
 
 
  suona()
 
 
'''End'''
 
 
 
'''Public''' Sub suona()
 
 
<FONT color=gray>' ''Avvia l'ascolto del file audio:''</font>
 
  mp.Play
 
 
 
  Do
 
<FONT color=gray>' ''Una brevissima pausa consente di agire sugli eventuali oggetti posti sul Form:''</font>
 
    Wait 0.01
 
    Write #File.Out, "\rDurata del brano: " & CStr(Date(0, 0, 0, 0, 0, 0, mp.Duration * 1000)) & "  -  Tempo trascorso: " & CStr(Date(0, 0, 0, 0, 0, 0, mp.Position * 1000))
 
  Loop Until (mp.Position >= mp.Duration) Or (bo = True)
 
 
 
  arresta()
 
 
 
'''End'''
 
 
 
'''Public''' Sub Button2_Click()
 
 
 
<FONT color=gray>' ''Mette in "pausa" l'ascolto del file audio.''
 
' ''(Per continuare l'ascolto del file, si dovrà nuovamente attivare la proprietà ".Play").''</font>
 
  mp.Pause
 
 
'''End'''
 
 
 
'''Public''' Sub Button3_Click()
 
 
 
  RadioButton1.Value = False
 
 
 
  bo = True
 
 
 
'''End'''
 
 
 
'''Public''' Sub arresta()
 
 
 
<FONT color=gray>' ''Se è stato cliccato sul "RadioButton", verrà ripetuta l'esecuzione del file audio:''</font>
 
  If RadioButton1.Value Then
 
    mp.Position = 0
 
    suona()
 
  Else
 
<FONT color=gray>' ''Altrimenti arresta l'ascolto del file audio:''</font>
 
    mp.Stop
 
  Endif
 
 
 
'''End'''
 
 
 
'''Public''' Sub Dial1_Change()
 
 
 
  mp.Audio.Volume = Dial1.Value / 10
 
  Wait 0.1
 
 
 
'''End'''
 
 
 
 
 
 
 
===Utilizzo in un'applicazione ''a riga di comando''===
 
Vediamo ora un semplice esempio di uso della Classe ''MediaPlayer'' in un'applicazione ''a riga di comando'':
 
Private bo As Boolean
 
 
 
'''Public''' Sub Main()
 
 
  Dim mp As MediaPlayer
 
 
 
  With mp = New MediaPlayer
 
    .URL = Media.URL("<FONT color=gray>''/percorso/del/file/audio''</font>")
 
    .Play()
 
  End With
 
 
 
  Do
 
<FONT color=gray>' ''Mostra in console la posizione, espressa in secondi, all'interno dei dati processati:''</font>
 
    Write #File.Out, "\rDurata del brano: " & CStr(Date(0, 0, 0, 0, 0, 0, mp.Duration * 1000)) & "  -  Tempo trascorso: " & CStr(Date(0, 0, 0, 0, 0, 0, mp.Position * 1000))
 
    Wait 0.01
 
  Loop Until (mp.Position >= mp.Duration) Or (bo = True)
 
 
 
  mp.Stop()
 
  mp.Close()
 
  Quit
 
 
 
'''End'''
 
 
 
'''Public''' Sub Application_Read()  <FONT color=gray>' ''Premendo il tasto "Invio" della tastiera, si arresta il programma''</font>
 
 
 
  bo = True
 
 
 
'''End'''
 
 
 
 
 
 
 
==La proprietà ''.Duration''==
 
La proprietà ''.Duration'' restituisce un valore di tipo Float che rappresenta la durata del brano musicale espresso in secondi.
 
<BR>Poiché detta proprietà ritorna più precisamente la durata dei dati processati, essa potrà essere utilizzabile solo successivamente all'attivazione della funzione ''.Play''. Per essere funzionante in modo automatico, potrà essere posta all'interno di una routine di attivazione di un ''Timer'' (vedi esempio precedente) o di un ciclo.
 
 
 
 
 
==La proprietà ''.Position''==
 
La proprietà ''.Position'' restituisce un valore di tipo Float che rappresenta la posizione, espressa in secondi all'interno dei dati processati.
 
<BR>Imposta, altresì, la posizione di esecuzione del brano. Pertanto, essa consente di spostare il processo dei dati, e dunque l'esecuzione del brano, ad un particolare punto temporale.
 
 
 
 
 
==Modificare il ''Volume''==
 
Per conoscere o modificare il livello del volume d'ascolto si dovrà utilizzare la proprietà "''.Volume''" della proprietà ''.Audio'' della Classe ''MediaPlayer''. Più in particolare la proprietà "''.Volume''" ritorna od imposta il volume del corrente flusso audio.
 
 
 
Nel primo caso restituisce un valore di tipo ''<SPAN style="text-decoration:underline">Float</span>'' che rappresenta il volume corrente:
 
valore_di_tipo_Float = mp.Audio.<FONT color=#B22222>Volume</font>
 
 
 
nel secondo caso il volume è impostato mediante un valore di tipo ''<SPAN style="text-decoration:underline">Float</span>'', il cui ambito di valori impostabili va da 0.00 a 10.00:
 
mp.Audio.<FONT color=#B22222>Volume</font> = valore_di_tipo_Float
 
 
 
 
 
==Annullare l'audio immediatamente==
 
Per annullare l'audio immediatamente, senza modificare i valori del volume, si ha a disposizione la proprietà "''.Mute''" della proprietà ''.Audio'' della Classe ''MediaPlayer''. Alla proprietà ''.Mute'' dovrà essere  assegnato il valore booleano ''True''.
 
mp.Audio.<FONT color=#B22222>Mute</font> = True
 
 
 
 
 
==L'evento ''_AboutToFinish''==
 
L'evento ''_AboutToFinish'' si scatena circa un secondo prima della fine della durata del file audio che si sta eseguendo.
 
 
 
 
 
==L'evento ''_End''==
 
L'evento ''_End'' si scatena quando la durata del file è terminata.
 
 
 
 
 
 
 
==Estrarre i ''Tag'' da un file audio==
 
Per estrarre i ''Tag'' da un file audio si utilizzerà l'evento ''_Tag'' della Classe ''MediaPlayer''. L'evento avrà come parametro una variabile, del tipo ''MediaTagList'', che conterrà la lista dei ''Tag'' trovati.
 
Private mp As New MediaPlayer <FONT color=#B22222>As "mp"</font>
 
 
 
'''Public''' Sub Button1_Click()
 
 
  mp.URL = Media.URL("<FONT color=gray>''/percorso/del/file/audio''</font>")
 
 
 
  mp.Play
 
 
 
'''End'''
 
 
 
<FONT color=gray>' ''Se ci sono "Tag" nel file audio, verrà sollevato il seguente evento:''</font>
 
'''Public''' Sub mp<FONT color=#B22222>_Tag</font>(tagLista As MediaTagList)
 
 
 
  Dim sTag As String
 
 
 
    For Each sTag In tagLista.Tags
 
<FONT color=gray>' ''Vediamo in console i Tag trovati del file audio:''</font>
 
      Print sTag, Str(tagLista[sTag])
 
    Next
 
 
 
'''End'''
 
V'è da evidenziare che l'evento ''_Tag'' sarà sollevato solo con l'attivazione della funzione ''.Play'' .
 
 
 
 
 
 
 
==Gli effetti video con i ''plug-in''==
 
E' possibile ottenere simpatici effetti video utilizzando i ''plug-in'' resi disposibili da ''GStreamer''.
 
 
 
In tal caso si farà uso anche della Classe ''MediaControl'' che è serve per gestire appositamente i ''plug-in'' di ''GStreamer''.
 
 
 
 
 
Mostreremo di seguito il codice esenziale per l'utilizzo degli effetti video con i ''plug-In'' (si inserirà anche una ''DrawingArea'' sul ''Form''):
 
Private mp As New MediaPlayer
 
 
 
'''Public''' Sub Form_Open()
 
 
 
  Dim da As DrawingArea
 
 
 
  With da = New DrawingArea(Me)
 
    .X = 10
 
    .Y = 10
 
    .W = 300
 
    .H = 300
 
    .Background = Color.Black
 
  End With
 
 
 
  mp.URL = Media.URL("<FONT Color=gray>''/percorso/del/file/audio''</font>")
 
 
 
  AvviaPlugin(da)
 
 
 
'''End'''
 
 
 
 
 
'''Private''' Procedure AvviaPlugin(drar As DrawingArea)
 
 
 
  Dim uscitaVideo, plugVis As MediaControl
 
  Dim b As Byte
 
  Dim tipoPlug As String[] = ["goom", "monoscope", "spacescope",
 
                              "spectrascope", "synaescope", "wavescope"]
 
  Dim arrplugin As MediaControl[]
 
 
 
<FONT Color=gray>' ''Istanzia il controllo di uscita video da usare. In questo caso sarà "ximagesink",''
 
' ''un "videosink" basato sullo standard X, e che è esso stesso un plug-in:''</font>
 
  uscitaVideo = New MediaControl(mp, "ximagesink")
 
 
 
<FONT Color=gray>' ''Si dice al MediaControl di mostrare il proprio output (gli effetti video)''
 
' ''in uno specifico controllo GUI, solitamente una DrawingArea:''</font>
 
  uscitaVideo.SetWindow(drar)
 
 
 
<FONT Color=gray>' ''Imposta il controllo di uscita video da usare:''</font>
 
  mp.Video.Output = uscitaVideo
 
 
 
<FONT Color=gray>' ''Un array di variabili di tipo "MediaControl", ossia di vari PlugIn disponibili:''</font>
 
  arrplugin = New MediaControl[]
 
  For b = 0 To 5
 
    plugVis = New MediaControl(mp, tipoPlug[b])
 
    arrplugin.Push(plugVis)
 
  Next
 
 
 
<FONT Color=gray>' ''Imposta il plug-in da utilizzare (ad esempio il 6° fra quelli contenuti dal vettore "arrplugin":''</font>
 
  mp.Video.Visualisation = arrplugin[5]
 
     
 
'''End'''
 
 
 
'''Public''' Sub Form_Activate()
 
 
 
<FONT Color=gray>' ''Esegue il file audio:''</font>
 
  mp.Play()
 
 
 
'''End'''
 
 
 
 
 
==Interfacciare la Classe ''MediaPlayer'' con il plugin "''jackaudiosink''" di ''GStreamer'' per eseguire i file audio==
 
Per eseguire i file audio con la Classe ''MediaPlayer'' è possibile anche effettuare un interfacciamento tra il programma Gambas e il server audio JACK. Per fare ciò, ci si servirà dell'apposito plugin di ''GStreamer'', chiamato "''jackaudiosink''". <SUP>&#91;[[#Note|Nota 1]]&#93;</sup>
 
 
 
Ovviamente bisognerà avere l'accortezza di avviare il server Jack (per esempio avviando il programma ''qjackctl'') <SPAN Style="text-decoration:underline">prima</span> di lanciare il programma Gambas.
 
 
 
All'avvio del programma viene creata dal server ''Jack'' una connessione tra il programma sorgente Gambas e la destinazione (di default il primo canale audio d'uscita disponibile della propria scheda audio).
 
 
 
 
 
Mostriamo un semplice ed essenziale esempio di esecuzione di un file audio in un'applicazione ''a riga di comando'':
 
'''Public''' Sub Main()
 
 
 
  Dim mp As MediaPlayer
 
 
 
  With mp = New MediaPlayer
 
    .URL = Media.URL("<FONT color=gray>''/percorso/del/file/audio''</font>")
 
    .Audio.Output = New MediaControl(mp, "jackaudiosink")
 
    .Play
 
  End With
 
 
 
  Sleep mp.Duration
 
 
 
  mp.Stop
 
       
 
'''End'''
 
 
 
 
 
=La Classe ''MediaPipeline''=
 
La Classe ''MediaPipeline'' è uno speciale contenitore di Elementi ''GStreamer'' (ossia i ''MediaControl'' del Componente ''gb.media''), ai quali fornisce un clock globale per la sincronizzazione ed un bus per l'inoltro di messaggi provenienti dai thread dello streaming.
 
 
 
Questa Classe implementa un funzionale media-player; pertanto è possibile anche mediante tale Classe eseguire in modo semplice un file audio impostando nei suoi argomenti il plugin ''Playbin''.
 
 
 
Mostriamo un esempio pratico in un'applicazione ''a riga di comando'':
 
'''Public''' Sub Main()
 
 
 
  Dim pl As MediaPipeline
 
  Dim s As String
 
 
 
 
 
  pl = New MediaPipeline(Null, "playbin")
 
  pl["uri"] = Media.URL("<FONT color=gray>''/percorso/del/file/audio''</font>")
 
 
 
  pl.Play()
 
 
 
<FONT color=gray>' ''Utilizziamo la funzione "Input" per consentire l'esecuzione del file audio, evitando così un eccessivo''
 
' ''aggravio di lavoro per la CPU. Inoltre, premendo il tasto "Invio" viene interrotta l'esecuzione.''</font>
 
  Input s
 
 
 
  pl.Stop
 
 
 
'''End'''
 
 
 
 
 
Il plugin "''playbin''" può anche essere inserito all'interno di un oggetto della Classe ''MediaControl'', la quale rappresenta un Elemento ordinario di ''GStreamer''.
 
  '''Public''' Sub Main()
 
 
 
  Dim pl As MediaPipeline
 
  Dim mc As MediaControl
 
  Dim s As String
 
 
 
  pl = New MediaPipeline
 
 
 
  mc = New MediaControl(pl, "playbin")
 
  mc["uri"] = Media.URL("<FONT color=gray>''/percorso/del/file/audio''</font>")
 
 
 
  pl.Play()
 
 
 
<FONT color=gray>' ''Utilizziamo la funzione "Input" per consentire l'esecuzione del file audio, evitando così un eccessivo''
 
' ''aggravio di lavoro per la CPU. Inoltre, premendo il tasto "Invio" viene interrotta l'esecuzione.''</font>
 
  Input s
 
 
 
  pl.Stop
 
 
 
'''End'''
 
 
 
 
 
==Utilizzare i plugin di GStreamer con le Classi ''MediaControl'' e ''MediaPipeline'' per eseguire i file audio==
 
E' possibile eseguire i file audio utilizzando specifici plugin di GStreamer <SUP>&#91;[[#Note|Nota 2]]&#93;</sup> con le Classi ''MediaControl'' e ''MediaPipeline''.
 
 
 
Mostriamo di seguito un paio di esempi per l'esecuzione di file audio.
 
 
 
====Eseguire un file WAV====
 
'''Public''' Sub Main()
 
 
 
  Dim pl As MediaPipeline
 
  Dim src, dcd, cnv, snk As MediaControl
 
 
 
    pl = New MediaPipeline
 
   
 
    src = New MediaControl(pl, "<FONT color=#B22222>filesrc</font>")
 
    src["location"] = "<FONT color=gray>''/percorso/del/file.wav''</font>"  <FONT color=gray>' ''"location" è una proprietà del plugin "filesrc"''</font>
 
   
 
    dcd = New MediaControl(pl, "<FONT color=#B22222>wavparse</font>")
 
    cnv = New MediaControl(pl, "<FONT color=#B22222>audioconvert</font>")
 
    snk = New MediaControl(pl, "<FONT color=#B22222>alsasink</font>")
 
    src.LinkTo(dcd)
 
    dcd.LinkTo(cnv)
 
    cnv.LinkTo(snk)
 
   
 
    pl.Play()
 
       
 
    While pl.Duration > pl.Position
 
      Write #File.Out, "\rTempo: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
 
      Wait 0.001
 
    Wend
 
   
 
    pl.Stop()
 
    pl.Close()
 
   
 
'''End'''
 
 
 
In quest'altro esempio si potranno impostare i valori della frequenza di campionamento (rate) e dei canali, nonché modificare in "tempo reale" mediante tre ''Slider'' i valori della tonalità, del tempo di esecuzione e del volume d'uscita. Le due impostazioni relative alla tonalità e al tempo di esecuzione verranno effettuate con il plugin "pitch", considerando che:
 
* per impostare la tonalità si userà l'omonima proprietà "pitch": il valore di partenza predefinito è 1.0;
 
* per impostare la velocità del tempo di esecuzione si userà la proprietà "tempo": il valore di partenza predefinito è 1.0.
 
Private pl As MediaPipeline
 
Private pit As MediaControl
 
Private vol As MediaControl
 
Private pitch As Float = 1.00
 
Private tempo As Float = 1.00
 
Private volume As Float = 1.00
 
 
 
'''Public''' Sub Form_Open()
 
 
 
  Dim src, par, cnv, res, enc, cnv2, snk As MediaControl
 
  Dim flt As MediaFilter
 
 
 
  pl = New MediaPipeline
 
 
 
  src = New MediaControl(pl, "filesrc")
 
  src["location"] = "<FONT color=gray>''/percorso/del/file.wav''</font>"
 
  par = New MediaControl(pl, "wavparse")
 
  cnv = New MediaControl(pl, "audioconvert")
 
  res = New MediaControl(pl, "audioresample")
 
  flt = New MediaFilter(pl, "audio/x-raw,rate=44100,channels=2")
 
  pit = New MediaControl(pl, "pitch")
 
  vol = New MediaControl(pl, "volume")
 
  cnv2 = New MediaControl(pl, "audioconvert")
 
  snk = New MediaControl(pl, "alsasink")
 
   
 
  src.LinkTo(par)
 
  par.LinkTo(cnv)
 
  cnv.LinkTo(res)
 
  res.LinkTo(flt)
 
  flt.LinkTo(pit)
 
  pit.LinkTo(cnv2)
 
  cnv2.LinkTo(vol)
 
  vol.LinkTo(snk)
 
 
 
<FONT Color=gray>' ''Imposta alcuni valori dei due "Slider":''</font>
 
  With Slider1
 
    .MinValue = 0
 
    .MaxValue = 1000
 
    .Value = 100
 
  End With
 
 
 
  With Slider2
 
    .MinValue = 0
 
    .MaxValue = 1000
 
    .Value = 100
 
  End With
 
 
 
  With Slider3
 
    .MinValue = 0
 
    .MaxValue = 1000
 
    .Value = 100
 
  End With
 
 
 
'''End'''
 
 
 
 
 
'''Public''' Sub Button1_Click()
 
 
 
  pl.Play()
 
 
 
  Do
 
    Write #File.Out, "\rDurata del brano: " & CStr(Date(0, 0, 0, 0, 0, 0, pl.Duration * 1000)) & "  -  Tempo trascorso: " & CStr(Date(0, 0, 0, 0, 0, 0, pl.Position * 1000))
 
    Wait 0.01
 
  Loop Until (pl.Position >= pl.Duration)
 
 
 
'''End'''
 
 
 
'''Public''' Sub Button2_Click()
 
 
 
  pl.Stop()
 
  pl.Close()
 
 
 
'''End'''
 
 
 
'''Public''' Sub Slider1_Change()
 
 
 
  pitch = Slider1.Value / 100
 
  pit["pitch"] = pitch
 
  ValueBox1.Value = pitch
 
 
 
'''End'''
 
 
 
'''Public''' Sub Slider2_Change()
 
 
 
  tempo = Slider2.Value / 100
 
  pit["tempo"] = tempo
 
  ValueBox2.Value = tempo
 
 
 
'''End'''
 
 
 
'''Public''' Sub Slider3_Change()
 
 
 
  volume = Slider3.Value / 100
 
  vol["volume"] = volume          <FONT Color=gray>' ''"volume" è una proprietà dell'omonimo plugin "volume"''</font>
 
  ValueBox3.Value = volume
 
 
 
'''End'''
 
 
 
 
 
====Eseguire un file MP3====
 
Attualmente ed incomprensibilmente, eseguendo un file MP3, la proprietà "''.Duration''" della Classe "''MediaPipeline''" ritorna solo e sempre il valore zero. Pertanto, per poter uscire alla fine dell'esecuzione del file audio MP3 usando il valore conosciuto della durata del file audio medesimo, bisognerà ricavarlo attraverso un complesso algoritmo. <SUP>&#091;[[#Note|Nota 3]]&#093;</sup>
 
 
 
Mostriamo di seguito il codice completo:
 
'''Public''' Sub Main()
 
 
 
  Dim pl As MediaPipeline
 
  Dim src, dcd, snk As MediaControl
 
  Dim fileMP3 As String
 
  Dim dur, i As Integer
 
  Dim tm As Date
 
   
 
  fileMP3 = "<FONT color=gray>''/percorso/del/file.mp3''</font>"
 
 
 
  pl = New MediaPipeline
 
   
 
  src = New MediaControl(pl, "filesrc")
 
  src["location"] = fileMP3
 
   
 
  dcd = New MediaControl(pl, "<FONT color=#B22222>mad</font>")
 
  snk = New MediaControl(pl, "alsasink")
 
  src.LinkTo(dcd)
 
  dcd.LinkTo(snk)
 
   
 
  pl.Play()
 
 
 
<FONT Color=gray>' ''Invoca la funzione per ottenere la durata del file audio MP3:''</font>
 
  dur = DurataMP3(fileMP3)
 
 
 
  tm = Now
 
 
 
  Repeat
 
    i = DateDiff(tm, Now, gb.Millisecond)
 
    Write "\rTempo: " & Date(0, 0, 0, 0, 0, 0, i)
 
    Wait 0.001
 
  Until i >= dur
 
 
 
<FONT Color=gray>' ''Libera la memoria e va in chiusura:''</font>
 
    pl.Stop
 
    pl.Close
 
   
 
    Write "\nEsecuzione terminata !"
 
 
 
'''End'''
 
 
 
'''Private''' Function DurataMP3(mp3 As String) As Integer
 
 
 
  Dim s, ver_mp3, layer, prot, medio, circa As String
 
  Dim j, frequenza, num_frame, brVar, totBR, durata1, durata2, durata As Integer
 
  Dim vB, lB, brB, frB As Byte
 
  Dim initium, secundum, tertium, bitrate, cpf As Short
 
 
 
  Print "File audio mp3: '"; File.Name(mp3)
 
 
 
  s = File.Load(mp3)
 
  Print "\nDimensione: "; Len(s); " byte"
 
 
 
  initium = 1
 
 
 
  For j = initium To Len(s) - 1
 
    If (Asc(s, j) = 255) And (Asc(s, j + 1) > 241) And (Asc(s, j + 2) > 15) Then
 
      secundum = Asc(s, j + 1)
 
      tertium = Asc(s, j + 2)
 
<FONT Color=gray>' ''Individua 2° byte dell'header per estrarre le seguenti informazioni generali sul file mp3:''
 
' ''- vesione MPEG;''
 
' ''- layer.''
 
' ''I primi 3 bit più significativi (tutti posti a 1) appartengono con quelli del 1° byte all'identificazione dell'header.''</font>
 
 
 
<FONT Color=gray>' ''Viene individuata la versione del file mp3:''</font>
 
      vB = Asc(s, j + 1) And 24
 
      Select Case vB
 
        Case 0
 
          ver_mp3 = "2.5"
 
        Case 16
 
          ver_mp3 = "2"
 
        Case 24
 
          ver_mp3 = "1"
 
      End Select
 
     
 
<FONT Color=gray>' ''Viene individuato il "Layer" del file mp3:''</font>
 
      lB = Asc(s, j + 1) And 6
 
      Select Case lB
 
        Case 2
 
          layer = "III"
 
        Case 4
 
          layer = "II"
 
        Case 6
 
          layer = "I"
 
      End Select
 
     
 
      Print "Versione MPEG = "; ver_mp3, "Layer = "; layer
 
     
 
<FONT Color=gray>' ''Si analizza, quindi, il terzo byte per estrarre le seguenti informazioni generali sul file mp3:''
 
' ''- bitrate;''
 
' ''- frequenza di campionamento;''
 
' ''Tali informazioni sono condizionate dalla versione e dal layer del file MPEG.''</font>
 
      brB = Asc(s, j + 2) And 240
 
      bitrate = EstraeBitRate(ver_mp3, layer, brB)
 
     
 
      frB = Asc(s, j + 2) And 12
 
      frequenza = EstraeFrequenza(ver_mp3, frB)
 
     
 
      Exit
 
     
 
    Endif
 
  Next
 
 
 
  For j = 1 To Len(s) - 2
 
    If (Asc(s, j) = 255) And (Asc(s, j + 1) = secundum) Then Inc num_frame
 
    If (Asc(s, j) = 255) And (Asc(s, j + 1) = secundum) And (Asc(s, j + 2) <> tertium) Then
 
      Inc brVar
 
      brB = Asc(s, j + 2) And 240
 
      totBR += EstraeBitRate(ver_mp3, layer, brB)
 
    Endif
 
  Next
 
 
 
  If brVar > num_frame * 0.1 Then
 
 
 
    Select Case layer
 
      Case "I"
 
        cpf = 384
 
      Case "II"
 
        cpf = 1152
 
      Case "III"
 
        If ver_mp3 = "1" Then
 
          cpf = 1152
 
        Else
 
          cpf = 576
 
        Endif
 
    End Select
 
    durata1 = Fix((num_frame * cpf / frequenza) * 1000)
 
    bitrate = totBR / brVar
 
    durata2 = Fix((Len(s) / bitrate) * 8)
 
    durata = (durata1 + durata2) / 2
 
    medio = "variabile medio "
 
    circa = "circa "
 
  Else
 
    durata = Fix((Len(s) / bitrate) * 8)
 
  Endif
 
 
 
  Print "BitRate " & medio & "= "; bitrate; " kbps"
 
  Print "Frequenza = hz "; frequenza
 
  Print "Durata " & circa & "= "; Date(0, 0, 0, 0, 0, 0, durata)
 
 
 
  Return durata
 
 
 
'''End'''
 
 
 
'''Private''' Function EstraeBitRate(Vmpeg As String, layB As String, bitB As Byte) As Short
 
 
 
  Dim velCamp As Short
 
 
 
  If Vmpeg = "1" Then  <FONT Color=gray>' ''Nel caso di Mpeg vers. 1''</font>
 
    Select Case layB    <FONT Color=gray>' ''Verifica il Layer''</font>
 
      Case "I"
 
        Select Case bitB
 
          Case 16
 
            velCamp = 32
 
          Case 32
 
            velCamp = 64
 
          Case 48
 
            velCamp = 96
 
          Case 64
 
            velCamp = 128
 
          Case 80
 
            velCamp = 160
 
          Case 96
 
            velCamp = 192
 
          Case 112
 
            velCamp = 224
 
          Case 128
 
            velCamp = 256
 
          Case 144
 
            velCamp = 288
 
          Case 160
 
            velCamp = 320
 
          Case 176
 
            velCamp = 352
 
          Case 192
 
            velCamp = 384
 
          Case 208
 
            velCamp = 416
 
          Case 224
 
            velCamp = 448
 
        End Select
 
      Case "II"
 
        Select Case bitB
 
          Case 16
 
            velCamp = 32
 
          Case 32
 
            velCamp = 48
 
          Case 48
 
            velCamp = 56
 
          Case 64
 
            velCamp = 64
 
          Case 80
 
            velCamp = 80
 
          Case 96
 
            velCamp = 96
 
          Case 112
 
            velCamp = 112
 
          Case 128
 
            velCamp = 128
 
          Case 144
 
            velCamp = 160
 
          Case 160
 
            velCamp = 192
 
          Case 176
 
            velCamp = 224
 
          Case 192
 
            velCamp = 256
 
          Case 208
 
            velCamp = 320
 
          Case 224
 
            velCamp = 384
 
        End Select
 
      Case "III"
 
        Select Case bitB
 
          Case 16
 
            velCamp = 32
 
          Case 32
 
            velCamp = 40
 
          Case 48
 
            velCamp = 48
 
          Case 64
 
            velCamp = 56
 
          Case 80
 
            velCamp = 64
 
          Case 96
 
            velCamp = 80
 
          Case 112
 
            velCamp = 96
 
          Case 128
 
            velCamp = 112
 
          Case 144
 
            velCamp = 128
 
          Case 160
 
            velCamp = 160
 
          Case 176
 
            velCamp = 192
 
          Case 192
 
            velCamp = 224
 
          Case 208
 
            velCamp = 256
 
          Case 224
 
            velCamp = 320
 
        End Select
 
    End Select
 
   
 
  Else
 
   
 
    Select Case layB    <FONT Color=gray>' ''Verifica il Layer''</font>
 
      Case "I"
 
        Select Case bitB
 
          Case 16
 
            velCamp = 32
 
          Case 32
 
            velCamp = 48
 
          Case 48
 
            velCamp = 56
 
          Case 64
 
            velCamp = 64
 
          Case 80
 
            velCamp = 80
 
          Case 96
 
            velCamp = 96
 
          Case 112
 
            velCamp = 112
 
          Case 128
 
            velCamp = 128
 
          Case 144
 
            velCamp = 144
 
          Case 160
 
            velCamp = 160
 
          Case 176
 
            velCamp = 176
 
          Case 192
 
            velCamp = 192
 
          Case 208
 
            velCamp = 224
 
          Case 224
 
            velCamp = 256
 
        End Select
 
      Case "II" To "III"
 
        Select Case bitB
 
          Case 16
 
            velCamp = 8
 
          Case 32
 
            velCamp = 16
 
          Case 48
 
            velCamp = 24
 
          Case 64
 
            velCamp = 32
 
          Case 80
 
            velCamp = 40
 
          Case 96
 
            velCamp = 48
 
          Case 112
 
            velCamp = 56
 
          Case 128
 
            velCamp = 64
 
          Case 144
 
            velCamp = 80
 
          Case 160
 
            velCamp = 96
 
          Case 176
 
            velCamp = 112
 
          Case 192
 
            velCamp = 128
 
          Case 208
 
            velCamp = 144
 
          Case 224
 
            velCamp = 320
 
        End Select
 
    End Select
 
   
 
  Endif
 
 
 
  Return velCamp
 
 
 
'''End'''
 
 
 
'''Private''' Function EstraeFrequenza(Vmpeg As String, fre As Byte) As Integer
 
 
 
  Dim frq As Integer
 
 
 
    Select Case Vmpeg
 
      Case "1"          <FONT Color=gray>' ''Nel caso di Mpeg vers. 1''</font>
 
      Select Case fre
 
        Case 0
 
          frq = 44100
 
        Case 4
 
          frq = 48000
 
        Case 8
 
          frq = 32000
 
      End Select
 
    Case "2"          <FONT Color=gray>' ''Nel caso di Mpeg vers. 2''</font>
 
      Select Case fre
 
        Case 0
 
          frq = 22050
 
        Case 4
 
          frq = 24000
 
        Case 8
 
          frq = 16000
 
      End Select
 
    Case "2.5"        <FONT Color=gray>' ''Nel caso di Mpeg vers. 2.5''</font>
 
      Select Case fre
 
        Case 0
 
          frq = 11025
 
        Case 4
 
          frq = 12000
 
        Case 8
 
          frq = 8000
 
      End Select
 
  End Select
 
 
 
  Return frq
 
 
 
'''End'''
 
 
 
 
 
====Eseguire un file AAC====
 
'''Public''' Sub Main()
 
 
 
  Dim pl As MediaPipeline
 
  Dim src, dcd, snk As MediaControl
 
 
 
    pl = New MediaPipeline
 
   
 
    src = New MediaControl(pl, "filesrc")
 
    src["location"] = "<FONT color=gray>''/percorso/del/file.aac''</font>"  <FONT color=gray>' ''"location" è una proprietà del plugin "filesrc"''</font>
 
   
 
    dcd = New MediaControl(pl, "<FONT color=#B22222>faad</font>")
 
    snk = New MediaControl(pl, "alsasink")
 
    src.LinkTo(dcd)
 
    dcd.LinkTo(snk)
 
   
 
    pl.Play()
 
       
 
    While pl.Duration > pl.Position
 
      Write #File.Out, "\rTempo: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
 
      Wait 0.001
 
    Wend
 
   
 
'''End'''
 
 
 
 
 
====Eseguire un file FLAC====
 
'''Public''' Sub Main()
 
 
 
  Dim pl As MediaPipeline
 
  Dim src, fpa, fde, snk As MediaControl
 
 
 
    pl = New MediaPipeline
 
   
 
    src = New MediaControl(pl, "filesrc")
 
    src["location"] = "<FONT color=gray>''/percorso/del/file.flac''</font>"  <FONT color=gray>' ''"location" è una proprietà del plugin "filesrc"''</font>
 
   
 
    fpa = New MediaControl(pl, "<FONT color=#B22222>flacparse</font>")
 
    fde = New MediaControl(pp, "<FONT color=#B22222>flacdec</font>")
 
    snk = New MediaControl(pl, "alsasink")
 
   
 
    src.LinkTo(fpa)
 
    fpa.LinkTo(fde)
 
    fde.LinkTo(snk)
 
   
 
    pl.Play()
 
       
 
    While pl.Duration > pl.Position
 
      Write #File.Out, "\rTempo: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
 
    Wend
 
   
 
'''End'''
 
 
 
 
 
===Interfacciare le Classi ''MediaControl'' e ''MediaPipeline'' con il plugin "''jackaudiosink''" di ''GStreamer'' per eseguire i file audio===
 
Per eseguire i file audio con le Classi ''MediaControl'' e ''MediaPipeline'' è possibile anche effettuare un interfacciamento tra il programma Gambas e il server audio JACK. Per fare ciò, ci si servirà dell'apposito plugin di ''GStreamer'', chiamato "''jackaudiosink''".
 
 
 
Ovviamente bisognerà avere l'accortezza di avviare il server Jack (per esempio avviando il programma ''qjackctl'') <SPAN Style="text-decoration:underline">prima</span> di lanciare il programma Gambas.
 
 
 
All'avvio del programma viene creata dal server ''Jack'' una connessione tra il programma sorgente Gambas e la destinazione (di default il primo canale audio d'uscita disponibile della propria scheda audio).
 
 
 
 
 
Mostriamo un semplice esempio di esecuzione di un file wav in un'applicazione ''a riga di comando'':
 
'''Public''' Sub Main()
 
 
 
  Dim pl As MediaPipeline
 
  Dim src, prs, cnv, snk As MediaControl
 
 
  pl = New MediaPipeline
 
 
 
  src = New MediaControl(pl, "filesrc")
 
  src["location"] = "<FONT color=gray>''/percorso/del/file.wav''</font>"      <FONT color=gray>' ''"location" è una proprietà del plugin "filesrc"''</font>
 
  prs = New MediaControl(pl, "wavparse")
 
  cnv = New MediaControl(pl, "audioconvert")
 
  snk = New MediaControl(pl, "jackaudiosink")
 
 
 
  src.LinkTo(prs)
 
  prs.LinkTo(cnv)
 
  cnv.LinkTo(snk)
 
 
 
  pl.Play()
 
 
 
  Print "\nDurata: " & Date(0, 0, 0, 0, 0, 0, pl.Duration * 1000)
 
  Wait pl.Duration
 
 
 
  pl.Stop()
 
  pl.Close()
 
 
 
'''End'''
 
 
 
 
 
 
 
 
 
 
 
=Note=
 
[1] La stesura di paragrafo è stata possibile anche grazie al fondamentale apporto e studio del membro [http://www.gambas-it.org/smf/index.php?action=profile;u=1141 allegfede] del forum gambas-it.org .
 
 
 
[2] Per avere contezza di quali siano i plugin ed i filtri da utilizzare, è opportuno vedere sulla rete la [https://gstreamer.freedesktop.org/documentation/ documentazione di GStreamer] e gli eventuali esempi pratici.
 
 
 
[3] Si segnalano come riferimento le seguenti pagine della Wiki:
 
* http://www.gambas-it.org/wiki/index.php?title=La_struttura_di_un_file_MPEG
 
* http://www.gambas-it.org/wiki/index.php?title=Calcolare_la_durata_di_un_file_MP3
 

Versione attuale delle 00:47, 23 set 2022