diff --git a/DrumMachine.pro b/DrumMachine.pro index 6156b5c..85fbc6c 100755 --- a/DrumMachine.pro +++ b/DrumMachine.pro @@ -11,6 +11,11 @@ win32: { LIBS += -lwinmm } +unix: { + DEFINES += __LINUX_ALSA__ + LIBS += -lasound +} + DEFINES += QT_DEPRECATED_WARNINGS QT_DISABLE_DEPRECATED_BEFORE=0x060000 SOURCES += \ diff --git a/mainwindow.cpp b/mainwindow.cpp index 5602e99..bce1d3b 100755 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -17,9 +17,12 @@ MainWindow::MainWindow(const presets::PresetsConfig &presetsConfig, QWidget *par m_presetsModel{*presetsConfig.presets} { m_ui->setupUi(this); + m_ui->splitter->setSizes({99999, 1}); connect(&m_midiIn, &MidiInWrapper::messageReceived, this, &MainWindow::messageReceived); + connect(m_ui->sequencerWidget, &SequencerWidget::triggerSample, m_ui->samplesWidget, &SamplesWidget::sequencerTriggerSample); + updateMidiDevices(); connect(m_ui->pushButtonMidiController, &QAbstractButton::pressed, this, [this](){ @@ -99,6 +102,7 @@ void MainWindow::currentRowChanged(const QModelIndex ¤t) m_ui->presetDetailWidget->setPreset(preset); m_filesModel.setPreset(preset); + m_ui->sequencerWidget->setPreset(preset); m_ui->samplesWidget->setPreset(preset); } diff --git a/mainwindow.ui b/mainwindow.ui index ca925ae..1e6a8a2 100755 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -192,7 +192,16 @@ - + + + + + + + + + + @@ -222,6 +231,12 @@
presetdetailwidget.h
1 + + SequencerWidget + QWidget +
sequencerwidget.h
+ 1 +
diff --git a/sampleswidget.cpp b/sampleswidget.cpp index 63a394e..d364ad3 100755 --- a/sampleswidget.cpp +++ b/sampleswidget.cpp @@ -28,8 +28,6 @@ SamplesWidget::SamplesWidget(QWidget *parent) : for (const auto &ref : getWidgets()) connect(&ref.get(), &SampleWidget::chokeTriggered, this, &SamplesWidget::chokeTriggered); - connect(m_ui->sequencerWidget, &SequencerWidget::triggerSample, this, &SamplesWidget::sequencerTriggerSample); - m_ui->sampleWidget_1->setNote(48); m_ui->sampleWidget_2->setNote(50); m_ui->sampleWidget_3->setNote(52); @@ -58,8 +56,6 @@ void SamplesWidget::setPreset(const presets::Preset &preset) { m_preset = preset; - m_ui->sequencerWidget->setPreset(preset); - updateWidgets(); } @@ -95,6 +91,17 @@ void SamplesWidget::setAudioDevice(const QAudioDeviceInfo &device) } } +void SamplesWidget::sequencerTriggerSample(int index) +{ + const auto widgets = getWidgets(); + if (index < 0 || index >= std::size(widgets)) + { + qDebug() << "index out of range" << index; + return; + } + widgets[index].get().pressed(127); +} + void SamplesWidget::chokeTriggered(int choke) { for (const auto &ref : getWidgets()) @@ -124,17 +131,6 @@ void SamplesWidget::updateWidgets() widgetsIter->get().setFile(*m_preset.id, *filesIter); } -void SamplesWidget::sequencerTriggerSample(int index) -{ - const auto widgets = getWidgets(); - if (index < 0 || index >= std::size(widgets)) - { - qDebug() << "index out of range" << index; - return; - } - widgets[index].get().pressed(127); -} - void SamplesWidget::stopAll() { for (const auto &ref : getWidgets()) diff --git a/sampleswidget.h b/sampleswidget.h index 293ad9d..9acda04 100755 --- a/sampleswidget.h +++ b/sampleswidget.h @@ -28,10 +28,12 @@ public: void setAudioDevice(const QAudioDeviceInfo &device); +public slots: + void sequencerTriggerSample(int index); + private slots: void chokeTriggered(int choke); void updateWidgets(); - void sequencerTriggerSample(int index); void stopAll(); private: diff --git a/sampleswidget.ui b/sampleswidget.ui index 26e2c96..bb7c46e 100755 --- a/sampleswidget.ui +++ b/sampleswidget.ui @@ -13,145 +13,26 @@ Form - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - + + + + + + + + + + + + + + + + @@ -166,30 +47,6 @@ - - - - Sequencer - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - @@ -219,19 +76,99 @@ - - + + + + + + + + - Qt::Vertical + Qt::Horizontal - 20 - 40 + 40 + 20 + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -241,12 +178,6 @@
samplewidget.h
1 - - SequencerWidget - QWidget -
sequencerwidget.h
- 1 -
diff --git a/samplewidget.cpp b/samplewidget.cpp index 85dccae..4a66e6d 100755 --- a/samplewidget.cpp +++ b/samplewidget.cpp @@ -2,7 +2,6 @@ #include "ui_samplewidget.h" #include -#include #include #include @@ -32,14 +31,14 @@ SampleWidget::SampleWidget(QWidget *parent) : connect(m_ui->pushButton, &QAbstractButton::pressed, this, [this](){ pressed(127); }); connect(m_ui->pushButton, &QAbstractButton::released, this, &SampleWidget::released); + connect(m_ui->toolButtonReload, &QAbstractButton::pressed, this, &SampleWidget::createEffect); updateStatus(); } SampleWidget::~SampleWidget() { - if (m_effect) - QMetaObject::invokeMethod(m_effect.get(), [effect=m_effect.release()](){ delete effect; }); + destroyEffect(); } void SampleWidget::setFile(const QString &presetId, const presets::File &file) @@ -112,7 +111,9 @@ void SampleWidget::pressed(quint8 velocity) Q_UNUSED(velocity) if (m_effect) + { QMetaObject::invokeMethod(m_effect.get(), &QSoundEffect::play); + } if (m_file && m_file->choke && *m_file->choke) emit chokeTriggered(*m_file->choke); @@ -130,8 +131,16 @@ void SampleWidget::forceStop() void SampleWidget::setupAudioThread(const QAudioDeviceInfo &device, QThread &thread) { - const auto setupEffect = [this,device](){ - m_effect = std::make_unique(device); + m_device = device; + m_thread = &thread; + + createEffect(); +} + +void SampleWidget::createEffect() +{ + QMetaObject::invokeMethod(QAbstractEventDispatcher::instance(m_thread), [this](){ + m_effect = std::make_unique(m_device); connect(m_effect.get(), &QSoundEffect::playingChanged, this, &SampleWidget::updateStatus); connect(m_effect.get(), &QSoundEffect::statusChanged, this, &SampleWidget::updateStatus); @@ -141,10 +150,7 @@ void SampleWidget::setupAudioThread(const QAudioDeviceInfo &device, QThread &thr m_effect->setSource(sampleUrl); QMetaObject::invokeMethod(this, &SampleWidget::updateStatus); - }; - - QMetaObject::invokeMethod(QAbstractEventDispatcher::instance(&thread), setupEffect); - //setupEffect(); + }); } void SampleWidget::updateStatus() @@ -183,6 +189,12 @@ void SampleWidget::updateStatus() m_ui->statusLabel->setText(toString(m_effect->status())); } +void SampleWidget::destroyEffect() +{ + if (m_effect) + QMetaObject::invokeMethod(m_effect.get(), [effect=m_effect.release()](){ delete effect; }); +} + QUrl SampleWidget::sampleUrl() const { if (!m_file || !m_file->filename) diff --git a/samplewidget.h b/samplewidget.h index 55084ed..56e4251 100755 --- a/samplewidget.h +++ b/samplewidget.h @@ -3,12 +3,12 @@ #include #include +#include #include "presets.h" namespace Ui { class SampleWidget; } class QThread; -class QAudioDeviceInfo; class QSoundEffect; class SampleWidget : public QFrame @@ -40,9 +40,12 @@ signals: void chokeTriggered(int choke); private slots: + void createEffect(); void updateStatus(); private: + void destroyEffect(); + QUrl sampleUrl() const; const std::unique_ptr m_ui; @@ -51,4 +54,7 @@ private: std::optional m_file; std::unique_ptr m_effect; + + QThread *m_thread{}; + QAudioDeviceInfo m_device; }; diff --git a/samplewidget.ui b/samplewidget.ui index 8fb911d..b696f55 100755 --- a/samplewidget.ui +++ b/samplewidget.ui @@ -33,7 +33,7 @@ - + diff --git a/sequencerwidget.cpp b/sequencerwidget.cpp index 91c82d5..1a18794 100755 --- a/sequencerwidget.cpp +++ b/sequencerwidget.cpp @@ -3,6 +3,8 @@ #include +#include + #include "presets.h" SequencerWidget::SequencerWidget(QWidget *parent) : @@ -30,6 +32,9 @@ void SequencerWidget::setPreset(const presets::Preset &preset) if (preset.tempo) m_ui->spinBoxTempo->setValue(*preset.tempo); + for (int i = 0; i < 24; i++) + qobject_cast(m_ui->gridLayout->itemAtPosition(2+(i*2), 0)->widget())->setText(*preset.files->at(i).filename); + m_selectedSequence = nullptr; m_ui->horizontalSlider->setMaximum(0); diff --git a/sequencerwidget.h b/sequencerwidget.h index 4d59ed8..d58f7dc 100755 --- a/sequencerwidget.h +++ b/sequencerwidget.h @@ -2,12 +2,14 @@ #include #include +#include #include #include namespace Ui { class SequencerWidget; } namespace presets { class Preset; class Sequence; } +class QLabel; class SequencerWidget : public QWidget { @@ -41,4 +43,5 @@ private: QTimer m_timer; int m_pos; + std::array m_sampleLabels; }; diff --git a/sequencerwidget.ui b/sequencerwidget.ui index 8c89b0c..420c010 100755 --- a/sequencerwidget.ui +++ b/sequencerwidget.ui @@ -6,16 +6,16 @@ 0 0 - 412 - 65 + 912 + 611 Form - + - + @@ -62,13 +62,457 @@ + + + + Qt::Horizontal + + + - - - Qt::Horizontal + + + true + + + + 0 + 0 + 878 + 921 + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + QFrame::VLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + TextLabel + + + + + + + TextLabel + + + + +