Я хочу управлять вводом / выводом компакт-диска с помощью программы на c в linux.
Я установил Ubuntu 16 на VMware.
Код, который я использовал is:
/* cdrom.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdlib.h>
#include <linux/cdrom.h>
#include <errno.h>
/* veuillez ajustez si necessaire */
#define CDROM "/dev/sr0"
#define FULL 0 /* lecture complete du cd rom */
static int open_cdrom (void) {
int fd = open (CDROM, O_RDONLY | O_NONBLOCK);
if (fd == -1) {
if (errno == ENOMEDIUM)
printf ("pas de cd dans le lecteur!\n");
else
perror ("erreur a l'ouverture()");
exit (EXIT_FAILURE);
}
return fd;
}
static void open_tray (int cdrom) {
if (ioctl (cdrom, CDROMEJECT) == -1) {
perror ("Eject yourself");
exit (EXIT_FAILURE);
}
}
/* function close */
static void close_tray (int cdrom) {
if (ioctl (cdrom, CDROMCLOSETRAY) == -1) {
printf ("veuillez fermer le plateau a cd a la main\n");
}}
static void lock_tray (int cdrom) {
if (ioctl (cdrom,CDROM_LOCKDOOR,1) <0) {
printf ("erreure\n");
}}
static void unlock_tray (int cdrom) {
if (ioctl (cdrom,CDROM_LOCKDOOR,0) <0) {
printf ("utilisez sudo\n");
}
}
static void capability_cdrom (int cdrom) {
const char *j[] = {"aucun", "oui"};
int caps = ioctl (cdrom, CDROM_GET_CAPABILITY);
if (caps == -1) {
perror ("CDROM_GET_CAPABILITY");
return;
}
printf ("CDROM-capacité:\n"
"\tCD-R : %s\n"
"\tCD-RW : %s\n"
"\tDVD : %s\n"
"\tDVD-R : %s\n"
"\tDVD-RAM : %s\n",
j[!!(caps & CDC_CD_R)],
j[!!(caps & CDC_CD_RW)],
j[!!(caps & CDC_DVD)],
j[!!(caps & CDC_DVD_R)],
j[!!(caps & CDC_DVD_RAM)]);
}
static void get_audio_status (int cdrom) {
struct cdrom_subchnl sub;
printf ("Audio-Status: ");
fflush (stdout);
sub.cdsc_format = CDROM_MSF;
if (ioctl (cdrom, CDROMSUBCHNL, &sub))
printf ("FAILED\n");
else {
switch (sub.cdsc_audiostatus) {
case CDROM_AUDIO_INVALID:
printf ("invalid\n");
break;
case CDROM_AUDIO_PLAY:
printf ("playing");
break;
case CDROM_AUDIO_PAUSED:
printf ("paused");
break;
case CDROM_AUDIO_COMPLETED:
printf ("completed\n");
break;
case CDROM_AUDIO_ERROR:
printf ("error\n");
break;
case CDROM_AUDIO_NO_STATUS:
printf ("no status\n");
break;
default:
printf ("Oops: unknown\n");
}
if (sub.cdsc_audiostatus == CDROM_AUDIO_PLAY ||
sub.cdsc_audiostatus == CDROM_AUDIO_PAUSED) {
printf (" at: %02d:%02d abs/ %02d:%02d track %d\n",
sub.cdsc_absaddr.msf.minute,
sub.cdsc_absaddr.msf.second,
sub.cdsc_reladdr.msf.minute,
sub.cdsc_reladdr.msf.second, sub.cdsc_trk);
}
}
}
static void content_cdrom (int cdrom) {
struct cdrom_tochdr tochdr;
struct cdrom_tocentry tocentry;
int track;
if (ioctl (cdrom, CDROMREADTOCHDR, &tochdr) == -1) {
perror ("ne peut pas obtenir lentete");
exit (EXIT_FAILURE);
}
printf ("\ncontenu %d Tracks:\n", tochdr.cdth_trk1);
track = tochdr.cdth_trk0;
while (track <= tochdr.cdth_trk1) {
tocentry.cdte_track = track;
tocentry.cdte_format = CDROM_MSF;
if (ioctl (cdrom, CDROMREADTOCENTRY, &tocentry)==-1) {
perror ("le contenu du cd ne peut pas etre determiné");
exit (EXIT_FAILURE);
}
printf ("%3d: %02d:%02d:%02d (%06d) %s%s\n",
tocentry.cdte_track,
tocentry.cdte_addr.msf.minute,
tocentry.cdte_addr.msf.second,
tocentry.cdte_addr.msf.frame,
tocentry.cdte_addr.msf.frame +
tocentry.cdte_addr.msf.second * 75 +
tocentry.cdte_addr.msf.minute * 75 * 60 - 150,
(tocentry.cdte_ctrl & CDROM_DATA_TRACK) ?
"data " : "audio",
CDROM_LEADOUT == track ? " (leadout)" : "");
track++;
}
}
static void play_cdrom( int cdrom, int flag ) {
struct cdrom_tocentry tocentry;
struct cdrom_msf play;
int track = flag;
int lead = flag;
if(flag == FULL) {
track = 1;
lead = CDROM_LEADOUT;
}
else {
track = flag;
lead = flag+1;
}
printf(".........\n");
/* debut de la 1ere chanson */
tocentry.cdte_track = track;
tocentry.cdte_format = CDROM_MSF;
if (ioctl (cdrom, CDROMREADTOCENTRY, &tocentry) == -1) {
perror ("le contenu du cd ne peut pas etre determiné\n");
exit (EXIT_FAILURE);
}
play.cdmsf_min0 = tocentry.cdte_addr.msf.minute;
play.cdmsf_sec0 = tocentry.cdte_addr.msf.second;
play.cdmsf_frame0 = tocentry.cdte_addr.msf.frame;
/*fin de la derniere chanson*/
tocentry.cdte_track = lead;
tocentry.cdte_format = CDROM_MSF;
if (ioctl (cdrom, CDROMREADTOCENTRY, &tocentry) == -1) {
perror ("le contenu du cd ne peut pas etre determiné\n");
exit (EXIT_FAILURE);
}
play.cdmsf_min1 = tocentry.cdte_addr.msf.minute;
play.cdmsf_sec1 = tocentry.cdte_addr.msf.second;
play.cdmsf_frame1 = tocentry.cdte_addr.msf.frame;
if (ioctl (cdrom, CDROMPLAYMSF, &play) == -1) {
perror ("le cd ne peut pas etre lu");
exit (EXIT_FAILURE);
}
}
static void stop_cdrom (int cdrom) {
if (ioctl (cdrom, CDROMSTOP) == -1) {
perror ("le cd ne peut pas s'arreter ");
return;
}
}
static void pause_cdrom (int cdrom) {
if (ioctl (cdrom, CDROMPAUSE) == -1) {
perror ("Ne peut pas mettre une pause");
return;
}
}
static void resume_cdrom (int cdrom) {
if (ioctl (cdrom, CDROMRESUME) == -1) {
perror ("le cd ne peut pas continué");
return;
}
}
int main (void) {
int fd_cdrom;
int select;
int track;
fd_cdrom = open_cdrom();
do{
printf("-1- CD-Tray eject\n");
printf("-2- CD-Tray close\n");
printf("-3- CDROM-capacité\n");
printf("-4- Audio-CD play (complet)\n");
printf("-5- jouer une piste\n");
printf("-6- <PAUSE> Audio-CD jouer\n");
printf("-7- <Resume>\n");
printf("-8- <STOP> \n");
printf("-9- Determiner le statut actuel\n");
printf("-10- Contenu du CD\n");
printf("-11- bloquer\n");
printf("-12- debloquer\n");
printf("-13- quiter\n");
printf("\n Tapez votre choix : ");
scanf("%d",&select);
switch( select ) {
case 1: open_tray( fd_cdrom ); break;
case 2: close_tray(fd_cdrom ); break;
case 3: capability_cdrom (fd_cdrom); break;
case 4: play_cdrom (fd_cdrom, FULL); break;
case 5: printf("Quelle piste voulez-vous entendre: ");
scanf("%d",&track);
play_cdrom(fd_cdrom, track); break;
case 6: pause_cdrom(fd_cdrom ); break;
case 7: resume_cdrom(fd_cdrom ); break;
case 8: stop_cdrom(fd_cdrom ); break;
case 9: get_audio_status(fd_cdrom );break;
case 10: content_cdrom(fd_cdrom ); break;
case 11: lock_tray( fd_cdrom ); break;
case 12: unlock_tray( fd_cdrom ); break;
case 13: printf("Bye\n"); break;
default : printf("erreur!\n");
}
} while( select != 13 );
stop_cdrom( fd_cdrom );
close (fd_cdrom);
return 0;
}
Код очень хорошо работает с:
open_tray( fd_cdrom );
close_tray(fd_cdrom );
capability_cdrom (fd_cdrom);
lock_tray( fd_cdrom );
unlock_tray( fd_cdrom );
Проблема для play
, она не сообщает о проблеме, но не запускает vl c игрок или даже ритмбокс