File indexing completed on 2024-05-12 04:51:01
0001 /* 0002 SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "k3baudiomaxspeedjob.h" 0007 #include "k3baudiotrack.h" 0008 #include "k3baudiodatasource.h" 0009 #include "k3baudiodoc.h" 0010 #include "k3baudiocdtracksource.h" 0011 #include "k3baudiodatasourceiterator.h" 0012 #include "k3bdevice.h" 0013 #include "k3bthread.h" 0014 #include "k3b_i18n.h" 0015 0016 #include <QDateTime> 0017 #include <QDebug> 0018 #include <QIODevice> 0019 #include <QScopedPointer> 0020 #include <QElapsedTimer> 0021 0022 0023 class K3b::AudioMaxSpeedJob::Private 0024 { 0025 public: 0026 int speedTest( K3b::AudioDataSource* source, QIODevice& sourceReader ); 0027 int maxSpeedByMedia() const; 0028 0029 int maxSpeed; 0030 K3b::AudioDoc* doc; 0031 char* buffer; 0032 }; 0033 0034 0035 // returns the amount of data read from this source 0036 int K3b::AudioMaxSpeedJob::Private::speedTest( K3b::AudioDataSource* source, QIODevice& sourceReader ) 0037 { 0038 // 0039 // in case of an audio track source we only test when the cd is inserted since asking the user would 0040 // confuse him a lot. 0041 // 0042 // FIXME: there is still the problem of the spin up time. 0043 // 0044 if( K3b::AudioCdTrackSource* cdts = dynamic_cast<K3b::AudioCdTrackSource*>( source ) ) { 0045 if( K3b::Device::Device* dev = cdts->searchForAudioCD() ) { 0046 cdts->setDevice( dev ); 0047 } 0048 else { 0049 qDebug() << "(K3b::AudioMaxSpeedJob) ignoring audio cd track source."; 0050 return 0; 0051 } 0052 } 0053 0054 QElapsedTimer t; 0055 qint64 dataRead = 0; 0056 qint64 r = 0; 0057 0058 // start the timer 0059 t.start(); 0060 0061 // read ten seconds of audio data. This is some value which seemed about right. :) 0062 while( dataRead < 2352*75*10 && (r = sourceReader.read( buffer, 2352LL*10LL )) > 0 ) { 0063 dataRead += r; 0064 } 0065 0066 // elapsed millisec 0067 int usedT = t.elapsed(); 0068 0069 if( r < 0 ) { 0070 qDebug() << "(K3b::AudioMaxSpeedJob) read failure."; 0071 return -1; 0072 } 0073 0074 // KB/sec (add 1 millisecond to avoid division by 0) 0075 int throughput = (dataRead*1000+usedT)/(usedT+1)/1024; 0076 qDebug() << "(K3b::AudioMaxSpeedJob) throughput: " << throughput 0077 << " (" << dataRead << "/" << usedT << ")" << Qt::endl; 0078 0079 0080 return throughput; 0081 } 0082 0083 0084 int K3b::AudioMaxSpeedJob::Private::maxSpeedByMedia() const 0085 { 0086 int s = 0; 0087 0088 QList<int> speeds = doc->burner()->determineSupportedWriteSpeeds(); 0089 // simply use what we have and let the writer decide if the speeds are empty 0090 if( !speeds.isEmpty() ) { 0091 // start with the highest speed and go down the list until we are below our max 0092 QList<int>::const_iterator it = speeds.constEnd(); 0093 --it; 0094 while( *it > maxSpeed && it != speeds.constBegin() ) 0095 --it; 0096 0097 // this is the first valid speed or the lowest supported one 0098 s = *it; 0099 qDebug() << "(K3b::AudioMaxSpeedJob) using speed factor: " << (s/175); 0100 } 0101 0102 return s; 0103 } 0104 0105 0106 0107 0108 K3b::AudioMaxSpeedJob::AudioMaxSpeedJob( K3b::AudioDoc* doc, K3b::JobHandler* jh, QObject* parent ) 0109 : K3b::ThreadJob( jh, parent ), 0110 d( new Private() ) 0111 { 0112 d->doc = doc; 0113 d->buffer = new char[2352*10]; 0114 } 0115 0116 0117 K3b::AudioMaxSpeedJob::~AudioMaxSpeedJob() 0118 { 0119 delete [] d->buffer; 0120 delete d; 0121 } 0122 0123 0124 int K3b::AudioMaxSpeedJob::maxSpeed() const 0125 { 0126 return d->maxSpeedByMedia(); 0127 } 0128 0129 0130 bool K3b::AudioMaxSpeedJob::run() 0131 { 0132 qDebug(); 0133 0134 K3b::AudioDataSourceIterator it( d->doc ); 0135 0136 // count sources for minimal progress info 0137 int numSources = 0; 0138 int sourcesDone = 0; 0139 while( it.current() ) { 0140 ++numSources; 0141 it.next(); 0142 } 0143 0144 bool success = true; 0145 d->maxSpeed = 175*1000; 0146 it.first(); 0147 0148 while( it.current() && !canceled() ) { 0149 QScopedPointer<QIODevice> sourceReader( it.current()->createReader() ); 0150 0151 if( !sourceReader->open( QIODevice::ReadOnly ) ) { 0152 qDebug() << "Cannot open source reader!"; 0153 success = false; 0154 break; 0155 } 0156 0157 // read some data 0158 int speed = d->speedTest( it.current(), *sourceReader ); 0159 0160 ++sourcesDone; 0161 emit percent( 100*numSources/sourcesDone ); 0162 0163 if( speed < 0 ) { 0164 success = false; 0165 break; 0166 } 0167 else if( speed > 0 ) { 0168 // update the max speed 0169 d->maxSpeed = qMin( d->maxSpeed, speed ); 0170 } 0171 0172 it.next(); 0173 } 0174 0175 if( canceled() ) { 0176 success = false; 0177 } 0178 0179 if( success ) 0180 qDebug() << "(K3b::AudioMaxSpeedJob) max speed: " << d->maxSpeed; 0181 0182 return success; 0183 } 0184 0185 #include "moc_k3baudiomaxspeedjob.cpp"