コード例 #1
0
K3b::Msf K3b::Msf::fromString( const QString& s, bool* ok )
{
  QRegExp rx = regExp();

  K3b::Msf msf;

  if( rx.exactMatch( s ) ) {
    //
    // first number - cap(1)
    // second number - cap(2)
    // third number - cap(3)
    //
    if( rx.cap(2).isEmpty() ) {
      msf.m_frames = rx.cap(1).toInt();
    }
    else {
      msf.m_minutes = rx.cap(1).toInt();
      msf.m_seconds = rx.cap(2).toInt();
      msf.m_frames = rx.cap(3).toInt();
    }

    if( ok )
      *ok = true;
  }
  else if( ok )
    *ok = false;

  msf.makeValid();

  return msf;
}
コード例 #2
0
ファイル: k3baudiorippingdialog.cpp プロジェクト: KDE/k3b
K3b::AudioRippingDialog::AudioRippingDialog( const K3b::Medium& medium,
                                              const KCDDB::CDInfo& entry,
                                              const QList<int>& tracks,
                                              QWidget *parent )
    : K3b::InteractionDialog( parent,
                            QString(),
                            QString(),
                            START_BUTTON|CANCEL_BUTTON,
                            START_BUTTON,
                            "Audio Ripping" ), // config group
      m_medium( medium ),
      m_cddbEntry( entry ),
      m_trackNumbers( tracks )
{
    d = new Private();

    setupGui();
    setupContextHelp();

    K3b::Msf length;
    K3b::Device::Toc toc = medium.toc();
    for( QList<int>::const_iterator it = m_trackNumbers.constBegin();
         it != m_trackNumbers.constEnd(); ++it ) {
        length += toc[*it].length();
    }
    setTitle( i18n("CD Ripping"),
              i18np("1 track (%2)", "%1 tracks (%2)",
                    m_trackNumbers.count(),length.toString()) );
}
コード例 #3
0
ファイル: k3btrm.cpp プロジェクト: KDE/k3b
void K3b::TRM::start( const K3b::Msf& length )
{
    if( KProtocolManager::useProxy() ) {
        QUrl proxy( KProtocolManager::proxyFor("http") );
        trm_SetProxy( d->trm, const_cast<char*>(proxy.host().toLatin1().constData()), short(proxy.port()) );
    }

    trm_SetPCMDataInfo( d->trm, 44100, 2, 16 );
    trm_SetSongLength( d->trm, length.totalFrames()/75 );
}
コード例 #4
0
ファイル: k3bffmpegwrapper.cpp プロジェクト: franhaufer/k3b
bool K3bFFMpegFile::seek( const K3b::Msf& msf )
{
    d->outputBufferSize = 0;
    d->packetSize = 0;

    double seconds = (double)msf.totalFrames()/75.0;
    quint64 timestamp = (quint64)(seconds * (double)AV_TIME_BASE);

    // FIXME: do we really need the start_time and why?
#if LIBAVFORMAT_BUILD >= 4619
    return ( ::av_seek_frame( d->formatContext, -1, timestamp + d->formatContext->start_time, 0 ) >= 0 );
#else
    return ( ::av_seek_frame( d->formatContext, -1, timestamp + d->formatContext->start_time ) >= 0 );
#endif
}
コード例 #5
0
ファイル: k3bfillstatusdisplay.cpp プロジェクト: KDE/k3b
void K3b::FillStatusDisplay::Private::setCdSize( const K3b::Msf& size )
{
    // Remove check mark from the currently checked action
    if( QAction* checked = cdSizeGroup->checkedAction() ) {
        checked->setChecked( false );
    }

    switch( size.totalFrames() ) {
        case MediaSizeCd74Min:
        case 650*512:
            displayWidget->setCdSize( MediaSizeCd74Min );
            action74Min->setChecked( true );
            break;
        case MediaSizeCd80Min:
        case 700*512:
            displayWidget->setCdSize( MediaSizeCd80Min );
            action80Min->setChecked( true );
            break;
        case MediaSizeCd100Min:
        case 880*512:
            displayWidget->setCdSize( MediaSizeCd100Min );
            action100Min->setChecked( true );
            break;
        case MediaSizeDvd4Gb:
        case 2306867: // rounded 4.4*1024*512
            displayWidget->setCdSize( MediaSizeDvd4Gb );
            actionDvd4_7GB->setChecked( true );
            break;
        case MediaSizeDvd8Gb:
        case 8*1024*512:
            displayWidget->setCdSize( MediaSizeDvd8Gb );
            actionDvdDoubleLayer->setChecked( true );
            break;
        case MediaSizeBluRay25Gb:
        //case 25*1024*512:
            displayWidget->setCdSize( MediaSizeBluRay25Gb );
            actionBD25->setChecked( true );
            break;
        case MediaSizeBluRay50Gb:
        //case 50*1024*512:
            displayWidget->setCdSize( MediaSizeBluRay50Gb );
            actionBD50->setChecked( true );
            break;
        default:
            displayWidget->setCdSize( size );
            break;
    }
}
コード例 #6
0
ファイル: k3bdatapropertiesdialog.cpp プロジェクト: KDE/k3b
void K3b::DataPropertiesDialog::loadListProperties( const QList<K3b::DataItem*>& items )
{
    m_labelIcon->setPixmap( DesktopIcon( "document-multiple", KIconLoader::SizeLarge ) );

    int files = 0;
    int folders = 0;
    KIO::filesize_t size = 0;
    K3b::Msf blocks = 0;
    for ( QList<K3b::DataItem*>::iterator it = m_dataItems.begin();
          it != m_dataItems.end(); ++it ) {
        K3b::DataItem* item = *it;
        if ( item->isFile() )
            ++files;
        else if ( item->isDir() )
            ++folders;
        blocks += item->blocks();
        size += item->size();
    }
    QString s = i18np( "One Item", "%1 Items", items.count() );
    s += " - ";
    if ( files > 0 )
        s += i18np( "One File", "%1 Files", files );
    else
        s += i18n( "No Files" );
    s += " - ";
    if ( folders > 0 )
        s += i18np( "One Folder", "%1 Folders", folders );
    else
        s += i18n( "No Folders" );
    m_multiSelectionLabel->setText( s );

    m_labelSize->setText( KIO::convertSize(size) );
    m_labelBlocks->setText( QString::number(blocks.lba()) );

    // the location of all items are the same since it is not possible to
    // select items from different folders
    // FIXME: maybe better use QString::section?
    QString location = '/' + items.first()->k3bPath();
    if( location[location.length()-1] == '/' )
        location.truncate( location.length()-1 );
    location.truncate( location.lastIndexOf('/') );
    if( location.isEmpty() )
        location = '/';
    m_labelLocation->setText( location );


    m_checkHideOnJoliet->setChecked( items.first()->hideOnJoliet() );
    for ( QList<K3b::DataItem*>::iterator it = m_dataItems.begin();
          it != m_dataItems.end(); ++it ) {
        K3b::DataItem* item = *it;
        if ( m_checkHideOnJoliet->isChecked() != item->hideOnJoliet() ) {
            m_checkHideOnJoliet->setCheckState( Qt::PartiallyChecked );
            break;
        }
    }
    m_checkHideOnRockRidge->setChecked( items.first()->hideOnRockRidge() );
    for ( QList<K3b::DataItem*>::iterator it = m_dataItems.begin();
          it != m_dataItems.end(); ++it ) {
        K3b::DataItem* item = *it;
        if ( m_checkHideOnRockRidge->isChecked() != item->hideOnRockRidge() ) {
            m_checkHideOnRockRidge->setCheckState( Qt::PartiallyChecked );
            break;
        }
    }

    int weight = items.first()->sortWeight();
    for ( QList<K3b::DataItem*>::iterator it = m_dataItems.begin();
          it != m_dataItems.end(); ++it ) {
        K3b::DataItem* item = *it;
        if ( weight != item->sortWeight() ) {
            weight = 0;
            break;
        }
    }
    m_editSortWeight->setText( QString::number( weight ) );
}
コード例 #7
0
bool K3b::operator>=( const K3b::Msf& m1, const K3b::Msf& m2 )
{
  return ( m1.lba() >= m2.lba() );
}
コード例 #8
0
bool K3b::operator<( const K3b::Msf& m1, const K3b::Msf& m2 )
{
  return ( m1.lba() < m2.lba() );
}
コード例 #9
0
bool K3b::operator==( const K3b::Msf& m1, const K3b::Msf& m2 )
{
  return ( m1.minutes() == m2.minutes() &&
	   m1.seconds() == m2.seconds() &&
	   m1.frames() == m2.frames() );
}
コード例 #10
0
K3b::Msf::Msf( const K3b::Msf& m )
  : m_minutes(m.minutes()),
    m_seconds(m.seconds()),
    m_frames(m.frames())
{
}
コード例 #11
0
ファイル: k3baudiorippingdialog.cpp プロジェクト: KDE/k3b
void K3b::AudioRippingDialog::refresh()
{
    d->viewTracks->clear();
    d->filenames.clear();

    QString baseDir = K3b::prepareDir( m_optionWidget->baseDir() );
    d->fsInfo.setPath( baseDir );

    KIO::filesize_t overallSize = 0;

    K3b::Device::Toc toc = m_medium.toc();

    if( m_optionWidget->createSingleFile() ) {
        long length = 0;
        for( QList<int>::const_iterator it = m_trackNumbers.constBegin();
             it != m_trackNumbers.constEnd(); ++it ) {
            length += ( m_checkUseIndex0->isChecked()
                        ? toc[*it].realAudioLength().lba()
                        : toc[*it].length().lba() );
        }

        QString filename;
        QString extension;
        long long fileSize = 0;
        if( m_optionWidget->encoder() == 0 ) {
            extension = "wav";
            fileSize = length * 2352 + 44;
        }
        else {
            extension = m_optionWidget->extension();
            fileSize = m_optionWidget->encoder()->fileSize( extension, length );
        }

        if( fileSize > 0 )
            overallSize = fileSize;

        filename = d->fsInfo.fixupPath( K3b::PatternParser::parsePattern( m_cddbEntry, 1,
                                                                          extension,
                                                                          m_patternWidget->playlistPattern(),
                                                                          m_patternWidget->replaceBlanks(),
                                                                          m_patternWidget->blankReplaceString() ) );

        d->addTrack( filename,
                     K3b::Msf(length).toString(),
                     fileSize < 0 ? i18n("unknown") : KIO::convertSize( fileSize ),
                     i18n("Audio") );

        d->filenames.append( baseDir + filename );

        if( m_optionWidget->createCueFile() ) {
            QString cueFileName = d->fsInfo.fixupPath( K3b::PatternParser::parsePattern( m_cddbEntry, 1,
                                                                                         QLatin1String( "cue" ),
                                                                                         m_patternWidget->playlistPattern(),
                                                                                         m_patternWidget->replaceBlanks(),
                                                                                         m_patternWidget->blankReplaceString() ) );
            d->addTrack( cueFileName, "-", "-", i18n("Cue-file") );
        }
    }
    else {
        for( int i = 0; i < m_trackNumbers.count(); ++i ) {
            int trackIndex = m_trackNumbers[i];

            QString extension;
            long long fileSize = 0;
            K3b::Msf trackLength = ( m_checkUseIndex0->isChecked()
                                     ? toc[trackIndex].realAudioLength()
                                     : toc[trackIndex].length() );
            if( m_optionWidget->encoder() == 0 ) {
                extension = "wav";
                fileSize = trackLength.audioBytes() + 44;
            }
            else {
                extension = m_optionWidget->extension();
                fileSize = m_optionWidget->encoder()->fileSize( extension, trackLength );
            }

            if( fileSize > 0 )
                overallSize += fileSize;

            if( toc[trackIndex].type() == K3b::Device::Track::TYPE_DATA ) {
                extension = ".iso";
                continue;  // TODO: find out how to rip the iso data
            }


            QString filename;

            filename = K3b::PatternParser::parsePattern( m_cddbEntry, trackIndex+1,
                                                         extension,
                                                         m_patternWidget->filenamePattern(),
                                                         m_patternWidget->replaceBlanks(),
                                                         m_patternWidget->blankReplaceString() );
            if ( filename.isEmpty() ){
                filename = i18n("Track%1", QString::number( trackIndex+1 ).rightJustified( 2, '0' ) ) + '.' + extension;
            }
            filename = d->fsInfo.fixupPath( filename );

            d->addTrack( filename,
                         trackLength.toString(),
                         fileSize < 0 ? i18n("unknown") : KIO::convertSize( fileSize ),
                         toc[trackIndex].type() == K3b::Device::Track::TYPE_AUDIO ? i18n("Audio") : i18n("Data") );

            d->filenames.append( baseDir + filename );
        }
    }

    // create playlist item
    if( m_optionWidget->createPlaylist() ) {
        QString filename = K3b::PatternParser::parsePattern( m_cddbEntry, 1,
                                                             QLatin1String( "m3u" ),
                                                             m_patternWidget->playlistPattern(),
                                                             m_patternWidget->replaceBlanks(),
                                                             m_patternWidget->blankReplaceString() );

        d->addTrack( filename, "-", "-", i18n("Playlist") );

        d->playlistFilename = d->fsInfo.fixupPath( baseDir + '/' + filename );
    }

    if( overallSize > 0 )
        m_optionWidget->setNeededSize( overallSize );
    else
        m_optionWidget->setNeededSize( 0 );
}
コード例 #12
0
ファイル: k3bmaddecoder.cpp プロジェクト: KDE/k3b
bool K3bMadDecoder::seekInternal( const K3b::Msf& pos )
{
    //
    // we need to reset the complete mad stuff
    //
    if( !initDecoderInternal() )
        return false;

    //
    // search a position
    // This is all hacking, I don't really know what I am doing here... ;)
    //
    double mp3FrameSecs = static_cast<double>(d->firstHeader.duration.seconds)
                          + static_cast<double>(d->firstHeader.duration.fraction) / static_cast<double>(MAD_TIMER_RESOLUTION);

    double posSecs = static_cast<double>(pos.totalFrames()) / 75.0;

    // seekPosition to seek after frame i
    unsigned int frame = static_cast<unsigned int>( posSecs / mp3FrameSecs );

    // Rob said: 29 frames is the theoretically max frame reservoir limit (whatever that means...)
    // it seems that mad needs at most 29 frames to get ready
    unsigned int frameReservoirProtect = ( frame > 29 ? 29 : frame );

    frame -= frameReservoirProtect;

    // seek in the input file behind the already decoded data
    d->handle->inputSeek( d->seekPositions[frame] );

    qDebug() << "(K3bMadDecoder) Seeking to frame " << frame << " with "
             << frameReservoirProtect << " reservoir frames." << endl;

    // decode some frames ignoring MAD_ERROR_BADDATAPTR errors
    unsigned int i = 1;
    while( i <= frameReservoirProtect ) {
        d->handle->fillStreamBuffer();
        if( mad_frame_decode( d->handle->madFrame, d->handle->madStream ) ) {
            if( MAD_RECOVERABLE( d->handle->madStream->error ) ) {
                if( d->handle->madStream->error == MAD_ERROR_BUFLEN )
                    continue;
                else if( d->handle->madStream->error != MAD_ERROR_BADDATAPTR ) {
                    qDebug() << "(K3bMadDecoder) Seeking: recoverable mad error ("
                             << mad_stream_errorstr(d->handle->madStream) << ")" << endl;
                    continue;
                }
                else {
                    qDebug() << "(K3bMadDecoder) Seeking: ignoring ("
                             << mad_stream_errorstr(d->handle->madStream) << ")" << endl;
                }
            }
            else
                return false;
        }

        if( i == frameReservoirProtect )  // synth only the last frame (Rob said so ;)
            mad_synth_frame( d->handle->madSynth, d->handle->madFrame );

        ++i;
    }

    return true;
}
コード例 #13
0
ファイル: k3btocfilewriter.cpp プロジェクト: franhaufer/k3b
bool K3b::TocFileWriter::save( QTextStream& t )
{
    writeHeader(t);

    if( !m_cdText.isEmpty() )
        writeGlobalCdText(t);

    //
    // see if we have multiple sessions
    //
    int sessions = 1;
    for( K3b::Device::Toc::iterator it = m_toc.begin(); it != m_toc.end(); ++it ) {
        if( (*it).session() > 1 )
            sessions = (*it).session();
    }

    if( m_sessionToWrite > sessions )
        m_sessionToWrite = 1;

    //
    // We can only hide the first track if both the first and the second track are
    // audio tracks.
    // We also can only hide the first track in the first session.
    //
    bool hideFirstTrack = m_hideFirstTrack;
    if( m_toc.count() < 2 ||
            m_toc[0].type() != K3b::Device::Track::TYPE_AUDIO ||
            m_toc[1].type() != K3b::Device::Track::TYPE_AUDIO ||
            (sessions > 1 && m_sessionToWrite != 1 ) )
        hideFirstTrack = false;


    // the dataStart will be the offset in case we do not write the first session
    K3b::Msf dataStart;

    int trackIndex = 0;
    if( hideFirstTrack ) {
        const K3b::Device::Track& hiddenTrack = m_toc[0];
        const K3b::Device::Track& track = m_toc[1];

        t << "// Track number 1 (hidden) and track number 2 (as track 1)" << endl;
        t << "TRACK AUDIO" << endl;

        if( track.copyPermitted() )
            t << "COPY" << endl;
        else
            t << "NO COPY" << endl;

        if( track.preEmphasis() )
            t << "PRE_EMPHASIS" << endl;
        else
            t << "NO PRE_EMPHASIS" << endl;

        if( !m_cdText.isEmpty() )
            writeTrackCdText( m_cdText[0], t );

        // the "hidden" file will be used as pregap for the "first" track
        t << "AUDIOFILE ";
        writeDataSource( 0, t );
        if( readFromStdin() )
            t << hiddenTrack.firstSector().toString();
        else
            t << " 0";
        t << " " << hiddenTrack.length().toString() << endl;
        t << "START" << endl; // use the whole hidden file as pregap

        // now comes the "real" first track
        t << "AUDIOFILE ";
        writeDataSource( 1, t );
        if( readFromStdin() )
            t << track.firstSector().toString() << " ";
        else
            t << "0 ";
        // no index 0 for the last track. Or should we allow this???
        if( m_toc.count() == 2 )
            t << track.length().toString();
        else
            t << track.realAudioLength().toString();
        t << endl << endl;

        trackIndex+=2;
    }
    else {
        //
        // Seek to the first track to write.
        // In case we hid the first track above it was the first track anyway.
        //
        while( m_toc[trackIndex].session() < m_sessionToWrite &&
                m_toc[trackIndex].session() > 0 )
            ++trackIndex;

        dataStart = m_toc[trackIndex].firstSector();
    }

    kDebug() << "(K3b::TocFileWriter) using offset of: " << dataStart.toString();

    while( trackIndex < m_toc.count() ) {
        if( m_toc[trackIndex].session() == 0 || m_toc[trackIndex].session() == m_sessionToWrite )
            writeTrack( trackIndex, dataStart, t );
        trackIndex++;
    }

    return ( t.status() == QTextStream::Ok );
}