Implemented loopstation widget sample downloading
This commit is contained in:
@ -196,6 +196,16 @@ void DrumMachineSettings::setLoopstationNextPreset(const MidiLearnSetting &value
|
|||||||
setLearnSetting("loopstation/nextPreset", value);
|
setLearnSetting("loopstation/nextPreset", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MidiLearnSetting DrumMachineSettings::loopstationSample(quint8 pad) const
|
||||||
|
{
|
||||||
|
return learnSetting(QString{"loopstation/pad%0"}.arg(pad));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrumMachineSettings::setLoopstationSample(quint8 pad, const MidiLearnSetting &value)
|
||||||
|
{
|
||||||
|
setLearnSetting(QString{"loopstation/pad%0"}.arg(pad), value);
|
||||||
|
}
|
||||||
|
|
||||||
MidiLearnSetting DrumMachineSettings::learnSetting(const QString &key) const
|
MidiLearnSetting DrumMachineSettings::learnSetting(const QString &key) const
|
||||||
{
|
{
|
||||||
return MidiLearnSetting{
|
return MidiLearnSetting{
|
||||||
|
@ -69,6 +69,9 @@ public:
|
|||||||
MidiLearnSetting loopstationNextPreset() const;
|
MidiLearnSetting loopstationNextPreset() const;
|
||||||
void setLoopstationNextPreset(const MidiLearnSetting &value);
|
void setLoopstationNextPreset(const MidiLearnSetting &value);
|
||||||
|
|
||||||
|
MidiLearnSetting loopstationSample(quint8 pad) const;
|
||||||
|
void setLoopstationSample(quint8 pad, const MidiLearnSetting &value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MidiLearnSetting learnSetting(const QString &key) const;
|
MidiLearnSetting learnSetting(const QString &key) const;
|
||||||
void setLearnSetting(const QString &key, const MidiLearnSetting &value);
|
void setLearnSetting(const QString &key, const MidiLearnSetting &value);
|
||||||
|
@ -52,9 +52,7 @@ void DrumPadSamplesWidget::midiReceived(const midi::MidiMessage &message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (DrumPadSampleWidget &widget : getWidgets())
|
for (DrumPadSampleWidget &widget : getWidgets())
|
||||||
{
|
|
||||||
widget.midiReceived(message);
|
widget.midiReceived(message);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrumPadSamplesWidget::writeSamples(frame_t *begin, frame_t *end)
|
void DrumPadSamplesWidget::writeSamples(frame_t *begin, frame_t *end)
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "ui_drumpadsamplewidget.h"
|
#include "ui_drumpadsamplewidget.h"
|
||||||
|
|
||||||
#include <QAbstractEventDispatcher>
|
#include <QAbstractEventDispatcher>
|
||||||
#include <QSoundEffect>
|
|
||||||
#include <QNetworkRequest>
|
#include <QNetworkRequest>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
@ -17,7 +16,7 @@ namespace {
|
|||||||
QString toString(QString value) { return value; }
|
QString toString(QString value) { return value; }
|
||||||
QString toString(int value) { return QString::number(value); }
|
QString toString(int value) { return QString::number(value); }
|
||||||
QString toString(bool value) { return value?"true":"false"; }
|
QString toString(bool value) { return value?"true":"false"; }
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
DrumPadSampleWidget::DrumPadSampleWidget(QWidget *parent) :
|
DrumPadSampleWidget::DrumPadSampleWidget(QWidget *parent) :
|
||||||
QFrame{parent},
|
QFrame{parent},
|
||||||
@ -212,7 +211,6 @@ void DrumPadSampleWidget::updateStatus()
|
|||||||
{
|
{
|
||||||
QPalette pal;
|
QPalette pal;
|
||||||
|
|
||||||
|
|
||||||
if (m_file && m_file->color && m_player.buffer().isValid())
|
if (m_file && m_file->color && m_player.buffer().isValid())
|
||||||
{
|
{
|
||||||
const auto bright = m_player.playing() ? 255 : 155;
|
const auto bright = m_player.playing() ? 255 : 155;
|
||||||
@ -264,9 +262,7 @@ void DrumPadSampleWidget::updateStatus()
|
|||||||
void DrumPadSampleWidget::requestFinished()
|
void DrumPadSampleWidget::requestFinished()
|
||||||
{
|
{
|
||||||
if (m_reply->error() == QNetworkReply::NoError)
|
if (m_reply->error() == QNetworkReply::NoError)
|
||||||
{
|
|
||||||
emit startDecoding(m_reply);
|
emit startDecoding(m_reply);
|
||||||
}
|
|
||||||
updateStatus();
|
updateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,54 +1,82 @@
|
|||||||
#include "loopstationsampleswidget.h"
|
#include "loopstationsampleswidget.h"
|
||||||
#include "ui_loopstationsampleswidget.h"
|
#include "ui_loopstationsampleswidget.h"
|
||||||
|
|
||||||
|
#include "loopstationpresets.h"
|
||||||
|
|
||||||
LoopStationSamplesWidget::LoopStationSamplesWidget(QWidget *parent) :
|
LoopStationSamplesWidget::LoopStationSamplesWidget(QWidget *parent) :
|
||||||
QWidget{parent},
|
QWidget{parent},
|
||||||
m_ui{std::make_unique<Ui::LoopStationSamplesWidget>()}
|
m_ui{std::make_unique<Ui::LoopStationSamplesWidget>()}
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
|
quint8 padNr{};
|
||||||
|
for (LoopStationSampleWidget &widget : getWidgets())
|
||||||
|
{
|
||||||
|
widget.setPadNr(padNr++);
|
||||||
|
connect(&widget, &LoopStationSampleWidget::sendMidi, this, &LoopStationSamplesWidget::sendMidi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LoopStationSamplesWidget::~LoopStationSamplesWidget() = default;
|
LoopStationSamplesWidget::~LoopStationSamplesWidget() = default;
|
||||||
|
|
||||||
void LoopStationSamplesWidget::loadSettings(DrumMachineSettings &settings)
|
void LoopStationSamplesWidget::loadSettings(DrumMachineSettings &settings)
|
||||||
{
|
{
|
||||||
Q_UNUSED(settings)
|
for (LoopStationSampleWidget &widget : getWidgets())
|
||||||
|
widget.loadSettings(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopStationSamplesWidget::setPreset(const loopstation_presets::Preset &preset)
|
void LoopStationSamplesWidget::setPreset(const loopstation_presets::Preset &preset)
|
||||||
{
|
{
|
||||||
Q_UNUSED(preset)
|
assert(preset.id);
|
||||||
|
assert(preset.pads);
|
||||||
|
|
||||||
|
const auto &presetId = *preset.id;
|
||||||
|
const auto &widgets = getWidgets();
|
||||||
|
const auto &pads = *preset.pads;
|
||||||
|
|
||||||
|
auto iter = std::begin(widgets);
|
||||||
|
auto iter2 = std::begin(pads);
|
||||||
|
int i{};
|
||||||
|
for (; iter != std::end(widgets) && iter2 != std::end(pads); iter++, iter2++)
|
||||||
|
{
|
||||||
|
((*iter)).get().setSample(presetId, QString{"%0_%1.wav"}.arg(presetId).arg(++i, 2, 10, QLatin1Char('0')), *iter2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopStationSamplesWidget::midiReceived(const midi::MidiMessage &message)
|
void LoopStationSamplesWidget::midiReceived(const midi::MidiMessage &message)
|
||||||
{
|
{
|
||||||
Q_UNUSED(message)
|
for (LoopStationSampleWidget &widget : getWidgets())
|
||||||
|
widget.midiReceived(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopStationSamplesWidget::writeSamples(frame_t *begin, frame_t *end)
|
void LoopStationSamplesWidget::writeSamples(frame_t *begin, frame_t *end)
|
||||||
{
|
{
|
||||||
Q_UNUSED(begin)
|
for (LoopStationSampleWidget &widget : getWidgets())
|
||||||
Q_UNUSED(end)
|
widget.writeSamples(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopStationSamplesWidget::injectNetworkAccessManager(QNetworkAccessManager &networkAccessManager)
|
void LoopStationSamplesWidget::injectNetworkAccessManager(QNetworkAccessManager &networkAccessManager)
|
||||||
{
|
{
|
||||||
Q_UNUSED(networkAccessManager)
|
for (LoopStationSampleWidget &widget : getWidgets())
|
||||||
|
widget.injectNetworkAccessManager(networkAccessManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopStationSamplesWidget::injectDecodingThread(QThread &thread)
|
void LoopStationSamplesWidget::injectDecodingThread(QThread &thread)
|
||||||
{
|
{
|
||||||
Q_UNUSED(thread)
|
for (LoopStationSampleWidget &widget : getWidgets())
|
||||||
|
widget.injectDecodingThread(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopStationSamplesWidget::unsendColors()
|
void LoopStationSamplesWidget::unsendColors()
|
||||||
{
|
{
|
||||||
|
for (LoopStationSampleWidget &widget : getWidgets())
|
||||||
|
widget.unsendColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopStationSamplesWidget::sendColors()
|
void LoopStationSamplesWidget::sendColors()
|
||||||
{
|
{
|
||||||
|
for (LoopStationSampleWidget &widget : getWidgets())
|
||||||
|
widget.sendColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<std::reference_wrapper<LoopStationSampleWidget>, 48> LoopStationSamplesWidget::getWidgets()
|
std::array<std::reference_wrapper<LoopStationSampleWidget>, 48> LoopStationSamplesWidget::getWidgets()
|
||||||
|
@ -1,11 +1,166 @@
|
|||||||
#include "loopstationsamplewidget.h"
|
#include "loopstationsamplewidget.h"
|
||||||
#include "ui_loopstationsamplewidget.h"
|
#include "ui_loopstationsamplewidget.h"
|
||||||
|
|
||||||
|
#include <QAbstractEventDispatcher>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QMetaEnum>
|
||||||
|
|
||||||
|
#include "audioformat.h"
|
||||||
|
#include "audiodecoder.h"
|
||||||
|
#include "drummachinesettings.h"
|
||||||
|
#include "midicontainers.h"
|
||||||
|
|
||||||
LoopStationSampleWidget::LoopStationSampleWidget(QWidget *parent) :
|
LoopStationSampleWidget::LoopStationSampleWidget(QWidget *parent) :
|
||||||
QFrame{parent},
|
QFrame{parent},
|
||||||
m_ui{std::make_unique<Ui::LoopStationSampleWidget>()}
|
m_ui{std::make_unique<Ui::LoopStationSampleWidget>()}
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(&m_player, &AudioPlayer::playingChanged, this, &LoopStationSampleWidget::updateStatus);
|
||||||
|
|
||||||
|
connect(m_ui->pushButtonPlay, &QAbstractButton::pressed, this, &LoopStationSampleWidget::pressed);
|
||||||
|
|
||||||
|
updateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
LoopStationSampleWidget::~LoopStationSampleWidget() = default;
|
LoopStationSampleWidget::~LoopStationSampleWidget() = default;
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::loadSettings(DrumMachineSettings &settings)
|
||||||
|
{
|
||||||
|
m_settings = &settings;
|
||||||
|
|
||||||
|
m_ui->pushButtonPlay->setLearnSetting(m_settings->loopstationSample(m_padNr));
|
||||||
|
|
||||||
|
connect(m_ui->pushButtonPlay, &MidiButton::learnSettingChanged, this, [this](const MidiLearnSetting &learnSetting){
|
||||||
|
Q_ASSERT(m_settings);
|
||||||
|
if (m_settings)
|
||||||
|
m_settings->setLoopstationSample(m_padNr, learnSetting);
|
||||||
|
else
|
||||||
|
qWarning() << "no settings available";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::setSample(const QString &presetId, const QString &filename, const QString &type)
|
||||||
|
{
|
||||||
|
m_presetId = presetId;
|
||||||
|
m_filename = filename;
|
||||||
|
|
||||||
|
m_player.setBuffer({});
|
||||||
|
|
||||||
|
startRequest();
|
||||||
|
|
||||||
|
m_ui->labelFilename->setText(filename);
|
||||||
|
m_ui->labelType->setText(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::pressed()
|
||||||
|
{
|
||||||
|
m_player.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::injectNetworkAccessManager(QNetworkAccessManager &networkAccessManager)
|
||||||
|
{
|
||||||
|
m_networkAccessManager = &networkAccessManager;
|
||||||
|
if (!m_presetId.isEmpty() && !m_filename.isEmpty())
|
||||||
|
startRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::injectDecodingThread(QThread &thread)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(QAbstractEventDispatcher::instance(&thread), [this](){
|
||||||
|
m_decoder = std::make_unique<AudioDecoder>();
|
||||||
|
connect(this, &LoopStationSampleWidget::startDecoding, m_decoder.get(), &AudioDecoder::startDecodingDevice);
|
||||||
|
connect(m_decoder.get(), &AudioDecoder::decodingFinished, this, &LoopStationSampleWidget::decodingFinished);
|
||||||
|
if (m_reply && m_reply->isFinished() && m_reply->error() == QNetworkReply::NoError)
|
||||||
|
m_decoder->startDecodingDevice(m_reply);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::writeSamples(frame_t *begin, frame_t *end)
|
||||||
|
{
|
||||||
|
m_player.writeSamples(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::midiReceived(const midi::MidiMessage &message)
|
||||||
|
{
|
||||||
|
m_ui->pushButtonPlay->midiReceived(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::unsendColor()
|
||||||
|
{
|
||||||
|
m_sendColors = false;
|
||||||
|
|
||||||
|
emit sendMidi(midi::MidiMessage {
|
||||||
|
.channel = m_ui->pushButtonPlay->learnSetting().channel,
|
||||||
|
.cmd = m_ui->pushButtonPlay->learnSetting().cmd,
|
||||||
|
.flag = true,
|
||||||
|
.note = m_ui->pushButtonPlay->learnSetting().note,
|
||||||
|
.velocity = 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::sendColor()
|
||||||
|
{
|
||||||
|
m_sendColors = true;
|
||||||
|
|
||||||
|
emit sendMidi(midi::MidiMessage {
|
||||||
|
.channel = m_ui->pushButtonPlay->learnSetting().channel,
|
||||||
|
.cmd = m_ui->pushButtonPlay->learnSetting().cmd,
|
||||||
|
.flag = true,
|
||||||
|
.note = m_ui->pushButtonPlay->learnSetting().note,
|
||||||
|
.velocity = uint8_t(m_padNr+1)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::updateStatus()
|
||||||
|
{
|
||||||
|
if (m_sendColors)
|
||||||
|
sendColor();
|
||||||
|
|
||||||
|
if (m_reply)
|
||||||
|
{
|
||||||
|
if (!m_reply->isFinished())
|
||||||
|
m_ui->labelStatus->setText(tr("Downloading..."));
|
||||||
|
else if (m_reply->error() != QNetworkReply::NoError)
|
||||||
|
m_ui->labelStatus->setText(QMetaEnum::fromType<QNetworkReply::NetworkError>().valueToKey(m_reply->error()));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!m_decoder)
|
||||||
|
m_ui->labelStatus->setText(tr("Waiting for decoder thread..."));
|
||||||
|
else
|
||||||
|
m_ui->labelStatus->setText(tr("Decoding"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_ui->labelStatus->setText(m_player.playing() ? tr("Playing") : tr("Ready"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::requestFinished()
|
||||||
|
{
|
||||||
|
if (m_reply->error() == QNetworkReply::NoError)
|
||||||
|
emit startDecoding(m_reply);
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::decodingFinished(const QAudioBuffer &buffer)
|
||||||
|
{
|
||||||
|
m_reply = nullptr;
|
||||||
|
m_player.setBuffer(buffer);
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopStationSampleWidget::startRequest()
|
||||||
|
{
|
||||||
|
if (m_networkAccessManager && !m_presetId.isEmpty() && !m_filename.isEmpty())
|
||||||
|
{
|
||||||
|
QNetworkRequest request{QUrl{QString{"https://brunner.ninja/komposthaufen/groovepad/presets/extracted/%0/%1"}.arg(m_presetId, m_filename)}};
|
||||||
|
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
|
||||||
|
request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, true);
|
||||||
|
m_reply = std::shared_ptr<QNetworkReply>{m_networkAccessManager->get(request)};
|
||||||
|
connect(m_reply.get(), &QNetworkReply::finished, this, &LoopStationSampleWidget::requestFinished);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
@ -4,7 +4,16 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "audioplayer.h"
|
||||||
|
|
||||||
namespace Ui { class LoopStationSampleWidget; }
|
namespace Ui { class LoopStationSampleWidget; }
|
||||||
|
class QNetworkAccessManager;
|
||||||
|
class QNetworkReply;
|
||||||
|
class QAudioBuffer;
|
||||||
|
class AudioDecoder;
|
||||||
|
class DrumMachineSettings;
|
||||||
|
namespace midi { struct MidiMessage; }
|
||||||
|
struct frame_t;
|
||||||
|
|
||||||
class LoopStationSampleWidget : public QFrame
|
class LoopStationSampleWidget : public QFrame
|
||||||
{
|
{
|
||||||
@ -12,8 +21,55 @@ class LoopStationSampleWidget : public QFrame
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LoopStationSampleWidget(QWidget *parent = nullptr);
|
explicit LoopStationSampleWidget(QWidget *parent = nullptr);
|
||||||
~LoopStationSampleWidget();
|
~LoopStationSampleWidget() override;
|
||||||
|
|
||||||
|
quint8 padNr() const { return m_padNr; }
|
||||||
|
void setPadNr(quint8 padNr) { m_padNr = padNr; }
|
||||||
|
|
||||||
|
void loadSettings(DrumMachineSettings &settings);
|
||||||
|
|
||||||
|
void setSample(const QString &presetId, const QString &filename, const QString &type);
|
||||||
|
|
||||||
|
void pressed();
|
||||||
|
|
||||||
|
void injectNetworkAccessManager(QNetworkAccessManager &networkAccessManager);
|
||||||
|
void injectDecodingThread(QThread &thread);
|
||||||
|
|
||||||
|
void writeSamples(frame_t *begin, frame_t *end);
|
||||||
|
|
||||||
|
void midiReceived(const midi::MidiMessage &message);
|
||||||
|
|
||||||
|
void unsendColor();
|
||||||
|
void sendColor();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void startDecoding(std::shared_ptr<QIODevice> device);
|
||||||
|
void sendMidi(const midi::MidiMessage &midiMsg);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateStatus();
|
||||||
|
void requestFinished();
|
||||||
|
void decodingFinished(const QAudioBuffer &buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void startRequest();
|
||||||
|
|
||||||
const std::unique_ptr<Ui::LoopStationSampleWidget> m_ui;
|
const std::unique_ptr<Ui::LoopStationSampleWidget> m_ui;
|
||||||
|
|
||||||
|
DrumMachineSettings *m_settings{};
|
||||||
|
|
||||||
|
std::shared_ptr<QNetworkReply> m_reply;
|
||||||
|
|
||||||
|
std::unique_ptr<AudioDecoder> m_decoder;
|
||||||
|
|
||||||
|
AudioPlayer m_player;
|
||||||
|
|
||||||
|
QString m_presetId;
|
||||||
|
QString m_filename;
|
||||||
|
|
||||||
|
QNetworkAccessManager *m_networkAccessManager{};
|
||||||
|
|
||||||
|
quint8 m_padNr{};
|
||||||
|
|
||||||
|
bool m_sendColors{};
|
||||||
};
|
};
|
||||||
|
@ -51,6 +51,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelType">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
@ -22,6 +22,8 @@ LoopStationWidget::LoopStationWidget(QWidget *parent) :
|
|||||||
connect(m_ui->pushButtonDown, &QAbstractButton::pressed, this, &LoopStationWidget::selectNextPreset);
|
connect(m_ui->pushButtonDown, &QAbstractButton::pressed, this, &LoopStationWidget::selectNextPreset);
|
||||||
connect(m_ui->pushButtonRefresh, &QAbstractButton::pressed, this, &LoopStationWidget::loadPresets);
|
connect(m_ui->pushButtonRefresh, &QAbstractButton::pressed, this, &LoopStationWidget::loadPresets);
|
||||||
|
|
||||||
|
connect(m_ui->samplesWidget, &LoopStationSamplesWidget::sendMidi, this, &LoopStationWidget::sendMidi);
|
||||||
|
|
||||||
m_presetsProxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
|
m_presetsProxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||||
m_presetsProxyModel.setSortRole(Qt::EditRole);
|
m_presetsProxyModel.setSortRole(Qt::EditRole);
|
||||||
m_presetsProxyModel.setSourceModel(&m_presetsModel);
|
m_presetsProxyModel.setSourceModel(&m_presetsModel);
|
||||||
|
Reference in New Issue
Block a user