Differenze tra le versioni di "Registrare il sonoro da una fonte esterna e salvarlo in un file audio mediante il Componente gb.media"

Da Gambas-it.org - Wikipedia.
 
(33 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
Il Componente ''gb.media'' consente mediante appositi plugin di ''GStreamer'' di registrare una fonte sonora esterna (ad esempio da un microfono) e salvare, quanto registrato, in un file audio.
 
Il Componente ''gb.media'' consente mediante appositi plugin di ''GStreamer'' di registrare una fonte sonora esterna (ad esempio da un microfono) e salvare, quanto registrato, in un file audio.
 
+
Mostriamo di seguito alcuni casi con applicazioni ''a riga di comando'', nei quali per interrompere la registrazione è sufficiente premere il tasto "''Invio'' ".  
Mostriamo di seguito alcuni casi con applicazioni ''a riga di comando'', nei quali per interrompere la registrazione è sufficiente premere il tasto "''Invio''".  
+
==Usare il plugin "alsasrc" di GStreamer per leggere i dati dalla scheda audio==
 
+
Nei seguenti esempi, per catturare sorgenti audio, useremo il plugin "alsasrc" di GStreamer, che legge i dati dalla scheda audio usando l'API di ALSA.
  
 
===Salvare la registrazione in un file audio WAV (44100 hertz, ''mono'', 16-bit)===
 
===Salvare la registrazione in un file audio WAV (44100 hertz, ''mono'', 16-bit)===
Riga 8: Riga 8:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
 
   Dim pl As MediaPipeline
 
   Dim pl As MediaPipeline
 
   Dim src, aco, wen, snk As MediaControl
 
   Dim src, aco, wen, snk As MediaControl
  Dim primofile As String
 
 
    
 
    
  primofile = "/tmp/primofile.wav"
+
  pl = New MediaPipeline
  bo = True
 
 
    
 
    
  pl = New MediaPipeline
+
  src = New MediaControl(pl, "alsasrc") 
 +
  aco = New MediaControl(pl, "audioconvert")
 +
  wen = New MediaControl(pl, "wavenc")
 +
  snk = New MediaControl(pl, "filesink")
 +
  snk["location"] = "/tmp/audio.wav"
 
    
 
    
  src = New MediaControl(pl, "alsasrc")   
+
  src.LinkTo(aco)
  aco = New MediaControl(pl, "audioconvert")
+
   aco.LinkTo(wen)
  wen = New MediaControl(pl, "wavenc")
+
  wen.LinkTo(snk)
  snk = New MediaControl(pl, "filesink")
 
  snk["location"] = primofile
 
 
    
 
    
  src.LinkTo(aco)
+
  pl.Play()
  aco.LinkTo(wen)
 
  wen.LinkTo(snk)
 
 
    
 
    
  pl.Play()
+
  While Not bo
 
+
    Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
  While bo
+
    Wait 0.01
    Write #File.Out, "\rTempo: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
+
  Wend
    Wait 0.001
+
  Wend
+
  pl.Stop()
 
+
  pl.Close()
  Copy primofile To "/tmp/audio.wav"
+
  Print "\nTermine registrazione"
 
+
  Quit
  pl.Stop()
 
  pl.Close()
 
  Print "Termine registrazione"
 
  Quit
 
 
    
 
    
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Public''' Sub Application_Read()
+
  Public Sub Application_Read()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando si preme sul tasto "Invio" della tastiera''</font>
 
 
  Dim s As String
 
 
 
  Input s
 
 
    
 
    
  bo = False
+
  bo = True
 
    
 
    
  '''End'''
+
  End
  
  
Riga 61: Riga 51:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
 
   Dim pl As MediaPipeline
 
   Dim pl As MediaPipeline
 
   Dim src, aco, wen, snk As MediaControl
 
   Dim src, aco, wen, snk As MediaControl
 
   Dim flt As MediaFilter
 
   Dim flt As MediaFilter
  Dim primofile As String
 
 
    
 
    
  primofile = "/tmp/primofile.wav"
+
  pl = New MediaPipeline
  bo = True
 
 
    
 
    
  pl = New MediaPipeline
+
  src = New MediaControl(pl, "alsasrc") 
 +
  aco = New MediaControl(pl, "audioconvert")
 +
  flt = New MediaFilter(pl, "audio/x-raw,rate=44100,depth=16,channels=2,width=16,signed=true")
 +
  wen = New MediaControl(pl, "wavenc")
 +
  snk = New MediaControl(pl, "filesink")
 +
  snk["location"] = "/tmp/audio.wav"
 
    
 
    
  src = New MediaControl(pl, "alsasrc")   
+
  src.LinkTo(aco)
  aco = New MediaControl(pl, "audioconvert")
+
   aco.LinkTo(flt)
  flt = New MediaFilter(pl, "audio/x-raw,rate=44100,depth=16,channels=2,width=16,signed=true")
+
  flt.LinkTo(wen)
  wen = New MediaControl(pl, "wavenc")
+
  wen.LinkTo(snk)
  snk = New MediaControl(pl, "filesink")
 
  snk["location"] = primofile
 
 
    
 
    
  src.LinkTo(aco)
+
  pl.Play()
  aco.LinkTo(flt)
 
  flt.LinkTo(wen)
 
  wen.LinkTo(snk)
 
 
    
 
    
  pl.Play()
+
  While Not bo
 +
    Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
 +
    Wait 0.01
 +
  Wend
 +
 +
  pl.Stop()
 +
  pl.Close()
 +
  Print "\nTermine registrazione"
 +
  Quit
 
    
 
    
  While bo
+
  End
    Write #File.Out, "\rTempo: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
 
    Wait 0.001
 
  Wend
 
 
 
  Copy primofile To "/tmp/audio.wav"
 
 
 
  pl.Stop()
 
  pl.Close()
 
  Print "Termine registrazione"
 
  Quit
 
 
 
  '''End'''
 
 
   
 
   
 
   
 
   
  '''Public''' Sub Application_Read()
+
  Public Sub Application_Read()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando si preme sul tasto "Invio" della tastiera''</font>
 
 
  Dim s As String
 
 
 
  Input s
 
 
    
 
    
  bo = False
+
  bo = True
 
    
 
    
  '''End'''
+
  End
  
  
 
===Salvare la registrazione in un file audio MP3===
 
===Salvare la registrazione in un file audio MP3===
 +
Private Const QUALITY As String = "quality"
 +
Private Const BITRATE As String = "bitrate"
 
  Private bo As Boolean
 
  Private bo As Boolean
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
+
 
   Dim pl As MediaPipeline
 
   Dim pl As MediaPipeline
   Dim src, aco, len, snk As MediaControl
+
   Dim src, aco, lam, snk As MediaControl
   Dim primofile As String
+
 
+
   pl = New MediaPipeline  
  primofile = "/tmp/primofile.mp3"
+
  bo = True
+
  src = New MediaControl(pl, "alsasrc")   
 
+
  aco = New MediaControl(pl, "audioconvert")
  pl = New MediaPipeline  
+
  lam = New MediaControl(pl, "lamemp3enc")
 
+
  lam["target"] = BITRATE  <FONT Color=gray>' ''Imposta il Bitrate.''</font>
  src = New MediaControl(pl, "alsasrc")   
+
  lam["cbr"] = True        <FONT Color=gray>' ''Imposta il Bitrate "Costante".''</font>
  aco = New MediaControl(pl, "audioconvert")
+
  lam["bitrate"] = 192      <FONT Color=gray>' ''Imposta il valore del Bitrate "Costante".''</font>
  len = New MediaControl(pl, "lamemp3enc")
+
  snk = New MediaControl(pl, "filesink")
  snk = New MediaControl(pl, "filesink")
+
  snk["location"] = "/tmp/audio.mp3"
  snk["location"] = primofile
+
 
+
  src.LinkTo(aco)
  src.LinkTo(aco)
+
  aco.LinkTo(lam)
  aco.LinkTo(len)
+
  lam.LinkTo(snk)
  len.LinkTo(snk)
+
 
+
  pl.Play()
  pl.Play()
+
 
+
  While Not bo
  While bo
+
    Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
    Write #File.Out, "\rTempo: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
+
    Wait 0.01
    Wait 0.001
+
  Wend
  Wend
+
 
+
  pl.Stop()
  Copy primofile To "/tmp/audio.mp3"
+
  pl.Close()
 
+
  Print "Termine registrazione"
  pl.Stop()
+
  Quit
  pl.Close()
+
  Print "Termine registrazione"
+
  End
  Quit
 
 
 
  '''End'''
 
 
   
 
   
 
   
 
   
  '''Public''' Sub Application_Read()
+
  Public Sub Application_Read()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando si preme sul tasto "Invio" della tastiera''</font>
 
 
  Dim s As String
 
 
 
  Input s
 
 
    
 
    
  bo = False
+
  bo = True
 
    
 
    
  '''End'''
+
  End
  
  
Riga 170: Riga 145:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
+
 
   Dim pl As MediaPipeline
 
   Dim pl As MediaPipeline
 
   Dim src, aco, ven, omu, snk As MediaControl
 
   Dim src, aco, ven, omu, snk As MediaControl
  Dim primofile As String
 
 
 
  primofile = "/tmp/primofile.ogg"
 
  bo = True
 
 
 
  pl = New MediaPipeline
 
 
 
  src = New MediaControl(pl, "alsasrc") 
 
  aco = New MediaControl(pl, "audioconvert")
 
  ven = New MediaControl(pl, "vorbisenc")
 
  omu = New MediaControl(pl, "oggmux")
 
  snk = New MediaControl(pl, "filesink")
 
  snk["location"] = primofile
 
 
 
  src.LinkTo(aco)
 
  aco.LinkTo(ven)
 
  ven.LinkTo(omu)
 
  omu.LinkTo(snk)
 
 
 
  pl.Play()
 
 
 
  While bo
 
    Write #File.Out, "\rTempo: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
 
    Wait 0.001
 
  Wend
 
 
 
  Copy primofile To "/tmp/audio.ogg"
 
 
 
  pl.Stop()
 
  pl.Close()
 
  Print "Termine registrazione"
 
  Quit
 
 
 
'''End'''
 
 
   
 
   
 +
  pl = New MediaPipeline
 +
 +
  src = New MediaControl(pl, "alsasrc") 
 +
  aco = New MediaControl(pl, "audioconvert")
 +
  ven = New MediaControl(pl, "vorbisenc")
 +
  omu = New MediaControl(pl, "oggmux")
 +
  snk = New MediaControl(pl, "filesink")
 +
  snk["location"] = "/tmp/audio.ogg"
 +
 +
  src.LinkTo(aco)
 +
  aco.LinkTo(ven)
 +
  ven.LinkTo(omu)
 +
  omu.LinkTo(snk)
 +
 +
  pl.Play()
 +
 +
  While Not bo
 +
    Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
 +
    Wait 0.01
 +
  Wend
 +
 +
  pl.Stop()
 +
  pl.Close()
 +
  Print "Termine registrazione"
 +
  Quit
 +
 +
End
 +
 +
 +
Public Sub Application_Read()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando si preme sul tasto "Invio" della tastiera''</font>
 +
 +
  bo = True
 +
 +
End
 +
 +
 +
===Salvare la registrazione in un file audio AAC===
 +
Private bo As Boolean
 +
 +
 +
Public Sub Main()
 +
 +
  Dim pl As MediaPipeline
 +
  Dim src, cnv, faac, snk As MediaControl
 +
  Dim flt As MediaFilter
 +
 +
  pl = New MediaPipeline
 +
 +
  src = New MediaControl(pl, "alsasrc")
 +
  cnv = New MediaControl(pl, "audioconvert")
 +
  faac = New MediaControl(pl, "faac")  <FONT Color=gray>' ''oppure anche "'''voaacenc'''"''</font>
 +
  flt = New MediaFilter(pl, "audio/mpeg,stream-format=adts,channels=2,rate=44100")
 +
  snk = New MediaControl(pl, "filesink")
 +
  snk["location"] = "/tmp/file.aac"
 +
 +
  src.LinkTo(cnv)
 +
  cnv.LinkTo(faac)
 +
  faac.LinkTo(flt)
 +
  flt.LinkTo(snk)
 +
 +
  pl.Play()
 +
 +
  While Not bo
 +
    Write "\r\e[0mTempo trascorso:    \e[31m" & Time(0, 0, 0, pl.Position * 1000)
 +
    Wait 0.01
 +
  Wend
 +
 +
  pl.Stop
 +
  pl.Close
 +
  Print "Termine registrazione !"
 +
  Quit
 +
 +
End
 +
 +
 +
Public Sub Application_Read()  <FONT Color=gray>' ''Questo Evento viene sollevato, quando si preme sul tasto "Invio" della tastiera''</font>
 +
 +
  bo = True
 
   
 
   
  '''Public''' Sub Application_Read()
+
  End
 
 
  Dim s As String
 
 
 
  Input s
 
 
 
  bo = False
 
 
 
'''End'''
 
  
  
===Impostare preliminarmente la durata della regisrazione audio===
+
===Impostare preliminarmente la durata della registrazione audio===
 
Nei precedenti esempi la registrazione audio veniva interrotta arbitrariamente dall'utente. Volendo impostare invece preliminarmente la durata della registrazione audio, bisognerà assegnare i rispettivi valori alle proprietà "''num-buffers''" e "''blocksize''" dell'elemento "''alsasrc''", nonché stabilire la durata del ciclo, previsto nella routine principale del codice, secondo il seguente calcolo:
 
Nei precedenti esempi la registrazione audio veniva interrotta arbitrariamente dall'utente. Volendo impostare invece preliminarmente la durata della registrazione audio, bisognerà assegnare i rispettivi valori alle proprietà "''num-buffers''" e "''blocksize''" dell'elemento "''alsasrc''", nonché stabilire la durata del ciclo, previsto nella routine principale del codice, secondo il seguente calcolo:
 
  durata = numero_buffer * dimensione_un_buffer * 8 / (frequenza_di_campionamento * canali * risoluzione_bit)
 
  durata = numero_buffer * dimensione_un_buffer * 8 / (frequenza_di_campionamento * canali * risoluzione_bit)
 
Così ad esempio: 40 * 44100 * 8 / (44100 * 2 * 16) = 10 secondi
 
Così ad esempio: 40 * 44100 * 8 / (44100 * 2 * 16) = 10 secondi
 
  
 
Mostriamo un esempio pratico:
 
Mostriamo un esempio pratico:
  '''Public''' Sub Main()
+
  Public Sub Main()
 
+
 
   Dim pl As MediaPipeline
 
   Dim pl As MediaPipeline
 
   Dim src, enc, snk As MediaControl
 
   Dim src, enc, snk As MediaControl
 
   Dim tm As Date
 
   Dim tm As Date
   Dim dur, bs, dur_eff, i As Integer
+
   Dim dur, bs, dur_eff As Integer
 
   Dim canali, bit As Byte
 
   Dim canali, bit As Byte
  Dim primofile, mss As String
+
 
 
  primofile = "/tmp/primofile"
 
 
 
 
  <FONT Color=gray>' ''Imposta il numero di blocchi audio di cui sarà formata la registrazione audio:''</font>
 
  <FONT Color=gray>' ''Imposta il numero di blocchi audio di cui sarà formata la registrazione audio:''</font>
  dur = 40
+
  dur = 40
  bs = 44100
+
  bs = 44100
  canali = 2
+
  canali = 2
  bit = 16
+
  bit = 16
  dur_eff = dur * bs * 8 / (bs * canali * bit)
+
  dur_eff = dur * bs * 8 / (bs * canali * bit)
 
    
 
    
  pl = New MediaPipeline  
+
  pl = New MediaPipeline  
 
    
 
    
  src = New MediaControl(pl, "alsasrc")
+
  src = New MediaControl(pl, "alsasrc")
  src["num-buffers"] = dur
+
  src["num-buffers"] = dur
  src["blocksize"] = bs
+
  src["blocksize"] = bs
  enc = New MediaControl(pl, "wavenc")
+
  enc = New MediaControl(pl, "wavenc")
  snk = New MediaControl(pl, "filesink")
+
  snk = New MediaControl(pl, "filesink")
  snk["location"] = primofile
+
  snk["location"] = "/tmp/file.wav"
 
      
 
      
 
  <FONT Color=gray>' ''Colleghiamo fra loro gli Elementi di "GStreamer":''</font>
 
  <FONT Color=gray>' ''Colleghiamo fra loro gli Elementi di "GStreamer":''</font>
  src.LinkTo(enc)
+
  src.LinkTo(enc)
  enc.LinkTo(snk)
+
  enc.LinkTo(snk)
 
    
 
    
 
  <FONT Color=gray>' ''Avvia la registrazione audio:''</font>
 
  <FONT Color=gray>' ''Avvia la registrazione audio:''</font>
  pl.Play()
+
  pl.Play()
 
    
 
    
  tm = Now  
+
  tm = Now  
 
    
 
    
  Do
+
  Repeat
    i = DateDiff(tm, Now, gb.Millisecond)
+
    Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
    If i < (dur_eff * 1000) Then
+
    Wait 0.01
      mss = "\rTempo: " & CStr(Date(0, 0, 0, 0, 0, 0, i))
+
  Until DateDiff(tm, Now, gb.Millisecond) >= (dur_eff * 1000)
    Else
+
      pl.Stop()
+
  pl.Stop()
      pl.Close()
+
  pl.Close()
      Copy primofile To "/tmp/file.wav"
+
  Print "\rRegistrazione terminata !"
      mss = "\rRegistrazione terminata !"
+
      Quit
+
End
    Endif
+
 
    Write #File.Out, mss
+
 
  Loop
+
==Usare il plugin "pulsesrc" di GStreamer per leggere i dati dalla scheda audio==
 
+
Nei seguenti esempi useremo il plugin "pulsesrc" di GStreamer, per catturare dati dalla scheda audio. specificando nel contempo anche il nome del dispositivo audio utilizzato.
  '''End'''
+
 
 +
====Registrare i dati in "Uscita" della scheda audio====
 +
In queato caso verranno registrati i dati audio in '''uscita''' dalla scheda audio (ad esempio quando vengono riprodotti da un file audio).
 +
<BR>Per conoscere il nome del dispositivo audio disponibile, è sufficiente lanciare da terminale la seguente riga di comando:
 +
~$ pactl list sinks
 +
che restituirà una serie di informazioni, le prime delle quali saranno simili a quanto segue:
 +
  <FONT Size=2>sink #0
 +
        Stato: SUSPENDED
 +
        Nome: alsa_output.pci-0000_00_14.2.analog-stereo
 +
        Descrizione: Audio interno Stereo analogico
 +
        Driver: module-alsa-card.c
 +
        Specifica di campionamento: s16le ch 2 44100 Hz
 +
        Mappa dei canali: front-left,front-right
 +
        Modulo di appartenenza: 7
 +
        Muto: no
 +
        Volume: front-left: 45773 /  70% / -9,35 dB,  front-right: 45773 /  70% / -9,35 dB
 +
                bilanciamento 0,00
 +
        Volume base: 65536 / 100% / 0,00 dB
 +
        Monitor della sorgente: alsa_output.pci-0000_00_14.2.analog-stereo.monitor
 +
        Latenza: 0 usec, configurata 0 usec</font>
 +
La riga, che a noi interessa, è:
 +
<FONT COLOR=darkgreen>Monitor della sorgente: '''alsa_output.pci-0000_00_14.2.analog-stereo.monitor'''</font>
 +
(ovviamente questa parte "pci-0000_00_14.2" potrà avere numeri diversi da utente a utente).
 +
 
 +
Questa riga può essere individuata anche più facilmente lanciando il comando:
 +
  ~$ pacmd list-sources
 +
La sottostringa che ci interessa davvero è comunque questa:
 +
<FONT COLOR=darkorange>'''alsa_output.pci-0000_00_14.2.analog-stereo.monitor'''</font>
 +
La stessa in Gambas può essere raccolta con questo semplice codice:
 +
Public Sub Main()
 +
 +
  Dim s As String
 +
 
 +
  Shell "pacmd list-sources" To s
 +
 
 +
  Print Scan(s, "*name: <*>*")[1]
 +
 +
End
 +
Da notare comunque che:
 +
<BR>1) la parte del nome "alsa_<B>output</b>", fa sì che saranno registrati i dati provenienti dall''''uscita''' sonora della scheda audio;
 +
 
 +
2) la parte "pci-0000_00_14.2" della stringa di informazioni, ottenute e riportate sopra a titolo esemplificativo (quindi può variare per ogni utente), può essere recuperata anche leggendo il nome dei file di collegamento presenti nella seguente cartella: "/dev/snd/by-path".
 +
