Differenze tra le versioni di "Eseguire un file MIDI mediante il componente gb.media"

Da Gambas-it.org - Wikipedia.
 
(47 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
Per eseguire ed ascoltare un file Midi, utilizzando un breve codice, è possibile adoperare le funzionalità della multipiattaforma ''gstreamer'', attivando il componente ''gb.media''.
 
Per eseguire ed ascoltare un file Midi, utilizzando un breve codice, è possibile adoperare le funzionalità della multipiattaforma ''gstreamer'', attivando il componente ''gb.media''.
  
E' necessario aver installato il file banco di suoni di default di Timidity: "''/usr/share/sounds/sf2/<FONT color=#B22222>TimGM6mb.sf2</font>''", oppure di FluidSynth: "''/usr/share/sounds/sf2/<FONT color=#B22222>FluidR3_GM.sf2</font>''".
+
E' necessario aver installato il file banco di suoni di default di Timidity:
 
+
''/usr/share/sounds/sf2/<FONT color=#B22222>TimGM6mb.sf2</font>''
 +
oppure di FluidSynth:
 +
''/usr/share/sounds/sf2/<FONT color=#B22222>FluidR3_GM.sf2</font>''
  
 
=La classe ''MediaPlayer''=
 
=La classe ''MediaPlayer''=
 
Si utilizzeranno i metodi specifici della Classe ''MediaPlayer'' del componente ''gb.media''.
 
Si utilizzeranno i metodi specifici della Classe ''MediaPlayer'' del componente ''gb.media''.
  
 +
Gli elementi essenziali per eseguire un file Midi con la Classe ''MediaPlayer'' sono:
 +
* la Proprietà ".Url" per caricare il file (se il file è memorizzato su dispositivo di memoria, allora il suo percorso andrà passato mediante il Metodo ".Url" della Classe statica "Media"; se il file è eseguito da un indirizzo web, allora sarà passato direttamente l'indirizzo web);
 +
* il Metodo ".Play()" per avviare l'esecuzione del file Midi;
 +
* la Proprietà ".Duration" per far eseguire il file Midi per l'intera sua durata;
 +
* il Metodo ".Close()" per chiudere il mediaplayer.
  
===Utilizzo in un'applicazione grafica===
+
===Utilizzo in un'applicazione ''a riga di comando''===
Ecco di seguito un semplicissimo codice per lanciare ed ascoltare uno standard file Midi (.mid) in un'applicazione grafica utilizzando un Timer.
+
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 As "MediaPlayer1"
 +
    .URL = Media.URL("<FONT Color=darkgreen>''/percorso/del/file.mid''</font>")
 +
    .Play()
 +
    Print "Durata del file Midi: \e[34m"; Str(Time(0, 0, 0, .Duration * 1000))
 +
    Repeat
 +
      Write "\r\e[0mTempo trascorso:      \e[1m\e[31m" & Str(Time(0, 0, 0, .Position * 1000))
 +
      Wait 0.01
 +
    Until bo
 +
    .Stop
 +
    .Close
 +
  End With
 +
 +
  Write "\n\e[0mEsecuzione terminata !"
 +
<FONT color=gray>' ''Avendo utilizzato l'Evento "Application_Read()", è necessario invocare l'istruzione "Quit" per terminare il programma:''</font>
 +
  Quit
 +
 +
End
 +
 +
 +
Public Sub MediaPlayer1_End()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando l'escuzione è terminata''</font>
 +
 +
  bo = True
 +
 +
End
 +
 +
 +
Public Sub Application_Read() <FONT color=gray>' ''Premendo il tasto "Invio" della tastiera, si arresta il programma''</font>
 +
 +
  bo = True
 +
 +
End
 +
 
 +
===Uso di applicazione grafica===
 +
Vediamo un semplice codice, con il quale sarà possibile ascoltare, porre in pausa e terminare un file Midi in un'applicazione grafica.
 
<BR>Porremo sul ''Form'' del progetto:
 
<BR>Porremo sul ''Form'' del progetto:
* tre ''Button'' per avviare, mettere in pausa ed arrestare l'esecuzione del file Midi;
+
* un ''ToggleButton'' per avviare ed arrestare l'esecuzione del file Midi;
 +
* un ''ToggleButton'' per porre in pausa l'esecuzione del file Midi;
 
* un ''Timer'' che ci consentirà di calcolare il tempo trascorso;
 
* un ''Timer'' che ci consentirà di calcolare il tempo trascorso;
* un ''RadioButton'' per far ripetere a volontà il medesimo file Midi:
+
  Private mp As New <FONT color=#B22222>MediaPlayer</font>
  '''Private''' mp As New <FONT color=#B22222>MediaPlayer</font>
 
 
   
 
   
 
   
 
   
  '''Public''' Sub Form_Open()
+
  Public Sub Form_Open()
 
   
 
   
<FONT color=gray>' ''Carica il file Midi .mid:''</font>
+
  ToggleButton2.Enabled = False
  mp.URL = Media.URL("''/percorso/del/file.mid''")
 
 
   
 
   
  <FONT color=gray>' ''Facciamo in modo che il "Timer", alla sua prima attivazione, parta senza alcun ritardo:''</font>
+
  <FONT color=gray>' ''Carica un file Midi:''</font>
   Timer1.Delay = 1
+
   mp.URL = Media.URL("<FONT color=darkgreen>''/percorso/del/file/Midi''</font>")
 
   
 
   
  '''End'''
+
  End
 
 
 
   
 
   
'''Public''' Sub Button1_Click()
 
 
   
 
   
  suona()
+
Public Sub ToggleButton1_Click()
 
   
 
   
  '''End'''
+
  If ToggleButton1.Value Then
 +
    ToggleButton2.Enabled = True
 +
    Esegue()
 +
  Else
 +
  <FONT Color=gray>' ''Chiama la funzione per arrestare l'esecuzione del file Midi:''</font>
 +
    Arresta()
 +
    ToggleButton2.Value = False
 +
    ToggleButton2.Enabled = False
 +
  Endif
 
   
 
   
  '''Public''' Sub suona()
+
  End
 
 
<FONT color=gray>' ''Avvia l'ascolto del file Midi:''</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 Timer1_Timer()
 
   
 
   
  '''Public''' Sub Button2_Click()
+
  <FONT Color=gray>' ''Mostra in console la durata del file Midi e il tempo trascorso:''</font>
 +
  Write "\rDurata: " & Time(0, 0, 0, mp.Duration * 1000) &
 +
        "  -  Tempo trascorso: " & Time(0, 0, 0, mp.Position * 1000)
 
   
 
   
  <FONT color=gray>' ''Mette in "pausa" l'ascolto del file Midi.''
+
  <FONT Color=gray>' ''Se la posizione corrente è uguale o maggiore della durata complessiva del file Midi, allora arresta l'esecuzione del file Midi:''</font>
' ''(Per continuare l'ascolto del file, si dovrà nuovamente attivare la proprietà ".Play"):</font>
+
  If mp.Position >= mp.Duration Then Arresta()
  mp.<FONT color=#B22222>Pause</font>
 
 
   
 
   
  '''End'''
+
  End
 
   
 
   
'''Public''' Sub Button3_Click()
 
 
   
 
   
  RadioButton1.Value = False
+
Public Sub Esegue()
 
   
 
   
  <FONT color=gray>' ''Chiama la funzione per arrestare l'esecuzione del file Midi:''</font>
+
  <FONT Color=gray>' ''Avvia l'ascolto del file Midi:''</font>
  arresta()
+
  mp.Play
 
   
 
   
  '''End'''
+
  With Timer1
 +
  <FONT Color=gray>' ''Il "Timer" si attiva ogni 70 millesimi di secondo:''</font>
 +
    .Delay = 70
 +
    .Start
 +
  End With
 
   
 
   
 +
End
 
   
 
   
'''Public''' Sub arresta()
 
 
   
 
   
  <FONT color=gray>' ''Arresta l'ascolto del file Midi:''</font>
+
  Public Sub Arresta()
  mp.<FONT color=#B22222>Stop</font>
 
 
   
 
   
  Timer1.Stop
+
<FONT Color=gray>' ''Arresta l'ascolto del file Midi:''</font>
 +
  mp.Stop
 +
  mp.Close
 +
  Timer1.Stop
 +
  ToggleButton1.Value = False
 
   
 
   
  <FONT color=gray>' ''Se è stato cliccato sul "RadioButton", verrà ripetuta l'esecuzione del file Midi:''</font>
+
  End
  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 ToggleButton2_Click()
 
   
 
   
  '''Public''' Sub Timer1_Timer()
+
  <FONT Color=gray>' ''Mette in "pausa" l'ascolto del file Midi.''
   
+
  ' ''(Per continuare l'ascolto del file, si dovrà nuovamente attivare la Proprietà ".Play"):''</font>
<FONT color=gray>' ''Mostra in console la posizione, espressa in secondi, all'interno dei dati processati:''</font>
+
  If ToggleButton2.Value Then
  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))
+
    mp.Pause
 +
   Else
 +
    If ToggleButton1.Value Then Esegue()
 +
  Endif
 
   
 
   
  <FONT color=gray>' ''Se la posizione corrente è uguale o maggiore della durata complessiva del brano Midi,''
+
  End
