Estrarre informazioni da un file OggVorbis con le funzioni esterne del API di Vorbisfile

Da Gambas-it.org - Wikipedia.

La libreria di VorbisFile consente di estrarre informazioni di carattere generale da un file audio OggVorbis.


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 Vorbis sarà la seguente:

#include <vorbis/vorbisfile.h>
#include "vorbis/codec.h"


int Dim_OggVorbis_File() {
  return sizeof(OggVorbis_File);
} 

long Lungh_Header(OggVorbis_File *ov, int i) {
    return (ov->dataoffsets[i]-ov->offsets[i]);
}

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_upper As Long
  bitrate_nominal As Long
  bitrate_lower As Long
  bitrate_window As Long
End Struct


Library "libvorbisfile:3.3.4"

' int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes)
' Initializes an OggVorbis_File structure and prepare a bitstream for playback.
Private Extern ov_open(fP As Pointer, vf As Pointer, initial As String, ibytes As Long) As Integer

' long ov_seekable(OggVorbis_File *vf)
' This indicates whether or not the bitstream is seekable.
Private Extern ov_seekable(vf As Pointer) As Long

' long ov_streams(OggVorbis_File *vf)
' Returns the number of logical bitstreams within our physical bitstream.
Private Extern ov_streams(vf As Pointer) As Long

' 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 Pointer, i As Integer) As Long

' 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 Pointer, i As Integer) As Float

' vorbis_info *ov_info(OggVorbis_File *vf,int link)
' Returns the vorbis_info struct for the specified bitstream.
Private Extern ov_info(vf As Pointer, linkI As Integer) As Vorbis_info

' long ov_bitrate(OggVorbis_File *vf,int i)
' Returns the average bitrate for the specified logical bitstream.
Private Extern ov_bitrate(vf As Pointer, i As Integer) As Long

' long ov_serialnumber(OggVorbis_File *vf,int i)
' Returns the serialnumber of the specified logical bitstream link number within the overall physical bitstream.
Private Extern ov_serialnumber(vf As Pointer, i As Integer) As Long

' ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i)
' Returns the total (compressed) bytes of the physical bitstream or a specified logical bitstream.
Private Extern ov_raw_total(vf As Pointer, i As Integer) As Long

' 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



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



Library "/tmp/libadhoc"

Private Extern Dim_OggVorbis_File() As Integer
Private Extern Lungh_Header(OggVorbis_File As Pointer, n As Integer) As Long
Private Extern Obt_Comm(p As Pointer) As Pointer


Public Sub Main()

 Dim percorsoFileOGG As String
 Dim err, i As Integer
 Dim ov, fin, commP, vend As Pointer
 Dim vi As New Vorbis_info

 
   Shell "gcc -o /tmp/libadhoc.so " & Application.path &/ "libadhoc.c -shared -fPIC" Wait
   
   percorsoFileOGG = "/percorso/del/file.ogg"

   fin = fopen(percorsoFileOGG, "rb")
   
   ov = Alloc(Dim_OggVorbis_File())

   err = ov_open(fin, ov, Null, -1)
   If err < 0 Then Error.Raise("Impossibile aprire il file: " & percorsoFileOGG & " !")
   
   Print "File audio: "; percorsoFileOGG
   Print "\n==Caratteristiche del file audio==\n"

   If ov_seekable(ov) Then
     Print "Il flusso di dati in ingresso è contenuto in "; ov_streams(ov); " sezioni logiche di dati"
     Print "Totale campioni di dati: "; ov_pcm_total(ov, -1)
     Print "Durata totale di esecuzione dei dati: "; Fix(ov_time_total(ov, -1)); " secondi"
   Else
     Print "Il file non ha consentito la ricerca."
     Print "Informazioni sul primo flusso di dati logico:\n"
   Endif
   
   For i = 0 To ov_streams(ov) - 1
     
     vi = ov_info(ov, i)
     Print "\n\tInformazioni sulla sezione "; i + 1; " di dati logici:"
     Print "\t\tFrequenza di campionamento: Hz "; vi.rate
     Print "\t\tCanali di uscita: "; vi.channels
     Print "\t\tBitrate: "; ov_bitrate(ov, i) \ 1000; " kbps"
     Print "\t\tNumero seriale: "; ov_serialnumber(ov, i)
     Print "\t\tLunghezza dell'header: "; Lungh_Header(ov, i); " byte"
     Print "\t\tLunghezza file compresso: "; ov_raw_total(ov, i); " byte"
     Print "\t\tDurata dell'esecuzione: "; Fix(ov_time_total(ov, i)); " secondi"
     commP = ov_comment(ov, -1)
     vend = Obt_Comm(commP)
     Print "\t\tCodificato con "; String@(vend)
   Next

' Va in chiusura:
   fclose(fin)
   Free(ov)

End


Riferimenti

[1] Vorbisfile Documentation