Fixed midi handling for control change and implemented tab selection with midi

This commit is contained in:
2022-12-28 04:56:09 +01:00
parent 9d6c73782c
commit 629d2e6cd3
20 changed files with 481 additions and 455 deletions

View File

@ -1,6 +1,6 @@
QT = core multimedia gui widgets network
CONFIG += c++20
CONFIG += c++22
QMAKE_CXXFLAGS += -Werror=all
release: QMAKE_CXXFLAGS_RELEASE -= -O1
@ -30,6 +30,7 @@ SOURCES += \
main.cpp \
midicontainers.cpp \
midiinwrapper.cpp \
midilearnsetting.cpp \
midioutwrapper.cpp \
synthisizer.cpp \
treetotableproxymodel.cpp \
@ -60,6 +61,7 @@ HEADERS += \
drumpadpresets.h \
drumpadpresetsmodel.h \
drumpadpresettagsmodel.h \
futurecpp.h \
graphrenderer.h \
jsonconverters.h \
loopstationjsonconverters.h \
@ -68,6 +70,7 @@ HEADERS += \
loopstationpresettagsmodel.h \
midicontainers.h \
midiinwrapper.h \
midilearnsetting.h \
midioutwrapper.h \
synthisizer.h \
treetotableproxymodel.h \

View File

@ -3,6 +3,9 @@
#include <QStandardPaths>
#include <QDebug>
#include "midilearnsetting.h"
#include "futurecpp.h"
QString DrumMachineSettings::defaultCacheDir() const
{
return QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
@ -73,6 +76,16 @@ void DrumMachineSettings::setLastMidiOutDevice(const QString &lastMidiOutDevice)
setValue("lastMidiOutDevice", lastMidiOutDevice);
}
MidiLearnSetting DrumMachineSettings::tabWidget(quint8 index) const
{
return learnSetting(QString{"tabWidget%0"}.arg(index));
}
void DrumMachineSettings::setTabWidget(quint8 index, const MidiLearnSetting &value)
{
setLearnSetting(QString{"tabWidget%0"}.arg(index), value);
}
QString DrumMachineSettings::drumpadLastPresetId() const
{
return value("drumpad/lastPresetId").toString();
@ -83,144 +96,74 @@ void DrumMachineSettings::setDrumpadLastPresetId(const QString &lastPresetId)
setValue("drumpad/lastPresetId", lastPresetId);
}
quint8 DrumMachineSettings::drumpadChannelPrevPreset() const
MidiLearnSetting DrumMachineSettings::drumpadPrevPreset() const
{
return value("drumpad/prevPreset_channel", 99).toUInt();
return learnSetting("drumpad/prevPreset");
}
void DrumMachineSettings::setDrumpadChannelPrevPreset(quint8 channel)
void DrumMachineSettings::setDrumpadPrevPreset(const MidiLearnSetting &value)
{
setValue("drumpad/prevPreset_channel", channel);
setLearnSetting("drumpad/prevPreset", value);
}
quint8 DrumMachineSettings::drumpadNotePrevPreset() const
MidiLearnSetting DrumMachineSettings::drumpadNextPreset() const
{
return value("drumpad/prevPreset_note", 99).toUInt();
return learnSetting("drumpad/nextPreset");
}
void DrumMachineSettings::setDrumpadNotePrevPreset(quint8 note)
void DrumMachineSettings::setDrumpadNextPreset(const MidiLearnSetting &value)
{
setValue("drumpad/prevPreset_note", note);
setLearnSetting("drumpad/nextPreset", value);
}
quint8 DrumMachineSettings::drumpadChannelNextPreset() const
MidiLearnSetting DrumMachineSettings::drumpadPrevSequence() const
{
return value("drumpad/nextPreset_channel", 99).toUInt();
return learnSetting("drumpad/prevSequence");
}
void DrumMachineSettings::setDrumpadChannelNextPreset(quint8 channel)
void DrumMachineSettings::setDrumpadPrevSequence(const MidiLearnSetting &value)
{
setValue("drumpad/nextPreset_channel", channel);
setLearnSetting("drumpad/prevSequence", value);
}
quint8 DrumMachineSettings::drumpadNoteNextPreset() const
MidiLearnSetting DrumMachineSettings::drumpadNextSequence() const
{
return value("drumpad/nextPreset_note", 99).toUInt();
return learnSetting("drumpad/nextSequence");
}
void DrumMachineSettings::setDrumpadNoteNextPreset(quint8 note)
void DrumMachineSettings::setDrumpadNextSequence(const MidiLearnSetting &value)
{
setValue("drumpad/nextPreset_note", note);
setLearnSetting("drumpad/nextSequence", value);
}
quint8 DrumMachineSettings::drumpadChannelPrevSequence() const
MidiLearnSetting DrumMachineSettings::drumpadPlayPause() const
{
return value("drumpad/prevSequence_channel", 99).toUInt();
return learnSetting("drumpad/playPause");
}
void DrumMachineSettings::setDrumpadChannelPrevSequence(quint8 channel)
void DrumMachineSettings::setDrumpadPlayPause(const MidiLearnSetting &value)
{
setValue("drumpad/prevSequence_channel", channel);
setLearnSetting("drumpad/playPause", value);
}
quint8 DrumMachineSettings::drumpadNotePrevSequence() const
MidiLearnSetting DrumMachineSettings::drumpadStop() const
{
return value("drumpad/prevSequence_note", 99).toUInt();
return learnSetting("drumpad/stop");
}
void DrumMachineSettings::setDrumpadNotePrevSequence(quint8 note)
void DrumMachineSettings::setDrumpadStop(const MidiLearnSetting &value)
{
setValue("drumpad/prevSequence_note", note);
setLearnSetting("drumpad/stop", value);
}
quint8 DrumMachineSettings::drumpadChannelNextSequence() const
MidiLearnSetting DrumMachineSettings::drumpadSample(quint8 pad) const
{
return value("drumpad/nextSequence_channel", 99).toUInt();
return learnSetting(QString{"drumpad/pad%0"}.arg(pad));
}
void DrumMachineSettings::setDrumpadChannelNextSequence(quint8 channel)
void DrumMachineSettings::setDrumpadSample(quint8 pad, const MidiLearnSetting &value)
{
setValue("drumpad/nextSequence_channel", channel);
}
quint8 DrumMachineSettings::drumpadNoteNextSequence() const
{
return value("drumpad/nextSequence_note", 99).toUInt();
}
void DrumMachineSettings::setDrumpadNoteNextSequence(quint8 note)
{
setValue("drumpad/nextSequence_note", note);
}
quint8 DrumMachineSettings::drumpadChannelPlayPause() const
{
return value("drumpad/playPause_channel", 99).toUInt();
}
void DrumMachineSettings::setDrumpadChannelPlayPause(quint8 channel)
{
setValue("drumpad/playPause_channel", channel);
}
quint8 DrumMachineSettings::drumpadNotePlayPause() const
{
return value("drumpad/playPause_note", 99).toUInt();
}
void DrumMachineSettings::setDrumpadNotePlayPause(quint8 note)
{
setValue("drumpad/playPause_note", note);
}
quint8 DrumMachineSettings::drumpadChannelStop() const
{
return value("drumpad/stop_channel", 99).toUInt();
}
void DrumMachineSettings::setDrumpadChannelStop(quint8 channel)
{
setValue("drumpad/stop_channel", channel);
}
quint8 DrumMachineSettings::drumpadNoteStop() const
{
return value("drumpad/stop_note", 99).toUInt();
}
void DrumMachineSettings::setDrumpadNoteStop(quint8 note)
{
setValue("drumpad/stop_note", note);
}
quint8 DrumMachineSettings::drumpadChannel(quint8 pad) const
{
return value(QString{"drumpad/pad%0_channel"}.arg(pad), 99).toUInt();
}
void DrumMachineSettings::setDrumpadChannel(quint8 pad, quint8 channel)
{
setValue(QString{"drumpad/pad%0_channel"}.arg(pad), channel);
}
quint8 DrumMachineSettings::drumpadNote(quint8 pad) const
{
return value(QString{"drumpad/pad%0_note"}.arg(pad), 99).toUInt();
}
void DrumMachineSettings::setDrumpadNote(quint8 pad, quint8 note)
{
setValue(QString{"drumpad/pad%0_note"}.arg(pad), note);
setLearnSetting(QString{"drumpad/pad%0"}.arg(pad), value);
}
QString DrumMachineSettings::loopstationLastPresetId() const
@ -233,42 +176,38 @@ void DrumMachineSettings::setLoopstationLastPresetId(const QString &lastPresetId
setValue("loopstation/lastPresetId", lastPresetId);
}
quint8 DrumMachineSettings::loopstationChannelPrevPreset() const
MidiLearnSetting DrumMachineSettings::loopstationPrevPreset() const
{
return value("loopstation/prevPreset_channel", 99).toUInt();
return learnSetting("loopstation/prevPreset");
}
void DrumMachineSettings::setLoopstationChannelPrevPreset(quint8 channel)
void DrumMachineSettings::setLoopstationPrevPreset(const MidiLearnSetting &value)
{
setValue("loopstation/prevPreset_channel", channel);
setLearnSetting("loopstation/prevPreset", value);
}
quint8 DrumMachineSettings::loopstationNotePrevPreset() const
MidiLearnSetting DrumMachineSettings::loopstationNextPreset() const
{
return value("loopstation/prevPreset_note", 99).toUInt();
return learnSetting("loopstation/nextPreset");
}
void DrumMachineSettings::setLoopstationNotePrevPreset(quint8 note)
void DrumMachineSettings::setLoopstationNextPreset(const MidiLearnSetting &value)
{
setValue("loopstation/prevPreset_note", note);
setLearnSetting("loopstation/nextPreset", value);
}
quint8 DrumMachineSettings::loopstationChannelNextPreset() const
MidiLearnSetting DrumMachineSettings::learnSetting(const QString &key) const
{
return value("loopstation/nextPreset_channel", 99).toUInt();
return MidiLearnSetting{
.cmd = midi::Command(value(QString{"%0_cmd"}.arg(key), std::to_underlying(midi::Command::NoteOn)).value<std::underlying_type_t<midi::Command>>()),
.channel = value(QString{"%0_channel"}.arg(key), 99).value<quint8>(),
.note = value(QString{"%0_note"}.arg(key), 99).value<quint8>()
};
}
void DrumMachineSettings::setLoopstationChannelNextPreset(quint8 channel)
void DrumMachineSettings::setLearnSetting(const QString &key, const MidiLearnSetting &value)
{
setValue("loopstation/nextPreset_channel", channel);
}
quint8 DrumMachineSettings::loopstationNoteNextPreset() const
{
return value("loopstation/nextPreset_note", 99).toUInt();
}
void DrumMachineSettings::setLoopstationNoteNextPreset(quint8 note)
{
setValue("loopstation/nextPreset_note", note);
setValue(QString{"%0_note"}.arg(key), std::to_underlying(value.cmd));
setValue(QString{"%0_channel"}.arg(key), value.channel);
setValue(QString{"%0_note"}.arg(key), value.note);
}