<BR>I file presenti nella predetta cartella "by-path", sono visibili anche nel percorso "/sys/devices/pci0000:00".
 +
 
 +
Mostriamo un esempio pratico a "riga di comando", con il quale si otterrà un file audio finale del formato MP3:
 +
Private Const QUALITY As String = "quality"
 +
Private Const BITRATE As String = "bitrate"
 +
Private bo As Boolean
 +
 +
 +
Public Sub Main()
 +
 +
  Dim pl As MediaPipeline
 +
  Dim src, lam, snk As MediaControl
 +
  Dim sorg As String
 +
 +
  Shell "pacmd list-sources" To sorg
 +
  sorg = Scan(sorg, "*name: <*>*")[1]
 +
 +
  pl = New MediaPipeline
 +
 +
  src = New MediaControl(pl, "pulsesrc") 
 +
  src["device"] = <FONT COLOR=darkgreen>sorg</font>
 +
  lam = New MediaControl(pl, "lamemp3enc")
 +
  lam["target"] = BITRATE    <FONT Color=gray>' ''Imposta il Bitrate.''</font>
 +
  lam["cbr"] = True          <FONT Color=gray>' ''Imposta il Bitrate "Costante".''</font>
 +
  lam["bitrate"] = 192      <FONT Color=gray>' ''Imposta il valore del Bitrate "Costante".''</font>
 +
  snk = New MediaControl(pl, "filesink")
 +
  snk["location"] = "/tmp/audio.mp3"
 +
 +
  src.LinkTo(lam)
 +
  lam.LinkTo(snk)
 +
 +
  pl.Play()
 +
 +
  While Not bo
 +
    Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
 +
    Wait 0.01
 +
  Wend
 +
 +
  pl.Stop()
 +
  pl.Close()
 +
  Print "\nTermine registrazione"
 +
  Quit
 +
 +
