Differenze tra le versioni di "Convertire un file OggVorbis in WAV con le funzioni esterne del API di Libvorbisidec"
(11 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 | + | 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 | Public Struct vorbis_info | ||
version As Integer | version As Integer | ||
Riga 27: | Riga 18: | ||
codec_setup As Pointer | codec_setup As Pointer | ||
End Struct | 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 57: | 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 | ||
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
'''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 | + | Dim datiPCMgrezzi As String |
Dim pcmout As New Byte[](4096) | Dim pcmout As New Byte[](4096) | ||
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> | |
+ | 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( | ||
Dim fl, fwav As File | Dim fl, fwav As File | ||
− | Dim dati As New Byte[](Stat( | + | 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> | |
− | + | ||
− | + | 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> | ||
+ | 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) | |
− | + | 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''' | ||
Riga 148: | 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