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

Da Gambas-it.org - Wikipedia.
 
(5 versioni intermedie di uno stesso utente non sono mostrate)
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 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 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)
 
+
   If InStr(s, "RUNNING") > 0 Then
+
   If InStr(s, "RUNNING") > 0 Then  
    Write "\r" & Split(s, gb.NewLine)[8]
+
  fr = Scan(Split(s, gb.NewLine)[8], "*: *")[1]
 +
  Write "\rFrame: \e[31m" & fr &
 +
        "\e[0m    Tempo trascorso: " &
 +
        Str(Time(0, 0, 0, (Val(fr) / <FONT Color=#B22222>44100</font>) * 1000)) <FONT Color=gray>' </font><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 attuale delle 19:41, 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 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