End
 +
 +
Public Sub Application_Read()  <FONT Color=gray>' ''Questo Evento viene sollevato, cliccando sul tasto "Invio" della tastiera''</font>
 +
 
 +
bo = True
 +
 
 +
End
 +
In quest'altro esempio, analogo al precedente, si otterrà un file audio di formato OGG:
 +
Private bo As Boolean
 +
 +
 +
Public Sub Main()
 +
 +
  Dim pl As MediaPipeline
 +
  Dim src, aco, ven, omu, snk As MediaControl
 +
  Dim sorg As String
 +
 +
  Shell "pacmd list-sources" To sorg
 +
  sorg = Scan(sorg, "*name: <*>*")[1]
 +
 +
  pl = New MediaPipeline
 +
 +
  src = New MediaControl(pl, "pulsesrc") 
 +
  src["device"] = <FONT COLOR=darkgreen>sorg</font>
 +
  aco = New MediaControl(pl, "audioconvert")
 +
  ven = New MediaControl(pl, "vorbisenc")
 +
  omu = New MediaControl(pl, "oggmux")
 +
  snk = New MediaControl(pl, "filesink")
 +
  snk["location"] = "/tmp/audio.ogg"
 +
 +
  src.LinkTo(aco)
 +
  aco.LinkTo(ven)
 +
  ven.LinkTo(omu)
 +
  omu.LinkTo(snk)
 +
 +
  pl.Play()
 +
 +
  While Not bo
 +
    Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
 +
    Wait 0.01
 +
  Wend
 +
 +
  pl.Stop()
 +
  pl.Close()
 +
  Print "\nTermine registrazione"
 +
  Quit
 +
 +
