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.
 
(12 versioni intermedie di uno stesso utente non sono mostrate)
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 fruire in Gambas delle risorse del API di ''Ogg Vorbis'' si dovrà utilizzare la libreria condivisa: "''libvorbisfile.so.3.3.8'' ".
  
 
+
Di seguito mostreremo un semplice codice per convertire un file ''OggVorbis'' (44100 hertz, 16 bit, 2 canali) nel corrispondente file ''WAV''.
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.
+
Library "libvorbisfile:3.3.8"
 
 
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
 
  Public Struct vorbis_comment
Riga 25: Riga 13:
 
  End Struct
 
  End Struct
 
   
 
   
 +
Public Struct ogg_sync_state
 +
  data As Pointer
 +
  storage As Integer
 +
  fill As Integer
 +
  returned As Integer
 +
  unisynced As Integer
 +
  headerbytes As Integer
 +
  bodybytes As Integer
 +
End Struct
 
   
 
   
  Library "libvorbisfile:3.3.4"
+
  Public Struct ogg_stream_state
 +
  body_data As Pointer
 +
  body_storage As Long
 +
  body_fill As Long
 +
  body_returned As Long
 +
  lacing_vals As Pointer
 +
  granule_vals As Pointer
 +
  lacing_storage As Long
 +
  lacing_fill As Long
 +
  lacing_packet As Long
 +
  lacing_returned As Long
 +
  header[282] As Byte
 +
  header_fill As Integer
 +
  e_o_s As Integer
 +
  b_o_s As Integer
 +
  serialno As Long
 +
  pageno As Long
 +
  packetno As Long
 +
  granulepos As Long
 +
End Struct
 
   
 
   
  <FONT color=gray>' ''int ov_open(FILE *f, OggVorbis_File *vf, const char *initial, long ibytes)''
+
  Public Struct vorbis_dsp_state
  ' ''Open and initialize an OggVorbis_File structure.''</font>
+
  analysisp As Integer
  Private Extern ov_open(f As Pointer, vfP As Pointer, initial As String, ibytes As Long) As Integer
+
  vi As Pointer
 +
  pcm As Pointer
 +
  pcmret As Pointer
 +
  pcm_storage As Integer
 +
  pcm_current As Integer
 +
  pcm_returned As Integer
 +
  preextrapolate As Integer
 +
  eofflag As Integer
 +
  lW As Long
 +
  W As Long
 +
  nW As Long
 +
  centerW As Long
 +
  granulepos As Long
 +
  sequence As Long
 +
  glue_bits As Long
 +
  time_bits As Long
 +
  floor_bits As Long
 +
  res_bits As Long
 +
End Struct
 +
   
 +
  Public Struct oggpack_buffer
 +
  endbyte As Long
 +
  endbit As Integer
 +
  buffer As Pointer
 +
  ptr As Pointer
 +
  storage As Long
 +
End Struct
 +
 +
Public Struct vorbis_block
 +
  pcm As Pointer
 +
  opb As Struct Oggpack_buffer
 +
  lW As Long
 +
  W As Long
 +
  nW As Long
 +
  pcmend As Integer
 +
  mode As Integer
 +
  eofflag As Integer
 +
  granulepos As Long
 +
  sequence As Long
 +
  vd As Pointer
 +
  localstore As Pointer
 +
  localtop As Long
 +
  localalloc As Long
 +
  totaluse As Long
 +
  reap As Pointer
 +
  glue_bits As Long
 +
  time_bits As Long
 +
  floor_bits As Long
 +
  res_bits As Long
 +
  internal As Pointer
 +
End Struct
 
   
 
   
  <FONT color=gray>' ''vorbis_info *ov_info(OggVorbis_File *vf,int link)''
+
  Public Struct ov_callbacks
' ''Returns the vorbis_info struct for the specified bitstream.''</font>
+
  fread As Pointer
Private Extern ov_info(OVf As Pointer, lnk As Integer) As Vorbis_info
+
  _ov_header_fseek_wrap As Pointer
 +
  void As Pointer
 +
  ftell As Pointer
 +
End Struct
 
   
 
   
  <FONT color=gray>' ''double ov_time_total(OggVorbis_File *vf,int i)''
+
  Public Struct OggVorbis_File
