void AnalyzeTask::run_ex(void) { int fileType = fileTypeNormal; QString currentFile = QDir::fromNativeSeparators(m_inputFile); qDebug("Analyzing: %s", QUTF8(currentFile)); AudioFileModel file = analyzeFile(currentFile, &fileType); if(*m_abortFlag) { qWarning("Operation cancelled by user!"); return; } switch(fileType) { case fileTypeDenied: qWarning("Cannot access file for reading, skipping!"); break; case fileTypeCDDA: qWarning("Dummy CDDA file detected, skipping!"); break; default: if(file.metaInfo().title().isEmpty() || file.techInfo().containerType().isEmpty() || file.techInfo().audioType().isEmpty()) { fileType = fileTypeUnknown; if(!QFileInfo(currentFile).suffix().compare("cue", Qt::CaseInsensitive)) { qWarning("Cue Sheet file detected, skipping!"); fileType = fileTypeCueSheet; } else if(!QFileInfo(currentFile).suffix().compare("avs", Qt::CaseInsensitive)) { qDebug("Found a potential Avisynth script, investigating..."); if(analyzeAvisynthFile(currentFile, file)) { fileType = fileTypeNormal; } else { qDebug("Rejected Avisynth file: %s", QUTF8(file.filePath())); } } else { qDebug("Rejected file of unknown type: %s", QUTF8(file.filePath())); } } break; } //Emit the file now! emit fileAnalyzed(m_taskId, fileType, file); }
void DiskObserverThread::observe(void) { unsigned __int64 minimumSpace = MIN_DISKSPACE; unsigned __int64 freeSpace, previousSpace = 0ui64; bool ok = false; forever { freeSpace = lamexp_free_diskspace(m_path, &ok); if(ok) { if(freeSpace < minimumSpace) { qWarning("Free diskspace on '%s' dropped below %s MB, only %s MB free!", QUTF8(m_path), QUTF8(QString::number(minimumSpace / 1048576ui64)), QUTF8(QString::number(freeSpace / 1048576ui64))); emit messageLogged(tr("Low diskspace on drive '%1' detected (only %2 MB are free), problems can occur!").arg(QDir::toNativeSeparators(m_path), QString::number(freeSpace / 1048576ui64)), ProgressModel::SysMsg_Warning); minimumSpace = qMin(freeSpace, (minimumSpace >> 1)); } if(freeSpace != previousSpace) { emit freeSpaceChanged(freeSpace); previousSpace = freeSpace; } } if(m_semaphore.tryAcquire(1, 2000)) break; }
CueSplitter::CueSplitter(const QString &outputDir, const QString &baseName, CueSheetModel *model, const QList<AudioFileModel> &inputFilesInfo) : m_model(model), m_outputDir(outputDir), m_baseName(baseName), m_soxBin(lamexp_lookup_tool("sox.exe")) { if(m_soxBin.isEmpty()) { qFatal("Invalid path to SoX binary. Tool not initialized properly."); } m_decompressedFiles.clear(); m_tempFiles.clear(); qDebug("\n[CueSplitter]"); int nInputFiles = inputFilesInfo.count(); for(int i = 0; i < nInputFiles; i++) { m_inputFilesInfo.insert(inputFilesInfo[i].filePath(), inputFilesInfo[i]); qDebug("File %02d: <%s>", i, QUTF8(inputFilesInfo[i].filePath())); } qDebug("All input files added."); m_bSuccess = false; }
void CueSplitter::run() { m_bSuccess = false; m_bAborted = false; m_abortFlag = false; m_nTracksSuccess = 0; m_nTracksSkipped = 0; m_decompressedFiles.clear(); m_activeFile.clear(); if(!QDir(m_outputDir).exists()) { qWarning("Output directory \"%s\" does not exist!", QUTF8(m_outputDir)); return; } QStringList inputFileList = m_inputFilesInfo.keys(); int nInputFiles = inputFileList.count(); emit progressMaxChanged(nInputFiles); emit progressValChanged(0); //Decompress all input files for(int i = 0; i < nInputFiles; i++) { const AudioFileModel_TechInfo &inputFileInfo = m_inputFilesInfo[inputFileList.at(i)].techInfo(); if(inputFileInfo.containerType().compare("Wave", Qt::CaseInsensitive) || inputFileInfo.audioType().compare("PCM", Qt::CaseInsensitive)) { AbstractDecoder *decoder = DecoderRegistry::lookup(inputFileInfo.containerType(), inputFileInfo.containerProfile(), inputFileInfo.audioType(), inputFileInfo.audioProfile(), inputFileInfo.audioVersion()); if(decoder) { m_activeFile = shortName(QFileInfo(inputFileList.at(i)).fileName()); emit fileSelected(m_activeFile); emit progressValChanged(i+1); QString tempFile = QString("%1/~%2.wav").arg(m_outputDir, lamexp_rand_str()); connect(decoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection); if(decoder->decode(inputFileList.at(i), tempFile, &m_abortFlag)) { m_decompressedFiles.insert(inputFileList.at(i), tempFile); m_tempFiles.append(tempFile); } else { qWarning("Failed to decompress file: <%s>", inputFileList.at(i).toLatin1().constData()); lamexp_remove_file(tempFile); } m_activeFile.clear(); LAMEXP_DELETE(decoder); } else { qWarning("Unsupported input file: <%s>", inputFileList.at(i).toLatin1().constData()); } }
inline void flushValues(void) { QMutexLocker lock(m_cacheLock); if(!m_cacheDirty->isEmpty()) { QSet<QString>::ConstIterator iter; for(iter = m_cacheDirty->constBegin(); iter != m_cacheDirty->constEnd(); iter++) { if(m_cache->contains(*iter)) { m_configFile->setValue((*iter), m_cache->value(*iter)); } else { qWarning("Could not find '%s' in cache, but it has been marked as dirty!", QUTF8(*iter)); } } m_configFile->sync(); m_cacheDirty->clear(); } }
bool PlaylistImporter::parsePlaylist_m3u(QFile &data, QStringList &fileList, const QDir &baseDir, const QDir &rootDir) { const QTextCodec *codec = QTextCodec::codecForName("System"); const bool preferUTF8 = data.fileName().endsWith(".m3u8", Qt::CaseInsensitive); bool foundAtLeastOneFile = false; data.reset(); while(!data.atEnd()) { QString filePath[3]; QByteArray line = data.readLine(); if(preferUTF8) { filePath[0] = QString(QDir::fromNativeSeparators(QString::fromUtf8(line.constData(), line.size()).trimmed())); filePath[1] = QString(QDir::fromNativeSeparators(codec->toUnicode(line.constData(), line.size()).trimmed())); filePath[2] = QString(QDir::fromNativeSeparators(QString::fromLatin1(line.constData(), line.size()).trimmed())); } else { filePath[0] = QString(QDir::fromNativeSeparators(codec->toUnicode(line.constData(), line.size()).trimmed())); filePath[1] = QString(QDir::fromNativeSeparators(QString::fromLatin1(line.constData(), line.size()).trimmed())); filePath[2] = QString(QDir::fromNativeSeparators(QString::fromUtf8(line.constData(), line.size()).trimmed())); } for(size_t i = 0; i < 3; i++) { if(!(filePath[i].isEmpty() || filePath[i].startsWith("#") || filePath[i].contains(QChar(QChar::ReplacementCharacter)))) { QFileInfo filename(filePath[i]); filename.setCaching(false); fixFilePath(filename, baseDir, rootDir); if(filename.exists() && filename.isFile()) { qDebug("Found: \"%s\"", QUTF8(filePath[i])); if(isPlaylist(filename.canonicalFilePath()) == notPlaylist) { fileList << filename.canonicalFilePath(); } foundAtLeastOneFile = true; break; } } } } //If we did not find any files yet, try UTF-16 now if(!foundAtLeastOneFile) { const char* codecs[2] = {"UTF-16LE", "UTF-16BE"}; for(size_t i = 0; i < 2; i++) { QTextStream stream(&data); stream.setAutoDetectUnicode(false); stream.setCodec(codecs[i]); stream.seek(0i64); while(!stream.atEnd()) { QString filePath = stream.readLine().trimmed(); if(!(filePath.isEmpty() || filePath.startsWith("#") || filePath.contains(QChar(QChar::ReplacementCharacter)))) { QFileInfo filename(filePath); filename.setCaching(false); fixFilePath(filename, baseDir, rootDir); if(filename.exists() && filename.isFile()) { if(isPlaylist(filename.canonicalFilePath()) == notPlaylist) { fileList << filename.canonicalFilePath(); } foundAtLeastOneFile = true; } } } if(foundAtLeastOneFile) break; } } return foundAtLeastOneFile; }
int FileListModel::importFromCsv(QWidget *parent, const QString &inFile) { QFile file(inFile); if(!file.open(QIODevice::ReadOnly)) { return CsvError_FileOpen; } QTextCodec *codec = NULL; QByteArray bomCheck = file.peek(16); if((!bomCheck.isEmpty()) && bomCheck.startsWith("\xef\xbb\xbf")) { codec = QTextCodec::codecForName("UTF-8"); } else if((!bomCheck.isEmpty()) && bomCheck.startsWith("\xff\xfe")) { codec = QTextCodec::codecForName("UTF-16LE"); } else if((!bomCheck.isEmpty()) && bomCheck.startsWith("\xfe\xff")) { codec = QTextCodec::codecForName("UTF-16BE"); } else { const QString systemDefault = tr("(System Default)"); QStringList codecList; codecList.append(systemDefault); codecList.append(lamexp_available_codepages()); QInputDialog *input = new QInputDialog(parent); input->setLabelText(EXPAND(tr("Select ANSI Codepage for CSV file:"))); input->setOkButtonText(tr("OK")); input->setCancelButtonText(tr("Cancel")); input->setTextEchoMode(QLineEdit::Normal); input->setComboBoxItems(codecList); if(input->exec() < 1) { LAMEXP_DELETE(input); return CsvError_Aborted; } if(input->textValue().compare(systemDefault, Qt::CaseInsensitive)) { qDebug("User-selected codec is: %s", input->textValue().toLatin1().constData()); codec = QTextCodec::codecForName(input->textValue().toLatin1().constData()); } else { qDebug("Going to use the system's default codec!"); codec = QTextCodec::codecForName("System"); } LAMEXP_DELETE(input); } bomCheck.clear(); //----------------------// QTextStream stream(&file); stream.setAutoDetectUnicode(false); stream.setCodec(codec); QString headerLine = stream.readLine().simplified(); while(headerLine.isEmpty()) { if(stream.atEnd()) { qWarning("The file appears to be empty!"); return CsvError_FileRead; } qWarning("Skipping a blank line at beginning of CSV file!"); headerLine = stream.readLine().simplified(); } QStringList header = headerLine.split(";", QString::KeepEmptyParts); const int nCols = header.count(); const int nFiles = m_fileList.count(); if(nCols < 1) { qWarning("Header appears to be empty!"); return CsvError_FileRead; } bool *ignore = new bool[nCols]; memset(ignore, 0, sizeof(bool) * nCols); for(int i = 0; i < nCols; i++) { if((header[i] = header[i].trimmed()).isEmpty()) { ignore[i] = true; } } //----------------------// for(int i = 0; i < nFiles; i++) { if(stream.atEnd()) { LAMEXP_DELETE_ARRAY(ignore); return CsvError_Incomplete; } QString line = stream.readLine().simplified(); if(line.isEmpty()) { qWarning("Skipping a blank line in CSV file!"); continue; } QStringList data = line.split(";", QString::KeepEmptyParts); if(data.count() < header.count()) { qWarning("Skipping an incomplete line in CSV file!"); continue; } const QString key = m_fileList[i]; for(int j = 0; j < nCols; j++) { if(ignore[j]) { continue; } else if(CHECK_HDR(header.at(j), "POSITION")) { bool ok = false; unsigned int temp = data.at(j).trimmed().toUInt(&ok); if(ok) m_fileStore[key].metaInfo().setPosition(temp); } else if(CHECK_HDR(header.at(j), "TITLE")) { QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileStore[key].metaInfo().setTitle(temp); } else if(CHECK_HDR(header.at(j), "ARTIST")) { QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileStore[key].metaInfo().setArtist(temp); } else if(CHECK_HDR(header.at(j), "ALBUM")) { QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileStore[key].metaInfo().setAlbum(temp); } else if(CHECK_HDR(header.at(j), "GENRE")) { QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileStore[key].metaInfo().setGenre(temp); } else if(CHECK_HDR(header.at(j), "YEAR")) { bool ok = false; unsigned int temp = data.at(j).trimmed().toUInt(&ok); if(ok) m_fileStore[key].metaInfo().setYear(temp); } else if(CHECK_HDR(header.at(j), "COMMENT")) { QString temp = data.at(j).trimmed(); if(!temp.isEmpty()) m_fileStore[key].metaInfo().setComment(temp); } else { qWarning("Unkonw field '%s' will be ignored!", QUTF8(header.at(j))); ignore[j] = true; if(!checkArray(ignore, false, nCols)) { qWarning("No known fields left, aborting!"); return CsvError_NoTags; } } } } //----------------------// LAMEXP_DELETE_ARRAY(ignore); return CsvError_OK; }
QString SettingsModel::defaultLanguage(void) const { QReadLocker readLock(&s_lock); //Default already initialized? if(m_defaultLanguage) { return *m_defaultLanguage; } //Acquire write lock now readLock.unlock(); QWriteLocker writeLock(&s_lock); //Default still not initialized? if(m_defaultLanguage) { return *m_defaultLanguage; } //Detect system langauge QLocale systemLanguage= QLocale::system(); qDebug("[Locale]"); qDebug("Language: %s (%d)", QUTF8(QLocale::languageToString(systemLanguage.language())), systemLanguage.language()); qDebug("Country is: %s (%d)", QUTF8(QLocale::countryToString(systemLanguage.country())), systemLanguage.country()); qDebug("Script is: %s (%d)\n", QUTF8(QLocale::scriptToString(systemLanguage.script())), systemLanguage.script()); //Check if we can use the default translation if(systemLanguage.language() == QLocale::English /*|| systemLanguage.language() == QLocale::C*/) { m_defaultLanguage = new QString(LAMEXP_DEFAULT_LANGID); return LAMEXP_DEFAULT_LANGID; } //Try to find a suitable translation for the user's system language *and* country QStringList languages = lamexp_query_translations(); while(!languages.isEmpty()) { QString currentLangId = languages.takeFirst(); if(lamexp_translation_sysid(currentLangId) == systemLanguage.language()) { if(lamexp_translation_country(currentLangId) == systemLanguage.country()) { m_defaultLanguage = new QString(currentLangId); return currentLangId; } } } //Try to find a suitable translation for the user's system language languages = lamexp_query_translations(); while(!languages.isEmpty()) { QString currentLangId = languages.takeFirst(); if(lamexp_translation_sysid(currentLangId) == systemLanguage.language()) { m_defaultLanguage = new QString(currentLangId); return currentLangId; } } //Fall back to the default translation m_defaultLanguage = new QString(LAMEXP_DEFAULT_LANGID); return LAMEXP_DEFAULT_LANGID; }
SettingsModel::SettingsModel(void) { QString configPath = "LameXP.ini"; if(!lamexp_portable_mode()) { QString dataPath = initDirectory(QDesktopServices::storageLocation(QDesktopServices::DataLocation)); if(!dataPath.isEmpty()) { configPath = QString("%1/config.ini").arg(QDir(dataPath).canonicalPath()); } else { qWarning("SettingsModel: DataLocation could not be initialized!"); dataPath = initDirectory(QDesktopServices::storageLocation(QDesktopServices::HomeLocation)); if(!dataPath.isEmpty()) { configPath = QString("%1/LameXP.ini").arg(QDir(dataPath).canonicalPath()); } } } else { qDebug("LameXP is running in \"portable\" mode -> config in application dir!\n"); QString appPath = QFileInfo(QApplication::applicationFilePath()).canonicalFilePath(); if(appPath.isEmpty()) { appPath = QFileInfo(QApplication::applicationFilePath()).absoluteFilePath(); } if(QFileInfo(appPath).exists() && QFileInfo(appPath).isFile()) { configPath = QString("%1/%2.ini").arg(QFileInfo(appPath).absolutePath(), QFileInfo(appPath).completeBaseName()); } } //Create settings QSettings *configFile = new QSettings(configPath, QSettings::IniFormat); const QString groupKey = QString().sprintf("LameXP_%u%02u%05u", lamexp_version_major(), lamexp_version_minor(), lamexp_version_confg()); QStringList childGroups =configFile->childGroups(); //Clean-up settings while(!childGroups.isEmpty()) { QString current = childGroups.takeFirst(); QRegExp filter("^LameXP_(\\d+)(\\d\\d)(\\d\\d\\d\\d\\d)$"); if(filter.indexIn(current) >= 0) { bool ok = false; unsigned int temp = filter.cap(3).toUInt(&ok) + 10; if(ok && (temp >= lamexp_version_confg())) { continue; } } qWarning("Deleting obsolete group from config: %s", QUTF8(current)); REMOVE_GROUP(configFile, current); } //Setup settings configFile->beginGroup(groupKey); configFile->setValue(g_settingsId_versionNumber, QApplication::applicationVersion()); configFile->sync(); //Create the cache m_configCache = new SettingsCache(configFile); }
void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned int *id_val, cover_t *coverType, QByteArray *coverData, const QString &key, const QString &value) { //qWarning("'%s' -> '%s'", QUTF8(key), QUTF8(value)); /*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.techInfo().setContainerType(QString()); audioFile.techInfo().setAudioType(QString()); qWarning("Skipping info for playlist file!"); return; } /*General Section*/ if(IS_SEC("Gen")) { if(IS_KEY("Gen_Format")) { audioFile.techInfo().setContainerType(value); } else if(IS_KEY("Gen_Format_Profile")) { audioFile.techInfo().setContainerProfile(value); } else if(IS_KEY("Gen_Title") || IS_KEY("Gen_Track")) { audioFile.metaInfo().setTitle(value); } else if(IS_KEY("Gen_Duration")) { unsigned int tmp = parseDuration(value); if(tmp > 0) audioFile.techInfo().setDuration(tmp); } else if(IS_KEY("Gen_Artist") || IS_KEY("Gen_Performer")) { audioFile.metaInfo().setArtist(value); } else if(IS_KEY("Gen_Album")) { audioFile.metaInfo().setAlbum(value); } else if(IS_KEY("Gen_Genre")) { audioFile.metaInfo().setGenre(value); } else if(IS_KEY("Gen_Released_Date") || IS_KEY("Gen_Recorded_Date")) { unsigned int tmp = parseYear(value); if(tmp > 0) audioFile.metaInfo().setYear(tmp); } else if(IS_KEY("Gen_Comment")) { audioFile.metaInfo().setComment(value); } else if(IS_KEY("Gen_Track/Position")) { bool ok = false; unsigned int tmp = value.toUInt(&ok); if(ok) audioFile.metaInfo().setPosition(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!", QUTF8(key), QUTF8(value)); } return; } /*Audio Section*/ if(IS_SEC("Aud")) { if(IS_KEY("Aud_Format")) { audioFile.techInfo().setAudioType(value); } else if(IS_KEY("Aud_Format_Profile")) { audioFile.techInfo().setAudioProfile(value); } else if(IS_KEY("Aud_Format_Version")) { audioFile.techInfo().setAudioVersion(value); } else if(IS_KEY("Aud_Channel(s)")) { bool ok = false; unsigned int tmp = value.toUInt(&ok); if(ok) audioFile.techInfo().setAudioChannels(tmp); } else if(IS_KEY("Aud_SamplingRate")) { bool ok = false; unsigned int tmp = value.toUInt(&ok); if(ok) audioFile.techInfo().setAudioSamplerate(tmp); } else if(IS_KEY("Aud_BitDepth")) { bool ok = false; unsigned int tmp = value.toUInt(&ok); if(ok) audioFile.techInfo().setAudioBitdepth(tmp); } else if(IS_KEY("Aud_Duration")) { unsigned int tmp = parseDuration(value); if(tmp > 0) audioFile.techInfo().setDuration(tmp); } else if(IS_KEY("Aud_BitRate")) { bool ok = false; unsigned int tmp = value.toUInt(&ok); if(ok) audioFile.techInfo().setAudioBitrate(tmp/1000); } else if(IS_KEY("Aud_BitRate_Mode")) { if(!value.compare("CBR", Qt::CaseInsensitive)) audioFile.techInfo().setAudioBitrateMode(AudioFileModel::BitrateModeConstant); if(!value.compare("VBR", Qt::CaseInsensitive)) audioFile.techInfo().setAudioBitrateMode(AudioFileModel::BitrateModeVariable); } else if(IS_KEY("Aud_Encoded_Library")) { audioFile.techInfo().setAudioEncodeLib(value); } else { qWarning("Unknown key '%s' with value '%s' found!", QUTF8(key), QUTF8(value)); } return; } /*Section not recognized*/ qWarning("Unknown section: %s", QUTF8(key)); }