DJMFix.cpp
author František Kučera <franta-hg@frantovo.cz>
Sat, 19 Dec 2020 17:33:16 +0100
branchv_0
changeset 5 ef8f4023e32e
parent 2 f34476ab597f
child 6 bddcf2bf29f2
permissions -rw-r--r--
sending and receiving MIDI messages through ALSA (the dirty way)
     1 /**
     2  * DJM-Fix
     3  * Copyright © 2020 František Kučera (Frantovo.cz, GlobalCode.info)
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 3 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 #include <iostream>
    18 #include <iomanip>
    19 #include <thread>
    20 #include <atomic>
    21 #include <chrono>
    22 #include <stdexcept>
    23 
    24 #include "DJMFix.h"
    25 
    26 namespace djmfix {
    27 
    28 class DJMFixImpl : public DJMFix {
    29 private:
    30 	MidiSender* midiSender;
    31 	std::thread keepAliveThread;
    32 	std::atomic<bool> running{false};
    33 	std::atomic<bool> stopped{false};
    34 
    35 	void run() {
    36 		while (!stopped) {
    37 			std::cerr << "DJMFixImpl::run()" << std::endl; // TODO: do not mess STDIO
    38 			// TODO: send keep-alive messages
    39 			std::this_thread::sleep_for(std::chrono::milliseconds(200));
    40 		}
    41 	}
    42 
    43 	// TODO: remove
    44 	std::string toString(const MidiMessage& midiMessage) {
    45 		std::stringstream result;
    46 		for (uint8_t b : midiMessage) result << std::hex << std::setw(2) << std::setfill('0') << (int) b;
    47 		return result.str();
    48 	}
    49 
    50 public:
    51 
    52 	virtual ~DJMFixImpl() override {
    53 		std::cerr << "~DJMFixImpl()" << std::endl; // TODO: do not mess STDIO
    54 		if (running) stop();
    55 	}
    56 
    57 	void setMidiSender(MidiSender* midiSender) {
    58 		std::cerr << "DJMFixImpl::setMidiSender()" << std::endl; // TODO: do not mess STDIO
    59 		this->midiSender = midiSender;
    60 	}
    61 
    62 	virtual void receive(MidiMessage midiMessage) override {
    63 		std::cerr << "DJMFixImpl::receive(): size = " << midiMessage.size() << " data = " << toString(midiMessage) << std::endl; // TODO: do not mess STDIO
    64 
    65 		if (midiMessage.size() == 54 && midiMessage[9] == 0x13) {
    66 			std::cerr << "DJMFixImpl::receive(): got message with HashA and SeedE" << std::endl; // TODO: do not mess STDIO
    67 		}
    68 
    69 	}
    70 
    71 	void start() override {
    72 		std::cerr << "DJMFixImpl::start()" << std::endl; // TODO: do not mess STDIO
    73 		if (midiSender == nullptr) throw std::logic_error("need a midiSender when starting DJMFix");
    74 
    75 		// TODO: methods for parsing and constructing messages from parts (TLV)
    76 		midiSender->send({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x50, 0x01, 0xf7});
    77 		std::this_thread::sleep_for(std::chrono::milliseconds(10));
    78 		midiSender->send({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x12, 0x2a, 0x01, 0x0b, 0x50, 0x69, 0x6f, 0x6e, 0x65, 0x65, 0x72, 0x44, 0x4a, 0x02, 0x0b, 0x72, 0x65, 0x6b, 0x6f, 0x72, 0x64, 0x62, 0x6f, 0x78, 0x03, 0x12, 0x02, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0xf7});
    79 
    80 		keepAliveThread = std::thread(&DJMFixImpl::run, this);
    81 		running = true;
    82 
    83 	}
    84 
    85 	void stop() override {
    86 		stopped = true;
    87 		keepAliveThread.join();
    88 		running = false;
    89 		std::cerr << "DJMFixImpl::stop()" << std::endl; // TODO: do not mess STDIO
    90 	}
    91 };
    92 
    93 DJMFix* create() {
    94 	return new DJMFixImpl();
    95 }
    96 
    97 }