End
 +
 +
Public Sub Application_Read()  <FONT Color=gray>' ''Questo Evento viene sollevato, cliccando sul tasto "Invio" della tastiera''</font>
 +
 
 +
bo = True
 +
 
 +
End
 +
 
 +
====Registrare i dati in "Entrata" della scheda audio====
 +
Se si intende, invece, registrare i dati sonori in '''Entrata''' della scheda audio (ad esempio i dati audio provenienti da un microfono), riprendendo le righe esemplificative restituite dal comando "pactl list sinks", si prenderà in considerazione la riga:
 +
Nome: alsa_output.pci-0000_00_14.2.analog-stereo
 +
sostituenda la parola "output" con "'''input'''", ottenendo quindi:
 +
  alsa_<FONT Color=#B22222>'''input'''</font>.pci-0000_00_14.2.analog-stereo
  
  
Riga 290: Riga 441:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
+
 
   Dim pl As MediaPipeline
 
   Dim pl As MediaPipeline
 
   Dim src, aco, wen, snk As MediaControl
 
   Dim src, aco, wen, snk As MediaControl
 
   Dim flt As MediaFilter
 
   Dim flt As MediaFilter
   Dim primofile As String
+
 +
   pl = New MediaPipeline
 
    
 
    
  primofile = "/tmp/primofile.wav"
