Плеер не хочет запускаться после вызова ioctl? - PullRequest
0 голосов
/ 19 января 2020

Я хочу управлять вводом / выводом компакт-диска с помощью программы на 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 игрок или даже ритмбокс

...