Differenze tra le versioni di "Estrarre i dati audio di una traccia di un CD audio e crearne un file WAV con le risorse del API di libcdio paranoia"

Da Gambas-it.org - Wikipedia.
 
(Una versione intermedia di uno stesso utente non è mostrata)
Riga 1: Riga 1:
 
Usando alcune risorse esterne della libreria "''libcdio_paranoia''" è possibile anche estrarre i dati audio grezzi di una traccia di un CD audio e crearne un file WAV.
 
Usando alcune risorse esterne della libreria "''libcdio_paranoia''" è possibile anche estrarre i dati audio grezzi di una traccia di un CD audio e crearne un file WAV.
  
E' necessario avere installate nel proprio sistema le librerie condivise "''libcdio.so.17.0.0''", "''libcdio_cdda.so.2.0.0''" e "''libcdio_paranoia.so.2.0.0''".
+
E' necessario avere installate nel proprio sistema le librerie condivise "''libcdio.so.19.0.0''", "''libcdio_cdda.so.2.0.0''" e "''libcdio_paranoia.so.2.0.0''".
  
 
Nel codice che segue sarà richiamata la sola libreria condivisa: ''libcdio_paranoia.so.2.0.0''
 
Nel codice che segue sarà richiamata la sola libreria condivisa: ''libcdio_paranoia.so.2.0.0''
Riga 7: Riga 7:
 
  Private Const SEEK_SET As Integer = 0
 
  Private Const SEEK_SET As Integer = 0
 
   
 
   
  Library "libcdio_paranoia:2.0.0"
+
  Library "<FONT Color=blue>libcdio_paranoia:2.0.0</font>"
 
   
 
   
 
  Private Const CDIO_CD_FRAMESIZE_RAW As Integer = 2352
 
  Private Const CDIO_CD_FRAMESIZE_RAW As Integer = 2352
Riga 78: Riga 78:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
   Dim cdd, drives, p, buf As Pointer
+
   Dim drives, cdd, p, buf As Pointer
 
   Dim err, mes As Pointer
 
   Dim err, mes As Pointer
 
   Dim lsn, cur, tra, llsn As Integer
 
   Dim lsn, cur, tra, llsn As Integer
