# HG changeset patch # User František Kučera # Date 1608329972 -3600 # Node ID f34476ab597f43a7b0fe8aa073773651ce61b0cf # Parent 98274757fcf64e999d9643a8828e168559dd97ca background thread + AlsaBridge skeleton diff -r 98274757fcf6 -r f34476ab597f AlsaBridge.cpp --- /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 . + */ +#include + +#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); +} + +} +} diff -r 98274757fcf6 -r f34476ab597f AlsaBridge.h --- /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 . + */ +#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 diff -r 98274757fcf6 -r f34476ab597f DJMFix.cpp --- 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 . */ #include +#include +#include +#include #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(); } } diff -r 98274757fcf6 -r f34476ab597f DJMFix.h --- 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 -#include namespace djmfix { using MidiMessage = std::vector; -using MidiSender = std::function; + +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(); } diff -r 98274757fcf6 -r f34476ab597f Makefile --- 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 diff -r 98274757fcf6 -r f34476ab597f djm-fix.cpp --- 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 #include +#include +#include +#include #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::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::create()); + std::unique_ptr 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; }