Most colors are now configurable and added drum pad settings dialog

This commit is contained in:
2023-01-01 07:13:48 +01:00
parent d4ca6bdd12
commit 8483cbba7d
32 changed files with 1299 additions and 167 deletions

View File

@ -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

View File

@ -8,7 +8,7 @@
#include "audioformat.h"
AudioDecoder::AudioDecoder(QObject *parent) :
QObject(parent)
QObject{parent}
{
QObject::connect(&m_decoder, qOverload<QAudioDecoder::Error>(&QAudioDecoder::error),
this, &AudioDecoder::error);

View File

@ -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>();
}
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>();
}
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>();
}
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>();
}
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>();
}
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>();
}
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<quint8>();
}
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>();
}
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>();
}
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>();
}
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));

View File

@ -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);

View File

@ -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()}
{
}

View File

@ -1,16 +1,18 @@
#pragma once
#include <QObject>
#include <QString>
#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);

View File

@ -5,7 +5,8 @@
DrumPadPresetDetailWidget::DrumPadPresetDetailWidget(QWidget *parent) :
QScrollArea{parent},
m_ui{std::make_unique<Ui::DrumPadPresetDetailWidget>()}
m_ui{std::make_unique<Ui::DrumPadPresetDetailWidget>()},
m_tagsModel{this}
{
m_ui->setupUi(this);

View File

@ -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]);

View File

@ -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<Ui::DrumPadSamplesWidget> m_ui;
DrumMachineSettings *m_settings{};
drumpad_presets::Preset m_preset;
};

View File

@ -73,6 +73,19 @@
</item>
<item row="0" column="0" colspan="9">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButtonSettings">
<property name="maximumSize">
<size>
<width>32</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>⚙️</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
@ -87,14 +100,17 @@
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<widget class="MidiButton" name="pushButtonSwap">
<property name="text">
<string>Swap left/right</string>
<string>Swap Left/Right</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonStopAll">
<widget class="MidiButton" name="pushButtonStopAll">
<property name="text">
<string>Stop all</string>
</property>
@ -337,6 +353,11 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>MidiButton</class>
<extends>QPushButton</extends>
<header>widgets/midibutton.h</header>
</customwidget>
<customwidget>
<class>DrumPadSampleWidget</class>
<extends>QFrame</extends>

View File

@ -20,7 +20,8 @@ QString toString(bool value) { return value?"true":"false"; }
DrumPadSampleWidget::DrumPadSampleWidget(QWidget *parent) :
QFrame{parent},
m_ui{std::make_unique<Ui::DrumPadSampleWidget>()}
m_ui{std::make_unique<Ui::DrumPadSampleWidget>()},
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)
{

View File

@ -52,7 +52,7 @@ public:
void midiReceived(const midi::MidiMessage &message);
void unsendColor();
void sendColor();
void sendColor(bool force);
signals:
void chokeTriggered(int choke);

View File

@ -1,5 +1,5 @@
#include "sequencerwidget.h"
#include "ui_sequencerwidget.h"
#include "drumpadsequencerwidget.h"
#include "ui_drumpadsequencerwidget.h"
#include <algorithm>
@ -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<Ui::SequencerWidget>()}
m_ui{std::make_unique<Ui::DrumPadSequencerWidget>()},
m_timer{this}
{
m_ui->setupUi(this);
connect(m_ui->spinBoxTempo, qOverload<int>(&QSpinBox::valueChanged), this, &SequencerWidget::tempoChanged);
connect(m_ui->spinBoxTempo, qOverload<int>(&QSpinBox::valueChanged), this, &DrumPadSequencerWidget::tempoChanged);
connect(m_ui->comboBoxSequence, qOverload<int>(&QComboBox::currentIndexChanged), this, &SequencerWidget::sequenceSelected);
connect(m_ui->comboBoxSequence, qOverload<int>(&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);

View File

@ -8,18 +8,18 @@
#include <QTimer>
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<Ui::SequencerWidget> m_ui;
const std::unique_ptr<Ui::DrumPadSequencerWidget> m_ui;
DrumMachineSettings *m_settings{};
std::vector<drumpad_presets::Sequence> m_sequences;
const drumpad_presets::Sequence *m_selectedSequence{};

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SequencerWidget</class>
<widget class="QWidget" name="SequencerWidget">
<class>DrumPadSequencerWidget</class>
<widget class="QWidget" name="DrumPadSequencerWidget">
<property name="geometry">
<rect>
<x>0</x>

View File

@ -0,0 +1,102 @@
#include "drumpadsettingsdialog.h"
#include "ui_drumpadsettingsdialog.h"
#include <QDebug>
#include <QAbstractButton>
#include "drummachinesettings.h"
DrumPadSettingsDialog::DrumPadSettingsDialog(DrumMachineSettings &settings, QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::DrumPadSettingsDialog>()},
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());
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <QDialog>
#include <memory>
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<Ui::DrumPadSettingsDialog> m_ui;
DrumMachineSettings &m_settings;
};

