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

Da Gambas-it.org - Wikipedia.
Riga 8: Riga 8:
  
  
===Utilizzo in un'applicazione grafica===
+
===Uso di applicazione grafica===
Ecco di seguito un semplicissimo codice per lanciare ed ascoltare uno standard file Midi (.mid) in un'applicazione grafica utilizzando un Timer.
+
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>
 
   
 
   
Riga 19: Riga 19:
 
  '''Public''' Sub Form_Open()
 
  '''Public''' Sub Form_Open()
 
   
 
   
<FONT color=gray>' ''Carica il file Midi .mid:''</font>
+
  ToggleButton2.Enabled = False
  mp.URL = Media.URL("<FONT Color=gray>''/percorso/del/file.mid''</font>")
 
 
   
 
   
  <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=gray>''/percorso/del/file/Midi''</font>")
 
   
 
   
 
  '''End'''
 
  '''End'''
 
 
'''Public''' Sub Button1_Click()
 
 
   
 
   
  Suona()
+
'''Public''' Sub ToggleButton1_Click()
 +
 +
  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'''
 
   
 
   
  '''Private''' Procedure Suona()
+
  '''Public''' Sub Timer1_Timer()
 
 
<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'''
+
  <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)
 
   
 
   
'''Public''' Sub Button2_Click()
+
  <FONT Color=gray>' ''Se la posizione corrente è uguale o maggiore della durata complessiva del file Midi, allora arresta l'esecuzione del file Midi:''</font>
+
  If mp.Position >= mp.Duration Then 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.<FONT color=#B22222>Pause</font>
 
 
   
 
   
 
  '''End'''
 
  '''End'''
 
   
 
   
  '''Public''' Sub Button3_Click()
+
  '''Public''' Sub Esegue()
 
   
 
   
  RadioButton1.Value = False
+
<FONT Color=gray>' ''Avvia l'ascolto del file Midi:''</font>
 +
  mp.Play
 
   
 
   
  <FONT color=gray>' ''Chiama la funzione per arrestare l'esecuzione del file Midi:''</font>
+
  With Timer1
  Arresta()
+
  <FONT Color=gray>' ''Il "Timer" si attiva ogni 70 millesimi di secondo:''</font>
 +
    .Delay = 70
 +
    .Start
 +
  End With
 
   
 
   
 
  '''End'''
 
  '''End'''
 
   
 
   
  '''Private''' Procedure Arresta()
+
  '''Public''' Sub Arresta()
 
   
 
   
  <FONT color=gray>' ''Arresta l'ascolto del file Midi:''</font>
+
  <FONT Color=gray>' ''Arresta l'ascolto del file Midi:''</font>
  mp.<FONT color=#B22222>Stop</font>
+
  mp.Stop
+
  mp.Close
  Timer1.Stop
+
  Timer1.Stop
+
  ToggleButton1.Value = False
<FONT color=gray>' ''Se è stato cliccato sul "RadioButton", verrà ripetuta l'esecuzione del file Midi:''</font>
 
  If RadioButton1.Value Then
 
    mp.Position = 0
 
    Suona()
 
  Else
 
<FONT color=gray>' ''Arresta l'ascolto del file audio:''</font>
 
    mp.Stop
 
  Endif
 
 
   
 
   
 
  '''End'''
 
  '''End'''
 
   
 
   
  '''Public''' Sub Timer1_Timer()
+
  '''Public''' Sub ToggleButton2_Click()
 
   
 
   
  <FONT color=gray>' ''Mostra in console la posizione, espressa in secondi, all'interno dei dati processati:''</font>
+
  <FONT Color=gray>' ''Mette in "pausa" l'ascolto del file Midi.''
  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))
+
' ''(Per continuare l'ascolto del file, si dovrà nuovamente attivare la Proprietà ".Play"):''</font>
 +
  If ToggleButton2.Value Then
 +
    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, 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'''
 
  '''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("<FONT Color=gray>''/percorso/del/file.mid''</font>")