View File

@ -2,6 +2,8 @@
#include <QSettings>
struct MidiLearnSetting;
class DrumMachineSettings : public QSettings
{
public:
@ -27,58 +29,47 @@ public:
QString lastMidiOutDevice() const;
void setLastMidiOutDevice(const QString &lastMidiOutDevice);
MidiLearnSetting tabWidget(quint8 index) const;
void setTabWidget(quint8 index, const MidiLearnSetting &value);
QString drumpadLastPresetId() const;
void setDrumpadLastPresetId(const QString &lastPresetId);
quint8 drumpadChannelPrevPreset() const;
void setDrumpadChannelPrevPreset(quint8 channel);
quint8 drumpadNotePrevPreset() const;
void setDrumpadNotePrevPreset(quint8 note);
MidiLearnSetting drumpadPrevPreset() const;
void setDrumpadPrevPreset(const MidiLearnSetting &value);
quint8 drumpadChannelNextPreset() const;
void setDrumpadChannelNextPreset(quint8 channel);
quint8 drumpadNoteNextPreset() const;
void setDrumpadNoteNextPreset(quint8 note);
MidiLearnSetting drumpadNextPreset() const;
void setDrumpadNextPreset(const MidiLearnSetting &value);
quint8 drumpadChannelPrevSequence() const;
void setDrumpadChannelPrevSequence(quint8 channel);
quint8 drumpadNotePrevSequence() const;
void setDrumpadNotePrevSequence(quint8 note);
MidiLearnSetting drumpadPrevSequence() const;
void setDrumpadPrevSequence(const MidiLearnSetting &value);
quint8 drumpadChannelNextSequence() const;
void setDrumpadChannelNextSequence(quint8 channel);
quint8 drumpadNoteNextSequence() const;
void setDrumpadNoteNextSequence(quint8 note);
MidiLearnSetting drumpadNextSequence() const;
void setDrumpadNextSequence(const MidiLearnSetting &value);
quint8 drumpadChannelPlayPause() const;
void setDrumpadChannelPlayPause(quint8 channel);
quint8 drumpadNotePlayPause() const;
void setDrumpadNotePlayPause(quint8 note);
MidiLearnSetting drumpadPlayPause() const;
void setDrumpadPlayPause(const MidiLearnSetting &value);
quint8 drumpadChannelStop() const;
void setDrumpadChannelStop(quint8 channel);
quint8 drumpadNoteStop() const;
void setDrumpadNoteStop(quint8 note);
MidiLearnSetting drumpadStop() const;
void setDrumpadStop(const MidiLearnSetting &value);
quint8 drumpadChannel(quint8 pad) const;
void setDrumpadChannel(quint8 pad, quint8 channel);
quint8 drumpadNote(quint8 pad) const;
void setDrumpadNote(quint8 pad, quint8 note);
MidiLearnSetting drumpadSample(quint8 pad) const;
void setDrumpadSample(quint8 pad, const MidiLearnSetting &value);
QString loopstationLastPresetId() const;
void setLoopstationLastPresetId(const QString &lastPresetId);
quint8 loopstationChannelPrevPreset() const;
void setLoopstationChannelPrevPreset(quint8 channel);
quint8 loopstationNotePrevPreset() const;
void setLoopstationNotePrevPreset(quint8 note);
MidiLearnSetting loopstationPrevPreset() const;
void setLoopstationPrevPreset(const MidiLearnSetting &value);
quint8 loopstationChannelNextPreset() const;
void setLoopstationChannelNextPreset(quint8 channel);
quint8 loopstationNoteNextPreset() const;
void setLoopstationNoteNextPreset(quint8 note);
MidiLearnSetting loopstationNextPreset() const;
void setLoopstationNextPreset(const MidiLearnSetting &value);
private:
MidiLearnSetting learnSetting(const QString &key) const;
void setLearnSetting(const QString &key, const MidiLearnSetting &value);
};

