Conoscere le caratteristiche di CD e DVD con le funzioni del API di libcdio

Da Gambas-it.org - Wikipedia.

La libreria Libcdio consente di gestire i CD ed i relativi driver presenti nel sistema.

Per utilizzare le funzioni esterne del API di libcdio sarà necessario richiamare l'attuale libreria: "libcdio.so.13.0.0".


Mostriamo di seguito un semplice codice che consentirà di conoscere le caratteristiche di un CD o un DVD inserito nell'apposito lettore.
Poiché l'uso della libreria esterna libcdio prevede il richiamo di una Struttura, ed al fine di poter gestire detta Struttura esterna 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 gestione della Struttura utilizzata di libcdio sarà la seguente:

#include <cdio/cdio.h>
#include <cdio/cd_types.h>


int Dim_cdio_iso_analysis_t() {
  return sizeof(cdio_iso_analysis_t);
}


int Legge_isofs_size(cdio_iso_analysis_t *p) {
  return p->isofs_size;
}

char * Legge_iso_label(cdio_iso_analysis_t *p) {
  return p->iso_label;
}

int Legge_joliet_level(cdio_iso_analysis_t *p) {
  return p->joliet_level;
}

Tale codice in linguaggio C in questo esempio sarà posto nella cartella Dati dell'applicativo Gambas con il nome libadhoc.c, e andrà poi trasformato in una libreria condivisa .so , che - come già accennato - sarà richiamata nel codice Gambas.


Il codice Gambas, invece, potrà essere il seguente:

Library "libcdio:13.0.0"

Private Enum DRIVER_UNKNOWN = 0, DRIVER_AIX, DRIVER_BSDI, DRIVER_FREEBSD, DRIVER_NETBSD, DRIVER_LINUX, DRIVER_SOLARIS,
             DRIVER_OS2, DRIVER_OSX, DRIVER_WIN32, DRIVER_CDRDAO, DRIVER_BINCUE, DRIVER_NRG, DRIVER_DEVICE

Private Enum TRACK_FORMAT_AUDIO = 0, TRACK_FORMAT_CDI, TRACK_FORMAT_XA, TRACK_FORMAT_DATA, TRACK_FORMAT_PSX, TRACK_FORMAT_ERROR
             
Private Enum CDIO_FS_AUDIO = 1, CDIO_FS_HIGH_SIERRA, CDIO_FS_ISO_9660, CDIO_FS_INTERACTIVE, CDIO_FS_HFS, CDIO_FS_UFS, CDIO_FS_EXT2, CDIO_FS_ISO_HFS,
             CDIO_FS_ISO_9660_INTERACTIVE, CDIO_FS_3DO, CDIO_FS_XISO, CDIO_FS_UDFX, CDIO_FS_UDF, CDIO_FS_ISO_UDF, CDIO_FS_UNKNOWN

Private Enum CDIO_FS_MASK = &0F, CDIO_FS_ANAL_XA = &10, CDIO_FS_ANAL_MULTISESSION = &20, CDIO_FS_ANAL_PHOTO_CD = &40, CDIO_FS_ANAL_HIDDEN_TRACK = &80, CDIO_FS_ANAL_CDTV = &100,
             CDIO_FS_ANAL_BOOTABLE = &200, CDIO_FS_ANAL_VIDEOCD = &400, CDIO_FS_ANAL_ROCKRIDGE = &800, CDIO_FS_ANAL_JOLIET = &1000, CDIO_FS_ANAL_SVCD = &2000,
             CDIO_FS_ANAL_CVD = &4000, CDIO_FS_ANAL_XISO = &8000, CDIO_FS_ANAL_ISO9660_ANY = &10000, CDIO_FS_ANAL_VCD_ANY = &6400, CDIO_FS_MATCH_ALL = &F0 

Private Enum CDIO_DISC_MODE_CD_DA = 0, CDIO_DISC_MODE_CD_DATA, CDIO_DISC_MODE_CD_XA, CDIO_DISC_MODE_CD_MIXED,
             CDIO_DISC_MODE_DVD_ROM, CDIO_DISC_MODE_DVD_RAM, CDIO_DISC_MODE_DVD_R, CDIO_DISC_MODE_DVD_RW,
             CDIO_DISC_MODE_HD_DVD_ROM, CDIO_DISC_MODE_HD_DVD_RAM, CDIO_DISC_MODE_HD_DVD_R, CDIO_DISC_MODE_DVD_PR,
             CDIO_DISC_MODE_DVD_PRW, CDIO_DISC_MODE_DVD_PRW_DL, CDIO_DISC_MODE_DVD_PR_DL, CDIO_DISC_MODE_DVD_OTHER,
             CDIO_DISC_MODE_NO_INFO, CDIO_DISC_MODE_ERROR, CDIO_DISC_MODE_CD_I

' CdIo_t * cdio_open (const char *psz_source, driver_id_t driver_id)
' Sets up to read from place specified by psz_source and driver_id.
Private Extern cdio_open(psz_source As String, driver_id As Integer) As Pointer

