Differenze tra le versioni di "Conoscere in tempo reale la quantità di frame audio processati dalla scheda audio"

Da Gambas-it.org - Wikipedia.
Riga 5: Riga 5:
 
Mentre un qualunque programma sta eseguendo un file audio o Midi, è possibile lanciare uno dei seguenti codici.
 
Mentre un qualunque programma sta eseguendo un file audio o Midi, è possibile lanciare uno dei seguenti codici.
  
===Aprire in ''osservazione'' il file "...sub0/status"===
+
In questo codice nella routine principale apriremo il file "...sub0/status" del dispositivo audio attivo, ponendolo sotto ''osservazione'' al solo fine di far sollevare l'Evento di lettura "File_Read()", e così di leggere con una nuova e diversa apertura del medesimo file i dati utili, ogni qual volta vi sono dati appunto da leggere.
In questo primo codice nella routine principale apriremo il file "...sub0/status" del dispositivo audio attivo, ponendolo sotto osservazione al solo fine di far sollevare l'Evento di lettura "File_Read()", e così di leggere con una nuova e diversa apertura del medesimo file i dati utili, ogni qual volta vi sono dati appunto da leggere.
 
 
<BR>Una lettura diretta del file nella routine "File_Read()" mediante la variabile di tipo File, ottenuta con l'istruzione ''Open'' della routine principale "Sub Main()", non risulta possibile: seppure assenti errori, non vengono restituiti dati.
 
<BR>Una lettura diretta del file nella routine "File_Read()" mediante la variabile di tipo File, ottenuta con l'istruzione ''Open'' della routine principale "Sub Main()", non risulta possibile: seppure assenti errori, non vengono restituiti dati.
Private fl As File
+
<BR>Verrà mostrato il tempo trascorso sulla base dei frame audio processati.
Private dis As String
 
 
 
'''Public''' Sub Main()
 
 
 
<FONT Color=gray>' ''Verifica quale dispositivo audio è attivo:''</font>
 
  dis = DispositivoAttivo()
 
 
 
<FONT Color=gray>' ''Apriamo il file solo per far sollevare l'evento di lettura ogni qual volta v'è qualcosa di nuovo da leggervi:''</font>
 
  fl = Open dis For Read Watch
 
 
 
'''End'''
 
 
'''Private''' Function DispositivoAttivo() As String
 
 
 
  Dim per, ca, pc, su As String
 
 
<FONT Color=gray>' ''Verifica se qualche dispositivo audio è presente nel sistema:''</font>
 
  If Dir("/proc/asound", "card*", gb.Directory).Count == 0 Then Error.Raise("Dispositivo audio assente !")
 
 
 
  per = "/proc/asound"
 
 
 
  For Each ca In Dir(per, "card*", gb.Directory)
 
    For Each pc In Dir(per &/ ca, "pcm*p", gb.Directory)
 
      For Each su In Dir(per &/ ca &/ pc, "sub*", gb.Directory)
 
        If InStr(File.Load(per &/ ca &/ pc &/ su &/ "status"), "RUNNING") > 0 Then Break
 
      Next
 
    Next
 
  Next
 
 
 
  Return per &/ ca &/ pc &/ su &/ "status"
 
 
 
'''End'''
 
 
'''Public''' Sub File_Read()
 
 
 
  Dim s As String
 
 
 
  s = File.Load(dis)
 
 
 
  If InStr(s, "RUNNING") > 0 Then
 
    Write "\r" & Split(s, gb.NewLine)[8]
 
  Else
 
    fl.Close
 
  Endif
 
 
 
'''End'''
 
 
 
 
 
===Facendo uso del ''Timer''===
 
In qust'altro codice si fa uso di un Oggetto ''Timer'' :
 
 
  Private tm As Timer
 
  Private tm As Timer
 
  Private dis As String
 
  Private dis As String
