Skip to content

Commit

Permalink
update audio exporter
Browse files Browse the repository at this point in the history
  • Loading branch information
CrSjimo committed Sep 15, 2024
1 parent eb20797 commit d55a964
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 42 deletions.
8 changes: 5 additions & 3 deletions src/plugins/audioplugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ ck_add_plugin(${PROJECT_NAME}
MACRO_PREFIX AUDIO
)

if(AUDIO_TEST)
if (AUDIO_TEST)
target_compile_definitions(${PROJECT_NAME} PRIVATE AUDIO_TEST)
else()
list(FILTER _src EXCLUDE REGEX tests/)
endif()

# Configure target
file(GLOB_RECURSE _src *.h *.cpp)
qm_configure_target(${PROJECT_NAME}
SOURCES ${_src}
QT_LINKS Core Gui Widgets
QT_INCLUDE_PRIVATE Core Gui Widgets
QT_LINKS Core Gui Widgets Test
QT_INCLUDE_PRIVATE Core Gui Widgets Test
LINKS
ChorusKit::AppCore
svscraft::Widgets
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
#include "audioexporter.h"
#include "audioexporter_p.h"
#include "../../../coreplugin/windows/iprojectwindow.h"

#include <QDir>
#include <QFileInfo>
#include <QVariant>
#include <QRegularExpression>
#include <QStandardPaths>

#include <CoreApi/iloader.h>

#include <audioplugin/internal/audiosettings.h>

namespace Audio {
using namespace Internal;

AudioExporterConfig::AudioExporterConfig() : d(new AudioExporterConfigData) {
}
Expand All @@ -29,6 +37,12 @@ namespace Audio {
void AudioExporterConfig::setFileType(AudioExporterConfig::FileType a_) {
d->fileType = a_;
}
bool AudioExporterConfig::formatMono() const {
return d->formatMono;
}
void AudioExporterConfig::setFormatMono(bool a_) {
d->formatMono = a_;
}
int AudioExporterConfig::formatOption() const {
return d->formatOption;
}
Expand Down Expand Up @@ -83,6 +97,7 @@ namespace Audio {
{"fileName", d->fileName},
{"fileDirectory", d->fileDirectory},
{"fileType", d->fileType},
{"formatMono", d->formatMono},
{"formatOption", d->formatOption},
{"formatQuality", d->formatQuality},
{"formatSampleRate", d->formatSampleRate},
Expand All @@ -98,6 +113,7 @@ namespace Audio {
config.d->fileName = map.value("fileName").toString();
config.d->fileDirectory = map.value("fileDirectory").toString();
config.d->fileType = static_cast<FileType>(map.value("fileType").toInt());
config.d->formatMono = map.value("formatMono").toBool();
config.d->formatOption = map.value("formatOption").toInt();
config.d->formatQuality = map.value("formatQuality").toInt();
config.d->formatSampleRate = map.value("formatSampleRate").toDouble();
Expand All @@ -109,6 +125,91 @@ namespace Audio {
return config;
}

QString AudioExporterPrivate::projectName() const {
// project file's base name
return QFileInfo(windowHandle->doc()->filePath()).baseName();
}
QString AudioExporterPrivate::projectDirectory() const {
if (auto dir = QFileInfo(windowHandle->doc()->filePath()).dir(); dir.isRelative()) {
return QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first();
} else {
return dir.path();
}
}
QString AudioExporterPrivate::trackName(int trackIndex) const {
return windowHandle->doc()->dataModel().model()->tracks()->at(trackIndex)->trackName();
}
bool AudioExporterPrivate::calculateTemplate(QString &templateString) const {
return calculateTemplate(templateString, {}, -1);
}
bool AudioExporterPrivate::calculateTemplate(QString &templateString, const QString &trackName,
int trackIndex) const {
static QRegularExpression re(R"re(\$\{(.*?)\})re");
bool allTemplatesMatch = true;
auto templateStringView = QStringView(templateString);
int pos = 0;
QString result;
for (auto matchIt = re.globalMatch(templateStringView); matchIt.hasNext(); matchIt.next()) {
auto match = matchIt.peekNext();
auto templateName = match.captured(1);
auto replacedText = match.captured(0);
if (templateName == "projectName") {
replacedText = projectName();
} else if (templateName == "sampleRate") {
replacedText = QString::number(config.formatSampleRate());
} else if (templateName == "today") {
replacedText = QDate::currentDate().toString("yyyyMMdd");
} else if (templateName == "$") {
replacedText = QStringLiteral("$");
} else if (trackIndex != -1) {
if (templateName == "trackName") {
replacedText = trackName;
} else if (templateName == "trackIndex") {
replacedText = QString::number(trackIndex + 1);
}
} else {
allTemplatesMatch = false;
}
result += templateStringView.mid(pos, match.capturedStart(0) - pos);
result += replacedText;
pos = match.capturedEnd(0);
}
result += templateStringView.right(templateStringView.length() - pos);
templateString = result;
return allTemplatesMatch;
}
void AudioExporterPrivate::updateFileListAndWarnings() {
warning = {};
if (config.fileType() == AudioExporterConfig::FT_Mp3 || config.fileType() == AudioExporterConfig::FT_OggVorbis)
warning |= AudioExporter::W_LossyFormat;
fileList.clear();
if (config.sourceOption() == AudioExporterConfig::SO_All) {
auto calculatedFileName = config.fileName();
if (!calculateTemplate(calculatedFileName))
warning |= AudioExporter::W_UnrecognizedTemplate;
auto fileInfo = QFileInfo(QDir(projectDirectory()).absoluteFilePath(calculatedFileName));
if (fileInfo.exists())
warning |= AudioExporter::W_WillOverwrite;
fileList.append(fileInfo.canonicalFilePath());
} else {
if (config.source().isEmpty())
warning |= AudioExporter::W_NoFile;
QSet<QString> fileSet;
for (auto index : config.source()) {
auto calculatedFileName = config.fileName();
if (!calculateTemplate(calculatedFileName, trackName(index), index))
warning |= AudioExporter::W_UnrecognizedTemplate;
auto fileInfo = QFileInfo(QDir(projectDirectory()).absoluteFilePath(calculatedFileName));
if (fileInfo.exists())
warning |= AudioExporter::W_WillOverwrite;
if (fileSet.contains(fileInfo.canonicalFilePath()))
warning |= AudioExporter::W_DuplicatedFile;
fileSet.insert(fileInfo.canonicalFilePath());
}
fileList.append(fileSet.values());
}
}

AudioExporter::AudioExporter(Core::IProjectWindow *window, QObject *parent) : QObject(parent), d_ptr(new AudioExporterPrivate) {
Q_D(AudioExporter);
d->q_ptr = this;
Expand All @@ -117,9 +218,7 @@ namespace Audio {
AudioExporter::~AudioExporter() = default;

QStringList AudioExporter::presets() {
auto &settings = *Core::ILoader::instance()->settings();
const auto obj = settings["Audio"].toObject();
return obj["audioExporterPresets"].toObject().keys();
return AudioSettings::audioExporterPresets().toObject().keys();
}

QList<QPair<QString, AudioExporterConfig>> AudioExporter::predefinedPresets() {
Expand Down Expand Up @@ -212,43 +311,43 @@ namespace Audio {
}

AudioExporterConfig AudioExporter::preset(const QString &name) {
auto &settings = *Core::ILoader::instance()->settings();
const auto obj = settings["Audio"].toObject();
return AudioExporterConfig::fromVariantMap(obj["audioExporterPresets"][name].toObject().toVariantMap());
return AudioExporterConfig::fromVariantMap(AudioSettings::audioExporterPresets()[name].toObject().toVariantMap());
}

void AudioExporter::addPreset(const QString &name, const AudioExporterConfig &config) {
auto &settings = *Core::ILoader::instance()->settings();
auto obj = settings["Audio"].toObject();
auto presetsObj = obj["audioExporterPresets"].toObject();
auto presetsObj = AudioSettings::audioExporterPresets().toObject();
presetsObj.insert(name, QJsonObject::fromVariantMap(config.toVariantMap()));
obj["audioExporterPresets"] = presetsObj;
settings["Audio"] = obj;
AudioSettings::setAudioExporterPresets(presetsObj);
}

bool AudioExporter::removePreset(const QString &name) {
auto &settings = *Core::ILoader::instance()->settings();
auto obj = settings["Audio"].toObject();
auto presetsObj = obj["audioExporterPresets"].toObject();
auto presetsObj = AudioSettings::audioExporterPresets().toObject();
if (!presetsObj.contains(name))
return false;
presetsObj.remove(name);
obj["audioExporterPresets"] = presetsObj;
settings["Audio"] = obj;
AudioSettings::setAudioExporterPresets(presetsObj);
return true;
}

static QList<AudioExporterListener *> m_listeners;

void AudioExporter::registerListener(AudioExporterListener *listener) {
m_listeners.append(listener);
}

void AudioExporter::setConfig(const AudioExporterConfig &config) {
Q_D(AudioExporter);
d->config = config;
d->updateFileListAndWarnings();
}
AudioExporterConfig AudioExporter::config() const {
Q_D(const AudioExporter);
return d->config;
}

AudioExporter::Warning AudioExporter::warning() const {
return Audio::AudioExporter::Warning();
Q_D(const AudioExporter);
return d->warning;
}

QStringList AudioExporter::warningText(AudioExporter::Warning warning) {
Expand All @@ -272,10 +371,15 @@ namespace Audio {
}

QStringList AudioExporter::dryRun() const {
return QStringList();
Q_D(const AudioExporter);
return d->fileList;
}

AudioExporter::Result AudioExporter::exec() {
return {};
}

int AudioExporter::exec() {
return 0;
void AudioExporter::cancel(bool isFail) {

}
} // Audio
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace Core {
namespace Audio {

class AudioExporterConfigData;

class AudioExporterPrivate;

class AudioExporterConfig {
Expand All @@ -34,6 +33,9 @@ namespace Audio {
FileType fileType() const;
void setFileType(FileType);

bool formatMono() const;
void setFormatMono(bool);

int formatOption() const;
void setFormatOption(int);

Expand Down Expand Up @@ -79,41 +81,57 @@ namespace Audio {
QSharedDataPointer<AudioExporterConfigData> d;
};

class AudioExporterListener {
public:
virtual bool willStartCallback(Core::IProjectWindow *window) = 0;
virtual void willFinishCallback(Core::IProjectWindow *window) = 0;
};

class AudioExporter : public QObject {
Q_OBJECT
Q_DECLARE_PRIVATE(AudioExporter)
public:
enum WarningFlag {
W_NoFile = 0x0001,
W_DuplicatedFile = 0x0002,
W_WillOverwrite = 0x0004,
W_UnrecognizedTemplate = 0x0008,
W_LossyFormat = 0x00010,
};
Q_DECLARE_FLAGS(Warning, WarningFlag)

explicit AudioExporter(Core::IProjectWindow *window, QObject *parent = nullptr);
~AudioExporter() override;

Core::IProjectWindow *windowHandle() const;

[[nodiscard]] static QStringList presets();
[[nodiscard]] static QList<QPair<QString, AudioExporterConfig>> predefinedPresets();
[[nodiscard]] static AudioExporterConfig preset(const QString &name);
static void addPreset(const QString &name, const AudioExporterConfig &config);
static bool removePreset(const QString &name);

static void registerListener(AudioExporterListener *listener);

void setConfig(const AudioExporterConfig &config);
AudioExporterConfig config() const;

enum WarningFlag {
W_NoFile = 0x0001,
W_DuplicatedFile = 0x0002,
W_WillOverwrite = 0x0004,
W_UnrecognizedTemplate = 0x0008,
W_LossyFormat = 0x00010,
};
Q_DECLARE_FLAGS(Warning, WarningFlag)
Warning warning() const;
[[nodiscard]]static QStringList warningText(Warning warning);

QStringList dryRun() const;

enum Result {
R_OK,
R_Fail,
R_Abort,
};
int exec();
Result exec();

void cancel(bool isFail = false);

signals:
void progressChanged(int sourceIndex, double progressRatio);

private:
QScopedPointer<AudioExporterPrivate> d_ptr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Audio {
QString fileName;
QString fileDirectory;
AudioExporterConfig::FileType fileType;
bool formatMono;
int formatOption;
int formatQuality;
double formatSampleRate;
Expand All @@ -28,6 +29,17 @@ namespace Audio {
AudioExporter *q_ptr;
AudioExporterConfig config;
Core::IProjectWindow *windowHandle;

QString projectName() const;
QString projectDirectory() const;
QString trackName(int trackIndex) const;

bool calculateTemplate(QString &templateString) const;
bool calculateTemplate(QString &templateString, const QString &trackName, int trackIndex) const;

AudioExporter::Warning warning;
QStringList fileList;
void updateFileListAndWarnings();
};
}

Expand Down
13 changes: 11 additions & 2 deletions src/plugins/audioplugin/internal/audioplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
#include <audioplugin/internal/pseudosingerpage.h>
#include <audioplugin/internal/audioexportpage.h>

#ifdef AUDIO_TEST
# include <audioplugin/internal/TestAudioExporterCalculateTemplate.h>
#endif

namespace Audio::Internal {

AudioPlugin::AudioPlugin() {
Expand All @@ -49,6 +53,11 @@ namespace Audio::Internal {
auto splash = Core::InitRoutine::splash();
splash->showMessage(tr("Initializing audio plugin..."));

#ifdef AUDIO_TEST
auto iLoader = Core::ILoader::instance();
iLoader->addObject("debug.UnitTest", new TestAudioExporterCalculateTemplate);
#endif

auto settings = Core::ILoader::instance()->settings();
if (!settings->contains("Audio"))
settings->insert("Audio", QJsonObject());
Expand Down Expand Up @@ -101,8 +110,8 @@ namespace Audio::Internal {
new DeviceTester(iAudio->outputSystemInterface(true), iAudio->outputSystemInterface(true));
new DeviceTester(iAudio->outputSystemInterface(false), iAudio->outputSystemInterface(false));

// AudioExportDialog dlg;
// dlg.exec();
AudioExportDialog dlg;
dlg.exec();

return true;
}
Expand Down
Loading

0 comments on commit d55a964

Please sign in to comment.