Logo Search packages:      
Sourcecode: k9copy version File versions  Download package

bool K3bDevice::Device::readRawToc ( K3bDevice::Toc toc  )  const [protected]

The preferred toc reading method for all CDs. Also reads session info. undefined for DVDs.

Definition at line 1021 of file k3bdevice.cpp.

References blockDeviceName(), close(), K3bDevice::Toc::firstSector(), getTrackDataMode(), isOpen(), open(), rawTocDataWithBcdValues(), and readTocPmaAtip().

Referenced by readToc().

{
  // if the device is already opened we do not close it
  // to allow fast multible method calls in a row
  bool needToClose = !isOpen();

  bool success = false;

  toc.clear();

  if( open() ) {
    //
    // Read Raw TOC (format: 0010b)
    //
    // For POINT from 01h-63h we get all the tracks
    // POINT a1h gices us the last track number in the session in PMIN
    // POINT a2h gives the start of the session lead-out in PMIN,PSEC,PFRAME
    //

    unsigned char* data = 0;
    int dataLen = 0;

    if( readTocPmaAtip( &data, dataLen, 2, false, 1 ) ) {
      if( dataLen > 4 ) {
      success = true;

      toc_raw_track_descriptor* tr = (toc_raw_track_descriptor*)&data[4];

      //
      // debug the raw toc data
      //
      kdDebug() << "Session |  ADR   | CONTROL|  TNO   | POINT  |  Min   |  Sec   | Frame  |  Zero  |  PMIN  |  PSEC  | PFRAME |" << endl;
      for( int i = 0; i < (dataLen-4)/(int)sizeof(toc_raw_track_descriptor); ++i ) {
        QString s;
        s += QString( " %1 |" ).arg( (int)tr[i].session_number, 6 );
        s += QString( " %1 |" ).arg( (int)tr[i].adr, 6 );
        s += QString( " %1 |" ).arg( (int)tr[i].control, 6 );
        s += QString( " %1 |" ).arg( (int)tr[i].tno, 6 );
        s += QString( " %1 |" ).arg( (int)tr[i].point, 6, 16 );
        s += QString( " %1 |" ).arg( (int)tr[i].min, 6 );
        s += QString( " %1 |" ).arg( (int)tr[i].sec, 6 );
        s += QString( " %1 |" ).arg( (int)tr[i].frame, 6 );
        s += QString( " %1 |" ).arg( (int)tr[i].zero, 6, 16 );
        s += QString( " %1 |" ).arg( (int)tr[i].p_min, 6 );
        s += QString( " %1 |" ).arg( (int)tr[i].p_sec, 6 );
        s += QString( " %1 |" ).arg( (int)tr[i].p_frame, 6 );
        kdDebug() << s << endl;
      }

      //
      // First we try to determine if the raw toc data uses BCD values
      //
      int isBcd = rawTocDataWithBcdValues( data, dataLen );
      if( isBcd == -1 ) {
        delete [] data;
        return false;
      }

      K3b::Msf sessionLeadOut;

      for( int i = 0; i < (dataLen-4)/(int)sizeof(toc_raw_track_descriptor); ++i ) {
        if( tr[i].adr == 1 && tr[i].point <= 0x63 ) {
          // track
          K3bTrack track;
          track.m_session = tr[i].session_number;

          // :( We use 00:00:00 == 0 lba)
          if( isBcd )
            track.m_firstSector = K3b::Msf( K3bDevice::fromBcd(tr[i].p_min),
                                    K3bDevice::fromBcd(tr[i].p_sec),
                                    K3bDevice::fromBcd(tr[i].p_frame) ) - 150;
          else
            track.m_firstSector = K3b::Msf( tr[i].p_min, tr[i].p_sec, tr[i].p_frame ) - 150;

          track.m_type = ( tr[i].control & 0x4 ? Track::DATA : Track::AUDIO );
          track.m_mode = ( track.type() == Track::DATA ? getTrackDataMode(track) : Track::UNKNOWN );
          track.m_copyPermitted = ( tr[i].control & 0x2 );
          track.m_preEmphasis = ( tr[i].control & 0x1 );

          //
          // only do this within a session because otherwise we already set the last sector with the session leadout
          //
          if( !toc.isEmpty() )
            if( toc[toc.count()-1].session() == track.session() )
            toc[toc.count()-1].m_lastSector = track.firstSector() - 1;

          toc.append(track);
        }
        else if( tr[i].point == 0xa2 ) {
          //
          // since the session is always reported before the tracks this is where we do this:
          // set the previous session's last tracks's last sector to the first sector of the
          // session leadout (which was reported before the tracks)
          //
          // This only happens on multisession CDs
          //
          if( !toc.isEmpty() )
            toc[toc.count()-1].m_lastSector = sessionLeadOut - 1;

          // this is save since the descriptors are reported in ascending order of the session number
          // :( We use 00:00:00 == 0 lba)
          if( isBcd )
            sessionLeadOut = K3b::Msf( K3bDevice::fromBcd(tr[i].p_min),
                               K3bDevice::fromBcd(tr[i].p_sec),
                               K3bDevice::fromBcd(tr[i].p_frame) ) - 150;
          else
            sessionLeadOut = K3b::Msf( tr[i].p_min, tr[i].p_sec, tr[i].p_frame ) - 150;
        }
      }

      // set the last track's last sector
      if( !toc.isEmpty() )
        toc[toc.count()-1].m_lastSector = sessionLeadOut - 1;
      }
      else
      kdDebug() << "(K3bDevice::Device) " << blockDeviceName() << " empty raw toc." << endl;

      delete [] data;
    }
  }

  if( needToClose )
    close();

  return success;
}


Generated by  Doxygen 1.6.0   Back to index