Differenze tra le versioni di "Convertire un file OggVorbis in WAV ed estrarne anche informazioni con le funzioni esterne del API di VorbisFile"

Da Gambas-it.org - Wikipedia.
Riga 1: Riga 1:
 
La libreria di '''''VorbisFile''''' consente di estrarre informazioni di carattere generale da un file audio ''OggVorbis'' e di convertirlo in un file audio WAV.
 
La libreria di '''''VorbisFile''''' consente di estrarre informazioni di carattere generale da un file audio ''OggVorbis'' e di convertirlo in un file audio WAV.
  
 +
Per poter fruire in Gambas delle risorse del API di ''Ogg Vorbis'' si dovrà utilizzare la libreria: "libvorbisfile.so.3.3.4"
  
Per poter utilizzare le risorse del API di ''VorbisFile'', bisognerà richiamare la libreria attualmente alla versione: ''libvorbisfile.so.3.3.4''
 
  
 +
Di seguito mostreremo un semplice codice per convertire un file ''OggVorbis'' in file ''WAV''. Poiché l'uso della libreria esterna ''Libvorbisfile'' prevede il richiamo della ''Struttura'' esterna molto complessa: ''OggVorbis_File'', al fine di poter gestire detta ''Struttura'' esterna in modo assolutamente sicuro, riserveremo un'area di memoria di dimensione pari a quella, preliminarmente calcolata, occupata dalla ''Struttura'' esterna.
  
Vediamo di seguito un esempio di codice.
+
Il codice Gambas potrà essere il seguente:
 
+
  Public Struct vorbis_info
Poiché l'uso della libreria esterna ''libvorbisfile'' prevede il richiamo diretto ed indiretto di alcune Strutture, ed al fine di poter gestire dette Strutture esterne in modo assolutamente sicuro, ci serviremo di un'apposita libreria esterna scritta in C, che realizzeremo ''ad hoc'' e che richiameremo all'interno del codice Gambas.
 
La libreria ''ad hoc'' per la [[Gestire_con_sicurezza_le_Strutture_esterne|''sicura'' gestione delle Strutture]] di ''libvorbisfile'' sarà la seguente:
 
#include "vorbis/codec.h"
 
#include "vorbis/vorbisfile.h"
 
 
 
int obt_OggVorbis_File_dim() {
 
  return sizeof(OggVorbis_File);
 
}
 
 
 
char * obt_comm(vorbis_comment * p) {
 
  return p->vendor;
 
}
 
Tale codice in linguaggio C in questo esempio verrà posto nella cartella ''Dati'' dell'applicativo Gambas, ed andrà poi trasformato in una libreria condivisa ''.so'' , che - come già accennato - sarà richiamata nel codice Gambas.
 
 
 
 
 
Il codice Gambas dell'applicativo sarà invece il seguente:
 
  '''Public''' Struct vorbis_info
 
 
   version As Integer
 
   version As Integer
 
   channels As Integer
 
   channels As Integer
 
   rate As Long
 
   rate As Long
<FONT color=gray>' ''BITRATE:''
 
' ''1) Tutti e tre impostati sullo stesso valore: implica un bitstream a valore fisso.''
 
' ''2) Solo il nominale impostato: nessun rigido limite superiore/inferiore.''
 
' ''3) Superiore e/o inferiore impostato: implica un flusso di bit VBR che segue i limiti di bitrate.''</font>
 
 
   bitrate_upper As Long
 
   bitrate_upper As Long
 
   bitrate_nominal As Long
 
   bitrate_nominal As Long
 
   bitrate_lower As Long
 
   bitrate_lower As Long
 
   bitrate_window As Long
 
   bitrate_window As Long
  '''End''' Struct
+
  codec_setup As Pointer
 +
End Struct
 +
 +
Public Struct vorbis_comment
 +
  user_comments As Pointer
 +
  comment_lengths As Pointer
 +
  comments As Integer
 +
  vendor As Pointer
 +
  End Struct
 
   
 
   
 
   
 
   
 
  Library "libvorbisfile:3.3.4"
 
  Library "libvorbisfile:3.3.4"
 
   
 
   
  <FONT color=gray>' ''int ov_fopen(const char *path,OggVorbis_File *vf)''
