File indexing completed on 2024-05-12 04:51:01

0001 /*
0002     SPDX-FileCopyrightText: 2010 Michal Malek <michalm@jabster.pl>
0003     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "k3baudioimager.h"
0009 #include "k3baudiodoc.h"
0010 #include "k3baudiojobtempdata.h"
0011 #include "k3baudiotrack.h"
0012 #include "k3baudiotrackreader.h"
0013 #include "k3baudiodatasource.h"
0014 #include "k3bthread.h"
0015 #include "k3bwavefilewriter.h"
0016 #include "k3b_i18n.h"
0017 
0018 #include <QDebug>
0019 #include <QIODevice>
0020 #include <QFile>
0021 
0022 #include <unistd.h>
0023 
0024 
0025 class K3b::AudioImager::Private
0026 {
0027 public:
0028     Private()
0029         : ioDev(0) {
0030     }
0031 
0032     QIODevice* ioDev;
0033     AudioImager::ErrorType lastError;
0034     AudioDoc* doc;
0035     AudioJobTempData* tempData;
0036 };
0037 
0038 
0039 
0040 K3b::AudioImager::AudioImager( AudioDoc* doc, AudioJobTempData* tempData, JobHandler* jh, QObject* parent )
0041     : K3b::ThreadJob( jh, parent ),
0042       d( new Private() )
0043 {
0044     d->doc = doc;
0045     d->tempData = tempData;
0046 }
0047 
0048 
0049 K3b::AudioImager::~AudioImager()
0050 {
0051     delete d;
0052 }
0053 
0054 
0055 void K3b::AudioImager::writeTo( QIODevice* dev )
0056 {
0057     d->ioDev = dev;
0058 }
0059 
0060 
0061 K3b::AudioImager::ErrorType K3b::AudioImager::lastErrorType() const
0062 {
0063     return d->lastError;
0064 }
0065 
0066 
0067 bool K3b::AudioImager::run()
0068 {
0069     d->lastError = K3b::AudioImager::ERROR_UNKNOWN;
0070 
0071     K3b::WaveFileWriter waveFileWriter;
0072 
0073     qint64 totalSize = d->doc->length().audioBytes();
0074     qint64 totalRead = 0;
0075     char buffer[2352 * 10];
0076 
0077     for( AudioTrack* track = d->doc->firstTrack(); track != 0; track = track->next() ) {
0078 
0079         emit nextTrack( track->trackNumber(), d->doc->numOfTracks() );
0080 
0081         //
0082         // Create track reader
0083         //
0084         AudioTrackReader trackReader( *track );
0085         if( !trackReader.open() ) {
0086             emit infoMessage( i18n("Unable to read track %1.", track->trackNumber()), K3b::Job::MessageError );
0087             return false;
0088         }
0089 
0090         //
0091         // Initialize the reading
0092         //
0093         qint64 read = 0;
0094         qint64 trackRead = 0;
0095 
0096         //
0097         // Create the image file
0098         //
0099         if( !d->ioDev ) {
0100             QString imageFile = d->tempData->bufferFileName( track );
0101             if( !waveFileWriter.open( imageFile ) ) {
0102                 emit infoMessage( i18n("Could not open %1 for writing", imageFile), K3b::Job::MessageError );
0103                 return false;
0104             }
0105         }
0106 
0107         //
0108         // Read data from the track
0109         //
0110         while( !trackReader.atEnd() && (read = trackReader.read( buffer, sizeof(buffer) )) > 0 ) {
0111             if( !d->ioDev ) {
0112                 waveFileWriter.write( buffer, read, K3b::WaveFileWriter::BigEndian );
0113             }
0114             else {
0115                 qint64 w = d->ioDev->write( buffer, read );
0116                 if ( w != read ) {
0117                     qDebug() << "(K3b::AudioImager::WorkThread) writing to device" << d->ioDev << "failed:" << read << w;
0118                     d->lastError = K3b::AudioImager::ERROR_FD_WRITE;
0119                     return false;
0120                 }
0121             }
0122 
0123             if( canceled() ) {
0124                 return false;
0125             }
0126 
0127             //
0128             // Emit progress
0129             //
0130             totalRead += read;
0131             trackRead += read;
0132 
0133             emit subPercent( 100LL*trackRead/trackReader.size() );
0134             emit percent( 100LL*totalRead/totalSize );
0135             emit processedSubSize( trackRead/1024LL/1024LL, trackReader.size()/1024LL/1024LL );
0136             emit processedSize( totalRead/1024LL/1024LL, totalSize/1024LL/1024LL );
0137         }
0138 
0139         if( read < 0 ) {
0140             emit infoMessage( i18n("Error while decoding track %1.", track->trackNumber()), K3b::Job::MessageError );
0141             qDebug() << "(K3b::AudioImager::WorkThread) read error on track " << track->trackNumber()
0142                      << " at pos " << K3b::Msf(trackRead/2352) << Qt::endl;
0143             d->lastError = K3b::AudioImager::ERROR_DECODING_TRACK;
0144             return false;
0145         }
0146     }
0147 
0148     return true;
0149 }
0150 
0151 #include "moc_k3baudioimager.cpp"