View File

@ -0,0 +1,340 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DrumPadSettingsDialog</class>
<widget class="QDialog" name="DrumPadSettingsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>326</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="labelColorPrevPreset">
<property name="text">
<string>Color Prev Preset:</string>
</property>
<property name="buddy">
<cstring>spinBoxColorPrevPreset</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelColorNextPreset">
<property name="text">
<string>Color Next Preset:</string>
</property>
<property name="buddy">
<cstring>spinBoxColorNextPreset</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelColorPrevSequence">
<property name="text">
<string>Color Prev Sequence:</string>
</property>
<property name="buddy">
<cstring>spinBoxColorPrevSequence</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelColorNextSequence">
<property name="text">
<string>Color Next Sequence:</string>
</property>
<property name="buddy">
<cstring>spinBoxColorNextSequence</cstring>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelColorPlayPause">
<property name="text">
<string>Color Play Pause:</string>
</property>
<property name="buddy">
<cstring>spinBoxColorPlayPause</cstring>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="labelColorStopSequence">
<property name="text">
<string>Color Stop Sequence:</string>
</property>
<property name="buddy">
<cstring>spinBoxColorStopSequence</cstring>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="labelColorSwap">
<property name="text">
<string>Color Swap:</string>
</property>
<property name="buddy">
<cstring>spinBoxColorSwap</cstring>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="labelColorStopAll">
<property name="text">
<string>Color Stop All:</string>
</property>
<property name="buddy">
<cstring>spinBoxColorStopAll</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="spinBoxColorPrevPreset">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="spinBoxColorNextPreset">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSpinBox" name="spinBoxColorPrevSequence">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSpinBox" name="spinBoxColorNextSequence">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QSpinBox" name="spinBoxColorPlayPause">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QSpinBox" name="spinBoxColorStopSequence">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QSpinBox" name="spinBoxColorSwap">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="7" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QSpinBox" name="spinBoxColorStopAll">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DrumPadSettingsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DrumPadSettingsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -14,7 +14,10 @@
DrumPadWidget::DrumPadWidget(QWidget *parent) :
QSplitter{parent},
m_ui{std::make_unique<Ui::DrumPadWidget>()}
m_ui{std::make_unique<Ui::DrumPadWidget>()},
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();

View File

@ -9,7 +9,6 @@
#include "drumpadfilesmodel.h"
namespace Ui { class DrumPadWidget; }
class SequencerWidget;
class QModelIndex;
class QNetworkAccessManager;
class QThread;

View File

@ -107,7 +107,7 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="SequencerWidget" name="sequencerWidget" native="true"/>
<widget class="DrumPadSequencerWidget" name="sequencerWidget" native="true"/>
<widget class="DrumPadSamplesWidget" name="samplesWidget" native="true"/>
</widget>
</widget>
@ -130,9 +130,9 @@
<container>1</container>
</customwidget>
<customwidget>
<class>SequencerWidget</class>
<class>DrumPadSequencerWidget</class>
<extends>QWidget</extends>
<header>widgets/sequencerwidget.h</header>
<header>widgets/drumpadsequencerwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>

View File

