|
|
|
/*
|
|
|
|
*
|
|
|
|
* $Id: k3baudiosessionreadingjob.cpp 619556 2007-01-03 17:38:12Z trueg $
|
|
|
|
* Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
|
|
|
|
*
|
|
|
|
* This file is part of the K3b project.
|
|
|
|
* Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
|
|
|
|
*
|
|
|
|
* 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 "k3baudiosessionreadingjob.h"
|
|
|
|
|
|
|
|
#include <k3bthread.h>
|
|
|
|
#include <k3btoc.h>
|
|
|
|
#include <k3bcdparanoialib.h>
|
|
|
|
#include <k3bwavefilewriter.h>
|
|
|
|
#include <k3bglobals.h>
|
|
|
|
#include <k3bdevice.h>
|
|
|
|
#include <k3bcore.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
|
|
class K3bAudioSessionReadingJob::WorkThread : public K3bThread
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
WorkThread();
|
|
|
|
~WorkThread();
|
|
|
|
|
|
|
|
void init();
|
|
|
|
void run();
|
|
|
|
void cancel();
|
|
|
|
|
|
|
|
bool canceled;
|
|
|
|
|
|
|
|
int fd;
|
|
|
|
K3bCdparanoiaLib* paranoia;
|
|
|
|
K3bDevice::Device* device;
|
|
|
|
K3bDevice::Toc toc;
|
|
|
|
K3bWaveFileWriter* waveFileWriter;
|
|
|
|
TQStringList filenames;
|
|
|
|
int paranoiaMode;
|
|
|
|
int retries;
|
|
|
|
bool neverSkip;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
K3bAudioSessionReadingJob::WorkThread::WorkThread()
|
|
|
|
: K3bThread(),
|
|
|
|
fd(-1),
|
|
|
|
paranoia(0),
|
|
|
|
waveFileWriter(0),
|
|
|
|
paranoiaMode(0),
|
|
|
|
retries(50),
|
|
|
|
neverSkip(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bAudioSessionReadingJob::WorkThread::~WorkThread()
|
|
|
|
{
|
|
|
|
delete waveFileWriter;
|
|
|
|
delete paranoia;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::WorkThread::init()
|
|
|
|
{
|
|
|
|
canceled = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::WorkThread::run()
|
|
|
|
{
|
|
|
|
if( !paranoia )
|
|
|
|
paranoia = K3bCdparanoiaLib::create();
|
|
|
|
|
|
|
|
if( !paranoia ) {
|
|
|
|
emitInfoMessage( i18n("Could not load libcdparanoia."), K3bJob::ERROR );
|
|
|
|
emitFinished(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( toc.isEmpty() )
|
|
|
|
toc = device->readToc();
|
|
|
|
|
|
|
|
if( !paranoia->initParanoia( device, toc ) ) {
|
|
|
|
emitInfoMessage( i18n("Could not open device %1").arg(device->blockDeviceName()),
|
|
|
|
K3bJob::ERROR );
|
|
|
|
emitFinished(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !paranoia->initReading() ) {
|
|
|
|
emitInfoMessage( i18n("Error while initializing audio ripping."), K3bJob::ERROR );
|
|
|
|
emitFinished(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
device->block( true );
|
|
|
|
|
|
|
|
// init settings
|
|
|
|
paranoia->setMaxRetries( retries );
|
|
|
|
paranoia->setParanoiaMode( paranoiaMode );
|
|
|
|
paranoia->setNeverSkip( neverSkip );
|
|
|
|
|
|
|
|
bool writeError = false;
|
|
|
|
unsigned int trackNum = 1;
|
|
|
|
unsigned int currentTrack = 0;
|
|
|
|
unsigned long trackRead = 0;
|
|
|
|
unsigned long totalRead = 0;
|
|
|
|
unsigned int lastTrackPercent = 0;
|
|
|
|
unsigned int lastTotalPercent = 0;
|
|
|
|
bool newTrack = true;
|
|
|
|
int status = 0;
|
|
|
|
char* buffer = 0;
|
|
|
|
while( !canceled && (buffer = paranoia->read( &status, &trackNum, fd == -1 /*when writing to a wav be want little endian */ )) ) {
|
|
|
|
|
|
|
|
if( currentTrack != trackNum ) {
|
|
|
|
emitNextTrack( trackNum, paranoia->toc().count() );
|
|
|
|
trackRead = 0;
|
|
|
|
lastTrackPercent = 0;
|
|
|
|
|
|
|
|
currentTrack = trackNum;
|
|
|
|
newTrack = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fd > 0 ) {
|
|
|
|
if( ::write( fd, buffer, CD_FRAMESIZE_RAW ) != CD_FRAMESIZE_RAW ) {
|
|
|
|
kdDebug() << "(K3bAudioSessionCopyJob::WorkThread) error while writing to fd " << fd << endl;
|
|
|
|
writeError = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if( newTrack ) {
|
|
|
|
newTrack = false;
|
|
|
|
|
|
|
|
if( !waveFileWriter )
|
|
|
|
waveFileWriter = new K3bWaveFileWriter();
|
|
|
|
|
|
|
|
if( filenames.count() < currentTrack ) {
|
|
|
|
kdDebug() << "(K3bAudioSessionCopyJob) not enough image filenames given: " << currentTrack << endl;
|
|
|
|
writeError = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !waveFileWriter->open( filenames[currentTrack-1] ) ) {
|
|
|
|
emitInfoMessage( i18n("Unable to open '%1' for writing.").arg(filenames[currentTrack-1]), K3bJob::ERROR );
|
|
|
|
writeError = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
waveFileWriter->write( buffer,
|
|
|
|
CD_FRAMESIZE_RAW,
|
|
|
|
K3bWaveFileWriter::LittleEndian );
|
|
|
|
}
|
|
|
|
|
|
|
|
trackRead++;
|
|
|
|
totalRead++;
|
|
|
|
|
|
|
|
unsigned int trackPercent = 100 * trackRead / toc[currentTrack-1].length().lba();
|
|
|
|
if( trackPercent > lastTrackPercent ) {
|
|
|
|
lastTrackPercent = trackPercent;
|
|
|
|
emitSubPercent( lastTrackPercent );
|
|
|
|
}
|
|
|
|
unsigned int totalPercent = 100 * totalRead / paranoia->rippedDataLength();
|
|
|
|
if( totalPercent > lastTotalPercent ) {
|
|
|
|
lastTotalPercent = totalPercent;
|
|
|
|
emitPercent( lastTotalPercent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( waveFileWriter )
|
|
|
|
waveFileWriter->close();
|
|
|
|
|
|
|
|
paranoia->close();
|
|
|
|
|
|
|
|
device->block( false );
|
|
|
|
|
|
|
|
if( status != K3bCdparanoiaLib::S_OK ) {
|
|
|
|
emitInfoMessage( i18n("Unrecoverable error while ripping track %1.").arg(trackNum), K3bJob::ERROR );
|
|
|
|
emitFinished(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
emitFinished( !writeError & !canceled );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::WorkThread::cancel()
|
|
|
|
{
|
|
|
|
canceled = true;
|
|
|
|
// FIXME: add backup killing like in the audio ripping and make sure to close paranoia
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
K3bAudioSessionReadingJob::K3bAudioSessionReadingJob( K3bJobHandler* jh, TQObject* parent, const char* name )
|
|
|
|
: K3bThreadJob( jh, parent, name )
|
|
|
|
{
|
|
|
|
m_thread = new WorkThread();
|
|
|
|
setThread( m_thread );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
K3bAudioSessionReadingJob::~K3bAudioSessionReadingJob()
|
|
|
|
{
|
|
|
|
delete m_thread;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::setDevice( K3bDevice::Device* dev )
|
|
|
|
{
|
|
|
|
m_thread->device = dev;
|
|
|
|
m_thread->toc = K3bDevice::Toc();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::setToc( const K3bDevice::Toc& toc )
|
|
|
|
{
|
|
|
|
m_thread->toc = toc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::writeToFd( int fd )
|
|
|
|
{
|
|
|
|
m_thread->fd = fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::setImageNames( const TQStringList& l )
|
|
|
|
{
|
|
|
|
m_thread->filenames = l;
|
|
|
|
m_thread->fd = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::setParanoiaMode( int m )
|
|
|
|
{
|
|
|
|
m_thread->paranoiaMode = m;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::setReadRetries( int r )
|
|
|
|
{
|
|
|
|
m_thread->retries = r;
|
|
|
|
}
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::setNeverSkip( bool b )
|
|
|
|
{
|
|
|
|
m_thread->neverSkip = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::start()
|
|
|
|
{
|
|
|
|
k3bcore->blockDevice( m_thread->device );
|
|
|
|
K3bThreadJob::start();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void K3bAudioSessionReadingJob::cleanupJob( bool success )
|
|
|
|
{
|
|
|
|
Q_UNUSED( success );
|
|
|
|
k3bcore->unblockDevice( m_thread->device );
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "k3baudiosessionreadingjob.moc"
|