From b740cfa4b6eb8c0621661f85232f2488cf127b13 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Sat, 10 Jun 2023 21:31:50 +0200 Subject: [PATCH] Work in progress --- midicontainers.h | 2 + midiinwrapper.cpp | 33 +- midiinwrapper.h | 4 + widgets/drumpadsettingsdialog.ui | 705 ++++++++++++++++++++------- widgets/loopstationsamplewidget.cpp | 17 +- widgets/loopstationsettingsdialog.ui | 475 +++++++++++++++--- widgets/mainwindow.cpp | 6 + widgets/mainwindow.h | 1 + widgets/synthisizerwidget.cpp | 36 +- widgets/synthisizerwidget.h | 3 +- widgets/synthisizerwidget.ui | 26 + 11 files changed, 1053 insertions(+), 255 deletions(-) diff --git a/midicontainers.h b/midicontainers.h index 0c4fed7..e7f987c 100755 --- a/midicontainers.h +++ b/midicontainers.h @@ -27,6 +27,8 @@ struct MidiMessage bool operator==(const MidiMessage &other) const; }; +static_assert(sizeof(MidiMessage) == 3); + } // namespace midi Q_DECLARE_METATYPE(midi::Command) diff --git a/midiinwrapper.cpp b/midiinwrapper.cpp index 5b646dd..41736fb 100755 --- a/midiinwrapper.cpp +++ b/midiinwrapper.cpp @@ -3,6 +3,9 @@ #include #include #include +#include + +#include #include "midicontainers.h" @@ -67,9 +70,37 @@ void MidiInWrapper::mycallback(double deltatime, std::vector *mes return; } + if (message->size() == 1) + { + if (const auto opcode = message->at(0); opcode == 250) + { + wrapper->m_counting = true; + wrapper->m_timerCounter = 0; + } + else if (opcode == 252) + { + wrapper->m_counting = false; + } + else if (opcode == 248) + { + if (wrapper->m_counting) + { + if (wrapper->m_timerCounter == 0 || wrapper->m_timerCounter == 12) + wrapper->onQuarterNote(); + wrapper->m_timerCounter++; + if (wrapper->m_timerCounter >= 24) + wrapper->m_timerCounter = 0; + } + } + else + qWarning() << "unknown opcode" << opcode; + + return; + } + if (message->size() < sizeof(midi::MidiMessage)) { - qCritical() << "called with message that is shorter than 3 bytes"; + qCritical() << "called with message that is shorter than 3 bytes (" << message->size() << ')'; return; } diff --git a/midiinwrapper.h b/midiinwrapper.h index b4f7a71..465ede6 100755 --- a/midiinwrapper.h +++ b/midiinwrapper.h @@ -26,9 +26,13 @@ public: signals: void midiReceived(const midi::MidiMessage &message); + void onQuarterNote(); private: static void mycallback(double deltatime, std::vector *message, void *userData); RtMidiIn midiIn; + + int m_timerCounter{}; + bool m_counting{true}; }; diff --git a/widgets/drumpadsettingsdialog.ui b/widgets/drumpadsettingsdialog.ui index 631165d..b5d6a80 100644 --- a/widgets/drumpadsettingsdialog.ui +++ b/widgets/drumpadsettingsdialog.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 326 + 439 + 585 @@ -15,36 +15,30 @@ - - - - - Color Prev Preset: - - - spinBoxColorPrevPreset - - - - - - - Color Next Preset: - - - spinBoxColorNextPreset - - - - - - - Color Prev Sequence: - - - spinBoxColorPrevSequence - - + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + @@ -56,33 +50,177 @@ - - + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + - Color Play Pause: + Color Other: - spinBoxColorPlayPause + ColorOtherPlaying - - + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + - Color Stop Sequence: + Color Green: - spinBoxColorStopSequence + ColorGreenPlaying - - + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + - Color Swap: + Color Purple: - spinBoxColorSwap + spinBoxColorPurplePlaying @@ -96,6 +234,13 @@ + + + + Idle + + + @@ -120,137 +265,47 @@ - - - - - - 255 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + Color Next Preset: + + + spinBoxColorNextPreset + + - - - - - - 255 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + Color Stop Sequence: + + + spinBoxColorStopSequence + + - - - - - - 255 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + Color Prev Sequence: + + + spinBoxColorPrevSequence + + - - + + - + 255 - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 255 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 255 - - - - - + Qt::Horizontal @@ -288,8 +343,328 @@ + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Playing + + + + + + + Color Blue: + + + ColorBluePlaying + + + + + + + Color Red: + + + spinBoxColorRedPlaying + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Color Yellow: + + + spinBoxColorYellowPlaying + + + + + + + Color Swap: + + + spinBoxColorSwap + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Color Prev Preset: + + + spinBoxColorPrevPreset + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Color Play Pause: + + + spinBoxColorPlayPause + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/widgets/loopstationsamplewidget.cpp b/widgets/loopstationsamplewidget.cpp index 7305997..2c5df30 100644 --- a/widgets/loopstationsamplewidget.cpp +++ b/widgets/loopstationsamplewidget.cpp @@ -124,13 +124,13 @@ void LoopStationSampleWidget::sendColor(bool force) if (m_player.buffer().isValid()) { if (m_category == 0) - newColor = m_player.playing() ? 44 : 47; //dunkelblue + newColor = m_player.playing() ? 44 : 47; // darkblue else if (m_category == 1) newColor = m_player.playing() ? 16 : 19; // green else if (m_category == 2) newColor = m_player.playing() ? 48 : 51; // violet else if (m_category == 3) - newColor = m_player.playing() ? 36 : 39; // hellblue + newColor = m_player.playing() ? 36 : 39; // lightblue else if (m_category == 4) newColor = m_player.playing() ? 8 : 11; // orange else if (m_category == 5) @@ -203,18 +203,19 @@ void LoopStationSampleWidget::updateStatus() #endif ; + if (m_category == 0) - newColor = QColor{bright, dark, bright}; + newColor = QColor{dark, dark, bright}; // darkblue else if (m_category == 1) - newColor = QColor{bright, dark, dark}; + newColor = QColor{dark, bright, dark}; // green else if (m_category == 2) - newColor = QColor{bright, bright, dark}; + newColor = QColor{bright, dark, bright}; // violet else if (m_category == 3) - newColor = QColor{dark, bright, dark}; + newColor = QColor{dark, bright, bright}; // lightblue else if (m_category == 4) - newColor = QColor{dark, dark, bright}; + newColor = QColor{bright, bright, dark}; // yellow else if (m_category == 5) - newColor = QColor{dark, bright, bright}; + newColor = QColor{bright, dark, dark}; // red else { qWarning() << "unknown category:" << m_category; diff --git a/widgets/loopstationsettingsdialog.ui b/widgets/loopstationsettingsdialog.ui index 52fc36d..2b95e8d 100644 --- a/widgets/loopstationsettingsdialog.ui +++ b/widgets/loopstationsettingsdialog.ui @@ -7,7 +7,7 @@ 0 0 439 - 230 + 435 @@ -15,82 +15,18 @@ - - - - - Color Prev Preset: - - - spinBoxColorPrevPreset - - - - - + + + - + 255 - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Color Next Preset: - - - spinBoxColorNextPreset - - - - - - - Color Play Pause: - - - spinBoxColorPlayPause - - - - - - - Color Stop: - - - spinBoxColorStop - - - - - - - - - 255 - - - - - + Qt::Horizontal @@ -128,17 +64,395 @@ - - + + + + Idle + + + + + - + 255 - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Playing + + + + + + + Color Category 0: + + + spinBox + + + + + + + Color Play Pause: + + + spinBoxColorPlayPause + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Color Stop: + + + spinBoxColorStop + + + + + + + Color Category 4: + + + spinBox_9 + + + + + + + Color Next Preset: + + + spinBoxColorNextPreset + + + + + + + Color Prev Preset: + + + spinBoxColorPrevPreset + + + + + + + Color Category 1: + + + spinBox_3 + + + + + + + Color Category 2: + + + spinBox_5 + + + + + + + Color Category 3 + + + spinBox_7 + + + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Color Category 5: + + + spinBox_11 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Qt::Horizontal @@ -154,6 +468,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 9636076..4602916 100755 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -46,6 +46,7 @@ MainWindow::MainWindow(QWidget *parent) : m_ui->loopStationWidget->injectNetworkAccessManager(m_networkAccessManager); connect(&m_midiIn, &MidiInWrapper::midiReceived, this, &MainWindow::midiReceived); + connect(&m_midiIn, &MidiInWrapper::onQuarterNote, this, &MainWindow::onQuarterNote); { QEventLoop eventLoop; @@ -327,6 +328,11 @@ void MainWindow::midiReceived(const midi::MidiMessage &message) m_ui->synthisizerWidget->midiReceived(message); } +void MainWindow::onQuarterNote() +{ + m_ui->synthisizerWidget->onQuarterNote(); +} + void MainWindow::sendMidi(const midi::MidiMessage &midiMsg) { if (m_midiOut.isPortOpen()) diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 9ebb76d..3ad454f 100755 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -33,6 +33,7 @@ private slots: void openMidiInDevice(); void openMidiOutDevice(); void midiReceived(const midi::MidiMessage &message); + void onQuarterNote(); void sendMidi(const midi::MidiMessage &midiMsg); void currentChanged(int index); diff --git a/widgets/synthisizerwidget.cpp b/widgets/synthisizerwidget.cpp index 932d1ec..2cb21dc 100644 --- a/widgets/synthisizerwidget.cpp +++ b/widgets/synthisizerwidget.cpp @@ -3,6 +3,9 @@ #include +#include +#include + #include "audioformat.h" #include "midicontainers.h" @@ -12,15 +15,20 @@ SynthisizerWidget::SynthisizerWidget(QWidget *parent) : { m_ui->setupUi(this); - connect(m_ui->horizontalSliderVolume, &QSlider::valueChanged, - &m_synthisizer, [&synthisizer=m_synthisizer](int value){ synthisizer.setVolume(float(value) / 100.f); }); + for (Synthisizer &synthisizer : m_synthisizers) + connect(m_ui->horizontalSliderVolume, &QSlider::valueChanged, + &synthisizer, [&synthisizer](int value){ synthisizer.setVolume(float(value) / 100.f); }); + +// m_synthisizers.at(8).setFrequency(1209); +// m_synthisizers.at(9).setFrequency(697); } SynthisizerWidget::~SynthisizerWidget() = default; void SynthisizerWidget::writeSamples(frame_t *begin, frame_t *end) { - m_synthisizer.writeSamples(begin, end); + for (Synthisizer &synthisizer : m_synthisizers) + synthisizer.writeSamples(begin, end); } void SynthisizerWidget::loadSettings(DrumMachineSettings &settings) @@ -38,11 +46,27 @@ void SynthisizerWidget::sendColors() void SynthisizerWidget::midiReceived(const midi::MidiMessage &message) { + auto freq = 440.*std::pow(std::pow(2., 1./12.), message.note-48); if (message.cmd == midi::Command::NoteOff || (message.cmd == midi::Command::NoteOn && message.velocity == 0)) { - if (m_synthisizer.frequency() == int16_t(440.*std::pow(std::pow(2., 1./12.), message.note-48))) - m_synthisizer.setFrequency(0); + for (Synthisizer &synthisizer : m_synthisizers) + if (synthisizer.frequency() == int16_t(freq)) + synthisizer.setFrequency(0); } else if (message.cmd == midi::Command::NoteOn) - m_synthisizer.setFrequency(440.*std::pow(std::pow(2., 1./12.), message.note-48)); + { + for (Synthisizer &synthisizer : m_synthisizers) + if (!synthisizer.frequency()) + { + synthisizer.setFrequency(freq); + break; + } + } +} + +void SynthisizerWidget::onQuarterNote() +{ + auto &synthisizer = m_synthisizers.back(); + synthisizer.setFrequency(440.); + QTimer::singleShot(6, &synthisizer, [&synthisizer](){ synthisizer.setFrequency(0.); }); } diff --git a/widgets/synthisizerwidget.h b/widgets/synthisizerwidget.h index 6d5db69..93290be 100644 --- a/widgets/synthisizerwidget.h +++ b/widgets/synthisizerwidget.h @@ -28,9 +28,10 @@ signals: public slots: void midiReceived(const midi::MidiMessage &message); + void onQuarterNote(); private: const std::unique_ptr m_ui; - Synthisizer m_synthisizer; + std::array m_synthisizers; }; diff --git a/widgets/synthisizerwidget.ui b/widgets/synthisizerwidget.ui index 4d88fb0..abdb571 100644 --- a/widgets/synthisizerwidget.ui +++ b/widgets/synthisizerwidget.ui @@ -58,6 +58,32 @@ horizontalSliderVolume + + + + 30 + 170 + 55 + 18 + + + + Bpm + + + + + + 110 + 170 + 62 + 27 + + + + 999.990000000000009 + +