diff options
Diffstat (limited to 'libk3b/jobs/k3bcdda2wavreader.cpp')
-rw-r--r-- | libk3b/jobs/k3bcdda2wavreader.cpp | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/libk3b/jobs/k3bcdda2wavreader.cpp b/libk3b/jobs/k3bcdda2wavreader.cpp new file mode 100644 index 0000000..3df87d3 --- /dev/null +++ b/libk3b/jobs/k3bcdda2wavreader.cpp @@ -0,0 +1,254 @@ +/* + * + * $Id: k3bcdda2wavreader.cpp 619556 2007-01-03 17:38:12Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include "k3bcdda2wavreader.h" + +#include <k3bexternalbinmanager.h> +#include <k3bdevice.h> +#include <k3bdevicemanager.h> +#include <k3bcore.h> +#include <k3bprocess.h> + +#include <kdebug.h> +#include <klocale.h> + +#include <qvaluevector.h> +#include <qregexp.h> + + +class K3bCdda2wavReader::Private +{ +public: + Private() + : cdda2wavBin(0), + process(0), + cancaled(false), + running(false), + fdToWriteTo(-1) { + } + + const K3bExternalBin* cdda2wavBin; + K3bProcess* process; + + bool cancaled; + bool running; + + int fdToWriteTo; + + int currentTrack; + QValueVector<int> trackOffsets; +}; + + +K3bCdda2wavReader::K3bCdda2wavReader( QObject* parent, const char* name ) + : K3bJob( parent, name ) +{ + d = new Private(); +} + + +K3bCdda2wavReader::~K3bCdda2wavReader() +{ + delete d->process; + delete d; +} + + +bool K3bCdda2wavReader::active() const +{ + return d->running; +} + + +void K3bCdda2wavReader::writeToFd( int fd ) +{ + d->fdToWriteTo = fd; +} + + +void K3bCdda2wavReader::start() +{ + start( false ); +} + + +void K3bCdda2wavReader::start( bool onlyInfo ) +{ + d->running = true; + d->cancaled = false; + d->currentTrack = 1; + d->trackOffsets.clear(); + + jobStarted(); + + d->cdda2wavBin = k3bcore->externalBinManager()->binObject( "cdda2wav" ); + if( !d->cdda2wavBin ) { + emit infoMessage( i18n("Could not find %1 executable.").arg("cdda2wav"), ERROR ); + jobFinished(false); + d->running = false; + return; + } + + // prepare the process + delete d->process; + d->process = new K3bProcess(); + d->process->setSplitStdout(true); + d->process->setSuppressEmptyLines(true); + d->process->setWorkingDirectory( m_imagePath ); + connect( d->process, SIGNAL(stdoutLine(const QString&)), this, SLOT(slotProcessLine(const QString&)) ); + connect( d->process, SIGNAL(stderrLine(const QString&)), this, SLOT(slotProcessLine(const QString&)) ); + connect( d->process, SIGNAL(processExited(KProcess*)), this, SLOT(slotProcessExited(KProcess*)) ); + + // create the command line + *d->process << d->cdda2wavBin->path; + *d->process << "-vall" << ( d->cdda2wavBin->hasFeature( "gui" ) ? "-gui" : "-g" ); + if( d->cdda2wavBin->hasFeature( "dev" ) ) + *d->process << QString("dev=%1").arg(K3bDevice::externalBinDeviceParameter(m_device, d->cdda2wavBin)); + else + *d->process << "-D" << K3bDevice::externalBinDeviceParameter(m_device, d->cdda2wavBin); + *d->process << ( d->cdda2wavBin->hasFeature( "bulk" ) ? "-bulk" : "-B" ); + if( onlyInfo ) + *d->process << ( d->cdda2wavBin->hasFeature( "info-only" ) ? "-info-only" : "-J" ); + else if( d->fdToWriteTo != -1 ) + *d->process << ( d->cdda2wavBin->hasFeature( "no-infofile" ) ? "-no-infofile" : "-H" ); + + // additional user parameters from config + const QStringList& params = d->cdda2wavBin->userParameters(); + for( QStringList::const_iterator it = params.begin(); it != params.end(); ++it ) + *d->process << *it; + + // start the thing + if( !d->process->start( KProcess::NotifyOnExit, KProcess::All ) ) { + // something went wrong when starting the program + // it "should" be the executable + kdDebug() << "(K3bCdda2wavReader) could not start cdda2wav" << endl; + emit infoMessage( i18n("Could not start %1.").arg("cdda2wav"), K3bJob::ERROR ); + d->running = false; + jobFinished(false); + } +} + + +void K3bCdda2wavReader::cancel() +{ + if( d->running ) { + d->cancaled = true; + if( d->process ) + if( d->process->isRunning() ) + d->process->kill(); + } +} + + +void K3bCdda2wavReader::slotProcessLine( const QString& line ) +{ + // Tracks:11 44:37.30 + // CDINDEX discid: ZvzBXv614ACgzn1bWWy107cs0nA- + // CDDB discid: 0x8a0a730b + // CD-Text: not detected + // CD-Extra: not detected + // Album title: '' from '' + // T01: 0 3:39.70 audio linear copydenied stereo title '' from '' + // T02: 16495 3:10.47 audio linear copydenied stereo title '' from '' + // T03: 30792 3:30.00 audio linear copydenied stereo title '' from '' + // T04: 46542 4:05.05 audio linear copydenied stereo title '' from '' + // T05: 64922 3:44.35 audio linear copydenied stereo title '' from '' + // T06: 81757 4:36.45 audio linear copydenied stereo title '' from '' + // T07: 102502 3:59.30 audio linear copydenied stereo title '' from '' + // T08: 120457 5:24.30 audio linear copydenied stereo title '' from '' + // T09: 144787 3:26.28 audio linear copydenied stereo title '' from '' + // T10: 160265 4:07.20 audio linear copydenied stereo title '' from '' + // T11: 178810 4:51.20 audio linear copydenied stereo title '' from '' + + // percent_done: + // 100% track 1 successfully recorded + // 100% track 2 successfully recorded + // 100% track 3 successfully recorded + + + + static QRegExp rx( "T\\d\\d:" ); + if( rx.exactMatch( line.left(4) ) || line.startsWith( "Leadout" ) ) { + int pos = line.find( " " ); + int endpos = line.find( QRegExp( "\\d" ), pos ); + endpos = line.find( " ", endpos ); + bool ok; + int offset = line.mid( pos, endpos-pos ).toInt(&ok); + if( ok ) + d->trackOffsets.append( offset ); + else + kdDebug() << "(K3bCdda2wavReader) track offset parsing error: '" << line.mid( pos, endpos-pos ) << "'" << endl; + } + + else if( line.startsWith( "percent_done" ) ) { + // the reading starts + d->currentTrack = 1; + emit nextTrack( d->currentTrack, d->trackOffsets.count() ); + } + + else if( line.contains("successfully recorded") ) { + d->currentTrack++; + emit nextTrack( d->currentTrack, d->trackOffsets.count() ); + } + + else if( line.contains("%") ) { + // parse progress + bool ok; + int p = line.left(3).toInt(&ok); + if( ok ) { + emit subPercent( p ); + + int overall = d->trackOffsets[d->currentTrack-1]; + int tSize = d->trackOffsets[d->currentTrack] - d->trackOffsets[d->currentTrack-1]; + overall += (tSize*p/100); + + emit percent( overall*100/d->trackOffsets[d->trackOffsets.count()-1] ); + } + else + kdDebug() << "(K3bCdda2wavReader) track progress parsing error: '" << line.left(3) << "'" << endl; + } +} + + +void K3bCdda2wavReader::slotProcessExited( KProcess* p ) +{ + d->running = false; + + if( d->cancaled ) { + emit canceled(); + jobFinished(false); + return; + } + + if( p->normalExit() ) { + // TODO: improve this + + if( p->exitStatus() == 0 ) { + jobFinished( true ); + } + else { + emit infoMessage( i18n("%1 returned an unknown error (code %2).") + .arg("Cdda2wav").arg(p->exitStatus()), ERROR ); + jobFinished( false ); + } + } + else { + emit infoMessage( i18n("%1 did not exit cleanly.").arg("Cdda2wav"), + ERROR ); + jobFinished( false ); + } +} + +#include "k3bcdda2wavreader.moc" |