Conoscere le caratteristiche di CD e DVD con le funzioni del API di libcdio
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 ' bool cdio_is_discmode_cdrom(discmode_t discmode) ' Return true if discmode is some sort of CD. Private Extern cdio_is_discmode_cdrom(discmode_t as Integer) As Boolean ' bool cdio_is_discmode_dvd(discmode_t discmode) ' Return true if discmode is some sort of DVD. Private Extern cdio_is_discmode_dvd(discmode_t as Integer) As Boolean ' 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) Dim dm As Integer dm = cdio_get_discmode(cdio_P) If cdio_is_discmode_cdrom(dm) Then Print "Il disco presente nel lettore è un CD." If cdio_is_discmode_dvd(dm) Then Print "Il disco presente nel lettore è un DVD." Select Case dm 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 Error.Raise("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