OSDLCDROMDrive.cc

Go to the documentation of this file.
00001 #include "OSDLCDROMDrive.h"
00002 
00003 
00004 #include "OSDLUtils.h"   // for getBackendLastError
00005 
00006 #include "SDL.h"         // for CD-ROM primitives
00007 
00008 #include <list>  
00009 
00010 using std::list ;
00011 using std::string ;
00012 
00013 
00014 using namespace OSDL ;
00015 
00016 
00017 // CD track section.
00018 
00019 CDTrack::CDTrack( const SDL_CDtrack & track ) throw() :
00020     _trackData( & track )
00021 {
00022 
00023 }
00024 
00025 
00026 CDTrack::~CDTrack() throw() 
00027 {
00028 
00029     // _trackData not owned.
00030     
00031 }
00032 
00033 
00034 TrackNumber CDTrack::getTrackNumber() const throw()
00035 {
00036 
00037     return _trackData->id ; 
00038     
00039 }
00040 
00041 
00042 TrackType CDTrack::getTrackType() const throw()
00043 {
00044 
00045     switch( _trackData->type )
00046     {
00047     
00048         case SDL_AUDIO_TRACK:
00049             return audioTrack ;
00050             break ;
00051             
00052         case SDL_DATA_TRACK:
00053             return dataTrack ;
00054             break ;
00055         
00056         default:
00057             Ceylan::emergencyShutdown( 
00058                 "CDTrack::getTrackType : unexpected type (abnormal)." ) ;
00059             // Do not care, just to avoid a warning :
00060             return dataTrack ;
00061             break ;
00062     
00063     }
00064                 
00065 }
00066 
00067 
00068 FrameCount CDTrack::getLength() const throw()
00069 {
00070 
00071     return _trackData->length ;
00072      
00073 }
00074 
00075 
00076 FrameCount CDTrack::getFrameOffset() const throw()
00077 {
00078 
00079     return _trackData->offset ; 
00080     
00081 }
00082 
00083 
00084 const string CDTrack::toString( Ceylan::VerbosityLevels level ) const throw()
00085 {
00086     
00087     string res = "Track #" + Ceylan::toString( getTrackNumber() ) 
00088         + " : this is " ;
00089     
00090     switch( getTrackType() )
00091     {
00092         
00093         case audioTrack:
00094             res += "an audio track, its length is " 
00095                 + Ceylan::toString( getLength() ) 
00096                 + " frames (about " 
00097                 + Ceylan::toString( 
00098                     CDROMDrive::ConvertFrameCountToTime( getLength() ) ) 
00099                 + " seconds)" ;
00100             break ;
00101             
00102         case dataTrack:
00103             res += "a data track, its length is " 
00104                 + Ceylan::toString( getLength() ) 
00105                 + " frames" ;
00106             break ;
00107             
00108         default:
00109             res += "unexpected track type" ;
00110             break ; 
00111                 
00112     }
00113 
00114     res += ". Current frame offset is " + Ceylan::toString( getFrameOffset() ) ;
00115     
00116     return res ;
00117     
00118 }
00119 
00120 
00121 
00122 
00123 
00124 // CD-ROM drive section.        
00125     
00126     
00127 const FrameCount CDROMDrive::FramesPerSecond = CD_FPS ;
00128 
00129                 
00130 CDROMDrive::CDROMDrive( CDROMDriveNumber driveNumber ) 
00131         throw( CDROMDriveException ) :
00132     Object(),
00133     _driveNumber( driveNumber ),
00134     _statusUpdated( false ),
00135     _driveStatus( 0 )
00136 {
00137     
00138 }
00139 
00140 
00141 CDROMDrive::~CDROMDrive() throw()
00142 {
00143     
00144     if ( _driveStatus != 0 )
00145         close() ;
00146         
00147 }
00148 
00149 
00150 void CDROMDrive::open() throw( CDROMDriveException )
00151 {
00152 
00153     if ( _driveStatus != 0 )
00154         throw CDROMDriveException( 
00155             "CDROMDrive::open : drive already opened." ) ;
00156         
00157     _driveStatus = SDL_CDOpen( _driveNumber ) ;
00158     
00159     if ( _driveStatus == 0 )
00160         throw CDROMDriveException( "CDROMDrive::open : open failed : "
00161             + Utils::getBackendLastError() ) ;
00162     
00163 }
00164 
00165 
00166 void CDROMDrive::close() throw( CDROMDriveException )
00167 {
00168 
00169     if ( _driveStatus == 0 )
00170         throw CDROMDriveException( 
00171             "CDROMDrive::close : drive was not already opened." ) ;
00172         
00173     SDL_CDClose( _driveStatus ) ;
00174     
00175     // Owned ? ::free( _driveStatus ) ?
00176     _driveStatus = 0 ;
00177         
00178 }
00179 
00180 
00181 void CDROMDrive::eject() const throw( CDROMDriveException )
00182 {
00183 
00184     if ( _driveStatus == 0 )
00185         throw CDROMDriveException( 
00186             "CDROMDrive::eject : drive was not already opened." ) ;
00187 
00188     if ( SDL_CDEject( _driveStatus ) != 0 )
00189         throw CDROMDriveException( 
00190             "CDROMDrive::eject : " + Utils::getBackendLastError() ) ;
00191         
00192 }
00193 
00194 
00195 CDROMDrive::Status CDROMDrive::getStatus() throw( CDROMDriveException )
00196 {
00197             
00198     Status status = getConstStatus() ;
00199     
00200     _statusUpdated = true ;
00201     
00202     return status ;
00203     
00204 }
00205         
00206 
00207 CDROMDrive::Status CDROMDrive::getConstStatus() const 
00208     throw( CDROMDriveException )
00209 {
00210 
00211     if ( _driveStatus == 0 )
00212         throw CDROMDriveException( 
00213             "CDROMDrive::getConstStatus : drive was not already opened." ) ;
00214 
00215         
00216     switch( SDL_CDStatus( _driveStatus ) )
00217     {
00218     
00219         case CD_TRAYEMPTY:
00220             return TrayEmpty ;
00221             break ;
00222             
00223         case CD_STOPPED:
00224             return Stopped ;
00225             break ;
00226                         
00227         case CD_PLAYING:
00228             return Playing ;
00229             break ;
00230             
00231         case CD_PAUSED:
00232             return Paused ;
00233             break ;
00234             
00235         case CD_ERROR:
00236             return InError ;
00237             break ;
00238             
00239         default:
00240             Ceylan::emergencyShutdown( 
00241                 "CDROMDrive::getConstStatus : unknown status read" ) ;
00242             // Do not care, just to avoid a warning :
00243             return InError ;            
00244             break ;
00245                 
00246     }
00247     
00248 }
00249 
00250 
00251 
00252 bool CDROMDrive::isCDInDrive() throw( CDROMDriveException )
00253 {
00254     
00255     CDROMDrive::Status status = getStatus() ;
00256 
00257     return ( ( status != TrayEmpty) && ( status != InError ) ) ;
00258     
00259 }
00260 
00261 TrackNumber CDROMDrive::getTracksCount() const throw( CDROMDriveException )
00262 {
00263 
00264     if ( _driveStatus == 0 )
00265         throw CDROMDriveException( 
00266             "CDROMDrive::getTracksCount : drive was not already opened." ) ;
00267 
00268     return _driveStatus->numtracks ;
00269     
00270 }
00271 
00272 
00273 FrameCount CDROMDrive::getTrackDuration( TrackNumber targetTrack ) 
00274     const throw( CDROMDriveException )
00275 {
00276     
00277     // Checks as well that the drive is opened :
00278     if ( targetTrack >= getTracksCount() )
00279         throw CDROMDriveException( "CDROMDrive::getTrackDuration : "
00280             "specified track (" 
00281             + Ceylan::toString( targetTrack ) + ") out of range." ) ;
00282         
00283     return _driveStatus->track[targetTrack].length ;        
00284     
00285 }
00286 
00287     
00288 CDTrack & CDROMDrive::getTrack( TrackNumber targetTrack ) const 
00289     throw( CDROMDriveException )
00290 {
00291 
00292     // Checks as well that the drive is opened :
00293     if ( targetTrack >= getTracksCount() )
00294         throw CDROMDriveException( "CDROMDrive::getTrack : "
00295             "specified track (" + Ceylan::toString( targetTrack )
00296             + ") out of range." ) ;
00297 
00298     return * new CDTrack( _driveStatus->track[ targetTrack ] ) ;
00299     
00300 }
00301 
00302                     
00303 void CDROMDrive::playFrames( FrameCount startingFrame, 
00304     FrameCount durationInFrames ) throw( CDROMDriveException )      
00305 {
00306 
00307     if ( _driveStatus == 0 )
00308         throw CDROMDriveException( 
00309             "CDROMDrive::playFrames : drive was not already opened." ) ;
00310 
00311     if ( SDL_CDPlay( _driveStatus, startingFrame, durationInFrames) != 0 )
00312         throw CDROMDriveException( "CDROMDrive::playFrames failed : " 
00313             + Utils::getBackendLastError() ) ;
00314     
00315 }
00316 
00317 
00318 void CDROMDrive::playTracks( TrackNumber startingTrack, 
00319     TrackNumber numberOfTracks, FrameCount startingFrameOffset, 
00320     FrameCount stoppingFrameOffset ) throw( CDROMDriveException )   
00321 {
00322 
00323     // Updated status needed to play tracks (check that drive is opened too) :
00324     if ( ! _statusUpdated )
00325         getStatus() ;
00326     
00327     if ( SDL_CDPlayTracks( _driveStatus, startingTrack, startingFrameOffset,
00328         numberOfTracks, stoppingFrameOffset ) != 0 )
00329     {       
00330         throw CDROMDriveException( "CDROMDrive::playTracks failed : " 
00331             + Utils::getBackendLastError() ) ;
00332     }       
00333 
00334 }
00335 
00336 
00337 void CDROMDrive::pause() const throw( CDROMDriveException )
00338 {
00339     
00340     if ( _driveStatus == 0 )
00341         throw CDROMDriveException( 
00342             "CDROMDrive::pause : drive was not already opened." ) ;
00343         
00344     if ( SDL_CDPause( _driveStatus ) != 0 )
00345         throw CDROMDriveException( "CDROMDrive::pause failed : "
00346             + Utils::getBackendLastError() ) ;
00347         
00348 }
00349 
00350 
00351 void CDROMDrive::resume() const throw( CDROMDriveException )
00352 {
00353     
00354     if ( _driveStatus == 0 )
00355         throw CDROMDriveException( 
00356             "CDROMDrive::resume : drive was not already opened." ) ;
00357         
00358     if ( SDL_CDResume( _driveStatus ) != 0 )
00359         throw CDROMDriveException( "CDROMDrive::resume failed : "
00360             + Utils::getBackendLastError() ) ;
00361         
00362 }
00363 
00364         
00365 const string CDROMDrive::toString( Ceylan::VerbosityLevels level ) const throw()
00366 {
00367     
00368     string res ;
00369 
00370     if ( _driveNumber == 0 )
00371         res = "Default CD-ROM drive (#0)" ;
00372     else
00373         res = "CD-ROM drive #" + Ceylan::toString( _driveNumber ) ;
00374     
00375     res += ". System-dependent name for this drive is '" 
00376         + string( SDL_CDName( _driveNumber ) ) ;
00377     
00378     res += "'. It is currently " ;
00379     
00380     if ( _driveStatus == 0 ) 
00381         res += "not " ;
00382     res += "opened for access" ;
00383 
00384     if ( level == Ceylan::low ) 
00385         return res ;
00386         
00387         
00388     if ( _driveStatus != 0 )
00389     {
00390         
00391         res + ". " ;
00392         
00393         switch( getConstStatus() )
00394         {
00395     
00396             case TrayEmpty:
00397                 res += "Tray is empty" ;
00398                 break ;
00399             
00400             case Stopped:
00401                 res += "Drive is stopped" ;
00402                 break ;
00403         
00404             case Playing:
00405                 res += "Drive is playing" ;
00406                 break ;
00407         
00408             case Paused:
00409                 res += "Drive is paused" ;
00410                 break ;
00411             
00412             case InError:
00413                 res += "Drive is in error" ;
00414                 break ;
00415             
00416             default:    
00417                 res += "Unknown drive status (abnormal)" ;
00418                 break ;
00419     
00420         }       
00421             
00422         TrackNumber count = getTracksCount() ;
00423         
00424         res += ". There is/are " + Ceylan::toString( count ) + " track(s) : " ;
00425         
00426         list<string> tracks ;
00427         
00428         for ( TrackNumber i = 0; i < count; i++ )
00429         {
00430             
00431             CDTrack currentTrack( _driveStatus->track[ i ] ) ;
00432             
00433             tracks.push_back( "Track #" + Ceylan::toString( i ) + " : " 
00434                 + currentTrack.toString( level ) ) ;
00435                 
00436         }
00437         
00438         res += Ceylan::formatStringList( tracks ) ;     
00439     } 
00440         
00441     return res ;    
00442         
00443 }
00444                             
00445 
00446 
00447 FrameCount CDROMDrive::ConvertTimeToFrameCount( 
00448     Ceylan::System::Second duration ) throw()
00449 {
00450 
00451     return duration * FramesPerSecond ;
00452     
00453 }
00454 
00455 
00456 Ceylan::System::Second CDROMDrive::ConvertFrameCountToTime( 
00457     FrameCount duration ) throw()
00458 {
00459 
00460     return duration / FramesPerSecond ;
00461     
00462 }
00463 

Generated on Fri Mar 30 14:46:59 2007 for OSDL by  doxygen 1.5.1