+
  src = New MediaControl(pl, "<FONT Color=#B22222>jackaudiosrc</font>")
  bo = True
+
  src["client-name"] = "Nome_Client"
 +
  src["connect"] = 0
 +
  aco = New MediaControl(pl, "audioconvert")
 +
  flt = New MediaFilter(pl, "audio/x-raw,rate=44100,depth=16,channels=2,width=16,signed=true")
 +
  wen = New MediaControl(pl, "wavenc")
 +
  snk = New MediaControl(pl, "filesink")
 +
  snk["location"] = "/tmp/audio.wav"
 
    
 
    
  pl = New MediaPipeline
+
  src.LinkTo(aco)
 +
  aco.LinkTo(flt)
 +
  flt.LinkTo(wen)
 +
  wen.LinkTo(snk)
 
    
 
    
  src = New MediaControl(pl, "<FONT Color=#B22222>jackaudiosrc</font>")
+
  pl.Play()
  src["client-name"] = "Nome_Client"
 
  src["connect"] = 0
 
  aco = New MediaControl(pl, "audioconvert")
 
  flt = New MediaFilter(pl, "audio/x-raw,rate=44100,depth=16,channels=2,width=16,signed=true")
 
  wen = New MediaControl(pl, "wavenc")
 
  snk = New MediaControl(pl, "filesink")
 
  snk["location"] = primofile
 
 
    
 
    
  src.LinkTo(aco)
+
  While Not bo
  aco.LinkTo(flt)
+
    Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
  flt.LinkTo(wen)
+
    Wait 0.01
  wen.LinkTo(snk)