' ''Returns the total time in seconds of the physical bitstream.''</font>
+
  datasource As Pointer
Private Extern ov_time_total(OVf As Pointer, i As Integer) As Float
+
  seekable As Integer
 +
  offset As Long
 +
  end_ As Long
 +
  oy As Struct Ogg_sync_state
 +
  links As Integer
 +
  offsets As Pointer
 +
  dataoffsets As Pointer
 +
  serialnos As Pointer
 +
  pcmlengths As Pointer
 +
  vi As Pointer
 +
  vc As Pointer
 +
  pcm_offset As Long
 +
  ready_state As Integer
 +
  current_serialno As Long
 +
  current_link As Integer
 +
  bittrack As Float
 +
  samptrack As Float
 +
  os As Struct Ogg_stream_state
 +
  vd As Struct Vorbis_dsp_state
 +
  vb As Struct Vorbis_block
 +
  callbacks As Struct Ov_callbacks
 +
End Struct
 
   
 
   
 +
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
 +
End Struct
 +
 
 +
<FONT color=gray>' ''int ov_fopen(const char *path,OggVorbis_File *vf)''
 +
' ''Opens and initialize an OggVorbis_File structure.''</font>
 +
Private Extern ov_fopen(path As String, vf As OggVorbis_File) As Integer
 +
 
 
  <FONT color=gray>' ''ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i)''
 
  <FONT color=gray>' ''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.''</font>
 
  ' ''Returns the total pcm samples of the physical bitstream or a specified logical bitstream.''</font>
  Private Extern ov_pcm_total(OVf As Pointer, i As Integer) As Long
+
  Private Extern ov_pcm_total(vf As OggVorbis_File, i As Integer) As Long
 +
 +
<FONT color=gray>' ''vorbis_info *ov_info(OggVorbis_File *vf,int link)''
 +
' ''Returns the vorbis_info struct for the specified bitstream.''</font>
 +
Private Extern ov_info(vf As OggVorbis_File, linkI As Integer) As Vorbis_info
 +
 
 +
<FONT color=gray>' ''double ov_time_total(OggVorbis_File *vf,int i)''
 +
' ''Returns the total time in seconds of the physical bitstream or a specified logical bitstream.''</font>
 +
Private Extern ov_time_total(vf As OggVorbis_File, i As Integer) As Float
 
   
 
   
  <FONT color=gray>' ''vorbis_comment *ov_comment(OggVorbis_File *vf, int link)''
+
  <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>
 
  ' ''Returns a pointer to the vorbis_comment struct for the specified bitstream.''</font>
  Private Extern ov_comment(OVf As Pointer, lnk As Integer) As Pointer
+
  Private Extern ov_comment(vf As OggVorbis_File, 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)''
 
  <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>
 
  ' ''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
+
  Private Extern ov_read(vf As OggVorbis_File, buffer As Pointer, length As Integer, bigendianp As Integer, word As Integer, sgned As Integer, bitstream As Pointer) As Long
 
+
 
 
   
 
   
  Library "libc:6"
+
  Public Sub Main()
 
<FONT color=gray>' ''FILE *fopen(const char *path, const char *mode)''
 
' ''Open a file and create a new stream for it.''</font>
 
Private Extern fopen(path As String, mode As String) As Pointer
 
 
<FONT color=gray>' ''int fclose(FILE *stream)''
 
' ''Close STREAM.''</font>
 
Private Extern fclose(stmP As Pointer) As Integer
 
 
    
 
    
+
   Dim vf As New OggVorbis_File
'''Public''' Sub Main()
 
 
   Dim vf, fin As Pointer
 
 
   Dim vi As Vorbis_info
 
   Dim vi As Vorbis_info
 +
  Dim commenti As Vorbis_comment
 +
  Dim fin As Pointer
 
   Dim eo, current_section, err, i As Integer
 
   Dim eo, current_section, err, i As Integer
   Dim ret As Long
+
   Dim rit As Long
 
   Dim datiPCMgrezzi, fileOGG As String
 
   Dim datiPCMgrezzi, fileOGG As String
 
   Dim pcmout As New Byte[](4096)
 
   Dim pcmout As New Byte[](4096)
   Dim f As File