+
  <FONT color=gray>' ''int ov_open(FILE *f, OggVorbis_File *vf, const char *initial, long ibytes)''
  ' ''Function used to open and initialize an OggVorbis_File structure. It sets up all the related decoding structure.''</font>
+
  ' ''Open and initialize an OggVorbis_File structure.''</font>
  '''Private''' Extern ov_fopen(path As String, OggVorbis_File As Pointer) As Integer
+
  Private Extern ov_open(f As Pointer, vfP As Pointer, initial As String, ibytes As Long) As Integer
 
<FONT color=gray>' ''vorbis_comment *ov_comment(OggVorbis_File *vf,int link)''
 
' ''Returns a pointer to the vorbis_comment struct for the specified bitstream.''</font>
 
'''Private''' Extern ov_comment(OggVorbis_File As Pointer, lnk As Integer) As Pointer
 
 
   
 
   
 
  <FONT color=gray>' ''vorbis_info *ov_info(OggVorbis_File *vf,int link)''
 
  <FONT color=gray>' ''vorbis_info *ov_info(OggVorbis_File *vf,int link)''
 
  ' ''Returns the vorbis_info struct for the specified bitstream.''</font>
 
  ' ''Returns the vorbis_info struct for the specified bitstream.''</font>
  '''Private''' Extern ov_info(OggVorbis_File As Pointer, lnk As Integer) As Vorbis_info
+
  Private Extern ov_info(OVf As Pointer, lnk As Integer) As Vorbis_info
 
   
 
   
 
  <FONT color=gray>' ''double ov_time_total(OggVorbis_File *vf,int i)''
 
  <FONT color=gray>' ''double ov_time_total(OggVorbis_File *vf,int i)''
 
  ' ''Returns the total time in seconds of the physical bitstream.''</font>
 
  ' ''Returns the total time in seconds of the physical bitstream.''</font>
  '''Private''' Extern ov_time_total(OggVorbis_File *vf,int link)
+
  Private Extern ov_time_total(OVf As Pointer, i As Integer) As Float
 
   
 
   
  <FONT color=gray>' ''long ov_read(OggVorbis_File *vf,char *buffer,int length, int bigendianp,int word,int sgned,int *bitstream)''
+
  <FONT color=gray>' ''ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i)''
  ' ''This function makes up the main chunk of a decode loop.''</font>
+
  ' ''Returns the total pcm samples of the physical bitstream or a specified logical bitstream.''</font>
  '''Private''' Extern ov_read(OggVorbis_File As Pointer, buf As Byte[], length As Integer, bigendianp As Integer, word As Integer, sgned As Integer, bitstream As Pointer) As Long
+
  Private Extern ov_pcm_total(OVf As Pointer, i As Integer) As Long
 
   
 
   
  <FONT color=gray>' ''int ov_clear(OggVorbis_File *vf)''
+
  <FONT color=gray>' ''vorbis_comment *ov_comment(OggVorbis_File *vf, int link)''
  ' ''To clear the decoder's buffers.''</font>
+
  ' ''Returns a pointer to the vorbis_comment struct for the specified bitstream.''</font>
  '''Private''' Extern ov_clear(OggVorbis_File As Pointer) As Integer
+
  Private Extern ov_comment(OVf As Pointer, lnk As Integer) As Pointer
 
   
 
   
 +
<FONT color=gray>' ''long ov_read(OggVorbis_File *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream)''
 +
' ''Decode a Vorbis file within a loop.''</font>
 +
Private Extern ov_read(OVf As Pointer, buffer As Byte[], length As Integer, bigendianp As Integer, word As Integer, sgned As Integer, bitstream As Pointer) As Long
 +
 
 
   
 
   
  <FONT color=gray>' ''Richiamiamo la nostra libreria esterna speciale,
+
  Library "libc:6"
' ''per la gestione "sicura" della Struttura di VorbisFile:''</font>
 
Library "/tmp/libreria_vf"
 
'''Private''' Extern obt_OggVorbis_File_dim() As Integer
 
'''Private''' Extern obt_comm(p As Pointer) As Pointer
 
 
   
 
   
 +
<FONT color=gray>' ''FILE *fopen(const char *path, const char *mode)''
 +
' ''Apre il file path associandolo ad uno stream.''</font>
 +
Private Extern fopen(path As String, mode As String) As Pointer
 +
 +
<FONT color=gray>' ''int fclose(FILE *stream)''
 +