30
futurecpp.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
// system includes
#include <cstring>
#include <limits>
#include <type_traits>
// C++20 backports (until espressif finally updates their aged compiler suite)
namespace std {
template <class To, class From>
typename std::enable_if_t<
sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> && std::is_trivially_copyable_v<To>,
To>
// constexpr support needs compiler magic
bit_cast(const From& src) noexcept
{
static_assert(std::is_trivially_constructible_v<To>,
"This implementation additionally requires destination type to be trivially constructible");
To dst;
std::memcpy(&dst, &src, sizeof(To));
return dst;
}
template <typename EnumT, typename = std::enable_if_t<std::is_enum<EnumT>{}>>
constexpr std::underlying_type_t<EnumT> to_underlying(EnumT e) noexcept {
return static_cast<std::underlying_type_t<EnumT>>(e);
}
} // namespace std

View File

@ -1,6 +1,10 @@
#include "midicontainers.h"
#include <QCoreApplication>
#include <QDebugStateSaver>
#include <QDataStream>
#include "futurecpp.h"
namespace midi {
bool MidiMessage::operator==(const MidiMessage &other) const
@ -11,13 +15,64 @@ bool MidiMessage::operator==(const MidiMessage &other) const
note == other.note &&
velocity == other.velocity;
}
}
} // namespace midi
namespace {
void registerMidiMessageMetatype()
{
qRegisterMetaType<midi::Command>();
qRegisterMetaType<midi::MidiMessage>();
qRegisterMetaTypeStreamOperators<midi::Command>("midi::Command");
qRegisterMetaTypeStreamOperators<midi::MidiMessage>("midi::MidiMessage");
}
Q_COREAPP_STARTUP_FUNCTION(registerMidiMessageMetatype)
} // namespace
QDebug operator<<(QDebug debug, const midi::MidiMessage &value)
{
QDebugStateSaver saver{debug};
debug.nospace() << "midi::MidiMessage{.channel=" << value.channel << ",.cmd=" << value.cmd << ",.flag=" << value.flag << ",.note=" << value.note << ",.velocity=" << value.velocity << "}";
return debug;
}
QDataStream &operator<<(QDataStream &out, const midi::Command &value)
{
return out << std::to_underlying(value);
}
QDataStream &operator>>(QDataStream &in, midi::Command &value)
{
std::underlying_type_t<midi::Command> v;
in >> v;
value = midi::Command(v);
return in;
}
QDataStream &operator<<(QDataStream &out, const midi::MidiMessage &value)
{
return out << value.channel << value.cmd << value.flag << value.note << value.velocity;
}
QDataStream &operator>>(QDataStream &in, midi::MidiMessage &value)
{
{
typeof(value.channel) channel;
in >> channel;
value.channel = channel;
}
{
typeof(value.cmd) cmd;
in >> cmd;
value.cmd = cmd;
}
{
typeof(value.flag) flag;
in >> flag;
value.flag = flag;
}
in >> value.note;
in >> value.velocity;
return in;
}

View File

@ -26,6 +26,16 @@ struct MidiMessage
bool operator==(const MidiMessage &other) const;
};
}
} // namespace midi
Q_DECLARE_METATYPE(midi::Command)
Q_DECLARE_METATYPE(midi::MidiMessage)
QDebug operator<<(QDebug debug, const midi::MidiMessage &value);
QDataStream &operator<<(QDataStream &out, const midi::Command &value);
QDataStream &operator>>(QDataStream &in, midi::Command &value);
QDataStream &operator<<(QDataStream &out, const midi::MidiMessage &value);
QDataStream &operator>>(QDataStream &in, midi::MidiMessage &value);

42
midilearnsetting.cpp Normal file
View File