' ''allora arresta l'esecuzione del file Midi (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 del ''Timer''.
In quest'altro esempio, simile al precedente, verrà utilizzato un ciclo al posto di un oggetto ''Timer'':
+
<BR>Si porrà anche un Controllo ''Slider'' per poter modificare il volume.
 
  Private mp As New MediaPlayer
 
  Private mp As New MediaPlayer
 
   
 
   
 
   
 
   
  '''Public''' Sub Form_Open()
+
  Public Sub Form_Open()
    
+
 +
  With Slider1
 +
    .MinValue = 0
 +
    .MaxValue = 100
 +
    .Value = 50
 +
   End With
 +
 +
  ToggleButton2.Enabled = False
 +
 
  <FONT color=gray>' ''Carica un file Midi:''</font>
 
  <FONT color=gray>' ''Carica un file Midi:''</font>
   mp.URL = Media.URL("''/percorso/mio/file.mid''")
+
   mp.URL = Media.URL("<FONT color=darkgreen>''/percorso/del/file/Midi''</font>")
 +
 +
End
 
   
 
   
'''End'''
 
 
 
 
   
 
   
  '''Public''' Sub Button1_Click()
+
  Public Sub ToggleButton1_Click()
 
   
 
   
   suona()
+
   If ToggleButton1.Value Then
 +
    ToggleButton2.Enabled = True
 +
    Esegue()
 +
  Else
 +
<FONT color=gray>' ''Chiama la funzione per arrestare l'esecuzione del file Midi:''</font>
 +
    Arresta()
 +
    ToggleButton2.Value = False
 +
    ToggleButton2.Enabled = False
 +
  Endif
 
   
 
   
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub suona()
+
  Public Sub Esegue()
 
   
 
   
 
  <FONT color=gray>' ''Avvia l'ascolto del file Midi:''</font>
 
  <FONT color=gray>' ''Avvia l'ascolto del file Midi:''</font>
 
   mp.Play
 
   mp.Play
 
    
 
    
   Do
+
   Repeat
  <FONT color=gray>' ''Una brevissima pausa consente di agire sugli eventuali oggetti posti sul Form:''</font>
+
  <FONT color=gray>' ''Una brevissima pausa consente di agire sugli eventuali "Controlli" posti sul Form:''</font>
 
     Wait 0.01
 
     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))
+
     Write "\rDurata: " & Str(Time(0, 0, 0, mp.Duration * 1000)) &
   Loop Until mp.Position >= mp.Duration
+
          "  -  Tempo trascorso: " & Str(Time(0, 0, 0, mp.Position * 1000))
 
+
   Until (mp.Position >= mp.Duration)
   arresta()
+
 
+
   Arresta()
  '''End'''
+
 +
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub Button2_Click()
+
  Public Sub Arresta()
 
 
<FONT color=gray>' ''Mette in "pausa" l'ascolto del file Midi.''
 
' ''(Per continuare l'ascolto del file, si dovrà nuovamente attivare la proprietà ".Play").''</font>
 
  mp.Pause
 
 
   
 
   
  '''End'''
+
  <FONT color=gray>' ''Arresta l'ascolto del file Midi:''</font>
 +
  mp.Stop
 +
  mp.Close
 +
  Timer1.Stop
 +
  ToggleButton1.Value = False
 
   
 
   
 +
End
 
   
 
   
'''Public''' Sub Button3_Click()
 
 
 
  RadioButton1.Value = False
 
 
 
  mp.Position = mp.Duration + 1
 
 
 
'''End'''
 
 
   
 
   
 +
Public Sub ToggleButton2_Click()
 
   
 
   
'''Public''' Sub arresta()
+
  <FONT color=gray>' ''Mette in "pausa" l'ascolto del file Midi.''
 
+
' ''(Per continuare l'ascolto del file, si dovrà nuovamente attivare la Proprietà ".Play"):''</font>
  <FONT color=gray>' ''Se è stato cliccato sul "RadioButton", verrà ripetuta l'esecuzione del file Midi:''</font>
+
   If ToggleButton2.Value Then  
   If RadioButton1.Value Then
+
     mp.Pause
     mp.Position = 0
 
    suona()
 
 
   Else
 
   Else
<FONT color=gray>' ''Altrimenti arresta l'ascolto del file Midi:''</font>
+
     If ToggleButton1.Value Then Esegue()
     mp.Stop
 
 
   Endif
 
   Endif
 
 
'''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'':
 
'''Public''' Sub Main()
 
 
   
 
   
  Dim mp As MediaPlayer
+
End
 
+
  With mp = New MediaPlayer
+
    .URL = Media.URL("''/percorso/mio/file.mid''")
+
Public Sub Slider1_Change()
    .Play
+
   
  End With
+
   mp.Audio.Volume = Slider1.Value / 100
 
+
  Do
+
  End
  <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))
 
  Loop Until mp.Position >= mp.Duration
 
 
 
  mp.Stop
 
 
 
  '''End'''
 
 
 
 
 
  
 
==La proprietà ''.Duration''==
 
==La proprietà ''.Duration''==
La proprietà ''.Duration'' restituisce un valore di tipo Float che rappresenta la durata del brano musicale espresso in secondi.
+
La Proprietà ".Duration" restituisce un valore di tipo Float che rappresenta la durata del file Midi 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).
+
<BR>Poiché detta proprietà ritorna più precisamente la durata dei dati processati, essa potrà essere utilizzabile <SPAN Style="text-decoration:underline">solo successivamente all'attivazione del Metodo ".Play"</span>.
 
+
Public Sub Main()
 +
 +
  Dim mp As MediaPlayer
 +
 +
  With mp = New MediaPlayer
 +
    .URL = Media.URL("<FONT Color=darkgreen>''/percorso/del/file/Midi''</font>")
 +
    .Play
 +
    Print "Durata: \e[34m"; Time(0, 0, 0, .Duration * 1000)
 +
    Repeat
 +
      Wait 0.01
 +
      Write "\r      \e[31m" & Str(Time(0, 0, 0, .pos * 1000))
 +
    Until .Pos >= .Duration
 +
    .Stop
 +
    .Close
 +
  End With
 +
 +
End
 +
oppure più semplicemente:
 +
    ......
 +
    .Play
 +
    Print "Durata: \e[34m"; Time(0, 0, 0, .Duration * 1000)
 +
    Wait .Duration
 +
    .Stop
 +
    .Close
 +
  End With
  
==La proprietà ''.Position''==
+
==La Proprietà ".Position"==
La proprietà ''.Position'' restituisce un valore di tipo Float che rappresenta la posizione, espressa in secondi all'interno dei dati processati.
+
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.
 
<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''==
 
==Modificare il ''Volume''==
Per modificare il volume dell'ascolto si dovrà utilizzare la proprietà "''.Volume''" della proprietà ''.Audio'' della Classe ''MediaPlayer''.
+
Per modificare il volume dell'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:
+
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>
 
  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>'':
 
nel secondo caso il volume è impostato mediante un valore di tipo ''<SPAN style="text-decoration:underline">Float</span>'':
 
  mp.Audio.<FONT color=#B22222>Volume</font> = valore_di_tipo_Float
 
  mp.Audio.<FONT color=#B22222>Volume</font> = valore_di_tipo_Float
 
  
 
==Annullare l'audio immediatamente==
 
==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''.
+
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
 
  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 che si sta eseguendo.
  
==L'evento ''_AboutToFinish''==
+
==L'evento _End()==
L'evento ''_AboutToFinish'' si scatena circa un secondo prima della fine della durata del file che si sta eseguendo.
+
L'evento "_End()" si scatena quando l'esecuzione del file Midi è terminata.
 
+
<BR>Esempio:
 
+
Private bo As Boolean
==L'evento ''_End''==
+
L'evento ''_End'' si scatena quando la durata del file è terminata.
+
 
+
Public Sub Main()
 
+
 +
  Dim mp As MediaPlayer
 +
 +
  With mp = New MediaPlayer As "MediaPlayer1"
 +
    .URL = Media.URL("<FONT Color=darkgreen>''/percorso/del/file/Midi''</font>")
 +
    .Play
 +
    Print "\rDurata del file Midi: "; Str(Time(0, 0, 0, .Duration * 1000))
 +
    Repeat
 +
      Write "\r\e[0mTempo trascorso:      \e[31m" & Str(Time(0, 0, 0, .Position * 1000))
 +
      Wait 0.01
 +
    Until bo
 +
    .Stop
 +
    .Close
 +
  End With
 +
 +
  Write "\n\e[0mEsecuzione terminata !"
 +
 +
End
 +
 +
 +
Public Sub MediaPlayer1<FONT Color=#B22222>_End()</font>  <FONT Color=gray>' ''Questo Evento viene sollevato, quando l'esecuzione è terminata''</font>
 +
 +
  bo = True
 +
 +
End
  
 
==Gli effetti video con i ''plug-in''==
 
==Gli effetti video con i ''plug-in''==
 
E' possibile ottenere simpatici effetti video utilizzando i ''plug-in'' resi disposibili da ''GStreamer''.
 
E' possibile ottenere simpatici effetti video utilizzando i ''plug-in'' resi disposibili da ''GStreamer''.
 
+
<BR>Gli effetti video disponibili sono:
 +
"goom", "goom2k1", "monoscope", "spacescope", "spectrascope", "synaescope", "wavescope"
 
In tal caso si farà uso anche della Classe ''MediaControl'' che è serve per gestire appositamente i ''plug-in'' di ''GStreamer''.
 
In tal caso si farà uso anche della Classe ''MediaControl'' che è serve per gestire appositamente i ''plug-in'' di ''GStreamer''.
 
+
<BR>Per consentire l'uso dei [https://gstreamer.freedesktop.org/documentation/additional/splitup.html?gi-language=c plugin] dei visualizzatori audio, è necessario avere installati nel sistema i seguenti pacchetti dei [https://gstreamer.freedesktop.org/documentation/additional/splitup.html?gi-language=c plugin]:
 +
<BR> - gstreamer1.0-plugins-bad
 +
<BR> - gstreamer1.0-plugins-base
 +
<BR> - gstreamer1.0-plugins-base-apps
 +
<BR> - gstreamer1.0-plugins-good
 +
<BR> - gstreamer1.0-plugins-ugly
  
 
Mostreremo di seguito il codice esenziale per l'utilizzo degli effetti video con i ''plug-In'' (si inserirà anche una ''DrawingArea'' sul ''Form''):
 
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
+
  Private mp As MediaPlayer
 +
 +
 +
Public Sub ToggleButton1_Click()
 
    
 
    
 +
  If ToggleButton1.Value Then
 +
    Dim DrawingArea1 As DrawingArea
 +
    Dim plugVis As MediaControl
 +
    Dim tipoPlug As String[] = ["goom", "goom2k1", "monoscope", "spacescope",
 +
                                "spectrascope", "synaescope", "wavescope"]
 +
 +
    With DrawingArea1 = New DrawingArea(Me)
 +
      .X = 10
 +
      .Y = 10
 +
      .W = 300
 +
      .H = 300
 +
      .Background = Color.Black
 +
    End With
 +
 +
    mp = New MediaPlayer As "MediaPlayer1"
 +
 +
<FONT Color=gray>' ''Imposta un plug-in grafico (ad esempio il 7° fra quelli contenuti dal vettore "tipoplug") da mostrare nella "DrawingArea" durante l'esecuzione del file audio:''</font>
 +
    plugVis = New MediaControl(mp, tipoPlug[6])
 +
    plugVis["style"] = 2    <SUP>&#91;[[#Note|nota 1]]&#93;</sup>
 +
<FONT Color=gray>' ''Si dice al MediaControl di mostrare il proprio output (gli effetti video) in uno specifico controllo GUI, solitamente una DrawingArea:''</font>
 +
    mp.SetWindow(DrawingArea1)
 +
 +
    mp.URL = Media.URL("<FONT color=darkgreen>''/percorso/del/file/Midi''</font>")
 +
 +
    mp.Play()
 +
 +
  <FONT Color=gray>' ''La seguente riga deve stare "dopo" il Metodo ".Play()", altrimenti - in caso si arresti e poi si riavvii l'esecuzione del flusso audio - l'esecuzione si arresterà dopo qualche secondo:''</font>
 +
    mp.Video.Visualisation = plugVis
 +
  Else
 +
    mp.Stop
 +
    mp.Close
 +
  Endif
 +
   
 +
End
 +
 
   
 
   
  '''Public''' Sub Form_Open()
+
  Public Sub MediaPlayer1_End()
 
 
  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.mid''</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'''
 
 
   
 
   
 +
  mp.Close
 
   
 
   
  '''Public''' Sub Form_Activate()
