Convertire un file OggVorbis in WAV ed estrarne anche informazioni con le funzioni esterne del API di VorbisFile
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 utilizzare le risorse del API di VorbisFile, bisognerà richiamare la libreria attualmente alla versione: libvorbisfile.so.3.3.4
Vediamo di seguito un esempio di codice.
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 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 channels As Integer rate As Long ' 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. bitrate_upper As Long bitrate_nominal As Long bitrate_lower As Long bitrate_window As Long End Struct Library "libvorbisfile:3.3.4" ' int ov_fopen(const char *path,OggVorbis_File *vf) ' Function used to open and initialize an OggVorbis_File structure. It sets up all the related decoding structure. Private Extern ov_fopen(path As String, OggVorbis_File As Pointer) As Integer ' 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(OggVorbis_File As Pointer, lnk As Integer) As Pointer ' vorbis_info *ov_info(OggVorbis_File *vf,int link) ' Returns the vorbis_info struct for the specified bitstream. Private Extern ov_info(OggVorbis_File 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(OggVorbis_File *vf,int link) ' long ov_read(OggVorbis_File *vf,char *buffer,int length, int bigendianp,int word,int sgned,int *bitstream) ' This function makes up the main chunk of a decode loop. 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 ' int ov_clear(OggVorbis_File *vf) ' To clear the decoder's buffers. Private Extern ov_clear(OggVorbis_File As Pointer) As Integer ' Richiamiamo la nostra libreria esterna speciale, ' per la gestione "sicura" della Struttura di VorbisFile: Library "/tmp/libreria_vf" Private Extern obt_OggVorbis_File_dim() As Integer Private Extern obt_Vorbis_Comment_dim() As Integer Private Extern obt_Vorbis_Info_dim() As Integer Private Extern obt_comm(p As Pointer) As Pointer Public Sub Main() Dim buffer As New Byte[4096] Dim fl As File Dim ovf, commP, vend As Pointer Dim vi As Vorbis_info Dim err, eo, current_section, durata As Integer 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, &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 ' Se non è presente la libreria "ad hoc" da noi realizzata, allora la crea: If Exist("/tmp/libreria_vf.so") = False Then creaVf() ' Genera ed apre il futuro file wav: fl = Open "/tmp/fileWAV.wav" For Create ovf = Alloc(obt_OggVorbis_File_dim()) err = ov_fopen("/percorso/del/file.ogg", ovf) If err < 0 Then Error.Raise("Errore nell'apertura del file audio !") vi = ov_info(ovf, -1) With vi Print "Frequenza di campionamento: hz "; .rate Print "Canali d'uscita: "; .channels If .bitrate_lower > 0 Then Print "Bitrate inferiore: "; .bitrate_lower If .bitrate_nominal > 0 Then Print "Bitrate nominale: "; .bitrate_nominal If .bitrate_upper > 0 Then Print "Bitrate superiore: "; .bitrate_upper End With durata = Fix(ov_time_total(ovf, -1) * 1000) 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) ' Inizia la scrittura del file wav: bh.Write(fl, 0, bh.Count) While eo = 0 ret = ov_read(ovf, buffer, 4096, 0, 2, 1, VarPtr(current_section)) If ret = 0 Then eo = 1 ' Eof Else If ret < 0 Then Error.Raise("Errore nella lettura dei dati audio del file !") Else buffer.Write(fl, 0, ret) Endif Wend ' Va in chiusura: fl.Close ov_clear(ovf) Free(ovf) End ' Crea l'apposita libreria per la gestione sicura delle Strutture di 'libvorbisfile': Private Procedure creaVf() Shell "gcc -o /tmp/libreria_vf.so " & Application.Path &/ "libreria_vf.c -shared -fPIC" Wait End