Differenze tra le versioni di "Convertire un file OggVorbis in WAV con le funzioni esterne del API di Libvorbisidec"

Da Gambas-it.org - Wikipedia.
 
(15 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
La libreria '''Libvorbisidec''' (''Tremor'') intende essere il più possibile simile alla libreria ''Vorbisfile'' distribuita gratuitamente da ''Xiph.org'' . Essa fornisce una libreria di solo numeri interi destinati alla decodifica di tutti i formati di file ''Vorbis'' attuali e futuri.
+
La libreria '''Libvorbisidec''' (''Tremor'') intende essere il più possibile simile alla libreria ''Vorbisfile'' distribuita gratuitamente da ''Xiph.org'' . Essa fornisce una libreria di soli valori con numeri ''interi'' destinati alla decodifica di tutti i formati di file ''Vorbis'' attuali e futuri.
  
 +
Per poter fruire delle risorse del API di ''Libvorbisidec'' si dovrà utilizzare la libreria condivisa: "''libvorbisidec.so.1.0.3'' "
  
Per poter fruire delle risorse del API di ''Libvorbisidec'' si dovrà utilizzare la libreria (nella sua attuale versione): "libvorbisidec.so.1.0.3"
+
Di seguito mostreremo un semplice codice per convertire un file OggVorbis in file WAV. Poiché l'uso della libreria esterna ''Libvorbisidec'' 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:
Di seguito mostreremo un semplice codice per convertire un file OggVorbis in file WAV. Poiché l'uso della libreria esterna ''Libvorbisidec'' prevede il richiamo di una complessa Struttura esterna, ed al fine di poter gestire detta Struttura esterna in modo assolutamente sicuro, ci serviremo di una libreria esterna scritta in C, che realizzeremo ad hoc e che richiameremo all'interno del codice Gambas:
+
  Library "libvorbisidec:1.0.3"
  #include <stdio.h>
 
#include "/usr/include/tremor/ivorbisfile.h"
 
 
   
 
   
   
+
  Public Struct vorbis_info
int Dim_OggVorbis_File() {
+
  version As Integer
   return sizeof(OggVorbis_File);
+
  channels As Integer
}
+
   rate As Long
Tale codice in linguaggio C in questo esempio sarà posto nella cartella ''Dati'' dell'applicativo Gambas, e andrà poi trasformato in una libreria condivisa ''.so'' , che - come già accennato - sarà richiamata nel codice Gambas.
+
  bitrate_upper As Long
 
+
  bitrate_nominal As Long
 
+
  bitrate_lower As Long
Il codice Gambas potrà essere il seguente:
+
  bitrate_window As Long
  Library "libvorbisidec:1.0.3"
+
  codec_setup As Pointer
 +
  End Struct
 
   
 
   
 
  <FONT color=gray>' ''int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes)''
 
  <FONT color=gray>' ''int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes)''
Riga 26: Riga 26:
 
  ' ''Decode a Vorbis file within a loop.''</font>
 
  ' ''Decode a Vorbis file within a loop.''</font>
 
  Private Extern ov_read(vfP As Pointer, buffer As Byte[], length As Integer, bitstream As Pointer) As Long
 
  Private Extern ov_read(vfP As Pointer, buffer As Byte[], length As Integer, bitstream As Pointer) 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(vfP As Pointer, linkI As Integer) As Vorbis_info
 +
 +
<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>
 +
Private Extern ov_pcm_total(vfP As Pointer, i As Integer) As Long
 
   
 
   
 
   
 
   
Riga 37: Riga 45:
 
  ' ''Chiude il file associato a stream.''</font>
 
  ' ''Chiude il file associato a stream.''</font>
 
  Private Extern fclose(stmP As Pointer) As Integer
 
  Private Extern fclose(stmP As Pointer) As Integer
+
 
 
Library "/tmp/libadhoc"
 
 
Private Extern Dim_OggVorbis_File() As Integer
 
 
 
   
 
   
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
 
   Dim vf, fin As Pointer
 
   Dim vf, fin As Pointer
 +
  Dim vi As Vorbis_info
 
   Dim eo, current_section, err As Integer
 
   Dim eo, current_section, err As Integer
 
   Dim ret As Long
 
   Dim ret As Long
   Dim filefinaleWAV As String = "/tmp/datiPCMgrezzi"
+
   Dim datiPCMgrezzi As String
 
   Dim pcmout As New Byte[](4096)
 
   Dim pcmout As New Byte[](4096)
 
   Dim f As File
 
   Dim f As File
 
   
 
   
<FONT color=gray>' ''Creiamo la libreria ad hoc per la gestione "sicura" della Struttura "OggVorbis_File":''</font>
+
  datiPCMgrezzi = Temp
   Shell "gcc -o /tmp/libadhoc.so " & Application.Path &/ "libadhoc.c -shared" Wait
+
    
    
+
   fin = fopen("<FONT color=gray>''/percorso/del/file.ogg''</font>", "rb")
  fin = fopen("/home/ploppo/Scrivania/LINUX/Hydrate-Kenny_Beltrey.ogg", "rb")
 
 
   
 
   
  f = Open filefinaleWAV For Create
+
  f = Open datiPCMgrezzi For Create
 
    
 
    
  vf = Alloc(Dim_OggVorbis_File())
+
<FONT color=gray>' ''Allochiamo un'area di memoria di dimensione a quella occupata dalla Struttura "OggVorbis_File":''</font>
 
+
  vf = Alloc(SizeOf(gb.Byte), 944)
  err = ov_open(fin, vf, Null, 0)
 
  If err < 0 Then Error.Raise("Il file caricato potrebbe non essere del formato Ogg !")
 
 
    
 
    
 +
  err = ov_open(fin, vf, Null, 0)
 +
  If err < 0 Then Error.Raise("Il file caricato potrebbe non essere del formato Ogg !")
 +
 +
<FONT color=gray>' ''Estrae alcune informazioni generali del file audio Ogg caricato:''</font>
 +
  vi = ov_info(vf, -1)
 +
  If IsNull(vi) Then Error.Raise("Errore !")
 +
 +
  With vi
 +
    Print "Frequenza di campionamento: Hz "; .rate
 +
    Print "Canali di uscita: "; .channels
 +
    Print "Bitrate: "; .bitrate_nominal; " bps"
 +
    Print "Lunghezza dei campioni decodificati: "; ov_pcm_total(vf, -1); " byte"
 +
  End With
 +
 +
  Write "\e[5mAttendere...\e[0m"
 +
  Flush
 +
 
  <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 Not eo
+
  While Not eo
    ret = ov_read(vf, pcmout, pcmout.Count, VarPtr(current_section))
+
    ret = ov_read(vf, pcmout, pcmout.Count, VarPtr(current_section))
    If ret = 0 Then
+
    If ret = 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(f, 0, ret)
    Endif
+
    Endif
  Wend
+
  Wend
 
+
 
  <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(filefinaleWAV)
+
  crea_file_wav(datiPCMgrezzi)
 
   
 
   
+
  <FONT color=gray>' ''Va in chiusura:''</font>
<FONT color=gray>' ''Va in chiusura:''</font>
+
  Write "\rConversione terminata !"
  Free(vf)
+
  Free(vf)
  f.Close
+
  f.Close
  fclose(fin)
+
  fclose(fin)
 
   
 
   
 
  '''End'''
 
  '''End'''
 
   
 
   
+
  '''Private''' Procedure crea_file_wav(datiGrezzi As String)
  '''Private''' Procedure crea_file_wav(audioWAV As String)
 
 
    
 
    
 
   Dim fl, fwav As File
 
   Dim fl, fwav As File
   Dim dati As New Byte[](Stat(audioWAV).Size)
+
  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,
 
   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>
+
                    &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 audioWAV For Read Write
+
  dati.Read(fl)
  dati.Read(fl)
+
     
  fl.Close
+
  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)