+
  End
 
 
<FONT Color=gray>' ''Esegue il file Midi:''</font>
 
  mp.Play()
 
 
 
'''End'''
 
  
  
 
==Interfacciare la Classe ''MediaPlayer'' con il plugin "''jackaudiosink''" di ''GStreamer'' per eseguire i file Midi==
 
==Interfacciare la Classe ''MediaPlayer'' con il plugin "''jackaudiosink''" di ''GStreamer'' per eseguire i file Midi==
Per eseguire i file Midi 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>&#091;[[#Note|Nota 1]]&#093;</sup>
+
Per eseguire i file Midi 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>&#091;[[#Note|nota 2]]&#093;</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.
 
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).
 
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 Midi in un'applicazione ''a riga di comando'':
 
Mostriamo un semplice ed essenziale esempio di esecuzione di un file Midi in un'applicazione ''a riga di comando'':
  '''Public''' Sub Main()
+
  Public Sub Main()
 
+
 
   Dim mp As MediaPlayer
 
   Dim mp As MediaPlayer
 
+
  With mp = New MediaPlayer
+
  With mp = New MediaPlayer
    .URL = Media.URL("<FONT color=gray>''/percorso/del/file.mid''</font>")
+
    .URL = Media.URL("<FONT color=darkgreen>''/percorso/del/file.mid''</font>")
    .Audio.Output = New MediaControl(mp, "jackaudiosink")
+
    .Audio.Output = New MediaControl(mp, "jackaudiosink")
    .Play
+
    .Play
  End With
+
  End With
 
+
  Sleep mp.Duration
+
  Wait mp.Duration
 
+
  mp.Stop
+
  mp.Stop
       
+
  mp.Close
  '''End'''
+
 +
  End
  
  
Riga 317: Riga 394:
 
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.
 
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 Midi impostando nei suoi argomenti il plugin ''Playbin''.
+
==Usare la Classe "MediaPipeline" con il decoder "playbin" di GStreamer==
 +
La Classe implementa un funzionale media-player; pertanto è possibile anche mediante tale Classe eseguire in modo semplice un file Midi impostando nei suoi argomenti il plugin ''Playbin''.
  
 
Mostriamo un esempio pratico in un'applicazione ''a riga di comando'':
 
Mostriamo un esempio pratico in un'applicazione ''a riga di comando'':
  '''Public''' Sub Main()
+
  Public Sub Main()
 
+
 +
  Dim pl As MediaPipeline
 +
  Dim s As String
 +
 +
  pl = New MediaPipeline(Null, "playbin")
 +
  pl["uri"] = Media.URL("<FONT color=darkgreen>''/percorso/del/file.mid''</font>")
 +
 +
  pl.Play()
 +
 +
<FONT color=gray>' ''Utilizziamo la funzione "Input" per consentire l'esecuzione del file Midi, evitando così un eccessivo aggravio di lavoro per la CPU.''
 +
' ''L'esecuzione viene interrotta, inserendo nella Console/Terminale un carattere dalla tastiera e premendo il tasto "Invio"."''</font>
 +
  Input s
 +
 +
  pl.Stop
 +
  pl.Close
 +
 +
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 pl As MediaPipeline
    
+
   Dim mc As MediaControl
    
+
   Dim s As String
  pl = New MediaPipeline(Null, "playbin")
 
  pl["uri"] = Media.URL("<FONT color=gray>''/percorso/del/file.mid''</font>")
 
 
    
 
    
  pl.State = Media.Playing
+
  pl = New MediaPipeline
  pl.Play()
 
 
    
 
    
<FONT color=gray>' ''Utilizziamo la funzione "Input" per consentire l'esecuzione del file Midi, evitando così un eccessivo''
+
  mc = New MediaControl(pl, "playbin")
' ''aggravio di lavoro per la CPU. Inoltre, premendo il tasto "Invio" viene interrotta l'esecuzione."''</font>
+
  mc["uri"] = Media.URL("<FONT color=darkgreen>''/percorso/del/file.mid''</font>")
  Input s
+
 
 +
  pl.Play()
 
    
 
    
  pl.Stop
+
<FONT color=gray>' ''Utilizziamo la funzione "Input" per consentire l'esecuzione del file Midi, evitando così un eccessivo aggravio di lavoro per la CPU.''
 
+
  ' ''L'esecuzione viene interrotta, inserendo nella Console/Terminale un carattere dalla tastiera e premendo il tasto "Invio"."''</font>
  '''End'''
+
  Input s
 +
 +
  pl.Stop
 +
  pl.Close
 +
 
 +
End
  
 +
==Usare i plugin di GStreamer con le Classi ''MediaControl'' e ''MediaPipeline'' per eseguire i file MIDI==
 +
E' possibile eseguire i file MIDI utilizzando specifici plugin di ''GStreamer'' con le Classi ''MediaControl'' e ''MediaPipeline''.  <SUP>&#091;[[#Note|Nota 3]]&#093;</sup>
  
Il plugin "''playbin''" può anche essere inserito all'interno di un oggetto della Classe ''MediaControl'', la quale rappresenta un Elemento ordinario di ''GStreamer''.
+
===Usando il plugin "decodebin"===
  '''Public''' Sub Main()
+
E' possibile utilizzare il plugin "decodebin" di ''GStreamer'':
 
+
Private bo As Boolean
 +
 +
 +
Public Sub Main()
 +
 
   Dim pl As MediaPipeline
 
   Dim pl As MediaPipeline
   Dim mc As MediaControl
+
   Dim src, dcb, con, vol, snk As MediaControl
 +
 +
  pl = New MediaPipeline As "PLine"
 +
 +
  src = New MediaControl(pl, "filesrc")
 +
  src["location"] = "<FONT color=darkgreen>''/percorso/del/file/midi''</font>"
 +
 +
  dcb = New MediaControl(pl, "decodebin")
 +
  con = New MediaControl(pl, "audioconvert")
 +
  vol = New MediaControl(pl, "volume")        <FONT color=gray>' ''<1.0 = volume <100% | 1.0 = volume 100% | >1.0 = volume >100%''</font>
 +
  vol["volume"] = 0.5
 +
  snk = New MediaControl(pl, "autoaudiosink")
 +
 +
  src.LinkTo(dcb)
 +
  dcb.LinkLaterTo(con)
 +
  con.LinkTo(vol)
 +
  vol.LinkTo(snk)
 +
 +
  pl.Play()
 +
 +
  Repeat
 +
    Write "\rTempo Trascorso: " & Str(Time(0, 0, 0, pl.Position * 1000))
 +
    Wait 0.01
 +
  Until bo
 +
 +
  pl.Close()
 +
 +
