Fixed midi handling for control change and implemented tab selection with midi
This commit is contained in:
@@ -51,34 +51,9 @@ void DrumPadSamplesWidget::midiReceived(const midi::MidiMessage &message)
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.cmd != midi::Command::NoteOn &&
|
||||
message.cmd != midi::Command::NoteOff &&
|
||||
message.cmd != midi::Command::ControlChange)
|
||||
return;
|
||||
|
||||
for (DrumPadSampleWidget &widget : getWidgets())
|
||||
{
|
||||
if (widget.isLearning())
|
||||
{
|
||||
widget.learn(message.channel, message.note);
|
||||
}
|
||||
else if (widget.channel() == message.channel && widget.note() == message.note)
|
||||
{
|
||||
switch (message.cmd)
|
||||
{
|
||||
case midi::Command::NoteOn:
|
||||
case midi::Command::ControlChange:
|
||||
if (message.velocity != 0)
|
||||
widget.pressed(message.velocity);
|
||||
else
|
||||
Q_FALLTHROUGH();
|
||||
case midi::Command::NoteOff:
|
||||
widget.released();
|
||||
break;
|
||||
default:
|
||||
__builtin_unreachable();
|
||||
}
|
||||
}
|
||||
widget.midiReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +95,7 @@ void DrumPadSamplesWidget::sequencerTriggerSample(int index)
|
||||
qDebug() << "index out of range" << index;
|
||||
return;
|
||||
}
|
||||
widgets[index].get().pressed(127);
|
||||
widgets[index].get().pressed();
|
||||
}
|
||||
|
||||
void DrumPadSamplesWidget::chokeTriggered(int choke)
|
||||
|
@@ -30,9 +30,8 @@ DrumPadSampleWidget::DrumPadSampleWidget(QWidget *parent) :
|
||||
|
||||
connect(&m_player, &AudioPlayer::playingChanged, this, &DrumPadSampleWidget::updateStatus);
|
||||
|
||||
connect(m_ui->pushButton, &QAbstractButton::pressed, this, [this](){ pressed(127); });
|
||||
connect(m_ui->pushButton, &QAbstractButton::released, this, &DrumPadSampleWidget::released);
|
||||
connect(m_ui->toolButtonLearn, &QAbstractButton::pressed, this, &DrumPadSampleWidget::learnPressed);
|
||||
connect(m_ui->pushButtonPlay, &QAbstractButton::pressed, this, &DrumPadSampleWidget::pressed);
|
||||
connect(m_ui->pushButtonPlay, &QAbstractButton::released, this, &DrumPadSampleWidget::released);
|
||||
|
||||
updateStatus();
|
||||
}
|
||||
@@ -41,10 +40,17 @@ DrumPadSampleWidget::~DrumPadSampleWidget() = default;
|
||||
|
||||
void DrumPadSampleWidget::loadSettings(DrumMachineSettings &settings)
|
||||
{
|
||||
m_ui->channelSpinBox->setValue(settings.drumpadChannel(m_padNr));
|
||||
m_ui->noteSpinBox->setValue(settings.drumpadNote(m_padNr));
|
||||
|
||||
m_settings = &settings;
|
||||
|
||||
m_ui->pushButtonPlay->setLearnSetting(m_settings->drumpadSample(m_padNr));
|
||||
|
||||
connect(m_ui->pushButtonPlay, &MidiButton::learnSettingChanged, this, [this](const MidiLearnSetting &learnSetting){
|
||||
Q_ASSERT(m_settings);
|
||||
if (m_settings)
|
||||
m_settings->setDrumpadSample(m_padNr, learnSetting);
|
||||
else
|
||||
qWarning() << "no settings available";
|
||||
});
|
||||
}
|
||||
|
||||
void DrumPadSampleWidget::setFile(const QString &presetId, const drumpad_presets::File &file)
|
||||
@@ -80,38 +86,6 @@ void DrumPadSampleWidget::setFile(const QString &presetId, const drumpad_presets
|
||||
setupLabel(file.choke, m_ui->chokeLabel);
|
||||
}
|
||||
|
||||
quint8 DrumPadSampleWidget::channel() const
|
||||
{
|
||||
return m_ui->channelSpinBox->value();
|
||||
}
|
||||
|
||||
void DrumPadSampleWidget::setChannel(quint8 channel)
|
||||
{
|
||||
m_ui->channelSpinBox->setValue(channel);
|
||||
|
||||
Q_ASSERT(m_settings);
|
||||
if (m_settings)
|
||||
m_settings->setDrumpadChannel(m_padNr, channel);
|
||||
else
|
||||
qWarning() << "no settings available";
|
||||
}
|
||||
|
||||
quint8 DrumPadSampleWidget::note() const
|
||||
{
|
||||
return m_ui->noteSpinBox->value();
|
||||
}
|
||||
|
||||
void DrumPadSampleWidget::setNote(quint8 note)
|
||||
{
|
||||
m_ui->noteSpinBox->setValue(note);
|
||||
|
||||
Q_ASSERT(m_settings);
|
||||
if (m_settings)
|
||||
m_settings->setDrumpadNote(m_padNr, note);
|
||||
else
|
||||
qWarning() << "no settings available";
|
||||
}
|
||||
|
||||
int DrumPadSampleWidget::speed() const
|
||||
{
|
||||
return m_ui->dialSpeed->value();
|
||||
@@ -139,10 +113,8 @@ std::optional<int> DrumPadSampleWidget::choke() const
|
||||
return m_file->choke;
|
||||
}
|
||||
|
||||
void DrumPadSampleWidget::pressed(quint8 velocity)
|
||||
void DrumPadSampleWidget::pressed()
|
||||
{
|
||||
Q_UNUSED(velocity)
|
||||
|
||||
m_player.restart();
|
||||
|
||||
if (m_file && m_file->choke && *m_file->choke)
|
||||
@@ -181,61 +153,59 @@ void DrumPadSampleWidget::writeSamples(frame_t *begin, frame_t *end)
|
||||
m_player.writeSamples(begin, end);
|
||||
}
|
||||
|
||||
void DrumPadSampleWidget::learn(quint8 channel, quint8 note)
|
||||
void DrumPadSampleWidget::midiReceived(const midi::MidiMessage &message)
|
||||
{
|
||||
setChannel(channel);
|
||||
setNote(note);
|
||||
if (m_learning)
|
||||
learnPressed();
|
||||
m_ui->pushButtonPlay->midiReceived(message);
|
||||
}
|
||||
|
||||
void DrumPadSampleWidget::unsendColor()
|
||||
{
|
||||
m_sendColors = false;
|
||||
midi::MidiMessage midiMsg;
|
||||
|
||||
midiMsg.channel = m_ui->channelSpinBox->value();
|
||||
midiMsg.cmd = midi::Command::NoteOn;
|
||||
midiMsg.flag = true;
|
||||
midiMsg.note = m_ui->noteSpinBox->value();
|
||||
midiMsg.velocity = 0;
|
||||
|
||||
emit sendMidi(midiMsg);
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonPlay->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonPlay->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonPlay->learnSetting().note,
|
||||
.velocity = 0
|
||||
});
|
||||
}
|
||||
|
||||
void DrumPadSampleWidget::sendColor()
|
||||
{
|
||||
m_sendColors = true;
|
||||
midi::MidiMessage midiMsg;
|
||||
|
||||
midiMsg.channel = m_ui->channelSpinBox->value();
|
||||
midiMsg.cmd = midi::Command::NoteOn;
|
||||
midiMsg.flag = true;
|
||||
midiMsg.note = m_ui->noteSpinBox->value();
|
||||
uint8_t velocity;
|
||||
|
||||
if (m_file && m_file->color && m_player.buffer().isValid())
|
||||
{
|
||||
const auto &color = *m_file->color;
|
||||
if (color == "purple")
|
||||
midiMsg.velocity = m_player.playing() ? 43 : 18;
|
||||
velocity = m_player.playing() ? 43 : 18;
|
||||
else if (color == "red")
|
||||
midiMsg.velocity = m_player.playing() ? 3 : 1;
|
||||
velocity = m_player.playing() ? 3 : 1;
|
||||
else if (color == "yellow")
|
||||
midiMsg.velocity = m_player.playing() ? 58 : 33;
|
||||
velocity = m_player.playing() ? 58 : 33;
|
||||
else if (color == "green")
|
||||
midiMsg.velocity = m_player.playing() ? 56 : 16;
|
||||
velocity = m_player.playing() ? 56 : 16;
|
||||
else if (color == "blue")
|
||||
midiMsg.velocity = m_player.playing() ? 49 : 51;
|
||||
velocity = m_player.playing() ? 49 : 51;
|
||||
else
|
||||
goto noColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
noColor:
|
||||
midiMsg.velocity = 0;
|
||||
velocity = 0;
|
||||
}
|
||||
|
||||
emit sendMidi(midiMsg);
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonPlay->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonPlay->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonPlay->learnSetting().note,
|
||||
.velocity = velocity
|
||||
});
|
||||
}
|
||||
|
||||
void DrumPadSampleWidget::updateStatus()
|
||||
@@ -309,27 +279,6 @@ void DrumPadSampleWidget::decodingFinished(const QAudioBuffer &buffer)
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
void DrumPadSampleWidget::learnPressed()
|
||||
{
|
||||
auto palette = m_ui->toolButtonLearn->palette();
|
||||
|
||||
if (m_learning)
|
||||
{
|
||||
palette.setColor(m_ui->toolButtonLearn->backgroundRole(), m_oldColor);
|
||||
palette.setBrush(m_ui->toolButtonLearn->backgroundRole(), m_oldBrush);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oldColor = palette.color(m_ui->toolButtonLearn->backgroundRole());
|
||||
m_oldBrush = palette.brush(m_ui->toolButtonLearn->backgroundRole());
|
||||
palette.setColor(m_ui->toolButtonLearn->backgroundRole(), Qt::red);
|
||||
palette.setBrush(m_ui->toolButtonLearn->backgroundRole(), Qt::red);
|
||||
}
|
||||
m_ui->toolButtonLearn->setPalette(palette);
|
||||
|
||||
m_learning = !m_learning;
|
||||
}
|
||||
|
||||
void DrumPadSampleWidget::startRequest()
|
||||
{
|
||||
if (m_networkAccessManager && m_file->filename)
|
||||
|
@@ -31,12 +31,6 @@ public:
|
||||
|
||||
void setFile(const QString &presetId, const drumpad_presets::File &file);
|
||||
|
||||
quint8 channel() const;
|
||||
void setChannel(quint8 channel);
|
||||
|
||||
quint8 note() const;
|
||||
void setNote(quint8 note);
|
||||
|
||||
int speed() const;
|
||||
void setSpeed(int speed);
|
||||
|
||||
@@ -45,7 +39,7 @@ public:
|
||||
|
||||
std::optional<int> choke() const;
|
||||
|
||||
void pressed(quint8 velocity);
|
||||
void pressed();
|
||||
void released();
|
||||
|
||||
void forceStop();
|
||||
@@ -55,8 +49,7 @@ public:
|
||||
|
||||
void writeSamples(frame_t *begin, frame_t *end);
|
||||
|
||||
bool isLearning() const { return m_learning; }
|
||||
void learn(quint8 channel, quint8 note);
|
||||
void midiReceived(const midi::MidiMessage &message);
|
||||
|
||||
void unsendColor();
|
||||
void sendColor();
|
||||
@@ -70,7 +63,6 @@ private slots:
|
||||
void updateStatus();
|
||||
void requestFinished();
|
||||
void decodingFinished(const QAudioBuffer &buffer);
|
||||
void learnPressed();
|
||||
|
||||
private:
|
||||
void startRequest();
|
||||
@@ -92,9 +84,5 @@ private:
|
||||
|
||||
quint8 m_padNr{};
|
||||
|
||||
bool m_learning{};
|
||||
QColor m_oldColor;
|
||||
QBrush m_oldBrush;
|
||||
|
||||
bool m_sendColors{};
|
||||
};
|
||||
|
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>140</width>
|
||||
<height>157</height>
|
||||
<width>135</width>
|
||||
<height>122</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
@@ -59,7 +59,7 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="MidiButton" name="pushButton">
|
||||
<widget class="MidiButton" name="pushButtonPlay">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
@@ -95,23 +95,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="channelSpinBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="noteSpinBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButtonLearn">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
|
@@ -64,15 +64,11 @@ void DrumPadWidget::loadSettings(DrumMachineSettings &settings)
|
||||
{
|
||||
m_settings = &settings;
|
||||
|
||||
m_ui->pushButtonUp->setChannel(m_settings->drumpadChannelPrevPreset());
|
||||
m_ui->pushButtonUp->setNote(m_settings->drumpadNotePrevPreset());
|
||||
m_ui->pushButtonDown->setChannel(m_settings->drumpadChannelNextPreset());
|
||||
m_ui->pushButtonDown->setNote(m_settings->drumpadNoteNextPreset());
|
||||
m_ui->pushButtonUp->setLearnSetting(m_settings->drumpadPrevPreset());
|
||||
m_ui->pushButtonDown->setLearnSetting(m_settings->drumpadNextPreset());
|
||||
|
||||
connect(m_ui->pushButtonUp, &MidiButton::channelChanged, m_settings, &DrumMachineSettings::setDrumpadChannelPrevPreset);
|
||||
connect(m_ui->pushButtonUp, &MidiButton::noteChanged, m_settings, &DrumMachineSettings::setDrumpadNotePrevPreset);
|
||||
connect(m_ui->pushButtonDown, &MidiButton::channelChanged, m_settings, &DrumMachineSettings::setDrumpadChannelNextPreset);
|
||||
connect(m_ui->pushButtonDown, &MidiButton::noteChanged, m_settings, &DrumMachineSettings::setDrumpadNoteNextPreset);
|
||||
connect(m_ui->pushButtonUp, &MidiButton::learnSettingChanged, m_settings, &DrumMachineSettings::setDrumpadPrevPreset);
|
||||
connect(m_ui->pushButtonDown, &MidiButton::learnSettingChanged, m_settings, &DrumMachineSettings::setDrumpadNextPreset);
|
||||
|
||||
m_ui->sequencerWidget->loadSettings(settings);
|
||||
m_ui->samplesWidget->loadSettings(settings);
|
||||
@@ -81,17 +77,17 @@ void DrumPadWidget::loadSettings(DrumMachineSettings &settings)
|
||||
void DrumPadWidget::unsendColors()
|
||||
{
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonUp->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonUp->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonUp->note(),
|
||||
.note = m_ui->pushButtonUp->learnSetting().note,
|
||||
.velocity = 0
|
||||
});
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonDown->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonDown->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonDown->note(),
|
||||
.note = m_ui->pushButtonDown->learnSetting().note,
|
||||
.velocity = 0
|
||||
});
|
||||
|
||||
@@ -102,17 +98,17 @@ void DrumPadWidget::unsendColors()
|
||||
void DrumPadWidget::sendColors()
|
||||
{
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonUp->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonUp->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonUp->note(),
|
||||
.note = m_ui->pushButtonUp->learnSetting().note,
|
||||
.velocity = 127
|
||||
});
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonDown->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonDown->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonDown->note(),
|
||||
.note = m_ui->pushButtonDown->learnSetting().note,
|
||||
.velocity = 127
|
||||
});
|
||||
|
||||
|
@@ -57,31 +57,27 @@ void LoopStationWidget::loadSettings(DrumMachineSettings &settings)
|
||||
{
|
||||
m_settings = &settings;
|
||||
|
||||
m_ui->pushButtonUp->setChannel(m_settings->loopstationChannelPrevPreset());
|
||||
m_ui->pushButtonUp->setNote(m_settings->loopstationNotePrevPreset());
|
||||
m_ui->pushButtonDown->setChannel(m_settings->loopstationChannelNextPreset());
|
||||
m_ui->pushButtonDown->setNote(m_settings->loopstationNoteNextPreset());
|
||||
m_ui->pushButtonUp->setLearnSetting(m_settings->loopstationPrevPreset());
|
||||
m_ui->pushButtonDown->setLearnSetting(m_settings->loopstationNextPreset());
|
||||
|
||||
connect(m_ui->pushButtonUp, &MidiButton::channelChanged, m_settings, &DrumMachineSettings::setLoopstationChannelPrevPreset);
|
||||
connect(m_ui->pushButtonUp, &MidiButton::noteChanged, m_settings, &DrumMachineSettings::setLoopstationNotePrevPreset);
|
||||
connect(m_ui->pushButtonDown, &MidiButton::channelChanged, m_settings, &DrumMachineSettings::setLoopstationChannelNextPreset);
|
||||
connect(m_ui->pushButtonDown, &MidiButton::noteChanged, m_settings, &DrumMachineSettings::setLoopstationNoteNextPreset);
|
||||
connect(m_ui->pushButtonUp, &MidiButton::learnSettingChanged, m_settings, &DrumMachineSettings::setLoopstationPrevPreset);
|
||||
connect(m_ui->pushButtonDown, &MidiButton::learnSettingChanged, m_settings, &DrumMachineSettings::setLoopstationNextPreset);
|
||||
}
|
||||
|
||||
void LoopStationWidget::unsendColors()
|
||||
{
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonUp->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonUp->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonUp->note(),
|
||||
.note = m_ui->pushButtonUp->learnSetting().note,
|
||||
.velocity = 0
|
||||
});
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonDown->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonDown->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonDown->note(),
|
||||
.note = m_ui->pushButtonDown->learnSetting().note,
|
||||
.velocity = 0
|
||||
});
|
||||
}
|
||||
@@ -89,17 +85,17 @@ void LoopStationWidget::unsendColors()
|
||||
void LoopStationWidget::sendColors()
|
||||
{
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonUp->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonUp->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonUp->note(),
|
||||
.note = m_ui->pushButtonUp->learnSetting().note,
|
||||
.velocity = 127
|
||||
});
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonDown->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonDown->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonDown->note(),
|
||||
.note = m_ui->pushButtonDown->learnSetting().note,
|
||||
.velocity = 127
|
||||
});
|
||||
}
|
||||
|
@@ -303,6 +303,10 @@ void MainWindow::updateMidiOutDevices()
|
||||
|
||||
void MainWindow::loadSettings()
|
||||
{
|
||||
for (int i = 0; i < m_ui->tabWidget->count(); i++)
|
||||
m_ui->tabWidget->setLearnSetting(i, m_settings.tabWidget(i));
|
||||
connect(m_ui->tabWidget, &MidiTabWidget::learnSettingChanged, &m_settings, &DrumMachineSettings::setTabWidget);
|
||||
|
||||
m_ui->drumPadWidget->loadSettings(m_settings);
|
||||
m_ui->loopStationWidget->loadSettings(m_settings);
|
||||
m_ui->djWidget->loadSettings(m_settings);
|
||||
@@ -311,6 +315,17 @@ void MainWindow::loadSettings()
|
||||
|
||||
void MainWindow::unsendColors(int index)
|
||||
{
|
||||
{
|
||||
const auto &learnSetting = m_ui->tabWidget->learnSetting(index);
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = learnSetting.channel,
|
||||
.cmd = learnSetting.cmd,
|
||||
.flag = true,
|
||||
.note = learnSetting.note,
|
||||
.velocity = 0
|
||||
});
|
||||
}
|
||||
|
||||
if (index == 0)
|
||||
m_ui->drumPadWidget->unsendColors();
|
||||
else if (index == 1)
|
||||
@@ -323,6 +338,17 @@ void MainWindow::unsendColors(int index)
|
||||
|
||||
void MainWindow::sendColors(int index)
|
||||
{
|
||||
{
|
||||
const auto &learnSetting = m_ui->tabWidget->learnSetting(index);
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = learnSetting.channel,
|
||||
.cmd = learnSetting.cmd,
|
||||
.flag = true,
|
||||
.note = learnSetting.note,
|
||||
.velocity = 3
|
||||
});
|
||||
}
|
||||
|
||||
if (index == 0)
|
||||
m_ui->drumPadWidget->sendColors();
|
||||
else if (index == 1)
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "midicontainers.h"
|
||||
#include "futurecpp.h"
|
||||
|
||||
MidiButton::MidiButton(QWidget *parent) :
|
||||
QPushButton{parent}
|
||||
@@ -13,6 +14,22 @@ MidiButton::MidiButton(QWidget *parent) :
|
||||
auto action = new QAction{tr("Learn...")};
|
||||
connect(action, &QAction::triggered, this, &MidiButton::learn);
|
||||
addAction(action);
|
||||
|
||||
{
|
||||
m_actionCmd = new QAction{tr("cmd:")};
|
||||
m_actionCmd->setDisabled(true);
|
||||
addAction(m_actionCmd);
|
||||
}
|
||||
{
|
||||
m_actionChannel = new QAction{tr("channel:")};
|
||||
m_actionChannel->setDisabled(true);
|
||||
addAction(m_actionChannel);
|
||||
}
|
||||
{
|
||||
m_actionNote = new QAction{tr("note:")};
|
||||
m_actionNote->setDisabled(true);
|
||||
addAction(m_actionNote);
|
||||
}
|
||||
}
|
||||
|
||||
MidiButton::MidiButton(const QString &text, QWidget *parent) :
|
||||
@@ -25,6 +42,16 @@ MidiButton::MidiButton(const QIcon &icon, const QString &text, QWidget *parent)
|
||||
{
|
||||
}
|
||||
|
||||
void MidiButton::setLearnSetting(const MidiLearnSetting &learnSetting)
|
||||
{
|
||||
if (m_learnSetting == learnSetting)
|
||||
return;
|
||||
emit learnSettingChanged(m_learnSetting = learnSetting);
|
||||
m_actionCmd->setText(tr("cmd: %0").arg(std::to_underlying(m_learnSetting.cmd)));
|
||||
m_actionChannel->setText(tr("channel: %0").arg(m_learnSetting.channel));
|
||||
m_actionNote->setText(tr("note: %0").arg(m_learnSetting.note));
|
||||
}
|
||||
|
||||
void MidiButton::learn()
|
||||
{
|
||||
auto palette = this->palette();
|
||||
@@ -48,38 +75,49 @@ void MidiButton::learn()
|
||||
|
||||
void MidiButton::midiReceived(const midi::MidiMessage &message)
|
||||
{
|
||||
if (message.cmd != midi::Command::NoteOn &&
|
||||
message.cmd != midi::Command::NoteOff &&
|
||||
message.cmd != midi::Command::ControlChange)
|
||||
return;
|
||||
|
||||
if (m_learning)
|
||||
{
|
||||
if ((message.cmd != midi::Command::NoteOn && message.cmd != midi::Command::ControlChange) || message.velocity == 0)
|
||||
return;
|
||||
|
||||
setChannel(message.channel);
|
||||
setNote(message.note);
|
||||
setLearnSetting(MidiLearnSetting{
|
||||
.cmd = message.cmd == midi::Command::NoteOff ? midi::Command::NoteOn : message.cmd,
|
||||
.channel = message.channel,
|
||||
.note = message.note
|
||||
});
|
||||
|
||||
learn();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (message.channel != m_channel || message.note != m_note)
|
||||
if (message.channel != m_learnSetting.channel ||
|
||||
message.note != m_learnSetting.note)
|
||||
return;
|
||||
|
||||
switch (message.cmd)
|
||||
if (m_learnSetting.cmd == midi::Command::NoteOn || m_learnSetting.cmd == midi::Command::NoteOff)
|
||||
{
|
||||
switch (message.cmd)
|
||||
{
|
||||
case midi::Command::NoteOn:
|
||||
if (message.velocity != 0)
|
||||
emit pressed();
|
||||
else
|
||||
Q_FALLTHROUGH();
|
||||
case midi::Command::NoteOff:
|
||||
emit released();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (m_learnSetting.cmd == message.cmd)
|
||||
{
|
||||
case midi::Command::NoteOn:
|
||||
case midi::Command::ControlChange:
|
||||
if (message.velocity != 0)
|
||||
emit pressed();
|
||||
else
|
||||
Q_FALLTHROUGH();
|
||||
case midi::Command::NoteOff:
|
||||
emit released();
|
||||
break;
|
||||
default:
|
||||
__builtin_unreachable();
|
||||
emit released();
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -2,38 +2,39 @@
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
#include "midilearnsetting.h"
|
||||
|
||||
namespace midi { struct MidiMessage; }
|
||||
class QAction;
|
||||
|
||||
class MidiButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(quint8 channel READ channel WRITE setChannel NOTIFY channelChanged)
|
||||
Q_PROPERTY(quint8 note READ note WRITE setNote NOTIFY noteChanged)
|
||||
Q_PROPERTY(MidiLearnSetting learnSetting READ learnSetting WRITE setLearnSetting NOTIFY learnSettingChanged)
|
||||
|
||||
public:
|
||||
explicit MidiButton(QWidget *parent = nullptr);
|
||||
explicit MidiButton(const QString &text, QWidget *parent = nullptr);
|
||||
MidiButton(const QIcon& icon, const QString &text, QWidget *parent = nullptr);
|
||||
|
||||
quint8 channel() const { return m_channel; }
|
||||
void setChannel(quint8 channel) { if (channel == m_channel) return; emit channelChanged(m_channel = channel); }
|
||||
|
||||
quint8 note() const { return m_note; }
|
||||
void setNote(quint8 note) { if (note == m_note) return; emit noteChanged(m_note = note); }
|
||||
MidiLearnSetting learnSetting() const { return m_learnSetting; }
|
||||
void setLearnSetting(const MidiLearnSetting &learnSetting);
|
||||
|
||||
signals:
|
||||
void channelChanged(quint8 channel);
|
||||
void noteChanged(quint8 note);
|
||||
void learnSettingChanged(const MidiLearnSetting &learnSetting);
|
||||
|
||||
public slots:
|
||||
void learn();
|
||||
void midiReceived(const midi::MidiMessage &message);
|
||||
|
||||
private:
|
||||
quint8 m_channel{99};
|
||||
quint8 m_note{99};
|
||||
MidiLearnSetting m_learnSetting;
|
||||
|
||||
bool m_learning{};
|
||||
QColor m_oldColor;
|
||||
QBrush m_oldBrush;
|
||||
|
||||
QAction *m_actionCmd{};
|
||||
QAction *m_actionChannel{};
|
||||
QAction *m_actionNote{};
|
||||
};
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "midicontainers.h"
|
||||
#include "futurecpp.h"
|
||||
|
||||
MidiTabWidget::MidiTabWidget(QWidget *parent) :
|
||||
QTabWidget{parent}
|
||||
@@ -14,30 +15,16 @@ MidiTabWidget::MidiTabWidget(QWidget *parent) :
|
||||
connect(tabBar(), &QWidget::customContextMenuRequested, this, &MidiTabWidget::showContextMenu);
|
||||
}
|
||||
|
||||
quint8 MidiTabWidget::channel(int index) const
|
||||
MidiLearnSetting MidiTabWidget::learnSetting(int index) const
|
||||
{
|
||||
return m_channelNotes[index].channel;
|
||||
return m_learnSettings[index];
|
||||
}
|
||||
|
||||
void MidiTabWidget::setChannel(int index, quint8 channel)
|
||||
void MidiTabWidget::setLearnSetting(int index, const MidiLearnSetting &learnSetting)
|
||||
{
|
||||
auto &channelNote = m_channelNotes[index];
|
||||
if (channelNote.channel == channel)
|
||||
if (learnSetting == m_learnSettings[index])
|
||||
return;
|
||||
emit channelChanged(index, channelNote.channel = channel);
|
||||
}
|
||||
|
||||
quint8 MidiTabWidget::note(int index) const
|
||||
{
|
||||
return m_channelNotes[index].note;
|
||||
}
|
||||
|
||||
void MidiTabWidget::setNote(int index, quint8 note)
|
||||
{
|
||||
auto &channelNote = m_channelNotes[index];
|
||||
if (channelNote.note == note)
|
||||
return;
|
||||
emit noteChanged(index, channelNote.note = note);
|
||||
emit learnSettingChanged(index, m_learnSettings[index] = learnSetting);
|
||||
}
|
||||
|
||||
void MidiTabWidget::learn(int index)
|
||||
@@ -67,18 +54,21 @@ void MidiTabWidget::midiReceived(const midi::MidiMessage &message)
|
||||
|
||||
if (m_learning)
|
||||
{
|
||||
qDebug() << "learning" << message.cmd << message.velocity << message.channel << message.note;
|
||||
setChannel(*m_learning, message.channel);
|
||||
setNote(*m_learning, message.note);
|
||||
setLearnSetting(*m_learning, MidiLearnSetting{
|
||||
.cmd = message.cmd == midi::Command::NoteOff ? midi::Command::NoteOn : message.cmd,
|
||||
.channel = message.channel,
|
||||
.note = message.note
|
||||
});
|
||||
|
||||
learn(*m_learning);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "normal" << message.cmd << message.velocity << message.channel << message.note;
|
||||
for (int i = 0; i < count(); i++)
|
||||
{
|
||||
if (message.channel != m_channelNotes[i].channel ||
|
||||
message.note != m_channelNotes[i].note)
|
||||
if (message.cmd != m_learnSettings[i].cmd ||
|
||||
message.channel != m_learnSettings[i].channel ||
|
||||
message.note != m_learnSettings[i].note)
|
||||
continue;
|
||||
|
||||
setCurrentIndex(i);
|
||||
@@ -90,13 +80,13 @@ void MidiTabWidget::midiReceived(const midi::MidiMessage &message)
|
||||
void MidiTabWidget::tabInserted(int index)
|
||||
{
|
||||
QTabWidget::tabInserted(index);
|
||||
m_channelNotes.insert(std::begin(m_channelNotes) + index, ChannelNote{.channel=quint8(index)});
|
||||
m_learnSettings.insert(std::begin(m_learnSettings) + index, MidiLearnSetting{});
|
||||
}
|
||||
|
||||
void MidiTabWidget::tabRemoved(int index)
|
||||
{
|
||||
QTabWidget::tabInserted(index);
|
||||
m_channelNotes.erase(std::begin(m_channelNotes) + index);
|
||||
m_learnSettings.erase(std::begin(m_learnSettings) + index);
|
||||
}
|
||||
|
||||
void MidiTabWidget::showContextMenu(const QPoint &pos)
|
||||
@@ -107,6 +97,12 @@ void MidiTabWidget::showContextMenu(const QPoint &pos)
|
||||
|
||||
QMenu menu{tabBar()};
|
||||
const auto learnAction = menu.addAction(tr("Learn..."));
|
||||
{
|
||||
const auto &learnSetting = m_learnSettings[index];
|
||||
menu.addAction(tr("cmd: %0").arg(std::to_underlying(learnSetting.cmd)))->setDisabled(true);
|
||||
menu.addAction(tr("channel: %0").arg(learnSetting.channel))->setDisabled(true);
|
||||
menu.addAction(tr("note: %0").arg(learnSetting.note))->setDisabled(true);
|
||||
}
|
||||
if (const auto selectedAction = menu.exec(tabBar()->mapToGlobal(pos));
|
||||
selectedAction == learnAction)
|
||||
{
|
||||
|
@@ -5,6 +5,8 @@
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "midilearnsetting.h"
|
||||
|
||||
namespace midi { struct MidiMessage; }
|
||||
|
||||
class MidiTabWidget : public QTabWidget
|
||||
@@ -14,15 +16,11 @@ class MidiTabWidget : public QTabWidget
|
||||
public:
|
||||
explicit MidiTabWidget(QWidget *parent = nullptr);
|
||||
|
||||
quint8 channel(int index) const;
|
||||
void setChannel(int index, quint8 channel);
|
||||
|
||||
quint8 note(int index) const;
|
||||
void setNote(int index, quint8 note);
|
||||
MidiLearnSetting learnSetting(int index) const;
|
||||
void setLearnSetting(int index, const MidiLearnSetting &learnSetting);
|
||||
|
||||
signals:
|
||||
void channelChanged(int index, quint8 channel);
|
||||
void noteChanged(int index, quint8 note);
|
||||
void learnSettingChanged(int index, const MidiLearnSetting &learnSetting);
|
||||
|
||||
public slots:
|
||||
void learn(int index);
|
||||
@@ -39,10 +37,5 @@ private:
|
||||
std::optional<int> m_learning;
|
||||
QColor m_oldColor;
|
||||
|
||||
struct ChannelNote
|
||||
{
|
||||
quint8 channel{99};
|
||||
quint8 note{99};
|
||||
};
|
||||
std::vector<ChannelNote> m_channelNotes;
|
||||
std::vector<MidiLearnSetting> m_learnSettings;
|
||||
};
|
||||
|
@@ -36,23 +36,15 @@ SequencerWidget::~SequencerWidget() = default;
|
||||
|
||||
void SequencerWidget::loadSettings(DrumMachineSettings &settings)
|
||||
{
|
||||
m_ui->pushButtonUp->setChannel(settings.drumpadChannelPrevSequence());
|
||||
m_ui->pushButtonUp->setNote(settings.drumpadNotePrevSequence());
|
||||
m_ui->pushButtonDown->setChannel(settings.drumpadChannelNextSequence());
|
||||
m_ui->pushButtonDown->setNote(settings.drumpadNoteNextSequence());
|
||||
m_ui->pushButtonPlayPause->setChannel(settings.drumpadChannelPlayPause());
|
||||
m_ui->pushButtonPlayPause->setNote(settings.drumpadNotePlayPause());
|
||||
m_ui->pushButtonStop->setChannel(settings.drumpadChannelStop());
|
||||
m_ui->pushButtonStop->setNote(settings.drumpadNoteStop());
|
||||
m_ui->pushButtonUp->setLearnSetting(settings.drumpadPrevSequence());
|
||||
m_ui->pushButtonDown->setLearnSetting(settings.drumpadNextSequence());
|
||||
m_ui->pushButtonPlayPause->setLearnSetting(settings.drumpadPlayPause());
|
||||
m_ui->pushButtonStop->setLearnSetting(settings.drumpadStop());
|
||||
|
||||
connect(m_ui->pushButtonUp, &MidiButton::channelChanged, &settings, &DrumMachineSettings::setDrumpadChannelPrevSequence);
|
||||
connect(m_ui->pushButtonUp, &MidiButton::noteChanged, &settings, &DrumMachineSettings::setDrumpadNotePrevSequence);
|
||||
connect(m_ui->pushButtonDown, &MidiButton::channelChanged, &settings, &DrumMachineSettings::setDrumpadChannelNextSequence);
|
||||
connect(m_ui->pushButtonDown, &MidiButton::noteChanged, &settings, &DrumMachineSettings::setDrumpadNoteNextSequence);
|
||||
connect(m_ui->pushButtonPlayPause, &MidiButton::channelChanged, &settings, &DrumMachineSettings::setDrumpadChannelPlayPause);
|
||||
connect(m_ui->pushButtonPlayPause, &MidiButton::noteChanged, &settings, &DrumMachineSettings::setDrumpadNotePlayPause);
|
||||
connect(m_ui->pushButtonStop, &MidiButton::channelChanged, &settings, &DrumMachineSettings::setDrumpadChannelStop);
|
||||
connect(m_ui->pushButtonStop, &MidiButton::noteChanged, &settings, &DrumMachineSettings::setDrumpadNoteStop);
|
||||
connect(m_ui->pushButtonUp, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadPrevSequence);
|
||||
connect(m_ui->pushButtonDown, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadNextSequence);
|
||||
connect(m_ui->pushButtonPlayPause, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadPlayPause);
|
||||
connect(m_ui->pushButtonStop, &MidiButton::learnSettingChanged, &settings, &DrumMachineSettings::setDrumpadStop);
|
||||
}
|
||||
|
||||
void SequencerWidget::unsendColors()
|
||||
@@ -60,31 +52,31 @@ void SequencerWidget::unsendColors()
|
||||
m_sendColors = false;
|
||||
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonUp->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonUp->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonUp->note(),
|
||||
.note = m_ui->pushButtonUp->learnSetting().note,
|
||||
.velocity = 0
|
||||
});
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonDown->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonDown->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonDown->note(),
|
||||
.note = m_ui->pushButtonDown->learnSetting().note,
|
||||
.velocity = 0
|
||||
});
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonPlayPause->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonPlayPause->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonPlayPause->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonPlayPause->note(),
|
||||
.note = m_ui->pushButtonPlayPause->learnSetting().note,
|
||||
.velocity = 0
|
||||
});
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonStop->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonStop->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonStop->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonStop->note(),
|
||||
.note = m_ui->pushButtonStop->learnSetting().note,
|
||||
.velocity = 0
|
||||
});
|
||||
}
|
||||
@@ -94,31 +86,31 @@ void SequencerWidget::sendColors()
|
||||
m_sendColors = true;
|
||||
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonUp->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonUp->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonUp->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonUp->note(),
|
||||
.note = m_ui->pushButtonUp->learnSetting().note,
|
||||
.velocity = 127
|
||||
});
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonDown->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonDown->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonDown->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonDown->note(),
|
||||
.note = m_ui->pushButtonDown->learnSetting().note,
|
||||
.velocity = 127
|
||||
});
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonPlayPause->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonPlayPause->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonPlayPause->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonPlayPause->note(),
|
||||
.note = m_ui->pushButtonPlayPause->learnSetting().note,
|
||||
.velocity = 60
|
||||
});
|
||||
emit sendMidi(midi::MidiMessage {
|
||||
.channel = m_ui->pushButtonStop->channel(),
|
||||
.cmd = midi::Command::NoteOn,
|
||||
.channel = m_ui->pushButtonStop->learnSetting().channel,
|
||||
.cmd = m_ui->pushButtonStop->learnSetting().cmd,
|
||||
.flag = true,
|
||||
.note = m_ui->pushButtonStop->note(),
|
||||
.note = m_ui->pushButtonStop->learnSetting().note,
|
||||
.velocity = 3
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user