+
  Wend
 +
 +
  pl.Stop()
 +
  pl.Close()
 +
  Print "Termine registrazione"
 +
  Quit
 
    
 
    
  pl.Play()
+
End
 
+
  While bo
+
    Write #File.Out, "\rTempo: " & Date(0, 0, 0, 0, 0, 0, pl.Position * 1000)
+
Public Sub Application_Read()  <FONT Color=gray>' ''Questo Evento viene sollevato, cliccando sul tasto "Invio" della tastiera''</font>
    Wait 0.001
 
  Wend
 
 
 
  Copy primofile To "/tmp/audio.wav"
 
 
 
  pl.Stop()
 
  pl.Close()
 
  Print "Termine registrazione"
 
  Quit
 
 
 
  '''End'''
 
 
   
 
   
 +
  bo = True
 
   
 
   
  '''Public''' Sub Application_Read()
+
  End
 
 
  Dim s As String
 
 
 
  Input s
 
 
 
  bo = False
 
 
 
'''End'''
 

Versione attuale delle 18:45, 17 gen 2024

Il Componente gb.media consente mediante appositi plugin di GStreamer di registrare una fonte sonora esterna (ad esempio da un microfono) e salvare, quanto registrato, in un file audio. Mostriamo di seguito alcuni casi con applicazioni a riga di comando, nei quali per interrompere la registrazione è sufficiente premere il tasto "Invio ".

Usare il plugin "alsasrc" di GStreamer per leggere i dati dalla scheda audio

Nei seguenti esempi, per catturare sorgenti audio, useremo il plugin "alsasrc" di GStreamer, che legge i dati dalla scheda audio usando l'API di ALSA.

Salvare la registrazione in un file audio WAV (44100 hertz, mono, 16-bit)

Private bo As Boolean


Public Sub Main()
 
 Dim pl As MediaPipeline
 Dim src, aco, wen, snk As MediaControl
  
 pl = New MediaPipeline 
  
 src = New MediaControl(pl, "alsasrc")   
 aco = New MediaControl(pl, "audioconvert")
 wen = New MediaControl(pl, "wavenc")
 snk = New MediaControl(pl, "filesink")
 snk["location"] = "/tmp/audio.wav"
  
 src.LinkTo(aco)
 aco.LinkTo(wen)
 wen.LinkTo(snk)
  
 pl.Play()
  
 While Not bo
   Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Wend

 pl.Stop()
 pl.Close()
 Print "\nTermine registrazione"
 Quit
  
End


Public Sub Application_Read()  ' Questo Evento viene sollevato, quando si preme sul tasto "Invio" della tastiera
  
 bo = True
  
End


Salvare la registrazione in un file audio WAV (44100 hertz, stereo, 16-bit)

Private bo As Boolean


Public Sub Main()
 
 Dim pl As MediaPipeline
 Dim src, aco, wen, snk As MediaControl
 Dim flt As MediaFilter
  
 pl = New MediaPipeline 
  
 src = New MediaControl(pl, "alsasrc")   
 aco = New MediaControl(pl, "audioconvert")
 flt = New MediaFilter(pl, "audio/x-raw,rate=44100,depth=16,channels=2,width=16,signed=true")
 wen = New MediaControl(pl, "wavenc")
 snk = New MediaControl(pl, "filesink")
 snk["location"] = "/tmp/audio.wav"
  
 src.LinkTo(aco)
 aco.LinkTo(flt)
 flt.LinkTo(wen)
 wen.LinkTo(snk)
  
 pl.Play()
  
 While Not bo
   Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Wend

 pl.Stop()
 pl.Close()
 Print "\nTermine registrazione"
 Quit
  
End


Public Sub Application_Read()  ' Questo Evento viene sollevato, quando si preme sul tasto "Invio" della tastiera
  
 bo = True
  
End


Salvare la registrazione in un file audio MP3

Private Const QUALITY As String = "quality"
Private Const BITRATE As String = "bitrate"
Private bo As Boolean


Public Sub Main()

 Dim pl As MediaPipeline
 Dim src, aco, lam, snk As MediaControl

 pl = New MediaPipeline 

 src = New MediaControl(pl, "alsasrc")   
 aco = New MediaControl(pl, "audioconvert")
 lam = New MediaControl(pl, "lamemp3enc")
 lam["target"] = BITRATE   ' Imposta il Bitrate.
 lam["cbr"] = True         ' Imposta il Bitrate "Costante".
 lam["bitrate"] = 192      ' Imposta il valore del Bitrate "Costante".
 snk = New MediaControl(pl, "filesink")
 snk["location"] = "/tmp/audio.mp3"

 src.LinkTo(aco)
 aco.LinkTo(lam)
 lam.LinkTo(snk)

 pl.Play()

 While Not bo
   Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Wend

 pl.Stop()
 pl.Close()
 Print "Termine registrazione"
 Quit

End


Public Sub Application_Read()  ' Questo Evento viene sollevato, quando si preme sul tasto "Invio" della tastiera
  
 bo = True
  
End


Salvare la registrazione in un file audio OGG

Private bo As Boolean


Public Sub Main()

 Dim pl As MediaPipeline
 Dim src, aco, ven, omu, snk As MediaControl

 pl = New MediaPipeline 

 src = New MediaControl(pl, "alsasrc")   
 aco = New MediaControl(pl, "audioconvert")
 ven = New MediaControl(pl, "vorbisenc")
 omu = New MediaControl(pl, "oggmux")
 snk = New MediaControl(pl, "filesink")
 snk["location"] = "/tmp/audio.ogg"

 src.LinkTo(aco)
 aco.LinkTo(ven)
 ven.LinkTo(omu)
 omu.LinkTo(snk)

 pl.Play()

 While Not bo
   Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Wend

 pl.Stop()
 pl.Close()
 Print "Termine registrazione"
 Quit