@ -0,0 +1,42 @@
#include "midilearnsetting.h"
#include <QCoreApplication>
#include <QDebugStateSaver>
#include <QDataStream>
namespace {
void registerMidiLearnMessageMetatype()
{
qRegisterMetaType<MidiLearnSetting>();
qRegisterMetaTypeStreamOperators<MidiLearnSetting>("MidiLearnSetting");
}
Q_COREAPP_STARTUP_FUNCTION(registerMidiLearnMessageMetatype)
} // namespace
bool MidiLearnSetting::operator==(const MidiLearnSetting &other) const
{
return cmd == other.cmd &&
channel == other.channel &&
note == other.note;
}
QDebug operator<<(QDebug debug, const MidiLearnSetting &value)
{
QDebugStateSaver saver{debug};
debug.nospace() << "MidiLearnSetting{.cmd=" << value.cmd << ",.channel=" << value.channel << ",.note=" << value.note << "}";
return debug;
}
QDataStream &operator<<(QDataStream &out, const MidiLearnSetting &value)
{
out << value.cmd << value.channel << value.note;
return out;
}
QDataStream &operator>>(QDataStream &in, MidiLearnSetting &value)
{
in >> value.cmd >> value.channel >> value.note;
return in;
}

23
midilearnsetting.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <QDebug>
#include <QMetaType>
#include "midicontainers.h"
struct MidiLearnSetting
{
midi::Command cmd{midi::Command::NoteOn};
quint8 channel{99};
quint8 note{99};
bool operator==(const MidiLearnSetting &other) const;
QDebug operator<<(QDebug debug) const;
};
Q_DECLARE_METATYPE(MidiLearnSetting);
QDebug operator<<(QDebug debug, const MidiLearnSetting &value);
QDataStream &operator<<(QDataStream &out, const MidiLearnSetting &value);
QDataStream &operator>>(QDataStream &in, MidiLearnSetting &value);

View File

@ -51,34 +51,9 @@ void DrumPadSamplesWidget::midiReceived(const midi::MidiMessage &message)
return;
}
if (message.cmd != midi::Command::NoteOn &&
message.cmd != midi::Command::NoteOff &&
message.cmd != midi::Command::ControlChange)
return;
for (DrumPadSampleWidget &widget : getWidgets())
{
if (widget.isLearning())
{
widget.learn(message.channel, message.note);
}
else if (widget.channel() == message.channel && widget.note() == message.note)
{
switch (message.cmd)
{
case midi::Command::NoteOn:
case midi::Command::ControlChange:
if (message.velocity != 0)
widget.pressed(message.velocity);
else
Q_FALLTHROUGH();
case midi::Command::NoteOff:
widget.released();
break;
default:
__builtin_unreachable();
}
}
widget.midiReceived(message);
}
}
@ -120,7 +95,7 @@ void DrumPadSamplesWidget::sequencerTriggerSample(int index)
qDebug() << "index out of range" << index;
return;
}
widgets[index].get().pressed(127);
widgets[index].get().pressed();
}
void DrumPadSamplesWidget::chokeTriggered(int choke)

View File

