/* * * $Id: k3baudiomaxspeedjob.cpp 619556 2007-01-03 17:38:12Z trueg $ * Copyright (C) 2005 Sebastian Trueg * * This file is part of the K3b project. * Copyright (C) 1998-2007 Sebastian Trueg * * 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 "k3baudiomaxspeedjob.h" #include "k3baudiotrack.h" #include "k3baudiodatasource.h" #include "k3baudiodoc.h" #include "k3baudiocdtracksource.h" #include "k3baudiodatasourceiterator.h" #include #include #include #include #include class K3bAudioMaxSpeedJob::WorkThread : public K3bThread { public: WorkThread( K3bAudioDoc* doc ); ~WorkThread(); void run(); int speedTest( K3bAudioDataSource* source ); void cancel(); int maxSpeedByMedia() const; int maxSpeed; private: K3bAudioDoc* m_doc; bool m_canceled; char* m_buffer; }; K3bAudioMaxSpeedJob::WorkThread::WorkThread( K3bAudioDoc* doc ) : K3bThread(), m_doc(doc), m_canceled(false) { m_buffer = new char[2352*10]; } K3bAudioMaxSpeedJob::WorkThread::~WorkThread() { delete [] m_buffer; } void K3bAudioMaxSpeedJob::WorkThread::run() { kdDebug() << k_funcinfo << endl; m_canceled = false; emitStarted(); K3bAudioDataSourceIterator it( m_doc ); // count sources for minimal progress info int numSources = 0; int sourcesDone = 0; while( it.current() ) { ++numSources; it.next(); } bool success = true; maxSpeed = 175*1000; it.first(); while( it.current() && !m_canceled ) { if( !it.current()->seek(0) ) { kdDebug() << "(K3bAudioMaxSpeedJob) seek failed." << endl; success = false; break; } // read some data int speed = speedTest( it.current() ); ++sourcesDone; emitPercent( 100*numSources/sourcesDone ); if( speed < 0 ) { success = false; break; } else if( speed > 0 ) { // update the max speed maxSpeed = TQMIN( maxSpeed, speed ); } it.next(); } if( m_canceled ) { emitCanceled(); success = false; } if( success ) kdDebug() << "(K3bAudioMaxSpeedJob) max speed: " << maxSpeed << endl; emitFinished( success ); } // returns the amount of data read from this source int K3bAudioMaxSpeedJob::WorkThread::speedTest( K3bAudioDataSource* source ) { // // in case of an audio track source we only test when the cd is inserted since asking the user would // confuse him a lot. // // FIXME: there is still the problem of the spin up time. // if( K3bAudioCdTrackSource* cdts = dynamic_cast( source ) ) { if( K3bDevice::Device* dev = cdts->searchForAudioCD() ) { cdts->setDevice( dev ); } else { kdDebug() << "(K3bAudioMaxSpeedJob) ignoring audio cd track source." << endl; return 0; } } TQTime t; int dataRead = 0; int r = 0; // start the timer t.start(); // read ten seconds of audio data. This is some value which seemed about right. :) while( dataRead < 2352*75*10 && (r = source->read( m_buffer, 2352*10 )) > 0 ) { dataRead += r; } // elapsed millisec int usedT = t.elapsed(); if( r < 0 ) { kdDebug() << "(K3bAudioMaxSpeedJob) read failure." << endl; return -1; } // KB/sec (add 1 millisecond to avoid division by 0) int throughput = (dataRead*1000+usedT)/(usedT+1)/1024; kdDebug() << "(K3bAudioMaxSpeedJob) throughput: " << throughput << " (" << dataRead << "/" << usedT << ")" << endl; return throughput; } void K3bAudioMaxSpeedJob::WorkThread::cancel() { kdDebug() << k_funcinfo << endl; m_canceled = true; } int K3bAudioMaxSpeedJob::WorkThread::maxSpeedByMedia() const { int s = 0; TQValueList speeds = m_doc->burner()->determineSupportedWriteSpeeds(); // simply use what we have and let the writer decide if the speeds are empty if( !speeds.isEmpty() ) { // start with the highest speed and go down the list until we are below our max TQValueListIterator it = speeds.end(); --it; while( *it > maxSpeed && it != speeds.begin() ) --it; // this is the first valid speed or the lowest supported one s = *it; kdDebug() << "(K3bAudioMaxSpeedJob) using speed factor: " << (s/175) << endl; } return s; } K3bAudioMaxSpeedJob::K3bAudioMaxSpeedJob( K3bAudioDoc* doc, K3bJobHandler* jh, TQObject* parent, const char* name ) : K3bThreadJob( jh, parent, name ) { m_thread = new WorkThread( doc ); setThread( m_thread ); } K3bAudioMaxSpeedJob::~K3bAudioMaxSpeedJob() { delete m_thread; } int K3bAudioMaxSpeedJob::maxSpeed() const { return m_thread->maxSpeedByMedia(); } #include "k3baudiomaxspeedjob.moc"