diff --git a/DrumMachine.pro b/DrumMachine.pro index a5804a9..587edae 100755 --- a/DrumMachine.pro +++ b/DrumMachine.pro @@ -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 \ diff --git a/drummachinesettings.cpp b/drummachinesettings.cpp index 9885173..813b2e6 100644 --- a/drummachinesettings.cpp +++ b/drummachinesettings.cpp @@ -3,6 +3,9 @@ #include #include +#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>()), + .channel = value(QString{"%0_channel"}.arg(key), 99).value(), + .note = value(QString{"%0_note"}.arg(key), 99).value() + }; } -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); } diff --git a/drummachinesettings.h b/drummachinesettings.h index d1d7f89..a524c45 100644 --- a/drummachinesettings.h +++ b/drummachinesettings.h @@ -2,6 +2,8 @@ #include +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); }; diff --git a/futurecpp.h b/futurecpp.h new file mode 100644 index 0000000..b67578c --- /dev/null +++ b/futurecpp.h @@ -0,0 +1,30 @@ +#pragma once + +// system includes +#include +#include +#include + +// C++20 backports (until espressif finally updates their aged compiler suite) + +namespace std { +template +typename std::enable_if_t< + sizeof(To) == sizeof(From) && std::is_trivially_copyable_v && std::is_trivially_copyable_v, + To> +// constexpr support needs compiler magic +bit_cast(const From& src) noexcept +{ + static_assert(std::is_trivially_constructible_v, + "This implementation additionally requires destination type to be trivially constructible"); + + To dst; + std::memcpy(&dst, &src, sizeof(To)); + return dst; +} + +template {}>> +constexpr std::underlying_type_t to_underlying(EnumT e) noexcept { + return static_cast>(e); +} +} // namespace std diff --git a/midicontainers.cpp b/midicontainers.cpp index 025eebd..5673d3d 100755 --- a/midicontainers.cpp +++ b/midicontainers.cpp @@ -1,6 +1,10 @@ #include "midicontainers.h" #include +#include +#include + +#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(); qRegisterMetaType(); + + qRegisterMetaTypeStreamOperators("midi::Command"); + qRegisterMetaTypeStreamOperators("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 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; } diff --git a/midicontainers.h b/midicontainers.h index f6bf8a7..0c4fed7 100755 --- a/midicontainers.h +++ b/midicontainers.h @@ -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); diff --git a/midilearnsetting.cpp b/midilearnsetting.cpp new file mode 100644 index 0000000..0e4df9f --- /dev/null +++ b/midilearnsetting.cpp @@ -0,0 +1,42 @@ +#include "midilearnsetting.h" + +#include +#include +#include + +namespace { +void registerMidiLearnMessageMetatype() +{ + qRegisterMetaType(); + + qRegisterMetaTypeStreamOperators("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; +} diff --git a/midilearnsetting.h b/midilearnsetting.h new file mode 100644 index 0000000..9257408 --- /dev/null +++ b/midilearnsetting.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#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); diff --git a/widgets/drumpadsampleswidget.cpp b/widgets/drumpadsampleswidget.cpp index 2c579a1..8165961 100755 --- a/widgets/drumpadsampleswidget.cpp +++ b/widgets/drumpadsampleswidget.cpp @@ -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) diff --git a/widgets/drumpadsamplewidget.cpp b/widgets/drumpadsamplewidget.cpp index a340a53..b96171c 100755 --- a/widgets/drumpadsamplewidget.cpp +++ b/widgets/drumpadsamplewidget.cpp @@ -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 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) diff --git a/widgets/drumpadsamplewidget.h b/widgets/drumpadsamplewidget.h index a0f5c6e..87b1558 100755 --- a/widgets/drumpadsamplewidget.h +++ b/widgets/drumpadsamplewidget.h @@ -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 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{}; }; diff --git a/widgets/drumpadsamplewidget.ui b/widgets/drumpadsamplewidget.ui index 34e3fed..4a961f4 100755 --- a/widgets/drumpadsamplewidget.ui +++ b/widgets/drumpadsamplewidget.ui @@ -6,8 +6,8 @@ 0 0 - 140 - 157 + 135 + 122 @@ -59,7 +59,7 @@ - + 32 @@ -95,23 +95,6 @@ - - - - - - - - - - - - ... - - - - - diff --git a/widgets/drumpadwidget.cpp b/widgets/drumpadwidget.cpp index ab36095..28a1455 100644 --- a/widgets/drumpadwidget.cpp +++ b/widgets/drumpadwidget.cpp @@ -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 }); diff --git a/widgets/loopstationwidget.cpp b/widgets/loopstationwidget.cpp index 556d782..3f15396 100644 --- a/widgets/loopstationwidget.cpp +++ b/widgets/loopstationwidget.cpp @@ -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 }); } diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index e4ecde8..81a8387 100755 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -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) diff --git a/widgets/midibutton.cpp b/widgets/midibutton.cpp index 1b012fa..cf6e81d 100644 --- a/widgets/midibutton.cpp +++ b/widgets/midibutton.cpp @@ -4,6 +4,7 @@ #include #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; } } diff --git a/widgets/midibutton.h b/widgets/midibutton.h index f919071..ec3b0ca 100644 --- a/widgets/midibutton.h +++ b/widgets/midibutton.h @@ -2,38 +2,39 @@ #include +#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{}; }; diff --git a/widgets/miditabwidget.cpp b/widgets/miditabwidget.cpp index ba90c27..0391e5b 100644 --- a/widgets/miditabwidget.cpp +++ b/widgets/miditabwidget.cpp @@ -6,6 +6,7 @@ #include #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) { diff --git a/widgets/miditabwidget.h b/widgets/miditabwidget.h index 6e6b5e2..9a94fe8 100644 --- a/widgets/miditabwidget.h +++ b/widgets/miditabwidget.h @@ -5,6 +5,8 @@ #include #include +#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 m_learning; QColor m_oldColor; - struct ChannelNote - { - quint8 channel{99}; - quint8 note{99}; - }; - std::vector m_channelNotes; + std::vector m_learnSettings; }; diff --git a/widgets/sequencerwidget.cpp b/widgets/sequencerwidget.cpp index 7dcad5e..c5f9f72 100755 --- a/widgets/sequencerwidget.cpp +++ b/widgets/sequencerwidget.cpp @@ -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 }); }