@ -30,9 +30,8 @@ DrumPadSampleWidget::DrumPadSampleWidget(QWidget *parent) :
connect(&m_player, &AudioPlayer::playingChanged, this, &DrumPadSampleWidget::updateStatus);
connect(m_ui->pushButton, &QAbstractButton::pressed, this, [this](){ pressed(127); });
connect(m_ui->pushButton, &QAbstractButton::released, this, &DrumPadSampleWidget::released);
connect(m_ui->toolButtonLearn, &QAbstractButton::pressed, this, &DrumPadSampleWidget::learnPressed);
connect(m_ui->pushButtonPlay, &QAbstractButton::pressed, this, &DrumPadSampleWidget::pressed);
connect(m_ui->pushButtonPlay, &QAbstractButton::released, this, &DrumPadSampleWidget::released);
updateStatus();
}
@ -41,10 +40,17 @@ DrumPadSampleWidget::~DrumPadSampleWidget() = default;
void DrumPadSampleWidget::loadSettings(DrumMachineSettings &settings)
{
m_ui->channelSpinBox->setValue(settings.drumpadChannel(m_padNr));
m_ui->noteSpinBox->setValue(settings.drumpadNote(m_padNr));
m_settings = &settings;
m_ui->pushButtonPlay->setLearnSetting(m_settings->drumpadSample(m_padNr));
connect(m_ui->pushButtonPlay, &MidiButton::learnSettingChanged, this, [this](const MidiLearnSetting &learnSetting){
Q_ASSERT(m_settings);
if (m_settings)
m_settings->setDrumpadSample(m_padNr, learnSetting);
else
qWarning() << "no settings available";
});
}
void DrumPadSampleWidget::setFile(const QString &presetId, const drumpad_presets::File &file)
@ -80,38 +86,6 @@ void DrumPadSampleWidget::setFile(const QString &presetId, const drumpad_presets
setupLabel(file.choke, m_ui->chokeLabel);
}
quint8 DrumPadSampleWidget::channel() const
{
return m_ui->channelSpinBox->value();
}
void DrumPadSampleWidget::setChannel(quint8 channel)
{
m_ui->channelSpinBox->setValue(channel);
Q_ASSERT(m_settings);
if (m_settings)
m_settings->setDrumpadChannel(m_padNr, channel);
else
qWarning() << "no settings available";
}
quint8 DrumPadSampleWidget::note() const
{
return m_ui->noteSpinBox->value();
}
void DrumPadSampleWidget::setNote(quint8 note)
{
m_ui->noteSpinBox->setValue(note);
Q_ASSERT(m_settings);
if (m_settings)
m_settings->setDrumpadNote(m_padNr, note);
else
qWarning() << "no settings available";
}
int DrumPadSampleWidget::speed() const
{
return m_ui->dialSpeed->value();
@ -139,10 +113,8 @@ std::optional<int> DrumPadSampleWidget::choke() const
return m_file->choke;
}
void DrumPadSampleWidget::pressed(quint8 velocity)
void DrumPadSampleWidget::pressed()
{
Q_UNUSED(velocity)
m_player.restart();
if (m_file && m_file->choke && *m_file->choke)
@ -181,61 +153,59 @@ void DrumPadSampleWidget::writeSamples(frame_t *begin, frame_t *end)
m_player.writeSamples(begin, end);
}
void DrumPadSampleWidget::learn(quint8 channel, quint8 note)
void DrumPadSampleWidget::midiReceived(const midi::MidiMessage &message)
{
setChannel(channel);
setNote(note);
if (m_learning)
learnPressed();
m_ui->pushButtonPlay->midiReceived(message);
}
void DrumPadSampleWidget::unsendColor()
{
m_sendColors = false;
midi::MidiMessage midiMsg;
midiMsg.channel = m_ui->channelSpinBox->value();
midiMsg.cmd = midi::Command::NoteOn;
midiMsg.flag = true;
midiMsg.note = m_ui->noteSpinBox->value();
midiMsg.velocity = 0;
emit sendMidi(midiMsg);
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 DrumPadSampleWidget::sendColor()
{
m_sendColors = true;
midi::MidiMessage midiMsg;
midiMsg.channel = m_ui->channelSpinBox->value();
midiMsg.cmd = midi::Command::NoteOn;
midiMsg.flag = true;
midiMsg.note = m_ui->noteSpinBox->value();
uint8_t velocity;
if (m_file && m_file->color && m_player.buffer().isValid())
{
const auto &color = *m_file->color;
if (color == "purple")
midiMsg.velocity = m_player.playing() ? 43 : 18;
velocity = m_player.playing() ? 43 : 18;
else if (color == "red")
midiMsg.velocity = m_player.playing() ? 3 : 1;
velocity = m_player.playing() ? 3 : 1;
else if (color == "yellow")
midiMsg.velocity = m_player.playing() ? 58 : 33;
velocity = m_player.playing() ? 58 : 33;
else if (color == "green")
midiMsg.velocity = m_player.playing() ? 56 : 16;
velocity = m_player.playing() ? 56 : 16;
else if (color == "blue")
midiMsg.velocity = m_player.playing() ? 49 : 51;
velocity = m_player.playing() ? 49 : 51;
else
goto noColor;
}
else
{
noColor:
midiMsg.velocity = 0;
velocity = 0;
}
emit sendMidi(midiMsg);
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 = velocity
});
}
void DrumPadSampleWidget::updateStatus()
@ -309,27 +279,6 @@ void DrumPadSampleWidget::decodingFinished(const QAudioBuffer &buffer)
updateStatus();
}
void DrumPadSampleWidget::learnPressed()
{
auto palette = m_ui->toolButtonLearn->palette();
if (m_learning)
{
palette.setColor(m_ui->toolButtonLearn->backgroundRole(), m_oldColor);
palette.setBrush(m_ui->toolButtonLearn->backgroundRole(), m_oldBrush);
}
else
{
m_oldColor = palette.color(m_ui->toolButtonLearn->backgroundRole());
m_oldBrush = palette.brush(m_ui->toolButtonLearn->backgroundRole());
palette.setColor(m_ui->toolButtonLearn->backgroundRole(), Qt::red);
palette.setBrush(m_ui->toolButtonLearn->backgroundRole(), Qt::red);
}
m_ui->toolButtonLearn->setPalette(palette);
m_learning = !m_learning;
}
void DrumPadSampleWidget::startRequest()
{
if (m_networkAccessManager && m_file->filename)

View File

@ -31,12 +31,6 @@ public:
void setFile(const QString &presetId, const drumpad_presets::File &file);
quint8 channel() const;
void setChannel(quint8 channel);
quint8 note() const;
void setNote(quint8 note);
int speed() const;
void setSpeed(int speed);
@ -45,7 +39,7 @@ public:
std::optional<int> choke() const;
void pressed(quint8 velocity);
void pressed();
void released();
void forceStop();
@ -55,8 +49,7 @@ public:
void writeSamples(frame_t *begin, frame_t *end);
bool isLearning() const { return m_learning; }
void learn(quint8 channel, quint8 note);
void midiReceived(const midi::MidiMessage &message);
void unsendColor();
void sendColor();
@ -70,7 +63,6 @@ private slots:
void updateStatus();
void requestFinished();
void decodingFinished(const QAudioBuffer &buffer);
void learnPressed();
private:
void startRequest();
@ -92,9 +84,5 @@ private:
quint8 m_padNr{};
bool m_learning{};
QColor m_oldColor;
QBrush m_oldBrush;
bool m_sendColors{};
};

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>140</width>
<height>157</height>
<width>135</width>
<height>122</height>
</rect>
</property>
<property name="autoFillBackground">
@ -59,7 +59,7 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="MidiButton" name="pushButton">
<widget class="MidiButton" name="pushButtonPlay">
<property name="maximumSize">
<size>
<width>32</width>
@ -95,23 +95,6 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="channelSpinBox"/>
</item>
<item>
<widget class="QSpinBox" name="noteSpinBox"/>
</item>
<item>
<widget class="QToolButton" name="toolButtonLearn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>

View File

@ -64,15 +64,11 @@ void DrumPadWidget::loadSettings(DrumMachineSettings &settings)
{
m_settings = &settings;
m_ui->pushButtonUp->setChannel(m_settings->drumpadChannelPrevPreset());
m_ui->pushButtonUp->setNote(m_settings->drumpadNotePrevPreset());
m_ui->pushButtonDown->setChannel(m_settings->drumpadChannelNextPreset());
m_ui->pushButtonDown->setNote(m_settings->drumpadNoteNextPreset());
m_ui->pushButtonUp->setLearnSetting(m_settings->drumpadPrevPreset());
m_ui->pushButtonDown->setLearnSetting(m_settings->drumpadNextPreset());
connect(m_ui->pushButtonUp, &MidiButton::channelChanged, m_settings, &DrumMachineSettings::setDrumpadChannelPrevPreset);
connect(m_ui->pushButtonUp, &MidiButton::noteChanged, m_settings, &DrumMachineSettings::setDrumpadNotePrevPreset);
connect(m_ui->pushButtonDown, &MidiButton::channelChanged, m_settings, &DrumMachineSettings::setDrumpadChannelNextPreset);
connect(m_ui->pushButtonDown, &MidiButton::noteChanged, m_settings, &DrumMachineSettings::setDrumpadNoteNextPreset);
connect(m_ui->pushButtonUp, &MidiButton::learnSettingChanged, m_settings, &DrumMachineSettings::setDrumpadPrevPreset);
connect(m_ui->pushButtonDown, &MidiButton::learnSettingChanged, m_settings, &DrumMachineSettings::setDrumpadNextPreset);
m_ui->sequencerWidget->loadSettings(settings);
m_ui->samplesWidget->loadSettings(settings);
@ -81,17 +77,17 @@ void DrumPadWidget::loadSettings(DrumMachineSettings &settings)
void DrumPadWidget::unsendColors()
{
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonUp->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonUp->learnSetting().channel,
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonUp->note(),
.note = m_ui->pushButtonUp->learnSetting().note,
.velocity = 0
});
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonDown->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonDown->learnSetting().channel,
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonDown->note(),
.note = m_ui->pushButtonDown->learnSetting().note,
.velocity = 0
});
@ -102,17 +98,17 @@ void DrumPadWidget::unsendColors()
void DrumPadWidget::sendColors()
{
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonUp->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonUp->learnSetting().channel,
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonUp->note(),
.note = m_ui->pushButtonUp->learnSetting().note,
.velocity = 127
});
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonDown->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonDown->learnSetting().channel,
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonDown->note(),
.note = m_ui->pushButtonDown->learnSetting().note,
.velocity = 127
});

