File indexing completed on 2025-02-16 07:39:26
0001 /* 0002 SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "k3baudiosessionreadingjob.h" 0008 0009 #include "k3bthread.h" 0010 #include "k3btoc.h" 0011 #include "k3bcdparanoialib.h" 0012 #include "k3bwavefilewriter.h" 0013 #include "k3bglobals.h" 0014 #include "k3bdevice.h" 0015 #include "k3bcore.h" 0016 #include "k3b_i18n.h" 0017 0018 #include <QDebug> 0019 0020 #include <unistd.h> 0021 0022 0023 class K3b::AudioSessionReadingJob::Private 0024 { 0025 public: 0026 Private(); 0027 ~Private(); 0028 0029 QIODevice* ioDev; 0030 K3b::CdparanoiaLib* paranoia; 0031 K3b::Device::Device* device; 0032 K3b::Device::Toc toc; 0033 K3b::WaveFileWriter* waveFileWriter; 0034 QStringList filenames; 0035 int paranoiaMode; 0036 int retries; 0037 bool neverSkip; 0038 }; 0039 0040 0041 K3b::AudioSessionReadingJob::Private::Private() 0042 : ioDev( 0 ), 0043 paranoia(0), 0044 waveFileWriter(0), 0045 paranoiaMode(0), 0046 retries(50), 0047 neverSkip(false) 0048 { 0049 } 0050 0051 0052 K3b::AudioSessionReadingJob::Private::~Private() 0053 { 0054 delete waveFileWriter; 0055 delete paranoia; 0056 } 0057 0058 0059 K3b::AudioSessionReadingJob::AudioSessionReadingJob( K3b::JobHandler* jh, QObject* parent ) 0060 : K3b::ThreadJob( jh, parent ), 0061 d( new Private() ) 0062 { 0063 } 0064 0065 0066 K3b::AudioSessionReadingJob::~AudioSessionReadingJob() 0067 { 0068 delete d; 0069 } 0070 0071 0072 void K3b::AudioSessionReadingJob::setDevice( K3b::Device::Device* dev ) 0073 { 0074 d->device = dev; 0075 d->toc = K3b::Device::Toc(); 0076 } 0077 0078 0079 void K3b::AudioSessionReadingJob::setToc( const K3b::Device::Toc& toc ) 0080 { 0081 d->toc = toc; 0082 } 0083 0084 0085 void K3b::AudioSessionReadingJob::writeTo( QIODevice* ioDev ) 0086 { 0087 d->ioDev = ioDev; 0088 } 0089 0090 void K3b::AudioSessionReadingJob::setImageNames( const QStringList& l ) 0091 { 0092 d->filenames = l; 0093 d->ioDev = 0; 0094 } 0095 0096 0097 void K3b::AudioSessionReadingJob::setParanoiaMode( int m ) 0098 { 0099 d->paranoiaMode = m; 0100 } 0101 0102 0103 void K3b::AudioSessionReadingJob::setReadRetries( int r ) 0104 { 0105 d->retries = r; 0106 } 0107 0108 void K3b::AudioSessionReadingJob::setNeverSkip( bool b ) 0109 { 0110 d->neverSkip = b; 0111 } 0112 0113 0114 void K3b::AudioSessionReadingJob::start() 0115 { 0116 k3bcore->blockDevice( d->device ); 0117 K3b::ThreadJob::start(); 0118 } 0119 0120 0121 void K3b::AudioSessionReadingJob::jobFinished( bool success ) 0122 { 0123 k3bcore->unblockDevice( d->device ); 0124 K3b::ThreadJob::jobFinished( success ); 0125 } 0126 0127 0128 bool K3b::AudioSessionReadingJob::run() 0129 { 0130 if( !d->paranoia ) 0131 d->paranoia = K3b::CdparanoiaLib::create(); 0132 0133 if( !d->paranoia ) { 0134 emit infoMessage( i18n("Could not load libcdparanoia."), K3b::Job::MessageError ); 0135 return false; 0136 } 0137 0138 if( d->toc.isEmpty() ) 0139 d->toc = d->device->readToc(); 0140 0141 if( !d->paranoia->initParanoia( d->device, d->toc ) ) { 0142 emit infoMessage( i18n("Could not open device %1", d->device->blockDeviceName()), 0143 K3b::Job::MessageError ); 0144 return false; 0145 } 0146 0147 if( !d->paranoia->initReading() ) { 0148 emit infoMessage( i18n("Error while initializing audio ripping."), K3b::Job::MessageError ); 0149 return false; 0150 } 0151 0152 d->device->block( true ); 0153 0154 // init settings 0155 d->paranoia->setMaxRetries( d->retries ); 0156 d->paranoia->setParanoiaMode( d->paranoiaMode ); 0157 d->paranoia->setNeverSkip( d->neverSkip ); 0158 0159 bool writeError = false; 0160 unsigned int trackNum = 1; 0161 unsigned int currentTrack = 0; 0162 unsigned long trackRead = 0; 0163 unsigned long totalRead = 0; 0164 unsigned int lastTrackPercent = 0; 0165 unsigned int lastTotalPercent = 0; 0166 bool newTrack = true; 0167 int status = 0; 0168 char* buffer = 0; 0169 while( !canceled() && (buffer = d->paranoia->read( &status, &trackNum, !d->ioDev /*when writing to a wav be want little endian */ )) ) { 0170 0171 if( currentTrack != trackNum ) { 0172 emit nextTrack( trackNum, d->paranoia->toc().count() ); 0173 trackRead = 0; 0174 lastTrackPercent = 0; 0175 0176 currentTrack = trackNum; 0177 newTrack = true; 0178 } 0179 0180 if( d->ioDev ) { 0181 if( d->ioDev->write( buffer, CD_FRAMESIZE_RAW ) != CD_FRAMESIZE_RAW ) { 0182 qDebug() << "(K3b::AudioSessionCopyJob::WorkThread) error while writing to device " << d->ioDev; 0183 writeError = true; 0184 break; 0185 } 0186 } 0187 else { 0188 if( newTrack ) { 0189 newTrack = false; 0190 0191 if( !d->waveFileWriter ) 0192 d->waveFileWriter = new K3b::WaveFileWriter(); 0193 0194 if( d->filenames.count() < ( int )currentTrack ) { 0195 qDebug() << "(K3b::AudioSessionCopyJob) not enough image filenames given: " << currentTrack; 0196 writeError = true; 0197 break; 0198 } 0199 0200 if( !d->waveFileWriter->open( d->filenames[currentTrack-1] ) ) { 0201 emit infoMessage( i18n("Unable to open '%1' for writing.", d->filenames[currentTrack-1]), K3b::Job::MessageError ); 0202 writeError = true; 0203 break; 0204 } 0205 } 0206 0207 d->waveFileWriter->write( buffer, 0208 CD_FRAMESIZE_RAW, 0209 K3b::WaveFileWriter::LittleEndian ); 0210 } 0211 0212 trackRead++; 0213 totalRead++; 0214 0215 unsigned int trackPercent = 100 * trackRead / d->toc[currentTrack-1].length().lba(); 0216 if( trackPercent > lastTrackPercent ) { 0217 lastTrackPercent = trackPercent; 0218 emit subPercent( lastTrackPercent ); 0219 } 0220 unsigned int totalPercent = 100 * totalRead / d->paranoia->rippedDataLength(); 0221 if( totalPercent > lastTotalPercent ) { 0222 lastTotalPercent = totalPercent; 0223 emit percent( lastTotalPercent ); 0224 } 0225 } 0226 0227 if( d->waveFileWriter ) 0228 d->waveFileWriter->close(); 0229 0230 d->paranoia->close(); 0231 0232 d->device->block( false ); 0233 0234 if( status != K3b::CdparanoiaLib::S_OK ) { 0235 emit infoMessage( i18n("Unrecoverable error while ripping track %1.", trackNum), K3b::Job::MessageError ); 0236 return false; 0237 } 0238 0239 return !writeError && !canceled(); 0240 } 0241 0242 #include "moc_k3baudiosessionreadingjob.cpp"