From 8483cbba7d772d184b9e2fdebbb888c173636f0c Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Sun, 1 Jan 2023 07:13:48 +0100 Subject: [PATCH] Most colors are now configurable and added drum pad settings dialog --- DrumMachine.pro | 9 +- audiodecoder.cpp | 2 +- drummachinesettings.cpp | 228 +++++++++++- drummachinesettings.h | 65 +++- midioutwrapper.cpp | 3 +- midioutwrapper.h | 6 +- widgets/drumpadpresetdetailwidget.cpp | 3 +- widgets/drumpadsampleswidget.cpp | 69 +++- widgets/drumpadsampleswidget.h | 3 + widgets/drumpadsampleswidget.ui | 27 +- widgets/drumpadsamplewidget.cpp | 29 +- widgets/drumpadsamplewidget.h | 2 +- ...rwidget.cpp => drumpadsequencerwidget.cpp} | 75 ++-- ...encerwidget.h => drumpadsequencerwidget.h} | 12 +- ...cerwidget.ui => drumpadsequencerwidget.ui} | 4 +- widgets/drumpadsettingsdialog.cpp | 102 ++++++ widgets/drumpadsettingsdialog.h | 31 ++ widgets/drumpadsettingsdialog.ui | 340 ++++++++++++++++++ widgets/drumpadwidget.cpp | 19 +- widgets/drumpadwidget.h | 1 - widgets/drumpadwidget.ui | 6 +- widgets/loopstationpresetdetailwidget.cpp | 3 +- widgets/loopstationsampleswidget.cpp | 114 +++++- widgets/loopstationsampleswidget.h | 7 +- widgets/loopstationsampleswidget.ui | 38 +- widgets/loopstationsamplewidget.cpp | 34 +- widgets/loopstationsamplewidget.h | 6 +- widgets/loopstationwidget.cpp | 6 +- widgets/mainwindow.cpp | 118 ++++-- widgets/settingsdialog.cpp | 16 +- widgets/settingsdialog.ui | 83 ++++- widgets/trackdeck.cpp | 5 +- 32 files changed, 1299 insertions(+), 167 deletions(-) rename widgets/{sequencerwidget.cpp => drumpadsequencerwidget.cpp} (78%) rename widgets/{sequencerwidget.h => drumpadsequencerwidget.h} (78%) rename widgets/{sequencerwidget.ui => drumpadsequencerwidget.ui} (99%) create mode 100644 widgets/drumpadsettingsdialog.cpp create mode 100644 widgets/drumpadsettingsdialog.h create mode 100644 widgets/drumpadsettingsdialog.ui diff --git a/DrumMachine.pro b/DrumMachine.pro index cab1ced..bb507c4 100755 --- a/DrumMachine.pro +++ b/DrumMachine.pro @@ -38,6 +38,8 @@ SOURCES += \ widgets/drumpadpresetdetailwidget.cpp \ widgets/drumpadsampleswidget.cpp \ widgets/drumpadsamplewidget.cpp \ + widgets/drumpadsequencerwidget.cpp \ + widgets/drumpadsettingsdialog.cpp \ widgets/drumpadwidget.cpp \ widgets/loopstationpresetdetailwidget.cpp \ widgets/loopstationsampleswidget.cpp \ @@ -48,7 +50,6 @@ SOURCES += \ widgets/miditabwidget.cpp \ widgets/previewwidget.cpp \ widgets/scratchwidget.cpp \ - widgets/sequencerwidget.cpp \ widgets/settingsdialog.cpp \ widgets/synthisizerwidget.cpp \ widgets/trackdeck.cpp @@ -80,6 +81,8 @@ HEADERS += \ widgets/drumpadpresetdetailwidget.h \ widgets/drumpadsampleswidget.h \ widgets/drumpadsamplewidget.h \ + widgets/drumpadsequencerwidget.h \ + widgets/drumpadsettingsdialog.h \ widgets/drumpadwidget.h \ widgets/loopstationpresetdetailwidget.h \ widgets/loopstationsampleswidget.h \ @@ -90,7 +93,6 @@ HEADERS += \ widgets/miditabwidget.h \ widgets/previewwidget.h \ widgets/scratchwidget.h \ - widgets/sequencerwidget.h \ widgets/settingsdialog.h \ widgets/synthisizerwidget.h \ widgets/trackdeck.h @@ -100,13 +102,14 @@ FORMS += \ widgets/drumpadpresetdetailwidget.ui \ widgets/drumpadsampleswidget.ui \ widgets/drumpadsamplewidget.ui \ + widgets/drumpadsequencerwidget.ui \ + widgets/drumpadsettingsdialog.ui \ widgets/drumpadwidget.ui \ widgets/loopstationpresetdetailwidget.ui \ widgets/loopstationsampleswidget.ui \ widgets/loopstationsamplewidget.ui \ widgets/loopstationwidget.ui \ widgets/mainwindow.ui \ - widgets/sequencerwidget.ui \ widgets/settingsdialog.ui \ widgets/synthisizerwidget.ui \ widgets/trackdeck.ui diff --git a/audiodecoder.cpp b/audiodecoder.cpp index d13ad42..c0dc84f 100644 --- a/audiodecoder.cpp +++ b/audiodecoder.cpp @@ -8,7 +8,7 @@ #include "audioformat.h" AudioDecoder::AudioDecoder(QObject *parent) : - QObject(parent) + QObject{parent} { QObject::connect(&m_decoder, qOverload(&QAudioDecoder::error), this, &AudioDecoder::error); diff --git a/drummachinesettings.cpp b/drummachinesettings.cpp index a57c9f0..7285620 100644 --- a/drummachinesettings.cpp +++ b/drummachinesettings.cpp @@ -46,6 +46,16 @@ void DrumMachineSettings::setLastAudioDevice(const QString &lastAudioDevice) setValue("lastAudioDevice", lastAudioDevice); } +bool DrumMachineSettings::autoOpenAudioDevice() const +{ + return value("autoOpenAudioDevice").toBool(); +} + +void DrumMachineSettings::setAutoOpenAudioDevice(bool autoOpenAudioDevice) +{ + setValue("autoOpenAudioDevice", autoOpenAudioDevice); +} + unsigned int DrumMachineSettings::framesPerBuffer() const { return value("framesPerBuffer", 32).toUInt(); @@ -66,6 +76,16 @@ void DrumMachineSettings::setLastMidiInDevice(const QString &lastMidiInDevice) setValue("lastMidiInDevice", lastMidiInDevice); } +bool DrumMachineSettings::autoOpenMidiIn() const +{ + return value("autoOpenMidiIn").toBool(); +} + +void DrumMachineSettings::setAutoOpenMidiIn(bool autoOpenMidiIn) +{ + setValue("autoOpenMidiIn", autoOpenMidiIn); +} + QString DrumMachineSettings::lastMidiOutDevice() const { return value("lastMidiOutDevice").toString(); @@ -76,6 +96,31 @@ void DrumMachineSettings::setLastMidiOutDevice(const QString &lastMidiOutDevice) setValue("lastMidiOutDevice", lastMidiOutDevice); } +bool DrumMachineSettings::autoOpenMidiOut() const +{ + return value("autoOpenMidiOut").toBool(); +} + +void DrumMachineSettings::setAutoOpenMidiOut(bool autoOpenMidiOut) +{ + setValue("autoOpenMidiOut", autoOpenMidiOut); +} + +quint8 DrumMachineSettings::colorOff() const +{ + return value("colorOff", defaultColorOff()).value(); +} + +quint8 DrumMachineSettings::defaultColorOff() const +{ + return 0; +} + +void DrumMachineSettings::setColorOff(quint8 colorOff) +{ + setValue("colorOff", colorOff); +} + MidiLearnSetting DrumMachineSettings::tabWidget(quint8 index) const { return learnSetting(QString{"tabWidget%0"}.arg(index)); @@ -86,6 +131,21 @@ void DrumMachineSettings::setTabWidget(quint8 index, const MidiLearnSetting &val setLearnSetting(QString{"tabWidget%0"}.arg(index), value); } +quint8 DrumMachineSettings::colorTabWidget() const +{ + return value("colorTabWidget", defaultColorTabWidget()).value(); +} + +quint8 DrumMachineSettings::defaultColorTabWidget() const +{ + return 3; +} + +void DrumMachineSettings::setColorTabWidget(quint8 colorTabWidget) +{ + setValue("colorTabWidget", colorTabWidget); +} + QString DrumMachineSettings::drumpadLastPresetId() const { return value("drumpad/lastPresetId").toString(); @@ -106,6 +166,21 @@ void DrumMachineSettings::setDrumpadPrevPreset(const MidiLearnSetting &value) setLearnSetting("drumpad/prevPreset", value); } +quint8 DrumMachineSettings::drumpadColorPrevPreset() const +{ + return value("drumpad/colorPrevPreset", defaultDrumpadColorPrevPreset()).value(); +} + +quint8 DrumMachineSettings::defaultDrumpadColorPrevPreset() const +{ + return 127; +} + +void DrumMachineSettings::setDrumpadColorPrevPreset(quint8 drumpadColorPrevPreset) +{ + setValue("drumpad/colorPrevPreset", drumpadColorPrevPreset); +} + MidiLearnSetting DrumMachineSettings::drumpadNextPreset() const { return learnSetting("drumpad/nextPreset"); @@ -116,6 +191,21 @@ void DrumMachineSettings::setDrumpadNextPreset(const MidiLearnSetting &value) setLearnSetting("drumpad/nextPreset", value); } +quint8 DrumMachineSettings::drumpadColorNextPreset() const +{ + return value("drumpad/colorNextPreset", defaultDrumpadColorNextPreset()).value(); +} + +quint8 DrumMachineSettings::defaultDrumpadColorNextPreset() const +{ + return 127; +} + +void DrumMachineSettings::setDrumpadColorNextPreset(quint8 drumpadColorNextPreset) +{ + setValue("drumpad/colorNextPreset", drumpadColorNextPreset); +} + MidiLearnSetting DrumMachineSettings::drumpadPrevSequence() const { return learnSetting("drumpad/prevSequence"); @@ -126,6 +216,21 @@ void DrumMachineSettings::setDrumpadPrevSequence(const MidiLearnSetting &value) setLearnSetting("drumpad/prevSequence", value); } +quint8 DrumMachineSettings::drumpadColorPrevSequence() const +{ + return value("drumpad/colorPrevSequence", defaultDrumpadColorPrevSequence()).value(); +} + +quint8 DrumMachineSettings::defaultDrumpadColorPrevSequence() const +{ + return 127; +} + +void DrumMachineSettings::setDrumpadColorPrevSequence(quint8 drumpadColorPrevSequence) +{ + setValue("drumpad/colorPrevSequence", drumpadColorPrevSequence); +} + MidiLearnSetting DrumMachineSettings::drumpadNextSequence() const { return learnSetting("drumpad/nextSequence"); @@ -136,6 +241,21 @@ void DrumMachineSettings::setDrumpadNextSequence(const MidiLearnSetting &value) setLearnSetting("drumpad/nextSequence", value); } +quint8 DrumMachineSettings::drumpadColorNextSequence() const +{ + return value("drumpad/colorNextSequence", defaultDrumpadColorNextSequence()).value(); +} + +quint8 DrumMachineSettings::defaultDrumpadColorNextSequence() const +{ + return 127; +} + +void DrumMachineSettings::setDrumpadColorNextSequence(quint8 drumpadColorNextSequence) +{ + setValue("drumpad/colorNextSequence", drumpadColorNextSequence); +} + MidiLearnSetting DrumMachineSettings::drumpadPlayPause() const { return learnSetting("drumpad/playPause"); @@ -146,14 +266,94 @@ void DrumMachineSettings::setDrumpadPlayPause(const MidiLearnSetting &value) setLearnSetting("drumpad/playPause", value); } -MidiLearnSetting DrumMachineSettings::drumpadStop() const +quint8 DrumMachineSettings::drumpadColorPlayPause() const { - return learnSetting("drumpad/stop"); + return value("drumpad/colorPlayPause", defaultDrumpadColorPlayPause()).value(); } -void DrumMachineSettings::setDrumpadStop(const MidiLearnSetting &value) +quint8 DrumMachineSettings::defaultDrumpadColorPlayPause() const { - setLearnSetting("drumpad/stop", value); + return 3; +} + +void DrumMachineSettings::setDrumpadColorPlayPause(quint8 drumpadColorPlayPause) +{ + setValue("drumpad/colorPlayPause", drumpadColorPlayPause); +} + +MidiLearnSetting DrumMachineSettings::drumpadStopSequence() const +{ + return learnSetting("drumpad/stopSequence"); +} + +void DrumMachineSettings::setDrumpadStopSequence(const MidiLearnSetting &value) +{ + setLearnSetting("drumpad/stopSequence", value); +} + +quint8 DrumMachineSettings::drumpadColorStopSequence() const +{ + return value("drumpad/colorStopSequence", defaultDrumpadColorStopSequence()).value(); +} + +quint8 DrumMachineSettings::defaultDrumpadColorStopSequence() const +{ + return 60; +} + +void DrumMachineSettings::setDrumpadColorStopSequence(quint8 drumpadColorStopSequence) +{ + setValue("drumpad/colorStopSequence", drumpadColorStopSequence); +} + +MidiLearnSetting DrumMachineSettings::drumpadSwap() const +{ + return learnSetting("drumpad/swap"); +} + +void DrumMachineSettings::setDrumpadSwap(const MidiLearnSetting &value) +{ + setLearnSetting("drumpad/swap", value); +} + +quint8 DrumMachineSettings::drumpadColorSwap() const +{ + return value("drumpad/colorSwap", defaultDrumpadColorSwap()).value(); +} + +quint8 DrumMachineSettings::defaultDrumpadColorSwap() const +{ + return 127; +} + +void DrumMachineSettings::setDrumpadColorSwap(quint8 drumpadColorSwap) +{ + setValue("drumpad/colorSwap", drumpadColorSwap); +} + +MidiLearnSetting DrumMachineSettings::drumpadStopAll() const +{ + return learnSetting("drumpad/stopAll"); +} + +void DrumMachineSettings::setDrumpadStopAll(const MidiLearnSetting &value) +{ + setLearnSetting("drumpad/stopAll", value); +} + +quint8 DrumMachineSettings::drumpadColorStopAll() const +{ + return value("drumpad/colorStopAll", defaultDrumpadColorStopAll()).value(); +} + +quint8 DrumMachineSettings::defaultDrumpadColorStopAll() const +{ + return 60; +} + +void DrumMachineSettings::setDrumpadColorStopAll(quint8 drumpadColorStopAll) +{ + setValue("drumpad/colorStopAll", drumpadColorStopAll); } MidiLearnSetting DrumMachineSettings::drumpadSample(quint8 pad) const @@ -196,6 +396,26 @@ void DrumMachineSettings::setLoopstationNextPreset(const MidiLearnSetting &value setLearnSetting("loopstation/nextPreset", value); } +MidiLearnSetting DrumMachineSettings::loopstationPlayPause() const +{ + return learnSetting("loopstation/playPause"); +} + +void DrumMachineSettings::setLoopstationPlayPause(const MidiLearnSetting &value) +{ + setLearnSetting("loopstation/playPause", value); +} + +MidiLearnSetting DrumMachineSettings::loopstationStop() const +{ + return learnSetting("loopstation/stop"); +} + +void DrumMachineSettings::setLoopstationStop(const MidiLearnSetting &value) +{ + setLearnSetting("loopstation/stop", value); +} + MidiLearnSetting DrumMachineSettings::loopstationSample(quint8 pad) const { return learnSetting(QString{"loopstation/pad%0"}.arg(pad)); diff --git a/drummachinesettings.h b/drummachinesettings.h index ef640bc..8d50711 100644 --- a/drummachinesettings.h +++ b/drummachinesettings.h @@ -20,18 +20,35 @@ public: QString lastAudioDevice() const; void setLastAudioDevice(const QString &lastAudioDevice); + bool autoOpenAudioDevice() const; + void setAutoOpenAudioDevice(bool autoOpenAudioDevice); + unsigned int framesPerBuffer() const; void setFramesPerBuffer(unsigned int framesPerBuffer); QString lastMidiInDevice() const; void setLastMidiInDevice(const QString &lastMidiInDevice); + bool autoOpenMidiIn() const; + void setAutoOpenMidiIn(bool autoOpenMidiIn); + QString lastMidiOutDevice() const; void setLastMidiOutDevice(const QString &lastMidiOutDevice); + bool autoOpenMidiOut() const; + void setAutoOpenMidiOut(bool autoOpenMidiOut); + + quint8 colorOff() const; + quint8 defaultColorOff() const; + void setColorOff(quint8 colorOff); + MidiLearnSetting tabWidget(quint8 index) const; void setTabWidget(quint8 index, const MidiLearnSetting &value); + quint8 colorTabWidget() const; + quint8 defaultColorTabWidget() const; + void setColorTabWidget(quint8 colorTabWidget); + QString drumpadLastPresetId() const; @@ -40,20 +57,58 @@ public: MidiLearnSetting drumpadPrevPreset() const; void setDrumpadPrevPreset(const MidiLearnSetting &value); + quint8 drumpadColorPrevPreset() const; + quint8 defaultDrumpadColorPrevPreset() const; + void setDrumpadColorPrevPreset(quint8 drumpadColorPrevPreset); + MidiLearnSetting drumpadNextPreset() const; void setDrumpadNextPreset(const MidiLearnSetting &value); + quint8 drumpadColorNextPreset() const; + quint8 defaultDrumpadColorNextPreset() const; + void setDrumpadColorNextPreset(quint8 drumpadColorNextPreset); + MidiLearnSetting drumpadPrevSequence() const; void setDrumpadPrevSequence(const MidiLearnSetting &value); + quint8 drumpadColorPrevSequence() const; + quint8 defaultDrumpadColorPrevSequence() const; + void setDrumpadColorPrevSequence(quint8 drumpadColorPrevSequence); + MidiLearnSetting drumpadNextSequence() const; void setDrumpadNextSequence(const MidiLearnSetting &value); + quint8 drumpadColorNextSequence() const; + quint8 defaultDrumpadColorNextSequence() const; + void setDrumpadColorNextSequence(quint8 drumpadColorNextSequence); + MidiLearnSetting drumpadPlayPause() const; void setDrumpadPlayPause(const MidiLearnSetting &value); - MidiLearnSetting drumpadStop() const; - void setDrumpadStop(const MidiLearnSetting &value); + quint8 drumpadColorPlayPause() const; + quint8 defaultDrumpadColorPlayPause() const; + void setDrumpadColorPlayPause(quint8 drumpadColorPlayPause); + + MidiLearnSetting drumpadStopSequence() const; + void setDrumpadStopSequence(const MidiLearnSetting &value); + + quint8 drumpadColorStopSequence() const; + quint8 defaultDrumpadColorStopSequence() const; + void setDrumpadColorStopSequence(quint8 drumpadColorStopSequence); + + MidiLearnSetting drumpadSwap() const; + void setDrumpadSwap(const MidiLearnSetting &value); + + quint8 drumpadColorSwap() const; + quint8 defaultDrumpadColorSwap() const; + void setDrumpadColorSwap(quint8 drumpadColorSwap); + + MidiLearnSetting drumpadStopAll() const; + void setDrumpadStopAll(const MidiLearnSetting &value); + + quint8 drumpadColorStopAll() const; + quint8 defaultDrumpadColorStopAll() const; + void setDrumpadColorStopAll(quint8 drumpadColorStopAll); MidiLearnSetting drumpadSample(quint8 pad) const; void setDrumpadSample(quint8 pad, const MidiLearnSetting &value); @@ -69,6 +124,12 @@ public: MidiLearnSetting loopstationNextPreset() const; void setLoopstationNextPreset(const MidiLearnSetting &value); + MidiLearnSetting loopstationPlayPause() const; + void setLoopstationPlayPause(const MidiLearnSetting &value); + + MidiLearnSetting loopstationStop() const; + void setLoopstationStop(const MidiLearnSetting &value); + MidiLearnSetting loopstationSample(quint8 pad) const; void setLoopstationSample(quint8 pad, const MidiLearnSetting &value); diff --git a/midioutwrapper.cpp b/midioutwrapper.cpp index 53d5904..92c5ac5 100644 --- a/midioutwrapper.cpp +++ b/midioutwrapper.cpp @@ -4,7 +4,8 @@ #include "midicontainers.h" -MidiOutWrapper::MidiOutWrapper(RtMidi::Api api, const QString &clientName) : +MidiOutWrapper::MidiOutWrapper(RtMidi::Api api, const QString &clientName, QObject *parent) : + QObject{parent}, midiOut{api, clientName.toStdString()} { } diff --git a/midioutwrapper.h b/midioutwrapper.h index 99ce7ee..6914b3b 100644 --- a/midioutwrapper.h +++ b/midioutwrapper.h @@ -1,16 +1,18 @@ #pragma once +#include #include #include "rtmidi/RtMidi.h" namespace midi { struct MidiMessage; } -class MidiOutWrapper +class MidiOutWrapper : public QObject { public: MidiOutWrapper(RtMidi::Api api = RtMidi::UNSPECIFIED, - const QString &clientName = "RtMidi Input Client"); + const QString &clientName = "RtMidi Input Client", + QObject *parent = nullptr); void openPort(unsigned int portNumber, const QString &portName); void openVirtualPort(const QString &portName); diff --git a/widgets/drumpadpresetdetailwidget.cpp b/widgets/drumpadpresetdetailwidget.cpp index ed2f01d..a4bf5a2 100755 --- a/widgets/drumpadpresetdetailwidget.cpp +++ b/widgets/drumpadpresetdetailwidget.cpp @@ -5,7 +5,8 @@ DrumPadPresetDetailWidget::DrumPadPresetDetailWidget(QWidget *parent) : QScrollArea{parent}, - m_ui{std::make_unique()} + m_ui{std::make_unique()}, + m_tagsModel{this} { m_ui->setupUi(this); diff --git a/widgets/drumpadsampleswidget.cpp b/widgets/drumpadsampleswidget.cpp index 7b0091e..76f6943 100755 --- a/widgets/drumpadsampleswidget.cpp +++ b/widgets/drumpadsampleswidget.cpp @@ -8,6 +8,8 @@ #include "audioformat.h" #include "midicontainers.h" +#include "drummachinesettings.h" +#include "drumpadsettingsdialog.h" DrumPadSamplesWidget::DrumPadSamplesWidget(QWidget *parent) : QWidget{parent}, @@ -15,8 +17,8 @@ DrumPadSamplesWidget::DrumPadSamplesWidget(QWidget *parent) : { m_ui->setupUi(this); - connect(m_ui->checkBox, &QCheckBox::toggled, this, &DrumPadSamplesWidget::updateWidgets); - + connect(m_ui->pushButtonSettings, &QAbstractButton::pressed, this, &DrumPadSamplesWidget::showSettings); + connect(m_ui->pushButtonSwap, &QAbstractButton::toggled, this, &DrumPadSamplesWidget::updateWidgets); connect(m_ui->pushButtonStopAll, &QAbstractButton::pressed, this, &DrumPadSamplesWidget::stopAll); quint8 padNr{}; @@ -32,6 +34,14 @@ DrumPadSamplesWidget::~DrumPadSamplesWidget() = default; void DrumPadSamplesWidget::loadSettings(DrumMachineSettings &settings) { + m_settings = &settings; + + m_ui->pushButtonSwap->setLearnSetting(settings.drumpadSwap()); + m_ui->pushButtonStopAll->setLearnSetting(settings.drumpadStopAll()); + + connect(m_ui->pushButtonSwap, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadSwap); + connect(m_ui->pushButtonStopAll, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadStopAll); + for (DrumPadSampleWidget &widget : getWidgets()) widget.loadSettings(settings); } @@ -45,11 +55,8 @@ void DrumPadSamplesWidget::setPreset(const drumpad_presets::Preset &preset) void DrumPadSamplesWidget::midiReceived(const midi::MidiMessage &message) { - if (message == midi::MidiMessage{.channel=0,.cmd=midi::Command::ControlChange,.flag=true,.note=64,.velocity=127}) - { - m_ui->checkBox->toggle(); - return; - } + m_ui->pushButtonSwap->midiReceived(message); + m_ui->pushButtonStopAll->midiReceived(message); for (DrumPadSampleWidget &widget : getWidgets()) widget.midiReceived(message); @@ -75,14 +82,46 @@ void DrumPadSamplesWidget::injectDecodingThread(QThread &thread) void DrumPadSamplesWidget::unsendColors() { + const quint8 color = m_settings ? m_settings->colorOff() : quint8{0}; + + emit sendMidi(midi::MidiMessage { + .channel = m_ui->pushButtonSwap->learnSetting().channel, + .cmd = m_ui->pushButtonSwap->learnSetting().cmd, + .flag = true, + .note = m_ui->pushButtonSwap->learnSetting().note, + .velocity = color + }); + emit sendMidi(midi::MidiMessage { + .channel = m_ui->pushButtonStopAll->learnSetting().channel, + .cmd = m_ui->pushButtonStopAll->learnSetting().cmd, + .flag = true, + .note = m_ui->pushButtonStopAll->learnSetting().note, + .velocity = color + }); + for (DrumPadSampleWidget &widget : getWidgets()) widget.unsendColor(); } void DrumPadSamplesWidget::sendColors() { + emit sendMidi(midi::MidiMessage { + .channel = m_ui->pushButtonSwap->learnSetting().channel, + .cmd = m_ui->pushButtonSwap->learnSetting().cmd, + .flag = true, + .note = m_ui->pushButtonSwap->learnSetting().note, + .velocity = m_settings ? m_settings->drumpadColorSwap() : quint8{127} + }); + emit sendMidi(midi::MidiMessage { + .channel = m_ui->pushButtonStopAll->learnSetting().channel, + .cmd = m_ui->pushButtonStopAll->learnSetting().cmd, + .flag = true, + .note = m_ui->pushButtonStopAll->learnSetting().note, + .velocity = m_settings ? m_settings->drumpadColorStopAll() : quint8{127} + }); + for (DrumPadSampleWidget &widget : getWidgets()) - widget.sendColor(); + widget.sendColor(true); } void DrumPadSamplesWidget::sequencerTriggerSample(int index) @@ -96,6 +135,18 @@ void DrumPadSamplesWidget::sequencerTriggerSample(int index) widgets[index].get().pressed(); } +void DrumPadSamplesWidget::showSettings() +{ + if (!m_settings) + { + qWarning() << "settings are missing"; + return; + } + + DrumPadSettingsDialog dialog{*m_settings, this}; + dialog.exec(); +} + void DrumPadSamplesWidget::chokeTriggered(int choke) { for (DrumPadSampleWidget &widget : getWidgets()) @@ -114,7 +165,7 @@ void DrumPadSamplesWidget::updateWidgets() auto files = *m_preset.files; - if (m_ui->checkBox->isChecked()) + if (m_ui->pushButtonSwap->isChecked()) for (int i = 0; i < 12; i++) std::swap(files[i], files[i+12]); diff --git a/widgets/drumpadsampleswidget.h b/widgets/drumpadsampleswidget.h index 0f59aee..1bc5af6 100755 --- a/widgets/drumpadsampleswidget.h +++ b/widgets/drumpadsampleswidget.h @@ -44,6 +44,7 @@ public slots: void sequencerTriggerSample(int index); private slots: + void showSettings(); void chokeTriggered(int choke); void updateWidgets(); void stopAll(); @@ -53,5 +54,7 @@ private: const std::unique_ptr m_ui; + DrumMachineSettings *m_settings{}; + drumpad_presets::Preset m_preset; }; diff --git a/widgets/drumpadsampleswidget.ui b/widgets/drumpadsampleswidget.ui index 1b4dc67..1f89042 100755 --- a/widgets/drumpadsampleswidget.ui +++ b/widgets/drumpadsampleswidget.ui @@ -73,6 +73,19 @@ + + + + + 32 + 16777215 + + + + ⚙️ + + + @@ -87,14 +100,17 @@ - + - Swap left/right + Swap Left/Right + + + true - + Stop all @@ -337,6 +353,11 @@ + + MidiButton + QPushButton +
widgets/midibutton.h
+
DrumPadSampleWidget QFrame diff --git a/widgets/drumpadsamplewidget.cpp b/widgets/drumpadsamplewidget.cpp index 2edd454..8bdc213 100755 --- a/widgets/drumpadsamplewidget.cpp +++ b/widgets/drumpadsamplewidget.cpp @@ -20,7 +20,8 @@ QString toString(bool value) { return value?"true":"false"; } DrumPadSampleWidget::DrumPadSampleWidget(QWidget *parent) : QFrame{parent}, - m_ui{std::make_unique()} + m_ui{std::make_unique()}, + m_player{this} { m_ui->setupUi(this); @@ -161,17 +162,20 @@ void DrumPadSampleWidget::unsendColor() { m_sendColors = false; + const quint8 color = m_settings ? m_settings->colorOff() : quint8{0}; + 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 + .velocity = color }); - m_lastMidiColor = 0; + + m_lastMidiColor = color; } -void DrumPadSampleWidget::sendColor() +void DrumPadSampleWidget::sendColor(bool force) { m_sendColors = true; @@ -181,25 +185,24 @@ void DrumPadSampleWidget::sendColor() { const auto &color = *m_file->color; if (color == "purple") - newColor = m_player.playing() ? 43 : 18; + newColor = m_player.playing() ? 56 : 59; else if (color == "red") - newColor = m_player.playing() ? 3 : 1; + newColor = m_player.playing() ? 4 : 7; else if (color == "yellow") - newColor = m_player.playing() ? 58 : 33; + newColor = m_player.playing() ? 12 : 15; else if (color == "green") - newColor = m_player.playing() ? 56 : 16; + newColor = m_player.playing() ? 20 : 23; else if (color == "blue") - newColor = m_player.playing() ? 49 : 51; + newColor = m_player.playing() ? 44 : 47; else - goto noColor; + newColor = m_player.playing() ? 127 : 1; } else { -noColor: newColor = 0; } - if (newColor != m_lastMidiColor) + if (force || newColor != m_lastMidiColor) { emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonPlay->learnSetting().channel, @@ -253,7 +256,7 @@ void DrumPadSampleWidget::updateStatus() } if (m_sendColors) - sendColor(); + sendColor(false); if (m_reply) { diff --git a/widgets/drumpadsamplewidget.h b/widgets/drumpadsamplewidget.h index e4fd002..3e248fc 100755 --- a/widgets/drumpadsamplewidget.h +++ b/widgets/drumpadsamplewidget.h @@ -52,7 +52,7 @@ public: void midiReceived(const midi::MidiMessage &message); void unsendColor(); - void sendColor(); + void sendColor(bool force); signals: void chokeTriggered(int choke); diff --git a/widgets/sequencerwidget.cpp b/widgets/drumpadsequencerwidget.cpp similarity index 78% rename from widgets/sequencerwidget.cpp rename to widgets/drumpadsequencerwidget.cpp index 6bfc576..4402d9b 100755 --- a/widgets/sequencerwidget.cpp +++ b/widgets/drumpadsequencerwidget.cpp @@ -1,5 +1,5 @@ -#include "sequencerwidget.h" -#include "ui_sequencerwidget.h" +#include "drumpadsequencerwidget.h" +#include "ui_drumpadsequencerwidget.h" #include @@ -9,80 +9,85 @@ #include "drummachinesettings.h" #include "midicontainers.h" -SequencerWidget::SequencerWidget(QWidget *parent) : +DrumPadSequencerWidget::DrumPadSequencerWidget(QWidget *parent) : QWidget{parent}, - m_ui{std::make_unique()} + m_ui{std::make_unique()}, + m_timer{this} { m_ui->setupUi(this); - connect(m_ui->spinBoxTempo, qOverload(&QSpinBox::valueChanged), this, &SequencerWidget::tempoChanged); + connect(m_ui->spinBoxTempo, qOverload(&QSpinBox::valueChanged), this, &DrumPadSequencerWidget::tempoChanged); - connect(m_ui->comboBoxSequence, qOverload(&QComboBox::currentIndexChanged), this, &SequencerWidget::sequenceSelected); + connect(m_ui->comboBoxSequence, qOverload(&QComboBox::currentIndexChanged), this, &DrumPadSequencerWidget::sequenceSelected); - connect(m_ui->pushButtonUp, &QAbstractButton::pressed, this, &SequencerWidget::selectPrevSequence); - connect(m_ui->pushButtonDown, &QAbstractButton::pressed, this, &SequencerWidget::selectNextSequence); - connect(m_ui->pushButtonPlayPause, &QAbstractButton::pressed, this, &SequencerWidget::playPause); - connect(m_ui->pushButtonStop, &QAbstractButton::pressed, this, &SequencerWidget::stop); + connect(m_ui->pushButtonUp, &QAbstractButton::pressed, this, &DrumPadSequencerWidget::selectPrevSequence); + connect(m_ui->pushButtonDown, &QAbstractButton::pressed, this, &DrumPadSequencerWidget::selectNextSequence); + connect(m_ui->pushButtonPlayPause, &QAbstractButton::pressed, this, &DrumPadSequencerWidget::playPause); + connect(m_ui->pushButtonStop, &QAbstractButton::pressed, this, &DrumPadSequencerWidget::stop); connect(m_ui->horizontalSlider, &QSlider::valueChanged, this, [=](int value){ m_pos = value; updateStatusLabel(); }); - connect(&m_timer, &QTimer::timeout, this, &SequencerWidget::timeout); + connect(&m_timer, &QTimer::timeout, this, &DrumPadSequencerWidget::timeout); m_timer.setTimerType(Qt::PreciseTimer); updateStatusLabel(); } -SequencerWidget::~SequencerWidget() = default; +DrumPadSequencerWidget::~DrumPadSequencerWidget() = default; -void SequencerWidget::loadSettings(DrumMachineSettings &settings) +void DrumPadSequencerWidget::loadSettings(DrumMachineSettings &settings) { + m_settings = &settings; + m_ui->pushButtonUp->setLearnSetting(settings.drumpadPrevSequence()); m_ui->pushButtonDown->setLearnSetting(settings.drumpadNextSequence()); m_ui->pushButtonPlayPause->setLearnSetting(settings.drumpadPlayPause()); - m_ui->pushButtonStop->setLearnSetting(settings.drumpadStop()); + m_ui->pushButtonStop->setLearnSetting(settings.drumpadStopSequence()); 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); + connect(m_ui->pushButtonStop, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadStopSequence); } -void SequencerWidget::unsendColors() +void DrumPadSequencerWidget::unsendColors() { m_sendColors = false; + const quint8 color = m_settings ? m_settings->colorOff() : quint8{0}; + emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonUp->learnSetting().channel, .cmd = m_ui->pushButtonUp->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonUp->learnSetting().note, - .velocity = 0 + .velocity = color }); emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonDown->learnSetting().channel, .cmd = m_ui->pushButtonDown->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonDown->learnSetting().note, - .velocity = 0 + .velocity = color }); emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonPlayPause->learnSetting().channel, .cmd = m_ui->pushButtonPlayPause->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonPlayPause->learnSetting().note, - .velocity = 0 + .velocity = color }); emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonStop->learnSetting().channel, .cmd = m_ui->pushButtonStop->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonStop->learnSetting().note, - .velocity = 0 + .velocity = color }); } -void SequencerWidget::sendColors() +void DrumPadSequencerWidget::sendColors() { m_sendColors = true; @@ -91,32 +96,32 @@ void SequencerWidget::sendColors() .cmd = m_ui->pushButtonUp->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonUp->learnSetting().note, - .velocity = 127 + .velocity = m_settings ? m_settings->drumpadColorPrevSequence() : quint8{127} }); emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonDown->learnSetting().channel, .cmd = m_ui->pushButtonDown->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonDown->learnSetting().note, - .velocity = 127 + .velocity = m_settings ? m_settings->drumpadColorNextSequence() : quint8{127} }); emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonPlayPause->learnSetting().channel, .cmd = m_ui->pushButtonPlayPause->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonPlayPause->learnSetting().note, - .velocity = 60 + .velocity = m_settings ? m_settings->drumpadColorPlayPause() : quint8{3} }); emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonStop->learnSetting().channel, .cmd = m_ui->pushButtonStop->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonStop->learnSetting().note, - .velocity = 3 + .velocity = m_settings ? m_settings->drumpadColorStopSequence() : quint8{60} }); } -void SequencerWidget::setPreset(const drumpad_presets::Preset &preset) +void DrumPadSequencerWidget::setPreset(const drumpad_presets::Preset &preset) { if (preset.tempo) m_ui->spinBoxTempo->setValue(*preset.tempo); @@ -155,7 +160,7 @@ void SequencerWidget::setPreset(const drumpad_presets::Preset &preset) sequenceSelected(); } -void SequencerWidget::midiReceived(const midi::MidiMessage &message) +void DrumPadSequencerWidget::midiReceived(const midi::MidiMessage &message) { m_ui->pushButtonUp->midiReceived(message); m_ui->pushButtonDown->midiReceived(message); @@ -163,7 +168,7 @@ void SequencerWidget::midiReceived(const midi::MidiMessage &message) m_ui->pushButtonStop->midiReceived(message); } -void SequencerWidget::playPause() +void DrumPadSequencerWidget::playPause() { if (m_timer.isActive()) { @@ -177,7 +182,7 @@ void SequencerWidget::playPause() } } -void SequencerWidget::stop() +void DrumPadSequencerWidget::stop() { m_timer.stop(); m_ui->pushButtonPlayPause->setText(tr("▶")); @@ -186,12 +191,12 @@ void SequencerWidget::stop() updateStatusLabel(); } -void SequencerWidget::tempoChanged(int tempo) +void DrumPadSequencerWidget::tempoChanged(int tempo) { m_timer.setInterval(1000. * 60. / tempo / 4.); } -void SequencerWidget::sequenceSelected() +void DrumPadSequencerWidget::sequenceSelected() { const auto index = m_ui->comboBoxSequence->currentIndex(); @@ -210,7 +215,7 @@ void SequencerWidget::sequenceSelected() updateStatusLabel(); } -void SequencerWidget::timeout() +void DrumPadSequencerWidget::timeout() { if (m_selectedSequence && m_selectedSequence->pads) { @@ -244,18 +249,18 @@ void SequencerWidget::timeout() updateStatusLabel(); } -void SequencerWidget::updateStatusLabel() +void DrumPadSequencerWidget::updateStatusLabel() { m_ui->labelStatus->setText(QString{"%0 / %1"}.arg(m_pos+1).arg(m_selectedSequence && m_selectedSequence->sequencerSize ? *m_selectedSequence->sequencerSize-1 : -1)); } -void SequencerWidget::selectPrevSequence() +void DrumPadSequencerWidget::selectPrevSequence() { if (const auto index = m_ui->comboBoxSequence->currentIndex(); index > 0) m_ui->comboBoxSequence->setCurrentIndex(index - 1); } -void SequencerWidget::selectNextSequence() +void DrumPadSequencerWidget::selectNextSequence() { if (const auto index = m_ui->comboBoxSequence->currentIndex(); index + 1 < m_ui->comboBoxSequence->count()) m_ui->comboBoxSequence->setCurrentIndex(index + 1); diff --git a/widgets/sequencerwidget.h b/widgets/drumpadsequencerwidget.h similarity index 78% rename from widgets/sequencerwidget.h rename to widgets/drumpadsequencerwidget.h index d191285..96f71f0 100755 --- a/widgets/sequencerwidget.h +++ b/widgets/drumpadsequencerwidget.h @@ -8,18 +8,18 @@ #include class QLabel; -namespace Ui { class SequencerWidget; } +namespace Ui { class DrumPadSequencerWidget; } namespace drumpad_presets { struct Preset; struct Sequence; } class DrumMachineSettings; namespace midi { struct MidiMessage; } -class SequencerWidget : public QWidget +class DrumPadSequencerWidget : public QWidget { Q_OBJECT public: - explicit SequencerWidget(QWidget *parent = nullptr); - ~SequencerWidget() override; + explicit DrumPadSequencerWidget(QWidget *parent = nullptr); + ~DrumPadSequencerWidget() override; void loadSettings(DrumMachineSettings &settings); void unsendColors(); @@ -48,7 +48,9 @@ private slots: void selectNextSequence(); private: - const std::unique_ptr m_ui; + const std::unique_ptr m_ui; + + DrumMachineSettings *m_settings{}; std::vector m_sequences; const drumpad_presets::Sequence *m_selectedSequence{}; diff --git a/widgets/sequencerwidget.ui b/widgets/drumpadsequencerwidget.ui similarity index 99% rename from widgets/sequencerwidget.ui rename to widgets/drumpadsequencerwidget.ui index afd3310..30da36d 100755 --- a/widgets/sequencerwidget.ui +++ b/widgets/drumpadsequencerwidget.ui @@ -1,7 +1,7 @@ - SequencerWidget - + DrumPadSequencerWidget + 0 diff --git a/widgets/drumpadsettingsdialog.cpp b/widgets/drumpadsettingsdialog.cpp new file mode 100644 index 0000000..a7f7574 --- /dev/null +++ b/widgets/drumpadsettingsdialog.cpp @@ -0,0 +1,102 @@ +#include "drumpadsettingsdialog.h" +#include "ui_drumpadsettingsdialog.h" + +#include +#include + +#include "drummachinesettings.h" + +DrumPadSettingsDialog::DrumPadSettingsDialog(DrumMachineSettings &settings, QWidget *parent) : + QDialog{parent}, + m_ui{std::make_unique()}, + m_settings{settings} +{ + m_ui->setupUi(this); + + connect(m_ui->buttonBox, &QDialogButtonBox::clicked, this, &DrumPadSettingsDialog::buttonClicked); + + resetFields(); +} + +DrumPadSettingsDialog::~DrumPadSettingsDialog() = default; + +void DrumPadSettingsDialog::accept() +{ + if (const quint8 colorPrevPreset = m_ui->spinBoxColorPrevPreset->value(); + m_settings.drumpadColorPrevPreset() != colorPrevPreset) + m_settings.setDrumpadColorPrevPreset(colorPrevPreset); + + if (const quint8 colorNextPreset = m_ui->spinBoxColorNextPreset->value(); + m_settings.drumpadColorNextPreset() != colorNextPreset) + m_settings.setDrumpadColorNextPreset(colorNextPreset); + + if (const quint8 colorPrevSequence = m_ui->spinBoxColorPrevSequence->value(); + m_settings.drumpadColorPrevSequence() != colorPrevSequence) + m_settings.setDrumpadColorPrevSequence(colorPrevSequence); + + if (const quint8 colorNextSequence = m_ui->spinBoxColorNextSequence->value(); + m_settings.drumpadColorNextSequence() != colorNextSequence) + m_settings.setDrumpadColorNextSequence(colorNextSequence); + + if (const quint8 colorPlayPause = m_ui->spinBoxColorPlayPause->value(); + m_settings.drumpadColorPlayPause() != colorPlayPause) + m_settings.setDrumpadColorPlayPause(colorPlayPause); + + if (const quint8 colorStopSequence = m_ui->spinBoxColorStopSequence->value(); + m_settings.drumpadColorStopSequence() != colorStopSequence) + m_settings.setDrumpadColorStopSequence(colorStopSequence); + + if (const quint8 colorSwap = m_ui->spinBoxColorSwap->value(); + m_settings.drumpadColorSwap() != colorSwap) + m_settings.setDrumpadColorSwap(colorSwap); + + if (const quint8 colorStopAll = m_ui->spinBoxColorStopAll->value(); + m_settings.drumpadColorStopAll() != colorStopAll) + m_settings.setDrumpadColorStopAll(colorStopAll); + + QDialog::accept(); +} + +void DrumPadSettingsDialog::buttonClicked(QAbstractButton *button) +{ + if (!button) + { + qWarning() << "invalid button"; + return; + } + + switch (m_ui->buttonBox->standardButton(button)) + { + case QDialogButtonBox::Reset: + resetFields(); + return; + case QDialogButtonBox::RestoreDefaults: + restoreDefaults(); + return; + default:; + } +} + +void DrumPadSettingsDialog::resetFields() +{ + m_ui->spinBoxColorPrevPreset->setValue(m_settings.drumpadColorPrevPreset()); + m_ui->spinBoxColorNextPreset->setValue(m_settings.drumpadColorNextPreset()); + m_ui->spinBoxColorPrevSequence->setValue(m_settings.drumpadColorPrevSequence()); + m_ui->spinBoxColorNextSequence->setValue(m_settings.drumpadColorNextSequence()); + m_ui->spinBoxColorPlayPause->setValue(m_settings.drumpadColorPlayPause()); + m_ui->spinBoxColorStopSequence->setValue(m_settings.drumpadColorStopSequence()); + m_ui->spinBoxColorSwap->setValue(m_settings.drumpadColorSwap()); + m_ui->spinBoxColorStopAll->setValue(m_settings.drumpadColorStopAll()); +} + +void DrumPadSettingsDialog::restoreDefaults() +{ + m_ui->spinBoxColorPrevPreset->setValue(m_settings.defaultDrumpadColorPrevPreset()); + m_ui->spinBoxColorNextPreset->setValue(m_settings.defaultDrumpadColorNextPreset()); + m_ui->spinBoxColorPrevSequence->setValue(m_settings.defaultDrumpadColorPrevSequence()); + m_ui->spinBoxColorNextSequence->setValue(m_settings.defaultDrumpadColorNextSequence()); + m_ui->spinBoxColorPlayPause->setValue(m_settings.defaultDrumpadColorPlayPause()); + m_ui->spinBoxColorStopSequence->setValue(m_settings.defaultDrumpadColorStopSequence()); + m_ui->spinBoxColorSwap->setValue(m_settings.defaultDrumpadColorSwap()); + m_ui->spinBoxColorStopAll->setValue(m_settings.defaultDrumpadColorStopAll()); +} diff --git a/widgets/drumpadsettingsdialog.h b/widgets/drumpadsettingsdialog.h new file mode 100644 index 0000000..c889533 --- /dev/null +++ b/widgets/drumpadsettingsdialog.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +#include + +namespace Ui { class DrumPadSettingsDialog; } +class DrumMachineSettings; +class QAbstractButton; + +class DrumPadSettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit DrumPadSettingsDialog(DrumMachineSettings &settings, QWidget *parent = nullptr); + ~DrumPadSettingsDialog() override; + +public slots: + void accept() override; + +private slots: + void buttonClicked(QAbstractButton *button); + void resetFields(); + void restoreDefaults(); + +private: + const std::unique_ptr m_ui; + + DrumMachineSettings &m_settings; +}; diff --git a/widgets/drumpadsettingsdialog.ui b/widgets/drumpadsettingsdialog.ui new file mode 100644 index 0000000..9f7c8d8 --- /dev/null +++ b/widgets/drumpadsettingsdialog.ui @@ -0,0 +1,340 @@ + + + DrumPadSettingsDialog + + + + 0 + 0 + 400 + 326 + + + + Dialog + + + + + + + + Color Prev Preset: + + + spinBoxColorPrevPreset + + + + + + + Color Next Preset: + + + spinBoxColorNextPreset + + + + + + + Color Prev Sequence: + + + spinBoxColorPrevSequence + + + + + + + Color Next Sequence: + + + spinBoxColorNextSequence + + + + + + + Color Play Pause: + + + spinBoxColorPlayPause + + + + + + + Color Stop Sequence: + + + spinBoxColorStopSequence + + + + + + + Color Swap: + + + spinBoxColorSwap + + + + + + + Color Stop All: + + + spinBoxColorStopAll + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + DrumPadSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DrumPadSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/widgets/drumpadwidget.cpp b/widgets/drumpadwidget.cpp index 28a1455..185d052 100644 --- a/widgets/drumpadwidget.cpp +++ b/widgets/drumpadwidget.cpp @@ -14,7 +14,10 @@ DrumPadWidget::DrumPadWidget(QWidget *parent) : QSplitter{parent}, - m_ui{std::make_unique()} + m_ui{std::make_unique()}, + m_presetsModel{this}, + m_presetsProxyModel{this}, + m_filesModel{this} { m_ui->setupUi(this); @@ -22,10 +25,10 @@ DrumPadWidget::DrumPadWidget(QWidget *parent) : connect(m_ui->pushButtonDown, &QAbstractButton::pressed, this, &DrumPadWidget::selectNextPreset); connect(m_ui->pushButtonRefresh, &QAbstractButton::pressed, this, &DrumPadWidget::loadPresets); - connect(m_ui->sequencerWidget, &SequencerWidget::sendMidi, this, &DrumPadWidget::sendMidi); + connect(m_ui->sequencerWidget, &DrumPadSequencerWidget::sendMidi, this, &DrumPadWidget::sendMidi); connect(m_ui->samplesWidget, &DrumPadSamplesWidget::sendMidi, this, &DrumPadWidget::sendMidi); - connect(m_ui->sequencerWidget, &SequencerWidget::triggerSample, m_ui->samplesWidget, &DrumPadSamplesWidget::sequencerTriggerSample); + connect(m_ui->sequencerWidget, &DrumPadSequencerWidget::triggerSample, m_ui->samplesWidget, &DrumPadSamplesWidget::sequencerTriggerSample); m_presetsProxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive); m_presetsProxyModel.setSortRole(Qt::EditRole); @@ -76,19 +79,21 @@ void DrumPadWidget::loadSettings(DrumMachineSettings &settings) void DrumPadWidget::unsendColors() { + const quint8 color = m_settings ? m_settings->colorOff() : quint8{0}; + emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonUp->learnSetting().channel, .cmd = m_ui->pushButtonUp->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonUp->learnSetting().note, - .velocity = 0 + .velocity = color }); emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonDown->learnSetting().channel, .cmd = m_ui->pushButtonDown->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonDown->learnSetting().note, - .velocity = 0 + .velocity = color }); m_ui->sequencerWidget->unsendColors(); @@ -102,14 +107,14 @@ void DrumPadWidget::sendColors() .cmd = m_ui->pushButtonUp->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonUp->learnSetting().note, - .velocity = 127 + .velocity = m_settings ? m_settings->drumpadColorPrevPreset() : quint8{127} }); emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonDown->learnSetting().channel, .cmd = m_ui->pushButtonDown->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonDown->learnSetting().note, - .velocity = 127 + .velocity = m_settings ? m_settings->drumpadColorNextPreset() : quint8{127} }); m_ui->sequencerWidget->sendColors(); diff --git a/widgets/drumpadwidget.h b/widgets/drumpadwidget.h index e167d3d..3fcf25e 100644 --- a/widgets/drumpadwidget.h +++ b/widgets/drumpadwidget.h @@ -9,7 +9,6 @@ #include "drumpadfilesmodel.h" namespace Ui { class DrumPadWidget; } -class SequencerWidget; class QModelIndex; class QNetworkAccessManager; class QThread; diff --git a/widgets/drumpadwidget.ui b/widgets/drumpadwidget.ui index 741da7f..fa496d0 100644 --- a/widgets/drumpadwidget.ui +++ b/widgets/drumpadwidget.ui @@ -107,7 +107,7 @@ Qt::Vertical - + @@ -130,9 +130,9 @@ 1 - SequencerWidget + DrumPadSequencerWidget QWidget -
widgets/sequencerwidget.h
+
widgets/drumpadsequencerwidget.h
1
diff --git a/widgets/loopstationpresetdetailwidget.cpp b/widgets/loopstationpresetdetailwidget.cpp index 77f3f6b..f3297b3 100644 --- a/widgets/loopstationpresetdetailwidget.cpp +++ b/widgets/loopstationpresetdetailwidget.cpp @@ -5,7 +5,8 @@ LoopStationPresetDetailWidget::LoopStationPresetDetailWidget(QWidget *parent) : QScrollArea{parent}, - m_ui{std::make_unique()} + m_ui{std::make_unique()}, + m_tagsModel{this} { m_ui->setupUi(this); diff --git a/widgets/loopstationsampleswidget.cpp b/widgets/loopstationsampleswidget.cpp index 5d7f6e5..4cff50d 100644 --- a/widgets/loopstationsampleswidget.cpp +++ b/widgets/loopstationsampleswidget.cpp @@ -1,14 +1,20 @@ #include "loopstationsampleswidget.h" #include "ui_loopstationsampleswidget.h" +#include + #include "loopstationpresets.h" +#include "drummachinesettings.h" LoopStationSamplesWidget::LoopStationSamplesWidget(QWidget *parent) : QWidget{parent}, - m_ui{std::make_unique()} + m_ui{std::make_unique()}, + m_timer{this} { m_ui->setupUi(this); + connect(m_ui->pushButtonSettings, &QAbstractButton::pressed, this, &LoopStationSamplesWidget::showSettings); + connect(m_ui->spinBoxBpm, qOverload(&QSpinBox::valueChanged), this, &LoopStationSamplesWidget::tempoChanged); connect(m_ui->pushButtonPlayPause, &QAbstractButton::pressed, this, &LoopStationSamplesWidget::playPausePressed); @@ -23,7 +29,7 @@ LoopStationSamplesWidget::LoopStationSamplesWidget(QWidget *parent) : { widget.setPadNr(padNr++); connect(&widget, &LoopStationSampleWidget::sendMidi, this, &LoopStationSamplesWidget::sendMidi); - connect(&widget, &LoopStationSampleWidget::loopEnabled, this, &LoopStationSamplesWidget::loopEnabled); + connect(&widget, &LoopStationSampleWidget::loopEnabledChanged, this, &LoopStationSamplesWidget::loopEnabledChanged); } constexpr const auto setCategories = [](auto category, auto *widget0, auto *widget1, auto *widget2, auto *widget3, auto *widget4, auto *widget5, auto *widget6, auto *widget7){ @@ -54,6 +60,14 @@ LoopStationSamplesWidget::~LoopStationSamplesWidget() = default; void LoopStationSamplesWidget::loadSettings(DrumMachineSettings &settings) { + m_settings = &settings; + + m_ui->pushButtonPlayPause->setLearnSetting(settings.loopstationPlayPause()); + m_ui->pushButtonStop->setLearnSetting(settings.loopstationStop()); + + connect(m_ui->pushButtonPlayPause, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setLoopstationPlayPause); + connect(m_ui->pushButtonStop, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setLoopstationStop); + for (LoopStationSampleWidget &widget : getWidgets()) widget.loadSettings(settings); } @@ -83,6 +97,9 @@ void LoopStationSamplesWidget::setPreset(const loopstation_presets::Preset &pres void LoopStationSamplesWidget::midiReceived(const midi::MidiMessage &message) { + m_ui->pushButtonPlayPause->midiReceived(message); + m_ui->pushButtonStop->midiReceived(message); + for (LoopStationSampleWidget &widget : getWidgets()) widget.midiReceived(message); } @@ -106,15 +123,52 @@ void LoopStationSamplesWidget::injectDecodingThread(QThread &thread) } void LoopStationSamplesWidget::unsendColors() -{ +{ + const quint8 color = m_settings ? m_settings->colorOff() : quint8{0}; + + emit sendMidi(midi::MidiMessage { + .channel = m_ui->pushButtonPlayPause->learnSetting().channel, + .cmd = m_ui->pushButtonPlayPause->learnSetting().cmd, + .flag = true, + .note = m_ui->pushButtonPlayPause->learnSetting().note, + .velocity = color + }); + emit sendMidi(midi::MidiMessage { + .channel = m_ui->pushButtonStop->learnSetting().channel, + .cmd = m_ui->pushButtonStop->learnSetting().cmd, + .flag = true, + .note = m_ui->pushButtonStop->learnSetting().note, + .velocity = color + }); + for (LoopStationSampleWidget &widget : getWidgets()) widget.unsendColor(); } void LoopStationSamplesWidget::sendColors() { + emit sendMidi(midi::MidiMessage { + .channel = m_ui->pushButtonPlayPause->learnSetting().channel, + .cmd = m_ui->pushButtonPlayPause->learnSetting().cmd, + .flag = true, + .note = m_ui->pushButtonPlayPause->learnSetting().note, + .velocity = 3 + }); + emit sendMidi(midi::MidiMessage { + .channel = m_ui->pushButtonStop->learnSetting().channel, + .cmd = m_ui->pushButtonStop->learnSetting().cmd, + .flag = true, + .note = m_ui->pushButtonStop->learnSetting().note, + .velocity = 60 + }); + for (LoopStationSampleWidget &widget : getWidgets()) - widget.sendColor(); + widget.sendColor(true); +} + +void LoopStationSamplesWidget::showSettings() +{ + } void LoopStationSamplesWidget::timeout() @@ -143,34 +197,55 @@ void LoopStationSamplesWidget::tempoChanged(int tempo) m_timer.setInterval(1000. * 60. / tempo); } -void LoopStationSamplesWidget::loopEnabled(quint8 category) +void LoopStationSamplesWidget::loopEnabledChanged(bool loopEnabled, quint8 category) { - for (LoopStationSampleWidget &widget : getWidgets()) + if (loopEnabled) { - if (widget.category() != category) - continue; - if (&widget == sender()) - continue; - widget.setLoopEnabled(false); - } - - if (!m_timer.isActive()) - { - m_pos = 0; - m_ui->horizontalSlider->setValue(m_pos); - m_timer.start(); for (LoopStationSampleWidget &widget : getWidgets()) - widget.timeout(); + { + if (widget.category() != category) + continue; + if (&widget == sender()) + continue; + widget.setLoopEnabled(false); + } + + if (!m_timer.isActive()) + { + m_pos = 0; + m_ui->horizontalSlider->setValue(m_pos); + m_timer.start(); + m_ui->pushButtonPlayPause->setText(tr("▮▮")); + for (LoopStationSampleWidget &widget : getWidgets()) + widget.timeout(); + } + } + else + { + const auto widgets = getWidgets(); + if (m_timer.isActive() && std::none_of(std::begin(widgets), std::end(widgets), [](const LoopStationSampleWidget &widget){ + return widget.loopEnabled(); + })) + { + m_timer.stop(); + m_ui->pushButtonPlayPause->setText(tr("▶")); + m_pos = 0; + m_ui->horizontalSlider->setValue(m_pos); + } } } void LoopStationSamplesWidget::playPausePressed() { if (m_timer.isActive()) + { m_timer.stop(); + m_ui->pushButtonPlayPause->setText(tr("▶")); + } else { m_timer.start(); + m_ui->pushButtonPlayPause->setText(tr("▮▮")); if (m_pos == 0) for (LoopStationSampleWidget &widget : getWidgets()) widget.timeout(); @@ -180,6 +255,7 @@ void LoopStationSamplesWidget::playPausePressed() void LoopStationSamplesWidget::stopPressed() { m_timer.stop(); + m_ui->pushButtonPlayPause->setText(tr("▶")); for (LoopStationSampleWidget &widget : getWidgets()) { widget.setLoopEnabled(false); diff --git a/widgets/loopstationsampleswidget.h b/widgets/loopstationsampleswidget.h index dcc2de2..c1cc203 100644 --- a/widgets/loopstationsampleswidget.h +++ b/widgets/loopstationsampleswidget.h @@ -22,7 +22,7 @@ class LoopStationSamplesWidget : public QWidget public: explicit LoopStationSamplesWidget(QWidget *parent = nullptr); - ~LoopStationSamplesWidget(); + ~LoopStationSamplesWidget() override; void loadSettings(DrumMachineSettings &settings); @@ -42,9 +42,10 @@ signals: void sendMidi(const midi::MidiMessage &midiMsg); private slots: + void showSettings(); void timeout(); void tempoChanged(int tempo); - void loopEnabled(quint8 category); + void loopEnabledChanged(bool loopEnabled, quint8 category); void playPausePressed(); void stopPressed(); @@ -53,6 +54,8 @@ private: const std::unique_ptr m_ui; + DrumMachineSettings *m_settings{}; + QTimer m_timer; quint8 m_pos{}; diff --git a/widgets/loopstationsampleswidget.ui b/widgets/loopstationsampleswidget.ui index 23d774d..468d55c 100644 --- a/widgets/loopstationsampleswidget.ui +++ b/widgets/loopstationsampleswidget.ui @@ -558,6 +558,19 @@
+ + + + + 32 + 16777215 + + + + ⚙️ + + + @@ -579,16 +592,28 @@ - + + + + 32 + 16777215 + + - Play/Pause + - + + + + 32 + 16777215 + + - Stop + @@ -629,6 +654,11 @@
widgets/loopstationsamplewidget.h
1 + + MidiButton + QPushButton +
widgets/midibutton.h
+
diff --git a/widgets/loopstationsamplewidget.cpp b/widgets/loopstationsamplewidget.cpp index e2eab7b..7305997 100644 --- a/widgets/loopstationsamplewidget.cpp +++ b/widgets/loopstationsamplewidget.cpp @@ -15,16 +15,15 @@ LoopStationSampleWidget::LoopStationSampleWidget(QWidget *parent) : QFrame{parent}, - m_ui{std::make_unique()} + m_ui{std::make_unique()}, + m_player{this} { m_ui->setupUi(this); connect(&m_player, &AudioPlayer::playingChanged, this, &LoopStationSampleWidget::updateStatus); connect(m_ui->pushButtonPlay, &QAbstractButton::toggled, this, [this](bool toggled){ - if (!toggled) - return; - emit loopEnabled(m_category); + emit loopEnabledChanged(toggled, m_category); }); updateStatus(); @@ -99,24 +98,27 @@ void LoopStationSampleWidget::unsendColor() { m_sendColors = false; + const quint8 color = m_settings ? m_settings->colorOff() : quint8{0}; + 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 + .velocity = color }); - m_lastMidiColor = 0; + + m_lastMidiColor = color; } -void LoopStationSampleWidget::sendColor() +void LoopStationSampleWidget::sendColor(bool force) { m_sendColors = true; quint8 newColor; if (false) // testing colors on launchpad mk2 - newColor = m_padNr; + newColor = m_padNr + 48; else { if (m_player.buffer().isValid()) @@ -134,16 +136,15 @@ void LoopStationSampleWidget::sendColor() else if (m_category == 5) newColor = m_player.playing() ? 52 : 55; // pink else - goto noColor; + newColor = m_player.playing() ? 4 : 7; // red } else { -noColor: newColor = 0; } } - if (newColor != m_lastMidiColor) + if (force || newColor != m_lastMidiColor) { emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonPlay->learnSetting().channel, @@ -156,12 +157,17 @@ noColor: } } +bool LoopStationSampleWidget::loopEnabled() const +{ + return m_ui->pushButtonPlay->isChecked(); +} + void LoopStationSampleWidget::timeout() { if (m_ui->pushButtonPlay->isChecked()) { - // if is not playing or position > 90% - if (!m_player.playing() || m_player.position() >= m_player.buffer().frameCount() * 9 / 10) + // if is not playing or position > 80% + if (!m_player.playing() || m_player.position() >= m_player.buffer().frameCount() * 8 / 10) m_player.restart(); } else @@ -225,7 +231,7 @@ void LoopStationSampleWidget::updateStatus() } if (m_sendColors) - sendColor(); + sendColor(false); if (m_reply) { diff --git a/widgets/loopstationsamplewidget.h b/widgets/loopstationsamplewidget.h index 8e24588..a4045cf 100644 --- a/widgets/loopstationsamplewidget.h +++ b/widgets/loopstationsamplewidget.h @@ -41,7 +41,9 @@ public: void midiReceived(const midi::MidiMessage &message); void unsendColor(); - void sendColor(); + void sendColor(bool force); + + bool loopEnabled() const; public slots: void timeout(); @@ -51,7 +53,7 @@ public slots: signals: void startDecoding(std::shared_ptr device); void sendMidi(const midi::MidiMessage &midiMsg); - void loopEnabled(quint8 category); + void loopEnabledChanged(bool loopEnabled, quint8 category); private slots: void updateStatus(); diff --git a/widgets/loopstationwidget.cpp b/widgets/loopstationwidget.cpp index 182bcaf..b71bdfb 100644 --- a/widgets/loopstationwidget.cpp +++ b/widgets/loopstationwidget.cpp @@ -70,19 +70,21 @@ void LoopStationWidget::loadSettings(DrumMachineSettings &settings) void LoopStationWidget::unsendColors() { + const quint8 color = m_settings ? m_settings->colorOff() : quint8{0}; + emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonUp->learnSetting().channel, .cmd = m_ui->pushButtonUp->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonUp->learnSetting().note, - .velocity = 0 + .velocity = color }); emit sendMidi(midi::MidiMessage { .channel = m_ui->pushButtonDown->learnSetting().channel, .cmd = m_ui->pushButtonDown->learnSetting().cmd, .flag = true, .note = m_ui->pushButtonDown->learnSetting().note, - .velocity = 0 + .velocity = color }); m_ui->samplesWidget->unsendColors(); diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 28cd439..9636076 100755 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -27,9 +27,13 @@ int paCallback(const void *inputBuffer, void *outputBuffer, MainWindow::MainWindow(QWidget *parent) : QMainWindow{parent}, m_ui{std::make_unique()}, + m_settings{this}, m_paStream{nullptr, DummyDeleter}, - m_midiIn{RtMidi::UNSPECIFIED, "DrumMachine"}, - m_midiOut{RtMidi::UNSPECIFIED, "DrumMachine"} + m_midiIn{RtMidi::UNSPECIFIED, "DrumMachine", 100, this}, + m_midiOut{RtMidi::UNSPECIFIED, "DrumMachine", this}, + m_networkAccessManager{this}, + m_cache{this}, + m_decoderThread{this} { m_ui->setupUi(this); @@ -58,10 +62,15 @@ MainWindow::MainWindow(QWidget *parent) : updateAudioDevices(); connect(m_ui->pushButtonRefreshAudioDevices, &QAbstractButton::pressed, this, &MainWindow::updateAudioDevices); + m_ui->spinBoxBufferSize->setValue(m_settings.framesPerBuffer()); if (const auto &lastAudioDevice = m_settings.lastAudioDevice(); !lastAudioDevice.isEmpty()) { if (const auto index = m_ui->comboBoxAudioDevice->findText(lastAudioDevice); index >= 0) + { m_ui->comboBoxAudioDevice->setCurrentIndex(index); + if (m_settings.autoOpenAudioDevice()) + openAudioDevice(); + } else goto paDefault; } @@ -70,7 +79,6 @@ MainWindow::MainWindow(QWidget *parent) : paDefault: m_ui->comboBoxAudioDevice->setCurrentIndex(Pa_GetDefaultOutputDevice()); } - m_ui->spinBoxBufferSize->setValue(m_settings.framesPerBuffer()); connect(m_ui->pushButtonAudioDevice, &QAbstractButton::pressed, this, &MainWindow::openAudioDevice); updateMidiInDevices(); @@ -78,7 +86,11 @@ paDefault: if (const auto &lastMidiInDevice = m_settings.lastMidiInDevice(); !lastMidiInDevice.isEmpty()) { if (const auto index = m_ui->comboBoxMidiIn->findText(lastMidiInDevice); index >= 0) + { m_ui->comboBoxMidiIn->setCurrentIndex(index); + if (m_settings.autoOpenMidiIn()) + openMidiInDevice(); + } } connect(m_ui->pushButtonMidiIn, &QAbstractButton::pressed, this, &MainWindow::openMidiInDevice); @@ -87,7 +99,11 @@ paDefault: if (const auto &lastMidiOutDevice = m_settings.lastMidiOutDevice(); !lastMidiOutDevice.isEmpty()) { if (const auto index = m_ui->comboBoxMidiOut->findText(lastMidiOutDevice); index >= 0) + { m_ui->comboBoxMidiOut->setCurrentIndex(index); + if (m_settings.autoOpenMidiOut()) + openMidiOutDevice(); + } } connect(m_ui->pushButtonMidiOut, &QAbstractButton::pressed, this, &MainWindow::openMidiOutDevice); @@ -145,12 +161,19 @@ void MainWindow::openAudioDevice() { m_paStream = nullptr; m_ui->comboBoxAudioDevice->setEnabled(true); + m_ui->pushButtonRefreshAudioDevices->setEnabled(true); m_ui->spinBoxBufferSize->setEnabled(true); m_ui->pushButtonAudioDevice->setText(tr("Open")); + m_settings.setAutoOpenAudioDevice(false); } else { PaDeviceIndex index = m_ui->comboBoxAudioDevice->currentIndex(); + if (index < 0) + { + QMessageBox::warning(this, tr("No audio device selected!"), tr("No audio device selected!")); + return; + } const PaDeviceInfo* pInfo = Pa_GetDeviceInfo(index); @@ -166,7 +189,7 @@ void MainWindow::openAudioDevice() if (PaError err = Pa_OpenStream(&stream, NULL, &outputParameters, frameRate, m_ui->spinBoxBufferSize->value(), paNoFlag, &paCallback, this); err != paNoError) { - QMessageBox::warning(this, tr("Error opening stream!"), tr("Error opening stream!") + "\n\n" + Pa_GetErrorText(err)); + QMessageBox::warning(this, tr("Error opening audio device!"), tr("Error opening audio device!") + "\n\n" + Pa_GetErrorText(err)); return; } @@ -175,13 +198,13 @@ void MainWindow::openAudioDevice() if (PaError err = Pa_SetStreamFinishedCallback(smartPtr.get(), &paStreamFinished); err != paNoError) { - QMessageBox::warning(this, tr("Error setting finished callback!"), tr("Error setting finished callback!") + "\n\n" + Pa_GetErrorText(err)); + QMessageBox::warning(this, tr("Error opening audio device!"), tr("Error setting finished callback!") + "\n\n" + Pa_GetErrorText(err)); return; } if (PaError err = Pa_StartStream(smartPtr.get()); err != paNoError) { - QMessageBox::warning(this, tr("Error starting stream!"), tr("Error starting stream!") + "\n\n" + Pa_GetErrorText(err)); + QMessageBox::warning(this, tr("Error opening audio device!"), tr("Error starting stream!") + "\n\n" + Pa_GetErrorText(err)); return; } @@ -190,51 +213,100 @@ void MainWindow::openAudioDevice() m_paStream = std::move(smartPtr); m_ui->comboBoxAudioDevice->setEnabled(false); + m_ui->pushButtonRefreshAudioDevices->setEnabled(false); m_ui->spinBoxBufferSize->setEnabled(false); m_ui->pushButtonAudioDevice->setText(tr("Close")); - m_settings.setLastAudioDevice(m_ui->comboBoxAudioDevice->currentText()); m_settings.setFramesPerBuffer(m_ui->spinBoxBufferSize->value()); + m_settings.setAutoOpenAudioDevice(true); } } void MainWindow::openMidiInDevice() { if (m_midiIn.isPortOpen()) + { m_midiIn.closePort(); + + if (m_midiIn.isPortOpen()) + { + QMessageBox::warning(this, tr("Could not close midi in device!"), tr("Could not close midi in device!")); + return; + } + + m_ui->comboBoxMidiIn->setEnabled(true); + m_ui->pushButtonRefreshMidiIn->setEnabled(true); + m_ui->pushButtonMidiIn->setText(tr("Open")); + m_settings.setAutoOpenMidiIn(false); + } else { const auto index = m_ui->comboBoxMidiIn->currentIndex(); - if (index != -1) - m_midiIn.openPort(index, "Input"); - m_settings.setLastMidiInDevice(m_ui->comboBoxMidiIn->currentText()); - } + if (index < 0) + { + QMessageBox::warning(this, tr("No midi in device selected!"), tr("No midi in device selected!")); + return; + } - m_ui->comboBoxMidiIn->setDisabled(m_midiIn.isPortOpen()); - m_ui->pushButtonMidiIn->setText(m_midiIn.isPortOpen() ? tr("Close") : tr("Open")); + m_midiIn.openPort(index, "Input"); + + if (!m_midiIn.isPortOpen()) + { + QMessageBox::warning(this, tr("Could not open midi in device!"), tr("Could not open midi in device!")); + return; + } + + m_ui->comboBoxMidiIn->setEnabled(false); + m_ui->pushButtonRefreshMidiIn->setEnabled(false); + m_ui->pushButtonMidiIn->setText(tr("Close")); + m_settings.setLastMidiInDevice(m_ui->comboBoxMidiIn->currentText()); + m_settings.setAutoOpenMidiIn(true); + } } void MainWindow::openMidiOutDevice() { if (m_midiOut.isPortOpen()) { - qDebug() << "closing port"; unsendColors(m_ui->tabWidget->currentIndex()); + m_midiOut.closePort(); + + if (m_midiOut.isPortOpen()) + { + QMessageBox::warning(this, tr("Could not close midi out device!"), tr("Could not close midi out device!")); + return; + } + + m_ui->comboBoxMidiOut->setEnabled(true); + m_ui->pushButtonRefreshMidiOut->setEnabled(true); + m_ui->pushButtonMidiOut->setText(tr("Open")); + m_settings.setAutoOpenMidiOut(false); } else { const auto index = m_ui->comboBoxMidiOut->currentIndex(); - if (index != -1) + if (index < 0) { - m_midiOut.openPort(index, "Output"); - m_settings.setLastMidiOutDevice(m_ui->comboBoxMidiOut->currentText()); - sendColors(m_ui->tabWidget->currentIndex()); + QMessageBox::warning(this, tr("No midi out device selected!"), tr("No midi out device selected!")); + return; } - } - m_ui->comboBoxMidiOut->setDisabled(m_midiOut.isPortOpen()); - m_ui->pushButtonMidiOut->setText(m_midiOut.isPortOpen() ? tr("Close") : tr("Open")); + m_midiOut.openPort(index, "Output"); + + if (!m_midiOut.isPortOpen()) + { + QMessageBox::warning(this, tr("Could not open midi out device!"), tr("Could not open midi out device!")); + return; + } + + m_ui->comboBoxMidiOut->setEnabled(false); + m_ui->pushButtonRefreshMidiOut->setEnabled(false); + m_ui->pushButtonMidiOut->setText(tr("Close")); + m_settings.setLastMidiOutDevice(m_ui->comboBoxMidiOut->currentText()); + m_settings.setAutoOpenMidiOut(true); + sendColors(m_ui->tabWidget->currentIndex()); + } } void MainWindow::midiReceived(const midi::MidiMessage &message) @@ -322,7 +394,7 @@ void MainWindow::unsendColors(int index) .cmd = learnSetting.cmd, .flag = true, .note = learnSetting.note, - .velocity = 0 + .velocity = m_settings.colorOff() }); } @@ -347,7 +419,7 @@ void MainWindow::sendColors(int index) .cmd = learnSetting.cmd, .flag = true, .note = learnSetting.note, - .velocity = 3 + .velocity = m_settings.colorTabWidget() }); } diff --git a/widgets/settingsdialog.cpp b/widgets/settingsdialog.cpp index 6480f83..17c961e 100644 --- a/widgets/settingsdialog.cpp +++ b/widgets/settingsdialog.cpp @@ -47,10 +47,18 @@ void SettingsDialog::accept() m_settings.setCacheDir(cacheDir); } - const auto maximumCacheSize = qint64{m_ui->spinBoxMaxCacheSize->value()} * 1024 * 1024; - if (m_settings.maximumCacheSize() != maximumCacheSize) + if (const auto maximumCacheSize = qint64{m_ui->spinBoxMaxCacheSize->value()} * 1024 * 1024; + m_settings.maximumCacheSize() != maximumCacheSize) m_settings.setMaximumCacheSize(maximumCacheSize); + if (const quint8 colorOff = m_ui->spinBoxColorOff->value(); + m_settings.colorOff() != colorOff) + m_settings.setColorOff(colorOff); + + if (const quint8 colorTabWidget = m_ui->spinBoxColorTabWidget->value(); + m_settings.colorTabWidget() != colorTabWidget) + m_settings.setColorTabWidget(colorTabWidget); + QDialog::accept(); } @@ -78,12 +86,16 @@ void SettingsDialog::resetFields() { m_ui->lineEditCacheDir->setText(m_settings.cacheDir()); m_ui->spinBoxMaxCacheSize->setValue(m_settings.maximumCacheSize() / 1024 / 1024); + m_ui->spinBoxColorOff->setValue(m_settings.colorOff()); + m_ui->spinBoxColorTabWidget->setValue(m_settings.colorTabWidget()); } void SettingsDialog::restoreDefaults() { m_ui->lineEditCacheDir->setText(m_settings.defaultCacheDir()); m_ui->spinBoxMaxCacheSize->setValue(m_settings.defaultMaximumCacheSize() / 1024 / 1024); + m_ui->spinBoxColorOff->setValue(m_settings.defaultColorOff()); + m_ui->spinBoxColorTabWidget->setValue(m_settings.defaultColorTabWidget()); } void SettingsDialog::selectCacheDir() diff --git a/widgets/settingsdialog.ui b/widgets/settingsdialog.ui index 8bb4bcc..f1a39ad 100644 --- a/widgets/settingsdialog.ui +++ b/widgets/settingsdialog.ui @@ -40,6 +40,16 @@
+ + + + Max Cache Size: + + + spinBoxMaxCacheSize + + + @@ -61,16 +71,81 @@ - - + + - Max Cache Size: + Color Off: - spinBoxMaxCacheSize + spinBoxColorOff + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Usually 0 + + + + + + + + + Color Tab Widget: + + + spinBoxColorTabWidget + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + diff --git a/widgets/trackdeck.cpp b/widgets/trackdeck.cpp index c22ff3b..2867d2d 100644 --- a/widgets/trackdeck.cpp +++ b/widgets/trackdeck.cpp @@ -16,7 +16,10 @@ TrackDeck::TrackDeck(QWidget *parent) : QWidget{parent}, - m_ui{std::make_unique()} + m_ui{std::make_unique()}, + m_loopGroup{this}, + m_player{this}, + m_timer{this} { m_ui->setupUi(this); m_ui->progressBar->hide();