Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   Related Pages  

cdrom.cxx

00001 #include <freedb/freedb.hxx>
00002 
00003 #include <sys/ioctl.h>
00004 #include <sys/types.h>
00005 #include <sys/stat.h>
00006 #include <fcntl.h>
00007 
00020 vector<TrackPosition> Freedb::getTrackOffsets(string device = "/dev/cdrom")
00021 {
00022     /* open device */
00023     int fd = open(device.c_str(), O_RDONLY | O_NONBLOCK);
00024     if (fd == (-1))
00025     {
00026         Error err;
00027 
00028         err.errcode = errno;
00029         err.errmsg = "Error while opening CD-ROM device " + device;
00030         err.extinfo = strerror(errno);
00031 
00032         throw(err);
00033     }
00034 
00035     /* read TOC to get number of tracks */
00036     struct cdrom_tochdr header;
00037     int retval = ioctl(fd, CDROMREADTOCHDR, &header);
00038     if (fd == (-1))
00039     {
00040         Error err;
00041 
00042         err.errcode = errno;
00043         err.errmsg = "Error while reading TOC header on " + device;
00044         err.extinfo = strerror(errno);
00045 
00046         throw(err);
00047     }
00048     int num_tracks = header.cdth_trk1;
00049 
00050     /* loop through tracks and save offsets */
00051     TrackPosition offset;
00052     vector<TrackPosition> offsets;
00053     struct cdrom_tocentry te;
00054     int pos_frames;
00055 
00056     for (int i = 0; i <= num_tracks; i++)
00057     {
00058 
00059         te.cdte_track = (i == num_tracks ? CDROM_LEADOUT : i + 1);
00060         te.cdte_format = CDROM_MSF;
00061 
00062         retval = ioctl(fd, CDROMREADTOCENTRY, &te);
00063         if (retval == (-1))
00064         {
00065             Error err;
00066 
00067             err.errcode = errno;
00068             err.errmsg = "Error while reading TOC entry of track " + itos(i) + " on " + device;
00069             err.extinfo = strerror(errno);
00070 
00071             throw(err);
00072         }
00073 
00074         offset.min = static_cast<int>(te.cdte_addr.msf.minute);
00075         offset.sec = static_cast<int>(te.cdte_addr.msf.second);
00076         offset.frame = static_cast<int>(te.cdte_addr.msf.frame);
00077 
00078         offsets.push_back(offset);
00079         /*
00080          *  To calculate the absolute frame position:
00081          *
00082          *  pos_abs = offset.frame + offset.second * CD_FRAMES + offset.minute * CD_SECS * CD_FRAMES;
00083          *
00084          *  Where CD_SECS is defined 60 and CD_FRAMES is defined 75 in linux/cdrom.h.
00085          */
00086     }
00087 
00088     /* done */
00089     return(offsets);
00090 }
00091 
00092 int Freedb::generateDiscSum(int n)
00093 {
00094     int sum = 0;
00095 
00096     while (n > 0)
00097     {
00098         sum += (n % 10);
00099         n = n / 10;
00100     }
00101 
00102     return(sum);
00103 }
00104 
00105 unsigned long Freedb::generateDiscID(const vector<TrackPosition> offsets, const int num_tracks)
00106 {
00107     int i = 0, t = 0, n = 0;
00108 
00109     while (i < num_tracks)
00110     {
00111         n += Freedb::generateDiscSum((offsets[i].min * 60) + offsets[i].sec);
00112         i++;
00113     }
00114 
00115     t = ((offsets[num_tracks].min * 60) + offsets[num_tracks].sec) -
00116         ((offsets[0].min * 60) + offsets[0].sec);
00117 
00118     return((n % 0xff) << 24 | t << 8 | num_tracks);
00119 }
00120 
00121 
00127 unsigned long Freedb::getDiscID(string device = "/dev/cdrom")
00128 {
00129     vector<TrackPosition> offsets;
00130 
00131     try
00132     {
00133         offsets = Freedb::getTrackOffsets();
00134     }
00135     catch(const Error& err)
00136     {
00137         throw err;
00138     }
00139 
00140     int num_tracks = 0;
00141 
00142     vector<TrackPosition>::const_iterator i = offsets.begin();
00143 
00144     while (i != offsets.end())
00145     {
00146         num_tracks++;
00147         i++;
00148     }
00149 
00150     return(Freedb::generateDiscID(offsets, num_tracks - 1));
00151 }

Generated on Wed Nov 6 17:32:02 2002 for libfreedb by doxygen1.2.18