Added Swedish translation, thanks to Åke Engelbrektson <eson57@gmail.com>
Updated mpg123 decoder to v1.14.2 (2012-05-12), compiled with GCC 4.6.1
Updated MediaInfo to v0.7.57 (2012-05-02), compiled with ICL 12.1.7 and MSVC 10.0
-
Implemented multi-threading in file analyzer for faster file import
+
Implemented multi-threading in file analyzer for faster file import (about 2.5x to 6.0x faster!)
Implemented multi-threading in initialization code for faster application startup
Fixed a potential crash (stack overflow) when adding a huge number of files
diff --git a/etc/Translation/Blank.ts b/etc/Translation/Blank.ts
index cb1d314b..fe35926d 100644
--- a/etc/Translation/Blank.ts
+++ b/etc/Translation/Blank.ts
@@ -776,7 +776,7 @@
-
+ Show Details
@@ -1448,9 +1448,9 @@
-
-
-
+
+
+ Check for Updates
@@ -1491,13 +1491,13 @@
-
+ Disable Update Reminder
-
+ Disable Sound Effects
@@ -1577,836 +1577,837 @@
-
+
+ Adding file(s), please wait...
-
-
+
+ Access Denied
-
+ %1 file(s) have been rejected, because read access was not granted!
-
+ This usually means the file is locked by another process.
-
+ CDDA Files
-
+ %1 file(s) have been rejected, because they are dummy CDDA files!
-
+ Sorry, LameXP cannot extract audio tracks from an Audio-CD at present.
-
+ We recommend using %1 for that purpose.
-
+ Cue Sheet
-
+ %1 file(s) have been rejected, because they appear to be Cue Sheet images!
-
+ Please use LameXP's Cue Sheet wizard for importing Cue Sheet files.
-
+ Files Rejected
-
+ %1 file(s) have been rejected, because the file format could not be recognized!
-
+ This usually means the file is damaged or the file format is not supported.
-
+ Scanning folder(s) for files, please wait...
-
+ DEMO VERSION
-
+ You can drop in audio files here!
-
+ Initializing directory outline, please be patient...
-
+ Open File in External Application
-
+ Browse File Location
-
+ Browse Selected Folder
-
+ Refresh Directory Outline
-
+ Bookmark Current Output Folder
-
+ Export Meta Tags to CSV File
-
+ Import Meta Tags from CSV File
-
+ License Declined
-
+ You have declined the license. Consequently the application will exit now!
-
+ Goodbye!
-
+ LameXP - Expired
-
+ This demo (pre-release) version of LameXP has expired at %1.
-
+ LameXP is free software and release versions won't expire.
-
-
+
+ Exit Program
-
+ It seems that a bogus anti-virus software is slowing down the startup of LameXP.
-
+ Please refer to the %1 document for details and solutions!
-
+ Slow Startup
-
-
-
-
-
+
+
+
+
+ Discard
-
-
+
+ Don't Show Again
-
+ Urgent Update
-
+ Your version of LameXP is more than a year old. Time for an update!
-
-
+
+ Ignore
-
+ Skipping update check this time, please be patient...
-
-
-
+
+
+ Update Reminder
-
+ Your last update check was more than 14 days ago. Check for updates now?
-
+ Your did not check for LameXP updates yet. Check for updates now?
-
+ Postpone
-
+ LameXP detected that your version of the Nero AAC encoder is outdated!
-
+ The current version available is %1 (or later), but you still have version %2 installed.
-
+ n/a
-
+ You can download the latest version of the Nero AAC encoder from the Nero website at:
-
+ (Hint: Please ignore the name of the downloaded ZIP file and check the included 'changelog.txt' instead!)
-
+ AAC Encoder Outdated
-
+ The Nero AAC encoder could not be found. AAC encoding support will be disabled.
-
+ Please put 'neroAacEnc.exe', 'neroAacDec.exe' and 'neroAacTag.exe' into the LameXP directory!
-
+ Your LameXP directory is located here:
-
+ You can download the Nero AAC encoder for free from the official Nero website at:
-
+ AAC Support Disabled
-
-
-
+
+
+ LameXP
-
+ You must add at least one file to the list before proceeding!
-
+ Not Found
-
+ Your currently selected TEMP folder does not exist anymore:
-
+ Restore Default
-
+ Cancel
-
+ There are less than %1 GB of free diskspace available on your system's TEMP folder.
-
+ It is highly recommend to free up more diskspace before proceeding with the encode!
-
+ Your TEMP folder is located at:
-
+ Low Diskspace Warning
-
+ Abort Encoding Process
-
+ Clean Disk Now
-
+ Low Diskspace
-
+ You are proceeding with low diskspace. Problems might occur!
-
+ Sorry, an unsupported encoder has been chosen!
-
+ Cannot write to the selected output directory.
-
+ Please choose a different directory!
-
+ Load Translation
-
+ Translation Files
-
+ Do you really want to disable the update reminder?
-
-
-
-
-
+
+
+
+
-
+
+ Yes
-
-
-
-
-
+
+
+
+
-
+
+ No
-
+ The update reminder has been disabled.
-
+ Please remember to check for updates at regular intervals!
-
+ The update reminder has been re-enabled.
-
+ Do you really want to disable all sound effects?
-
-
+
+ Sound Effects
-
+ All sound effects have been disabled.
-
+ The sound effects have been re-enabled.
-
-
-
+
+
+ Nero AAC Notifications
-
+ Do you really want to disable all Nero AAC Encoder notifications?
-
+ All Nero AAC Encoder notifications have been disabled.
-
+ The Nero AAC Encoder notifications have been re-enabled.
-
-
-
+
+
+ Slow Startup Notifications
-
+ Do you really want to disable the slow startup notifications?
-
+ The slow startup notifications have been disabled.
-
+ The slow startup notifications have been re-enabled.
-
-
+
+ Open Cue Sheet
-
-
+
+ Cue Sheet File
-
-
-
+
+
+ Beta Updates
-
+ Do you really want LameXP to check for Beta (pre-release) updates?
-
+ LameXP will check for Beta (pre-release) updates from now on.
-
+ Check Now
-
+ LameXP will <i>not</i> check for Beta (pre-release) updates from now on.
-
-
-
+
+
+ Hibernate Computer
-
+ Do you really want the computer to be hibernated on shutdown?
-
+ LameXP will hibernate the computer on shutdown from now on.
-
+ LameXP will <i>not</i> hibernate the computer on shutdown from now on.
-
-
-
+
+
+ Shell Integration
-
+ Do you really want to disable the LameXP shell integration?
-
+ The LameXP shell integration has been disabled.
-
+ The LameXP shell integration has been re-enabled.
-
-
+
+ Add file(s)
-
-
+
+ Add Folder
-
-
+
+ Save CSV file
-
-
-
-
+
+
+
+ CSV File
-
-
-
-
+
+
+
+ CSV Export
-
+ Sorry, there are no meta tags that can be exported!
-
+ Sorry, failed to open CSV file for writing!
-
+ Sorry, failed to write to the CSV file!
-
+ The CSV files was created successfully!
-
-
+
+ Open CSV file
-
-
-
-
-
+
+
+
+
+ CSV Import
-
+ Sorry, failed to open CSV file for reading!
-
+ Sorry, failed to read from the CSV file!
-
+ Sorry, the CSV file does not contain any known fields!
-
+ CSV file is incomplete. Not all files were updated!
-
+ The CSV files was imported successfully!
-
-
+
+ New Folder
-
+ Enter the name of the new folder:
-
+ Failed to create folder
-
+ The new folder could not be created:
-
+ Drive is read-only or insufficient access rights!
-
+ QAAC (Apple)
-
+ FHG AAC (Winamp)
-
+ Nero AAC
-
+ Not available!
-
+ Current AAC Encoder: %1
-
-
-
-
+
+
+
+ Quality Level %1
-
-
-
+
+
+ Compression %1
-
-
-
+
+
+ Uncompressed
-
+ Best Quality (Very Slow)
-
+ High Quality (Recommended)
-
+ Average Quality (Default)
-
+ Low Quality (Fast)
-
+ Poor Quality (Very Fast)
-
+ File name without extension
-
+ Track number with leading zero
-
+ Track title
-
+ Artist name
-
+ Album name
-
+ Year with (at least) four digits
-
+ Comment
-
+ Characters forbidden in file names:
-
+ Rename Macros
-
+ %1 Instance(s)
-
+ Cannot write to the selected directory. Please choose another directory!
-
+ Already Running
-
+ LameXP is already running, please use the running instance!
diff --git a/etc/Translation/LameXP_PL.ts b/etc/Translation/LameXP_PL.ts
index 2c7d61d4..4bb203a7 100644
--- a/etc/Translation/LameXP_PL.ts
+++ b/etc/Translation/LameXP_PL.ts
@@ -776,7 +776,7 @@
-
+ Show DetailsPokaż szczegóły
@@ -1448,9 +1448,9 @@
-
-
-
+
+
+ Check for UpdatesSprawdź aktualizacje
@@ -1491,13 +1491,13 @@
-
+ Disable Update ReminderWyłącz przypominanie o aktualizacji
-
+ Disable Sound EffectsWyłącz efekty dźwiękowe
@@ -1577,836 +1577,837 @@
Hibernuj zamiast zamykać
-
+
+ Adding file(s), please wait...Dodawanie plików, prosze czekać...
-
-
+
+ Access DeniedDostęp zablokowany
-
+ %1 file(s) have been rejected, because read access was not granted!%1 plik(ów) zostało odrzuconych z powodu braku dostępu do pliku!
-
+ This usually means the file is locked by another process.To przeważnie oznacza, że plik jest zablokowany przez inny proces.
-
+ CDDA FilesPliki CDDA
-
+ %1 file(s) have been rejected, because they are dummy CDDA files!%1 plik(ów) zostało odrzuconych ponieważ to nie są właściwe pliki CDDA!
-
+ Sorry, LameXP cannot extract audio tracks from an Audio-CD at present.LameXP nie może teraz wyekstrachować ścieżki z płyty Audio-CD.
-
+ We recommend using %1 for that purpose.Zaleca się użycie w tym celu %1.
-
+ Cue SheetCue Sheet
-
+ %1 file(s) have been rejected, because they appear to be Cue Sheet images!%1 plik(ów) zostało odrzuconych, ponieważ to nie są pliki obrazów Cue Sheet!
-
+ Please use LameXP's Cue Sheet wizard for importing Cue Sheet files.Prosze użyć przewodnika Cue Sheet w LameXP w celu importowania tych plików.
-
+ Files RejectedPliki odrzucone
-
+ %1 file(s) have been rejected, because the file format could not be recognized!%1 plik(ów) zostało odrzuconych, ponieważ ich format nie został rozpoznany!
-
+ This usually means the file is damaged or the file format is not supported.To przeważnie oznacza że plik jest uszkodzony lub format pliku nie jest wspierany.
-
+ Scanning folder(s) for files, please wait...Skanowanie folderu/ów, prosze czekać...
-
+ You can drop in audio files here!Tutaj możesz upuścić pliki dźwiękowe!
-
+ Open File in External ApplicationOtwórz plik w zewnętrznym programie
-
+ Browse File LocationOtwórz lokalizację pliku
-
+ Browse Selected FolderOtwórz wybrany folder
-
+ Bookmark Current Output FolderZapamiętaj wybrany folder
-
+ License DeclinedLicencja odrzucona
-
+ You have declined the license. Consequently the application will exit now!Odrzuciłeś licencję. W takim razie program zostanie teraz zamknięty!
-
+ Goodbye!Naraska!
-
+ LameXP - ExpiredLameXP - Termin wygasł
-
+ This demo (pre-release) version of LameXP has expired at %1.Ta wersja demo (beta) LameXP wygasła %1.
-
+ LameXP is free software and release versions won't expire.LameXP jest darmowym oprogramowaniem i pełna wersja nie wygasa.
-
-
+
+ Exit ProgramWyjdź z programu
-
+ It seems that a bogus anti-virus software is slowing down the startup of LameXP.Najwyraźniej twoje oprogramowanie antywirusowe spowalnia uruchamianie się LameXP.
-
+ Please refer to the %1 document for details and solutions!Prosze sprawdzić dokument %1 w celu dalszych szcegółów i rozwiązań!
-
+ Slow StartupPowolny start
-
-
-
-
-
+
+
+
+
+ DiscardZamknij
-
-
+
+ Don't Show AgainNie pokazuj ponownie
-
+ Urgent UpdateWażna aktualizacja
-
+ Your version of LameXP is more than a year old. Time for an update!Twoja wersja LameXP jest starsza niż rok! Czas na aktualizację!
-
-
-
+
+
+ Update ReminderPowiadomienie aktualizacji
-
+ Your last update check was more than 14 days ago. Check for updates now?Ostatnie sprawdzenie aktualizacji było ponad 14 dni temu. Sprawdzić teraz aktualizacje?
-
+ Your did not check for LameXP updates yet. Check for updates now?Nie sprawdzałeś jeszcze aktualizacji LameXP. Sprawdzić teraz aktualizacje?
-
+ PostponePrzełóż
-
+ LameXP detected that your version of the Nero AAC encoder is outdated!LameXP wykrył że Twoja wersja kodera Nero AAC jest nieaktualna!
-
+ The current version available is %1 (or later), but you still have version %2 installed.Wersją dostępną obecnie jest %1, Twoja wersja to %2.
-
+ n/an/d
-
+ You can download the latest version of the Nero AAC encoder from the Nero website at:Możesz pobrać najnowszą wersję kodera Nero AAC ze strony Nero:
-
+ AAC Encoder OutdatedKoder AAC jest nieaktualny
-
+ The Nero AAC encoder could not be found. AAC encoding support will be disabled.Nie można odnaleźć kodera Nero AAC. Kompresja formatu AAC zostanie wyłączona.
-
+ Please put 'neroAacEnc.exe', 'neroAacDec.exe' and 'neroAacTag.exe' into the LameXP directory!Prosze skopiować 'neroAacEnc.exe', 'neroAacDec.exe', oraz 'neroAacTag.exe' do folderu LameXP!
-
+ Your LameXP directory is located here:Folder aplikacji LameXP znajduje się tutaj:
-
+ You can download the Nero AAC encoder for free from the official Nero website at:Możesz pobrać koder Nero AAC za darmo z oficjalnej strony Nero:
-
+ AAC Support DisabledWsparcie dla AAC wyłączone
-
-
-
+
+
+ LameXPLameXP
-
+ You must add at least one file to the list before proceeding!Powinienieś dodać przynajmniej jeden plik do listy aby zacząć działać!
-
+ Not FoundNie znaleziono
-
+ Your currently selected TEMP folder does not exist anymore:Wybrany przez Ciebie folder tymczasowy TEMP już nie istnieje:
-
+ Restore DefaultPrzywróć domyślne
-
+ CancelAnuluj
-
+ Low Diskspace WarningOstrzeżenie o małej ilości miejsca na dysku
-
+ There are less than %1 GB of free diskspace available on your system's TEMP folder.Jest mniej niż %1 GB dostępnego miejsca w systemowym folderze TEMP.
-
+ DEMO VERSIONWERSJA DEMO
-
+ (Hint: Please ignore the name of the downloaded ZIP file and check the included 'changelog.txt' instead!)(Podpowiedź: Zignoruj nazwę pobranego pliku ZIP, w zamian sprawdż załączony w archiwum plik "changelog.txt"!)
-
+ It is highly recommend to free up more diskspace before proceeding with the encode!Jest wysoce zalecane zwolnić miejsce na dysku zanim zaczniesz kompresję!
-
+ Your TEMP folder is located at:Twój folder TEMP znajduję się:
-
+ Abort Encoding ProcessPrzerwij proces kompresji
-
+ Clean Disk NowWykonaj oczyszczanie dysku
-
-
+
+ IgnoreIgnoruj
-
+ Initializing directory outline, please be patient...Ładowanie zestawu folderów, prosze czekać...
-
+ Refresh Directory OutlineOdśwież foldery
-
+ Export Meta Tags to CSV FileEksportuj Tagi do pliku CVS
-
+ Import Meta Tags from CSV FileImportuj Tagi do pliku CVS
-
+ Skipping update check this time, please be patient...Pomijanie sprawdzania aktualizacji, prosze czekać...
-
+ Low DiskspaceMało miejsca na dysku
-
+ You are proceeding with low diskspace. Problems might occur!Chcesz zacząć działać z małą ilością miejsca na dysku. Mogą wystąpić problemy!
-
+ Sorry, an unsupported encoder has been chosen!Został wybrany koder, który nie jest wspierany!
-
+ Cannot write to the selected output directory.Nie można zapisać do wybranej lokalizacji.
-
+ Please choose a different directory!Prosze wybrać inną lokalizację!
-
+ Load TranslationZaladuj plik językowy
-
+ Translation FilesPliki językowe
-
+ Do you really want to disable the update reminder?Czy na pewno chcesz wyłączyć przypominanie o aktualizacjach?
-
-
-
-
-
+
+
+
+
-
+
+ YesTak
-
-
-
-
-
+
+
+
+
-
+
+ NoNie
-
+ The update reminder has been disabled.Przypominanie o aktualizacjach wyłączone.
-
+ Please remember to check for updates at regular intervals!Prosze pamiętać o okresowym sprawdzaniu aktualizacji!
-
+ The update reminder has been re-enabled.Przypominanie o aktualizacjach ponownie włączone.
-
+ Do you really want to disable all sound effects?Czy na pewno chcesz wyłączyć wszystkie dźwiękowe?
-
-
+
+ Sound EffectsEfekty dźwiękowe
-
+ All sound effects have been disabled.Wszystkie efekty dźwiękowe zostały wyłączone.
-
+ The sound effects have been re-enabled.Efekty dźwiękowe zostały ponownie włączone.
-
-
-
+
+
+ Nero AAC NotificationsPowiadomienia Nero AAC
-
+ Do you really want to disable all Nero AAC Encoder notifications?Czy na pewno chcesz wyłączyć wszystkie powiadomienia Nero AAC?
-
+ All Nero AAC Encoder notifications have been disabled.Wszystkie powiadomienia kodera Nero AAC zostały wyłączone.
-
+ The Nero AAC Encoder notifications have been re-enabled.Powiadomienia Nero AAC zostały ponownie włączone.
-
-
-
+
+
+ Slow Startup NotificationsPowiadomienia o powolnym starcie
-
+ Do you really want to disable the slow startup notifications?Czy na pewno chcesz wyłączyć powiadomienia o powolnym starcie?
-
+ The slow startup notifications have been disabled.Powiadomienia o powolnym starcie zostały wyłączone.
-
+ The slow startup notifications have been re-enabled.Powiadomienia o powolnym starcie zostały ponownie włączone.
-
-
+
+ Open Cue SheetOtwórz plik Cue Sheet
-
-
+
+ Cue Sheet FilePlik Cue Sheet
-
-
-
+
+
+ Beta UpdatesAktualizacje Beta
-
+ Do you really want LameXP to check for Beta (pre-release) updates?Czy na pewno chcesz aby LameXP sprawdzał aktualizacje Beta?
-
+ LameXP will check for Beta (pre-release) updates from now on.Od teraz LameXP będzie sprawdzał aktualizacje Beta.
-
+ Check NowSprawdź teraz
-
+ LameXP will <i>not</i> check for Beta (pre-release) updates from now on.LameXP od teraz <i>nie będzie</i> sprawdzał aktualizacji Beta.
-
-
-
+
+
+ Hibernate ComputerHibernuj komputer
-
+ Do you really want the computer to be hibernated on shutdown?Czy na pewno chcesz aby komputer był hibernowany zamiast zamykany?
-
+ LameXP will hibernate the computer on shutdown from now on.Od teraz LameXP będzie hibernował komputer zamiast zamykać.
-
+ LameXP will <i>not</i> hibernate the computer on shutdown from now on.LameXP od teraz <i>nie</i> będzie hibernował komputera tylko zamykał.
-
-
-
+
+
+ Shell IntegrationIntegracja z systemem
-
+ Do you really want to disable the LameXP shell integration?Czy na pewno chcesz wyłączyć integrację LameXP z systemem?
-
+ The LameXP shell integration has been disabled.Integracja LameXP z systemem zostałą wyłączona.
-
+ The LameXP shell integration has been re-enabled.Integracja LameXP z systemem została ponownie włączona.
-
-
+
+ Add file(s)Dodaj plik(i)
-
-
+
+ Add FolderDodaj folder
-
-
+
+ Save CSV fileZapisz plik CSV
-
-
-
-
+
+
+
+ CSV FilePlik CSV
-
-
-
-
+
+
+
+ CSV ExportEksportowanie CSV
-
+ Sorry, there are no meta tags that can be exported!Nie ma żadnych tagów, które można eksportować!
-
+ Sorry, failed to open CSV file for writing!Nie można otworzyć pliku CSV aby go zapisać!
-
+ Sorry, failed to write to the CSV file!Nie można zapisać do pliku CSV!
-
+ The CSV files was created successfully!Pliki CSV utworzone pomyślnie!
-
-
+
+ Open CSV fileOtwórz plik CSV
-
+ Sorry, failed to open CSV file for reading!Nie można otworzyć pliku CSV aby go wczytać!
-
-
-
-
-
+
+
+
+
+ CSV ImportImportowanie CSV
-
+ Sorry, failed to read from the CSV file!Próba odczytania pliku CSV zakończona niepowodzeniem!
-
+ Sorry, the CSV file does not contain any known fields!Plik CSV nie zawiera żadnych znanych pól!
-
+ CSV file is incomplete. Not all files were updated!Plik CSV nie jest kompletny. Nie wszystkie pliki zostały zaktualizowane!
-
+ The CSV files was imported successfully!Pliki CSV zaimportowano pomyślnie!
-
-
+
+ New FolderNowy folder
-
+ Enter the name of the new folder:Wprowadź nazwę nowego folderu:
-
+ Failed to create folderUtworzenie folderu zakończone niepowodzeniem
-
+ The new folder could not be created:Nowy folder nie mógł zostać stworzony:
-
+ Drive is read-only or insufficient access rights!Dysk tylko do odczytu lub brak praw dostępu!
-
+ QAAC (Apple)QAAC (Apple)
-
+ FHG AAC (Winamp)FHG AAC (Winamp)
-
+ Nero AACNero AAC
-
+ Not available!Niedostępny!
-
+ Current AAC Encoder: %1Obecny koder AAC: %1
-
-
-
-
+
+
+
+ Quality Level %1Poziom jakości %1
-
-
-
+
+
+ Compression %1Kompresja %1
-
-
-
+
+
+ UncompressedNieskompresowany
-
+ Best Quality (Very Slow)Najlepsza jakość (Bardzo wolno)
-
+ High Quality (Recommended)Wysoka jakość (Zalecane)
-
+ Average Quality (Default)Średnia jakość (Domyślnie)
-
+ Low Quality (Fast)Niska jakość (Szybko)
-
+ Poor Quality (Very Fast)Najniższa jakość (Bardzo szybko)
-
+ File name without extensionNazwa pliku bez rozszerzenia
-
+ Track number with leading zeroNumer ścieżki z zerem na początku
-
+ Track titleNazwa ścieżki
-
+ Artist nameNazwa Artysty
-
+ Album nameNazwa Albumu
-
+ Year with (at least) four digitsRok z (przynajmniej) czterema cyframi
-
+ CommentKomentarz
-
+ Characters forbidden in file names:Zabronione znaki w nazwach plików:
-
+ Rename MacrosZmień nazwy makr
-
+ %1 Instance(s)%1 wątek/ki
-
+ Cannot write to the selected directory. Please choose another directory!Nie można zapisać do wybranej lokalizacji. Prosze wybierz inną lokalizację!
-
+ Already RunningJuż działa
-
+ LameXP is already running, please use the running instance!LameXP już działa, przejdź do działającego programu!
diff --git a/etc/Translation/LameXP_SV.ts b/etc/Translation/LameXP_SV.ts
index 96cd9bc4..8b82990c 100644
--- a/etc/Translation/LameXP_SV.ts
+++ b/etc/Translation/LameXP_SV.ts
@@ -776,7 +776,7 @@
-
+ Show DetailsVisa detaljer
@@ -1448,9 +1448,9 @@
-
-
-
+
+
+ Check for UpdatesSök efter uppdateringar
@@ -1491,13 +1491,13 @@
-
+ Disable Update ReminderInaktivera uppdateringsmeddelande
-
+ Disable Sound EffectsInaktivera ljudeffekter
@@ -1577,836 +1577,837 @@
Försätt datorn i viloläge vid avslut
-
+
+ Adding file(s), please wait...Lägger till fil(er), vänta...
-
-
+
+ Access DeniedÅtkomst nekad
-
+ %1 file(s) have been rejected, because read access was not granted!%1 fil(er) har undantagits, på grund av att åtkomst nekades!
-
+ This usually means the file is locked by another process.Det innebär oftast att filen är låst av någon annan process.
-
+ CDDA FilesCDDA-filer
-
+ %1 file(s) have been rejected, because they are dummy CDDA files!%1 fil(er) har undantagits, på grund av att det är fejkade CDDA-filer
-
+ Sorry, LameXP cannot extract audio tracks from an Audio-CD at present.LameXP kan för närvarande inte extrahera ljudspår från en ljud-CD.
-
+ We recommend using %1 for that purpose.Vi rekommenderar att du använder %1 för det ändamålet.
-
+ Cue SheetCue-fil
-
+ %1 file(s) have been rejected, because they appear to be Cue Sheet images!%1 fil(er) har undantagits, på grund av att de verkar vara cue-filer!
-
+ Please use LameXP's Cue Sheet wizard for importing Cue Sheet files.Använd LameXPs cue-guide för att importera cue-filer.
-
+ Files RejectedUndantagna filer
-
+ %1 file(s) have been rejected, because the file format could not be recognized!%1 fil(er) har undantagits, på grund av att filformatet inte känns igen!
-
+ This usually means the file is damaged or the file format is not supported.Det innebär oftast att filen är skadad eller att filformatet inte stöds.
-
+ Scanning folder(s) for files, please wait...Genomsöker mapp(ar) efter fil(er), vänta...
-
+ DEMO VERSIONDEMOVERSION
-
+ You can drop in audio files here!Du kan dra och släppa filer här!
-
+ Initializing directory outline, please be patient...Initierar mappdisposition, vänta...
-
+ Open File in External ApplicationÖppna fil i externt program
-
+ Browse File LocationÖppna målmappen
-
+ Browse Selected FolderÖppna markerad mapp
-
+ Refresh Directory OutlineUppdatera mappdisposition
-
+ Bookmark Current Output FolderLägg till aktuell utdatamapp i favoriter
-
+ Export Meta Tags to CSV FileExportera metadata till CSV-fil
-
+ Import Meta Tags from CSV FileImportera metadata från CSV-fil
-
+ License DeclinedLicensavtal avvisat
-
+ You have declined the license. Consequently the application will exit now!Du har nekat att godkänna licensavtalet. Programmet kommer nu att avslutas!
-
+ Goodbye!Hej då!
-
+ LameXP - ExpiredLameXP - Upphört
-
+ This demo (pre-release) version of LameXP has expired at %1.Denna demoversion av LameXP har upphört att gälla från %1.
-
+ LameXP is free software and release versions won't expire.LameXP är kostnadsfritt och release-versionerna upphör inte att gälla.
-
-
+
+ Exit ProgramAvsluta programmet
-
+ It seems that a bogus anti-virus software is slowing down the startup of LameXP.Det verkar som ett antivirusprogram orsakar långsammare uppstart av LameXP.
-
+ Please refer to the %1 document for details and solutions!Läs gärna %1 för detaljer och lösningar!
-
+ Slow StartupLångsam uppstart
-
-
-
-
-
+
+
+
+
+ DiscardStäng
-
-
+
+ Don't Show AgainVisa inte igen
-
+ Urgent UpdateViktig uppdatering
-
+ Your version of LameXP is more than a year old. Time for an update!Din version av LameXP är mer än ett år gammal. Dags att uppdatera!
-
-
+
+ IgnoreIgnorera
-
+ Skipping update check this time, please be patient...Hoppar över uppdateringskontrollen den här gången, vänta...
-
-
-
+
+
+ Update ReminderUppdateringspåminnelse
-
+ Your last update check was more than 14 days ago. Check for updates now?Din senaste uppdateringskontroll var för mer än 14 dagar sedan. Vill du söka efter uppdateringar nu?
-
+ Your did not check for LameXP updates yet. Check for updates now?Du har inte genomfört uppdateringskontroll ännu. Vill du söka efter uppdateringar nu?
-
+ PostponeSkjut upp
-
+ LameXP detected that your version of the Nero AAC encoder is outdated!LameXP har uptäckt att din version av Nero AAC-kodare är utdaterad!
-
+ The current version available is %1 (or later), but you still have version %2 installed.Aktuell version är %1 (eller senare), men du har fortfarande version %2.
-
+ n/an/a
-
+ You can download the latest version of the Nero AAC encoder from the Nero website at:Du kan ladda ner senaste versionen av Nero AAC-kodare från Neros webbsida:
-
+ (Hint: Please ignore the name of the downloaded ZIP file and check the included 'changelog.txt' instead!)(Tips: Bortse från den nedladde zipfilens namn, och kontrollera istället den inkluderade textfilen 'changelog.txt'!)
-
+ AAC Encoder OutdatedAAC-kodare utdaterad
-
+ The Nero AAC encoder could not be found. AAC encoding support will be disabled.Neros AAC-kodare kan inte hittas. Stödet för AAC-kodning kommer att inaktiveras.
-
+ Please put 'neroAacEnc.exe', 'neroAacDec.exe' and 'neroAacTag.exe' into the LameXP directory!Placera 'neroAacEnc.exe', 'neroAacDec.exe' och 'neroAacTag.exe' i LameXPs programmmapp!
-
+ Your LameXP directory is located here:Din LameXP programmapp finns här:
-
+ You can download the Nero AAC encoder for free from the official Nero website at:Du kan ladda ner Nero AAC-kodare gratis från den officiella webbsidan:
-
+ AAC Support DisabledAAC-stödet är inaktiverat
-
-
-
+
+
+ LameXPLameXP
-
+ You must add at least one file to the list before proceeding!Du måste lägga till minst en fil till listan innan du fortsätter!
-
+ Not FoundKan inte hittas
-
+ Your currently selected TEMP folder does not exist anymore:Din aktuella TEMP-mapp finns inte längre:
-
+ Restore DefaultÅterställ standard
-
+ CancelAvbryt
-
+ There are less than %1 GB of free diskspace available on your system's TEMP folder.Det finns mindre än %1 GB ledigt diskutrymme i systemets temp-mapp.
-
+ It is highly recommend to free up more diskspace before proceeding with the encode!Du behöver frigöra mer diskutrymme innan du fortsätter med omkodningen!
-
+ Your TEMP folder is located at:Temp-mappens placering:
-
+ Low Diskspace WarningVarning för dåligt diskutrymme
-
+ Abort Encoding ProcessAvbryt omkodningsprocessen
-
+ Clean Disk NowRensa disken nu
-
+ Low DiskspaceDåligt diskutrymme
-
+ You are proceeding with low diskspace. Problems might occur!Du fortsätter med dåligt diskutrymme. Problem kan uppstå!
-
+ Sorry, an unsupported encoder has been chosen!En kodare som saknar stöd har valts!
-
+ Cannot write to the selected output directory.Kan inte skriva till den valda utdatamappen.
-
+ Please choose a different directory!Välj en annan målmapp!
-
+ Load TranslationLäs in översättning
-
+ Translation FilesÖversättningsfiler
-
+ Do you really want to disable the update reminder?Vill du verkligen inaktivera uppdateringspåminnelsen?
-
-
-
-
-
+
+
+
+
-
+
+ YesJa
-
-
-
-
-
+
+
+
+
-
+
+ NoNej
-
+ The update reminder has been disabled.Uppdateringspåminnelsen har inaktiverats.
-
+ Please remember to check for updates at regular intervals!Glöm inte att söka efter uppdateringar med jämna mellanrum!
-
+ The update reminder has been re-enabled.Uppdateringspåminnelsen har återaktiverats.
-
+ Do you really want to disable all sound effects?Vill du verkligen inaktivera alla ljudeffekter?
-
-
+
+ Sound EffectsLjudeffekter
-
+ All sound effects have been disabled.Alla ljudeffekter har inaktiverats.
-
+ The sound effects have been re-enabled.Ljudeffekterna har återaktiverats.
-
-
-
+
+
+ Nero AAC NotificationsNero AAC-meddelanden
-
+ Do you really want to disable all Nero AAC Encoder notifications?Vill du verkligen inaktivera alla Nero AAC-meddelanden?
-
+ All Nero AAC Encoder notifications have been disabled.Alla Nero AAC-meddelanden har inaktiverats.
-
+ The Nero AAC Encoder notifications have been re-enabled.Nero AAC-meddelanden har återaktiverats.
-
-
-
+
+
+ Slow Startup NotificationsMeddelande om långsam uppstart
-
+ Do you really want to disable the slow startup notifications?Vill du verkligen inaktivera meddelanden om långsam uppstart?
-
+ The slow startup notifications have been disabled.Meddelanden om långsam uppstart har inaktiverats.
-
+ The slow startup notifications have been re-enabled.Meddelanden om långsam uppstart har återaktiverats.
-
-
+
+ Open Cue SheetÖppna cue-fil
-
-
+
+ Cue Sheet FileCue-fil
-
-
-
+
+
+ Beta UpdatesBeta-uppdateringar
-
+ Do you really want LameXP to check for Beta (pre-release) updates?Vill du verkligen att LameXP skall söka efter beta-uppdateringar?
-
+ LameXP will check for Beta (pre-release) updates from now on.LameXP kommer i fortsättningen att söka efter beta-uppdatyeringar.
-
+ Check NowSök nu
-
+ LameXP will <i>not</i> check for Beta (pre-release) updates from now on.LameXP kommer i fortsättningen <i>inte</i> att söka efter beta-uppdateringar.
-
-
-
+
+
+ Hibernate ComputerViloläge
-
+ Do you really want the computer to be hibernated on shutdown?Vill du verkligen att datorn skall försättas i viloläge vid avslut?
-
+ LameXP will hibernate the computer on shutdown from now on.LameXP kommer i fortsättningen att försätta datorn i viloläge vid avslut.
-
+ LameXP will <i>not</i> hibernate the computer on shutdown from now on.LameXP kommer i fortsättningen <i>inte</i> att försätta datorn i viloläge vid avslut.
-
-
-
+
+
+ Shell IntegrationUtforskarintegrering
-
+ Do you really want to disable the LameXP shell integration?Vill du verkligen inaktivera LameXPs utforskarintegration?
-
+ The LameXP shell integration has been disabled.LameXPs utforskarintegration har inaktiverats.
-
+ The LameXP shell integration has been re-enabled.LameXPs utforskarintegration har återaktiverats.
-
-
+
+ Add file(s)Lägg till fil(er)
-
-
+
+ Add FolderLägg till mapp
-
-
+
+ Save CSV fileSpara CSV-fil
-
-
-
-
+
+
+
+ CSV FileCSV-fil
-
-
-
-
+
+
+
+ CSV ExportCSV-export
-
+ Sorry, there are no meta tags that can be exported!Det finns ingen meta-data som kan exporteras!
-
+ Sorry, failed to open CSV file for writing!Kunde inte öppna CSV-filen för skrivning!
-
+ Sorry, failed to write to the CSV file!Kunde inte skriva till CSV-filen!
-
+ The CSV files was created successfully!CSV-filen skapades korrekt!
-
-
+
+ Open CSV fileÖppna CSV-fil
-
-
-
-
-
+
+
+
+
+ CSV ImportCSV-import
-
+ Sorry, failed to open CSV file for reading!Kunde inte öppna CSV-filen för läsning!
-
+ Sorry, failed to read from the CSV file!Kunde inte läsa från CSV-filen!
-
+ Sorry, the CSV file does not contain any known fields!CSV-filen innehåller inga kända fält!
-
+ CSV file is incomplete. Not all files were updated!CSV-filen är inte komplett. Alla filer uppdaterades inte!
-
+ The CSV files was imported successfully!CSV-filen importerades korrekt!
-
-
+
+ New FolderNy mapp
-
+ Enter the name of the new folder:Namn på den nya mappen:
-
+ Failed to create folderKunde inte skapa någon mapp
-
+ The new folder could not be created:Den nya mappen kunde inte skapas:
-
+ Drive is read-only or insufficient access rights!Diskenheten är skrivskyddad eller åtkomsträttigheter saknas!
-
+ QAAC (Apple)QAAC (Apple)
-
+ FHG AAC (Winamp)FHG AAC (Winamp)
-
+ Nero AACNero AAC
-
+ Not available!Ej tillgänglig!
-
+ Current AAC Encoder: %1Aktuell AAC-kodare: %1
-
-
-
-
+
+
+
+ Quality Level %1Kvallitetsnivå %1
-
-
-
+
+
+ Compression %1Kompression %1
-
-
-
+
+
+ UncompressedOkomprimerad
-
+ Best Quality (Very Slow)Bäst kvallitet (långsam)
-
+ High Quality (Recommended)Hög kvallitet (rekommenderas)
-
+ Average Quality (Default)Medelkvallitet (standard)
-
+ Low Quality (Fast)Låg kvallitet (snabb)
-
+ Poor Quality (Very Fast)Dålig kvallitet (mycket snabb)
-
+ File name without extensionFilnamn utan filtillägg
-
+ Track number with leading zeroSpårnummer med inledande nolla
-
+ Track titleSpårtitel
-
+ Artist nameArtistnamn
-
+ Album nameAlbumnamn
-
+ Year with (at least) four digitsÅrtal med (minst) fyra siffror
-
+ CommentKommentar
-
+ Characters forbidden in file names:Förbjudna tecken i filnamn:
-
+ Rename MacrosNamnändra macron
-
+ %1 Instance(s)%1 instans(er)
-
+ Cannot write to the selected directory. Please choose another directory!Kan inte skriva till den specificerade mappen. Välj en annan destination!
-
+ Already RunningKörs redan
-
+ LameXP is already running, please use the running instance!LameXP körs redan, använd den redan startade instansen!
diff --git a/src/Config.h b/src/Config.h
index 872d5e4f..b25eba2c 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -30,7 +30,7 @@
#define VER_LAMEXP_MINOR_LO 5
#define VER_LAMEXP_TYPE Alpha
#define VER_LAMEXP_PATCH 2
-#define VER_LAMEXP_BUILD 1023
+#define VER_LAMEXP_BUILD 1026
///////////////////////////////////////////////////////////////////////////////
// Tool versions (minimum expected versions!)
diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp
index 92a93383..6050ce10 100644
--- a/src/Dialog_MainWindow.cpp
+++ b/src/Dialog_MainWindow.cpp
@@ -31,6 +31,7 @@
#include "Dialog_DropBox.h"
#include "Dialog_CueImport.h"
#include "Thread_FileAnalyzer.h"
+#include "Thread_FileAnalyzer_ST.h"
#include "Thread_MessageHandler.h"
#include "Model_MetaInfo.h"
#include "Model_Settings.h"
@@ -515,6 +516,10 @@ void MainWindow::addFiles(const QStringList &files)
tabWidget->setCurrentIndex(0);
+ int timeMT = 0, timeST = 0;
+
+ //--MT--
+
FileAnalyzer *analyzer = new FileAnalyzer(files);
connect(analyzer, SIGNAL(fileSelected(QString)), m_banner, SLOT(setText(QString)), Qt::QueuedConnection);
connect(analyzer, SIGNAL(progressValChanged(unsigned int)), m_banner, SLOT(setProgressVal(unsigned int)), Qt::QueuedConnection);
@@ -525,13 +530,44 @@ void MainWindow::addFiles(const QStringList &files)
try
{
m_fileListModel->setBlockUpdates(true);
+ QTime startTime = QTime::currentTime();
m_banner->show(tr("Adding file(s), please wait..."), analyzer);
+ timeMT = startTime.secsTo(QTime::currentTime());
}
catch(...)
{
/* ignore any exceptions that may occur */
}
+ //--ST--
+
+ FileAnalyzer_ST *analyzerST = new FileAnalyzer_ST(files);
+ connect(analyzerST, SIGNAL(fileSelected(QString)), m_banner, SLOT(setText(QString)), Qt::QueuedConnection);
+ connect(analyzerST, SIGNAL(progressValChanged(unsigned int)), m_banner, SLOT(setProgressVal(unsigned int)), Qt::QueuedConnection);
+ connect(analyzerST, SIGNAL(progressMaxChanged(unsigned int)), m_banner, SLOT(setProgressMax(unsigned int)), Qt::QueuedConnection);
+ connect(analyzerST, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
+ connect(m_banner, SIGNAL(userAbort()), analyzerST, SLOT(abortProcess()), Qt::DirectConnection);
+
+ try
+ {
+ m_fileListModel->setBlockUpdates(true);
+ QTime startTime = QTime::currentTime();
+ m_banner->show(tr("Adding file(s), please wait..."), analyzerST);
+ timeST = startTime.secsTo(QTime::currentTime());
+ }
+ catch(...)
+ {
+ /* ignore any exceptions that may occur */
+ }
+
+ //------
+
+ double speedUp = static_cast(timeST) / static_cast(timeMT);
+ QMessageBox::information(this, "Speed Up", QString().sprintf("Announcement: The new multi-threaded file analyzer is %.1fx faster !!!", speedUp), QMessageBox::Ok);
+ qWarning("ST: %d, MT: %d", timeST, timeMT);
+
+ //------
+
m_fileListModel->setBlockUpdates(false);
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
sourceFileView->update();
@@ -557,6 +593,7 @@ void MainWindow::addFiles(const QStringList &files)
}
LAMEXP_DELETE(analyzer);
+ LAMEXP_DELETE(analyzerST);
m_banner->close();
}
diff --git a/src/Dialog_WorkingBanner.cpp b/src/Dialog_WorkingBanner.cpp
index bb320043..c60ede8b 100644
--- a/src/Dialog_WorkingBanner.cpp
+++ b/src/Dialog_WorkingBanner.cpp
@@ -100,6 +100,8 @@ WorkingBanner::~WorkingBanner(void)
void WorkingBanner::show(const QString &text)
{
m_canClose = false;
+ m_progressInt = -1;
+
QDialog::show();
setFixedSize(size());
setText(text);
diff --git a/src/Thread_FileAnalyzer_ST.cpp b/src/Thread_FileAnalyzer_ST.cpp
new file mode 100644
index 00000000..d2352e85
--- /dev/null
+++ b/src/Thread_FileAnalyzer_ST.cpp
@@ -0,0 +1,825 @@
+///////////////////////////////////////////////////////////////////////////////
+// LameXP - Audio Encoder Front-End
+// Copyright (C) 2004-2012 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
+///////////////////////////////////////////////////////////////////////////////
+
+// --------------------------------------------------------------------
+// !!! THIS IS THE OLD SINGLE-THREADED VERSION OF THE FILE ANALYZER !!!
+// --------------------------------------------------------------------
+
+#include "Thread_FileAnalyzer_ST.h"
+
+#include "Global.h"
+#include "LockedFile.h"
+#include "Model_AudioFile.h"
+#include "PlaylistImporter.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#define IS_KEY(KEY) (key.compare(KEY, Qt::CaseInsensitive) == 0)
+#define IS_SEC(SEC) (key.startsWith((SEC "_"), Qt::CaseInsensitive))
+#define FIRST_TOK(STR) (STR.split(" ", QString::SkipEmptyParts).first())
+
+////////////////////////////////////////////////////////////
+// Constructor
+////////////////////////////////////////////////////////////
+
+FileAnalyzer_ST::FileAnalyzer_ST(const QStringList &inputFiles)
+:
+ m_inputFiles(inputFiles),
+ m_mediaInfoBin(lamexp_lookup_tool("mediainfo.exe")),
+ m_avs2wavBin(lamexp_lookup_tool("avs2wav.exe")),
+ m_templateFile(NULL),
+ m_abortFlag(false)
+{
+ m_bSuccess = false;
+ m_bAborted = false;
+
+ if(m_mediaInfoBin.isEmpty())
+ {
+ qFatal("Invalid path to MediaInfo binary. Tool not initialized properly.");
+ }
+
+ m_filesAccepted = 0;
+ m_filesRejected = 0;
+ m_filesDenied = 0;
+ m_filesDummyCDDA = 0;
+ m_filesCueSheet = 0;
+}
+
+FileAnalyzer_ST::~FileAnalyzer_ST(void)
+{
+ if(m_templateFile)
+ {
+ QString templatePath = m_templateFile->filePath();
+ LAMEXP_DELETE(m_templateFile);
+ if(QFile::exists(templatePath)) QFile::remove(templatePath);
+ }
+}
+
+////////////////////////////////////////////////////////////
+// Static data
+////////////////////////////////////////////////////////////
+
+const char *FileAnalyzer_ST::g_tags_gen[] =
+{
+ "ID",
+ "Format",
+ "Format_Profile",
+ "Format_Version",
+ "Duration",
+ "Title", "Track",
+ "Track/Position",
+ "Artist", "Performer",
+ "Album",
+ "Genre",
+ "Released_Date", "Recorded_Date",
+ "Comment",
+ "Cover",
+ "Cover_Type",
+ "Cover_Mime",
+ "Cover_Data",
+ NULL
+};
+
+const char *FileAnalyzer_ST::g_tags_aud[] =
+{
+ "ID",
+ "Source",
+ "Format",
+ "Format_Profile",
+ "Format_Version",
+ "Channel(s)",
+ "SamplingRate",
+ "BitDepth",
+ "BitRate",
+ "BitRate_Mode",
+ NULL
+};
+
+////////////////////////////////////////////////////////////
+// Thread Main
+////////////////////////////////////////////////////////////
+
+void FileAnalyzer_ST::run()
+{
+ m_bSuccess = false;
+ m_bAborted = false;
+
+ m_filesAccepted = 0;
+ m_filesRejected = 0;
+ m_filesDenied = 0;
+ m_filesDummyCDDA = 0;
+ m_filesCueSheet = 0;
+
+ m_inputFiles.sort();
+ m_recentlyAdded.clear();
+ m_abortFlag = false;
+
+ if(!m_templateFile)
+ {
+ if(!createTemplate())
+ {
+ qWarning("Failed to create template file!");
+ return;
+ }
+ }
+
+ while(!m_inputFiles.isEmpty())
+ {
+ int fileType = fileTypeNormal;
+ QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst());
+ qDebug("Analyzing: %s", currentFile.toUtf8().constData());
+ emit fileSelected(QFileInfo(currentFile).fileName());
+ AudioFileModel file = analyzeFile(currentFile, &fileType);
+
+ if(m_abortFlag)
+ {
+ MessageBeep(MB_ICONERROR);
+ m_bAborted = true;
+ qWarning("Operation cancelled by user!");
+ return;
+ }
+ if(fileType == fileTypeSkip)
+ {
+ qWarning("File was recently added, skipping!");
+ continue;
+ }
+ if(fileType == fileTypeDenied)
+ {
+ m_filesDenied++;
+ qWarning("Cannot access file for reading, skipping!");
+ continue;
+ }
+ if(fileType == fileTypeCDDA)
+ {
+ m_filesDummyCDDA++;
+ qWarning("Dummy CDDA file detected, skipping!");
+ continue;
+ }
+
+ if(file.fileName().isEmpty() || file.formatContainerType().isEmpty() || file.formatAudioType().isEmpty())
+ {
+ if(PlaylistImporter::importPlaylist(m_inputFiles, currentFile))
+ {
+ qDebug("Imported playlist file.");
+ }
+ else if(!QFileInfo(currentFile).suffix().compare("cue", Qt::CaseInsensitive))
+ {
+ qWarning("Cue Sheet file detected, skipping!");
+ m_filesCueSheet++;
+ }
+ else if(!QFileInfo(currentFile).suffix().compare("avs", Qt::CaseInsensitive))
+ {
+ qDebug("Found a potential Avisynth script, investigating...");
+ if(analyzeAvisynthFile(currentFile, file))
+ {
+ m_filesAccepted++;
+ emit fileAnalyzed(file);
+ }
+ else
+ {
+ qDebug("Rejected Avisynth file: %s", file.filePath().toUtf8().constData());
+ m_filesRejected++;
+ }
+ }
+ else
+ {
+ qDebug("Rejected file of unknown type: %s", file.filePath().toUtf8().constData());
+ m_filesRejected++;
+ }
+ continue;
+ }
+
+ m_filesAccepted++;
+ m_recentlyAdded.append(file.filePath());
+ emit fileAnalyzed(file);
+ }
+
+ qDebug("All files added.\n");
+ m_bSuccess = true;
+}
+
+////////////////////////////////////////////////////////////
+// Privtae Functions
+////////////////////////////////////////////////////////////
+
+const AudioFileModel FileAnalyzer_ST::analyzeFile(const QString &filePath, int *type)
+{
+ *type = fileTypeNormal;
+
+ AudioFileModel audioFile(filePath);
+
+ if(m_recentlyAdded.contains(filePath, Qt::CaseInsensitive))
+ {
+ *type = fileTypeSkip;
+ return audioFile;
+ }
+
+ QFile readTest(filePath);
+ if(!readTest.open(QIODevice::ReadOnly))
+ {
+ *type = fileTypeDenied;
+ return audioFile;
+ }
+ if(checkFile_CDDA(readTest))
+ {
+ *type = fileTypeCDDA;
+ return audioFile;
+ }
+ readTest.close();
+
+ bool skipNext = false;
+ unsigned int id_val[2] = {UINT_MAX, UINT_MAX};
+ cover_t coverType = coverNone;
+ QByteArray coverData;
+
+ QStringList params;
+ params << QString("--Inform=file://%1").arg(QDir::toNativeSeparators(m_templateFile->filePath()));
+ params << QDir::toNativeSeparators(filePath);
+
+ QProcess process;
+ process.setProcessChannelMode(QProcess::MergedChannels);
+ process.setReadChannel(QProcess::StandardOutput);
+ process.start(m_mediaInfoBin, params);
+
+ if(!process.waitForStarted())
+ {
+ qWarning("MediaInfo process failed to create!");
+ qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData());
+ process.kill();
+ process.waitForFinished(-1);
+ return audioFile;
+ }
+
+ while(process.state() != QProcess::NotRunning)
+ {
+ if(m_abortFlag)
+ {
+ process.kill();
+ qWarning("Process was aborted on user request!");
+ break;
+ }
+
+ if(!process.waitForReadyRead())
+ {
+ if(process.state() == QProcess::Running)
+ {
+ qWarning("MediaInfo time out. Killing process and skipping file!");
+ process.kill();
+ process.waitForFinished(-1);
+ return audioFile;
+ }
+ }
+
+ QByteArray data;
+
+ while(process.canReadLine())
+ {
+ QString line = QString::fromUtf8(process.readLine().constData()).simplified();
+ if(!line.isEmpty())
+ {
+ //qDebug("Line:%s", line.toUtf8().constData());
+
+ int index = line.indexOf('=');
+ if(index > 0)
+ {
+ QString key = line.left(index).trimmed();
+ QString val = line.mid(index+1).trimmed();
+ if(!key.isEmpty())
+ {
+ updateInfo(audioFile, &skipNext, id_val, &coverType, &coverData, key, val);
+ }
+ }
+ }
+ }
+ }
+
+ if(audioFile.fileName().isEmpty())
+ {
+ QString baseName = QFileInfo(filePath).fileName();
+ int index = baseName.lastIndexOf(".");
+
+ if(index >= 0)
+ {
+ baseName = baseName.left(index);
+ }
+
+ baseName = baseName.replace("_", " ").simplified();
+ index = baseName.lastIndexOf(" - ");
+
+ if(index >= 0)
+ {
+ baseName = baseName.mid(index + 3).trimmed();
+ }
+
+ audioFile.setFileName(baseName);
+ }
+
+ process.waitForFinished();
+ if(process.state() != QProcess::NotRunning)
+ {
+ process.kill();
+ process.waitForFinished(-1);
+ }
+
+ if((coverType != coverNone) && (!coverData.isEmpty()))
+ {
+ retrieveCover(audioFile, coverType, coverData);
+ }
+
+ return audioFile;
+}
+
+void FileAnalyzer_ST::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned int *id_val, cover_t *coverType, QByteArray *coverData, const QString &key, const QString &value)
+{
+ //qWarning("'%s' -> '%s'", key.toUtf8().constData(), value.toUtf8().constData());
+
+ /*New Stream*/
+ if(IS_KEY("Gen_ID") || IS_KEY("Aud_ID"))
+ {
+ if(value.isEmpty())
+ {
+ *skipNext = false;
+ }
+ else
+ {
+ //We ignore all ID's, except for the lowest one!
+ bool ok = false;
+ unsigned int id = value.toUInt(&ok);
+ if(ok)
+ {
+ if(IS_KEY("Gen_ID")) { id_val[0] = qMin(id_val[0], id); *skipNext = (id > id_val[0]); }
+ if(IS_KEY("Aud_ID")) { id_val[1] = qMin(id_val[1], id); *skipNext = (id > id_val[1]); }
+ }
+ else
+ {
+ *skipNext = true;
+ }
+ }
+ if(*skipNext)
+ {
+ qWarning("Skipping info for non-primary stream!");
+ }
+ return;
+ }
+
+ /*Skip or empty?*/
+ if((*skipNext) || value.isEmpty())
+ {
+ return;
+ }
+
+ /*Playlist file?*/
+ if(IS_KEY("Aud_Source"))
+ {
+ *skipNext = true;
+ audioFile.setFormatContainerType(QString());
+ audioFile.setFormatAudioType(QString());
+ qWarning("Skipping info for playlist file!");
+ return;
+ }
+
+ /*General Section*/
+ if(IS_SEC("Gen"))
+ {
+ if(IS_KEY("Gen_Format"))
+ {
+ audioFile.setFormatContainerType(value);
+ }
+ else if(IS_KEY("Gen_Format_Profile"))
+ {
+ audioFile.setFormatContainerProfile(value);
+ }
+ else if(IS_KEY("Gen_Title") || IS_KEY("Gen_Track"))
+ {
+ audioFile.setFileName(value);
+ }
+ else if(IS_KEY("Gen_Duration"))
+ {
+ unsigned int tmp = parseDuration(value);
+ if(tmp > 0) audioFile.setFileDuration(tmp);
+ }
+ else if(IS_KEY("Gen_Artist") || IS_KEY("Gen_Performer"))
+ {
+ audioFile.setFileArtist(value);
+ }
+ else if(IS_KEY("Gen_Album"))
+ {
+ audioFile.setFileAlbum(value);
+ }
+ else if(IS_KEY("Gen_Genre"))
+ {
+ audioFile.setFileGenre(value);
+ }
+ else if(IS_KEY("Gen_Released_Date") || IS_KEY("Gen_Recorded_Date"))
+ {
+ unsigned int tmp = parseYear(value);
+ if(tmp > 0) audioFile.setFileYear(tmp);
+ }
+ else if(IS_KEY("Gen_Comment"))
+ {
+ audioFile.setFileComment(value);
+ }
+ else if(IS_KEY("Gen_Track/Position"))
+ {
+ bool ok = false;
+ unsigned int tmp = value.toUInt(&ok);
+ if(ok) audioFile.setFilePosition(tmp);
+ }
+ else if(IS_KEY("Gen_Cover") || IS_KEY("Gen_Cover_Type"))
+ {
+ if(*coverType == coverNone)
+ {
+ *coverType = coverJpeg;
+ }
+ }
+ else if(IS_KEY("Gen_Cover_Mime"))
+ {
+ QString temp = FIRST_TOK(value);
+ if(!temp.compare("image/jpeg", Qt::CaseInsensitive)) *coverType = coverJpeg;
+ else if(!temp.compare("image/png", Qt::CaseInsensitive)) *coverType = coverPng;
+ else if(!temp.compare("image/gif", Qt::CaseInsensitive)) *coverType = coverGif;
+ }
+ else if(IS_KEY("Gen_Cover_Data"))
+ {
+ if(!coverData->isEmpty()) coverData->clear();
+ coverData->append(QByteArray::fromBase64(FIRST_TOK(value).toLatin1()));
+ }
+ else
+ {
+ qWarning("Unknown key '%s' with value '%s' found!", key.toUtf8().constData(), value.toUtf8().constData());
+ }
+ return;
+ }
+
+ /*Audio Section*/
+ if(IS_SEC("Aud"))
+ {
+
+ if(IS_KEY("Aud_Format"))
+ {
+ audioFile.setFormatAudioType(value);
+ }
+ else if(IS_KEY("Aud_Format_Profile"))
+ {
+ audioFile.setFormatAudioProfile(value);
+ }
+ else if(IS_KEY("Aud_Format_Version"))
+ {
+ audioFile.setFormatAudioVersion(value);
+ }
+ else if(IS_KEY("Aud_Channel(s)"))
+ {
+ bool ok = false;
+ unsigned int tmp = value.toUInt(&ok);
+ if(ok) audioFile.setFormatAudioChannels(tmp);
+ }
+ else if(IS_KEY("Aud_SamplingRate"))
+ {
+ bool ok = false;
+ unsigned int tmp = value.toUInt(&ok);
+ if(ok) audioFile.setFormatAudioSamplerate(tmp);
+ }
+ else if(IS_KEY("Aud_BitDepth"))
+ {
+ bool ok = false;
+ unsigned int tmp = value.toUInt(&ok);
+ if(ok) audioFile.setFormatAudioBitdepth(tmp);
+ }
+ else if(IS_KEY("Aud_Duration"))
+ {
+ unsigned int tmp = parseDuration(value);
+ if(tmp > 0) audioFile.setFileDuration(tmp);
+ }
+ else if(IS_KEY("Aud_BitRate"))
+ {
+ bool ok = false;
+ unsigned int tmp = value.toUInt(&ok);
+ if(ok) audioFile.setFormatAudioBitrate(tmp/1000);
+ }
+ else if(IS_KEY("Aud_BitRate_Mode"))
+ {
+ if(!value.compare("CBR", Qt::CaseInsensitive)) audioFile.setFormatAudioBitrateMode(AudioFileModel::BitrateModeConstant);
+ if(!value.compare("VBR", Qt::CaseInsensitive)) audioFile.setFormatAudioBitrateMode(AudioFileModel::BitrateModeVariable);
+ }
+ else
+ {
+ qWarning("Unknown key '%s' with value '%s' found!", key.toUtf8().constData(), value.toUtf8().constData());
+ }
+ return;
+ }
+
+ /*Section not recognized*/
+ qWarning("Unknown section: %s", key.toUtf8().constData());
+}
+
+bool FileAnalyzer_ST::checkFile_CDDA(QFile &file)
+{
+ file.reset();
+ QByteArray data = file.read(128);
+
+ int i = data.indexOf("RIFF");
+ int j = data.indexOf("CDDA");
+ int k = data.indexOf("fmt ");
+
+ return ((i >= 0) && (j >= 0) && (k >= 0) && (k > j) && (j > i));
+}
+
+void FileAnalyzer_ST::retrieveCover(AudioFileModel &audioFile, cover_t coverType, const QByteArray &coverData)
+{
+ qDebug("Retrieving cover!");
+ QString extension;
+
+ switch(coverType)
+ {
+ case coverPng:
+ extension = QString::fromLatin1("png");
+ break;
+ case coverGif:
+ extension = QString::fromLatin1("gif");
+ break;
+ default:
+ extension = QString::fromLatin1("jpg");
+ break;
+ }
+
+ if(!(QImage::fromData(coverData, extension.toUpper().toLatin1().constData()).isNull()))
+ {
+ QFile coverFile(QString("%1/%2.%3").arg(lamexp_temp_folder2(), lamexp_rand_str(), extension));
+ if(coverFile.open(QIODevice::WriteOnly))
+ {
+ coverFile.write(coverData);
+ coverFile.close();
+ audioFile.setFileCover(coverFile.fileName(), true);
+ }
+ }
+ else
+ {
+ qWarning("Image data seems to be invalid :-(");
+ }
+}
+
+bool FileAnalyzer_ST::analyzeAvisynthFile(const QString &filePath, AudioFileModel &info)
+{
+ QProcess process;
+ process.setProcessChannelMode(QProcess::MergedChannels);
+ process.setReadChannel(QProcess::StandardOutput);
+ process.start(m_avs2wavBin, QStringList() << QDir::toNativeSeparators(filePath) << "?");
+
+ if(!process.waitForStarted())
+ {
+ qWarning("AVS2WAV process failed to create!");
+ qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData());
+ process.kill();
+ process.waitForFinished(-1);
+ return false;
+ }
+
+ bool bInfoHeaderFound = false;
+
+ while(process.state() != QProcess::NotRunning)
+ {
+ if(m_abortFlag)
+ {
+ process.kill();
+ qWarning("Process was aborted on user request!");
+ break;
+ }
+
+ if(!process.waitForReadyRead())
+ {
+ if(process.state() == QProcess::Running)
+ {
+ qWarning("AVS2WAV time out. Killing process and skipping file!");
+ process.kill();
+ process.waitForFinished(-1);
+ return false;
+ }
+ }
+
+ QByteArray data;
+
+ while(process.canReadLine())
+ {
+ QString line = QString::fromUtf8(process.readLine().constData()).simplified();
+ if(!line.isEmpty())
+ {
+ int index = line.indexOf(':');
+ if(index > 0)
+ {
+ QString key = line.left(index).trimmed();
+ QString val = line.mid(index+1).trimmed();
+
+ if(bInfoHeaderFound && !key.isEmpty() && !val.isEmpty())
+ {
+ if(key.compare("TotalSeconds", Qt::CaseInsensitive) == 0)
+ {
+ bool ok = false;
+ unsigned int duration = val.toUInt(&ok);
+ if(ok) info.setFileDuration(duration);
+ }
+ if(key.compare("SamplesPerSec", Qt::CaseInsensitive) == 0)
+ {
+ bool ok = false;
+ unsigned int samplerate = val.toUInt(&ok);
+ if(ok) info.setFormatAudioSamplerate (samplerate);
+ }
+ if(key.compare("Channels", Qt::CaseInsensitive) == 0)
+ {
+ bool ok = false;
+ unsigned int channels = val.toUInt(&ok);
+ if(ok) info.setFormatAudioChannels(channels);
+ }
+ if(key.compare("BitsPerSample", Qt::CaseInsensitive) == 0)
+ {
+ bool ok = false;
+ unsigned int bitdepth = val.toUInt(&ok);
+ if(ok) info.setFormatAudioBitdepth(bitdepth);
+ }
+ }
+ }
+ else
+ {
+ if(line.contains("[Audio Info]", Qt::CaseInsensitive))
+ {
+ info.setFormatAudioType("Avisynth");
+ info.setFormatContainerType("Avisynth");
+ bInfoHeaderFound = true;
+ }
+ }
+ }
+ }
+ }
+
+ process.waitForFinished();
+ if(process.state() != QProcess::NotRunning)
+ {
+ process.kill();
+ process.waitForFinished(-1);
+ }
+
+ //Check exit code
+ switch(process.exitCode())
+ {
+ case 0:
+ qDebug("Avisynth script was analyzed successfully.");
+ return true;
+ break;
+ case -5:
+ qWarning("It appears that Avisynth is not installed on the system!");
+ return false;
+ break;
+ default:
+ qWarning("Failed to open the Avisynth script, bad AVS file?");
+ return false;
+ break;
+ }
+}
+
+bool FileAnalyzer_ST::createTemplate(void)
+{
+ if(m_templateFile)
+ {
+ qWarning("Template file already exists!");
+ return true;
+ }
+
+ QString templatePath = QString("%1/%2.txt").arg(lamexp_temp_folder2(), lamexp_rand_str());
+
+ QFile templateFile(templatePath);
+ if(!templateFile.open(QIODevice::WriteOnly))
+ {
+ return false;
+ }
+
+ templateFile.write("General;");
+ for(size_t i = 0; g_tags_gen[i]; i++)
+ {
+ templateFile.write(QString("Gen_%1=%%1%\\n").arg(g_tags_gen[i]).toLatin1().constData());
+ }
+ templateFile.write("\\n\r\n");
+
+ templateFile.write("Audio;");
+ for(size_t i = 0; g_tags_aud[i]; i++)
+ {
+ templateFile.write(QString("Aud_%1=%%1%\\n").arg(g_tags_aud[i]).toLatin1().constData());
+ }
+ templateFile.write("\\n\r\n");
+
+ bool success = (templateFile.error() == QFile::NoError);
+ templateFile.close();
+
+ if(!success)
+ {
+ QFile::remove(templatePath);
+ return false;
+ }
+
+ try
+ {
+ m_templateFile = new LockedFile(templatePath);
+ }
+ catch(...)
+ {
+ qWarning("Failed to lock template file!");
+ return false;
+ }
+
+ return true;
+}
+
+unsigned int FileAnalyzer_ST::parseYear(const QString &str)
+{
+ if(str.startsWith("UTC", Qt::CaseInsensitive))
+ {
+ QDate date = QDate::fromString(str.mid(3).trimmed().left(10), "yyyy-MM-dd");
+ if(date.isValid())
+ {
+ return date.year();
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ bool ok = false;
+ int year = str.toInt(&ok);
+ if(ok && year > 0)
+ {
+ return year;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+}
+
+unsigned int FileAnalyzer_ST::parseDuration(const QString &str)
+{
+ bool ok = false;
+ unsigned int value = str.toUInt(&ok);
+ return ok ? (value/1000) : 0;
+}
+
+////////////////////////////////////////////////////////////
+// Public Functions
+////////////////////////////////////////////////////////////
+
+unsigned int FileAnalyzer_ST::filesAccepted(void)
+{
+ return m_filesAccepted;
+}
+
+unsigned int FileAnalyzer_ST::filesRejected(void)
+{
+ return m_filesRejected;
+}
+
+unsigned int FileAnalyzer_ST::filesDenied(void)
+{
+ return m_filesDenied;
+}
+
+unsigned int FileAnalyzer_ST::filesDummyCDDA(void)
+{
+ return m_filesDummyCDDA;
+}
+
+unsigned int FileAnalyzer_ST::filesCueSheet(void)
+{
+ return m_filesCueSheet;
+}
+
+////////////////////////////////////////////////////////////
+// EVENTS
+////////////////////////////////////////////////////////////
+
+/*NONE*/
diff --git a/src/Thread_FileAnalyzer_ST.h b/src/Thread_FileAnalyzer_ST.h
new file mode 100644
index 00000000..4bc87b26
--- /dev/null
+++ b/src/Thread_FileAnalyzer_ST.h
@@ -0,0 +1,107 @@
+///////////////////////////////////////////////////////////////////////////////
+// LameXP - Audio Encoder Front-End
+// Copyright (C) 2004-2012 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
+///////////////////////////////////////////////////////////////////////////////
+
+// --------------------------------------------------------------------
+// !!! THIS IS THE OLD SINGLE-THREADED VERSION OF THE FILE ANALYZER !!!
+// --------------------------------------------------------------------
+
+#pragma once
+
+#include
+#include
+
+class AudioFileModel;
+class QFile;
+class QDir;
+class QFileInfo;
+class LockedFile;
+
+////////////////////////////////////////////////////////////
+// Splash Thread
+////////////////////////////////////////////////////////////
+
+class FileAnalyzer_ST: public QThread
+{
+ Q_OBJECT
+
+public:
+ FileAnalyzer_ST(const QStringList &inputFiles);
+ ~FileAnalyzer_ST(void);
+ void run();
+ bool getSuccess(void) { return !isRunning() && m_bSuccess; }
+ unsigned int filesAccepted(void);
+ unsigned int filesRejected(void);
+ unsigned int filesDenied(void);
+ unsigned int filesDummyCDDA(void);
+ unsigned int filesCueSheet(void);
+
+signals:
+ void fileSelected(const QString &fileName);
+ void fileAnalyzed(const AudioFileModel &file);
+
+public slots:
+ void abortProcess(void) { m_abortFlag = true; }
+
+private:
+ enum cover_t
+ {
+ coverNone,
+ coverJpeg,
+ coverPng,
+ coverGif
+ };
+ enum fileType_t
+ {
+ fileTypeNormal = 0,
+ fileTypeCDDA = 1,
+ fileTypeDenied = 2,
+ fileTypeSkip = 3
+ };
+
+ const AudioFileModel analyzeFile(const QString &filePath, int *type);
+ void updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned int *id_val, cover_t *coverType, QByteArray *coverData, const QString &key, const QString &value);
+ unsigned int parseYear(const QString &str);
+ unsigned int parseDuration(const QString &str);
+ bool checkFile_CDDA(QFile &file);
+ void retrieveCover(AudioFileModel &audioFile, cover_t coverType, const QByteArray &coverData);
+ bool analyzeAvisynthFile(const QString &filePath, AudioFileModel &info);
+ bool createTemplate(void);
+
+ const QString m_mediaInfoBin;
+ const QString m_avs2wavBin;
+
+ QStringList m_inputFiles;
+ QStringList m_recentlyAdded;
+ unsigned int m_filesAccepted;
+ unsigned int m_filesRejected;
+ unsigned int m_filesDenied;
+ unsigned int m_filesDummyCDDA;
+ unsigned int m_filesCueSheet;
+ LockedFile *m_templateFile;
+
+ volatile bool m_abortFlag;
+
+ static const char *g_tags_gen[];
+ static const char *g_tags_aud[];
+
+ bool m_bAborted;
+ bool m_bSuccess;
+};
diff --git a/src/Thread_FileAnalyzer_Task.cpp b/src/Thread_FileAnalyzer_Task.cpp
index 74730238..8566b138 100644
--- a/src/Thread_FileAnalyzer_Task.cpp
+++ b/src/Thread_FileAnalyzer_Task.cpp
@@ -39,22 +39,25 @@
#include
#include
+#include
#define IS_KEY(KEY) (key.compare(KEY, Qt::CaseInsensitive) == 0)
#define IS_SEC(SEC) (key.startsWith((SEC "_"), Qt::CaseInsensitive))
#define FIRST_TOK(STR) (STR.split(" ", QString::SkipEmptyParts).first())
/* static vars */
-QReadWriteLock AnalyzeTask::s_lock;
QMutex AnalyzeTask::s_waitMutex;
QWaitCondition AnalyzeTask::s_waitCond;
-unsigned __int64 AnalyzeTask::s_threadIdx_created;
-unsigned __int64 AnalyzeTask::s_threadIdx_finished;
-unsigned int AnalyzeTask::s_filesAccepted;
-unsigned int AnalyzeTask::s_filesRejected;
-unsigned int AnalyzeTask::s_filesDenied;
-unsigned int AnalyzeTask::s_filesDummyCDDA;
-unsigned int AnalyzeTask::s_filesCueSheet;
+QSet AnalyzeTask::s_threadIdx_running;
+unsigned int AnalyzeTask::s_threadIdx_next = 0;
+
+/* more static vars */
+QReadWriteLock AnalyzeTask::s_lock;
+unsigned int AnalyzeTask::s_filesAccepted = 0;
+unsigned int AnalyzeTask::s_filesRejected = 0;
+unsigned int AnalyzeTask::s_filesDenied = 0;
+unsigned int AnalyzeTask::s_filesDummyCDDA = 0;
+unsigned int AnalyzeTask::s_filesCueSheet = 0;
QStringList AnalyzeTask::s_additionalFiles;
QSet AnalyzeTask::s_recentlyAdded;
@@ -84,7 +87,7 @@ AnalyzeTask::AnalyzeTask(const QString &inputFile, const QString &templateFile,
AnalyzeTask::~AnalyzeTask(void)
{
s_waitMutex.lock();
- s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1ui64);
+ s_threadIdx_running.remove(m_threadIdx);
s_waitMutex.unlock();
s_waitCond.wakeAll();
@@ -106,7 +109,7 @@ void AnalyzeTask::run()
}
s_waitMutex.lock();
- s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1ui64);
+ s_threadIdx_running.remove(m_threadIdx);
s_waitMutex.unlock();
s_waitCond.wakeAll();
@@ -130,7 +133,6 @@ void AnalyzeTask::run_ex(void)
}
if(fileType == fileTypeSkip)
{
- waitForPreviousThreads();
qWarning("File was recently added, skipping!");
return;
}
@@ -139,7 +141,6 @@ void AnalyzeTask::run_ex(void)
QWriteLocker lock(&s_lock);
s_filesDenied++;
lock.unlock();
- waitForPreviousThreads();
qWarning("Cannot access file for reading, skipping!");
return;
}
@@ -148,7 +149,6 @@ void AnalyzeTask::run_ex(void)
QWriteLocker lock(&s_lock);
s_filesDummyCDDA++;
lock.unlock();
- waitForPreviousThreads();
qWarning("Dummy CDDA file detected, skipping!");
return;
}
@@ -159,7 +159,6 @@ void AnalyzeTask::run_ex(void)
QStringList fileList;
if(PlaylistImporter::importPlaylist(fileList, currentFile))
{
- waitForPreviousThreads();
qDebug("Imported playlist file.");
QWriteLocker lock(&s_lock);
s_additionalFiles << fileList;
@@ -195,7 +194,6 @@ void AnalyzeTask::run_ex(void)
qDebug("Rejected file of unknown type: %s", file.filePath().toUtf8().constData());
s_filesRejected++;
}
- waitForPreviousThreads();
return;
}
@@ -725,7 +723,8 @@ unsigned int AnalyzeTask::parseDuration(const QString &str)
unsigned __int64 AnalyzeTask::makeThreadIdx(void)
{
s_waitMutex.lock();
- unsigned __int64 idx = s_threadIdx_created++;
+ unsigned int idx = s_threadIdx_next++;
+ s_threadIdx_running.insert(idx);
s_waitMutex.unlock();
return idx;
@@ -736,13 +735,20 @@ void AnalyzeTask::waitForPreviousThreads(void)
//This function will block until all threads with a *lower* index have terminated.
//Required to make sure that the files will be added in the "correct" order!
+ s_waitMutex.lock();
int retryCount = 0;
- while(retryCount < MAX_RETRIES)
+ forever
{
- s_waitMutex.lock();
+ bool bWaitFlag = false;
+ QSet::const_iterator i;
- if((s_threadIdx_finished >= m_threadIdx) || *m_abortFlag)
+ for(i = s_threadIdx_running.begin(); i != s_threadIdx_running.end(); ++i)
+ {
+ if(*i < m_threadIdx) { bWaitFlag = true; break; }
+ }
+
+ if((!bWaitFlag) || *m_abortFlag)
{
s_waitMutex.unlock();
return;
@@ -750,13 +756,13 @@ void AnalyzeTask::waitForPreviousThreads(void)
if(!s_waitCond.wait(&s_waitMutex, WAITCOND_TIMEOUT))
{
- retryCount++;
+ if(++retryCount > MAX_RETRIES)
+ {
+ qWarning("AnalyzeTask::waitForPreviousThreads encountered timeout !!!");
+ s_threadIdx_running.clear();
+ }
}
-
- s_waitMutex.unlock();
}
-
- qWarning("AnalyzeTask Timeout, will proceed anyway !!!");
}
////////////////////////////////////////////////////////////
@@ -835,8 +841,8 @@ void AnalyzeTask::reset(void)
lock.unlock();
s_waitMutex.lock();
- s_threadIdx_created = 0;
- s_threadIdx_finished = 0;
+ s_threadIdx_next = 0;
+ s_threadIdx_running.clear();
s_waitMutex.unlock();
}
diff --git a/src/Thread_FileAnalyzer_Task.h b/src/Thread_FileAnalyzer_Task.h
index e1135074..ac91aaaa 100644
--- a/src/Thread_FileAnalyzer_Task.h
+++ b/src/Thread_FileAnalyzer_Task.h
@@ -102,8 +102,8 @@ private:
static QMutex s_waitMutex;
static QWaitCondition s_waitCond;
- static unsigned __int64 s_threadIdx_created;
- static unsigned __int64 s_threadIdx_finished;
+ static QSet s_threadIdx_running;
+ static unsigned int s_threadIdx_next;
static QReadWriteLock s_lock;
static unsigned int s_filesAccepted;