Convertire un file OggVorbis in WAV ed estrarne anche informazioni con le funzioni esterne del API di VorbisFile
Da Gambas-it.org - Wikipedia.
Versione del 4 ott 2022 alle 05:15 di Vuott (Discussione | contributi)
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 fruire in Gambas delle risorse del API di Ogg Vorbis si dovrà utilizzare la libreria condivisa: "libvorbisfile.so.3.3.7 "
Di seguito mostreremo un semplice codice per convertire un file OggVorbis (44100 hertz, 16 bit, 2 canali) nel corrispondente file WAV.
Library "libvorbisfile:3.3.7" Public Struct vorbis_comment user_comments As Pointer comment_lengths As Pointer comments As Integer vendor As Pointer End Struct Public Struct ogg_sync_state data As Pointer storage As Integer fill As Integer returned As Integer unisynced As Integer headerbytes As Integer bodybytes As Integer End Struct Public Struct ogg_stream_state body_data As Pointer body_storage As Long body_fill As Long body_returned As Long lacing_vals As Pointer granule_vals As Pointer lacing_storage As Long lacing_fill As Long lacing_packet As Long lacing_returned As Long header[282] As Byte header_fill As Integer e_o_s As Integer b_o_s As Integer serialno As Long pageno As Long packetno As Long granulepos As Long End Struct Public Struct vorbis_dsp_state analysisp As Integer vi As Pointer pcm As Pointer pcmret As Pointer pcm_storage As Integer pcm_current As Integer pcm_returned As Integer preextrapolate As Integer eofflag As Integer lW As Long W As Long nW As Long centerW As Long granulepos As Long sequence As Long glue_bits As Long time_bits As Long floor_bits As Long res_bits As Long End Struct Public Struct oggpack_buffer endbyte As Long endbit As Integer buffer As Pointer ptr As Pointer storage As Long End Struct Public Struct vorbis_block pcm As Pointer opb As Struct Oggpack_buffer lW As Long W As Long nW As Long pcmend As Integer mode As Integer eofflag As Integer granulepos As Long sequence As Long vd As Pointer localstore As Pointer localtop As Long localalloc As Long totaluse As Long reap As Pointer glue_bits As Long time_bits As Long floor_bits As Long res_bits As Long internal As Pointer End Struct Public Struct ov_callbacks fread As Pointer _ov_header_fseek_wrap As Pointer void As Pointer ftell As Pointer End Struct Public Struct OggVorbis_File datasource As Pointer seekable As Integer offset As Long end_ As Long oy As Struct Ogg_sync_state links As Integer offsets As Pointer dataoffsets As Pointer serialnos As Pointer pcmlengths As Pointer vi As Pointer vc As Pointer pcm_offset As Long ready_state As Integer current_serialno As Long current_link As Integer bittrack As Float samptrack As Float os As Struct Ogg_stream_state vd As Struct Vorbis_dsp_state vb As Struct Vorbis_block callbacks As Struct Ov_callbacks End Struct 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 End Struct ' int ov_fopen(const char *path,OggVorbis_File *vf) ' Opens and initialize an OggVorbis_File structure. Private Extern ov_fopen(path As String, vf As OggVorbis_File) As Integer ' 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(vf As OggVorbis_File, i As Integer) As Long ' vorbis_info *ov_info(OggVorbis_File *vf,int link) ' Returns the vorbis_info struct for the specified bitstream. Private Extern ov_info(vf As OggVorbis_File, linkI As Integer) As Vorbis_info ' double ov_time_total(OggVorbis_File *vf,int i) ' Returns the total time in seconds of the physical bitstream or a specified logical bitstream. Private Extern ov_time_total(vf As OggVorbis_File, i As Integer) As Float ' 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(vf As OggVorbis_File, lnk As Integer) As Pointer ' long ov_read(OggVorbis_File *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream) ' Decode a Vorbis file within a loop. Private Extern ov_read(vf As OggVorbis_File, buffer As Pointer, length As Integer, bigendianp As Integer, word As Integer, sgned As Integer, bitstream As Pointer) As Long Public Sub Main() Dim vf As New OggVorbis_File Dim vi As Vorbis_info Dim commenti As Vorbis_comment Dim fin As Pointer Dim eo, current_section, err, i As Integer Dim rit As Long Dim datiPCMgrezzi, fileOGG As String Dim pcmout As New Byte[](4096) Dim fl As File Dim b As Byte fileOGG = "/percorso/del/file.ogg" datiPCMgrezzi = Temp fl = Open datiPCMgrezzi For Create err = ov_fopen(fileOGG, vf) 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) Print "File audio: "; fileOGG With vi Print "Frequenza di campionamento: "; .rate; " Hertz" Print "Canali di uscita: "; .channels Print "Bitrate: "; .bitrate_nominal \ 1000; " Kbps" Print "Durata del file ogg: "; Time(0, 0, 0, ov_time_total(vf, -1) * 1000) Print "Lunghezza dei campioni decodificati: "; ov_pcm_total(vf, -1); " byte" End With Print "Commenti presenti nel file ogg:" With commenti = ov_comment(vf, -1) If commenti.comments > 0 Then For b = 0 To commenti.comments - 1 i = 8 * b Print " "; String@(Pointer@(commenti.user_comments + i)) Next Print " "; String@(commenti.vendor) Endif 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 eo = 0 rit = ov_read(vf, pcmout.Data, pcmout.Count, 0, 2, 1, VarPtr(current_section)) If rit = 0 Then eo = 1 Else ' Scrive il file contenente i dati grezzi PCM: pcmout.Write(fl, 0, rit) Endif Wend Write "\rConversione terminata !" ' Va a creare il file WAV finale: crea_file_wav(datiPCMgrezzi) ' Va in chiusura: fl.Close 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) Print "\n\nDurata del file WAV: "; Time(0, 0, 0, ((i * 8) / (44100 * 16 * 2)) * 1000) dati.Clear bh.Clear fl.Close fwav.Close End