From 51bd371067d1c9f444731b885e16b3a19d689baf Mon Sep 17 00:00:00 2001 From: sakertooth Date: Sun, 27 Aug 2023 17:57:33 -0400 Subject: [PATCH] Add SampleLoader --- include/SampleLoader.h | 47 +++++++++++++++ src/gui/SampleLoader.cpp | 120 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 include/SampleLoader.h create mode 100644 src/gui/SampleLoader.cpp diff --git a/include/SampleLoader.h b/include/SampleLoader.h new file mode 100644 index 000000000..4a8ec7af1 --- /dev/null +++ b/include/SampleLoader.h @@ -0,0 +1,47 @@ +/* + * SampleLoader.h - Load audio and waveform files + * + * Copyright (c) saker + * + * This file is part of LMMS - https://lmms.io + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef LMMS_SAMPLE_BUFFER_LOADER_H +#define LMMS_SAMPLE_BUFFER_LOADER_H + +#include +#include + +#include "SampleBuffer.h" +#include "lmms_export.h" + +namespace lmms::gui { +class LMMS_EXPORT SampleLoader +{ +public: + static QString openAudioFile(const QString& previousFile = ""); + static QString openWaveformFile(const QString& previousFile = ""); + static std::unique_ptr createBufferFromFile(const QString& filePath); + static std::unique_ptr createBufferFromBase64(const QString& base64, int sampleRate); +private: + static void displayError(const QString& message); +}; +} // namespace lmms::gui + +#endif // LMMS_SAMPLE_BUFFER_LOADER_H \ No newline at end of file diff --git a/src/gui/SampleLoader.cpp b/src/gui/SampleLoader.cpp new file mode 100644 index 000000000..abcc046e9 --- /dev/null +++ b/src/gui/SampleLoader.cpp @@ -0,0 +1,120 @@ +/* + * SampleLoader.cpp - Static functions that open audio files + * + * Copyright (c) 2005-2014 Tobias Doerffel + * + * This file is part of LMMS - https://lmms.io + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "SampleLoader.h" + +#include +#include + +#include "ConfigManager.h" +#include "FileDialog.h" +#include "PathUtil.h" + +namespace lmms::gui { +QString SampleLoader::openAudioFile(const QString& previousFile) +{ + auto openFileDialog = gui::FileDialog(nullptr, QObject::tr("Open audio file")); + auto dir = QString{}; + + if (!previousFile.isEmpty()) + { + auto file = QString{previousFile}; + if (QFileInfo{file}.isRelative()) + { + file = ConfigManager::inst()->userSamplesDir() + file; + if (!QFileInfo{file}.exists()) { file = ConfigManager::inst()->factorySamplesDir() + previousFile; } + } + + dir = QFileInfo{file}.absolutePath(); + } + else { dir = ConfigManager::inst()->userSamplesDir(); } + + // change dir to position of previously opened file + openFileDialog.setDirectory(dir); + openFileDialog.setFileMode(gui::FileDialog::ExistingFiles); + + // set filters + // TODO: Since libsndfile 1.1.0, MP3 is supported + const auto fileTypes = QStringList{QObject::tr("All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc " + "*.aif *.aiff *.au *.raw)"), + QObject::tr("Wave-Files (*.wav)"), QObject::tr("OGG-Files (*.ogg)"), QObject::tr("DrumSynth-Files (*.ds)"), + QObject::tr("FLAC-Files (*.flac)"), QObject::tr("SPEEX-Files (*.spx)"), QObject::tr("VOC-Files (*.voc)"), + QObject::tr("AIFF-Files (*.aif *.aiff)"), QObject::tr("AU-Files (*.au)"), QObject::tr("RAW-Files (*.raw)")}; + + openFileDialog.setNameFilters(fileTypes); + + if (!previousFile.isEmpty()) + { + // select previously opened file + openFileDialog.selectFile(QFileInfo{previousFile}.fileName()); + } + + if (openFileDialog.exec() == QDialog::Accepted) + { + if (openFileDialog.selectedFiles().isEmpty()) { return ""; } + + return PathUtil::toShortestRelative(openFileDialog.selectedFiles()[0]); + } + + return ""; +} + +QString SampleLoader::openWaveformFile(const QString& previousFile) +{ + return openAudioFile( + previousFile.isEmpty() ? ConfigManager::inst()->factorySamplesDir() + "waveforms/10saw.flac" : previousFile); +} + +std::unique_ptr SampleLoader::createBufferFromFile(const QString& filePath) +{ + try + { + return std::make_unique(filePath); + } + catch (const std::runtime_error& error) + { + displayError(QString::fromStdString(error.what())); + return nullptr; + } +} + +std::unique_ptr SampleLoader::createBufferFromBase64(const QString& base64, int sampleRate) +{ + try + { + return std::make_unique(base64.toUtf8().toBase64(), sampleRate); + } + catch (const std::runtime_error& error) + { + displayError(QString::fromStdString(error.what())); + return nullptr; + } +} + +void SampleLoader::displayError(const QString& message) +{ + QMessageBox::critical(nullptr, QObject::tr("Error loading sample"), message); +} + +} // namespace lmms::gui \ No newline at end of file