Differenze tra le versioni di "Convertire un file OggVorbis in WAV con le funzioni esterne del API di Libvorbisidec"
Riga 57: | Riga 57: | ||
Dim f As File | Dim f As File | ||
− | + | datiPCMgrezzi = Temp | |
− | + | fin = fopen("<FONT color=gray>''/percorso/del/file.ogg''</font>", "rb") | |
− | + | f = Open datiPCMgrezzi For Create | |
<FONT color=gray>' ''Allochiamo un'area di memoria di dimensione a quella occupata dalla Struttura "OggVorbis_File":''</font> | <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 !") | |
<FONT color=gray>' ''Estrae alcune informazioni generali del file audio Ogg caricato:''</font> | <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 | |
− | + | ret = ov_read(vf, pcmout, pcmout.Count, VarPtr(current_section)) | |
− | + | If ret = 0 Then | |
− | + | eo = 1 | |
− | + | 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) | |
− | + | Endif | |
− | + | 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(datiPCMgrezzi) | |
− | |||
− | + | <FONT color=gray>' ''Va in chiusura:''</font> | |
− | + | Write "\rConversione terminata !" | |
− | + | Free(vf) | |
− | + | f.Close | |
+ | fclose(fin) | ||
'''End''' | '''End''' | ||
− | |||
'''Private''' Procedure crea_file_wav(datiGrezzi As String) | '''Private''' Procedure crea_file_wav(datiGrezzi As String) | ||
Riga 109: | Riga 111: | ||
Dim dati As New Byte[](Stat(datiGrezzi).Size) | 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] | + | &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> | <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.'' | <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[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 "<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) | |
− | + | dati.Clear | |
− | + | bh.Clear | |
− | + | fl.Close | |
− | + | fwav.Close | |
'''End''' | '''End''' |
Versione 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