' track_t cdio_get_first_track_num(const CdIo_t * p_cdio)
' Get the number of the first track.
Private Extern cdio_get_first_track_num(cdioP As Pointer) As Integer

' track_t cdio_get_num_tracks(const CdIo_t * p_cdio)
' Get the number of tracks on the CD.
Private Extern cdio_get_num_tracks(cdioP As Pointer) As Integer

' track_format_t cdio_get_track_format(const CdIo_t * p_cdio, track_t u_track)
' Get the format (audio, mode2, mode1) of track.
Private Extern cdio_get_track_format(cdioP As Pointer, u_track As Integer) As Integer

' discmode_t cdio_get_discmode (CdIo_t *p_cdio)
' Get disc mode - the kind of CD (CD-DA, CD-ROM mode 1, CD-MIXED, etc. that we've got.
Private Extern cdio_get_discmode(cdioP As Pointer) As Integer

' lsn_t cdio_get_track_lsn(const CdIo_t * p_cdio, track_t u_track)
' Return the starting LSN for track number i_track in p_cdio.
Private Extern cdio_get_track_lsn(cdioP As Pointer, u_track As Integer) As Integer

' cdio_fs_anal_t cdio_guess_cd_type(const CdIo_t *cdio, int start_session, track_t track_num, cdio_iso_analysis_t *iso_analysis)
' Try to determine what kind of CD-image and/or filesystem we have at track track_num.
Private Extern cdio_guess_cd_type(cdioP As Pointer, start_session As Integer, track_num As Integer, iso_an As Pointer) As Integer

' void cdio_destroy(CdIo_t * p_cdio)
' Free any resources associated with p_cdio.
Private Extern cdio_destroy(cdioP As Pointer)


Library "/tmp/libadhoc"
Private Extern Dim_cdio_iso_analysis_t() As Integer
Private Extern Legge_isofs_size(cia As Pointer) As Integer
Private Extern Legge_iso_label(cia As Pointer) As String
Private Extern Legge_joliet_level(cia As Pointer) As Integer


Public Sub Main()

 Dim p_cdio, cdio_iso_analysis As Pointer
 Dim fs, iniz_traccia, iniz_dati, num_data, num_audio As Integer
 Dim i, lsn, formato_traccia As Integer
 Dim num_tracce, num_prima_traccia As Byte
 Dim primo_dato, primo_audio As Integer = -1


  Shell "gcc -o /tmp/libadhoc.so " & Application.Path &/ "libadhoc.c -shared -lcdio" Wait

  cdio_iso_analysis = Alloc(Dim_cdio_iso_analysis_t())

  p_cdio = cdio_open(Null, DRIVER_LINUX)
  If IsNull(p_cdio) Then Error.Raise("Impossibile trovare il driver per il cd-rom !")
  
  num_prima_traccia = cdio_get_first_track_num(p_cdio)
  num_tracce = cdio_get_num_tracks(p_cdio)
   
' Verifica il numero delle tracce dati ed audio presenti nel CD:
  For i = num_prima_traccia To num_tracce
    If TRACK_FORMAT_AUDIO = cdio_get_track_format(p_cdio, i) Then
      Inc num_audio
      If -1 = primo_audio Then primo_audio = i
    Else
      Inc num_data
      If -1 = primo_dato Then primo_dato = i
    Endif
  Next
   
' Verifica il tipo di CD inserito:
  Analisi_1_Disco(p_cdio, num_data)

  If num_data = 0 Then
    Print "CD Audio\n"
  Else
    For i = primo_dato To num_tracce
      formato_traccia = cdio_get_track_format(p_cdio, i)
      lsn = cdio_get_track_lsn(p_cdio, i)

      If i = 1 Then
        iniz_traccia = 0
      Else
        iniz_traccia = lsn
      Endif
     
      If iniz_traccia < (iniz_dati + Legge_isofs_size(cdio_iso_analysis)) Then Continue
      fs = cdio_guess_cd_type(p_cdio, iniz_traccia, i, cdio_iso_analysis)
      
      Analisi_2_CD(cdio_iso_analysis, fs, primo_dato, num_audio)
    Next
     
  Endif
 

' Va in chiusura:
  Free(cdio_iso_analysis)
  cdio_destroy(p_cdio)

End