View File

@ -57,31 +57,27 @@ void LoopStationWidget::loadSettings(DrumMachineSettings &settings)
{
m_settings = &settings;
m_ui->pushButtonUp->setChannel(m_settings->loopstationChannelPrevPreset());
m_ui->pushButtonUp->setNote(m_settings->loopstationNotePrevPreset());
m_ui->pushButtonDown->setChannel(m_settings->loopstationChannelNextPreset());
m_ui->pushButtonDown->setNote(m_settings->loopstationNoteNextPreset());
m_ui->pushButtonUp->setLearnSetting(m_settings->loopstationPrevPreset());
m_ui->pushButtonDown->setLearnSetting(m_settings->loopstationNextPreset());
connect(m_ui->pushButtonUp, &MidiButton::channelChanged, m_settings, &DrumMachineSettings::setLoopstationChannelPrevPreset);
connect(m_ui->pushButtonUp, &MidiButton::noteChanged, m_settings, &DrumMachineSettings::setLoopstationNotePrevPreset);
connect(m_ui->pushButtonDown, &MidiButton::channelChanged, m_settings, &DrumMachineSettings::setLoopstationChannelNextPreset);
connect(m_ui->pushButtonDown, &MidiButton::noteChanged, m_settings, &DrumMachineSettings::setLoopstationNoteNextPreset);
connect(m_ui->pushButtonUp, &MidiButton::learnSettingChanged, m_settings, &DrumMachineSettings::setLoopstationPrevPreset);
connect(m_ui->pushButtonDown, &MidiButton::learnSettingChanged, m_settings, &DrumMachineSettings::setLoopstationNextPreset);
}
void LoopStationWidget::unsendColors()
{
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonUp->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonUp->learnSetting().channel,
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonUp->note(),
.note = m_ui->pushButtonUp->learnSetting().note,
.velocity = 0
});
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonDown->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonDown->learnSetting().channel,
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonDown->note(),
.note = m_ui->pushButtonDown->learnSetting().note,
.velocity = 0
});
}
@ -89,17 +85,17 @@ void LoopStationWidget::unsendColors()
void LoopStationWidget::sendColors()
{
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonUp->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonUp->learnSetting().channel,
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonUp->note(),
.note = m_ui->pushButtonUp->learnSetting().note,
.velocity = 127
});
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonDown->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonDown->learnSetting().channel,
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonDown->note(),
.note = m_ui->pushButtonDown->learnSetting().note,
.velocity = 127
});
}

View File