' ''Chiude il file associato a stream.''</font>
 +
Private Extern fclose(stmP As Pointer) As Integer
 +
 
 
   
 
   
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
   Dim buffer As New Byte[4096]
+
   Dim vf, fin As Pointer
  Dim fl As File
 
  Dim ovf, commP, vend As Pointer
 
 
   Dim vi As Vorbis_info
 
   Dim vi As Vorbis_info
   Dim err, eo, current_section, durata As Integer
+
   Dim eo, current_section, err, i As Integer
   Dim ret As Long
+
   Dim ret As Long
   Dim bh As Byte[] = [&52, &49, &46, &46, &00, &00, &00, &00, &57, &41, &56, &45, &66, &6D, &74, &20, &10, &00, &00, &00, &01, &00, &02, &00,
+
   Dim datiPCMgrezzi, fileOGG As String
                      &44, &AC, &00, &00, &10, &B1, &02, &00, &04, &00, &10, &00, &64, &61, &74, &61, &00, &00, &00, &00]   <FONT color=gray>' ''blocco d'intestazione del file wav futuro: 2 canali, 16 bit, hz 44100''</font>
+
  Dim pcmout As New Byte[](4096)
 +
  Dim f As File
 +
  Dim commenti As Vorbis_comment
 +
   Dim b As Byte
 
   
 
   
 +
  datiPCMgrezzi = "/tmp/datiPCMgrezzi"
 +
 
 +
  fileOGG = "<FONT color=gray>''/percorso/del/file.ogg''</font>"
 +
 
 +
  fin = fopen(fileOGG, "rb")
 
   
 
   
  <FONT color=gray>' ''Se non è presente la libreria "ad hoc" da noi realizzata, allora la crea:''</font>
+
  f = Open datiPCMgrezzi For Create
   If Exist("/tmp/libreria_vf.so") = False Then creaVf()
+
 
 +
  <FONT color=gray>' ''Allochiamo un'area di memoria di dimensione a quella occupata dalla Struttura "OggVorbis_File":''</font>
 +
   vf = Alloc(944)
 
    
 
    
<FONT color=gray>' ''Genera ed apre il futuro file wav:''</font>
+
  err = ov_open(fin, vf, Null, 0)
   fl = Open "/tmp/fileWAV.wav" For Create
+
   If err < 0 Then Error.Raise("Il file caricato potrebbe non essere del formato Ogg !")
 
   
 
   
   ovf = Alloc(obt_OggVorbis_File_dim())
+
<FONT color=gray>' ''Estrae alcune informazioni generali del file audio Ogg caricato:''</font>
 +
   vi = ov_info(vf, -1)
 
    
 
    
   err = ov_fopen("''/percorso/del/file.ogg''", ovf)
+
   Print "File audio:                              "; fileOGG
  If err < 0 Then Error.Raise("Errore nell'apertura del file audio !")
 
 
 
 
  vi = ov_info(ovf, -1)
 
 
 
   With vi
 
   With vi
     Print "Frequenza di campionamento: hz "; .rate
+
     Print "Frequenza di campionamento:             "; .rate; " Hertz"
     Print "Canali d'uscita: "; .channels
+
     Print "Canali di uscita:                       "; .channels
     If .bitrate_lower > 0 Then Print "Bitrate inferiore: "; .bitrate_lower
+
     Print "Bitrate:                                 "; .bitrate_nominal; " bps"
     If .bitrate_nominal > 0 Then Print "Bitrate nominale: "; .bitrate_nominal
+
     Print "Durata del file ogg:                    "; Date(0, 0, 0, 0, 0, 0, ov_time_total(vf, -1) * 1000)
     If .bitrate_upper > 0 Then Print "Bitrate superiore: "; .bitrate_upper
+
    Print "Lunghezza dei campioni decodificati:    "; ov_pcm_total(vf, -1); " byte"
 +
  End With
 +
  Print "Commenti presenti nel file ogg:"
 +
  commenti = ov_comment(vf, -1)
 +
  With commenti
 +
    For b = 0 To .comments - 1
 +
      i = 8 * b
 +
      Print "  "; String@(Pointer@(.user_comments + i))
 +
    Next
 +
     Print "   "; String@(.vendor)
 
   End With
 
   End With
 +
 
 
   
 
   
  durata = Fix(ov_time_total(ovf, -1) * 1000)