+
   Dim fl As File
  Dim commenti As Vorbis_comment
 
 
   Dim b As Byte
 
   Dim b As Byte
 
   
 
   
  datiPCMgrezzi = "/tmp/datiPCMgrezzi"
+
  fileOGG = "<FONT color=darkgreen>''/percorso/del/file.ogg''</font>"
 +
  datiPCMgrezzi = Temp
 +
   
 +
  fl = Open datiPCMgrezzi For Create
 +
   
 +
  err = ov_fopen(fileOGG, vf)
 +
  If err < 0 Then Error.Raise("Il file caricato potrebbe non essere del formato Ogg !")
 
    
 
    
  fileOGG = "<FONT color=gray>''/percorso/del/file.ogg''</font>"
+
<FONT color=gray>' ''Estrae alcune informazioni generali del file audio Ogg caricato:''</font>
 
+
  vi = ov_info(vf, -1)
  fin = fopen(fileOGG, "rb")
 
 
  f = Open datiPCMgrezzi For Create
 
 
 
<FONT color=gray>' ''Allochiamo un'area di memoria di dimensione a quella occupata dalla Struttura "OggVorbis_File":''</font>
 
  vf = Alloc(944)
 
 
    
 
    
  err = ov_open(fin, vf, Null, 0)
+
  Print "File audio:                              "; fileOGG
  If err < 0 Then Error.Raise("Il file caricato potrebbe non essere del formato Ogg !")