End
 +
 +
Public Sub PLine_End()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando l'esecuzione è terminata''</font>
 +
 +
  bo = True
 +
 +
End
 +
====Gli effetti video con i ''plug-in'' usando l'elemento "decodebin"====
 +
Anche con la Classe ''MediaPipeline'' è possibile ottenere gli effetti video utilizzando i ''plug-in'' resi disposibili da ''GStreamer''.
 +
Private pl As MediaPipeline
 +
 +
 +
Public Sub ToggleButton1_Click()
 +
 +
  If ToggleButton1.Value Then
 +
    Dim DrawingArea1 As DrawingArea
 +
    Dim src, dcb, tee, que1, que2 As MediaControl
 +
    Dim vcon, plug, vsnk As MediaControl
 +
    Dim acon, asnk As MediaControl
 +
    Dim tipoPlug As String[] = ["goom", "goom2k1", "monoscope", "spacescope",
 +
                                "spectrascope", "synaescope", "wavescope"]
 +
 +
    With DrawingArea1 = New DrawingArea(Me)
 +
      .X = 10
 +
      .Y = 10
 +
      .W = 300
 +
      .H = 300
 +
      .Background = Color.Black
 +
    End With
 +
 +
    pl = New MediaPipeline As "PLine"
 +
 +
    src = New MediaControl(pl, "filesrc")
 +
    src["location"] = "<FONT Color=darkgreen>''/percorso/del/file.mid''</font>"
 +
    dcb = New MediaControl(pl, "decodebin")
 +
    tee = New MediaControl(pl, "tee")
 +
    que1 = New MediaControl(pl, "queue")
 +
    vcon = New MediaControl(pl, "audioconvert")
 +
    plug = New MediaControl(pl, tipoPlug[4])
 +
    vsnk = New MediaControl(pl, "ximagesink")
 +
    que2 = New MediaControl(pl, "queue")
 +
    acon = New MediaControl(pl, "audioconvert")
 +
    asnk = New MediaControl(pl, "autoaudiosink")
 +
 +
    src.LinkTo(dcb)
 +
    dcb.LinkLaterTo(tee)
 +
<FONT Color=gray>' ''Parte video:''</font>
 +
    tee.LinkTo(que1)
 +
    que1.LinkTo(vcon)
 +
    vcon.LinkTo(plug)
 +
    plug.LinkTo(vsnk)
 +
<FONT Color=gray>' ''Parte audio:''</font>
 +
    tee.LinkTo(que2)
 +
    que2.LinkTo(acon)
 +
    acon.LinkTo(asnk)
 +
<FONT Color=gray>' ''Si dice al MediaControl di mostrare il proprio output (gli effetti video) in uno specifico controllo GUI, solitamente una DrawingArea:''</font>
 +
    vsnk.SetWindow(DrawingArea1)
 +
 +
    pl.Play()
 +
    While (pl.Duration < 0.1) Or (pl.Pos < 0.1)
 +
      Wait 0.01
 +
    Wend
 +
 +
    Wait pl.Duration
 +
 +
  Else
 +
    pl.Stop
 +
    pl.Close
 +
  Endif
 
    
 
    
 
+
End
  pl = New MediaPipeline
+
 
+
  mc = New MediaControl(pl, "playbin")
+
Public Sub PLine_Position()
  mc["uri"] = Media.URL("<FONT color=gray>''/percorso/del/file.mid''</font>")
+
 
+
  Me.Title = Str(Time(0, 0, 0, pl.Pos * 1000))
  pl.State = Media.Playing
+
  pl.Play()
+
End
 
+
  <FONT color=gray>' ''Utilizziamo la funzione "Input" per consentire l'esecuzione del file Midi, evitando così un eccessivo''
+
' ''aggravio di lavoro per la CPU. Inoltre, premendo il tasto "Invio viene interrotta l'esecuzione."''</font>
+
Public Sub PLine_End()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando l'esecuzione è terminata''</font>
  Input s
+
 
+
  pl.Close
  pl.Stop
+
  ToggleButton1.Value = False
 
+
  '''End'''
+
  End
  
 
+
===Usando i plugin specifici di GStreamer per il Midi===
==Utilizzare i plugin di GStreamer con le Classi ''MediaControl'' e ''MediaPipeline'' per eseguire i file MIDI==
+
I plugin specifici di ''GStreamer utilizzabili per il MIDI sono:
E' possibile eseguire i file MIDI utilizzando specifici plugin di ''GStreamer'' con le Classi ''MediaControl'' e ''MediaPipeline''.  <SUP>&#091;[[#Note|Nota 2]]&#093;</sup>
 
 
 
I plugin specifici da utilizzare per il MIDI sono:
 
 
* ''midiparse'': interpreta i file MIDI e li converte in eventi MIDI;
 
* ''midiparse'': interpreta i file MIDI e li converte in eventi MIDI;
 
* ''fluiddec'': effettua il render degli eventi MIDI in campioni audio grezzi.
 
* ''fluiddec'': effettua il render degli eventi MIDI in campioni audio grezzi.
  
Mostriamo di seguito un esempio in ambiente grafico per l'esecuzione dei file MIDI, nel quale sarà possibile impostare i valori della frequenza di campionamento (rate) e dei canali, nonché modificare in ''tempo reale'' mediante due ''Slider'' la tonalità e il tempo di esecuzione. Quest'ultime due impostazione verranno effettuate con il plugin "pitch", considerando che:
+
Mostriamo di seguito un esempio in ambiente grafico per l'esecuzione dei file MIDI, nel quale sarà possibile impostare i valori della frequenza di campionamento (rate) e dei canali, nonché modificare in ''tempo reale'' mediante tre ''Slider'' la tonalità, il tempo di esecuzione e il 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.00;
 
* per impostare la tonalità si userà l'omonima proprietà "pitch": il valore di partenza predefinito è 1.00;
 
* per impostare la velocità del tempo di esecuzione si userà la proprietà "tempo": il valore di partenza predefinito è 1.00 .
 
* per impostare la velocità del tempo di esecuzione si userà la proprietà "tempo": il valore di partenza predefinito è 1.00 .
 
  Private pl As MediaPipeline
 
  Private pl As MediaPipeline
 
  Private pit As MediaControl
 
  Private pit As MediaControl
 +
Private vol As MediaControl
 
  Private pitch As Float = 1.00
 
  Private pitch As Float = 1.00
 
  Private tempo As Float = 1.00
 
  Private tempo As Float = 1.00
 +
Private volume As Float = 1.00
 +
Private bo As Boolean
 
   
 
   
 
   
 
   
  '''Public''' Sub Form_Open()
+
  Public Sub Form_Open()
 
+
 
   Dim src, par, flu, res, cnv, snk As MediaControl
 
   Dim src, par, flu, res, cnv, snk As MediaControl
 
   Dim flt As MediaFilter
 
   Dim flt As MediaFilter
    
+
  pl = New MediaPipeline  
+
   pl = New MediaPipeline
   
+
  src = New MediaControl(pl, "<FONT color=#B22222>filesrc</font>")
+
  src = New MediaControl(pl, "<FONT color=#B22222>filesrc</font>")
  src["location"] = "<FONT color=gray>''/percorso/del/file.mid''</font>"  <FONT color=gray>' ''"location" è una proprietà del plugin "filesrc"''</font>
+
  src["location"] = "<FONT color=darkgreen>''/percorso/del/file.mid''</font>"  
   
+
   par = New MediaControl(pl, "<FONT color=#B22222>midiparse</font>")
  par = New MediaControl(pl, "<FONT color=#B22222>midiparse</font>")
+
  flu = New MediaControl(pl, "<FONT color=#B22222>fluiddec</font>")
  flu = New MediaControl(pl, "<FONT color=#B22222>fluiddec</font>")
+
  cnv = New MediaControl(pl, "<FONT color=#B22222>audioconvert</font>")
  res = New MediaControl(pl, "<FONT color=#B22222>audioresample</font>")
+
  pit = New MediaControl(pl, "<FONT color=#B22222>pitch</font>")
  flt = New MediaFilter(pl, "<FONT color=#B22222>audio/x-raw,rate=44100</font>")
+
  res = New MediaControl(pl, "<FONT color=#B22222>audioresample</font>")
  pit = New MediaControl(pl, "<FONT color=#B22222>pitch</font>")
+
  flt = New MediaFilter(pl, "<FONT color=#B22222>audio/x-raw,rate=44100,channels=2</font>")
 
+
  vol = New MediaControl(pl, "<FONT color=#B22222>volume</font>")
  cnv = New MediaControl(pl, "<FONT color=#B22222>audioconvert</font>")
+
  snk = New MediaControl(pl, "<FONT color=#B22222>alsasink</font>")
  snk = New MediaControl(pl, "<FONT color=#B22222>alsasink</font>")
 
 
  <FONT color=gray>' ''Volendo, è possibile utilizzare anche il plugin "autoaudiosink" al posto di "alsasink".''
 
  <FONT color=gray>' ''Volendo, è possibile utilizzare anche il plugin "autoaudiosink" al posto di "alsasink".''
 
  ' ''In tal caso, però, non sarà necessario utilizzare il plugin "audioconvert".''</font>
 
  ' ''In tal caso, però, non sarà necessario utilizzare il plugin "audioconvert".''</font>
 
