--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/AlsaBridge.cpp Fri Dec 18 23:19:32 2020 +0100
@@ -0,0 +1,56 @@
+/**
+ * DJM-Fix
+ * Copyright © 2020 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <iostream>
+
+#include "AlsaBridge.h"
+
+namespace djmfix {
+namespace alsa {
+
+class AlsaBridgeImpl : public AlsaBridge, private djmfix::MidiSender {
+private:
+ djmfix::DJMFix* djmFix;
+public:
+
+ AlsaBridgeImpl(djmfix::DJMFix* djmFix) : djmFix(djmFix) {
+ djmFix->setMidiSender(this);
+ }
+
+ virtual ~AlsaBridgeImpl() {
+ std::cerr << "~AlsaBridgeImpl()" << std::endl; // TODO: do not mess STDIO
+ }
+
+ virtual void start() override {
+ djmFix->start();
+ }
+
+ virtual void stop() override {
+ djmFix->stop();
+ }
+
+ virtual void send(MidiMessage midiMessage) override {
+ std::cerr << "AlsaBridgeImpl::send()" << std::endl; // TODO: do not mess STDIO
+ }
+
+};
+
+AlsaBridge* create(djmfix::DJMFix* djmFix) {
+ return new AlsaBridgeImpl(djmFix);
+}
+
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/AlsaBridge.h Fri Dec 18 23:19:32 2020 +0100
@@ -0,0 +1,35 @@
+/**
+ * DJM-Fix
+ * Copyright © 2020 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "DJMFix.h"
+
+namespace djmfix {
+namespace alsa {
+
+class AlsaBridge {
+public:
+ virtual ~AlsaBridge() = default;
+ virtual void start() = 0;
+ virtual void stop() = 0;
+
+};
+
+AlsaBridge* create(djmfix::DJMFix* djmFix);
+
+}
+}
\ No newline at end of file
--- a/DJMFix.cpp Fri Dec 18 21:35:36 2020 +0100
+++ b/DJMFix.cpp Fri Dec 18 23:19:32 2020 +0100
@@ -15,6 +15,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
+#include <thread>
+#include <chrono>
+#include <stdexcept>
#include "DJMFix.h"
@@ -22,34 +25,55 @@
class DJMFixImpl : public DJMFix {
private:
- MidiSender midiSender;
-public:
+ MidiSender* midiSender;
+ std::thread keepAliveThread;
+ bool running = false;
+ bool stopped = false;
- DJMFixImpl(MidiSender midiSender) : midiSender(midiSender) {
- std::cerr << "DJMFixImpl()" << std::endl; // TODO: do not mess STDIO
+ void run() {
+ while (!stopped) {
+ std::cerr << "DJMFixImpl::run()" << std::endl; // TODO: do not mess STDIO
+ // TODO: send keep-alive messages
+ std::this_thread::sleep_for(std::chrono::milliseconds(200));
+ }
}
+public:
+
virtual ~DJMFixImpl() override {
std::cerr << "~DJMFixImpl()" << std::endl; // TODO: do not mess STDIO
+ if (running) stop();
+ }
+
+ void setMidiSender(MidiSender* midiSender) {
+ std::cerr << "DJMFixImpl::setMidiSender()" << std::endl; // TODO: do not mess STDIO
+ this->midiSender = midiSender;
}
virtual void receive(MidiMessage midiMessage) override {
std::cerr << "DJMFixImpl::receive()" << std::endl; // TODO: do not mess STDIO
-
- midiSender({0xf0, 0xf7});
}
void start() override {
std::cerr << "DJMFixImpl::start()" << std::endl; // TODO: do not mess STDIO
+ if (midiSender == nullptr) throw std::logic_error("need a midiSender when starting");
+ midiSender->send({0xf0, 0xf7});
+
+ keepAliveThread = std::thread(&DJMFixImpl::run, this);
+ running = true;
+
}
void stop() override {
+ stopped = true;
+ keepAliveThread.join();
+ running = false;
std::cerr << "DJMFixImpl::stop()" << std::endl; // TODO: do not mess STDIO
}
};
-DJMFix* create(MidiSender midiSender) {
- return new DJMFixImpl(midiSender);
+DJMFix* create() {
+ return new DJMFixImpl();
}
}
--- a/DJMFix.h Fri Dec 18 21:35:36 2020 +0100
+++ b/DJMFix.h Fri Dec 18 23:19:32 2020 +0100
@@ -17,21 +17,26 @@
#pragma once
#include <vector>
-#include <functional>
namespace djmfix {
using MidiMessage = std::vector<uint8_t>;
-using MidiSender = std::function<void(MidiMessage) >;
+
+class MidiSender {
+public:
+ virtual ~MidiSender() = default;
+ virtual void send(MidiMessage midiMessage) = 0;
+};
class DJMFix {
public:
virtual ~DJMFix() = default;
+ virtual void setMidiSender(MidiSender* midiSender) = 0;
virtual void receive(MidiMessage midiMessage) = 0;
virtual void start() = 0;
virtual void stop() = 0;
};
-DJMFix* create(MidiSender midiSender);
+DJMFix* create();
}
--- a/Makefile Fri Dec 18 21:35:36 2020 +0100
+++ b/Makefile Fri Dec 18 23:19:32 2020 +0100
@@ -23,6 +23,6 @@
.PHONY: all clean run
-build/djm-fix: DJMFix.cpp DJMFix.h djm-fix.cpp
+build/djm-fix: DJMFix.cpp DJMFix.h AlsaBridge.cpp AlsaBridge.h djm-fix.cpp
mkdir -p build
- g++ -o $@ DJMFix.cpp djm-fix.cpp
+ g++ -o $@ DJMFix.cpp AlsaBridge.cpp djm-fix.cpp -lpthread
--- a/djm-fix.cpp Fri Dec 18 21:35:36 2020 +0100
+++ b/djm-fix.cpp Fri Dec 18 23:19:32 2020 +0100
@@ -17,19 +17,28 @@
#include <memory>
#include <iostream>
+#include <chrono>
+#include <thread>
+#include <csignal>
#include "DJMFix.h"
+#include "AlsaBridge.h"
+
+volatile static bool run = true;
+
+void interrupt(int signal) {
+ run = false;
+ std::cerr << "interrupt()" << std::endl; // TODO: do not mess STDIO
+}
int main(int argc, char**argv) {
-
- std::shared_ptr<djmfix::DJMFix> djmFix(djmfix::create([](djmfix::MidiMessage midiMessage) {
- std::cerr << "main: will send midiMessage" << std::endl; // TODO: do not mess STDIO
- }));
+ signal(SIGINT, interrupt);
+ std::unique_ptr<djmfix::DJMFix> djmFix(djmfix::create());
+ std::unique_ptr<djmfix::alsa::AlsaBridge> alsaBridge(djmfix::alsa::create(djmFix.get()));
- djmFix->start();
- djmFix->receive({0xf0, 0xf7});
- djmFix->stop();
-
+ alsaBridge->start();
+ while (run) std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ alsaBridge->stop();
return 0;
}