+
  With vi
 +
    Print "Frequenza di campionamento:              "; .rate; " Hertz"
 +
    Print "Canali di uscita:                        "; .channels
 +
    Print "Bitrate:                                "; .bitrate_nominal \ 1000; " Kbps"
 +
    Print "Durata del file ogg:                    "; Time(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:"
 +
  With commenti = ov_comment(vf, -1)
 +
    If commenti.comments > 0 Then
 +
      For b = 0 To commenti.comments - 1
 +
        i = 8 * b
 +
        Print "  "; String@(Pointer@(commenti.user_comments + i))
 +
      Next
 +
      Print "   "; String@(commenti.vendor)
 +
    Endif
 +
  End With
 
   
 
   
<FONT color=gray>' ''Estrae alcune informazioni generali del file audio Ogg caricato:''</font>
+
   Write "\e[5mAttendere...\e[0m"
  vi = ov_info(vf, -1)
+
   Flush
    
 
  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
 
    
 
 
   
 
   
 
  <FONT color=gray>' ''Ciclo per la decodifica dei dati Ogg e per la scrittura del file contenente i dati grezzi PCM:''</font>
 
  <FONT color=gray>' ''Ciclo per la decodifica dei dati Ogg e per la scrittura del file contenente i dati grezzi PCM:''</font>
  While eo = 0
+
  While eo = 0
    ret = ov_read(vf, pcmout, pcmout.Count, 0, 2, 1, VarPtr(current_section))
+
    rit = ov_read(vf, pcmout.Data, pcmout.Count, 0, 2, 1, VarPtr(current_section))
    If ret = 0 Then
+
    If rit = 0 Then
      eo = 1
+
      eo = 1
    Else
+
    Else
 
  <FONT color=gray>' ''Scrive il file contenente i dati grezzi PCM:''</font>
 
  <FONT color=gray>' ''Scrive il file contenente i dati grezzi PCM:''</font>
      pcmout.Write(f, 0, ret)
+
      pcmout.Write(fl, 0, rit)
    Endif
+
    Endif
  Wend
+
  Wend
    
+
 +
   Write "\rConversione terminata !"
 +
 
  <FONT color=gray>' ''Va a creare il file WAV finale:''</font>
 
  <FONT color=gray>' ''Va a creare il file WAV finale:''</font>
  crea_file_wav(datiPCMgrezzi)
+
  crea_file_wav(datiPCMgrezzi)
 
 
   
 
   
 
  <FONT color=gray>' ''Va in chiusura:''</font>
 
  <FONT color=gray>' ''Va in chiusura:''</font>
  Free(vf)
+
  fl.Close
  f.Close
 
  fclose(fin)
 
 
   
 
   
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Private''' Procedure crea_file_wav(datiGrezzi As String)
+
  Private Procedure crea_file_wav(datiGrezzi As String)
 
    
 
    
 
   Dim fl, fwav As File
 
   Dim fl, fwav As File
Riga 143: Riga 241:
 
                     &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>
 
                     &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
+
  fl = Open datiGrezzi For Read
  dati.Read(fl)
+
  dati.Read(fl)
 
        
 
        
  i = Lof(fl)
+
  i = Lof(fl)
  fl.Close
+
  fl.Close
  i2 = i + 36
+
  i2 = i + 36
 
+
 
 
  <FONT color=gray>' ''Imposta il valore dimensionale di 4 byte a partire dal 5° byte del futuro file wav:''</font>
 
  <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[4] = i2 And &FF
  bh[5] = Shr(i2 And &FF00&, 8)
+
  bh[5] = Shr(i2 And &FF00&, 8)
  bh[6] = Shr(i2 And &FF0000&, 16)
+
  bh[6] = Shr(i2 And &FF0000&, 16)
  bh[7] = Shr(i2 And &FF000000&, 24)
+
  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.''
 
  <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>
 
  ' ''Esso è relativo alla quantità effettiva dei dati audio grezzi.''</font>
  bh[40] = i And &FF
+
  bh[40] = i And &FF
  bh[41] = Shr(i And &FF00&, 8)
+
  bh[41] = Shr(i And &FF00&, 8)
  bh[42] = Shr(i And &FF0000&, 16)
+
  bh[42] = Shr(i And &FF0000&, 16)
  bh[43] = Shr(i And &FF000000&, 24)
+
  bh[43] = Shr(i And &FF000000&, 24)
     
+
  bh.Insert(dati, 44)
+
  bh.Insert(dati, 44)
 
   
 
   
  fwav = Open "<FONT color=gray>''/percorso/del/file.wav''</font>" For Create
+
  fwav = Open "<FONT color=darkgreen>''/percorso/del/file.wav''</font>" For Create
 
   
 
   
 
  <FONT color=gray>' ''Inizia la scrittura del file wav:''</font>
 
  <FONT color=gray>' ''Inizia la scrittura del file wav:''</font>
  bh.Write(fwav, 0, bh.Count)
+
  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)
+
  Print "\n\nDurata del file WAV: "; Time(0, 0, 0, ((i * 8) / (44100 * 16 * 2)) * 1000)
   
+
  dati.Clear
+
  dati.Clear
  bh.Clear
+
  bh.Clear
  fl.Close
+
  fl.Close
  fwav.Close
+
  fwav.Close
 
+
  '''End'''
+
  End
 
 
  
  

Versione attuale delle 05:28, 14 gen 2024

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 condivisa: "libvorbisfile.so.3.3.8 ".

Di seguito mostreremo un semplice codice per convertire un file OggVorbis (44100 hertz, 16 bit, 2 canali) nel corrispondente file WAV.

Library "libvorbisfile:3.3.8"

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

Public Struct ogg_sync_state
  data As Pointer
  storage As Integer
  fill As Integer
  returned As Integer
  unisynced As Integer
  headerbytes As Integer
  bodybytes As Integer
End Struct

Public Struct ogg_stream_state
  body_data As Pointer
  body_storage As Long
  body_fill As Long
  body_returned As Long
  lacing_vals As Pointer
  granule_vals As Pointer
  lacing_storage As Long
  lacing_fill As Long
  lacing_packet As Long
  lacing_returned As Long
  header[282] As Byte
  header_fill As Integer
  e_o_s As Integer
  b_o_s As Integer
  serialno As Long
  pageno As Long
  packetno As Long
  granulepos As Long
End Struct

Public Struct vorbis_dsp_state
  analysisp As Integer
  vi As Pointer
  pcm As Pointer
  pcmret As Pointer
  pcm_storage As Integer
  pcm_current As Integer
  pcm_returned As Integer
  preextrapolate As Integer
  eofflag As Integer
  lW As Long
  W As Long
  nW As Long
  centerW As Long
  granulepos As Long
  sequence As Long
  glue_bits As Long
  time_bits As Long
  floor_bits As Long
  res_bits As Long
End Struct

Public Struct oggpack_buffer
  endbyte As Long
  endbit As Integer
  buffer As Pointer
  ptr As Pointer
  storage As Long
End Struct

Public Struct vorbis_block
  pcm As Pointer
  opb As Struct Oggpack_buffer
  lW As Long
  W As Long
  nW As Long
  pcmend As Integer
  mode As Integer
  eofflag As Integer
  granulepos As Long
  sequence As Long
  vd As Pointer
  localstore As Pointer
  localtop As Long
  localalloc As Long
  totaluse As Long
  reap As Pointer
  glue_bits As Long
  time_bits As Long
  floor_bits As Long
  res_bits As Long
  internal As Pointer
End Struct

Public Struct ov_callbacks
  fread As Pointer
  _ov_header_fseek_wrap As Pointer
  void As Pointer
  ftell As Pointer
End Struct

Public Struct OggVorbis_File
  datasource As Pointer
  seekable As Integer
  offset As Long
  end_ As Long
  oy As Struct Ogg_sync_state
  links As Integer
  offsets As Pointer
  dataoffsets As Pointer
  serialnos As Pointer
  pcmlengths As Pointer
  vi As Pointer
  vc As Pointer
  pcm_offset As Long
  ready_state As Integer
  current_serialno As Long
  current_link As Integer
  bittrack As Float
  samptrack As Float
  os As Struct Ogg_stream_state
  vd As Struct Vorbis_dsp_state
  vb As Struct Vorbis_block
  callbacks As Struct Ov_callbacks
End Struct

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
End Struct
 
' int ov_fopen(const char *path,OggVorbis_File *vf)
' Opens and initialize an OggVorbis_File structure.
Private Extern ov_fopen(path As String, vf As OggVorbis_File) As Integer
 
' 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(vf As OggVorbis_File, i As Integer) As Long

' vorbis_info *ov_info(OggVorbis_File *vf,int link)
' Returns the vorbis_info struct for the specified bitstream.
Private Extern ov_info(vf As OggVorbis_File, linkI As Integer) As Vorbis_info
  
' double ov_time_total(OggVorbis_File *vf,int i)
' Returns the total time in seconds of the physical bitstream or a specified logical bitstream.
Private Extern ov_time_total(vf As OggVorbis_File, i As Integer) As Float

' 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(vf As OggVorbis_File, 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(vf As OggVorbis_File, buffer As Pointer, length As Integer, bigendianp As Integer, word As Integer, sgned As Integer, bitstream As Pointer) As Long
  

Public Sub Main()
 
 Dim vf As New OggVorbis_File
 Dim vi As Vorbis_info
 Dim commenti As Vorbis_comment
 Dim fin As Pointer
 Dim eo, current_section, err, i As Integer
 Dim rit As Long
 Dim datiPCMgrezzi, fileOGG As String
 Dim pcmout As New Byte[](4096)
 Dim fl As File
 Dim b As Byte

 fileOGG = "/percorso/del/file.ogg"
 datiPCMgrezzi = Temp
   
 fl = Open datiPCMgrezzi For Create
    
 err = ov_fopen(fileOGG, vf)
 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 \ 1000; " Kbps"
   Print "Durata del file ogg:                     "; Time(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:"
 With commenti = ov_comment(vf, -1)
   If commenti.comments > 0 Then
     For b = 0 To commenti.comments - 1
       i = 8 * b
       Print "   "; String@(Pointer@(commenti.user_comments + i))
     Next
     Print "   "; String@(commenti.vendor)
   Endif 
 End With

 Write "\e[5mAttendere...\e[0m"
 Flush

' Ciclo per la decodifica dei dati Ogg e per la scrittura del file contenente i dati grezzi PCM:
 While eo = 0
   rit = ov_read(vf, pcmout.Data, pcmout.Count, 0, 2, 1, VarPtr(current_section))
   If rit = 0 Then
     eo = 1
   Else
' Scrive il file contenente i dati grezzi PCM:
     pcmout.Write(fl, 0, rit)
   Endif
 Wend

 Write "\rConversione terminata !"

' Va a creare il file WAV finale:
 crea_file_wav(datiPCMgrezzi)

' Va in chiusura:
 fl.Close

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: "; Time(0, 0, 0, ((i * 8) / (44100 * 16 * 2)) * 1000)

 dati.Clear
 bh.Clear
 fl.Close
 fwav.Close

End


Riferimenti