+
  src.LinkTo(par)
+
  src.LinkTo(par)
  par.LinkTo(flu)
+
  par.LinkTo(flu)
  flu.LinkTo(res)
+
  flu.LinkTo(cnv)
  res.LinkTo(flt)
+
  cnv.LinkTo(pit)
  flt.LinkTo(pit)
+
  pit.LinkTo(res)
  pit.LinkTo(cnv)
+
  res.LinkTo(flt)
  cnv.LinkTo(snk)
+
  flt.LinkTo(vol)
 
+
  vol.LinkTo(snk)
 +
 
  <FONT color=gray>' ''Imposta alcuni valori dei due "Slider":''</font>
 
  <FONT color=gray>' ''Imposta alcuni valori dei due "Slider":''</font>
  With Slider1
+
  With Slider1
 
     .MinValue = 0
 
     .MinValue = 0
 
     .MaxValue = 1000
 
     .MaxValue = 1000
 
     .Value = 100
 
     .Value = 100
  End With
+
  End With
 
+
  With Slider2
+
  With Slider2
 +
    .MinValue = 0
 +
    .MaxValue = 1000
 +
    .Value = 100
 +
  End With
 +
 +
  With Slider3
 
     .MinValue = 0
 
     .MinValue = 0
 
     .MaxValue = 1000
 
     .MaxValue = 1000
 
     .Value = 100
 
     .Value = 100
  End With
+
  End With
 
+
  '''End'''
+
  End
 +
 
   
 
   
 +
Public Sub Button1_Click()
 
   
 
   
  '''Public''' Sub Button1_Click()
+
  pl.Play()
 
+
  <FONT color=gray>' ''Consente che, qualora sia stata arrestata l'esecuzione, il conteggio possa ricominciare da zero:''</font>
  pl.Play()
+
  bo = False
 
+
  While (pl.Duration > pl.Position) And (bo = False)
  While pl.Duration > pl.Position
+
    Write "\rDurata: " & Str(Time(0, 0, 0, pl.Duration * 1000)) &
    Write #File.Out, "\rDurata: " & Date(0, 0, 0, 0, 0, 0, pl.Duration * 1000) &
+
                    "    Tempo trascorso: " & Str(Time(0, 0, 0, pl.Position * 1000))
                      "    Tempo trascorso: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
+
    Wait 0.01
    Wait 0.01
+
  Wend
  Wend
+
   
+
  End
  '''End'''
 
 
   
 
   
 
   
 
   
  '''Public''' Sub Button2_Click()
+
  Public Sub Button2_Click()
 
      
 
      
 
   pl.Stop()
 
   pl.Stop()
 
   pl.Close()
 
   pl.Close()
 +
  bo = True
 
    
 
    
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub Slider1_Change()
+
  Public Sub Slider1_Change()
 
   
 
   
 
   pitch = Slider1.Value / 100
 
   pitch = Slider1.Value / 100
Riga 452: Riga 661:
 
   ValueBox1.Value = pitch
 
   ValueBox1.Value = pitch
 
    
 
    
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub Slider2_Change()
+
  Public Sub Slider2_Change()
 
   
 
   
 
   tempo = Slider2.Value / 100
 
   tempo = Slider2.Value / 100
Riga 461: Riga 670:
 
   ValueBox2.Value = tempo
 
   ValueBox2.Value = tempo
 
    
 
    
  '''End'''
+
  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
 +
 
 +
 
 +
Mostriamo di seguito un semplice esempio con applicazione ''a riga di comando'':
 +
Private bo As Boolean
 +
 +
 +
Public Sub Main()
 +
 
 +
  Dim pl As MediaPipeline
 +
  Dim src, par, flu, cnv, vol, snk As MediaControl
 +
 +
  pl = New MediaPipeline As "PLine"
 +
 +
  src = New MediaControl(pl, "filesrc")
 +
  src["location"] = "<FONT Color=darkgreen>''/percorso/del/file.mid''</font>"
 +
  par = New MediaControl(pl, "<FONT Color=#B22222>midiparse</font>")
 +
  flu = New MediaControl(pl, "<FONT Color=#B22222>fluiddec</font>")
 +
  cnv = New MediaControl(pl, "audioconvert")
 +
  vol = New MediaControl(pl, "volume")        <FONT color=gray>' ''<1.0 = volume <100% | 1.0 = volume 100% | >1.0 = volume >100%''</font>
 +
  vol["volume"] = 0.5
 +
  snk = New MediaControl(pl, "alsasink")
 +
 
 +
  src.LinkTo(par)
 +
  par.LinkTo(flu)
 +
  flu.LinkTo(cnv)
 +
  cnv.LinkTo(vol)
 +
  vol.LinkTo(snk)
 +
 
 +
  pl.Play()
 +
 
 +
  Print "Durata del file Midi: "; Str(Time(0, 0, 0, pl.Duration * 1000))
 +
  While Not bo
 +
    Write "\r\e[0mTempo trascorso:      \e[31m" & Str(Time(0, 0, 0, pl.Position * 1000))
 +
    Wait 0.01
 +
  Wend
 +
 
 +
  pl.Close()
 +
 
 +
  Write "\n\e[0mEsecuzione terminata !"
 +
 
 +
End
 +
 +
 +
Public Sub PLine_End()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando l'esecuzione è terminata''</font>
 +
 
 +
  bo = True
 +
 
 +
End
 +
 
 +
====Gli effetti video con i ''plug-in'' usando gli specifici elementi di GStreamer per il Midi====
 +
Private pl As MediaPipeline
 +
 +
 +
Public Sub ToggleButton1_Click()
 +
 +
  If ToggleButton1.Value Then
 +
    Dim DrawingArea1 As DrawingArea
 +
    Dim src, par, flu, tee, que1, que2 As MediaControl
 +
    Dim vcon, plug, vsnk As MediaControl
 +
    Dim acon, asnk As MediaControl
 +
    Dim tipoPlug As String[] = ["goom", "goom2k1", "monoscope", "spacescope",
 +
                                "spectrascope", "synaescope", "wavescope"]
 +
 +
    With DrawingArea1 = New DrawingArea(Me)
 +
      .X = 10
 +
      .Y = 10
 +
      .W = 300
 +
      .H = 300
 +
    End With
 +
 +
    pl = New MediaPipeline As "PLine"
 +
 +
    src = New MediaControl(pl, "filesrc")
 +
    src["location"] = "<FONT Color=darkgreen>''/percorso/del/file.mid''</font>"
 +
    par = New MediaControl(pl, "midiparse")
 +
    flu = New MediaControl(pl, "fluiddec")
 +
    tee = New MediaControl(pl, "tee")
 +
    que1 = New MediaControl(pl, "queue")
 +
    vcon = New MediaControl(pl, "audioconvert")
 +
    plug = New MediaControl(pl, tipoPlug[4])
 +
    vsnk = New MediaControl(pl, "ximagesink")
 +
    que2 = New MediaControl(pl, "queue")
 +
    acon = New MediaControl(pl, "audioconvert")
 +
    asnk = New MediaControl(pl, "autoaudiosink")
 +
 +
    src.LinkTo(par)
 +
    par.LinkTo(flu)
 +
    flu.LinkTo(tee)
 +
<FONT Color=gray>' ''Parte video:''</font>
 +
    tee.LinkTo(que1)
 +
    que1.LinkTo(vcon)
 +
    vcon.LinkTo(plug)
 +
    plug.LinkTo(vsnk)
 +
<FONT Color=gray>' ''Parte audio:''</font>
 +
    tee.LinkTo(que2)
 +
    que2.LinkTo(acon)
 +
    acon.LinkTo(asnk)
 +
<FONT Color=gray>' ''Si dice al MediaControl di mostrare il proprio output (gli effetti video) in uno specifico controllo GUI, solitamente una DrawingArea:''</font>
 +
    vsnk.SetWindow(DrawingArea1)
 +
 +
    pl.Play()
 +
    While (pl.Duration < 0.1) Or (pl.Pos < 0.1)
 +
      Wait 0.01
 +
    Wend
 +
 +
    Wait pl.Duration
 +
 +
  Else
 +
    pl.Stop
 +
    pl.Close
 +
  Endif
 +
 
 +
End
 +
 +
 +
Public Sub PLine_Position()
 +
 +
  Me.Title = Str(Time(0, 0, 0, pl.Pos * 1000))
 +
 +
End
 +
 +
 +
Public Sub PLine_End()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando l'esecuzione è terminata''</font>
 +
 +
  pl.Close
 +
  ToggleButton1.Value = False
 +
 +
End
 +
 
 +
===Impostare il file soundbank dei suoni per il Midi===
 +
E' possibile scegliere il file soundbank che consente l'ascolto dei suoni dal Midi, bisognerà utilizzare la proprietà "''soundfont'' " del plugin "fluiddec" di GStreamer, assegnandole il percorso del file sf2 o sf3 desiderato.
 +
 
 +
Riprendendo il codice di sopra a ''riga di comando'' avremo dunque:
 +
flu = New MediaControl(pl, "fluiddec")
 +
