Estrarre da un file MP3 i soli dati audio grezzi mediante la libreria libmpeg3

Da Gambas-it.org - Wikipedia.

Con alcune risorse della libreria "libmpeg3" è possibile estrarre i dati audio grezzi (PCM) da un file MP3.

E' necessario avere installata nel sistema e richiamare nel programma Gambas la libreria condivisa: libmpeg3.so.2.1.8


Mostriamo un esempio pratico:

Library "libmpeg3:2.1.8"

Public Struct mpeg3_t
  fs As Pointer
  demuxer As Pointer
  total_astreams As Integer
  atrack[65536] As Pointer
  total_vstreams As Integer
  vtrack[65536] As Pointer
  total_sstreams As Integer
  strack[65536] As Pointer
  frame_offsets As Pointer
  sample_offsets As Pointer
  keyframe_numbers As Pointer
  video_eof As Pointer
  audio_eof As Pointer
  total_frame_offsets As Pointer
  total_sample_offsets As Pointer
  total_samples As Pointer
  total_keyframe_numbers As Pointer
  channel_counts As Pointer
  indexes As Pointer
  total_indexes As Integer
  index_bytes As Long
  is_transport_stream As Integer
  is_program_stream As Integer
  is_ifo_file As Integer
  is_audio_stream As Integer
  is_video_stream As Integer
  is_bd As Integer
  packet_size As Integer
  last_type_read As Integer
  last_stream_read As Integer
  subtitle_track As Integer
  program As Integer
  cpus As Integer
  seekable As Integer
  toc_fd As Pointer
  byte_pts As Long
  have_palette As Integer
  palette[64] As Byte
  source_date As Long
End Struct

' int mpeg3_check_sig(char *path)
' Check for file compatibility.
Private Extern mpeg3_check_sig(path As String) As Integer

' mpeg3_t* mpeg3_open(char *path, int *error_return)
' Open the MPEG stream.
Private Extern mpeg3_open(path As String, error_return As Pointer) As Mpeg3_t

' int64_t mpeg3_get_bytes(mpeg3_t *file)
' Total bytes.
Private Extern mpeg3_get_bytes(mpeg3file As Mpeg3_t) As Long

' int mpeg3_audio_channels(mpeg3_t *file, int stream)
Private Extern mpeg3_audio_channels(mpeg3file As Mpeg3_t, _stream As Integer) As Integer

' int mpeg3_sample_rate(mpeg3_t *file, int stream)
Private Extern mpeg3_sample_rate(mpeg3file As Mpeg3_t, _stream As Integer) As Integer

' char* mpeg3_audio_format(mpeg3_t *file, int stream)
Private Extern mpeg3_audio_format(mpeg3file As Mpeg3_t, _stream As Integer) As Pointer

' long mpeg3_audio_samples(mpeg3_t *file, int stream)
Private Extern mpeg3_audio_samples(mpeg3file As Mpeg3_t, _stream As Integer) As Long

' int mpeg3_read_audio(mpeg3_t *file, float *output_f, short *output_i, int channel, long samples, int stream)
' Read a PCM buffer of audio from 1 channel and advance the position.
Private Extern mpeg3_read_audio(mpeg3 As Mpeg3_t, f As Pointer, i As Pointer, can As Integer, sa As Long, st As Integer)

' int mpeg3_reread_audio(mpeg3_t *file, float *output_f, short *output_i, int channel, long samples, int stream)
' Reread a PCM buffer of audio from 1 channel and advance the position.
Private Extern mpeg3_reread_audio(mpeg3 As Mpeg3_t, f As Pointer, i As Pointer, can As Integer, sa As Long, st As Integer) 

' double mpeg3_get_time(mpeg3_t *file)
' Give the seconds time in the last packet read.
Private Extern mpeg3_get_time(mpeg3 As Mpeg3_t) As Float

' int mpeg3_close(mpeg3_t *file)
Private Extern mpeg3_close(mpeg3file As Mpeg3_t) As Integer


Public Sub Main()
 
 Dim perc As String
 Dim i, can, freq As Integer
 Dim cmp As Long
 Dim mp3 As Mpeg3_t
 Dim cc1, cc2, cc3 As Short[]
 Dim fl As File
 
  perc = "/percorso/del/file.mp3"
  
  i = mpeg3_check_sig(perc)
  If i = 0 Then Error.Raise("Tipo file incompatibile !")
  
  mp3 = mpeg3_open(perc, 0)
  
  Print "File audio:     "; perc
  Print "Dimensione:     "; mpeg3_get_bytes(mp3); " byte"
  can = mpeg3_audio_channels(mp3, 0)
  Print "Numero canali:  "; can
  freq = mpeg3_sample_rate(mp3, 0)
  Print "Frequenza:      "; freq; " hertz"
  Print "Formato audio:  "; String@(mpeg3_audio_format(mp3, 0))
  cmp = mpeg3_audio_samples(mp3, 0)
  Print "Campioni audio: "; cmp; " byte"
  
''''''''''''''''''''''''''''''''''''''''''''''''
' Sezione per l'estrazione dei dati audio grezzi (PCM):
  cc1 = New Short[cmp * SizeOf(gb.Short)]
  cc2 = New Short[cmp * SizeOf(gb.Short)]
  cc3 = New Short[cc1.Count * can * SizeOf(gb.Short)]
  
  mpeg3_read_audio(mp3, 0, cc1.Data, 0, cmp, 0)
  If can = 2 Then mpeg3_reread_audio(mp3, 0, cc2.Data, 1, cmp, 0)
  Print "Durata:         "; Time(0, 0, 0, mpeg3_get_time(mp3) * 1000)
  
  For i = 0 To (cmp * SizeOf(gb.Short)) - 1 Step can
    cc3[i] = cc1[i / can]
    If can = 2 Then cc3[i + 1] = cc2[i / can]
  Next
  
' Crea il file dei dati audio grezzi PCM:
  fl = Open "/tmp/dati_grezzi" For Create
  cc3.Write(fl, 0, cc3.Count / can)
  fl.Close
  
  mpeg3_close(mp3)
  
End