+
   mp.URL = Media.URL("<FONT color=gray>''/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'''
 
   
 
   
  '''Private''' Procedure Suona()
+
  '''Public''' Sub Esegue()
 
   
 
   
 
  <FONT color=gray>' ''Avvia l'ascolto del file Midi:''</font>
 
  <FONT color=gray>' ''Avvia l'ascolto del file Midi:''</font>
Riga 115: Riga 126:
 
    
 
    
 
   Repeat
 
   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: " & Time(0, 0, 0, mp.Duration * 1000) &
   Until mp.Position >= mp.Duration
+
          "  -  Tempo trascorso: " & Time(0, 0, 0, mp.Position * 1000)
 
+
   Until (mp.Position >= mp.Duration)
 +
 
   Arresta()
 
   Arresta()
    
+
 +
'''End'''
 +
 +
'''Public''' Sub Arresta()
 +
 +
<FONT color=gray>' ''Arresta l'ascolto del file Midi:''</font>
 +
   mp.Stop
 +
  mp.Close
 +
  Timer1.Stop
 +
  ToggleButton1.Value = False
 +
 
  '''End'''
 
  '''End'''
 
   
 
   
  '''Public''' Sub Button2_Click()
+
  '''Public''' Sub ToggleButton2_Click()
 
+
 
  <FONT color=gray>' ''Mette in "pausa" l'ascolto del file Midi.''
 
  <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>
+
  ' ''(Per continuare l'ascolto del file, si dovrà nuovamente attivare la Proprietà ".Play"):''</font>
   mp.Pause
+
   If ToggleButton2.Value Then
 +
    mp.Pause
 +
  Else
 +
    If ToggleButton1.Value Then Esegue()
 +
  Endif
 
   
 
   
 
  '''End'''
 
  '''End'''
 
   
 
   
  '''Public''' Sub Button3_Click()
+
  '''Public''' Sub Slider1_Change()
 
 
  RadioButton1.Value = False
 
 
 
  mp.Position = mp.Duration + 1
 
 
 
'''End'''
 
 
   
 
   
 +
  mp.Audio.Volume = Slider1.Value / 100
 
   
 
   
'''Provate''' Procedure Arresta()
 
 
 
<FONT color=gray>' ''Se è stato cliccato sul "RadioButton", verrà ripetuta l'esecuzione del file Midi:''</font>
 
  If RadioButton1.Value Then
 
    mp.Position = 0
 
    Suona()
 
  Else
 
<FONT color=gray>' ''Altrimenti arresta l'ascolto del file Midi:''</font>
 
    mp.Stop
 
  Endif
 
 
 
 
  '''End'''
 
  '''End'''
  
