Added support for the QAAC Encoder, requires QuickTime v7.7.1 or newer (see FAQ doc for details)
Updated LAME encoder to v3.99.2 Final (2011-11-18), compiled with ICL 12.1.7 and MSVC 10.0 (details)
+
Updated MediaInfo to v0.7.51+ (2011-11-19), compiled with ICL 12.1.6 and MSVC 10.0
Implemented coalescing of update signals in order to reduce the CPU usage of the LameXP process
diff --git a/doc/FAQ.html b/doc/FAQ.html
index a7a87d90..9d0d167e 100644
--- a/doc/FAQ.html
+++ b/doc/FAQ.html
@@ -304,6 +304,7 @@ the same directory where your LameXP executable ('LameXP.exe') is located. For u
use any suitable archiver, such as WinRAR or 7-Zip. Once the required Nero encoder binaries are located in
the LameXP directory, the AAC encoding option should be "enabled" on the next startup of LameXP.
+
Optionally LameXP also supports the FHG AAC Encoder now. Just like the Nero encoder, the FHG encoder can NOT
be redistributed along with LameXP. However the FHG AAC Encoder is included with Winamp v5.62, which is
available as a free download (you don't need to buy the "Pro" version!) from the official Winamp web-site at:
@@ -320,7 +321,17 @@ In order to enable the FHG AAC Encoder support you will also need the 'FHG AAC E
Please follow the install instructions that are included with the 'FHG AAC Encoder Add-in' download package!
-Note that you do NOT need to install the Add-in, if you only want to use the Nero AAC Encoder.
+Note that you do NOT need to install the Add-in, if you only want to use the Nero AAC Encoder.
+
+
+As a third option, LameXP supports the QAAC encoder, i.e. the AAC encoder of QuickTime/iTunes. Just like the
+other two AAC encoders, the QAAC encoder can NOT be redistributed along with LameXP. Thus if you want to use
+the QAAC encoder, then you have to install QuickTime v7.7.1 (or newer). Alternatively iTunes v10.5 (or newer)
+can be installed. Both, QuickTime and iTunes, can be downloaded for free from the official Apple web-site.
+
+In addition to installing QuickTime/iTunes, you must download the QAAC encoder from this web-site. Then put
+'qaac.exe' and 'libsoxrate.dll' as well as 'msvcr100.dll' and 'msvcp100.dll' into the same directory where
+your LameXP executable ('LameXP.exe') is located. QAAC will then be "enabled" on the next startup of LameXP.
diff --git a/etc/Translation/Blank.ts b/etc/Translation/Blank.ts
index b2bddfbc..4e068ca7 100644
--- a/etc/Translation/Blank.ts
+++ b/etc/Translation/Blank.ts
@@ -710,7 +710,7 @@
-
+
@@ -1367,9 +1367,9 @@
-
-
-
+
+
+
@@ -1410,13 +1410,13 @@
-
+
-
+
@@ -1496,704 +1496,704 @@
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
-
+
+
-
-
+
+
+
-
-
+
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2633,114 +2633,114 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
@@ -2761,17 +2761,17 @@
QApplication
-
+
-
+
-
+
diff --git a/etc/Translation/LameXP_PL.ts b/etc/Translation/LameXP_PL.ts
index 1b9533f9..a5efd7cb 100644
--- a/etc/Translation/LameXP_PL.ts
+++ b/etc/Translation/LameXP_PL.ts
@@ -710,7 +710,7 @@
-
+ Pokaż szczegóły
@@ -1367,9 +1367,9 @@
-
-
-
+
+
+ Sprawdź aktualizacje
@@ -1410,13 +1410,13 @@
-
+ Wyłącz przypominanie o aktualizacji
-
+ Wyłącz efekty dźwiękowe
@@ -1496,704 +1496,704 @@
-
+ Dodawanie plików, prosze czekać...
-
-
+
+ Dostęp zablokowany
-
+ %1 plik(ów) zostało odrzuconych z powodu braku dostępu do pliku!
-
+ To przeważnie oznacza, że plik jest zablokowany przez inny proces.
-
+ Pliki CDDA
-
+ %1 plik(ów) zostało odrzuconych ponieważ to nie są właściwe pliki CDDA!
-
+ LameXP nie może teraz wyekstrachować ścieżki z płyty Audio-CD.
-
+ Zaleca się użycie w tym celu %1.
-
+ Cue Sheet
-
+ %1 plik(ów) zostało odrzuconych, ponieważ to nie są pliki obrazów Cue Sheet!
-
+ Prosze użyć przewodnika Cue Sheet w LameXP w celu importowania tych plików.
-
+ Pliki odrzucone
-
+ %1 plik(ów) zostało odrzuconych, ponieważ ich format nie został rozpoznany!
-
+ To przeważnie oznacza że plik jest uszkodzony lub format pliku nie jest wspierany.
-
+ Skanowanie folderu/ów, prosze czekać...
-
+ Tutaj możesz upuścić pliki dźwiękowe!
-
+ Otwórz plik w zewnętrznym programie
-
+ Otwórz lokalizację pliku
-
+ Otwórz wybrany folder
-
+ Zapamiętaj wybrany folder
-
+ Licencja odrzucona
-
+ Odrzuciłeś licencję. W takim razie program zostanie teraz zamknięty!
-
+ Naraska!
-
+ LameXP - Termin wygasł
-
+ Ta wersja demo (beta) LameXP wygasła %1.
-
+ LameXP jest darmowym oprogramowaniem i pełna wersja nie wygasa.
-
-
+
+ Wyjdź z programu
-
+
-
+ Prosze sprawdzić dokument %1 w celu dalszych szcegółów i rozwiązań!
-
+ Powolny start
-
-
-
+
+
-
-
+
+
+ Zamknij
-
-
+
+ Nie pokazuj ponownie
-
+ Ważna aktualizacja
-
+ Twoja wersja LameXP jest starsza niż rok! Czas na aktualizację!
-
-
-
+
+
+ Powiadomienie aktualizacji
-
+ Ostatnie sprawdzenie aktualizacji było ponad 14 dni temu. Sprawdzić teraz aktualizacje?
-
+ Nie sprawdzałeś jeszcze aktualizacji LameXP. Sprawdzić teraz aktualizacje?
-
+ Przełóż
-
+ LameXP wykrył że Twoja wersja kodera Nero AAC jest nieaktualna!
-
+ Wersją dostępną obecnie jest %1, Twoja wersja to %2.
-
+ n/d
-
+ Możesz pobrać najnowszą wersję kodera Nero AAC ze strony Nero:
-
+ Koder AAC jest nieaktualny
-
+ Nie można odnaleźć kodera Nero AAC. Kompresja formatu AAC zostanie wyłączona.
-
+ Prosze skopiować 'neroAacEnc.exe', 'neroAacDec.exe', oraz 'neroAacTag.exe' do folderu LameXP!
-
+ Folder aplikacji LameXP znajduje się tutaj:
-
+ Możesz pobrać koder Nero AAC za darmo z oficjalnej strony Nero:
-
+ Wsparcie dla AAC wyłączone
-
-
-
+
+
+ LameXP
-
+ Powinienieś dodać przynajmniej jeden plik do listy aby zacząć działać!
-
+ Nie znaleziono
-
+ Wybrany przez Ciebie folder tymczasowy TEMP już nie istnieje:
-
+ Przywróć domyślne
-
+ Anuluj
-
+ Ostrzeżenie o małej ilości miejsca na dysku
-
+ Jest mniej niż %1 GB dostępnego miejsca w systemowym folderze TEMP.
-
+
-
+
-
+ Jest wysoce zalecane zwolnić miejsce na dysku zanim zaczniesz kompresję!
-
+ Twój folder TEMP znajduję się:
-
+ Przerwij proces kompresji
-
+ Wykonaj oczyszczanie dysku
-
+ Ignoruj
-
+ Mało miejsca na dysku
-
+ Chcesz zacząć działać z małą ilością miejsca na dysku. Mogą wystąpić problemy!
-
+ Został wybrany koder, który nie jest wspierany!
-
+ Nie można zapisać do wybranej lokalizacji.
-
+ Prosze wybrać inną lokalizację!
-
+ Zaladuj plik językowy
-
+ Pliki językowe
-
+ Czy na pewno chcesz wyłączyć przypominanie o aktualizacjach?
-
-
-
-
-
-
-
+
+
+
+
+
+
+ Tak
-
-
-
-
-
-
-
+
+
+
+
+
+
+ Nie
-
+ Przypominanie o aktualizacjach wyłączone.
-
+ Prosze pamiętać o okresowym sprawdzaniu aktualizacji!
-
+ Przypominanie o aktualizacjach ponownie włączone.
-
+ Czy na pewno chcesz wyłączyć wszystkie dźwiękowe?
-
-
+
+ Efekty dźwiękowe
-
+ Wszystkie efekty dźwiękowe zostały wyłączone.
-
+ Efekty dźwiękowe zostały ponownie włączone.
-
-
-
+
+
+ Powiadomienia Nero AAC
-
+ Czy na pewno chcesz wyłączyć wszystkie powiadomienia Nero AAC?
-
+ Wszystkie powiadomienia kodera Nero AAC zostały wyłączone.
-
+ Powiadomienia Nero AAC zostały ponownie włączone.
-
-
-
+
+
+ Powiadomienia o powolnym starcie
-
+ Czy na pewno chcesz wyłączyć powiadomienia o powolnym starcie?
-
+ Powiadomienia o powolnym starcie zostały wyłączone.
-
+ Powiadomienia o powolnym starcie zostały ponownie włączone.
-
-
+
+ Otwórz plik Cue Sheet
-
-
+
+ Plik Cue Sheet
-
-
-
+
+
+ Aktualizacje Beta
-
+ Czy na pewno chcesz aby LameXP sprawdzał aktualizacje Beta?
-
+ Od teraz LameXP będzie sprawdzał aktualizacje Beta.
-
+ Sprawdź teraz
-
+ LameXP od teraz <i>nie będzie</i> sprawdzał aktualizacji Beta.
-
-
-
+
+
+
-
+
-
+
-
+
-
-
-
+
+
+ Integracja z systemem
-
+ Czy na pewno chcesz wyłączyć integrację LameXP z systemem?
-
+ Integracja LameXP z systemem zostałą wyłączona.
-
+ Integracja LameXP z systemem została ponownie włączona.
-
-
+
+ Dodaj plik(i)
-
-
+
+ Dodaj folder
-
-
+
+ Nowy folder
-
+ Wprowadź nazwę nowego folderu:
-
+ Utworzenie folderu zakończone niepowodzeniem
-
+ Nowy folder nie mógł zostać stworzony:
-
+ Dysk tylko do odczytu lub brak praw dostępu!
-
-
-
-
+
+
+
+ Poziom jakości %1
-
-
-
+
+
+ Kompresja %1
-
-
-
+
+
+ Nieskompresowany
-
+ Najlepsza jakość (Bardzo wolno)
-
+ Wysoka jakość (Zalecane)
-
+ Średnia jakość (Domyślnie)
-
+ Niska jakość (Szybko)
-
+ Najniższa jakość (Bardzo szybko)
-
+ Nazwa pliku bez rozszerzenia
-
+ Numer ścieżki z zerem na początku
-
+ Nazwa ścieżki
-
+ Nazwa Artysty
-
+ Nazwa Albumu
-
+ Rok z (przynajmniej) czterema cyframi
-
+ Komentarz
-
+ Zabronione znaki w nazwach plików:
-
+ Zmień nazwy makr
-
+ %1 wątek/ki
-
+ Nie można zapisać do wybranej lokalizacji. Prosze wybierz inną lokalizację!
-
+ Już działa
-
+ LameXP już działa, przejdź do działającego programu!
@@ -2633,114 +2633,114 @@
Powrót
-
+ Pokaż szczegóły wybranego zadania
-
+ Wybierz lokalizację dla plików wyjściowych
-
+ Kompresowanie plików
-
+ Twoje pliki są właśnie kompresowane, prosze być cierpliwy...
-
+ Kompresowanie plików, prosze czekać...
-
+ Wielowątkowosć włączona: Równolegle wykonywanych jest %1 kodowań!
-
+ Przerwano! Czekanie na wyłączenie procesu...
-
+ Kompresja: Prosze czekać, jak dotąd wykonano %1 z %2 plików...
-
+ Tworzenie pliku playlisty, prosze czekać...
-
+ Proces został przerwany przez użytkownika po wykonaniu %1 plików!
-
+ Proces został przedwcześnie zakończony przez użytkownika!
-
+ LameXP - Przerwano
-
+ Proces został przerwany przez użytkownika.
-
+ Błąd: %1 z %2 plików nie zostało skompresowanych. Kliknij dwukrotnie na plik aby zobaczyć szczegóły!
-
+ LameXP - Błąd
-
+ Przynajmniej jeden plik nie został skompresowany!
-
+ Kompresja wszystkich plików zakończona powodzeniem.
-
+ LameXP - Zrobione
-
+ Tworzenie playlisty zakończone niepowodzeniem
-
+ Playlista nie mogła zostać utworzona:
-
+ Ostrzeżenie: Komputer zostanie zamknięty za %1 sekund/y...
-
-
+
+ Anuluj wyłączenie komputera
@@ -2761,17 +2761,17 @@
QApplication
-
+ Plik wykonywalny '%1' nie działa w trybie kompatybilności z Windows.
-
+ Plik wykonywalny '%1' wymaga Qt v%2, znaleziono jednak Qt v%3.
-
+ Plik wykonywalny '%1' wymaga do uruchomienia Windows 2000 lub nowszego.
diff --git a/src/Config.h b/src/Config.h
index 0aa377d5..360676c3 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -29,8 +29,8 @@
#define VER_LAMEXP_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 4
#define VER_LAMEXP_TYPE Alpha
-#define VER_LAMEXP_PATCH 1
-#define VER_LAMEXP_BUILD 781
+#define VER_LAMEXP_PATCH 2
+#define VER_LAMEXP_BUILD 782
///////////////////////////////////////////////////////////////////////////////
// Tools versions
@@ -38,6 +38,7 @@
#define VER_LAMEXP_TOOL_NEROAAC 1540
#define VER_LAMEXP_TOOL_FHGAACENC 20110822
+#define VER_LAMEXP_TOOL_QAAC 104
///////////////////////////////////////////////////////////////////////////////
// Helper macros (aka: having fun with the C pre-processor)
diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp
index b2427898..bed1b7ed 100644
--- a/src/Dialog_MainWindow.cpp
+++ b/src/Dialog_MainWindow.cpp
@@ -90,6 +90,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
m_settings(settingsModel),
m_neroEncoderAvailable(lamexp_check_tool("neroAacEnc.exe") && lamexp_check_tool("neroAacDec.exe") && lamexp_check_tool("neroAacTag.exe")),
m_fhgEncoderAvailable(lamexp_check_tool("fhgaacenc.exe") && lamexp_check_tool("enc_fhgaac.dll") && lamexp_check_tool("nsutil.dll") && lamexp_check_tool("libmp4v2.dll")),
+ m_qaacEncoderAvailable(lamexp_check_tool("qaac.exe") && lamexp_check_tool("libsoxrate.dll") && lamexp_check_tool("msvcp100.dll") && lamexp_check_tool("msvcr100.dll")),
m_accepted(false),
m_firstTimeShown(true),
m_OutputFolderViewInitialized(false)
@@ -207,10 +208,10 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
m_modeButtonGroup->addButton(radioButtonModeQuality, SettingsModel::VBRMode);
m_modeButtonGroup->addButton(radioButtonModeAverageBitrate, SettingsModel::ABRMode);
m_modeButtonGroup->addButton(radioButtonConstBitrate, SettingsModel::CBRMode);
- radioButtonEncoderAAC->setEnabled(m_neroEncoderAvailable || m_fhgEncoderAvailable);
+ radioButtonEncoderAAC->setEnabled(m_neroEncoderAvailable || m_fhgEncoderAvailable || m_qaacEncoderAvailable);
radioButtonEncoderMP3->setChecked(m_settings->compressionEncoder() == SettingsModel::MP3Encoder);
radioButtonEncoderVorbis->setChecked(m_settings->compressionEncoder() == SettingsModel::VorbisEncoder);
- radioButtonEncoderAAC->setChecked((m_settings->compressionEncoder() == SettingsModel::AACEncoder) && (m_neroEncoderAvailable || m_fhgEncoderAvailable));
+ radioButtonEncoderAAC->setChecked((m_settings->compressionEncoder() == SettingsModel::AACEncoder) && (m_neroEncoderAvailable || m_fhgEncoderAvailable || m_qaacEncoderAvailable));
radioButtonEncoderAC3->setChecked(m_settings->compressionEncoder() == SettingsModel::AC3Encoder);
radioButtonEncoderFLAC->setChecked(m_settings->compressionEncoder() == SettingsModel::FLACEncoder);
radioButtonEncoderPCM->setChecked(m_settings->compressionEncoder() == SettingsModel::PCMEncoder);
@@ -246,7 +247,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
while(checkBoxUseSystemTempFolder->isChecked() == m_settings->customTempPathEnabled()) checkBoxUseSystemTempFolder->click();
while(checkBoxRenameOutput->isChecked() != m_settings->renameOutputFilesEnabled()) checkBoxRenameOutput->click();
while(checkBoxForceStereoDownmix->isChecked() != m_settings->forceStereoDownmix()) checkBoxForceStereoDownmix->click();
- checkBoxNeroAAC2PassMode->setEnabled(!m_fhgEncoderAvailable);
+ checkBoxNeroAAC2PassMode->setEnabled(!(m_fhgEncoderAvailable || m_qaacEncoderAvailable));
lineEditCustomParamLAME->setText(m_settings->customParametersLAME());
lineEditCustomParamOggEnc->setText(m_settings->customParametersOggEnc());
lineEditCustomParamNeroAAC->setText(m_settings->customParametersAacEnc());
@@ -1042,7 +1043,7 @@ void MainWindow::windowShown(void)
}
else
{
- if(m_settings->neroAacNotificationsEnabled() && (!m_fhgEncoderAvailable))
+ if(m_settings->neroAacNotificationsEnabled() && (!(m_fhgEncoderAvailable || m_qaacEncoderAvailable)))
{
QString appPath = QDir(QCoreApplication::applicationDirPath()).canonicalPath();
if(appPath.isEmpty()) appPath = QCoreApplication::applicationDirPath();
diff --git a/src/Dialog_MainWindow.h b/src/Dialog_MainWindow.h
index b055938c..ce672129 100644
--- a/src/Dialog_MainWindow.h
+++ b/src/Dialog_MainWindow.h
@@ -160,6 +160,7 @@ private:
const bool m_neroEncoderAvailable;
const bool m_fhgEncoderAvailable;
+ const bool m_qaacEncoderAvailable;
WorkingBanner *m_banner;
QStringList *m_delayedFileList;
diff --git a/src/Dialog_Processing.cpp b/src/Dialog_Processing.cpp
index 326b33a8..7eb6f359 100644
--- a/src/Dialog_Processing.cpp
+++ b/src/Dialog_Processing.cpp
@@ -35,6 +35,7 @@
#include "Encoder_Vorbis.h"
#include "Encoder_AAC.h"
#include "Encoder_AAC_FHG.h"
+#include "Encoder_AAC_QAAC.h"
#include "Encoder_AC3.h"
#include "Encoder_FLAC.h"
#include "Encoder_Wave.h"
@@ -660,7 +661,16 @@ void ProcessingDialog::startNextJob(void)
break;
case SettingsModel::AACEncoder:
{
- if(lamexp_check_tool("fhgaacenc.exe") && lamexp_check_tool("enc_fhgaac.dll"))
+ if(lamexp_check_tool("qaac.exe") && lamexp_check_tool("libsoxrate.dll"))
+ {
+ QAACEncoder *aacEncoder = new QAACEncoder();
+ aacEncoder->setBitrate(m_settings->compressionBitrate());
+ aacEncoder->setRCMode(m_settings->compressionRCMode());
+ aacEncoder->setProfile(m_settings->aacEncProfile());
+ aacEncoder->setCustomParams(m_settings->customParametersAacEnc());
+ encoder = aacEncoder;
+ }
+ else if(lamexp_check_tool("fhgaacenc.exe") && lamexp_check_tool("enc_fhgaac.dll"))
{
FHGAACEncoder *aacEncoder = new FHGAACEncoder();
aacEncoder->setBitrate(m_settings->compressionBitrate());
diff --git a/src/Encoder_AAC.cpp b/src/Encoder_AAC.cpp
index 2f311842..253d4579 100644
--- a/src/Encoder_AAC.cpp
+++ b/src/Encoder_AAC.cpp
@@ -54,7 +54,7 @@ bool AACEncoder::encode(const QString &sourceFile, const AudioFileModel &metaInf
switch(m_configRCMode)
{
case SettingsModel::VBRMode:
- args << "-q" << QString().sprintf("%.2f", qMin(1.0, qMax(0.0, static_cast(m_configBitrate * 5) / 100.0)));
+ args << "-q" << QString().sprintf("%.2f", qBound(0.0, static_cast(m_configBitrate * 5) / 100.0, 1.0));
break;
case SettingsModel::ABRMode:
args << "-br" << QString::number(qMax(32, qMin(500, (m_configBitrate * 8))) * 1000);
diff --git a/src/Encoder_AAC_QAAC.cpp b/src/Encoder_AAC_QAAC.cpp
new file mode 100644
index 00000000..f9c95fd9
--- /dev/null
+++ b/src/Encoder_AAC_QAAC.cpp
@@ -0,0 +1,184 @@
+///////////////////////////////////////////////////////////////////////////////
+// LameXP - Audio Encoder Front-End
+// Copyright (C) 2004-2011 LoRd_MuldeR
+//
+// 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.
+//
+// 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 "Encoder_AAC_QAAC.h"
+
+#include "Global.h"
+#include "Model_Settings.h"
+
+#include
+#include
+#include
+
+QAACEncoder::QAACEncoder(void)
+:
+ m_binary_enc(lamexp_lookup_tool("qaac.exe")),
+ m_binary_dll(lamexp_lookup_tool("libsoxrate.dll"))
+{
+ if(m_binary_enc.isEmpty() || m_binary_dll.isEmpty())
+ {
+ throw "Error initializing QAAC. Tool 'qaac.exe' is not registred!";
+ }
+
+ m_configProfile = 0;
+}
+
+QAACEncoder::~QAACEncoder(void)
+{
+}
+
+bool QAACEncoder::encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag)
+{
+ QProcess process;
+ QStringList args;
+
+ if(m_configRCMode != SettingsModel::VBRMode)
+ {
+ switch(m_configProfile)
+ {
+ case 2:
+ case 3:
+ args << "--he"; //Forces use of HE AAC profile (there is no explicit HEv2 switch for QAAC)
+ break;
+ }
+ }
+
+ switch(m_configRCMode)
+ {
+ case SettingsModel::CBRMode:
+ args << "--cbr" << QString::number(qBound(32, m_configBitrate * 8, 500));
+ break;
+ case SettingsModel::ABRMode:
+ args << "--abr" << QString::number(qBound(32, m_configBitrate * 8, 500));
+ break;
+ case SettingsModel::VBRMode:
+ args << "--tvbr" << QString::number(qBound(0, qRound((static_cast(m_configBitrate * 5) / 100.0) * 127.0), 127));
+ break;
+ default:
+ throw "Bad rate-control mode!";
+ break;
+ }
+
+ if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);
+
+ if(!metaInfo.fileName().isEmpty()) args << "--title" << metaInfo.fileName();
+ if(!metaInfo.fileArtist().isEmpty()) args << "--artist" << metaInfo.fileArtist();
+ if(!metaInfo.fileAlbum().isEmpty()) args << "--album" << metaInfo.fileAlbum();
+ if(!metaInfo.fileGenre().isEmpty()) args << "--genre" << metaInfo.fileGenre();
+ if(!metaInfo.fileComment().isEmpty()) args << "--comment" << metaInfo.fileComment();
+ if(metaInfo.fileYear()) args << "--date" << QString::number(metaInfo.fileYear());
+ if(metaInfo.filePosition()) args << "--track" << QString::number(metaInfo.filePosition());
+ if(!metaInfo.fileCover().isEmpty()) args << "--artwork" << metaInfo.fileCover();
+
+ args << "-o" << QDir::toNativeSeparators(outputFile);
+ args << QDir::toNativeSeparators(sourceFile);
+
+ if(!startProcess(process, m_binary_enc, args))
+ {
+ return false;
+ }
+
+ bool bTimeout = false;
+ bool bAborted = false;
+ int prevProgress = -1;
+
+ QRegExp regExp("\\[(\\d+)\\.(\\d)%\\]");
+
+ while(process.state() != QProcess::NotRunning)
+ {
+ if(*abortFlag)
+ {
+ process.kill();
+ bAborted = true;
+ emit messageLogged("\nABORTED BY USER !!!");
+ break;
+ }
+ process.waitForReadyRead(m_processTimeoutInterval);
+ if(!process.bytesAvailable() && process.state() == QProcess::Running)
+ {
+ process.kill();
+ qWarning("QAAC process timed out <-- killing!");
+ emit messageLogged("\nPROCESS TIMEOUT !!!");
+ bTimeout = true;
+ break;
+ }
+ while(process.bytesAvailable() > 0)
+ {
+ QByteArray line = process.readLine();
+ QString text = QString::fromUtf8(line.constData()).simplified();
+ if(regExp.lastIndexIn(text) >= 0)
+ {
+ bool ok = false;
+ int progress = regExp.cap(1).toInt(&ok);
+ if(ok && (progress > prevProgress))
+ {
+ emit statusUpdated(progress);
+ prevProgress = qMin(progress + 2, 99);
+ }
+ }
+ else if(!text.isEmpty())
+ {
+ emit messageLogged(text);
+ }
+ }
+ }
+
+ process.waitForFinished();
+ if(process.state() != QProcess::NotRunning)
+ {
+ process.kill();
+ process.waitForFinished(-1);
+ }
+
+ emit statusUpdated(100);
+ emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));
+
+ if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+QString QAACEncoder::extension(void)
+{
+ return "mp4";
+}
+
+bool QAACEncoder::isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion)
+{
+ if(containerType.compare("Wave", Qt::CaseInsensitive) == 0)
+ {
+ if(formatType.compare("PCM", Qt::CaseInsensitive) == 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+void QAACEncoder::setProfile(int profile)
+{
+ m_configProfile = profile;
+}
diff --git a/src/Encoder_AAC_QAAC.h b/src/Encoder_AAC_QAAC.h
new file mode 100644
index 00000000..ca52c0c6
--- /dev/null
+++ b/src/Encoder_AAC_QAAC.h
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////
+// LameXP - Audio Encoder Front-End
+// Copyright (C) 2004-2011 LoRd_MuldeR
+//
+// 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.
+//
+// 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
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include "Encoder_Abstract.h"
+
+#include
+
+class QAACEncoder : public AbstractEncoder
+{
+ Q_OBJECT
+
+public:
+ QAACEncoder(void);
+ ~QAACEncoder(void);
+
+ virtual bool encode(const QString &sourceFile, const AudioFileModel &metaInfo, const QString &outputFile, volatile bool *abortFlag);
+ virtual bool isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion);
+ virtual QString extension(void);
+
+ //Advanced options
+ virtual void setProfile(int profile);
+
+private:
+ const QString m_binary_enc;
+ const QString m_binary_dll;
+ int m_configProfile;
+};
diff --git a/src/Global.cpp b/src/Global.cpp
index 050eff40..40b7404c 100644
--- a/src/Global.cpp
+++ b/src/Global.cpp
@@ -169,6 +169,7 @@ static const char *g_lamexp_support_url = "http://forum.doom9.org/showthread.php
//Tool versions (expected versions!)
static const unsigned int g_lamexp_toolver_neroaac = VER_LAMEXP_TOOL_NEROAAC;
static const unsigned int g_lamexp_toolver_fhgaacenc = VER_LAMEXP_TOOL_FHGAACENC;
+static const unsigned int g_lamexp_toolver_qaacenc = VER_LAMEXP_TOOL_QAAC;
//Special folders
static QString g_lamexp_temp_folder;
@@ -239,7 +240,7 @@ const char *lamexp_version_compiler(void) { return g_lamexp_version_compiler; }
const char *lamexp_version_arch(void) { return g_lamexp_version_arch; }
unsigned int lamexp_toolver_neroaac(void) { return g_lamexp_toolver_neroaac; }
unsigned int lamexp_toolver_fhgaacenc(void) { return g_lamexp_toolver_fhgaacenc; }
-
+unsigned int lamexp_toolver_qaacenc(void) { return g_lamexp_toolver_qaacenc; }
/*
* URL getters
*/
diff --git a/src/Global.h b/src/Global.h
index 4e54423c..9655aff4 100644
--- a/src/Global.h
+++ b/src/Global.h
@@ -81,6 +81,7 @@ const char *lamexp_version_arch(void);
QDate lamexp_version_expires(void);
unsigned int lamexp_toolver_neroaac(void);
unsigned int lamexp_toolver_fhgaacenc(void);
+unsigned int lamexp_toolver_qaacenc(void);
const char *lamexp_website_url(void);
const char *lamexp_support_url(void);
DWORD lamexp_get_os_version(void);
diff --git a/src/Model_Settings.cpp b/src/Model_Settings.cpp
index b135fce6..7094f9a1 100644
--- a/src/Model_Settings.cpp
+++ b/src/Model_Settings.cpp
@@ -222,10 +222,13 @@ void SettingsModel::validate(void)
{
if(!(lamexp_check_tool("fhgaacenc.exe") && lamexp_check_tool("enc_fhgaac.dll")))
{
- if(this->compressionEncoder() == SettingsModel::AACEncoder)
+ if(!(lamexp_check_tool("qaac.exe") && lamexp_check_tool("libsoxrate.dll")))
{
- qWarning("AAC encoder selected, but not available any more. Reverting to MP3!");
- this->compressionEncoder(SettingsModel::MP3Encoder);
+ if(this->compressionEncoder() == SettingsModel::AACEncoder)
+ {
+ qWarning("AAC encoder selected, but not available any more. Reverting to MP3!");
+ this->compressionEncoder(SettingsModel::MP3Encoder);
+ }
}
}
}
diff --git a/src/Thread_Initialization.cpp b/src/Thread_Initialization.cpp
index eb7b4f2d..f2a1e375 100644
--- a/src/Thread_Initialization.cpp
+++ b/src/Thread_Initialization.cpp
@@ -202,11 +202,10 @@ void InitializationThread::run()
//Register all translations
initTranslations();
- //Look for Nero AAC encoder
+ //Look for AAC encoders
initNeroAac();
-
- //Look for FHG AAC encoder
initFhgAac();
+ initQAac();
delay();
m_bSuccess = true;
@@ -482,6 +481,111 @@ void InitializationThread::initFhgAac(void)
}
}
+void InitializationThread::initQAac(void)
+{
+ const QString appPath = QDir(QCoreApplication::applicationDirPath()).canonicalPath();
+
+ QFileInfo qaacFileInfo[4];
+ qaacFileInfo[0] = QFileInfo(QString("%1/qaac.exe").arg(appPath));
+ qaacFileInfo[1] = QFileInfo(QString("%1/libsoxrate.dll").arg(appPath));
+ qaacFileInfo[2] = QFileInfo(QString("%1/msvcp100.dll").arg(appPath));
+ qaacFileInfo[3] = QFileInfo(QString("%1/msvcr100.dll").arg(appPath));
+
+ bool qaacFilesFound = true;
+ for(int i = 0; i < 4; i++) { if(!qaacFileInfo[i].exists()) qaacFilesFound = false; }
+
+ //Lock the FhgAacEnc binaries
+ if(!qaacFilesFound)
+ {
+ qDebug("QAAC binaries not found -> QAAC support will be disabled!\n");
+ return;
+ }
+
+ qDebug("Found QAAC encoder:\n%s\n", qaacFileInfo[0].canonicalFilePath().toUtf8().constData());
+
+ LockedFile *qaacBin[4];
+ for(int i = 0; i < 4; i++) qaacBin[i] = NULL;
+
+ try
+ {
+ for(int i = 0; i < 4; i++)
+ {
+ qaacBin[i] = new LockedFile(qaacFileInfo[i].canonicalFilePath());
+ }
+ }
+ catch(...)
+ {
+ for(int i = 0; i < 4; i++) LAMEXP_DELETE(qaacBin[i]);
+ qWarning("Failed to get excluive lock to FhgAacEnc binary -> FhgAacEnc support will be disabled!");
+ return;
+ }
+
+ QProcess process;
+ process.setProcessChannelMode(QProcess::MergedChannels);
+ process.setReadChannel(QProcess::StandardOutput);
+ process.start(qaacFileInfo[0].canonicalFilePath(), QStringList());
+
+ if(!process.waitForStarted())
+ {
+ qWarning("QAAC process failed to create!");
+ qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData());
+ process.kill();
+ process.waitForFinished(-1);
+ for(int i = 0; i < 4; i++) LAMEXP_DELETE(qaacBin[i]);
+ return;
+ }
+
+ QRegExp qaacEncSig("qaac (\\d)\\.(\\d)(\\d)", Qt::CaseInsensitive);
+ unsigned int qaacVersion = 0;
+
+ 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);
+ for(int i = 0; i < 4; i++) LAMEXP_DELETE(qaacBin[i]);
+ 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);
+ }
+ }
+ }
+ }
+
+ if(!(qaacVersion > 0))
+ {
+ qWarning("QAAC version couldn't be determined -> QAAC support will be disabled!");
+ for(int i = 0; i < 4; i++) LAMEXP_DELETE(qaacBin[i]);
+ return;
+ }
+ else if(qaacVersion < lamexp_toolver_qaacenc())
+ {
+ qWarning("QAAC version is too much outdated -> QAAC support will be disabled!");
+ for(int i = 0; i < 4; i++) LAMEXP_DELETE(qaacBin[i]);
+ return;
+ }
+
+ for(int i = 0; i < 4; i++)
+ {
+ lamexp_register_tool(qaacFileInfo[i].fileName(), qaacBin[i], qaacVersion);
+ }
+}
+
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};
diff --git a/src/Thread_Initialization.h b/src/Thread_Initialization.h
index 73aa956c..94870d1a 100644
--- a/src/Thread_Initialization.h
+++ b/src/Thread_Initialization.h
@@ -45,6 +45,7 @@ private:
void initTranslations(void);
void initNeroAac(void);
void initFhgAac(void);
+ void initQAac(void);
bool m_bSuccess;
lamexp_cpu_t m_cpuFeatures;