+
  <FONT color=gray>' ''Ciclo per la decodifica dei dati Ogg e per la scrittura del file contenente i dati grezzi PCM:''</font>
  If durata < 0 Then
 
    Error.Raise("Errore nella definizione della durata del brano !")
 
  Else
 
    Print "Durata del brano: "; Date(0, 0, 0, 0, 0, 0, durata)
 
  Endif
 
   
 
   
 
  commP = ov_comment(ovf, -1)
 
  vend = obt_comm(commP)
 
  Print "Codificato con "; String@(vend)
 
   
 
 
  <FONT color=gray>' ''Inizia la scrittura del file wav:''</font>
 
  bh.Write(fl, 0, bh.Count)
 
 
 
   While eo = 0
 
   While eo = 0
     ret = ov_read(ovf, buffer, 4096, 0, 2, 1, VarPtr(current_section))
+
     ret = ov_read(vf, pcmout, pcmout.Count, 0, 2, 1, VarPtr(current_section))
     
 
 
     If ret = 0 Then
 
     If ret = 0 Then
       eo = 1       <FONT color=gray>' ''Fine dei dati audio''</font>
+
       eo = 1
    Else If ret < 0 Then
 
      Error.Raise("Errore nella lettura dei dati audio del file !")
 
 
     Else
 
     Else
  <FONT color=gray>' ''Scrive i dati audio PCM del nuovo file wav:''</font>
+
  <FONT color=gray>' ''Scrive il file contenente i dati grezzi PCM:''</font>
       buffer.Write(fl, 0, ret)
+
       pcmout.Write(f, 0, ret)
 
     Endif
 
     Endif
    Wend
+
  Wend
 +
 
 +
<FONT color=gray>' ''Va a creare il file WAV finale:''</font>
 +
  crea_file_wav(datiPCMgrezzi)
 
   
 
   
 
   
 
   
 
  <FONT color=gray>' ''Va in chiusura:''</font>
 
  <FONT color=gray>' ''Va in chiusura:''</font>
   fl.Close
+
   Free(vf)
   ov_clear(ovf)
+
  f.Close
  Free(ovf)
+
   fclose(fin)
 
   
 
   
 
  '''End'''
 
  '''End'''
 
   
 
   
 
   
 
   
  <FONT color=gray>' ''Crea l'apposita libreria per la gestione sicura delle Strutture di 'libvorbisfile':''</font>
+
  '''Private''' Procedure crea_file_wav(datiGrezzi As String)
  '''Private''' Procedure creaVf()
+
 
 +
  Dim fl, fwav As File
 +
  Dim i, i2 As Integer
 +
  Dim dati As New Byte[](Stat(datiGrezzi).Size)
 +
  Dim bh As Byte[] = [&52, &49, &46, &46, &00, &00, &00, &00, &57, &41, &56, &45, &66, &6D, &74, &20, &10, &00, &00, &00, &01, &00, &02, &00,
 +
                    &44, &AC, &00, &00, &10, &B1, &02, &00, &04, &00, &10, &00, &64, &61, &74, &61, &00, &00, &00, &00]    <FONT color=gray>' ''blocco d'intestazione del file wav futuro: 2 canali, 16 bit, hz 44100''</font>
 +
                   
 +
  fl = Open datiGrezzi For Read
 +
  dati.Read(fl)
 +
     
 +
  i = Lof(fl)
 +
  fl.Close
 +
  i2 = i + 36
 +
 
 +
<FONT color=gray>' ''Imposta il valore dimensionale di 4 byte a partire dal 5° byte del futuro file wav:''</font>
 +
  bh[4] = i2 And &FF
 +
  bh[5] = Shr(i2 And &FF00&, 8)
 +
  bh[6] = Shr(i2 And &FF0000&, 16)
 +
  bh[7] = Shr(i2 And &FF000000&, 24)
 +
 
 +
  <FONT color=gray>' ''Imposta il valore dimensionale di 4 byte a partire dal 41° byte del futuro file wav.''
 +
' ''Esso è relativo alla quantità effettiva dei dati audio grezzi.''</font>
 +
  bh[40] = i And &FF
 +
  bh[41] = Shr(i And &FF00&, 8)
 +
  bh[42] = Shr(i And &FF0000&, 16)
 +
  bh[43] = Shr(i And &FF000000&, 24)
 +
     
 +
  bh.Insert(dati, 44)
 
   
 
   
   Shell "gcc -o /tmp/libreria_vf.so " & Application.Path &/ "libreria_vf.c -shared -fPIC" Wait