Riga 162: Riga 172:
 
  '''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=gray>''/percorso/del/file/Midi''</font>")
    .Play()
+
    .Play()
  End With
+
    Print "Durata: \e[34m"; Time(0, 0, 0, .Duration * 1000)
 
+
    Repeat
  Repeat
 
 
  <FONT color=gray>' ''Mostra in console la posizione, espressa in secondi, all'interno dei dati processati:''</font>
 
  <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))
+
      Write "\r\e[0mTempo trascorso: \e[1m\e[31m" & Str(Time(0, 0, 0, .Position * 1000))
    Wait 0.01
+
      Wait 0.01
  Until (mp.Position >= mp.Duration) Or (bo = True)
+
    Until (mp.Position >= mp.Duration) Or bo
 
+
    .Stop
  mp.Stop()
+
    .Close
  mp.Close()
+
  End With
  Quit
+
 
+
<FONT color=gray>' ''Avendo utilizzato l'Evento "Application_Read()", è necessario invocare l'istruzione "Quit" per terminare il programma:''</font>
 +
  Quit
 +
 
  '''End'''
 
  '''End'''
 
   
 
   
  '''Public''' Sub Application_Read()   <FONT color=gray>' ''Cliccando nella console/Terminale e poi premendo il tasto "Invio" della tastiera, si arresta il programma''</font>
+
  '''Public''' Sub Application_Read() <FONT color=gray>' ''Premendo il tasto "Invio" della tastiera, si arresta il programma''</font>
 
   
 
   
 
   bo = True
 
   bo = True
Riga 225: Riga 236:
  
 
==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>
  
Riga 235: Riga 246:
  
 
==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
  

Versione delle 16:42, 15 gen 2022

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.


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: " & Time(0, 0, 0, mp.Duration * 1000) &
         "   -   Tempo trascorso: " & 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


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("/percorso/del/file/Midi")
   .Play()
   Print "Durata: \e[34m"; Time(0, 0, 0, .Duration * 1000)
   Repeat
' Mostra in console la posizione, espressa in secondi, all'interno dei dati processati:
     Write "\r\e[0mTempo trascorso: \e[1m\e[31m" & Str(Time(0, 0, 0, .Position * 1000))
     Wait 0.01
   Until (mp.Position >= mp.Duration) Or bo
   .Stop
   .Close
 End With

' Avendo utilizzato l'Evento "Application_Read()", è necessario invocare l'istruzione "Quit" per terminare il programma:
 Quit

End

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

 bo = True
 
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.

Per consentire che tale Evento si sollevi, si rende essere necessario porre i Metodi ".Stop()" - in particolar modo - e ".Close()" immediatamente prima dell'uscita dalla routine ove è posto il Metodo ".Play()".
Esempio:

Public Sub Button1_Click()

 Dim mp As MediaPlayer

 With mp = New MediaPlayer As "MediaPlayer1"
   .URL = Media.URL("/percorso/del/file/Midi")
   .Play
   Wait .Duration
   .Stop
   .Close
 End With

End

Public Sub MediaPlayer1_End()

 Print "Esecuzione terminata !"

End

oppure un'attesa adeguata con l'istruzione "Wait":

 ...
   .Play
   Wait .Duration
 End With

 Wait 0.3

End


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("/percorso/del/file.mid")
  
  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[]
  
' 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:
  uscitaVideo = New MediaControl(mp, "ximagesink")
  
' Si dice al MediaControl di mostrare il proprio output (gli effetti video)
' in uno specifico controllo GUI, solitamente una DrawingArea:
  uscitaVideo.SetWindow(drar)
  
' Imposta il controllo di uscita video da usare:
  mp.Video.Output = uscitaVideo
  
' Un array di variabili di tipo "MediaControl", ossia di vari PlugIn disponibili:
  arrplugin = New MediaControl[]
  For b = 0 To 5
    plugVis = New MediaControl(mp, tipoPlug[b])
    arrplugin.Push(plugVis)
  Next
  
' Imposta il plug-in da utilizzare (ad esempio il 6° fra quelli contenuti dal vettore "arrplugin":
  mp.Video.Visualisation = arrplugin[5]
     
End

Public Sub Form_Activate()
 
' Esegue il file Midi:
  mp.Play()
  
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 1]

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
  
  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 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. Inoltre, premendo il tasto "Invio" viene interrotta l'esecuzione."
  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. Inoltre, premendo il tasto "Invio viene interrotta l'esecuzione."
  Input s
  
  pl.Stop
  pl.Close
  
End


Utilizzare 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 2]

I plugin specifici da utilizzare 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


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"   ' "location" è una proprietà del plugin "filesrc"
   
  par = New MediaControl(pl, "midiparse")
  flu = New MediaControl(pl, "fluiddec")
  res = New MediaControl(pl, "audioresample")
  pit = New MediaControl(pl, "pitch")
  cnv = New MediaControl(pl, "audioconvert")
  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(res)
  res.LinkTo(pit)
  pit.LinkTo(cnv)
  cnv.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()
  
  While pl.Duration > pl.Position
    Write #File.Out, "\rDurata: " & Date(0, 0, 0, 0, 0, 0, pl.Duration * 1000) &
                     "    Tempo trascorso: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
    Wait 0.01
  Wend
   
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          ' "volume" è una proprietà dell'omonimo plugin "volume"
 ValueBox3.Value = volume


Mostriamo di seguito un semplice esempio con 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 "PL"
  
 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")
 snk = New MediaControl(pl, "alsasink")
  
 src.LinkTo(par)
 par.LinkTo(flu)
 flu.LinkTo(cnv)
 cnv.LinkTo(snk)
  
 pl.Play()
  
 Print "Durata del file Midi: "; Date(0, 0, 0, 0, 0, 0, pl.Duration * 1000)
 Repeat
   Write #File.Out, "\r\e[0mTempo trascorso:      \e[31m" & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
   Flush #File.Out
   Wait 0.01
 Until bo = True
  
 pl.Stop()
 pl.Close()
 
 Write #File.Out, "\n\e[0mEsecuzione terminata !"
 Flush #File.Out
 Quit
  
End


Public Sub PL_End()
 
 bo = True
 
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 "PL"
  
 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: "; Date(0, 0, 0, 0, 0, 0, pl.Duration * 1000)
 Repeat
   Write #File.Out, "\r\e[0mTempo trascorso:      \e[31m" & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
   Flush #File.Out
   Wait 0.01
 Until bo = True
  
 pl.Stop()
 pl.Close()
 
 Write #File.Out, "\n\e[0mEsecuzione terminata !"
 Flush #File.Out
 Quit
  
End


Public Sub PL_End()
 
 bo = True
 
End



Note

[1] La stesura di paragrafo è stata possibile anche grazie al fondamentale apporto e studio del membro 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