flu["soundfont"] = "<FONT Color=darkgreen>''/percorso/del/file.sf2''</font>"
  
  
Riga 473: Riga 826:
  
 
Mostriamo un semplice esempio di esecuzione di un file Midi in un'applicazione ''a riga di comando'':
 
Mostriamo un semplice esempio di esecuzione di un file Midi in un'applicazione ''a riga di comando'':
  '''Public''' Sub Main()
+
  Private bo As Boolean
 
+
Private pl As MediaPipeline
  Dim pl As MediaPipeline
+
   Dim src, prs, cnv, snk As MediaControl
+
 +
Public Sub Main()
 +
 +
   Dim src, par, flu, cnv, snk As MediaControl
 +
 +
  pl = New MediaPipeline As "PLine"
 
   
 
   
  pl = New MediaPipeline
 
 
 
 
   src = New MediaControl(pl, "filesrc")
 
   src = New MediaControl(pl, "filesrc")
   src["location"] = "<FONT color=gray>''/percorso/del/file.mid''</font>"     <FONT color=gray>' ''"location" è una proprietà del plugin "filesrc"''</font>
+
   src["location"] = "<FONT Color=darkgreen>''/percorso/del/file.mid''</font>"
   prs = New MediaControl(pl, "wavparse")
+
   par = New MediaControl(pl, "<FONT Color=#B22222>midiparse</font>")
   cnv = New MediaControl(pl, "audioconvert")
+
   flu = New MediaControl(pl, "<FONT Color=#B22222>fluiddec</font>")
   snk = New MediaControl(pl, "jackaudiosink")
+
   snk = New MediaControl(pl, "<FONT Color=#B22222>jackaudiosink</font>")
 
+
 
   src.LinkTo(prs)
 
   src.LinkTo(prs)
   prs.LinkTo(cnv)
+
   prs.LinkTo(flu)
   cnv.LinkTo(snk)
+
   flu.LinkTo(snk)
 
+
 
   pl.Play()
 
   pl.Play()
 +
 +
  Print "Durata del file Midi: "; Str(Time(0, 0, 0, pl.Duration * 1000))
 +
  Repeat
 +
    Write "\r\e[0mTempo trascorso:      \e[31m" & Str(Time(0, 0, 0, pl.Position * 1000))
 +
    Wait 0.01
 +
  Until bo = True
 +
 +
  pl.Stop()
 +
  pl.Close()
 +
 +
  Write "\n\e[0mEsecuzione terminata !"
 +
 +
End
 +
 +
 +
Public Sub PLine_End()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando l'esecuzione è terminata''</font>
 
    
 
    
   Print "\nDurata: " & Date(0, 0, 0, 0, 0, 0, pl.Duration * 1000)
+
   bo = True
   Wait pl.Duration
+
    
 
+
  End
  '''End'''
 
  
  
  
 +
=Note=
 +
[1] Sullo stile dell'elemento "wavescope" vedere: [https://gstreamer.freedesktop.org/documentation/audiovisualizers/wavescope.html?gi-language=c#GstWaveScopeStyle Stile wavescope]
  
=Note=
+
[2] 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 .
[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] Si rinvia come riferimento alla seguente pagina web: https://cgit.freedesktop.org/gstreamer/gstreamer/tree/docs/random/uraeus/gstreamer_and_midi.txt
+
[3] Si rinvia come riferimento alla seguente pagina web: https://github.com/Xilinx/gstreamer/blob/master/docs/random/uraeus/gstreamer_and_midi.txt

Versione attuale delle 19:54, 17 gen 2024

Per eseguire ed ascoltare un file Midi, utilizzando un breve codice, è possibile adoperare le funzionalità della multipiattaforma gstreamer, attivando il componente gb.media.

E' necessario aver installato il file banco di suoni di default di Timidity:

/usr/share/sounds/sf2/TimGM6mb.sf2

oppure di FluidSynth:

/usr/share/sounds/sf2/FluidR3_GM.sf2

La classe MediaPlayer

Si utilizzeranno i metodi specifici della Classe MediaPlayer del componente gb.media.

Gli elementi essenziali per eseguire un file Midi con la Classe MediaPlayer sono:

  • la Proprietà ".Url" per caricare il file (se il file è memorizzato su dispositivo di memoria, allora il suo percorso andrà passato mediante il Metodo ".Url" della Classe statica "Media"; se il file è eseguito da un indirizzo web, allora sarà passato direttamente l'indirizzo web);
  • il Metodo ".Play()" per avviare l'esecuzione del file Midi;
  • la Proprietà ".Duration" per far eseguire il file Midi per l'intera sua durata;
  • il Metodo ".Close()" per chiudere il mediaplayer.

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 As "MediaPlayer1"
   .URL = Media.URL("/percorso/del/file.mid")
   .Play()
   Print "Durata del file Midi: \e[34m"; Str(Time(0, 0, 0, .Duration * 1000))
   Repeat
     Write "\r\e[0mTempo trascorso:      \e[1m\e[31m" & Str(Time(0, 0, 0, .Position * 1000))
     Wait 0.01
   Until bo
   .Stop
   .Close
 End With

 Write "\n\e[0mEsecuzione terminata !"
' Avendo utilizzato l'Evento "Application_Read()", è necessario invocare l'istruzione "Quit" per terminare il programma:
 Quit

End


Public Sub MediaPlayer1_End()  ' Questo Evento viene sollevato, quando l'escuzione è terminata

 bo = True

End


Public Sub Application_Read() ' Premendo il tasto "Invio" della tastiera, si arresta il programma

 bo = True

End

Uso di applicazione grafica

Vediamo un semplice codice, con il quale sarà possibile ascoltare, porre in pausa e terminare un file Midi in un'applicazione grafica.
Porremo sul Form del progetto:

  • un ToggleButton per avviare ed arrestare l'esecuzione del file Midi;
  • un ToggleButton per porre in pausa l'esecuzione del file Midi;
  • un Timer che ci consentirà di calcolare il tempo trascorso;
Private mp As New MediaPlayer


Public Sub Form_Open()

 ToggleButton2.Enabled = False

' Carica un file Midi:
  mp.URL = Media.URL("/percorso/del/file/Midi")

End


Public Sub ToggleButton1_Click()

 If ToggleButton1.Value Then 
   ToggleButton2.Enabled = True
   Esegue()
 Else 
' Chiama la funzione per arrestare l'esecuzione del file Midi:
   Arresta()
   ToggleButton2.Value = False
   ToggleButton2.Enabled = False
 Endif 

End


Public Sub Timer1_Timer()

' Mostra in console la durata del file Midi e il tempo trascorso:
 Write "\rDurata: " & Time(0, 0, 0, mp.Duration * 1000) &
       "   -   Tempo trascorso: " & Time(0, 0, 0, mp.Position * 1000)

' Se la posizione corrente è uguale o maggiore della durata complessiva del file Midi, allora arresta l'esecuzione del file Midi:
 If mp.Position >= mp.Duration Then Arresta()

End


Public Sub Esegue()

' Avvia l'ascolto del file Midi:
 mp.Play

 With Timer1
' Il "Timer" si attiva ogni 70 millesimi di secondo:
   .Delay = 70
   .Start
 End With

End


Public Sub Arresta()

' Arresta l'ascolto del file Midi:
 mp.Stop
 mp.Close
 Timer1.Stop
 ToggleButton1.Value = False

End


Public Sub ToggleButton2_Click()

' Mette in "pausa" l'ascolto del file Midi.
' (Per continuare l'ascolto del file, si dovrà nuovamente attivare la Proprietà ".Play"):
 If ToggleButton2.Value Then 
   mp.Pause
 Else 
   If ToggleButton1.Value Then Esegue()
 Endif

End

In quest'altro esempio, simile al precedente, verrà utilizzato un ciclo al posto del Timer.
Si porrà anche un Controllo Slider per poter modificare il volume.

Private mp As New MediaPlayer


Public Sub Form_Open()

 With Slider1
   .MinValue = 0
   .MaxValue = 100
   .Value = 50
 End With

 ToggleButton2.Enabled = False

' Carica un file Midi:
 mp.URL = Media.URL("/percorso/del/file/Midi")

End


Public Sub ToggleButton1_Click()

 If ToggleButton1.Value Then 
   ToggleButton2.Enabled = True
   Esegue()
 Else 
' Chiama la funzione per arrestare l'esecuzione del file Midi:
   Arresta()
   ToggleButton2.Value = False
   ToggleButton2.Enabled = False
 Endif 

End


Public Sub Esegue()

' Avvia l'ascolto del file Midi:
 mp.Play
 
 Repeat
' Una brevissima pausa consente di agire sugli eventuali "Controlli" posti sul Form:
   Wait 0.01
   Write "\rDurata: " & Str(Time(0, 0, 0, mp.Duration * 1000)) &
         "   -   Tempo trascorso: " & Str(Time(0, 0, 0, mp.Position * 1000))
 Until (mp.Position >= mp.Duration)

 Arresta()

End


Public Sub Arresta()

' Arresta l'ascolto del file Midi:
 mp.Stop
 mp.Close
 Timer1.Stop
 ToggleButton1.Value = False

End


Public Sub ToggleButton2_Click()

' Mette in "pausa" l'ascolto del file Midi.
' (Per continuare l'ascolto del file, si dovrà nuovamente attivare la Proprietà ".Play"):
 If ToggleButton2.Value Then 
   mp.Pause
 Else
   If ToggleButton1.Value Then Esegue()
 Endif

End