+
  bh.Insert(dati, 44)
 
   
 
   
  fwav = Open "/tmp/fileAudio.wav" For Create
+
  fwav = Open "<FONT color=gray>''/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)
 
      
 
      
  dati.Clear
+
  dati.Clear
  bh.Clear
+
  bh.Clear
  fl.Close
+
  fl.Close
  fwav.Close
+
  fwav.Close
 
    
 
    
 
  '''End'''
 
  '''End'''
Riga 117: Riga 150:
  
 
=Riferimenti=
 
=Riferimenti=
[1] [http://courses.cs.washington.edu/courses/cse466/09wi/labs/l7/tremor/ L'API di ''Tremor-Libvorbisidec'']
+
[1] [http://sourcecodebrowser.com/libvorbisidec/1.0.2plus-psvn14261/index.html L'API di ''Libvorbisidec'']
 +
 
 +
[2] [http://courses.cs.washington.edu/courses/cse466/09wi/labs/l7/tremor/ L'API di ''Tremor-Libvorbisidec'']

Versione attuale delle 05:34, 4 ott 2022

La libreria Libvorbisidec (Tremor) intende essere il più possibile simile alla libreria Vorbisfile distribuita gratuitamente da Xiph.org . Essa fornisce una libreria di soli valori con numeri interi destinati alla decodifica di tutti i formati di file Vorbis attuali e futuri.

Per poter fruire delle risorse del API di Libvorbisidec si dovrà utilizzare la libreria condivisa: "libvorbisidec.so.1.0.3 "

Di seguito mostreremo un semplice codice per convertire un file OggVorbis in file WAV. Poiché l'uso della libreria esterna Libvorbisidec 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:

Library "libvorbisidec:1.0.3"

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

' 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

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

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

' 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(vfP As Pointer, i As Integer) 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 As Integer
 Dim ret As Long
 Dim datiPCMgrezzi As String
 Dim pcmout As New Byte[](4096)
 Dim f As File

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

 f = Open datiPCMgrezzi For Create
 
' Allochiamo un'area di memoria di dimensione a quella occupata dalla Struttura "OggVorbis_File":
 vf = Alloc(SizeOf(gb.Byte), 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)
 If IsNull(vi) Then Error.Raise("Errore !")

 With vi
   Print "Frequenza di campionamento: Hz "; .rate
   Print "Canali di uscita: "; .channels
   Print "Bitrate: "; .bitrate_nominal; " bps"
   Print "Lunghezza dei campioni decodificati: "; ov_pcm_total(vf, -1); " byte"
 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 Not eo
   ret = ov_read(vf, pcmout, pcmout.Count, 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:
 Write "\rConversione terminata !"
 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)
   
 dati.Clear
 bh.Clear
 fl.Close
 fwav.Close
 
End


Riferimenti

[1] L'API di Libvorbisidec

[2] L'API di Tremor-Libvorbisidec