End


Public Sub Application_Read()  ' Questo Evento viene sollevato, quando si preme sul tasto "Invio" della tastiera

 bo = True

End


Salvare la registrazione in un file audio AAC

Private bo As Boolean


Public Sub Main()

 Dim pl As MediaPipeline
 Dim src, cnv, faac, snk As MediaControl
 Dim flt As MediaFilter

 pl = New MediaPipeline

 src = New MediaControl(pl, "alsasrc")
 cnv = New MediaControl(pl, "audioconvert")
 faac = New MediaControl(pl, "faac")   ' oppure anche "voaacenc"
 flt = New MediaFilter(pl, "audio/mpeg,stream-format=adts,channels=2,rate=44100")
 snk = New MediaControl(pl, "filesink")
 snk["location"] = "/tmp/file.aac"

 src.LinkTo(cnv)
 cnv.LinkTo(faac)
 faac.LinkTo(flt)
 flt.LinkTo(snk)

 pl.Play()

 While Not bo
   Write "\r\e[0mTempo trascorso:     \e[31m" & Time(0, 0, 0, pl.Position * 1000)
   Wait 0.01
 Wend

 pl.Stop
 pl.Close
 Print "Termine registrazione !"
 Quit

End


Public Sub Application_Read()  ' Questo Evento viene sollevato, quando si preme sul tasto "Invio" della tastiera

 bo = True

End


Impostare preliminarmente la durata della registrazione audio

Nei precedenti esempi la registrazione audio veniva interrotta arbitrariamente dall'utente. Volendo impostare invece preliminarmente la durata della registrazione audio, bisognerà assegnare i rispettivi valori alle proprietà "num-buffers" e "blocksize" dell'elemento "alsasrc", nonché stabilire la durata del ciclo, previsto nella routine principale del codice, secondo il seguente calcolo:

durata = numero_buffer * dimensione_un_buffer * 8 / (frequenza_di_campionamento * canali * risoluzione_bit)

Così ad esempio: 40 * 44100 * 8 / (44100 * 2 * 16) = 10 secondi

Mostriamo un esempio pratico:

Public Sub Main()

 Dim pl As MediaPipeline
 Dim src, enc, snk As MediaControl
 Dim tm As Date
 Dim dur, bs, dur_eff As Integer
 Dim canali, bit As Byte

' Imposta il numero di blocchi audio di cui sarà formata la registrazione audio:
 dur = 40
 bs = 44100
 canali = 2
 bit = 16
 dur_eff = dur * bs * 8 / (bs * canali * bit)
  
 pl = New MediaPipeline 
  
 src = New MediaControl(pl, "alsasrc")
 src["num-buffers"] = dur
 src["blocksize"] = bs
 enc = New MediaControl(pl, "wavenc")
 snk = New MediaControl(pl, "filesink")
 snk["location"] = "/tmp/file.wav"
   
' Colleghiamo fra loro gli Elementi di "GStreamer":
 src.LinkTo(enc)
 enc.LinkTo(snk)
  
' Avvia la registrazione audio:
 pl.Play()
  
 tm = Now 
  
 Repeat 
   Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Until DateDiff(tm, Now, gb.Millisecond) >= (dur_eff * 1000)

 pl.Stop()
 pl.Close()
 Print "\rRegistrazione terminata !"

End


Usare il plugin "pulsesrc" di GStreamer per leggere i dati dalla scheda audio

Nei seguenti esempi useremo il plugin "pulsesrc" di GStreamer, per catturare dati dalla scheda audio. specificando nel contempo anche il nome del dispositivo audio utilizzato.

Registrare i dati in "Uscita" della scheda audio

In queato caso verranno registrati i dati audio in uscita dalla scheda audio (ad esempio quando vengono riprodotti da un file audio).
Per conoscere il nome del dispositivo audio disponibile, è sufficiente lanciare da terminale la seguente riga di comando:

~$ pactl list sinks

che restituirà una serie di informazioni, le prime delle quali saranno simili a quanto segue:

 sink #0
       Stato: SUSPENDED
       Nome: alsa_output.pci-0000_00_14.2.analog-stereo
       Descrizione: Audio interno Stereo analogico
       Driver: module-alsa-card.c
       Specifica di campionamento: s16le ch 2 44100 Hz
       Mappa dei canali: front-left,front-right
       Modulo di appartenenza: 7
       Muto: no
       Volume: front-left: 45773 /  70% / -9,35 dB,   front-right: 45773 /  70% / -9,35 dB
               bilanciamento 0,00
       Volume base: 65536 / 100% / 0,00 dB
       Monitor della sorgente: alsa_output.pci-0000_00_14.2.analog-stereo.monitor
       Latenza: 0 usec, configurata 0 usec

La riga, che a noi interessa, è:

Monitor della sorgente: alsa_output.pci-0000_00_14.2.analog-stereo.monitor

(ovviamente questa parte "pci-0000_00_14.2" potrà avere numeri diversi da utente a utente).

Questa riga può essere individuata anche più facilmente lanciando il comando:

 ~$ pacmd list-sources

La sottostringa che ci interessa davvero è comunque questa:

alsa_output.pci-0000_00_14.2.analog-stereo.monitor