Riga 99: Riga 47:
 
  '''Public''' Sub Tempus_Timer()
 
  '''Public''' Sub Tempus_Timer()
 
    
 
    
   Dim s As String
+
   Dim s, fr As String
 
+
 
   s = File.Load(dis)
 
   s = File.Load(dis)
    
+
   fr = Scan(Split(s, gb.NewLine)[8], "*: *")[1]
   If InStr(s, "RUNNING") > 0 Then
+
    Write "\r" & Split(s, gb.NewLine)[8]
+
   If InStr(s, "RUNNING") > 0 Then  
 +
  Write "\rFrame: " & fr &
 +
    "    Tempo trascorso: " & Str(Time(0, 0, 0, (Val(fr) / 44100) * 1000)) <SUP>&#091;[[#Note|nota 1]]&#093;</sup>
 
   Else
 
   Else
 
     tm.Stop
 
     tm.Stop
 
   Endif
 
   Endif
 
+
 
  '''End'''
 
  '''End'''
  
  
===Usando un ciclo e mostrando anche il tempo trascorso===
+
 
In questo esempio viene utilizzato un ciclo e mostrato anche il tempo trascorso sulla base dei frame audio processati (per ora il valore del tempo trascorso mostrato in console è valido <SPAN Style="text-decoration:underline">solo eseguendo un file di formato WAV o un file Midi</span>).
+
=Note=
<BR>Va chiarito che il file audio o Midi da caricare nella variabile "s" di tipo Stringa, sarà il medesimo che si sta facendo eseguire con un qualsiasi programma di lettura audio/Midi, e di cui ovviamente si intende rilevare la quantità di frame audio processati.
+
[1] Vedasi la 5<SUP>a</sup> modalità mostrata in questa pagina: [https://www.gambas-it.org/wiki/index.php/Calcolare_la_durata_di_un_file_audio_WAV#5a_modalit.C3.A0 Calcolare la durata di un file audio WAV]
'''Public''' Sub Main()
 
 
 
  Dim s, pr, dis As String
 
  Dim fl As File
 
  Dim i, hz, fr, mid As Integer
 
  Dim can, bla, bit As Short
 
 
 
  s = "<FONT Color=gray>''/percorso/del/file''</font>"
 
  Print "File audio: "; s
 
 
 
  fl = Open s For Read
 
  i = Lof(fl)
 
  Read #fl, mid
 
  If mid == 1684558925 Then  <FONT Color=gray>' ''Se è un file Midi...''</font>
 
    Print "Dimensione:  "; i; " byte"
 
    i = 2147483647
 
    can = 2
 
    hz = 44100
 
    bla = 4
 
    bit = 16
 
  Else                        <FONT Color=gray>' ''Se è un file WAV...''</font>
 
    i -= InStr(File.Load(s), "data") + 7
 
    Print "Dati audio:  "; i; " byte"
 
    Seek fl, InStr(File.Load(s), "fmt ") + 9
 
    Read #fl, can
 
    Print "Canali:      "; can
 
    Read #fl, hz
 
    Print "Frequenza:  "; hz; " hertz"
 
    Seek #fl, 32
 
    Read #fl, bla
 
    i /= bla
 
    pr = CStr(i)
 
    Read #fl, bit
 
    Print "Risoluzione: "; bit; " bit"
 
  Endif
 
  fl.Close
 
 
 
  dis = DispositivoAttivo()
 
 
 
  Print
 
  Repeat
 
    s = File.Load(dis)
 
    If s == "closed\n" Then Break
 
    fr = Val(Scan(s, "*hw_ptr*: *\n*")[2])
 
    Write "\r\e[0mFrame da processare: " & pr &
 
          " | Frame processati: \e[34m\e[1m" & CStr(fr) &
 
          "\e[0m | Tempo trascorso: \e[35m" &
 
          CStr(Time(0, 0, 0, ((fr * 8 * bla) / (hz * can * bit)) * 1000))
 
    Wait 0.01
 
  Until fr >= i
 
 
 
'''End'''
 
 
 
'''Private''' Function DispositivoAttivo() As String  <FONT Color=gray>' ''Verifica quale dispositivo audio è attivo''</font>
 
 
 
  Dim per, ca, pc, su As String
 
 
<FONT Color=gray>' ''Verifica se qualche dispositivo audio è presente nel sistema:''</font>
 
  If Dir("/proc/asound", "card*", gb.Directory).Count == 0 Then Error.Raise("Dispositivo audio assente !")
 
 
 
  per = "/proc/asound"
 
 
 
  For Each ca In Dir(per, "card*", gb.Directory)
 
    For Each pc In Dir(per &/ ca, "pcm*p", gb.Directory)
 
      For Each su In Dir(per &/ ca &/ pc, "sub*", gb.Directory)
 
        If InStr(File.Load(per &/ ca &/ pc &/ su &/ "status"), "RUNNING") > 0 Then Break
 
      Next
 
    Next
 
  Next
 
 
 
  Return per &/ ca &/ pc &/ su &/ "status"
 
 
 
'''End'''
 

Versione delle 19:13, 22 set 2022

Per rilevare in tempo reale la quantità di frame audio processati dalla scheda audio, si verificherà in continuazione il valore associato all'elemento "hw_ptr " nel file "/proc/asound/card.../pcm...p/sub0/status ".

In particolare il driver ALSA aggiorna "hw_ptr " dopo aver copiato un frame nel framework ALSA.

Mentre un qualunque programma sta eseguendo un file audio o Midi, è possibile lanciare uno dei seguenti codici.

In questo codice nella routine principale apriremo il file "...sub0/status" del dispositivo audio attivo, ponendolo sotto osservazione al solo fine di far sollevare l'Evento di lettura "File_Read()", e così di leggere con una nuova e diversa apertura del medesimo file i dati utili, ogni qual volta vi sono dati appunto da leggere.
Una lettura diretta del file nella routine "File_Read()" mediante la variabile di tipo File, ottenuta con l'istruzione Open della routine principale "Sub Main()", non risulta possibile: seppure assenti errori, non vengono restituiti dati.
Verrà mostrato il tempo trascorso sulla base dei frame audio processati.

Private tm As Timer
Private dis As String


Public Sub Main()
 
' Verifica quale dispositivo audio è attivo:
 dis = DispositivoAttivo()
 
 With tm = New Timer As "Tempus"
   .Delay = 1
   .Start
 End With
 
End

Private Function DispositivoAttivo() As String
 
 Dim per, ca, pc, su As String

' Verifica se qualche dispositivo audio è presente nel sistema:
 If Dir("/proc/asound", "card*", gb.Directory).Count == 0 Then Error.Raise("Dispositivo audio assente !")
 
 per = "/proc/asound"
 
 For Each ca In Dir(per, "card*", gb.Directory)
   For Each pc In Dir(per &/ ca, "pcm*p", gb.Directory)
     For Each su In Dir(per &/ ca &/ pc, "sub*", gb.Directory)
       If InStr(File.Load(per &/ ca &/ pc &/ su &/ "status"), "RUNNING") > 0 Then Break
     Next
   Next
 Next
 
 Return per &/ ca &/ pc &/ su &/ "status"
  
End

Public Sub Tempus_Timer()
 
 Dim s, fr As String

 s = File.Load(dis)
 fr = Scan(Split(s, gb.NewLine)[8], "*: *")[1]

 If InStr(s, "RUNNING") > 0 Then 
  Write "\rFrame: " & fr &
   "     Tempo trascorso: " & Str(Time(0, 0, 0, (Val(fr) / 44100) * 1000)) [nota 1]
 Else
   tm.Stop
 Endif

End


Note

[1] Vedasi la 5a modalità mostrata in questa pagina: Calcolare la durata di un file audio WAV