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

Da Gambas-it.org - Wikipedia.

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 anche il tempo trascorso calcolato sulla base dei frame audio processati, ma si presuppone nel codice che il file audio abbia una frequenza di campionamento di 44100 hertz oppure che sia un file MIDI. Pertanto, se il file audio ha una frequenza di campionamento diversa da 44100 hertz, andrà cambiato il valore presente nella routine "Tempus_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, fr As String

 s = File.Load(dis)

 If InStr(s, "RUNNING") > 0 Then 
  fr = Scan(Split(s, gb.NewLine)[8], "*: *")[1]
  Write "\rFrame: \e[31m" & fr &
        "\e[0m     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