summaryrefslogtreecommitdiffstats
path: root/libk3b/jobs/k3baudiosessionreadingjob.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libk3b/jobs/k3baudiosessionreadingjob.cpp')
-rw-r--r--libk3b/jobs/k3baudiosessionreadingjob.cpp278
1 files changed, 278 insertions, 0 deletions
diff --git a/libk3b/jobs/k3baudiosessionreadingjob.cpp b/libk3b/jobs/k3baudiosessionreadingjob.cpp
new file mode 100644
index 0000000..f4ac550
--- /dev/null
+++ b/libk3b/jobs/k3baudiosessionreadingjob.cpp
@@ -0,0 +1,278 @@
+/*
+ *
+ * $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;
+ QStringList 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, QObject* 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 QStringList& 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"