La stessa in Gambas può essere raccolta con questo semplice codice:

Public Sub Main()

 Dim s As String
 
 Shell "pacmd list-sources" To s
 
 Print Scan(s, "*name: <*>*")[1]

End

Da notare comunque che:
1) la parte del nome "alsa_output", fa sì che saranno registrati i dati provenienti dall'uscita sonora della scheda audio;

2) la parte "pci-0000_00_14.2" della stringa di informazioni, ottenute e riportate sopra a titolo esemplificativo (quindi può variare per ogni utente), può essere recuperata anche leggendo il nome dei file di collegamento presenti nella seguente cartella: "/dev/snd/by-path".
I file presenti nella predetta cartella "by-path", sono visibili anche nel percorso "/sys/devices/pci0000:00".

Mostriamo un esempio pratico a "riga di comando", con il quale si otterrà un file audio finale del formato MP3:

Private Const QUALITY As String = "quality"
Private Const BITRATE As String = "bitrate"
Private bo As Boolean


Public Sub Main()

 Dim pl As MediaPipeline
 Dim src, lam, snk As MediaControl
 Dim sorg As String

 Shell "pacmd list-sources" To sorg
 sorg = Scan(sorg, "*name: <*>*")[1]

 pl = New MediaPipeline 

 src = New MediaControl(pl, "pulsesrc")   
 src["device"] = sorg
 lam = New MediaControl(pl, "lamemp3enc")
 lam["target"] = BITRATE    ' Imposta il Bitrate.
 lam["cbr"] = True          ' Imposta il Bitrate "Costante".
 lam["bitrate"] = 192       ' Imposta il valore del Bitrate "Costante".
 snk = New MediaControl(pl, "filesink")
 snk["location"] = "/tmp/audio.mp3"

 src.LinkTo(lam)
 lam.LinkTo(snk)

 pl.Play()

 While Not bo
   Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Wend

 pl.Stop()
 pl.Close()
 Print "\nTermine registrazione"
 Quit

End

Public Sub Application_Read()  ' Questo Evento viene sollevato, cliccando sul tasto "Invio" della tastiera
 
bo = True
 
End

In quest'altro esempio, analogo al precedente, si otterrà un file audio di formato OGG:

Private bo As Boolean


Public Sub Main()

 Dim pl As MediaPipeline
 Dim src, aco, ven, omu, snk As MediaControl
 Dim sorg As String

 Shell "pacmd list-sources" To sorg
 sorg = Scan(sorg, "*name: <*>*")[1]

 pl = New MediaPipeline 

 src = New MediaControl(pl, "pulsesrc")   
 src["device"] = sorg
 aco = New MediaControl(pl, "audioconvert")
 ven = New MediaControl(pl, "vorbisenc")
 omu = New MediaControl(pl, "oggmux")
 snk = New MediaControl(pl, "filesink")
 snk["location"] = "/tmp/audio.ogg"

 src.LinkTo(aco)
 aco.LinkTo(ven)
 ven.LinkTo(omu)
 omu.LinkTo(snk)

 pl.Play()

 While Not bo
   Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Wend

 pl.Stop()
 pl.Close()
 Print "\nTermine registrazione"
 Quit

End

Public Sub Application_Read()  ' Questo Evento viene sollevato, cliccando sul tasto "Invio" della tastiera
 
bo = True
 
End

Registrare i dati in "Entrata" della scheda audio

Se si intende, invece, registrare i dati sonori in Entrata della scheda audio (ad esempio i dati audio provenienti da un microfono), riprendendo le righe esemplificative restituite dal comando "pactl list sinks", si prenderà in considerazione la riga:

Nome: alsa_output.pci-0000_00_14.2.analog-stereo

sostituenda la parola "output" con "input", ottenendo quindi:

alsa_input.pci-0000_00_14.2.analog-stereo


Registrare utilizzando il plugin "jackaudiosink" di GStreamer

Per effettuare una registrazione audio è possibile anche creare 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. Successivamente all'avvio del programma bisognerà connettere la porta d'entrata del client, creato dal server Jack e che rappresenta il programma Gambas, e la destinazione (di default il primo canale audio d'uscita disponibile della propria scheda audio).

Mostriamo un semplice esempio di registrazione con un'applicazione a riga di comando, nel quale si genererà alla fine un file WAV:

Private bo As Boolean


Public Sub Main()

 Dim pl As MediaPipeline
 Dim src, aco, wen, snk As MediaControl
 Dim flt As MediaFilter

 pl = New MediaPipeline 
 
 src = New MediaControl(pl, "jackaudiosrc")
 src["client-name"] = "Nome_Client"
 src["connect"] = 0
 aco = New MediaControl(pl, "audioconvert")
 flt = New MediaFilter(pl, "audio/x-raw,rate=44100,depth=16,channels=2,width=16,signed=true")
 wen = New MediaControl(pl, "wavenc")
 snk = New MediaControl(pl, "filesink")
 snk["location"] = "/tmp/audio.wav"
  
 src.LinkTo(aco)
 aco.LinkTo(flt)
 flt.LinkTo(wen)
 wen.LinkTo(snk)
  
 pl.Play()
  
 While Not bo
   Write "\rTempo: " & Str(Time(0, 0, 0, pl.Position * 1000))
   Wait 0.01
 Wend

 pl.Stop()
 pl.Close()
 Print "Termine registrazione"
 Quit
  
End


Public Sub Application_Read()  ' Questo Evento viene sollevato, cliccando sul tasto "Invio" della tastiera

 bo = True

End