DJMFix.cpp
author František Kučera <franta-hg@frantovo.cz>
Mon, 04 Jan 2021 17:11:57 +0100
branchv_0
changeset 13 334b727f7516
parent 12 15d87fdd6e6c
permissions -rw-r--r--
improved logging and error messages
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     1
/**
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     2
 * DJM-Fix
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     3
 * Copyright © 2020 František Kučera (Frantovo.cz, GlobalCode.info)
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     4
 *
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     5
 * This program is free software: you can redistribute it and/or modify
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     6
 * it under the terms of the GNU General Public License as published by
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     7
 * the Free Software Foundation, version 3 of the License.
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     8
 *
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     9
 * This program is distributed in the hope that it will be useful,
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    12
 * GNU General Public License for more details.
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    13
 *
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    14
 * You should have received a copy of the GNU General Public License
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4ee5349be21d project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    16
 */
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    17
#include <iostream>
12
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
    18
#include <sstream>
5
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    19
#include <iomanip>
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    20
#include <thread>
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    21
#include <mutex>
5
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    22
#include <atomic>
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    23
#include <chrono>
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    24
#include <stdexcept>
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    25
#include <vector>
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    26
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    27
#include "DJMFix.h"
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    28
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    29
namespace djmfix {
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    30
12
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
    31
using L = djmfix::logging::Level;
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    32
using Bytes = std::vector<uint8_t>;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    33
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    34
class DJMFixImpl : public DJMFix {
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    35
private:
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    36
	MidiSender* midiSender;
12
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
    37
	djmfix::logging::Logger* logger;
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    38
	const int keepAliveInterval = 200;
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    39
	int keepAliveCounter = 0;
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    40
	std::thread keepAliveThread;
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    41
	std::recursive_mutex midiMutex;
5
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    42
	std::atomic<bool> running{false};
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    43
	std::atomic<bool> stopped{false};
8
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    44
	std::atomic<bool> sendKeepAlive{false};
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    45
	Bytes seed2;
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    46
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    47
	void run() {
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    48
		while (!stopped) {
12
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
    49
			logger->log(L::FINE, "DJMFixImpl::run()");
8
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    50
			if (sendKeepAlive) send({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x50, 0x01, 0xf7});
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    51
			std::this_thread::sleep_for(std::chrono::milliseconds(keepAliveInterval));
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    52
			keepAliveCounter++;
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    53
			if (keepAliveCounter % (60 * 1000 / keepAliveInterval) == 0) logger->log(L::INFO, "Still sending periodic keep-alive messages (each " + std::to_string(keepAliveInterval) + " ms).");
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    54
		}
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    55
	}
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    56
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    57
	void send(const MidiMessage& midiMessage) {
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    58
		std::lock_guard<std::recursive_mutex> lock(midiMutex);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    59
		midiSender->send(midiMessage);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    60
	}
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    61
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    62
	std::string toString(const Bytes& midiMessage) {
5
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    63
		std::stringstream result;
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    64
		for (uint8_t b : midiMessage) result << std::hex << std::setw(2) << std::setfill('0') << (int) b;
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    65
		return result.str();
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    66
	}
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    67
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    68
	Bytes normalize(const Bytes& data) {
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    69
		if (data.size() % 2) throw std::invalid_argument("Data before normalization must have even number of bytes.");
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    70
		Bytes result;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    71
		result.reserve(data.size() / 2);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    72
		for (size_t i = 0; i < data.size() / 2; i++) result.push_back((data[i * 2] & 0x0F) << 4 | (data[i * 2 + 1] & 0x0F));
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    73
		return result;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    74
	}
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    75
8
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    76
	Bytes denormalize(const Bytes& data) {
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    77
		Bytes result;
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    78
		result.reserve(data.size()*2);
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    79
		for (size_t i = 0; i < data.size(); i++) {
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    80
			result.push_back(data[i] >> 4);
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    81
			result.push_back(data[i] & 0x0F);
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    82
		}
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    83
		return result;
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    84
	}
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
    85
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    86
	uint32_t fnv32hash(const Bytes& buff) {
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    87
		uint32_t hash = 0x811c9dc5;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    88
		for (uint8_t b : buff) hash = ((b^hash) * 0x1000193);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    89
		return hash;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    90
	}
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    91
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    92
	Bytes toBytes(const uint32_t value) {
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    93
		Bytes result;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    94
		result.reserve(4);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    95
		result.push_back(value >> 24);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    96
		result.push_back(value >> 16);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    97
		result.push_back(value >> 8);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    98
		result.push_back(value >> 0);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    99
		return result;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   100
	}
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   101
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   102
	bool equals(Bytes a, Bytes b) {
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   103
		if (a.size() != b.size()) return false;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   104
		for (size_t i = 0; i < a.size(); i++) if (a[i] != b[i]) return false;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   105
		return true;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   106
	}
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   107
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   108
	template<typename T> std::vector<T> concat(const std::vector<T>& a, const std::vector<T>& b, const std::vector<T>& c = {}) {
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   109
		std::vector<T> result;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   110
		result.reserve(a.size() + b.size() + c.size());
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   111
		for (size_t i = 0; i < a.size(); i++) result.push_back(a[i]);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   112
		for (size_t i = 0; i < b.size(); i++) result.push_back(b[i]);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   113
		for (size_t i = 0; i < c.size(); i++) result.push_back(c[i]);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   114
		return result;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   115
	}
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   116
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   117
	template<typename T> std::vector<T> xOR(const std::vector<T>& a, const std::vector<T>& b) {
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   118
		if (a.size() != b.size()) throw std::invalid_argument("Both must be the same length when doing XOR.");
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   119
		std::vector<T> result;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   120
		result.reserve(a.size());
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   121
		for (size_t i = 0; i < a.size(); i++) result.push_back(a[i] ^ b[i]);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   122
		return result;
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   123
	}
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   124
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   125
public:
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   126
12
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   127
	DJMFixImpl(djmfix::logging::Logger* logger) : logger(logger ? logger : djmfix::logging::blackhole()) {
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   128
	}
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   129
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   130
	virtual ~DJMFixImpl() override {
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   131
		logger->log(L::FINER, "~DJMFixImpl()");
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   132
		if (running) stop();
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   133
	}
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   134
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   135
	void setMidiSender(MidiSender* midiSender) {
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   136
		logger->log(L::FINER, "DJMFixImpl::setMidiSender()");
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   137
		this->midiSender = midiSender;
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   138
	}
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   139
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   140
	virtual void receive(const MidiMessage& midiMessage) override {
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   141
		logger->log(L::FINE, "Received a message: size = " + std::to_string(midiMessage.size()) + " data = " + toString(midiMessage));
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   142
		std::lock_guard<std::recursive_mutex> lock(midiMutex);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   143
7
889b4b8737bd send the second message as a response (instead of after a fixed delay)
František Kučera <franta-hg@frantovo.cz>
parents: 6
diff changeset
   144
889b4b8737bd send the second message as a response (instead of after a fixed delay)
František Kučera <franta-hg@frantovo.cz>
parents: 6
diff changeset
   145
		if (midiMessage.size() == 12 && midiMessage[9] == 0x11) {
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   146
			logger->log(L::INFO, "Received greeting message.");
7
889b4b8737bd send the second message as a response (instead of after a fixed delay)
František Kučera <franta-hg@frantovo.cz>
parents: 6
diff changeset
   147
			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});
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   148
			logger->log(L::INFO, "Sent message with seed1.");
7
889b4b8737bd send the second message as a response (instead of after a fixed delay)
František Kučera <franta-hg@frantovo.cz>
parents: 6
diff changeset
   149
		} else if (midiMessage.size() == 54 && midiMessage[9] == 0x13 && midiMessage[33] == 0x04 && midiMessage[43] == 0x03) {
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   150
			Bytes hash1(midiMessage.begin() + 35, midiMessage.begin() + 35 + 8);
8
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   151
			seed2 = Bytes(midiMessage.begin() + 45, midiMessage.begin() + 45 + 8);
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   152
			hash1 = normalize(hash1);
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   153
			seed2 = normalize(seed2);
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   154
			logger->log(L::INFO, "Received message with hash1 = " + toString(hash1) + " and seed2 = " + toString(seed2));
5
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   155
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   156
			Bytes seed0 = {0x68, 0x01, 0x31, 0xFB};
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   157
			Bytes seed1 = {0x29, 0x00, 0x00, 0x00, 0x23, 0x48, 0x00, 0x00};
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   158
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   159
			Bytes hash1check = toBytes(fnv32hash(concat(seed1, xOR(seed0, seed2))));
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   160
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   161
			if (equals(hash1, hash1check)) {
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   162
				logger->log(L::INFO, "Verification of hash1 was successful.");
8
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   163
				Bytes hash2 = toBytes(fnv32hash(concat(seed2, xOR(seed0, seed2))));
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   164
				send(concat({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x14, 0x38, 0x01, 0x0b, 0x50, 0x69, 0x6f, 0x6e, 0x65, 0x65, 0x72, 0x44, 0x4a, 0x02, 0x0b, 0x72, 0x65, 0x6b, 0x6f, 0x72, 0x64, 0x62, 0x6f, 0x78, 0x04, 0x0a}, concat(denormalize(hash2),{0x05, 0x16, 0x05, 0x09, 0x0b, 0x05, 0x04, 0x0b, 0x0f, 0x0e, 0x0e, 0x04, 0x04, 0x0a, 0x05, 0x0a, 0x0c, 0x08, 0x0e, 0x04, 0x0c, 0x05, 0xf7})));
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   165
				logger->log(L::INFO, "Sent message with hash2.");
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   166
			} else {
12
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   167
				std::stringstream logMessage;
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   168
				logMessage
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   169
						<< "Verification of hash1 failed: "
8
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   170
						<< " midiMessage = " << toString(midiMessage)
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   171
						<< " seed0 = " << toString(seed0)
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   172
						<< " seed1 = " << toString(seed1)
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   173
						<< " seed2 = " << toString(seed2)
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   174
						<< " hash1 = " << toString(hash1)
12
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   175
						<< " hash1check = " << toString(hash1check);
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   176
				logger->log(L::SEVERE, logMessage.str());
8
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   177
				// TODO: graceful death
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   178
			}
8
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   179
		} else if (midiMessage.size() == 12 && midiMessage[9] == 0x15) {
87dfa7c89294 first working version (still dirty, but working)
František Kučera <franta-hg@frantovo.cz>
parents: 7
diff changeset
   180
			sendKeepAlive = true;
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   181
			logger->log(L::INFO, "Received acknowledgment message. Started sending keep-alive messages. LINE/PHONO channels should work now.");
5
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   182
		}
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   183
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   184
	}
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   185
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   186
	void start() override {
12
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   187
		logger->log(L::FINE, "DJMFixImpl::start()");
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   188
		if (midiSender == nullptr) throw std::logic_error("Need a midiSender when starting DJMFix");
5
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   189
ef8f4023e32e sending and receiving MIDI messages through ALSA (the dirty way)
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   190
		// TODO: methods for parsing and constructing messages from parts (TLV)
6
bddcf2bf29f2 verify the response from the mixer
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
   191
		send({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x50, 0x01, 0xf7});
13
334b727f7516 improved logging and error messages
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   192
		logger->log(L::INFO, "Sent greeting message.");
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   193
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   194
		keepAliveThread = std::thread(&DJMFixImpl::run, this);
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   195
		running = true;
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   196
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   197
	}
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   198
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   199
	void stop() override {
2
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   200
		stopped = true;
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   201
		keepAliveThread.join();
f34476ab597f background thread + AlsaBridge skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   202
		running = false;
12
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   203
		logger->log(L::FINE, "DJMFixImpl::stop()");
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   204
	}
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   205
};
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   206
12
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   207
DJMFix* create(djmfix::logging::Logger* logger) {
15d87fdd6e6c use Logger instead of messing with STDIO directly
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   208
	return new DJMFixImpl(logger);
1
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   209
}
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   210
98274757fcf6 more bones
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   211
}