Convertire un file OggVorbis in WAV con le funzioni esterne del API di Libvorbisidec
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 (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 occupata dalla Struttura' esterna, che abiamo preventivamente calcolato
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 Library "libvorbisidec:1.0.3" ' 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 = "/tmp/datiPCMgrezzi" 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(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) 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 ' 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: Free(vf) f.Close fclose(fin) End Private Procedure crea_file_wav(datiGrezzi As String) Dim fl, fwav As File 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 Write dati.Read(fl) fl.Close 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