Conoscere in tempo reale la quantità di frame audio processati dalla scheda audio

Da Gambas-it.org - Wikipedia.
Versione del 19 ago 2020 alle 03:10 di Vuott (Discussione | contributi) (Creata pagina con "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...")

(diff) ← Versione meno recente | Versione attuale (diff) | Versione più recente → (diff)

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.


Aprire in osservazione il file "...sub0/status"

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.
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
Private dis As String


Public Sub Main()
 
' Verifica quale dispositivo audio è attivo:
 dis = DispositivoAttivo()
 
' Apriamo il file solo per far sollevare l'evento di lettura ogni qual volta v'è qualcosa di nuovo da leggervi:
 fl = Open dis For Read Watch
 
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 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 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 As String
 
 s = File.Load(dis)
 
 If InStr(s, "RUNNING") > 0 Then
   Write "\r" & Split(s, gb.NewLine)[8]
 Else
   tm.Stop
 Endif
 
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 eseguendo un file di formato WAV o un file Midi).
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.

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 = "/percorso/del/file"
 Print "File audio:  "; s
 
 fl = Open s For Read
 i = Lof(fl)
 Read #fl, mid
 If mid == 1684558925 Then   ' Se è un file Midi...
   Print "Dimensione:  "; i; " byte"
   i = 2147483647
   can = 2
   hz = 44100
   bla = 4
   bit = 16
 Else                        ' Se è un file WAV...
   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
   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(Date(0, 0, 0, 0, 0, 0, ((fr * 8 * bla) / (hz * can * bit)) * 1000))
 Until fr >= i
 
End
 

Private Function DispositivoAttivo() As String   ' Verifica quale dispositivo audio è attivo
 
 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


Pagina in costruzione !