Public Sub Slider1_Change()

 mp.Audio.Volume = Slider1.Value / 100

End

La proprietà .Duration

La Proprietà ".Duration" restituisce un valore di tipo Float che rappresenta la durata del file Midi espresso in secondi.
Poiché detta proprietà ritorna più precisamente la durata dei dati processati, essa potrà essere utilizzabile solo successivamente all'attivazione del Metodo ".Play".

Public Sub Main()

 Dim mp As MediaPlayer

 With mp = New MediaPlayer
   .URL = Media.URL("/percorso/del/file/Midi")
   .Play
   Print "Durata: \e[34m"; Time(0, 0, 0, .Duration * 1000)
   Repeat 
     Wait 0.01
     Write "\r       \e[31m" & Str(Time(0, 0, 0, .pos * 1000))
   Until .Pos >= .Duration
   .Stop
   .Close
 End With

End

oppure più semplicemente:

   ......
   .Play
   Print "Durata: \e[34m"; Time(0, 0, 0, .Duration * 1000)
   Wait .Duration
   .Stop
   .Close
 End With

La Proprietà ".Position"

La Proprietà ".Position" restituisce un valore di tipo Float che rappresenta la posizione, espressa in secondi all'interno dei dati processati.
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 modificare il volume dell'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 Float che rappresenta il volume corrente:

valore_di_tipo_Float = mp.Audio.Volume

nel secondo caso il volume è impostato mediante un valore di tipo Float:

mp.Audio.Volume = 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.Mute = True

L'evento _AboutToFinish()

L'evento "_AboutToFinish()" si scatena circa un secondo prima della fine della durata del file che si sta eseguendo.

L'evento _End()

L'evento "_End()" si scatena quando l'esecuzione del file Midi è terminata.
Esempio:

Private bo As Boolean


Public Sub Main()

 Dim mp As MediaPlayer

 With mp = New MediaPlayer As "MediaPlayer1"
   .URL = Media.URL("/percorso/del/file/Midi")
   .Play
   Print "\rDurata del file Midi: "; Str(Time(0, 0, 0, .Duration * 1000))
   Repeat
     Write "\r\e[0mTempo trascorso:      \e[31m" & Str(Time(0, 0, 0, .Position * 1000))
     Wait 0.01
   Until bo
   .Stop
   .Close
 End With

 Write "\n\e[0mEsecuzione terminata !"

End


Public Sub MediaPlayer1_End()  ' Questo Evento viene sollevato, quando l'esecuzione è terminata

 bo = True

End

Gli effetti video con i plug-in

E' possibile ottenere simpatici effetti video utilizzando i plug-in resi disposibili da GStreamer.
Gli effetti video disponibili sono:

"goom", "goom2k1", "monoscope", "spacescope", "spectrascope", "synaescope", "wavescope"

In tal caso si farà uso anche della Classe MediaControl che è serve per gestire appositamente i plug-in di GStreamer.
Per consentire l'uso dei plugin dei visualizzatori audio, è necessario avere installati nel sistema i seguenti pacchetti dei plugin:
- gstreamer1.0-plugins-bad
- gstreamer1.0-plugins-base
- gstreamer1.0-plugins-base-apps
- gstreamer1.0-plugins-good
- gstreamer1.0-plugins-ugly

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 MediaPlayer


Public Sub ToggleButton1_Click()
 
 If ToggleButton1.Value Then 
   Dim DrawingArea1 As DrawingArea
   Dim plugVis As MediaControl
   Dim tipoPlug As String[] = ["goom", "goom2k1", "monoscope", "spacescope",
                               "spectrascope", "synaescope", "wavescope"]

   With DrawingArea1 = New DrawingArea(Me)
     .X = 10
     .Y = 10
     .W = 300
     .H = 300
     .Background = Color.Black
   End With

   mp = New MediaPlayer As "MediaPlayer1"

' Imposta un plug-in grafico (ad esempio il 7° fra quelli contenuti dal vettore "tipoplug") da mostrare nella "DrawingArea" durante l'esecuzione del file audio:
   plugVis = New MediaControl(mp, tipoPlug[6])
   plugVis["style"] = 2    [nota 1]
' Si dice al MediaControl di mostrare il proprio output (gli effetti video) in uno specifico controllo GUI, solitamente una DrawingArea:
   mp.SetWindow(DrawingArea1)

   mp.URL = Media.URL("/percorso/del/file/Midi")

   mp.Play()

 ' La seguente riga deve stare "dopo" il Metodo ".Play()", altrimenti - in caso si arresti e poi si riavvii l'esecuzione del flusso audio - l'esecuzione si arresterà dopo qualche secondo:
   mp.Video.Visualisation = plugVis
 Else 
   mp.Stop
   mp.Close
 Endif 
   
End


Public Sub MediaPlayer1_End()

 mp.Close

End


Interfacciare la Classe MediaPlayer con il plugin "jackaudiosink" di GStreamer per eseguire i file Midi

Per eseguire i file Midi 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". [nota 2]

Ovviamente bisognerà avere l'accortezza di avviare il server Jack (per esempio avviando il programma qjackctl) prima 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 Midi in un'applicazione a riga di comando:

Public Sub Main()

 Dim mp As MediaPlayer

 With mp = New MediaPlayer
   .URL = Media.URL("/percorso/del/file.mid")
   .Audio.Output = New MediaControl(mp, "jackaudiosink")
   .Play
 End With

 Wait mp.Duration

 mp.Stop
 mp.Close

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.

Usare la Classe "MediaPipeline" con il decoder "playbin" di GStreamer

La Classe implementa un funzionale media-player; pertanto è possibile anche mediante tale Classe eseguire in modo semplice un file Midi 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("/percorso/del/file.mid")

 pl.Play()

' Utilizziamo la funzione "Input" per consentire l'esecuzione del file Midi, evitando così un eccessivo aggravio di lavoro per la CPU.
' L'esecuzione viene interrotta, inserendo nella Console/Terminale un carattere dalla tastiera e premendo il tasto "Invio"."
 Input s

 pl.Stop
 pl.Close

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("/percorso/del/file.mid")
 
 pl.Play()
  
' Utilizziamo la funzione "Input" per consentire l'esecuzione del file Midi, evitando così un eccessivo aggravio di lavoro per la CPU.
' L'esecuzione viene interrotta, inserendo nella Console/Terminale un carattere dalla tastiera e premendo il tasto "Invio"."
 Input s

 pl.Stop
 pl.Close
 
End

Usare i plugin di GStreamer con le Classi MediaControl e MediaPipeline per eseguire i file MIDI

E' possibile eseguire i file MIDI utilizzando specifici plugin di GStreamer con le Classi MediaControl e MediaPipeline. [Nota 3]

Usando il plugin "decodebin"

E' possibile utilizzare il plugin "decodebin" di GStreamer:

Private bo As Boolean


Public Sub Main()

 Dim pl As MediaPipeline
 Dim src, dcb, con, vol, snk As MediaControl

 pl = New MediaPipeline As "PLine"

 src = New MediaControl(pl, "filesrc")
 src["location"] = "/percorso/del/file/midi"

 dcb = New MediaControl(pl, "decodebin")
 con = New MediaControl(pl, "audioconvert")
 vol = New MediaControl(pl, "volume")         ' <1.0 = volume <100% | 1.0 = volume 100% | >1.0 = volume >100%
 vol["volume"] = 0.5
 snk = New MediaControl(pl, "autoaudiosink")

 src.LinkTo(dcb)
 dcb.LinkLaterTo(con)
 con.LinkTo(vol)
 vol.LinkTo(snk)

 pl.Play()

 Repeat 
   Write "\rTempo Trascorso: " & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Until bo

 pl.Close()

End

Public Sub PLine_End()  ' Questo Evento viene sollevato, quando l'esecuzione è terminata

 bo = True

End

Gli effetti video con i plug-in usando l'elemento "decodebin"

Anche con la Classe MediaPipeline è possibile ottenere gli effetti video utilizzando i plug-in resi disposibili da GStreamer.

Private pl As MediaPipeline


Public Sub ToggleButton1_Click()

 If ToggleButton1.Value Then 
   Dim DrawingArea1 As DrawingArea
   Dim src, dcb, tee, que1, que2 As MediaControl
   Dim vcon, plug, vsnk As MediaControl
   Dim acon, asnk As MediaControl
   Dim tipoPlug As String[] = ["goom", "goom2k1", "monoscope", "spacescope",
                               "spectrascope", "synaescope", "wavescope"]

   With DrawingArea1 = New DrawingArea(Me)
     .X = 10
     .Y = 10
     .W = 300
     .H = 300
     .Background = Color.Black
   End With 

   pl = New MediaPipeline As "PLine"

   src = New MediaControl(pl, "filesrc")
   src["location"] = "/percorso/del/file.mid"
   dcb = New MediaControl(pl, "decodebin")
   tee = New MediaControl(pl, "tee")
   que1 = New MediaControl(pl, "queue")
   vcon = New MediaControl(pl, "audioconvert")
   plug = New MediaControl(pl, tipoPlug[4])
   vsnk = New MediaControl(pl, "ximagesink")
   que2 = New MediaControl(pl, "queue")
   acon = New MediaControl(pl, "audioconvert")
   asnk = New MediaControl(pl, "autoaudiosink")

   src.LinkTo(dcb)
   dcb.LinkLaterTo(tee)
' Parte video:
   tee.LinkTo(que1)
   que1.LinkTo(vcon)
   vcon.LinkTo(plug)
   plug.LinkTo(vsnk)