@ -5,7 +5,8 @@
LoopStationPresetDetailWidget::LoopStationPresetDetailWidget(QWidget *parent) :
QScrollArea{parent},
m_ui{std::make_unique<Ui::LoopStationPresetDetailWidget>()}
m_ui{std::make_unique<Ui::LoopStationPresetDetailWidget>()},
m_tagsModel{this}
{
m_ui->setupUi(this);

View File

@ -1,14 +1,20 @@
#include "loopstationsampleswidget.h"
#include "ui_loopstationsampleswidget.h"
#include <algorithm>
#include "loopstationpresets.h"
#include "drummachinesettings.h"
LoopStationSamplesWidget::LoopStationSamplesWidget(QWidget *parent) :
QWidget{parent},
m_ui{std::make_unique<Ui::LoopStationSamplesWidget>()}
m_ui{std::make_unique<Ui::LoopStationSamplesWidget>()},
m_timer{this}
{
m_ui->setupUi(this);
connect(m_ui->pushButtonSettings, &QAbstractButton::pressed, this, &LoopStationSamplesWidget::showSettings);
connect(m_ui->spinBoxBpm, qOverload<int>(&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);

View File

@ -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<Ui::LoopStationSamplesWidget> m_ui;
DrumMachineSettings *m_settings{};
QTimer m_timer;
quint8 m_pos{};

View File

@ -558,6 +558,19 @@
</item>
<item row="0" column="0" colspan="12">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButtonSettings">
<property name="maximumSize">
<size>
<width>32</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>⚙️</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelBpm">
<property name="text">
@ -579,16 +592,28 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonPlayPause">
<widget class="MidiButton" name="pushButtonPlayPause">
<property name="maximumSize">
<size>
<width>32</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Play/Pause</string>
<string></string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonStop">
<widget class="MidiButton" name="pushButtonStop">
<property name="maximumSize">
<size>
<width>32</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Stop</string>
<string></string>
</property>
</widget>
</item>
@ -629,6 +654,11 @@
<header>widgets/loopstationsamplewidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>MidiButton</class>
<extends>QPushButton</extends>
<header>widgets/midibutton.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@ -15,16 +15,15 @@
LoopStationSampleWidget::LoopStationSampleWidget(QWidget *parent) :
QFrame{parent},
m_ui{std::make_unique<Ui::LoopStationSampleWidget>()}
m_ui{std::make_unique<Ui::LoopStationSampleWidget>()},
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)
{

View File

@ -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<QIODevice> device);
void sendMidi(const midi::MidiMessage &midiMsg);
void loopEnabled(quint8 category);
void loopEnabledChanged(bool loopEnabled, quint8 category);
private slots:
void updateStatus();

View File

@ -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();

View File

@ -27,9 +27,13 @@ int paCallback(const void *inputBuffer, void *outputBuffer,
MainWindow::MainWindow(QWidget *parent) :
QMainWindow{parent},
m_ui{std::make_unique<Ui::MainWindow>()},
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()
});
}

View File

@ -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()

View File

@ -40,6 +40,16 @@
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelMaxCacheSize">
<property name="text">
<string>Max Cache Size:</string>
</property>
<property name="buddy">
<cstring>spinBoxMaxCacheSize</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0">
<item>
@ -61,16 +71,81 @@
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelMaxCacheSize">
<item row="2" column="0">
<widget class="QLabel" name="labelColorOff">
<property name="text">
<string>Max Cache Size:</string>
<string>Color Off:</string>
</property>
<property name="buddy">
<cstring>spinBoxMaxCacheSize</cstring>
<cstring>spinBoxColorOff</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSpinBox" name="spinBoxColorOff">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="labelColorOffHint">
<property name="text">
<string>Usually 0</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelColorTabWidget">
<property name="text">
<string>Color Tab Widget:</string>
</property>
<property name="buddy">
<cstring>spinBoxColorTabWidget</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSpinBox" name="spinBoxColorTabWidget">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>

View File

@ -16,7 +16,10 @@
TrackDeck::TrackDeck(QWidget *parent) :
QWidget{parent},
m_ui{std::make_unique<Ui::TrackDeck>()}
m_ui{std::make_unique<Ui::TrackDeck>()},
m_loopGroup{this},
m_player{this},
m_timer{this}
{
m_ui->setupUi(this);
m_ui->progressBar->hide();