+
   fwav = Open "<FONT color=gray>''/percorso/del/file.wav''</font>" For Create
 
   
 
   
 +
<FONT color=gray>' ''Inizia la scrittura del file wav:''</font>
 +
  bh.Write(fwav, 0, bh.Count)
 +
 
 +
  Print "\n\nDurata del file WAV: "; Date(0, 0, 0, 0, 0, 0, ((i * 8) / (44100 * 16 * 2)) * 1000)
 +
   
 +
  dati.Clear
 +
  bh.Clear
 +
  fl.Close
 +
  fwav.Close
 +
 
 
  '''End'''
 
  '''End'''
 +
  
  
  
 
=Riferimenti=
 
=Riferimenti=
[1] [http://www.xiph.org/vorbis/doc/vorbisfile/index.html Vorbisfile Documentation]
+
* http://www.xiph.org/vorbis/doc/
 +
* http://www.vorbis.com/setup_linux/

Versione delle 18:26, 30 gen 2016

La libreria di VorbisFile consente di estrarre informazioni di carattere generale da un file audio OggVorbis e di convertirlo in un file audio WAV.

Per poter fruire in Gambas delle risorse del API di Ogg Vorbis si dovrà utilizzare la libreria: "libvorbisfile.so.3.3.4"


Di seguito mostreremo un semplice codice per convertire un file OggVorbis in file WAV. Poiché l'uso della libreria esterna Libvorbisfile prevede il richiamo della Struttura esterna molto complessa: OggVorbis_File, al fine di poter gestire detta Struttura esterna in modo assolutamente sicuro, riserveremo un'area di memoria di dimensione pari a quella, preliminarmente calcolata, occupata dalla Struttura esterna.

Il codice Gambas potrà essere il seguente:

Public Struct vorbis_info
  version As Integer
  channels As Integer
  rate As Long
  bitrate_upper As Long
  bitrate_nominal As Long
  bitrate_lower As Long
  bitrate_window As Long
  codec_setup As Pointer
End Struct

Public Struct vorbis_comment
  user_comments As Pointer
  comment_lengths As Pointer
  comments As Integer
  vendor As Pointer
End Struct


Library "libvorbisfile:3.3.4"

' int ov_open(FILE *f, OggVorbis_File *vf, const char *initial, long ibytes)
' Open and initialize an OggVorbis_File structure.
Private Extern ov_open(f As Pointer, vfP As Pointer, initial As String, ibytes As Long) As Integer

' vorbis_info *ov_info(OggVorbis_File *vf,int link)
' Returns the vorbis_info struct for the specified bitstream.
Private Extern ov_info(OVf As Pointer, lnk As Integer) As Vorbis_info

' double ov_time_total(OggVorbis_File *vf,int i)
' Returns the total time in seconds of the physical bitstream.
Private Extern ov_time_total(OVf As Pointer, i As Integer) As Float

' ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i)
' Returns the total pcm samples of the physical bitstream or a specified logical bitstream.
Private Extern ov_pcm_total(OVf As Pointer, i As Integer) As Long

' vorbis_comment *ov_comment(OggVorbis_File *vf, int link)
' Returns a pointer to the vorbis_comment struct for the specified bitstream.
Private Extern ov_comment(OVf As Pointer, lnk As Integer) As Pointer

' long ov_read(OggVorbis_File *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream)
' Decode a Vorbis file within a loop.
Private Extern ov_read(OVf As Pointer, buffer As Byte[], length As Integer, bigendianp As Integer, word As Integer, sgned As Integer, bitstream As Pointer) As Long
 

Library "libc:6"

' FILE *fopen(const char *path, const char *mode)
' Apre il file path associandolo ad uno stream.
Private Extern fopen(path As String, mode As String) As Pointer

' int fclose(FILE *stream)
' Chiude il file associato a stream.
Private Extern fclose(stmP As Pointer) As Integer
 

Public Sub Main()

 Dim vf, fin As Pointer
 Dim vi As Vorbis_info
 Dim eo, current_section, err, i As Integer
 Dim ret As Long
 Dim datiPCMgrezzi, fileOGG As String
 Dim pcmout As New Byte[](4096)
 Dim f As File
 Dim commenti As Vorbis_comment
 Dim b As Byte

  datiPCMgrezzi = "/tmp/datiPCMgrezzi"
  
  fileOGG = "/percorso/del/file.ogg"
  
  fin = fopen(fileOGG, "rb")

  f = Open datiPCMgrezzi For Create
 
' Allochiamo un'area di memoria di dimensione a quella occupata dalla Struttura "OggVorbis_File":
  vf = Alloc(944)
 
  err = ov_open(fin, vf, Null, 0)
  If err < 0 Then Error.Raise("Il file caricato potrebbe non essere del formato Ogg !")

' Estrae alcune informazioni generali del file audio Ogg caricato:
  vi = ov_info(vf, -1)
 
  Print "File audio:                              "; fileOGG
  With vi
    Print "Frequenza di campionamento:              "; .rate; " Hertz"
    Print "Canali di uscita:                        "; .channels
    Print "Bitrate:                                 "; .bitrate_nominal; " bps"
    Print "Durata del file ogg:                     "; Date(0, 0, 0, 0, 0, 0, ov_time_total(vf, -1) * 1000)
    Print "Lunghezza dei campioni decodificati:     "; ov_pcm_total(vf, -1); " byte"
  End With
  Print "Commenti presenti nel file ogg:"
  commenti = ov_comment(vf, -1)
  With commenti
    For b = 0 To .comments - 1
      i = 8 * b
      Print "   "; String@(Pointer@(.user_comments + i))
    Next
    Print "   "; String@(.vendor)
  End With
 

' Ciclo per la decodifica dei dati Ogg e per la scrittura del file contenente i dati grezzi PCM:
  While eo = 0
    ret = ov_read(vf, pcmout, pcmout.Count, 0, 2, 1, VarPtr(current_section))
    If ret = 0 Then
      eo = 1
    Else
' Scrive il file contenente i dati grezzi PCM:
      pcmout.Write(f, 0, ret)
    Endif
  Wend
 
' Va a creare il file WAV finale:
  crea_file_wav(datiPCMgrezzi)


' Va in chiusura:
  Free(vf)
  f.Close
  fclose(fin)

End


Private Procedure crea_file_wav(datiGrezzi As String)
 
 Dim fl, fwav As File
 Dim i, i2 As Integer
 Dim dati As New Byte[](Stat(datiGrezzi).Size)
 Dim bh As Byte[] = [&52, &49, &46, &46, &00, &00, &00, &00, &57, &41, &56, &45, &66, &6D, &74, &20, &10, &00, &00, &00, &01, &00, &02, &00,
                    &44, &AC, &00, &00, &10, &B1, &02, &00, &04, &00, &10, &00, &64, &61, &74, &61, &00, &00, &00, &00]    ' blocco d'intestazione del file wav futuro: 2 canali, 16 bit, hz 44100
                    
  fl = Open datiGrezzi For Read
  dati.Read(fl)
     
  i = Lof(fl)
  fl.Close
  i2 = i + 36
  
' Imposta il valore dimensionale di 4 byte a partire dal 5° byte del futuro file wav:
  bh[4] = i2 And &FF
  bh[5] = Shr(i2 And &FF00&, 8)
  bh[6] = Shr(i2 And &FF0000&, 16)
  bh[7] = Shr(i2 And &FF000000&, 24)
  
' Imposta il valore dimensionale di 4 byte a partire dal 41° byte del futuro file wav.
' Esso è relativo alla quantità effettiva dei dati audio grezzi.
  bh[40] = i And &FF
  bh[41] = Shr(i And &FF00&, 8)
  bh[42] = Shr(i And &FF0000&, 16)
  bh[43] = Shr(i And &FF000000&, 24)
     
  bh.Insert(dati, 44)

  fwav = Open "/percorso/del/file.wav" For Create

' Inizia la scrittura del file wav:
  bh.Write(fwav, 0, bh.Count)
  
  Print "\n\nDurata del file WAV: "; Date(0, 0, 0, 0, 0, 0, ((i * 8) / (44100 * 16 * 2)) * 1000)
   
  dati.Clear
  bh.Clear
  fl.Close
  fwav.Close
 
End



Riferimenti