@ -303,6 +303,10 @@ void MainWindow::updateMidiOutDevices()
void MainWindow::loadSettings()
{
for (int i = 0; i < m_ui->tabWidget->count(); i++)
m_ui->tabWidget->setLearnSetting(i, m_settings.tabWidget(i));
connect(m_ui->tabWidget, &MidiTabWidget::learnSettingChanged, &m_settings, &DrumMachineSettings::setTabWidget);
m_ui->drumPadWidget->loadSettings(m_settings);
m_ui->loopStationWidget->loadSettings(m_settings);
m_ui->djWidget->loadSettings(m_settings);
@ -311,6 +315,17 @@ void MainWindow::loadSettings()
void MainWindow::unsendColors(int index)
{
{
const auto &learnSetting = m_ui->tabWidget->learnSetting(index);
emit sendMidi(midi::MidiMessage {
.channel = learnSetting.channel,
.cmd = learnSetting.cmd,
.flag = true,
.note = learnSetting.note,
.velocity = 0
});
}
if (index == 0)
m_ui->drumPadWidget->unsendColors();
else if (index == 1)
@ -323,6 +338,17 @@ void MainWindow::unsendColors(int index)
void MainWindow::sendColors(int index)
{
{
const auto &learnSetting = m_ui->tabWidget->learnSetting(index);
emit sendMidi(midi::MidiMessage {
.channel = learnSetting.channel,
.cmd = learnSetting.cmd,
.flag = true,
.note = learnSetting.note,
.velocity = 3
});
}
if (index == 0)
m_ui->drumPadWidget->sendColors();
else if (index == 1)

View File

@ -4,6 +4,7 @@
#include <QtGlobal>
#include "midicontainers.h"
#include "futurecpp.h"
MidiButton::MidiButton(QWidget *parent) :
QPushButton{parent}
@ -13,6 +14,22 @@ MidiButton::MidiButton(QWidget *parent) :
auto action = new QAction{tr("Learn...")};
connect(action, &QAction::triggered, this, &MidiButton::learn);
addAction(action);
{
m_actionCmd = new QAction{tr("cmd:")};
m_actionCmd->setDisabled(true);
addAction(m_actionCmd);
}
{
m_actionChannel = new QAction{tr("channel:")};
m_actionChannel->setDisabled(true);
addAction(m_actionChannel);
}
{
m_actionNote = new QAction{tr("note:")};
m_actionNote->setDisabled(true);
addAction(m_actionNote);
}
}
MidiButton::MidiButton(const QString &text, QWidget *parent) :
@ -25,6 +42,16 @@ MidiButton::MidiButton(const QIcon &icon, const QString &text, QWidget *parent)
{
}
void MidiButton::setLearnSetting(const MidiLearnSetting &learnSetting)
{
if (m_learnSetting == learnSetting)
return;
emit learnSettingChanged(m_learnSetting = learnSetting);
m_actionCmd->setText(tr("cmd: %0").arg(std::to_underlying(m_learnSetting.cmd)));
m_actionChannel->setText(tr("channel: %0").arg(m_learnSetting.channel));
m_actionNote->setText(tr("note: %0").arg(m_learnSetting.note));
}
void MidiButton::learn()
{
auto palette = this->palette();
@ -48,38 +75,49 @@ void MidiButton::learn()
void MidiButton::midiReceived(const midi::MidiMessage &message)
{
if (message.cmd != midi::Command::NoteOn &&
message.cmd != midi::Command::NoteOff &&
message.cmd != midi::Command::ControlChange)
return;
if (m_learning)
{
if ((message.cmd != midi::Command::NoteOn && message.cmd != midi::Command::ControlChange) || message.velocity == 0)
return;
setChannel(message.channel);
setNote(message.note);
setLearnSetting(MidiLearnSetting{
.cmd = message.cmd == midi::Command::NoteOff ? midi::Command::NoteOn : message.cmd,
.channel = message.channel,
.note = message.note
});
learn();
}
else
{
if (message.channel != m_channel || message.note != m_note)
if (message.channel != m_learnSetting.channel ||
message.note != m_learnSetting.note)
return;
switch (message.cmd)
if (m_learnSetting.cmd == midi::Command::NoteOn || m_learnSetting.cmd == midi::Command::NoteOff)
{
switch (message.cmd)
{
case midi::Command::NoteOn:
if (message.velocity != 0)
emit pressed();
else
Q_FALLTHROUGH();
case midi::Command::NoteOff:
emit released();
break;
default:
return;
}
}
else if (m_learnSetting.cmd == message.cmd)
{
case midi::Command::NoteOn:
case midi::Command::ControlChange:
if (message.velocity != 0)
emit pressed();
else
Q_FALLTHROUGH();
case midi::Command::NoteOff:
emit released();
break;
default:
__builtin_unreachable();
emit released();
}
else
return;
}
}

View File

@ -2,38 +2,39 @@
#include <QPushButton>
#include "midilearnsetting.h"
namespace midi { struct MidiMessage; }
class QAction;
class MidiButton : public QPushButton
{
Q_OBJECT
Q_PROPERTY(quint8 channel READ channel WRITE setChannel NOTIFY channelChanged)
Q_PROPERTY(quint8 note READ note WRITE setNote NOTIFY noteChanged)
Q_PROPERTY(MidiLearnSetting learnSetting READ learnSetting WRITE setLearnSetting NOTIFY learnSettingChanged)
public:
explicit MidiButton(QWidget *parent = nullptr);
explicit MidiButton(const QString &text, QWidget *parent = nullptr);
MidiButton(const QIcon& icon, const QString &text, QWidget *parent = nullptr);
quint8 channel() const { return m_channel; }
void setChannel(quint8 channel) { if (channel == m_channel) return; emit channelChanged(m_channel = channel); }
quint8 note() const { return m_note; }
void setNote(quint8 note) { if (note == m_note) return; emit noteChanged(m_note = note); }
MidiLearnSetting learnSetting() const { return m_learnSetting; }
void setLearnSetting(const MidiLearnSetting &learnSetting);
signals:
void channelChanged(quint8 channel);
void noteChanged(quint8 note);
void learnSettingChanged(const MidiLearnSetting &learnSetting);
public slots:
void learn();
void midiReceived(const midi::MidiMessage &message);
private:
quint8 m_channel{99};
quint8 m_note{99};
MidiLearnSetting m_learnSetting;
bool m_learning{};
QColor m_oldColor;
QBrush m_oldBrush;
QAction *m_actionCmd{};
QAction *m_actionChannel{};
QAction *m_actionNote{};
};

View File

@ -6,6 +6,7 @@
#include <QDebug>
#include "midicontainers.h"
#include "futurecpp.h"
MidiTabWidget::MidiTabWidget(QWidget *parent) :
QTabWidget{parent}
@ -14,30 +15,16 @@ MidiTabWidget::MidiTabWidget(QWidget *parent) :
connect(tabBar(), &QWidget::customContextMenuRequested, this, &MidiTabWidget::showContextMenu);
}
quint8 MidiTabWidget::channel(int index) const
MidiLearnSetting MidiTabWidget::learnSetting(int index) const
{
return m_channelNotes[index].channel;
return m_learnSettings[index];
}
void MidiTabWidget::setChannel(int index, quint8 channel)
void MidiTabWidget::setLearnSetting(int index, const MidiLearnSetting &learnSetting)
{
auto &channelNote = m_channelNotes[index];
if (channelNote.channel == channel)
if (learnSetting == m_learnSettings[index])
return;
emit channelChanged(index, channelNote.channel = channel);
}
quint8 MidiTabWidget::note(int index) const
{
return m_channelNotes[index].note;
}
void MidiTabWidget::setNote(int index, quint8 note)
{
auto &channelNote = m_channelNotes[index];
if (channelNote.note == note)
return;
emit noteChanged(index, channelNote.note = note);
emit learnSettingChanged(index, m_learnSettings[index] = learnSetting);
}
void MidiTabWidget::learn(int index)
@ -67,18 +54,21 @@ void MidiTabWidget::midiReceived(const midi::MidiMessage &message)
if (m_learning)
{
qDebug() << "learning" << message.cmd << message.velocity << message.channel << message.note;
setChannel(*m_learning, message.channel);
setNote(*m_learning, message.note);
setLearnSetting(*m_learning, MidiLearnSetting{
.cmd = message.cmd == midi::Command::NoteOff ? midi::Command::NoteOn : message.cmd,
.channel = message.channel,
.note = message.note
});
learn(*m_learning);
}
else
{
qDebug() << "normal" << message.cmd << message.velocity << message.channel << message.note;
for (int i = 0; i < count(); i++)
{
if (message.channel != m_channelNotes[i].channel ||
message.note != m_channelNotes[i].note)
if (message.cmd != m_learnSettings[i].cmd ||
message.channel != m_learnSettings[i].channel ||
message.note != m_learnSettings[i].note)
continue;
setCurrentIndex(i);
@ -90,13 +80,13 @@ void MidiTabWidget::midiReceived(const midi::MidiMessage &message)
void MidiTabWidget::tabInserted(int index)
{
QTabWidget::tabInserted(index);
m_channelNotes.insert(std::begin(m_channelNotes) + index, ChannelNote{.channel=quint8(index)});
m_learnSettings.insert(std::begin(m_learnSettings) + index, MidiLearnSetting{});
}
void MidiTabWidget::tabRemoved(int index)
{
QTabWidget::tabInserted(index);
m_channelNotes.erase(std::begin(m_channelNotes) + index);
m_learnSettings.erase(std::begin(m_learnSettings) + index);
}
void MidiTabWidget::showContextMenu(const QPoint &pos)
@ -107,6 +97,12 @@ void MidiTabWidget::showContextMenu(const QPoint &pos)
QMenu menu{tabBar()};
const auto learnAction = menu.addAction(tr("Learn..."));
{
const auto &learnSetting = m_learnSettings[index];
menu.addAction(tr("cmd: %0").arg(std::to_underlying(learnSetting.cmd)))->setDisabled(true);
menu.addAction(tr("channel: %0").arg(learnSetting.channel))->setDisabled(true);
menu.addAction(tr("note: %0").arg(learnSetting.note))->setDisabled(true);
}
if (const auto selectedAction = menu.exec(tabBar()->mapToGlobal(pos));
selectedAction == learnAction)
{

View File

@ -5,6 +5,8 @@
#include <optional>
#include <vector>
#include "midilearnsetting.h"
namespace midi { struct MidiMessage; }
class MidiTabWidget : public QTabWidget
@ -14,15 +16,11 @@ class MidiTabWidget : public QTabWidget
public:
explicit MidiTabWidget(QWidget *parent = nullptr);
quint8 channel(int index) const;
void setChannel(int index, quint8 channel);
quint8 note(int index) const;
void setNote(int index, quint8 note);
MidiLearnSetting learnSetting(int index) const;
void setLearnSetting(int index, const MidiLearnSetting &learnSetting);
signals:
void channelChanged(int index, quint8 channel);
void noteChanged(int index, quint8 note);
void learnSettingChanged(int index, const MidiLearnSetting &learnSetting);
public slots:
void learn(int index);
@ -39,10 +37,5 @@ private:
std::optional<int> m_learning;
QColor m_oldColor;
struct ChannelNote
{
quint8 channel{99};
quint8 note{99};
};
std::vector<ChannelNote> m_channelNotes;
std::vector<MidiLearnSetting> m_learnSettings;
};

View File

@ -36,23 +36,15 @@ SequencerWidget::~SequencerWidget() = default;
void SequencerWidget::loadSettings(DrumMachineSettings &settings)
{
m_ui->pushButtonUp->setChannel(settings.drumpadChannelPrevSequence());
m_ui->pushButtonUp->setNote(settings.drumpadNotePrevSequence());
m_ui->pushButtonDown->setChannel(settings.drumpadChannelNextSequence());
m_ui->pushButtonDown->setNote(settings.drumpadNoteNextSequence());
m_ui->pushButtonPlayPause->setChannel(settings.drumpadChannelPlayPause());
m_ui->pushButtonPlayPause->setNote(settings.drumpadNotePlayPause());
m_ui->pushButtonStop->setChannel(settings.drumpadChannelStop());
m_ui->pushButtonStop->setNote(settings.drumpadNoteStop());
m_ui->pushButtonUp->setLearnSetting(settings.drumpadPrevSequence());
m_ui->pushButtonDown->setLearnSetting(settings.drumpadNextSequence());
m_ui->pushButtonPlayPause->setLearnSetting(settings.drumpadPlayPause());
m_ui->pushButtonStop->setLearnSetting(settings.drumpadStop());
connect(m_ui->pushButtonUp, &MidiButton::channelChanged, &settings, &DrumMachineSettings::setDrumpadChannelPrevSequence);
connect(m_ui->pushButtonUp, &MidiButton::noteChanged, &settings, &DrumMachineSettings::setDrumpadNotePrevSequence);
connect(m_ui->pushButtonDown, &MidiButton::channelChanged, &settings, &DrumMachineSettings::setDrumpadChannelNextSequence);
connect(m_ui->pushButtonDown, &MidiButton::noteChanged, &settings, &DrumMachineSettings::setDrumpadNoteNextSequence);
connect(m_ui->pushButtonPlayPause, &MidiButton::channelChanged, &settings, &DrumMachineSettings::setDrumpadChannelPlayPause);
connect(m_ui->pushButtonPlayPause, &MidiButton::noteChanged, &settings, &DrumMachineSettings::setDrumpadNotePlayPause);
connect(m_ui->pushButtonStop, &MidiButton::channelChanged, &settings, &DrumMachineSettings::setDrumpadChannelStop);
connect(m_ui->pushButtonStop, &MidiButton::noteChanged, &settings, &DrumMachineSettings::setDrumpadNoteStop);
connect(m_ui->pushButtonUp, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadPrevSequence);
connect(m_ui->pushButtonDown, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadNextSequence);
connect(m_ui->pushButtonPlayPause, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadPlayPause);
connect(m_ui->pushButtonStop, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadStop);
}
void SequencerWidget::unsendColors()
@ -60,31 +52,31 @@ void SequencerWidget::unsendColors()
m_sendColors = false;
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonUp->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonUp->learnSetting().channel,
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonUp->note(),
.note = m_ui->pushButtonUp->learnSetting().note,
.velocity = 0
});
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonDown->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonDown->learnSetting().channel,
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonDown->note(),
.note = m_ui->pushButtonDown->learnSetting().note,
.velocity = 0
});
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonPlayPause->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonPlayPause->learnSetting().channel,
.cmd = m_ui->pushButtonPlayPause->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonPlayPause->note(),
.note = m_ui->pushButtonPlayPause->learnSetting().note,
.velocity = 0
});
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonStop->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonStop->learnSetting().channel,
.cmd = m_ui->pushButtonStop->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonStop->note(),
.note = m_ui->pushButtonStop->learnSetting().note,
.velocity = 0
});
}
@ -94,31 +86,31 @@ void SequencerWidget::sendColors()
m_sendColors = true;
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonUp->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonUp->learnSetting().channel,
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonUp->note(),
.note = m_ui->pushButtonUp->learnSetting().note,
.velocity = 127
});
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonDown->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonDown->learnSetting().channel,
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonDown->note(),
.note = m_ui->pushButtonDown->learnSetting().note,
.velocity = 127
});
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonPlayPause->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonPlayPause->learnSetting().channel,
.cmd = m_ui->pushButtonPlayPause->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonPlayPause->note(),
.note = m_ui->pushButtonPlayPause->learnSetting().note,
.velocity = 60
});
emit sendMidi(midi::MidiMessage {
.channel = m_ui->pushButtonStop->channel(),
.cmd = midi::Command::NoteOn,
.channel = m_ui->pushButtonStop->learnSetting().channel,
.cmd = m_ui->pushButtonStop->learnSetting().cmd,
.flag = true,
.note = m_ui->pushButtonStop->note(),
.note = m_ui->pushButtonStop->learnSetting().note,
.velocity = 3
});
}