Riga 107: Riga 107:
 
  <FONT Color=gray>' ''Ora si leggono i frame del numero della traccia audio, indicato nella Costante "TRACCIA", del CD audio:''</font>
 
  <FONT Color=gray>' ''Ora si leggono i frame del numero della traccia audio, indicato nella Costante "TRACCIA", del CD audio:''</font>
 
   p = cdio_paranoia_init(cdd)
 
   p = cdio_paranoia_init(cdd)
 +
  If p == 0 Then Error.Raise("Errore !")
 
    
 
    
 
   lsn = cdio_cddap_track_firstsector(cdd, <FONT Color=#B22222>TRACCIA</font>)
 
   lsn = cdio_cddap_track_firstsector(cdd, <FONT Color=#B22222>TRACCIA</font>)
Riga 136: Riga 137:
 
   cdio_cddap_close(cdd)
 
   cdio_cddap_close(cdd)
 
    
 
    
  '''End'''
+
  End
 
    
 
    
 
   
 
   
  '''Private''' Procedure Scrive_WAV_header(fl As File, byte As Integer)
+
  Private Procedure Scrive_WAV_header(fl As File, byte As Integer)
 
    
 
    
 
                                   <FONT Color=gray>' ''Indice:''</font>
 
                                   <FONT Color=gray>' ''Indice:''</font>
Riga 155: Riga 156:
 
   Numeri(byte, fl, 4)            <FONT Color=gray>' ''40-43''</font>
 
   Numeri(byte, fl, 4)            <FONT Color=gray>' ''40-43''</font>
 
    
 
    
  '''End'''
+
  End
 
+
  '''Private''' Procedure Numeri(num As Long, fi As File, bt As Integer)
+
 +
  Private Procedure Numeri(num As Long, fi As File, bt As Integer)
 
    
 
    
 
   Dim i As Integer
 
   Dim i As Integer
Riga 169: Riga 171:
 
   Until bt == 0
 
   Until bt == 0
 
    
 
    
  '''End'''
+
  End

Versione attuale delle 08:25, 4 giu 2024

Usando alcune risorse esterne della libreria "libcdio_paranoia" è possibile anche estrarre i dati audio grezzi di una traccia di un CD audio e crearne un file WAV.

E' necessario avere installate nel proprio sistema le librerie condivise "libcdio.so.19.0.0", "libcdio_cdda.so.2.0.0" e "libcdio_paranoia.so.2.0.0".

Nel codice che segue sarà richiamata la sola libreria condivisa: libcdio_paranoia.so.2.0.0

Private Const TRACCIA As Integer = 4   '' Imposta il numero della traccia audio di cui estrarre i dati audio
Private Const SEEK_SET As Integer = 0

Library "libcdio_paranoia:2.0.0"

Private Const CDIO_CD_FRAMESIZE_RAW As Integer = 2352
Private Enum CDIO_FS_AUDIO = 1, CDIO_FS_HIGH_SIERRA, CDIO_FS_ISO_9660, CDIO_FS_INTERACTIVE, CDIO_FS_HFS, CDIO_FS_UFS
Private Enum CDDA_MESSAGE_FORGETIT = 0, CDDA_MESSAGE_PRINTIT, CDDA_MESSAGE_LOGIT, CD_FRAMESAMPLES = 588, MAXTRK = 100
Private Enum PARANOIA_MODE_DISABLE = 0, PARANOIA_MODE_VERIFY = 1, PARANOIA_MODE_FRAGMENT = 2, PARANOIA_MODE_OVERLAP = 4,
             PARANOIA_MODE_SCRATCH = 8, PARANOIA_MODE_REPAIR = 16, PARANOIA_MODE_NEVERSKIP = 32, PARANOIA_MODE_FULL = 255

' char ** cdio_get_devices_with_cap (char *ppsz_search_devices[], cdio_fs_anal_t capabilities, bool b_any)
' Get an array of device names in search_devices that have at least the capabilities listed by the capabities parameter.
Private Extern cdio_get_devices_with_cap(ppsz_search_devices As Pointer, capabilities As Integer, b_any As Boolean) As Pointer

' cdrom_drive_t *cdio_cddap_identify(const char *psz_device, int messagedest, char **ppsz_message)
' Returns a paranoia CD-ROM drive object with a CD-DA.
Private Extern cdio_cddap_identify(psz_device As String, messagedest As Integer, ppsz_message As Pointer) As Pointer

' void cdio_free_device_list (char * device_list[])
' Free device list returned.
Private Extern cdio_free_device_list(device_list As Pointer)

' void cdio_cddap_verbose_set(cdrom_drive_t *d, int err_action, int mes_action)
Private Extern cdio_cddap_verbose_set(d As Pointer, err_action As Integer, mes_action As Integer)

' int cdio_cddap_open(cdrom_drive_t *d)
Private Extern cdio_cddap_open(d As Pointer) As Integer

' cdrom_paranoia_t *cdio_paranoia_init(cdrom_drive_t *d)
' Get and initialize a new cdrom_paranoia object from cdrom_drive.
Private Extern cdio_paranoia_init(d As Pointer) As Pointer

' lsn_t cdio_cddap_track_firstsector(cdrom_drive_t *d, track_t i_track)
' Return the lsn for the start of track i_track.
Private Extern cdio_cddap_track_firstsector(d As Pointer, i_track As Integer) As Integer

' int cdio_cddap_sector_gettrack(cdrom_drive_t *d, lsn_t lsn)
' Return the track containing the given LSN.
Private Extern cdio_cddap_sector_gettrack(d As Pointer, lsn As Integer) As Integer

' lsn_t cdio_cddap_track_lastsector(cdrom_drive_t *d, track_t i_track)
' Get last lsn of the track.
Private Extern cdio_cddap_track_lastsector(d As Pointer, i_track As Integer) As Integer

' void cdio_paranoia_modeset(cdrom_paranoia_t *p, int mode_flags)
' Set the kind of repair you want to on for reading.
Private Extern cdio_paranoia_modeset(p As Pointer, mode_flags As Integer)

' lsn_t cdio_paranoia_seek(cdrom_paranoia_t *p, int32_t seek, int whence)
' Reposition reading offset.
Private Extern cdio_paranoia_seek(p As Pointer, _seek As Integer, whence As Integer) As Integer

' int16_t *cdio_paranoia_read(cdrom_paranoia_t *p, void(*callback)(long int, paranoia_cb_mode_t))
' Reads the next sector of audio data.
Private Extern cdio_paranoia_read(p As Pointer, callback As Pointer) As Pointer

' char *cdio_cddap_errors(cdrom_drive_t *d)
' Returns the current error buffer.
Private Extern cdio_cddap_errors(d As Pointer) As Pointer

' char *cdio_cddap_messages(cdrom_drive_t *d)
' Returns the current message buffer.
Private Extern cdio_cddap_messages(d As Pointer) As Pointer

' void cdio_paranoia_free(cdrom_paranoia_t *p)
' Free any resources associated with p.
Private Extern cdio_paranoia_free(p As Pointer)

' int cdio_cddap_close(cdrom_drive_t *d)
' Closes d and releases all storage associated with it.
Private Extern cdio_cddap_close(d As Pointer) As Integer


Public Sub Main()
 
 Dim drives, cdd, p, buf As Pointer
 Dim err, mes As Pointer
 Dim lsn, cur, tra, llsn As Integer
 Dim fl As File
 
' Cerca un dispositivo con un CD-DA caricato:
 drives = cdio_get_devices_with_cap(0, CDIO_FS_AUDIO, False)
 
 If (drives > 0) And (Not IsNull(String@(Pointer@(drives)))) Then
' Se ha trovato un CD-ROM con un CD-DA caricato, allora utilizza la prima unità nell'elenco:
   cdd = cdio_cddap_identify(String@(Pointer@(drives)), 1, 0)
   Print "Unità CD-Da trovata e utilizzata: "; String@(Pointer@(drives))
 Else
   Error.Raise("Impossibile cercare o accedere ad un drive CD-ROM contenente un CD audio !")
 Endif
 
' Non si ha più bisogno della lista dei dispositivi, pertanto si libera la memoria:
 cdio_free_device_list(drives)
 
 If cdd == 0 Then Error.Raise("Impossibile identificare il disco CD audio !")
 
 cdio_cddap_verbose_set(cdd, CDDA_MESSAGE_PRINTIT, CDDA_MESSAGE_PRINTIT)
 
 If cdio_cddap_open(cdd) <> 0 Then Error.Raise("Impossibile aprire il disco !")
 
' Ora si leggono i frame del numero della traccia audio, indicato nella Costante "TRACCIA", del CD audio:
 p = cdio_paranoia_init(cdd)
 If p == 0 Then Error.Raise("Errore !")
 
 lsn = cdio_cddap_track_firstsector(cdd, TRACCIA)
 If lsn == -1 Then Error.Raise("Problemi nell'avvio dell'LSN !")
 
 tra = cdio_cddap_sector_gettrack(cdd, lsn)
 llsn = cdio_cddap_track_lastsector(cdd, tra)
 
' Il file WAV sarà salvato nella cartella "/tmp":
 fl = Open "/tmp/wave.wav" For Create
 
 cdio_paranoia_modeset(p, PARANOIA_MODE_FULL Xor PARANOIA_MODE_NEVERSKIP)
 cdio_paranoia_seek(p, lsn, SEEK_SET)
 
 Scrive_WAV_header(fl, (llsn - lsn + 1) * CDIO_CD_FRAMESIZE_RAW)
 
 For cur = lsn To llsn - 1
   buf = cdio_paranoia_read(p, 0)
   err = cdio_cddap_errors(cdd)
   mes = cdio_cddap_messages(cdd)
   If mes > 0 Then Print String@(mes)
   If err > 0 Then Print String@(err)
   If buf == 0 Then Error.Raise("Errore lettura di Paranoia !")
   Write #fl, buf, CDIO_CD_FRAMESIZE_RAW
 Next
 
 fl.Close
 cdio_paranoia_free(p)
 cdio_cddap_close(cdd)
 
End
 

Private Procedure Scrive_WAV_header(fl As File, byte As Integer)
 
                                 ' Indice:
 Write #fl, "RIFF"               '  0- 3
 Numeri(byte + 44 - 8, fl, 4)    '  4- 7
 Write #fl, "WAVEfmt "           '  8-15
 Numeri(16, fl, 4)               ' 16-19
 Numeri(1, fl, 2)                ' 20-21
 Numeri(2, fl, 2)                ' 22-23
 Numeri(44100, fl, 4)            ' 24-27
 Numeri(44100 * 2 * 2, fl, 4)    ' 28-31
 Numeri(4, fl, 2)                ' 32-33
 Numeri(16, fl, 2)               ' 34-35
 Write #fl, "data"               ' 36-39
 Numeri(byte, fl, 4)             ' 40-43
 
End


Private Procedure Numeri(num As Long, fi As File, bt As Integer)
 
 Dim i As Integer
 Dim b As Byte
 
 Repeat
   b = Shr(num, Shl(i, 3)) And &FF
   Write #fi, b As Byte
   Inc i
   Dec bt
 Until bt == 0
 
End