' Parte audio:
   tee.LinkTo(que2)
   que2.LinkTo(acon)
   acon.LinkTo(asnk)
' Si dice al MediaControl di mostrare il proprio output (gli effetti video) in uno specifico controllo GUI, solitamente una DrawingArea:
   vsnk.SetWindow(DrawingArea1)

   pl.Play()
   While (pl.Duration < 0.1) Or (pl.Pos < 0.1)
     Wait 0.01
   Wend

   Wait pl.Duration

 Else 
   pl.Stop
   pl.Close
 Endif 
 
End


Public Sub PLine_Position()

 Me.Title = Str(Time(0, 0, 0, pl.Pos * 1000))

End


Public Sub PLine_End()  ' Questo Evento viene sollevato, quando l'esecuzione è terminata

 pl.Close
 ToggleButton1.Value = False

End

Usando i plugin specifici di GStreamer per il Midi

I plugin specifici di GStreamer utilizzabili per il MIDI sono:

  • midiparse: interpreta i file MIDI e li converte in eventi MIDI;
  • fluiddec: effettua il render degli eventi MIDI in campioni audio grezzi.

Mostriamo di seguito un esempio in ambiente grafico per l'esecuzione dei file MIDI, nel quale sarà possibile impostare i valori della frequenza di campionamento (rate) e dei canali, nonché modificare in tempo reale mediante tre Slider la tonalità, il tempo di esecuzione e il 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.00;
  • per impostare la velocità del tempo di esecuzione si userà la proprietà "tempo": il valore di partenza predefinito è 1.00 .
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
Private bo As Boolean


Public Sub Form_Open()

 Dim src, par, flu, res, cnv, snk As MediaControl
 Dim flt As MediaFilter

 pl = New MediaPipeline

 src = New MediaControl(pl, "filesrc")
 src["location"] = "/percorso/del/file.mid"    
 par = New MediaControl(pl, "midiparse")
 flu = New MediaControl(pl, "fluiddec")
 cnv = New MediaControl(pl, "audioconvert")
 pit = New MediaControl(pl, "pitch")
 res = New MediaControl(pl, "audioresample")
 flt = New MediaFilter(pl, "audio/x-raw,rate=44100,channels=2")
 vol = New MediaControl(pl, "volume")
 snk = New MediaControl(pl, "alsasink")
' Volendo, è possibile utilizzare anche il plugin "autoaudiosink" al posto di "alsasink".
' In tal caso, però, non sarà necessario utilizzare il plugin "audioconvert".

 src.LinkTo(par)
 par.LinkTo(flu)
 flu.LinkTo(cnv)
 cnv.LinkTo(pit)
 pit.LinkTo(res)
 res.LinkTo(flt)
 flt.LinkTo(vol)
 vol.LinkTo(snk)

' Imposta alcuni valori dei due "Slider":
 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()
' Consente che, qualora sia stata arrestata l'esecuzione, il conteggio possa ricominciare da zero:
 bo = False
 While (pl.Duration > pl.Position) And (bo = False)
   Write "\rDurata: " & Str(Time(0, 0, 0, pl.Duration * 1000)) &
                    "    Tempo trascorso: " & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Wend

End


Public Sub Button2_Click()
   
 pl.Stop()
 pl.Close()
 bo = True
 
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          ' "volume" è una proprietà dell'omonimo plugin "volume"
 ValueBox3.Value = volume

End


Mostriamo di seguito un semplice esempio con applicazione a riga di comando:

Private bo As Boolean


Public Sub Main()
 
 Dim pl As MediaPipeline
 Dim src, par, flu, cnv, vol, snk As MediaControl

 pl = New MediaPipeline As "PLine"

 src = New MediaControl(pl, "filesrc")
 src["location"] = "/percorso/del/file.mid"
 par = New MediaControl(pl, "midiparse")
 flu = New MediaControl(pl, "fluiddec")
 cnv = New MediaControl(pl, "audioconvert")
 vol = New MediaControl(pl, "volume")         ' <1.0 = volume <100% | 1.0 = volume 100% | >1.0 = volume >100%
 vol["volume"] = 0.5
 snk = New MediaControl(pl, "alsasink")
  
 src.LinkTo(par)
 par.LinkTo(flu)
 flu.LinkTo(cnv)
 cnv.LinkTo(vol)
 vol.LinkTo(snk)
  
 pl.Play()
  
 Print "Durata del file Midi: "; Str(Time(0, 0, 0, pl.Duration * 1000))
 While Not bo
   Write "\r\e[0mTempo trascorso:      \e[31m" & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Wend
  
 pl.Close()
 
 Write "\n\e[0mEsecuzione terminata !"
  
End


Public Sub PLine_End()  ' Questo Evento viene sollevato, quando l'esecuzione è terminata
 
 bo = True
 
End

Gli effetti video con i plug-in usando gli specifici elementi di GStreamer per il Midi

Private pl As MediaPipeline


Public Sub ToggleButton1_Click()

 If ToggleButton1.Value Then 
   Dim DrawingArea1 As DrawingArea
   Dim src, par, flu, tee, que1, que2 As MediaControl
   Dim vcon, plug, vsnk As MediaControl
   Dim acon, asnk As MediaControl
   Dim tipoPlug As String[] = ["goom", "goom2k1", "monoscope", "spacescope",
                               "spectrascope", "synaescope", "wavescope"]

   With DrawingArea1 = New DrawingArea(Me)
     .X = 10
     .Y = 10
     .W = 300
     .H = 300
   End With 

   pl = New MediaPipeline As "PLine"

   src = New MediaControl(pl, "filesrc")
   src["location"] = "/percorso/del/file.mid"
   par = New MediaControl(pl, "midiparse")
   flu = New MediaControl(pl, "fluiddec")
   tee = New MediaControl(pl, "tee")
   que1 = New MediaControl(pl, "queue")
   vcon = New MediaControl(pl, "audioconvert")
   plug = New MediaControl(pl, tipoPlug[4])
   vsnk = New MediaControl(pl, "ximagesink")
   que2 = New MediaControl(pl, "queue")
   acon = New MediaControl(pl, "audioconvert")
   asnk = New MediaControl(pl, "autoaudiosink")

   src.LinkTo(par)
   par.LinkTo(flu)
   flu.LinkTo(tee)
' Parte video:
   tee.LinkTo(que1)
   que1.LinkTo(vcon)
   vcon.LinkTo(plug)
   plug.LinkTo(vsnk)
' Parte audio:
   tee.LinkTo(que2)
   que2.LinkTo(acon)
   acon.LinkTo(asnk)
' Si dice al MediaControl di mostrare il proprio output (gli effetti video) in uno specifico controllo GUI, solitamente una DrawingArea:
   vsnk.SetWindow(DrawingArea1)

   pl.Play()
   While (pl.Duration < 0.1) Or (pl.Pos < 0.1)
     Wait 0.01
   Wend

   Wait pl.Duration

 Else 
   pl.Stop
   pl.Close
 Endif 
 
End


Public Sub PLine_Position()

 Me.Title = Str(Time(0, 0, 0, pl.Pos * 1000))

End


Public Sub PLine_End()  ' Questo Evento viene sollevato, quando l'esecuzione è terminata

 pl.Close
 ToggleButton1.Value = False

End

Impostare il file soundbank dei suoni per il Midi

E' possibile scegliere il file soundbank che consente l'ascolto dei suoni dal Midi, bisognerà utilizzare la proprietà "soundfont " del plugin "fluiddec" di GStreamer, assegnandole il percorso del file sf2 o sf3 desiderato.

Riprendendo il codice di sopra a riga di comando avremo dunque:

flu = New MediaControl(pl, "fluiddec")
flu["soundfont"] = "/percorso/del/file.sf2"


Interfacciare le Classi MediaControl e MediaPipeline con il plugin "jackaudiosink" di GStreamer per eseguire i file Midi

Per eseguire i file Midi 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) prima 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 Midi in un'applicazione a riga di comando:

Private bo As Boolean
Private pl As MediaPipeline


Public Sub Main()

 Dim src, par, flu, cnv, snk As MediaControl

 pl = New MediaPipeline As "PLine"

 src = New MediaControl(pl, "filesrc")
 src["location"] = "/percorso/del/file.mid"
 par = New MediaControl(pl, "midiparse")
 flu = New MediaControl(pl, "fluiddec")
 snk = New MediaControl(pl, "jackaudiosink")

 src.LinkTo(prs)
 prs.LinkTo(flu)
 flu.LinkTo(snk)

 pl.Play()

 Print "Durata del file Midi: "; Str(Time(0, 0, 0, pl.Duration * 1000))
 Repeat
   Write "\r\e[0mTempo trascorso:      \e[31m" & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Until bo = True

 pl.Stop()
 pl.Close()

 Write "\n\e[0mEsecuzione terminata !"

End


Public Sub PLine_End()  ' Questo Evento viene sollevato, quando l'esecuzione è terminata
 
 bo = True
 
End


Note

[1] Sullo stile dell'elemento "wavescope" vedere: Stile wavescope

[2] La stesura di paragrafo è stata possibile anche grazie al fondamentale apporto e studio del membro allegfede del forum gambas-it.org .

[3] Si rinvia come riferimento alla seguente pagina web: https://github.com/Xilinx/gstreamer/blob/master/docs/random/uraeus/gstreamer_and_midi.txt