2010-11-06 23:04:47 +01:00
///////////////////////////////////////////////////////////////////////////////
// LameXP - Audio Encoder Front-End
2014-01-01 17:05:52 +01:00
// Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
2010-11-06 23:04:47 +01:00
//
// 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
2013-10-23 20:56:57 +02:00
// (at your option) any later version, but always including the *additional*
// restrictions defined in the "License.txt" file.
2010-11-06 23:04:47 +01:00
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// http://www.gnu.org/licenses/gpl-2.0.txt
///////////////////////////////////////////////////////////////////////////////
# include "Thread_Initialization.h"
# include "LockedFile.h"
2011-10-19 00:24:03 +02:00
# include "Tools.h"
2013-10-29 02:05:43 +01:00
# include "Tool_Abstract.h"
2010-11-06 23:04:47 +01:00
2010-11-11 22:58:02 +01:00
# include <QFileInfo>
# include <QCoreApplication>
2010-11-12 15:58:53 +01:00
# include <QProcess>
2010-12-12 01:49:07 +01:00
# include <QMap>
# include <QDir>
2010-12-12 13:44:11 +01:00
# include <QLibrary>
2011-01-04 19:58:18 +01:00
# include <QResource>
2011-12-18 15:19:07 +01:00
# include <QTextStream>
2012-04-29 21:17:51 +02:00
# include <QRunnable>
# include <QThreadPool>
# include <QMutex>
2013-10-18 20:49:22 +02:00
# include <QQueue>
2010-12-12 13:44:11 +01:00
2011-10-19 00:24:03 +02:00
/* helper macros */
2011-10-18 18:54:56 +02:00
# define PRINT_CPU_TYPE(X) case X: qDebug("Selected CPU is: " #X)
2013-10-16 18:24:16 +02:00
/* constants */
2012-04-29 21:17:51 +02:00
static const double g_allowedExtractDelay = 12.0 ;
2013-10-16 18:24:16 +02:00
static const size_t BUFF_SIZE = 512 ;
2013-11-01 19:34:27 +01:00
static const size_t EXPECTED_TOOL_COUNT = 27 ;
/* benchmark */
# undef ENABLE_BENCHMARK
2012-04-29 21:17:51 +02:00
2013-11-02 16:39:59 +01:00
/* number of CPU cores -> number of threads */
static unsigned int cores2threads ( const unsigned int cores )
{
static const size_t LUT_LEN = 4 ;
static const struct
{
const unsigned int upperBound ;
const double coeffs [ 4 ] ;
}
LUT [ LUT_LEN ] =
{
{ 4 , { - 0.052695810565 , 0.158087431694 , 4.982841530055 , - 1.088233151184 } } ,
{ 8 , { 0.042431693989 , - 0.983442622951 , 9.548961748634 , - 7.176393442623 } } ,
{ 12 , { - 0.006277322404 , 0.185573770492 , 0.196830601093 , 17.762622950820 } } ,
{ 32 , { 0.000673497268 , - 0.064655737705 , 3.199584699454 , 5.751606557377 } }
} ;
size_t index = 0 ;
while ( ( cores > LUT [ index ] . upperBound ) & & ( index < ( LUT_LEN - 1 ) ) ) index + + ;
const double x = qBound ( 1.0 , double ( cores ) , double ( LUT [ LUT_LEN - 1 ] . upperBound ) ) ;
const double y = ( LUT [ index ] . coeffs [ 0 ] * pow ( x , 3.0 ) ) + ( LUT [ index ] . coeffs [ 1 ] * pow ( x , 2.0 ) ) + ( LUT [ index ] . coeffs [ 2 ] * x ) + LUT [ index ] . coeffs [ 3 ] ;
return qRound ( abs ( y ) ) ;
}
2012-04-29 21:17:51 +02:00
////////////////////////////////////////////////////////////
// ExtractorTask class
////////////////////////////////////////////////////////////
class ExtractorTask : public QRunnable
{
public :
2013-10-18 20:49:22 +02:00
ExtractorTask ( QResource * const toolResource , const QDir & appDir , const QString & toolName , const QByteArray & toolHash , const unsigned int toolVersion , const QString & toolTag )
2012-04-29 21:17:51 +02:00
:
2013-10-16 18:24:16 +02:00
m_appDir ( appDir ) ,
m_toolName ( toolName ) ,
m_toolHash ( toolHash ) ,
m_toolVersion ( toolVersion ) ,
2013-10-18 20:49:22 +02:00
m_toolTag ( toolTag ) ,
m_toolResource ( toolResource )
2012-04-29 21:17:51 +02:00
{
/* Nothing to do */
}
2013-10-18 20:49:22 +02:00
~ ExtractorTask ( void )
{
delete m_toolResource ;
}
2012-04-29 21:17:51 +02:00
static void clearFlags ( void )
{
2013-10-16 18:24:16 +02:00
QMutexLocker lock ( & s_mutex ) ;
s_bExcept = false ;
s_bCustom = false ;
s_errMsg [ 0 ] = char ( 0 ) ;
2012-04-29 21:17:51 +02:00
}
2013-10-16 18:24:16 +02:00
static bool getExcept ( void ) { bool ret ; QMutexLocker lock ( & s_mutex ) ; ret = s_bExcept ; return ret ; }
static bool getCustom ( void ) { bool ret ; QMutexLocker lock ( & s_mutex ) ; ret = s_bCustom ; return ret ; }
2013-10-16 03:31:14 +02:00
2013-10-16 18:24:16 +02:00
static bool getErrMsg ( char * buffer , const size_t buffSize )
2013-10-16 03:31:14 +02:00
{
2013-10-16 18:24:16 +02:00
QMutexLocker lock ( & s_mutex ) ;
if ( s_errMsg [ 0 ] )
{
strncpy_s ( buffer , BUFF_SIZE , s_errMsg , _TRUNCATE ) ;
return true ;
}
return false ;
2013-10-16 03:31:14 +02:00
}
2012-04-29 21:17:51 +02:00
protected :
2012-05-04 04:01:10 +02:00
void run ( void )
2012-04-29 21:17:51 +02:00
{
try
{
2013-10-16 18:24:16 +02:00
if ( ! getExcept ( ) ) doExtract ( ) ;
2012-04-29 21:17:51 +02:00
}
2013-10-18 21:37:40 +02:00
catch ( const std : : exception & e )
2013-10-18 20:49:22 +02:00
{
QMutexLocker lock ( & s_mutex ) ;
if ( ! s_bExcept )
{
s_bExcept = true ;
strncpy_s ( s_errMsg , BUFF_SIZE , e . what ( ) , _TRUNCATE ) ;
}
lock . unlock ( ) ;
qWarning ( " ExtractorTask exception error: \n %s \n \n " , e . what ( ) ) ;
}
catch ( . . . )
2012-04-29 21:17:51 +02:00
{
2013-10-16 18:24:16 +02:00
QMutexLocker lock ( & s_mutex ) ;
if ( ! s_bExcept )
2012-05-03 23:11:16 +02:00
{
2013-10-16 18:24:16 +02:00
s_bExcept = true ;
2013-10-18 20:49:22 +02:00
strncpy_s ( s_errMsg , BUFF_SIZE , " Unknown exception error! " , _TRUNCATE ) ;
2012-05-03 23:11:16 +02:00
}
2013-10-18 20:49:22 +02:00
lock . unlock ( ) ;
qWarning ( " ExtractorTask encountered an unknown exception! " ) ;
2012-04-29 21:17:51 +02:00
}
}
2013-10-16 18:24:16 +02:00
void doExtract ( void )
{
LockedFile * lockedFile = NULL ;
unsigned int version = m_toolVersion ;
2013-10-18 20:49:22 +02:00
QFileInfo toolFileInfo ( m_toolName ) ;
const QString toolShortName = QString ( " %1.%2 " ) . arg ( toolFileInfo . baseName ( ) . toLower ( ) , toolFileInfo . suffix ( ) . toLower ( ) ) ;
QFileInfo customTool ( QString ( " %1/tools/%2/%3 " ) . arg ( m_appDir . canonicalPath ( ) , QString : : number ( lamexp_version_build ( ) ) , toolShortName ) ) ;
2013-10-16 18:24:16 +02:00
if ( customTool . exists ( ) & & customTool . isFile ( ) )
{
2013-10-18 20:49:22 +02:00
qDebug ( " Setting up file: %s <- %s " , toolShortName . toLatin1 ( ) . constData ( ) , m_appDir . relativeFilePath ( customTool . canonicalFilePath ( ) ) . toLatin1 ( ) . constData ( ) ) ;
2013-10-16 18:24:16 +02:00
lockedFile = new LockedFile ( customTool . canonicalFilePath ( ) ) ; version = UINT_MAX ; s_bCustom = true ;
}
else
{
2013-10-18 20:49:22 +02:00
qDebug ( " Extracting file: %s -> %s " , m_toolName . toLatin1 ( ) . constData ( ) , toolShortName . toLatin1 ( ) . constData ( ) ) ;
lockedFile = new LockedFile ( m_toolResource , QString ( " %1/lxp_%2 " ) . arg ( lamexp_temp_folder2 ( ) , toolShortName ) , m_toolHash ) ;
2013-10-16 18:24:16 +02:00
}
if ( lockedFile )
{
2013-10-18 20:49:22 +02:00
lamexp_register_tool ( toolShortName , lockedFile , version , & m_toolTag ) ;
2013-10-16 18:24:16 +02:00
}
}
2012-04-29 21:17:51 +02:00
private :
2013-10-18 20:49:22 +02:00
QResource * const m_toolResource ;
2012-04-29 21:17:51 +02:00
const QDir m_appDir ;
const QString m_toolName ;
2013-10-16 03:31:14 +02:00
const QByteArray m_toolHash ;
2013-10-16 18:24:16 +02:00
const unsigned int m_toolVersion ;
const QString m_toolTag ;
2012-04-29 21:17:51 +02:00
2013-10-16 18:24:16 +02:00
static volatile bool s_bExcept ;
2012-04-29 21:17:51 +02:00
static volatile bool s_bCustom ;
static QMutex s_mutex ;
2013-10-16 18:24:16 +02:00
static char s_errMsg [ BUFF_SIZE ] ;
2012-04-29 21:17:51 +02:00
} ;
QMutex ExtractorTask : : s_mutex ;
2013-10-18 20:49:22 +02:00
char ExtractorTask : : s_errMsg [ BUFF_SIZE ] = { ' \0 ' } ;
2013-10-16 18:24:16 +02:00
volatile bool ExtractorTask : : s_bExcept = false ;
volatile bool ExtractorTask : : s_bCustom = false ;
2011-06-24 18:17:04 +02:00
2010-11-06 23:04:47 +01:00
////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////
2011-04-11 02:53:29 +02:00
InitializationThread : : InitializationThread ( const lamexp_cpu_t * cpuFeatures )
2010-11-06 23:04:47 +01:00
{
m_bSuccess = false ;
2011-04-11 02:53:29 +02:00
memset ( & m_cpuFeatures , 0 , sizeof ( lamexp_cpu_t ) ) ;
2011-06-24 18:17:04 +02:00
m_slowIndicator = false ;
2011-04-11 02:53:29 +02:00
if ( cpuFeatures )
{
memcpy ( & m_cpuFeatures , cpuFeatures , sizeof ( lamexp_cpu_t ) ) ;
}
2010-11-06 23:04:47 +01:00
}
2010-11-12 15:58:53 +01:00
////////////////////////////////////////////////////////////
// Thread Main
////////////////////////////////////////////////////////////
2010-11-06 23:04:47 +01:00
2013-11-01 19:34:27 +01:00
# ifdef ENABLE_BENCHMARK
# define DO_INIT_FUNCT runBenchmark
# else //ENABLE_BENCHMARK
# define DO_INIT_FUNCT doInit
# endif //ENABLE_BENCHMARK
void InitializationThread : : run ( void )
{
try
{
DO_INIT_FUNCT ( ) ;
}
catch ( const std : : exception & error )
{
fflush ( stdout ) ; fflush ( stderr ) ;
fprintf ( stderr , " \n GURU MEDITATION !!! \n \n Exception error: \n %s \n " , error . what ( ) ) ;
lamexp_fatal_exit ( L " Unhandeled C++ exception error, application will exit! " ) ;
}
catch ( . . . )
{
fflush ( stdout ) ; fflush ( stderr ) ;
fprintf ( stderr , " \n GURU MEDITATION !!! \n \n Unknown exception error! \n " ) ;
lamexp_fatal_exit ( L " Unhandeled C++ exception error, application will exit! " ) ;
}
}
double InitializationThread : : doInit ( const size_t threadCount )
2010-11-06 23:04:47 +01:00
{
m_bSuccess = false ;
delay ( ) ;
2011-03-21 17:36:43 +01:00
2011-04-11 02:53:29 +02:00
//CPU type selection
2011-10-18 18:54:56 +02:00
unsigned int cpuSupport = 0 ;
if ( m_cpuFeatures . sse & & m_cpuFeatures . sse2 & & m_cpuFeatures . intel )
{
cpuSupport = m_cpuFeatures . x64 ? CPU_TYPE_X64_SSE : CPU_TYPE_X86_SSE ;
}
else
{
cpuSupport = m_cpuFeatures . x64 ? CPU_TYPE_X64_GEN : CPU_TYPE_X86_GEN ;
}
2012-04-05 13:40:52 +02:00
//Hack to disable x64 on Wine, as x64 binaries won't run under Wine (tested with Wine 1.4 under Ubuntu 12.04 x64)
if ( cpuSupport & CPU_TYPE_X64_ALL )
{
if ( lamexp_detect_wine ( ) )
{
qWarning ( " Running under Wine on a 64-Bit system. Going to disable all x64 support! \n " ) ;
cpuSupport = ( cpuSupport = = CPU_TYPE_X64_SSE ) ? CPU_TYPE_X86_SSE : CPU_TYPE_X86_GEN ;
}
}
2011-10-21 16:17:22 +02:00
2011-10-18 18:54:56 +02:00
//Print selected CPU type
switch ( cpuSupport )
{
PRINT_CPU_TYPE ( CPU_TYPE_X86_GEN ) ; break ;
PRINT_CPU_TYPE ( CPU_TYPE_X86_SSE ) ; break ;
PRINT_CPU_TYPE ( CPU_TYPE_X64_GEN ) ; break ;
PRINT_CPU_TYPE ( CPU_TYPE_X64_SSE ) ; break ;
2013-10-18 21:37:40 +02:00
default : THROW ( " CPU support undefined! " ) ;
2011-10-18 18:54:56 +02:00
}
2013-10-21 15:00:55 +02:00
//Allocate queues
2013-10-18 20:49:22 +02:00
QQueue < QString > queueToolName ;
QQueue < QString > queueChecksum ;
QQueue < QString > queueVersInfo ;
QQueue < unsigned int > queueVersions ;
QQueue < unsigned int > queueCpuTypes ;
2010-12-12 01:49:07 +01:00
2011-04-11 02:53:29 +02:00
//Init properties
2013-10-16 18:24:16 +02:00
for ( int i = 0 ; true ; i + + )
2010-11-06 23:04:47 +01:00
{
2013-10-16 18:24:16 +02:00
if ( ! ( g_lamexp_tools [ i ] . pcName | | g_lamexp_tools [ i ] . pcHash | | g_lamexp_tools [ i ] . uiVersion ) )
2010-12-18 15:15:17 +01:00
{
break ;
}
else if ( g_lamexp_tools [ i ] . pcName & & g_lamexp_tools [ i ] . pcHash & & g_lamexp_tools [ i ] . uiVersion )
2010-11-06 23:04:47 +01:00
{
2013-10-18 20:49:22 +02:00
queueToolName . enqueue ( QString : : fromLatin1 ( g_lamexp_tools [ i ] . pcName ) ) ;
queueChecksum . enqueue ( QString : : fromLatin1 ( g_lamexp_tools [ i ] . pcHash ) ) ;
queueVersInfo . enqueue ( QString : : fromLatin1 ( g_lamexp_tools [ i ] . pcVersTag ) ) ;
queueCpuTypes . enqueue ( g_lamexp_tools [ i ] . uiCpuType ) ;
queueVersions . enqueue ( g_lamexp_tools [ i ] . uiVersion ) ;
2010-11-06 23:04:47 +01:00
}
2010-12-18 15:15:17 +01:00
else
{
qFatal ( " Inconsistent checksum data detected. Take care! " ) ;
}
2010-12-12 01:49:07 +01:00
}
2010-11-06 23:04:47 +01:00
2011-04-17 20:38:49 +02:00
QDir appDir = QDir ( QCoreApplication : : applicationDirPath ( ) ) . canonicalPath ( ) ;
2012-04-29 21:17:51 +02:00
QThreadPool * pool = new QThreadPool ( ) ;
2013-11-02 16:39:59 +01:00
pool - > setMaxThreadCount ( ( threadCount > 0 ) ? threadCount : qBound ( 2U , cores2threads ( m_cpuFeatures . count ) , EXPECTED_TOOL_COUNT ) ) ;
2013-11-03 23:43:21 +01:00
/* qWarning("Using %u threads for extraction.", pool->maxThreadCount()); */
2013-11-02 16:39:59 +01:00
2012-11-27 01:02:55 +01:00
LockedFile : : selfTest ( ) ;
2012-04-29 21:17:51 +02:00
ExtractorTask : : clearFlags ( ) ;
2013-10-16 18:24:16 +02:00
const long long timeExtractStart = lamexp_perfcounter_value ( ) ;
2011-04-17 20:38:49 +02:00
2010-12-12 01:49:07 +01:00
//Extract all files
2013-10-18 20:49:22 +02:00
while ( ! ( queueToolName . isEmpty ( ) | | queueChecksum . isEmpty ( ) | | queueVersInfo . isEmpty ( ) | | queueCpuTypes . isEmpty ( ) | | queueVersions . isEmpty ( ) ) )
2010-12-12 01:49:07 +01:00
{
2013-10-18 20:49:22 +02:00
const QString toolName = queueToolName . dequeue ( ) ;
const QString checksum = queueChecksum . dequeue ( ) ;
const QString versInfo = queueVersInfo . dequeue ( ) ;
const unsigned int cpuType = queueCpuTypes . dequeue ( ) ;
const unsigned int version = queueVersions . dequeue ( ) ;
2011-04-11 02:53:29 +02:00
2013-10-18 20:49:22 +02:00
const QByteArray toolHash ( checksum . toLatin1 ( ) ) ;
if ( toolHash . size ( ) ! = 96 )
{
2013-10-21 15:00:55 +02:00
qFatal ( " The checksum for \" %s \" has an invalid size! " , QUTF8 ( toolName ) ) ;
2013-11-01 19:34:27 +01:00
return - 1.0 ;
2010-11-06 23:04:47 +01:00
}
2013-10-18 20:49:22 +02:00
QResource * resource = new QResource ( QString ( " :/tools/%1 " ) . arg ( toolName ) ) ;
if ( ! ( resource - > isValid ( ) & & resource - > data ( ) ) )
2010-11-06 23:04:47 +01:00
{
2013-10-18 20:49:22 +02:00
LAMEXP_DELETE ( resource ) ;
2013-10-21 15:00:55 +02:00
qFatal ( " The resource for \" %s \" could not be found! " , QUTF8 ( toolName ) ) ;
2013-11-01 19:34:27 +01:00
return - 1.0 ;
2010-11-06 23:04:47 +01:00
}
2013-10-18 20:49:22 +02:00
if ( cpuType & cpuSupport )
{
pool - > start ( new ExtractorTask ( resource , appDir , toolName , toolHash , version , versInfo ) ) ;
continue ;
}
LAMEXP_DELETE ( resource ) ;
}
//Sanity Check
if ( ! ( queueToolName . isEmpty ( ) & & queueChecksum . isEmpty ( ) & & queueVersInfo . isEmpty ( ) & & queueCpuTypes . isEmpty ( ) & & queueVersions . isEmpty ( ) ) )
{
qFatal ( " Checksum queues *not* empty fater verification completed. Take care! " ) ;
2010-11-06 23:04:47 +01:00
}
2012-05-03 23:11:16 +02:00
2012-04-29 21:17:51 +02:00
//Wait for extrator threads to finish
pool - > waitForDone ( ) ;
LAMEXP_DELETE ( pool ) ;
2013-10-16 18:24:16 +02:00
const long long timeExtractEnd = lamexp_perfcounter_value ( ) ;
2012-04-29 21:17:51 +02:00
//Make sure all files were extracted correctly
2013-10-16 18:24:16 +02:00
if ( ExtractorTask : : getExcept ( ) )
2012-04-29 21:17:51 +02:00
{
2013-10-16 18:24:16 +02:00
char errorMsg [ BUFF_SIZE ] ;
if ( ExtractorTask : : getErrMsg ( errorMsg , BUFF_SIZE ) )
{
qFatal ( " At least one of the required tools could not be initialized: \n %s " , errorMsg ) ;
2013-11-01 19:34:27 +01:00
return - 1.0 ;
2013-10-16 18:24:16 +02:00
}
qFatal ( " At least one of the required tools could not be initialized! " ) ;
2013-11-01 19:34:27 +01:00
return - 1.0 ;
2012-04-29 21:17:51 +02:00
}
2011-04-17 20:38:49 +02:00
qDebug ( " All extracted. \n " ) ;
//Using any custom tools?
2012-04-29 21:17:51 +02:00
if ( ExtractorTask : : getCustom ( ) )
2011-04-17 20:38:49 +02:00
{
qWarning ( " Warning: Using custom tools, you might encounter unexpected problems! \n " ) ;
}
2010-11-11 22:58:02 +01:00
2011-01-25 01:41:57 +01:00
//Check delay
2013-11-01 19:34:27 +01:00
const double delayExtract = static_cast < double > ( timeExtractEnd - timeExtractStart ) / static_cast < double > ( lamexp_perfcounter_frequ ( ) ) ;
2011-06-24 18:17:04 +02:00
if ( delayExtract > g_allowedExtractDelay )
2011-01-25 01:41:57 +01:00
{
2011-06-24 18:17:04 +02:00
m_slowIndicator = true ;
2011-01-25 01:41:57 +01:00
qWarning ( " Extracting tools took %.3f seconds -> probably slow realtime virus scanner. " , delayExtract ) ;
qWarning ( " Please report performance problems to your anti-virus developer !!! \n " ) ;
}
2013-06-29 18:06:21 +02:00
else
{
2013-10-16 18:24:16 +02:00
qDebug ( " Extracting the tools took %.5f seconds (OK). \n " , delayExtract ) ;
2013-06-29 18:06:21 +02:00
}
2011-01-25 01:41:57 +01:00
2011-01-04 19:58:18 +01:00
//Register all translations
initTranslations ( ) ;
2011-11-21 01:22:41 +01:00
//Look for AAC encoders
2010-11-12 15:58:53 +01:00
initNeroAac ( ) ;
2011-08-19 15:27:58 +02:00
initFhgAac ( ) ;
2011-11-21 01:22:41 +01:00
initQAac ( ) ;
2011-08-19 15:27:58 +02:00
2010-11-12 15:58:53 +01:00
m_bSuccess = true ;
2013-11-01 19:34:27 +01:00
delay ( ) ;
return delayExtract ;
}
void InitializationThread : : runBenchmark ( void )
{
# ifdef ENABLE_BENCHMARK
static const size_t nLoops = 5 ;
const size_t maxThreads = ( 5 * m_cpuFeatures . count ) ;
QMap < size_t , double > results ;
for ( size_t c = 1 ; c < = maxThreads ; c + + )
{
2013-11-02 14:28:52 +01:00
QList < double > delayLst ;
double delayAvg = 0.0 ;
2013-11-01 19:34:27 +01:00
for ( size_t i = 0 ; i < nLoops ; i + + )
{
2013-11-02 14:28:52 +01:00
delayLst < < doInit ( c ) ;
2013-11-01 19:34:27 +01:00
lamexp_clean_all_tools ( ) ;
}
2013-11-02 14:28:52 +01:00
qSort ( delayLst . begin ( ) , delayLst . end ( ) ) ;
delayLst . takeLast ( ) ;
delayLst . takeFirst ( ) ;
for ( QList < double > : : ConstIterator iter = delayLst . constBegin ( ) ; iter ! = delayLst . constEnd ( ) ; iter + + )
{
delayAvg + = ( * iter ) ;
}
results . insert ( c , ( delayAvg / double ( delayLst . count ( ) ) ) ) ;
2013-11-01 19:34:27 +01:00
}
qWarning ( " \n ---------------------------------------------- " ) ;
qWarning ( " Benchmark Results: " ) ;
qWarning ( " ---------------------------------------------- " ) ;
double bestTime = DBL_MAX ; size_t bestVal = 0 ;
QList < size_t > keys = results . keys ( ) ;
for ( QList < size_t > : : ConstIterator iter = keys . begin ( ) ; iter ! = keys . end ( ) ; iter + + )
{
const double time = results . value ( ( * iter ) , DBL_MAX ) ;
qWarning ( " %02u -> %7.4f " , ( * iter ) , time ) ;
if ( time < bestTime )
{
bestTime = time ;
bestVal = ( * iter ) ;
}
}
qWarning ( " ---------------------------------------------- " ) ;
qWarning ( " BEST: %u of %u (factor: %7.4f) " , bestVal , m_cpuFeatures . count , ( double ( bestVal ) / double ( m_cpuFeatures . count ) ) ) ;
qWarning ( " ---------------------------------------------- \n " ) ;
qFatal ( " Benchmark complete. Thanks and bye bye! " ) ;
# else //ENABLE_BENCHMARK
THROW ( " Sorry, the benchmark is *not* available in this build! " ) ;
# endif //ENABLE_BENCHMARK
2010-11-12 15:58:53 +01:00
}
////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS
////////////////////////////////////////////////////////////
void InitializationThread : : delay ( void )
{
2013-11-23 20:57:38 +01:00
lamexp_sleep ( 333 ) ;
2010-11-12 15:58:53 +01:00
}
2011-01-04 19:58:18 +01:00
void InitializationThread : : initTranslations ( void )
{
//Search for language files
QStringList qmFiles = QDir ( " :/localization " ) . entryList ( QStringList ( ) < < " LameXP_??.qm " , QDir : : Files , QDir : : Name ) ;
//Make sure we found at least one translation
if ( qmFiles . count ( ) < 1 )
{
qFatal ( " Could not find any translation files! " ) ;
return ;
}
//Add all available translations
while ( ! qmFiles . isEmpty ( ) )
{
QString langId , langName ;
2011-12-19 17:38:36 +01:00
unsigned int systemId = 0 , country = 0 ;
2011-01-04 19:58:18 +01:00
QString qmFile = qmFiles . takeFirst ( ) ;
QRegExp langIdExp ( " LameXP_( \\ w \\ w) \ \ . qm " , Qt::CaseInsensitive) ;
if ( langIdExp . indexIn ( qmFile ) > = 0 )
{
langId = langIdExp . cap ( 1 ) . toLower ( ) ;
2011-12-18 15:19:07 +01:00
QResource langRes = QResource ( QString ( " :/localization/%1.txt " ) . arg ( qmFile ) ) ;
if ( langRes . isValid ( ) & & langRes . size ( ) > 0 )
{
QByteArray data = QByteArray : : fromRawData ( reinterpret_cast < const char * > ( langRes . data ( ) ) , langRes . size ( ) ) ;
QTextStream stream ( & data , QIODevice : : ReadOnly ) ;
stream . setAutoDetectUnicode ( false ) ; stream . setCodec ( " UTF-8 " ) ;
while ( ! stream . atEnd ( ) )
{
QStringList langInfo = stream . readLine ( ) . simplified ( ) . split ( " , " , QString : : SkipEmptyParts ) ;
2011-12-19 15:48:50 +01:00
if ( langInfo . count ( ) = = 3 )
2011-12-18 15:19:07 +01:00
{
systemId = langInfo . at ( 0 ) . trimmed ( ) . toUInt ( ) ;
2011-12-19 17:38:36 +01:00
country = langInfo . at ( 1 ) . trimmed ( ) . toUInt ( ) ;
2011-12-19 15:48:50 +01:00
langName = langInfo . at ( 2 ) . trimmed ( ) ;
2011-12-18 15:19:07 +01:00
break ;
}
}
}
2011-01-04 19:58:18 +01:00
}
2011-12-18 15:19:07 +01:00
if ( ! ( langId . isEmpty ( ) | | langName . isEmpty ( ) | | systemId = = 0 ) )
2011-01-04 19:58:18 +01:00
{
2011-12-19 17:38:36 +01:00
if ( lamexp_translation_register ( langId , qmFile , langName , systemId , country ) )
2011-01-04 19:58:18 +01:00
{
2013-10-21 15:00:55 +02:00
qDebug ( " Registering translation: %s = %s (%u) [%u] " , QUTF8 ( qmFile ) , QUTF8 ( langName ) , systemId , country ) ;
2011-12-18 15:19:07 +01:00
}
else
{
qWarning ( " Failed to register: %s " , qmFile . toLatin1 ( ) . constData ( ) ) ;
2011-01-04 19:58:18 +01:00
}
}
}
qDebug ( " All registered. \n " ) ;
}
2010-11-12 15:58:53 +01:00
void InitializationThread : : initNeroAac ( void )
{
2011-04-17 20:38:49 +02:00
const QString appPath = QDir ( QCoreApplication : : applicationDirPath ( ) ) . canonicalPath ( ) ;
2010-11-11 22:58:02 +01:00
QFileInfo neroFileInfo [ 3 ] ;
2011-04-17 20:38:49 +02:00
neroFileInfo [ 0 ] = QFileInfo ( QString ( " %1/neroAacEnc.exe " ) . arg ( appPath ) ) ;
neroFileInfo [ 1 ] = QFileInfo ( QString ( " %1/neroAacDec.exe " ) . arg ( appPath ) ) ;
neroFileInfo [ 2 ] = QFileInfo ( QString ( " %1/neroAacTag.exe " ) . arg ( appPath ) ) ;
2010-11-11 22:58:02 +01:00
bool neroFilesFound = true ;
for ( int i = 0 ; i < 3 ; i + + ) { if ( ! neroFileInfo [ i ] . exists ( ) ) neroFilesFound = false ; }
//Lock the Nero binaries
2010-11-12 15:58:53 +01:00
if ( ! neroFilesFound )
2010-11-11 22:58:02 +01:00
{
2010-11-12 15:58:53 +01:00
qDebug ( " Nero encoder binaries not found -> AAC encoding support will be disabled! \n " ) ;
return ;
}
2013-10-21 15:00:55 +02:00
qDebug ( " Found Nero AAC encoder binary: \n %s \n " , QUTF8 ( neroFileInfo [ 0 ] . canonicalFilePath ( ) ) ) ;
2010-11-12 15:58:53 +01:00
LockedFile * neroBin [ 3 ] ;
for ( int i = 0 ; i < 3 ; i + + ) neroBin [ i ] = NULL ;
try
{
for ( int i = 0 ; i < 3 ; i + + )
{
2010-11-15 22:07:46 +01:00
neroBin [ i ] = new LockedFile ( neroFileInfo [ i ] . canonicalFilePath ( ) ) ;
2010-11-12 15:58:53 +01:00
}
}
catch ( . . . )
{
for ( int i = 0 ; i < 3 ; i + + ) LAMEXP_DELETE ( neroBin [ i ] ) ;
2010-11-20 19:16:04 +01:00
qWarning ( " Failed to get excluive lock to Nero encoder binary -> AAC encoding support will be disabled! " ) ;
2010-11-12 15:58:53 +01:00
return ;
}
QProcess process ;
2013-10-29 02:05:43 +01:00
lamexp_init_process ( process , neroFileInfo [ 0 ] . absolutePath ( ) ) ;
2010-11-20 16:17:51 +01:00
process . start ( neroFileInfo [ 0 ] . canonicalFilePath ( ) , QStringList ( ) < < " -help " ) ;
2010-11-12 15:58:53 +01:00
if ( ! process . waitForStarted ( ) )
{
qWarning ( " Nero process failed to create! " ) ;
2010-11-18 22:37:35 +01:00
qWarning ( " Error message: \" %s \" \n " , process . errorString ( ) . toLatin1 ( ) . constData ( ) ) ;
2010-11-12 15:58:53 +01:00
process . kill ( ) ;
process . waitForFinished ( - 1 ) ;
for ( int i = 0 ; i < 3 ; i + + ) LAMEXP_DELETE ( neroBin [ i ] ) ;
return ;
}
unsigned int neroVersion = 0 ;
while ( process . state ( ) ! = QProcess : : NotRunning )
{
if ( ! process . waitForReadyRead ( ) )
2010-11-11 22:58:02 +01:00
{
2010-11-12 15:58:53 +01:00
if ( process . state ( ) = = QProcess : : Running )
{
qWarning ( " Nero process time out -> killing! " ) ;
process . kill ( ) ;
process . waitForFinished ( - 1 ) ;
for ( int i = 0 ; i < 3 ; i + + ) LAMEXP_DELETE ( neroBin [ i ] ) ;
return ;
}
2010-11-11 22:58:02 +01:00
}
2010-11-12 15:58:53 +01:00
2010-11-18 22:37:35 +01:00
while ( process . canReadLine ( ) )
2010-11-11 22:58:02 +01:00
{
2010-11-18 22:37:35 +01:00
QString line = QString : : fromUtf8 ( process . readLine ( ) . constData ( ) ) . simplified ( ) ;
2010-11-12 15:58:53 +01:00
QStringList tokens = line . split ( " " , QString : : SkipEmptyParts , Qt : : CaseInsensitive ) ;
int index1 = tokens . indexOf ( " Package " ) ;
int index2 = tokens . indexOf ( " version: " ) ;
if ( index1 > = 0 & & index2 > = 0 & & index1 + 1 = = index2 & & index2 < tokens . count ( ) - 1 )
{
QStringList versionTokens = tokens . at ( index2 + 1 ) . split ( " . " , QString : : SkipEmptyParts , Qt : : CaseInsensitive ) ;
if ( versionTokens . count ( ) = = 4 )
{
neroVersion = 0 ;
2011-11-08 15:12:31 +01:00
neroVersion + = qMin ( 9 , qMax ( 0 , versionTokens . at ( 3 ) . toInt ( ) ) ) ;
neroVersion + = qMin ( 9 , qMax ( 0 , versionTokens . at ( 2 ) . toInt ( ) ) ) * 10 ;
neroVersion + = qMin ( 9 , qMax ( 0 , versionTokens . at ( 1 ) . toInt ( ) ) ) * 100 ;
neroVersion + = qMin ( 9 , qMax ( 0 , versionTokens . at ( 0 ) . toInt ( ) ) ) * 1000 ;
2010-11-12 15:58:53 +01:00
}
}
2010-11-11 22:58:02 +01:00
}
}
2010-11-12 15:58:53 +01:00
if ( ! ( neroVersion > 0 ) )
2010-11-11 22:58:02 +01:00
{
2010-12-14 01:25:13 +01:00
qWarning ( " Nero AAC version could not be determined -> AAC encoding support will be disabled! " ) ;
2010-11-12 15:58:53 +01:00
for ( int i = 0 ; i < 3 ; i + + ) LAMEXP_DELETE ( neroBin [ i ] ) ;
return ;
2010-11-11 22:58:02 +01:00
}
2010-11-06 23:04:47 +01:00
2010-11-12 15:58:53 +01:00
for ( int i = 0 ; i < 3 ; i + + )
{
lamexp_register_tool ( neroFileInfo [ i ] . fileName ( ) , neroBin [ i ] , neroVersion ) ;
}
2010-11-06 23:04:47 +01:00
}
2011-08-19 15:27:58 +02:00
void InitializationThread : : initFhgAac ( void )
{
const QString appPath = QDir ( QCoreApplication : : applicationDirPath ( ) ) . canonicalPath ( ) ;
2012-08-06 23:42:46 +02:00
QFileInfo fhgFileInfo [ 5 ] ;
2011-08-19 15:27:58 +02:00
fhgFileInfo [ 0 ] = QFileInfo ( QString ( " %1/fhgaacenc.exe " ) . arg ( appPath ) ) ;
fhgFileInfo [ 1 ] = QFileInfo ( QString ( " %1/enc_fhgaac.dll " ) . arg ( appPath ) ) ;
fhgFileInfo [ 2 ] = QFileInfo ( QString ( " %1/nsutil.dll " ) . arg ( appPath ) ) ;
fhgFileInfo [ 3 ] = QFileInfo ( QString ( " %1/libmp4v2.dll " ) . arg ( appPath ) ) ;
2012-08-06 23:42:46 +02:00
fhgFileInfo [ 4 ] = QFileInfo ( QString ( " %1/libsndfile-1.dll " ) . arg ( appPath ) ) ;
2011-08-19 15:27:58 +02:00
bool fhgFilesFound = true ;
2012-08-06 23:42:46 +02:00
for ( int i = 0 ; i < 5 ; i + + ) { if ( ! fhgFileInfo [ i ] . exists ( ) ) fhgFilesFound = false ; }
2011-08-19 15:27:58 +02:00
//Lock the FhgAacEnc binaries
if ( ! fhgFilesFound )
{
qDebug ( " FhgAacEnc binaries not found -> FhgAacEnc support will be disabled! \n " ) ;
return ;
}
2013-10-21 15:00:55 +02:00
qDebug ( " Found FhgAacEnc cli_exe: \n %s \n " , QUTF8 ( fhgFileInfo [ 0 ] . canonicalFilePath ( ) ) ) ;
qDebug ( " Found FhgAacEnc enc_dll: \n %s \n " , QUTF8 ( fhgFileInfo [ 1 ] . canonicalFilePath ( ) ) ) ;
2011-08-19 15:27:58 +02:00
2012-08-06 23:42:46 +02:00
LockedFile * fhgBin [ 5 ] ;
for ( int i = 0 ; i < 5 ; i + + ) fhgBin [ i ] = NULL ;
2011-08-19 15:27:58 +02:00
try
{
2012-08-06 23:42:46 +02:00
for ( int i = 0 ; i < 5 ; i + + )
2011-08-19 15:27:58 +02:00
{
fhgBin [ i ] = new LockedFile ( fhgFileInfo [ i ] . canonicalFilePath ( ) ) ;
}
}
catch ( . . . )
{
2012-08-06 23:42:46 +02:00
for ( int i = 0 ; i < 5 ; i + + ) LAMEXP_DELETE ( fhgBin [ i ] ) ;
2011-08-19 15:27:58 +02:00
qWarning ( " Failed to get excluive lock to FhgAacEnc binary -> FhgAacEnc support will be disabled! " ) ;
return ;
}
QProcess process ;
2013-10-29 02:05:43 +01:00
lamexp_init_process ( process , fhgFileInfo [ 0 ] . absolutePath ( ) ) ;
2011-08-19 15:27:58 +02:00
process . start ( fhgFileInfo [ 0 ] . canonicalFilePath ( ) , QStringList ( ) < < " --version " ) ;
if ( ! process . waitForStarted ( ) )
{
qWarning ( " FhgAacEnc process failed to create! " ) ;
qWarning ( " Error message: \" %s \" \n " , process . errorString ( ) . toLatin1 ( ) . constData ( ) ) ;
process . kill ( ) ;
process . waitForFinished ( - 1 ) ;
2012-08-06 23:42:46 +02:00
for ( int i = 0 ; i < 5 ; i + + ) LAMEXP_DELETE ( fhgBin [ i ] ) ;
2011-08-19 15:27:58 +02:00
return ;
}
QRegExp fhgAacEncSig ( " fhgaacenc version ( \\ d+) by tmkk " , Qt::CaseInsensitive) ;
unsigned int fhgVersion = 0 ;
while ( process . state ( ) ! = QProcess : : NotRunning )
{
process . waitForReadyRead ( ) ;
if ( ! process . bytesAvailable ( ) & & process . state ( ) = = QProcess : : Running )
{
qWarning ( " FhgAacEnc process time out -> killing! " ) ;
process . kill ( ) ;
process . waitForFinished ( - 1 ) ;
2012-08-06 23:42:46 +02:00
for ( int i = 0 ; i < 5 ; i + + ) LAMEXP_DELETE ( fhgBin [ i ] ) ;
2011-08-19 15:27:58 +02:00
return ;
}
while ( process . bytesAvailable ( ) > 0 )
{
QString line = QString : : fromUtf8 ( process . readLine ( ) . constData ( ) ) . simplified ( ) ;
if ( fhgAacEncSig . lastIndexIn ( line ) > = 0 )
{
bool ok = false ;
unsigned int temp = fhgAacEncSig . cap ( 1 ) . toUInt ( & ok ) ;
if ( ok ) fhgVersion = temp ;
}
}
}
if ( ! ( fhgVersion > 0 ) )
{
qWarning ( " FhgAacEnc version couldn't be determined -> FhgAacEnc support will be disabled! " ) ;
2012-08-06 23:42:46 +02:00
for ( int i = 0 ; i < 5 ; i + + ) LAMEXP_DELETE ( fhgBin [ i ] ) ;
2011-08-19 15:27:58 +02:00
return ;
}
2011-08-21 14:43:18 +02:00
else if ( fhgVersion < lamexp_toolver_fhgaacenc ( ) )
2011-08-19 15:27:58 +02:00
{
2012-08-06 23:42:46 +02:00
qWarning ( " FhgAacEnc version is too much outdated (%s) -> FhgAacEnc support will be disabled! " , lamexp_version2string ( " ????-??-?? " , fhgVersion , " N/A " ) . toLatin1 ( ) . constData ( ) ) ;
qWarning ( " Minimum required FhgAacEnc version currently is: %s \n " , lamexp_version2string ( " ????-??-?? " , lamexp_toolver_fhgaacenc ( ) , " N/A " ) . toLatin1 ( ) . constData ( ) ) ;
for ( int i = 0 ; i < 5 ; i + + ) LAMEXP_DELETE ( fhgBin [ i ] ) ;
2011-08-19 15:27:58 +02:00
return ;
}
2012-08-06 23:42:46 +02:00
for ( int i = 0 ; i < 5 ; i + + )
2011-08-19 15:27:58 +02:00
{
lamexp_register_tool ( fhgFileInfo [ i ] . fileName ( ) , fhgBin [ i ] , fhgVersion ) ;
}
}
2010-12-12 13:44:11 +01:00
2011-11-21 01:22:41 +01:00
void InitializationThread : : initQAac ( void )
{
const QString appPath = QDir ( QCoreApplication : : applicationDirPath ( ) ) . canonicalPath ( ) ;
2011-11-21 22:28:14 +01:00
2011-11-22 23:48:54 +01:00
QFileInfo qaacFileInfo [ 2 ] ;
qaacFileInfo [ 0 ] = QFileInfo ( QString ( " %1/qaac.exe " ) . arg ( appPath ) ) ;
qaacFileInfo [ 1 ] = QFileInfo ( QString ( " %1/libsoxrate.dll " ) . arg ( appPath ) ) ;
2011-11-21 01:22:41 +01:00
bool qaacFilesFound = true ;
2011-11-23 00:03:42 +01:00
for ( int i = 0 ; i < 2 ; i + + ) { if ( ! qaacFileInfo [ i ] . exists ( ) ) qaacFilesFound = false ; }
2011-11-21 01:22:41 +01:00
2011-11-21 14:40:32 +01:00
//Lock the QAAC binaries
2011-11-21 01:22:41 +01:00
if ( ! qaacFilesFound )
{
qDebug ( " QAAC binaries not found -> QAAC support will be disabled! \n " ) ;
return ;
}
2013-10-21 15:00:55 +02:00
qDebug ( " Found QAAC encoder: \n %s \n " , QUTF8 ( qaacFileInfo [ 0 ] . canonicalFilePath ( ) ) ) ;
2011-11-22 23:48:54 +01:00
LockedFile * qaacBin [ 2 ] ;
for ( int i = 0 ; i < 2 ; i + + ) qaacBin [ i ] = NULL ;
2011-11-21 01:22:41 +01:00
try
{
2011-11-22 23:48:54 +01:00
for ( int i = 0 ; i < 2 ; i + + )
{
qaacBin [ i ] = new LockedFile ( qaacFileInfo [ i ] . canonicalFilePath ( ) ) ;
}
2011-11-21 01:22:41 +01:00
}
catch ( . . . )
{
2011-11-22 23:48:54 +01:00
for ( int i = 0 ; i < 2 ; i + + ) LAMEXP_DELETE ( qaacBin [ i ] ) ;
2011-11-21 14:40:32 +01:00
qWarning ( " Failed to get excluive lock to QAAC binary -> QAAC support will be disabled! " ) ;
2011-11-21 01:22:41 +01:00
return ;
}
QProcess process ;
2013-10-29 02:05:43 +01:00
lamexp_init_process ( process , qaacFileInfo [ 0 ] . absolutePath ( ) ) ;
2011-11-22 23:48:54 +01:00
process . start ( qaacFileInfo [ 0 ] . canonicalFilePath ( ) , QStringList ( ) < < " --check " ) ;
2011-11-21 01:22:41 +01:00
if ( ! process . waitForStarted ( ) )
{
qWarning ( " QAAC process failed to create! " ) ;
qWarning ( " Error message: \" %s \" \n " , process . errorString ( ) . toLatin1 ( ) . constData ( ) ) ;
process . kill ( ) ;
process . waitForFinished ( - 1 ) ;
2011-11-22 23:48:54 +01:00
for ( int i = 0 ; i < 2 ; i + + ) LAMEXP_DELETE ( qaacBin [ i ] ) ;
2011-11-21 01:22:41 +01:00
return ;
}
QRegExp qaacEncSig ( " qaac ( \\ d) \ \ . ( \ \ d ) ( \ \ d ) " , Qt::CaseInsensitive) ;
2011-11-21 14:40:32 +01:00
QRegExp coreEncSig ( " CoreAudioToolbox ( \\ d) \ \ . ( \ \ d ) \ \ . ( \ \ d ) \ \ . ( \ \ d ) " , Qt::CaseInsensitive) ;
2011-11-21 01:22:41 +01:00
unsigned int qaacVersion = 0 ;
2011-11-21 14:40:32 +01:00
unsigned int coreVersion = 0 ;
2011-11-21 01:22:41 +01:00
while ( process . state ( ) ! = QProcess : : NotRunning )
{
process . waitForReadyRead ( ) ;
if ( ! process . bytesAvailable ( ) & & process . state ( ) = = QProcess : : Running )
{
qWarning ( " QAAC process time out -> killing! " ) ;
process . kill ( ) ;
process . waitForFinished ( - 1 ) ;
2011-11-22 23:48:54 +01:00
for ( int i = 0 ; i < 2 ; i + + ) LAMEXP_DELETE ( qaacBin [ i ] ) ;
2011-11-21 01:22:41 +01:00
return ;
}
while ( process . bytesAvailable ( ) > 0 )
{
QString line = QString : : fromUtf8 ( process . readLine ( ) . constData ( ) ) . simplified ( ) ;
if ( qaacEncSig . lastIndexIn ( line ) > = 0 )
{
unsigned int tmp [ 3 ] = { 0 , 0 , 0 } ;
bool ok [ 3 ] = { false , false , false } ;
tmp [ 0 ] = qaacEncSig . cap ( 1 ) . toUInt ( & ok [ 0 ] ) ;
tmp [ 1 ] = qaacEncSig . cap ( 2 ) . toUInt ( & ok [ 1 ] ) ;
tmp [ 2 ] = qaacEncSig . cap ( 3 ) . toUInt ( & ok [ 2 ] ) ;
if ( ok [ 0 ] & & ok [ 1 ] & & ok [ 2 ] )
{
qaacVersion = ( qBound ( 0U , tmp [ 0 ] , 9U ) * 100 ) + ( qBound ( 0U , tmp [ 1 ] , 9U ) * 10 ) + qBound ( 0U , tmp [ 2 ] , 9U ) ;
}
}
2011-11-21 14:40:32 +01:00
if ( coreEncSig . lastIndexIn ( line ) > = 0 )
{
unsigned int tmp [ 4 ] = { 0 , 0 , 0 , 0 } ;
bool ok [ 4 ] = { false , false , false , false } ;
tmp [ 0 ] = coreEncSig . cap ( 1 ) . toUInt ( & ok [ 0 ] ) ;
tmp [ 1 ] = coreEncSig . cap ( 2 ) . toUInt ( & ok [ 1 ] ) ;
tmp [ 2 ] = coreEncSig . cap ( 3 ) . toUInt ( & ok [ 2 ] ) ;
tmp [ 3 ] = coreEncSig . cap ( 4 ) . toUInt ( & ok [ 3 ] ) ;
if ( ok [ 0 ] & & ok [ 1 ] & & ok [ 2 ] & & ok [ 3 ] )
{
coreVersion = ( qBound ( 0U , tmp [ 0 ] , 9U ) * 1000 ) + ( qBound ( 0U , tmp [ 1 ] , 9U ) * 100 ) + ( qBound ( 0U , tmp [ 2 ] , 9U ) * 10 ) + qBound ( 0U , tmp [ 3 ] , 9U ) ;
}
}
2011-11-21 01:22:41 +01:00
}
}
2011-11-21 14:40:32 +01:00
//qDebug("qaac %d, CoreAudioToolbox %d", qaacVersion, coreVersion);
2011-11-21 01:22:41 +01:00
if ( ! ( qaacVersion > 0 ) )
{
qWarning ( " QAAC version couldn't be determined -> QAAC support will be disabled! " ) ;
2011-11-22 23:48:54 +01:00
for ( int i = 0 ; i < 2 ; i + + ) LAMEXP_DELETE ( qaacBin [ i ] ) ;
2011-11-21 01:22:41 +01:00
return ;
}
else if ( qaacVersion < lamexp_toolver_qaacenc ( ) )
{
2011-11-21 14:40:32 +01:00
qWarning ( " QAAC version is too much outdated (%s) -> QAAC support will be disabled! " , lamexp_version2string ( " v?.?? " , qaacVersion , " N/A " ) . toLatin1 ( ) . constData ( ) ) ;
2012-08-05 22:40:56 +02:00
qWarning ( " Minimum required QAAC version currently is: %s. \n " , lamexp_version2string ( " v?.?? " , lamexp_toolver_qaacenc ( ) , " N/A " ) . toLatin1 ( ) . constData ( ) ) ;
2011-11-22 23:48:54 +01:00
for ( int i = 0 ; i < 2 ; i + + ) LAMEXP_DELETE ( qaacBin [ i ] ) ;
2011-11-21 14:40:32 +01:00
return ;
}
if ( ! ( coreVersion > 0 ) )
{
qWarning ( " CoreAudioToolbox version couldn't be determined -> QAAC support will be disabled! " ) ;
2011-11-22 23:48:54 +01:00
for ( int i = 0 ; i < 2 ; i + + ) LAMEXP_DELETE ( qaacBin [ i ] ) ;
2011-11-21 14:40:32 +01:00
return ;
}
else if ( coreVersion < lamexp_toolver_coreaudio ( ) )
{
qWarning ( " CoreAudioToolbox version is too much outdated (%s) -> QAAC support will be disabled! " , lamexp_version2string ( " v?.?.?.? " , coreVersion , " N/A " ) . toLatin1 ( ) . constData ( ) ) ;
2012-08-05 22:40:56 +02:00
qWarning ( " Minimum required CoreAudioToolbox version currently is: %s. \n " , lamexp_version2string ( " v?.?? " , lamexp_toolver_coreaudio ( ) , " N/A " ) . toLatin1 ( ) . constData ( ) ) ;
2011-11-22 23:48:54 +01:00
for ( int i = 0 ; i < 2 ; i + + ) LAMEXP_DELETE ( qaacBin [ i ] ) ;
2011-11-21 01:22:41 +01:00
return ;
}
2011-11-22 23:48:54 +01:00
lamexp_register_tool ( qaacFileInfo [ 0 ] . fileName ( ) , qaacBin [ 0 ] , qaacVersion ) ;
lamexp_register_tool ( qaacFileInfo [ 1 ] . fileName ( ) , qaacBin [ 1 ] , qaacVersion ) ;
2011-11-21 01:22:41 +01:00
}
2011-10-19 00:24:03 +02:00
void InitializationThread : : selfTest ( void )
{
const unsigned int cpu [ 4 ] = { CPU_TYPE_X86_GEN , CPU_TYPE_X86_SSE , CPU_TYPE_X64_GEN , CPU_TYPE_X64_SSE } ;
2013-10-20 19:12:55 +02:00
LockedFile : : selfTest ( ) ;
2011-10-19 00:24:03 +02:00
for ( size_t k = 0 ; k < 4 ; k + + )
{
qDebug ( " [TEST] " ) ;
switch ( cpu [ k ] )
{
PRINT_CPU_TYPE ( CPU_TYPE_X86_GEN ) ; break ;
PRINT_CPU_TYPE ( CPU_TYPE_X86_SSE ) ; break ;
PRINT_CPU_TYPE ( CPU_TYPE_X64_GEN ) ; break ;
PRINT_CPU_TYPE ( CPU_TYPE_X64_SSE ) ; break ;
2013-10-18 21:37:40 +02:00
default : THROW ( " CPU support undefined! " ) ;
2011-10-19 00:24:03 +02:00
}
2013-10-20 19:12:55 +02:00
unsigned int n = 0 ;
for ( int i = 0 ; true ; i + + )
2011-10-19 00:24:03 +02:00
{
2013-10-20 19:12:55 +02:00
if ( ! ( g_lamexp_tools [ i ] . pcName | | g_lamexp_tools [ i ] . pcHash | | g_lamexp_tools [ i ] . uiVersion ) )
2011-10-19 00:24:03 +02:00
{
break ;
}
2013-10-20 19:12:55 +02:00
else if ( g_lamexp_tools [ i ] . pcName & & g_lamexp_tools [ i ] . pcHash & & g_lamexp_tools [ i ] . uiVersion )
{
const QString toolName = QString : : fromLatin1 ( g_lamexp_tools [ i ] . pcName ) ;
const QByteArray expectedHash = QByteArray ( g_lamexp_tools [ i ] . pcHash ) ;
if ( g_lamexp_tools [ i ] . uiCpuType & cpu [ k ] )
{
2013-10-21 15:00:55 +02:00
qDebug ( " %02i -> %s " , + + n , QUTF8 ( toolName ) ) ;
2013-10-20 19:12:55 +02:00
QFile resource ( QString ( " :/tools/%1 " ) . arg ( toolName ) ) ;
if ( ! resource . open ( QIODevice : : ReadOnly ) )
{
2013-10-21 15:00:55 +02:00
qFatal ( " The resource for \" %s \" could not be opened! " , QUTF8 ( toolName ) ) ;
2013-10-20 19:12:55 +02:00
break ;
}
QByteArray hash = LockedFile : : fileHash ( resource ) ;
if ( hash . isNull ( ) | | _stricmp ( hash . constData ( ) , expectedHash . constData ( ) ) )
{
2013-10-21 15:00:55 +02:00
qFatal ( " Hash check for tool \" %s \" has failed! " , QUTF8 ( toolName ) ) ;
2013-10-20 19:12:55 +02:00
break ;
}
resource . close ( ) ;
}
}
else
2011-10-19 00:24:03 +02:00
{
2013-10-20 19:12:55 +02:00
qFatal ( " Inconsistent checksum data detected. Take care! " ) ;
2011-10-19 00:24:03 +02:00
}
}
2013-11-01 19:34:27 +01:00
if ( n ! = EXPECTED_TOOL_COUNT )
2011-10-19 00:24:03 +02:00
{
2013-10-20 19:12:55 +02:00
qFatal ( " Tool count mismatch for CPU type %u !!! " , cpu [ 4 ] ) ;
2011-10-19 00:24:03 +02:00
}
qDebug ( " Done. \n " ) ;
}
}
2010-12-12 13:44:11 +01:00
2010-11-06 23:04:47 +01:00
////////////////////////////////////////////////////////////
// EVENTS
////////////////////////////////////////////////////////////
2013-11-01 19:34:27 +01:00
/*NONE*/