Merge pull request #11703 from RomanPudashkin/export_audio
export_audio
This commit is contained in:
commit
b18a68e413
13 changed files with 98 additions and 82 deletions
|
@ -59,3 +59,8 @@ void AudioExportModule::resolveImports()
|
|||
writers->reg({ "flac" }, std::make_shared<FlacWriter>());
|
||||
}
|
||||
}
|
||||
|
||||
void AudioExportModule::onInit(const framework::IApplication::RunMode&)
|
||||
{
|
||||
s_configuration->init();
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ public:
|
|||
std::string moduleName() const override;
|
||||
void registerExports() override;
|
||||
void resolveImports() override;
|
||||
void onInit(const framework::IApplication::RunMode& mode) override;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,13 @@ class IAudioExportConfiguration : MODULE_EXPORT_INTERFACE
|
|||
public:
|
||||
virtual ~IAudioExportConfiguration() = default;
|
||||
|
||||
virtual int exportMp3Bitrate() = 0;
|
||||
virtual int exportMp3Bitrate() const = 0;
|
||||
virtual void setExportMp3Bitrate(std::optional<int> bitrate) = 0;
|
||||
virtual const std::vector<int>& availableMp3BitRates() const = 0;
|
||||
|
||||
virtual int exportSampleRate() const = 0;
|
||||
virtual void setExportSampleRate(int rate) = 0;
|
||||
virtual const std::vector<int>& availableSampleRates() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "audio/iplayback.h"
|
||||
#include "audio/iaudiooutput.h"
|
||||
#include "async/asyncable.h"
|
||||
#include "iaudioexportconfiguration.h"
|
||||
|
||||
#include "project/inotationwriter.h"
|
||||
|
||||
|
@ -33,6 +34,7 @@ namespace mu::iex::audioexport {
|
|||
class AbstractAudioWriter : public project::INotationWriter, public async::Asyncable
|
||||
{
|
||||
INJECT(audioexport, audio::IPlayback, playback)
|
||||
INJECT(audioexport, IAudioExportConfiguration, configuration)
|
||||
|
||||
public:
|
||||
AbstractAudioWriter() = default;
|
||||
|
|
|
@ -22,11 +22,21 @@
|
|||
|
||||
#include "audioexportconfiguration.h"
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
using namespace mu::iex::audioexport;
|
||||
using namespace mu::framework;
|
||||
|
||||
static const Settings::Key EXPORT_SAMPLE_RATE_KEY("iex_audioexport", "export/audio/sampleRate");
|
||||
|
||||
static constexpr int DEFAULT_BITRATE = 128;
|
||||
|
||||
int AudioExportConfiguration::exportMp3Bitrate()
|
||||
void AudioExportConfiguration::init()
|
||||
{
|
||||
settings()->setDefaultValue(EXPORT_SAMPLE_RATE_KEY, Val(44100));
|
||||
}
|
||||
|
||||
int AudioExportConfiguration::exportMp3Bitrate() const
|
||||
{
|
||||
return m_exportMp3Bitrate ? m_exportMp3Bitrate.value() : DEFAULT_BITRATE;
|
||||
}
|
||||
|
@ -35,3 +45,25 @@ void AudioExportConfiguration::setExportMp3Bitrate(std::optional<int> bitrate)
|
|||
{
|
||||
m_exportMp3Bitrate = bitrate;
|
||||
}
|
||||
|
||||
const std::vector<int>& AudioExportConfiguration::availableMp3BitRates() const
|
||||
{
|
||||
static const std::vector<int> rates { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, };
|
||||
return rates;
|
||||
}
|
||||
|
||||
int AudioExportConfiguration::exportSampleRate() const
|
||||
{
|
||||
return settings()->value(EXPORT_SAMPLE_RATE_KEY).toInt();
|
||||
}
|
||||
|
||||
void AudioExportConfiguration::setExportSampleRate(int rate)
|
||||
{
|
||||
settings()->setSharedValue(EXPORT_SAMPLE_RATE_KEY, Val(rate));
|
||||
}
|
||||
|
||||
const std::vector<int>& AudioExportConfiguration::availableSampleRates() const
|
||||
{
|
||||
static const std::vector<int> rates { 32000, 44100, 48000 };
|
||||
return rates;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,15 @@ namespace mu::iex::audioexport {
|
|||
class AudioExportConfiguration : public IAudioExportConfiguration
|
||||
{
|
||||
public:
|
||||
int exportMp3Bitrate() override;
|
||||
void init();
|
||||
|
||||
int exportMp3Bitrate() const override;
|
||||
void setExportMp3Bitrate(std::optional<int> bitrate) override;
|
||||
const std::vector<int>& availableMp3BitRates() const override;
|
||||
|
||||
int exportSampleRate() const override;
|
||||
void setExportSampleRate(int rate) override;
|
||||
const std::vector<int>& availableSampleRates() const override;
|
||||
|
||||
private:
|
||||
std::optional<int> m_exportMp3Bitrate = std::nullopt;
|
||||
|
|
|
@ -27,13 +27,14 @@
|
|||
using namespace mu::iex::audioexport;
|
||||
using namespace mu::io;
|
||||
|
||||
mu::Ret FlacWriter::write(notation::INotationPtr notation, Device& destinationDevice, const Options& options)
|
||||
mu::Ret FlacWriter::write(notation::INotationPtr, Device& destinationDevice, const Options&)
|
||||
{
|
||||
UNUSED(notation)
|
||||
UNUSED(options)
|
||||
|
||||
//TODO Take actual data
|
||||
static const audio::SoundTrackFormat format { audio::SoundTrackType::FLAC, 48000, 2, 128 };
|
||||
static const audio::SoundTrackFormat format {
|
||||
audio::SoundTrackType::FLAC,
|
||||
static_cast<audio::sample_rate_t>(configuration()->exportSampleRate()),
|
||||
2 /* audioChannelsNumber */,
|
||||
128 /* bitRate */
|
||||
};
|
||||
|
||||
doWriteAndWait(destinationDevice, format);
|
||||
|
||||
|
|
|
@ -27,13 +27,14 @@
|
|||
using namespace mu::iex::audioexport;
|
||||
using namespace mu::framework;
|
||||
|
||||
mu::Ret Mp3Writer::write(notation::INotationPtr notation, io::Device& destinationDevice, const Options& options)
|
||||
mu::Ret Mp3Writer::write(notation::INotationPtr, io::Device& destinationDevice, const Options&)
|
||||
{
|
||||
UNUSED(notation)
|
||||
UNUSED(options)
|
||||
|
||||
//TODO Take actual data
|
||||
static const audio::SoundTrackFormat format { audio::SoundTrackType::MP3, 48000, 2, 128 };
|
||||
static const audio::SoundTrackFormat format {
|
||||
audio::SoundTrackType::MP3,
|
||||
static_cast<audio::sample_rate_t>(configuration()->exportSampleRate()),
|
||||
2 /* audioChannelsNumber */,
|
||||
configuration()->exportMp3Bitrate()
|
||||
};
|
||||
|
||||
doWriteAndWait(destinationDevice, format);
|
||||
|
||||
|
|
|
@ -27,13 +27,14 @@
|
|||
using namespace mu::iex::audioexport;
|
||||
using namespace mu::io;
|
||||
|
||||
mu::Ret OggWriter::write(notation::INotationPtr notation, Device& destinationDevice, const Options& options)
|
||||
mu::Ret OggWriter::write(notation::INotationPtr, Device& destinationDevice, const Options&)
|
||||
{
|
||||
UNUSED(notation)
|
||||
UNUSED(options)
|
||||
|
||||
//TODO Take actual data
|
||||
static const audio::SoundTrackFormat format { audio::SoundTrackType::OGG, 48000, 2, 128 };
|
||||
static const audio::SoundTrackFormat format {
|
||||
audio::SoundTrackType::OGG,
|
||||
static_cast<audio::sample_rate_t>(configuration()->exportSampleRate()),
|
||||
2 /* audioChannelsNumber */,
|
||||
128 /* bitRate */
|
||||
};
|
||||
|
||||
doWriteAndWait(destinationDevice, format);
|
||||
|
||||
|
|
|
@ -27,13 +27,14 @@
|
|||
using namespace mu::iex::audioexport;
|
||||
using namespace mu::framework;
|
||||
|
||||
mu::Ret WaveWriter::write(notation::INotationPtr notation, io::Device& destinationDevice, const Options& options)
|
||||
mu::Ret WaveWriter::write(notation::INotationPtr, io::Device& destinationDevice, const Options&)
|
||||
{
|
||||
UNUSED(notation)
|
||||
UNUSED(options)
|
||||
|
||||
//TODO Take actual data
|
||||
static const audio::SoundTrackFormat format { audio::SoundTrackType::WAV, 48000, 2 };
|
||||
static const audio::SoundTrackFormat format {
|
||||
audio::SoundTrackType::WAV,
|
||||
static_cast<audio::sample_rate_t>(configuration()->exportSampleRate()),
|
||||
2 /* audioChannelsNumber */,
|
||||
0 /* bitRate */
|
||||
};
|
||||
|
||||
doWriteAndWait(destinationDevice, format);
|
||||
|
||||
|
|
|
@ -31,20 +31,6 @@ ExportSettingsPage {
|
|||
|
||||
property bool showBitRateControl: false
|
||||
|
||||
CheckBox {
|
||||
width: parent.width
|
||||
text: qsTrc("project", "Normalize")
|
||||
|
||||
navigation.name: "NormalizeAudioCheckbox"
|
||||
navigation.panel: root.navigationPanel
|
||||
navigation.row: root.navigationOrder + 1
|
||||
|
||||
checked: root.model.normalizeAudio
|
||||
onClicked: {
|
||||
root.model.normalizeAudio = !checked
|
||||
}
|
||||
}
|
||||
|
||||
ExportOptionItem {
|
||||
id: sampleRateLabel
|
||||
text: qsTrc("project", "Sample rate:")
|
||||
|
@ -54,7 +40,7 @@ ExportSettingsPage {
|
|||
|
||||
navigation.name: "SampleRatesDropdown"
|
||||
navigation.panel: root.navigationPanel
|
||||
navigation.row: root.navigationOrder + 2
|
||||
navigation.row: root.navigationOrder + 1
|
||||
navigation.accessible.name: sampleRateLabel.text + " " + currentText
|
||||
|
||||
model: root.model.availableSampleRates().map(function(sampleRate) {
|
||||
|
@ -79,7 +65,7 @@ ExportSettingsPage {
|
|||
|
||||
navigation.name: "BitratesDropdown"
|
||||
navigation.panel: root.navigationPanel
|
||||
navigation.row: root.navigationOrder + 3
|
||||
navigation.row: root.navigationOrder + 2
|
||||
navigation.accessible.name: bitrateLabel.text + " " + currentText
|
||||
|
||||
model: root.model.availableBitRates().map(function(bitRate) {
|
||||
|
|
|
@ -69,8 +69,6 @@ ExportDialogModel::ExportDialogModel(QObject* parent)
|
|||
qtrc("project", "SVG Images"),
|
||||
qtrc("project", "SVG Images"),
|
||||
"SvgSettingsPage.qml"),
|
||||
/*
|
||||
* TODO: https://github.com/musescore/MuseScore/issues/10495
|
||||
ExportType::makeWithSuffixes({ "mp3" },
|
||||
qtrc("project", "MP3 Audio"),
|
||||
qtrc("project", "MP3 Audio Files"),
|
||||
|
@ -87,7 +85,6 @@ ExportDialogModel::ExportDialogModel(QObject* parent)
|
|||
qtrc("project", "FLAC Audio"),
|
||||
qtrc("project", "FLAC Audio Files"),
|
||||
"AudioSettingsPage.qml"),
|
||||
*/
|
||||
ExportType::makeWithSuffixes({ "mid", "midi", "kar" },
|
||||
qtrc("project", "MIDI File"),
|
||||
qtrc("project", "MIDI Files"),
|
||||
|
@ -363,48 +360,31 @@ void ExportDialogModel::setPngTransparentBackground(const bool& transparent)
|
|||
emit pngTransparentBackgroundChanged(transparent);
|
||||
}
|
||||
|
||||
bool ExportDialogModel::normalizeAudio() const
|
||||
{
|
||||
NOT_IMPLEMENTED;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExportDialogModel::setNormalizeAudio(bool normalizeAudio)
|
||||
{
|
||||
if (normalizeAudio == this->normalizeAudio()) {
|
||||
return;
|
||||
}
|
||||
|
||||
NOT_IMPLEMENTED;
|
||||
emit normalizeAudioChanged(normalizeAudio);
|
||||
}
|
||||
|
||||
QList<int> ExportDialogModel::availableSampleRates() const
|
||||
{
|
||||
NOT_IMPLEMENTED; // TODO: move to audio configuration
|
||||
return { 32000, 44100, 48000 };
|
||||
const std::vector<int>& rates = audioExportConfiguration()->availableSampleRates();
|
||||
return QList<int>(rates.cbegin(), rates.cend());
|
||||
}
|
||||
|
||||
int ExportDialogModel::sampleRate() const
|
||||
{
|
||||
NOT_IMPLEMENTED;
|
||||
return 44100;
|
||||
return audioExportConfiguration()->exportSampleRate();
|
||||
}
|
||||
|
||||
void ExportDialogModel::setSampleRate(int sampleRate)
|
||||
void ExportDialogModel::setSampleRate(int rate)
|
||||
{
|
||||
if (sampleRate == this->sampleRate()) {
|
||||
if (rate == sampleRate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
NOT_IMPLEMENTED;
|
||||
emit sampleRateChanged(sampleRate);
|
||||
audioExportConfiguration()->setExportSampleRate(rate);
|
||||
emit sampleRateChanged(rate);
|
||||
}
|
||||
|
||||
QList<int> ExportDialogModel::availableBitRates() const
|
||||
{
|
||||
NOT_IMPLEMENTED; // TODO: move to audio configuration
|
||||
return { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, };
|
||||
const std::vector<int>& rates = audioExportConfiguration()->availableMp3BitRates();
|
||||
return QList<int>(rates.cbegin(), rates.cend());
|
||||
}
|
||||
|
||||
int ExportDialogModel::bitRate() const
|
||||
|
@ -412,14 +392,14 @@ int ExportDialogModel::bitRate() const
|
|||
return audioExportConfiguration()->exportMp3Bitrate();
|
||||
}
|
||||
|
||||
void ExportDialogModel::setBitRate(int bitRate)
|
||||
void ExportDialogModel::setBitRate(int rate)
|
||||
{
|
||||
if (bitRate == this->bitRate()) {
|
||||
if (rate == bitRate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
audioExportConfiguration()->setExportMp3Bitrate(bitRate);
|
||||
emit bitRateChanged(bitRate);
|
||||
audioExportConfiguration()->setExportMp3Bitrate(rate);
|
||||
emit bitRateChanged(rate);
|
||||
}
|
||||
|
||||
bool ExportDialogModel::midiExpandRepeats() const
|
||||
|
@ -528,6 +508,5 @@ void ExportDialogModel::setShouldDestinationFolderBeOpenedOnExport(bool enabled)
|
|||
}
|
||||
|
||||
configuration()->setShouldDestinationFolderBeOpenedOnExport(enabled);
|
||||
|
||||
emit shouldDestinationFolderBeOpenedOnExportChanged(enabled);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,6 @@ class ExportDialogModel : public QAbstractListModel
|
|||
Q_PROPERTY(
|
||||
bool pngTransparentBackground READ pngTransparentBackground WRITE setPngTransparentBackground NOTIFY pngTransparentBackgroundChanged)
|
||||
|
||||
Q_PROPERTY(bool normalizeAudio READ normalizeAudio WRITE setNormalizeAudio NOTIFY normalizeAudioChanged)
|
||||
Q_PROPERTY(int sampleRate READ sampleRate WRITE setSampleRate NOTIFY sampleRateChanged)
|
||||
Q_PROPERTY(int bitRate READ bitRate WRITE setBitRate NOTIFY bitRateChanged)
|
||||
|
||||
|
@ -113,9 +112,6 @@ public:
|
|||
bool pngTransparentBackground() const;
|
||||
void setPngTransparentBackground(const bool& transparent);
|
||||
|
||||
bool normalizeAudio() const;
|
||||
void setNormalizeAudio(bool normalizeAudio);
|
||||
|
||||
Q_INVOKABLE QList<int> availableSampleRates() const;
|
||||
int sampleRate() const;
|
||||
void setSampleRate(int sampleRate);
|
||||
|
@ -155,7 +151,6 @@ signals:
|
|||
void pngResolutionChanged(int resolution);
|
||||
void pngTransparentBackgroundChanged(bool transparent);
|
||||
|
||||
void normalizeAudioChanged(bool normalizeAudio);
|
||||
void availableSampleRatesChanged();
|
||||
void sampleRateChanged(int sampleRate);
|
||||
void availableBitRatesChanged();
|
||||
|
|
Loading…
Reference in a new issue