Differenze tra le versioni di "Estrarre informazioni generali da un file audio flac"

Da Gambas-it.org - Wikipedia.
Riga 1: Riga 1:
Nel blocco chiamato ''METADATA_BLOCK_STREAMINFO'' di un file di formato ''FLAC'' sono contenute alcune informazioni di carattere generali del file medesimo che possono ovviamente essere estratte.
+
Il file audio FLAC (''Free Lossless Audio Codec'' è un formato audio simile a MP3, dunque compresso, ma senza perdita di dati, il che significa senza alcuna perdita di qualità.
  
 +
Il file ha una struttura complessa formata da blocchi e sottoblocchi omogenei di dati. Nel blocco chiamato ''METADATA_BLOCK_STREAMINFO'' sono contenute alcune informazioni di carattere generale del file medesimo che possono ovviamente essere estratte. In questa pagina mostreremo come estrarre tali informazioni dei dati da quel blocco, ed in particolare la frequenza di campionamento, il numero di canali, la risoluzione in bit del campionamento e il numero totale dei campioni.
  
=Struttura generale del file FLAC=
+
Va preliminarmente detto che tali informazioni sono contenute all'interno di 8 byte, scritti in ''big-endian'', successivi e contigui a cominciare dal byte di indice 18 (quindi dal 19° byte del file ''flac''). Ogni informazione è indicata da un certo numero di bit - all'interno di quegli otto byte - fino alla concorrenza di 64 bit totali (8 byte). Esse sono così disposte a cominciare, come s'è detto, dal primo bit del byte di indice 18:
 +
* i primi 20 bit per memorizzare il valore relativo alla ''frequenza di campionamento'';
 +
* i successivi 3 bit per indicare il numero di canali (al valore ottenuto va sempre aggiunta un'unità);
 +
* i successivi 5 bit per indicare la ''risoluzione in bit del campionamento'' (al valore ottenuto va sempre aggiunta un'unità);
 +
* i successivi 36 bit per indicare il numero totale dei frame (campioni audio coerenti).
 +
Quest'ultima informazione è importante per ottenere in rapporto alla frequenza di campionamento la durata, espressa in secondi, dell'audio memorizzato nel file ''flac'', secondo la formula:
 +
durata_in_secondi = numero_totale_frame / frequenza_campionamento
  
  
 +
==Estrarre le informazioni mediante le sole risorse di Gambas==
 +
Questa modalità prevede l'estrazione delle predette informazioni relative ai dati del file mediante le sole risorse di Gambas.
  
=Estrarre le informazioni mediante le sole risorse di Gambas=
+
Mostriamo un esempio:
  
  
  
  
=Estrarre le informazioni mediante le funzioni esterne di Libflac=
+
==Estrarre le informazioni mediante le funzioni esterne di Libflac==
Library "libFLAC:8.3.0"
+
In quest'altro caso si farà uso di alcune risorse della specifica libreria dinamica condivisa "''libflac.so.8.3.0''", che dovrà essere installata e nel sistema ed opportunamente richiamata in Gambas.
 
 
Private Const FLAC__STREAM_DECODER_INIT_STATUS_OK As Integer = 0
 
 
 
' FLAC__StreamDecoder *FLAC__stream_decoder_new(void)
 
' Create a new stream decoder instance.
 
Private Extern FLAC__stream_decoder_new() As Pointer
 
 
 
' FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file(FLAC__StreamDecoder *decoder, const char *filename, FLAC__StreamDecoderWriteCallback write_callback, FLAC__StreamDecoderMetadataCallback metadata_callback, FLAC__StreamDecoderErrorCallback error_callback, void *client_data)
 
' Initialize the decoder instance to decode native FLAC files.
 
Private Extern FLAC__stream_decoder_init_file(decoder As Pointer, filename As String, write_callback As Pointer, metadata_callback As Pointer, error_callback As Pointer, client_data As Pointer) As Integer
 
 
 
' FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder)
 
' Decode until the end of the stream.
 
Private Extern FLAC__stream_decoder_process_until_end_of_stream(decoder As Pointer) As Boolean
 
 
 
' unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder)
 
' Get the current sample rate in Hz of the stream being decoded.
 
Private Extern FLAC__stream_decoder_get_sample_rate(decoder As Pointer) As Integer
 
 
 
' unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder)
 
' Get the current number of channels in the stream being decoded.
 
Private Extern FLAC__stream_decoder_get_channels(decoder As Pointer) As Byte
 
 
 
' unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder)
 
' Get the current sample resolution in the stream being decoded.
 
Private Extern FLAC__stream_decoder_get_bits_per_sample(decoder As Pointer) As Byte
 
 
 
' FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder)
 
' Get the total number of samples in the stream being decoded.
 
Private Extern FLAC__stream_decoder_get_total_samples(decoder As Pointer) As Long
 
 
 
' void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder)
 
' Free a decoder instance.
 
Private Extern FLAC__stream_decoder_delete(decoder As Pointer)
 
 
 
 
 
Public Sub Main()
 
  
 +
Mostriamo un esempio pratico, sottolineando che è necessario prevedere, seppur vuote, le tre funzioni di ''Callback'' presenti in questo esempio.
 +
Library "libFLAC:8.3.0"
 +
 +
Private Const FLAC__STREAM_DECODER_INIT_STATUS_OK As Integer = 0
 +
 +
<FONT Color=gray>' ''FLAC__StreamDecoder *FLAC__stream_decoder_new(void)''
 +
' ''Create a new stream decoder instance.''</font>
 +
Private Extern FLAC__stream_decoder_new() As Pointer
 +
 +
<FONT Color=gray size=1>' ''FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file(FLAC__StreamDecoder *decoder, const char *filename, FLAC__StreamDecoderWriteCallback write_callback, FLAC__StreamDecoderMetadataCallback metadata_callback, FLAC__StreamDecoderErrorCallback error_callback, void *client_data)
 +
' ''Initialize the decoder instance to decode native FLAC files.''</font>
 +
Private Extern FLAC__stream_decoder_init_file(decoder As Pointer, filename As String, write_callback As Pointer, metadata_callback As Pointer, error_callback As Pointer, client_data As Pointer) As Integer
 +
 +
<FONT Color=gray>' ''FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder)''
 +
' ''Decode until the end of the stream.''</font>
 +
Private Extern FLAC__stream_decoder_process_until_end_of_stream(decoder As Pointer) As Boolean
 +
 +
<FONT Color=gray>' ''unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder)''
 +
' ''Get the current sample rate in Hz of the stream being decoded.''</font>
 +
Private Extern FLAC__stream_decoder_get_sample_rate(decoder As Pointer) As Integer
 +
 +
<FONT Color=gray>' ''unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder)''
 +
' ''Get the current number of channels in the stream being decoded.''</font>
 +
Private Extern FLAC__stream_decoder_get_channels(decoder As Pointer) As Byte
 +
 +
<FONT Color=gray>' ''unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder)''
 +
' ''Get the current sample resolution in the stream being decoded.''</font>
 +
Private Extern FLAC__stream_decoder_get_bits_per_sample(decoder As Pointer) As Byte
 +
 +
<FONT Color=gray>' ''FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder)''
 +
' ''Get the total number of samples in the stream being decoded.''</font>
 +
Private Extern FLAC__stream_decoder_get_total_samples(decoder As Pointer) As Long
 +
 +
<FONT Color=gray>' ''void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder)''
 +
' ''Free a decoder instance.''</font>
 +
Private Extern FLAC__stream_decoder_delete(decoder As Pointer)
 +
 +
 +
'''Public''' Sub Main()
 +
 
   Dim deco, fout As Pointer
 
   Dim deco, fout As Pointer
 
   Dim fileFlac As String
 
   Dim fileFlac As String
Riga 57: Riga 69:
 
   Dim bo As Boolean
 
   Dim bo As Boolean
 
   Dim campioni As Long
 
   Dim campioni As Long
 
+
   
     fileFlac = "/percorso/del/fie.flac"
+
     fileFlac = "<FONT Color=gray>''/percorso/del/file.flac''</font>"
 
+
   
 
     deco = FLAC__stream_decoder_new()
 
     deco = FLAC__stream_decoder_new()
 
     If deco = 0 Then Error.Raise("Impossibile inizializzare la libreria 'Flac' !")
 
     If deco = 0 Then Error.Raise("Impossibile inizializzare la libreria 'Flac' !")
Riga 65: Riga 77:
 
     status = FLAC__stream_decoder_init_file(deco, fileFlac, write_callback, metadata_callback, error_callback, fout)
 
     status = FLAC__stream_decoder_init_file(deco, fileFlac, write_callback, metadata_callback, error_callback, fout)
 
     If status <> FLAC__STREAM_DECODER_INIT_STATUS_OK Then Error.Raise("Impossibile inizializzare il decodificatore !")
 
     If status <> FLAC__STREAM_DECODER_INIT_STATUS_OK Then Error.Raise("Impossibile inizializzare il decodificatore !")
 
+
   
 
     bo = FLAC__stream_decoder_process_until_end_of_stream(deco)
 
     bo = FLAC__stream_decoder_process_until_end_of_stream(deco)
 
     If bo = False Then Error.Raise("Decodifica fallita !")
 
     If bo = False Then Error.Raise("Decodifica fallita !")
Riga 77: Riga 89:
 
     campioni = FLAC__stream_decoder_get_total_samples(deco)
 
     campioni = FLAC__stream_decoder_get_total_samples(deco)
 
     Print "Totale Campioni: "; campioni
 
     Print "Totale Campioni: "; campioni
 
+
   
 
     Print "Durata audio:    "; CStr(Date(0, 0, 0, 0, 0, 0, (campioni / frequenza) * 1000))
 
     Print "Durata audio:    "; CStr(Date(0, 0, 0, 0, 0, 0, (campioni / frequenza) * 1000))
 
+
   
 
     FLAC__stream_decoder_delete(deco)
 
     FLAC__stream_decoder_delete(deco)
 
+
   
End
+
'''End'''
 
+
 
+
Private Function write_callback(decoder As Pointer, frame As Pointer, buffer As Pointer, client_data As Pointer)
+
'''Private''' Function write_callback(decoder As Pointer, frame As Pointer, buffer As Pointer, client_data As Pointer)
 
    
 
    
End
+
'''End'''
 
+
Private Function metadata_callback(decoder As Pointer, metadata As Pointer, client_data As Pointer)
+
'''Private''' Function metadata_callback(decoder As Pointer, metadata As Pointer, client_data As Pointer)
 
+
End
+
'''End'''
 
+
Private Function error_callback(decoder As Pointer, errori As Integer, client_data As Pointer)
+
'''Private''' Function error_callback(decoder As Pointer, errori As Integer, client_data As Pointer)
 
    
 
    
End
+
'''End'''
  
  

Versione delle 01:46, 27 set 2016

Il file audio FLAC (Free Lossless Audio Codec è un formato audio simile a MP3, dunque compresso, ma senza perdita di dati, il che significa senza alcuna perdita di qualità.

Il file ha una struttura complessa formata da blocchi e sottoblocchi omogenei di dati. Nel blocco chiamato METADATA_BLOCK_STREAMINFO sono contenute alcune informazioni di carattere generale del file medesimo che possono ovviamente essere estratte. In questa pagina mostreremo come estrarre tali informazioni dei dati da quel blocco, ed in particolare la frequenza di campionamento, il numero di canali, la risoluzione in bit del campionamento e il numero totale dei campioni.

Va preliminarmente detto che tali informazioni sono contenute all'interno di 8 byte, scritti in big-endian, successivi e contigui a cominciare dal byte di indice 18 (quindi dal 19° byte del file flac). Ogni informazione è indicata da un certo numero di bit - all'interno di quegli otto byte - fino alla concorrenza di 64 bit totali (8 byte). Esse sono così disposte a cominciare, come s'è detto, dal primo bit del byte di indice 18:

  • i primi 20 bit per memorizzare il valore relativo alla frequenza di campionamento;
  • i successivi 3 bit per indicare il numero di canali (al valore ottenuto va sempre aggiunta un'unità);
  • i successivi 5 bit per indicare la risoluzione in bit del campionamento (al valore ottenuto va sempre aggiunta un'unità);
  • i successivi 36 bit per indicare il numero totale dei frame (campioni audio coerenti).

Quest'ultima informazione è importante per ottenere in rapporto alla frequenza di campionamento la durata, espressa in secondi, dell'audio memorizzato nel file flac, secondo la formula:

durata_in_secondi = numero_totale_frame / frequenza_campionamento


Estrarre le informazioni mediante le sole risorse di Gambas

Questa modalità prevede l'estrazione delle predette informazioni relative ai dati del file mediante le sole risorse di Gambas.

Mostriamo un esempio:



Estrarre le informazioni mediante le funzioni esterne di Libflac

In quest'altro caso si farà uso di alcune risorse della specifica libreria dinamica condivisa "libflac.so.8.3.0", che dovrà essere installata e nel sistema ed opportunamente richiamata in Gambas.

Mostriamo un esempio pratico, sottolineando che è necessario prevedere, seppur vuote, le tre funzioni di Callback presenti in questo esempio.

Library "libFLAC:8.3.0"

Private Const FLAC__STREAM_DECODER_INIT_STATUS_OK As Integer = 0

' FLAC__StreamDecoder *FLAC__stream_decoder_new(void)
' Create a new stream decoder instance.
Private Extern FLAC__stream_decoder_new() As Pointer

' FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file(FLAC__StreamDecoder *decoder, const char *filename, FLAC__StreamDecoderWriteCallback write_callback, FLAC__StreamDecoderMetadataCallback metadata_callback, FLAC__StreamDecoderErrorCallback error_callback, void *client_data)
' Initialize the decoder instance to decode native FLAC files.
Private Extern FLAC__stream_decoder_init_file(decoder As Pointer, filename As String, write_callback As Pointer, metadata_callback As Pointer, error_callback As Pointer, client_data As Pointer) As Integer

' FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder)
' Decode until the end of the stream.
Private Extern FLAC__stream_decoder_process_until_end_of_stream(decoder As Pointer) As Boolean

' unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder)
' Get the current sample rate in Hz of the stream being decoded.
Private Extern FLAC__stream_decoder_get_sample_rate(decoder As Pointer) As Integer

' unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder)
' Get the current number of channels in the stream being decoded.
Private Extern FLAC__stream_decoder_get_channels(decoder As Pointer) As Byte

' unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder)
' Get the current sample resolution in the stream being decoded.
Private Extern FLAC__stream_decoder_get_bits_per_sample(decoder As Pointer) As Byte

' FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder)
' Get the total number of samples in the stream being decoded.
Private Extern FLAC__stream_decoder_get_total_samples(decoder As Pointer) As Long

' void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder)
' Free a decoder instance.
Private Extern FLAC__stream_decoder_delete(decoder As Pointer)


Public Sub Main()

 Dim deco, fout As Pointer
 Dim fileFlac As String
 Dim status, frequenza As Integer
 Dim canali, bit As Byte
 Dim bo As Boolean
 Dim campioni As Long
   
   fileFlac = "/percorso/del/file.flac"
   
   deco = FLAC__stream_decoder_new()
   If deco = 0 Then Error.Raise("Impossibile inizializzare la libreria 'Flac' !")
   
   status = FLAC__stream_decoder_init_file(deco, fileFlac, write_callback, metadata_callback, error_callback, fout)
   If status <> FLAC__STREAM_DECODER_INIT_STATUS_OK Then Error.Raise("Impossibile inizializzare il decodificatore !")
   
   bo = FLAC__stream_decoder_process_until_end_of_stream(deco)
   If bo = False Then Error.Raise("Decodifica fallita !")
   
   frequenza = FLAC__stream_decoder_get_sample_rate(deco)
   Print "Frequenza:       "; frequenza; " Hertz"
   canali = FLAC__stream_decoder_get_channels(deco)
   Print "Numero canali:   "; canali
   bit = FLAC__stream_decoder_get_bits_per_sample(deco)
   Print "Risoluzione:     "; bit; "-bit"
   campioni = FLAC__stream_decoder_get_total_samples(deco)
   Print "Totale Campioni: "; campioni
   
   Print "Durata audio:    "; CStr(Date(0, 0, 0, 0, 0, 0, (campioni / frequenza) * 1000))
   
   FLAC__stream_decoder_delete(deco)
   
End


Private Function write_callback(decoder As Pointer, frame As Pointer, buffer As Pointer, client_data As Pointer)
 
End

Private Function metadata_callback(decoder As Pointer, metadata As Pointer, client_data As Pointer)

End

Private Function error_callback(decoder As Pointer, errori As Integer, client_data As Pointer)
 
End



Riferimenti


Pagina in costruzione !