Private Procedure Analisi_1_Disco(cdio_P As Pointer, nd As Integer)
 
 Select Case cdio_get_discmode(cdio_P)
   Case CDIO_DISC_MODE_CD_DA
     If nd <> 0 Then Print "CD-Audio"
   Case CDIO_DISC_MODE_CD_DATA
     Print "CD-Dati"
   Case CDIO_DISC_MODE_CD_XA
     Print "CD-Extended Architecture"
   Case CDIO_DISC_MODE_CD_MIXED
       Print "CD Misto"
   Case CDIO_DISC_MODE_DVD_ROM
     Print "DVD-ROM "
   Case CDIO_DISC_MODE_DVD_RAM
     Print "DVD-RAM"
   Case CDIO_DISC_MODE_DVD_R
     Print "CD-R"
   Case CDIO_DISC_MODE_DVD_RW
       Print "DVD-RW"
   Case CDIO_DISC_MODE_HD_DVD_ROM
     Print "HD-DVD-ROM"
   Case CDIO_DISC_MODE_HD_DVD_RAM
     Print "HD-DVD-RAM"
   Case CDIO_DISC_MODE_HD_DVD_R
     Print "HD-DVD-R"
   Case CDIO_DISC_MODE_DVD_PR
       Print "DVD-PR"
   Case CDIO_DISC_MODE_DVD_PRW
     Print "DVD-PRW"
   Case CDIO_DISC_MODE_DVD_PRW_DL
     Print "DVD-PRW-DL"
   Case CDIO_DISC_MODE_DVD_PR_DL
     Print "DVD-PR-DL"
   Case CDIO_DISC_MODE_DVD_OTHER
       Print "Altro tipo di DVD."
   Case CDIO_DISC_MODE_NO_INFO
     Print "Non rilevabile alcuna informazione sul disco."
   Case CDIO_DISC_MODE_ERROR
     Print "ERRORE riscontrato !\n(Verificare innanzitutto la presenza di un disco nel lettore.)"
   Case CDIO_DISC_MODE_CD_I
     Print "CD-Interactive"
 End Select
 
End


Private Procedure Analisi_2_CD(cdio_iso_analysis As Pointer, fs As Integer, primo_dato As Integer, num_audio As Integer)

 Dim s As String

  Select Case (fs And CDIO_FS_MASK)
    Case CDIO_FS_AUDIO
    Case CDIO_FS_ISO_9660
      s = "CD-ROM con filesystem ISO 9660"
      If (fs And CDIO_FS_ANAL_JOLIET) Then s &= " e livello di estensione 'joliet'  " & Legge_joliet_level(cdio_iso_analysis)
      If (fs And CDIO_FS_ANAL_ROCKRIDGE) Then s &= " ed estensioni 'rockridge'"
      Print s
    Case CDIO_FS_ISO_9660_INTERACTIVE
      Print "CD-ROM con CD-RTOS e filesystem ISO 9660\n"
    Case CDIO_FS_HIGH_SIERRA
      Print "CD-ROM con filesystem High Sierra\n"
    Case CDIO_FS_INTERACTIVE
      If num_audio > 0 Then
        Print "CD-Interactive/Ready"
      Else
        Print "CD-Interactive"
      Endif
    Case CDIO_FS_HFS
      Print "CD-ROM con Macintosh HFS\n"
    Case CDIO_FS_ISO_HFS
      Print "CD-ROM con Macintosh HFS e filesystem ISO 9660\n"
    Case CDIO_FS_UFS
      Print "CD-ROM con Unix UFS\n"
    Case CDIO_FS_EXT2
      Print "CD-ROM con un secondo filesystem esteso di Linux\n"
    Case CDIO_FS_3DO
      Print "CD-ROM con filesystem Panasonic 3DO\n"
    Case CDIO_FS_UNKNOWN
      Print "CD-ROM con filesystem sconosciuto\n"
  End Select
  
  Select Case (fs And CDIO_FS_MASK)
    Case CDIO_FS_ISO_9660
      Print "ISO 9660: "; Legge_isofs_size(cdio_iso_analysis); " blocchi, etichetta '"; Legge_iso_label(cdio_iso_analysis); "'"
    Case CDIO_FS_ISO_9660_INTERACTIVE
      Print "ISO 9660: "; Legge_isofs_size(cdio_iso_analysis); " blocchi, etichetta '"; Legge_iso_label(cdio_iso_analysis); "'"
    Case CDIO_FS_ISO_HFS
      Print "ISO 9660: "; Legge_isofs_size(cdio_iso_analysis); " blocchi, etichetta '"; Legge_iso_label(cdio_iso_analysis); "'"
  End Select
 
  If primo_dato = 1 And num_audio > 0 Then Print "CD a modalità mista   "
  If (fs And CDIO_FS_ANAL_XA) Then Print "settori XA   "
  If (fs And CDIO_FS_ANAL_MULTISESSION) Then Print "Multisessione"
  If (fs And CDIO_FS_ANAL_HIDDEN_TRACK) Then Print "Hidden Track   "
  If (fs And CDIO_FS_ANAL_PHOTO_CD) Then
    s = "Foto CD   "
    If num_audio > 0 Then
      Print " Portfolio " & s
    Else
      Print s
    Endif
  Endif
  If (fs And CDIO_FS_ANAL_CDTV) Then Print "Commodore CDTV   "
  If (primo_dato > 1) Then Print "CD-Plus/Extra   "
  If (fs And CDIO_FS_ANAL_BOOTABLE) Then Print "bootable CD  "
  If (fs And CDIO_FS_ANAL_VIDEOCD) And (num_audio = 0) Then Print "Video CD   "
  If (fs And CDIO_FS_ANAL_SVCD) Then Print "Super Video CD (SVCD) o Chaoji Video CD (CVD)"
  If (fs And CDIO_FS_ANAL_CVD) Then Print "Chaoji Video CD (CVD)"
 
End


Riferimenti