Skip to content

Commit 073a66a

Browse files
committed
refactor
1 parent a74e5d0 commit 073a66a

File tree

3 files changed

+176
-173
lines changed

3 files changed

+176
-173
lines changed

src/Config.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
#include <string.h>
66
#include <map>
77
struct Config {
8-
std::string configPath = "config.ini";
9-
std::string keymapPath = "keymap.cfg";
8+
std::string configPath;
9+
std::string keymapPath;
1010
int altcmkp = 0;
11-
char keymap[256];
11+
char keymap[256]; // idx is midi key code (0-127, typically), value is vk code (1-254)
1212

13-
Config() {
14-
for (size_t i = 0; i < 255; i++) {
15-
keymap[i] = 0; // idx is midi key code (0-127, typically), value is vk code (1-254)
16-
}
13+
void use(std::string configPath, std::string keymapPath) {
14+
this->configPath = configPath;
15+
this->keymapPath = keymapPath;
1716
}
1817

1918
void save() {
@@ -25,22 +24,23 @@ struct Config {
2524
out.open(keymapPath);
2625
if (out) out.write(keymap, 256);
2726
out.close();
28-
return;
2927
}
3028

3129
void load() {
3230
ini::IniFile storage;
3331
storage.load(configPath);
3432
if (storage["Compatibility"]["altcmkp"].as<std::string>() != "") altcmkp = storage["Compatibility"]["altcmkp"].as<int>();
3533

34+
for (size_t i = 0; i < 255; i++) {
35+
keymap[i] = 0;
36+
}
3637
std::ifstream in;
3738
in.open(keymapPath);
3839
if (in) in.getline(keymap, 256);
3940
in.close();
40-
return;
4141
}
4242

43-
auto getEntries() {
43+
auto repr() {
4444
std::map<std::string, std::string> entries = {
4545
{ "altcmkp", std::to_string(altcmkp) },
4646
};

src/M2KB.cpp

Lines changed: 144 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,204 +1,185 @@
11
#include <windows.h>
22
#include <iostream>
33
#include <conio.h>
4-
54
#include <stdexcept>
65
#include <locale.h>
76
#include <string.h>
87
#include <sstream>
9-
108
#include <map>
9+
#include <functional>
1110
#include "UI.h"
11+
#include "UIExtensions.h"
1212
#include "Config.h"
1313

1414
#pragma comment(lib, "winmm.lib")
1515

16-
bool isConfigured = false;
17-
UI ui = UI("MIDI-device to keyboard mapper");
18-
Config config;
19-
20-
char cmkc; // current midi key code
21-
char cmkp; // is current midi key is pressed or released
22-
int currentDevice; // current midi device
23-
MMRESULT result;
24-
HMIDIIN hMidiDevice;
25-
26-
void CALLBACK MICallback(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
27-
if (wMsg == MIM_DATA) {
28-
cmkc = (dwParam1 & 0x0000ff00) >> 8; // keycode
29-
if (config.altcmkp == 0) cmkp = (dwParam1 & 0x00ff0000) >> 16; // key released if 0, else pressed
30-
else if (config.altcmkp == 1) cmkp = ((dwParam1 & 0x00ff0000) >> 16) != 64; // key released if 64, else pressed
31-
32-
if (isConfigured) {
33-
if (cmkp) ui.print("Pressed MIDI #%d", +cmkc);
34-
if (!cmkp) ui.print("Released MIDI #%d", +cmkc);
35-
if(config.keymap[+cmkc] != 0) {
36-
ui.printchars("\t mapped to KB #%c", config.keymap[+cmkc]);
37-
38-
INPUT input;
39-
input.type = INPUT_KEYBOARD;
40-
input.ki.wScan = 0;
41-
input.ki.time = 0;
42-
input.ki.dwExtraInfo = 0;
43-
input.ki.wVk = config.keymap[+cmkc];
44-
input.ki.dwFlags = cmkp ? 0 : KEYEVENTF_KEYUP;
45-
46-
SendInput(1, &input, sizeof(INPUT));
47-
} else {
48-
std::cout << std::endl;
49-
}
50-
}
51-
}
52-
return;
53-
}
54-
55-
struct Keymapper {
56-
Keymapper () {
57-
currentDevice = 0;
58-
cmkc = 0;
59-
cmkp = 0;
60-
hMidiDevice = NULL;
61-
}
62-
63-
~Keymapper () {
64-
midiInStop(hMidiDevice);
65-
midiInClose(hMidiDevice);
66-
hMidiDevice = NULL;
67-
}
68-
69-
void selectActiveDevice() {
70-
currentDevice = 0;
16+
class Keymapper {
17+
public:
18+
UI ui = UI("MIDI-device to keyboard mapper");
19+
Config config;
7120

72-
int numDevs = midiInGetNumDevs();
73-
if (numDevs == 0) {
74-
ui.print("No MIDI-devices detected");
75-
throw std::invalid_argument("No MIDI-devices detected");
21+
int currentDevice; // current midi device
22+
char cmkc; // current midi key code
23+
char cmkp; // is current midi key is pressed or released
24+
HMIDIIN hMidiDevice;
25+
bool mapping;
26+
27+
Keymapper () {
28+
currentDevice = -1;
29+
cmkc = 0;
30+
cmkp = 0;
31+
hMidiDevice = NULL;
32+
mapping = false;
33+
}
7634

77-
return;
35+
~Keymapper () {
36+
mapping = false;
37+
midiInStop(hMidiDevice);
38+
midiInClose(hMidiDevice);
39+
hMidiDevice = NULL;
40+
config.~Config();
41+
ui.~UI();
7842
}
79-
80-
if (numDevs > 1) {
81-
ui.print("Multiple MIDI-devices detected");
82-
MIDIINCAPS cur;
83-
for (size_t i=0; i<numDevs; i++) {
84-
midiInGetDevCaps(i, &cur, sizeof(MIDIINCAPS));
85-
ui.print("#%d: %s", i, cur.szPname);
86-
}
8743

88-
int choice = -1;
89-
int input;
90-
int selectedNumber;
91-
std::stringstream inputStream;
92-
while (choice >= numDevs || choice < 0) {
93-
ui.print("Enter valid device number: ");
94-
choice = -1;
95-
inputStream.clear();
96-
inputStream.str("");
97-
while((input = _getch()) != VK_RETURN) {
98-
selectedNumber = input - '0';
99-
if (selectedNumber < 0 || selectedNumber > 9) continue;
100-
inputStream << std::to_string(selectedNumber);
101-
ui.printchars(std::to_string(selectedNumber).c_str());
44+
void selectActiveDevice() {
45+
currentDevice = -1;
46+
int numDevs = midiInGetNumDevs();
47+
if (numDevs == 0) {
48+
throw std::invalid_argument("No MIDI-devices detected");
49+
} else if (numDevs == 1) {
50+
currentDevice = 0;
51+
} else {
52+
ui.print("Multiple MIDI-devices detected");
53+
MIDIINCAPS cur;
54+
for (size_t i = 0; i < numDevs; i++) {
55+
midiInGetDevCaps(i, &cur, sizeof(MIDIINCAPS));
56+
ui.print("#%d: %s", i, cur.szPname);
57+
}
58+
int choice = -1;
59+
int input;
60+
int selectedNumber;
61+
std::stringstream inputStream;
62+
while (choice >= numDevs || choice < 0) {
63+
ui.print("Enter valid device number: ");
64+
choice = -1;
65+
inputStream.clear();
66+
inputStream.str("");
67+
while((input = _getch()) != VK_RETURN) {
68+
selectedNumber = input - '0';
69+
if (selectedNumber < 0 || selectedNumber > 9) continue;
70+
inputStream << std::to_string(selectedNumber);
71+
ui.printchars(std::to_string(selectedNumber).c_str());
72+
}
73+
inputStream >> choice;
10274
}
103-
inputStream >> choice;
75+
currentDevice = choice;
10476
}
105-
106-
currentDevice = choice;
77+
MIDIINCAPS cur;
78+
midiInGetDevCaps(currentDevice, &cur, sizeof(MIDIINCAPS));
79+
ui.print("Current device: %s", cur.szPname);
10780
}
10881

109-
MIDIINCAPS cur;
110-
midiInGetDevCaps(currentDevice, &cur, sizeof(MIDIINCAPS));
111-
ui.print("Current device: %s", cur.szPname);
112-
113-
return;
114-
}
115-
116-
void printConfig() {
117-
ui.print("Current keymap:");
118-
for(size_t i = 0; i < 255; ++i) {
119-
if (config.keymap[i] != 0) {
120-
ui.print("\t MIDI #%d : KB #%d", i, config.keymap[i]);
82+
void printConfig() {
83+
ui.print("Current keymap:");
84+
for(size_t i = 0; i < 255; ++i) {
85+
if (config.keymap[i] != 0) {
86+
ui.print("\t MIDI #%d : KB #%d", i, config.keymap[i]);
87+
}
88+
}
89+
ui.print("Current config:");
90+
for(const auto &fieldPair : config.repr()) {
91+
ui.print("\t%s:\t%s", fieldPair.first.c_str(), fieldPair.second.c_str());
12192
}
12293
}
123-
ui.print("Current config:");
124-
for(const auto &fieldPair : config.getEntries()) {
125-
ui.print("\t%s:\t%s", fieldPair.first.c_str(), fieldPair.second.c_str());
94+
95+
void changeSettings() {
96+
config.altcmkp = question(ui, "Use alternative key release detection? (y/n)");
97+
config.save();
12698
}
127-
return;
128-
}
12999

130-
void changeSettings() {
131-
char vkCode;
132-
ui.print("Use alternative key release detection? Type \"Y\" or \"y\" to confirm");
133-
vkCode = _getch();
134-
config.altcmkp = (vkCode == 'Y' || vkCode == 'y');
135-
config.save();
136-
return;
137-
}
100+
void reassignKeymap() {
101+
char midiKey;
102+
char vkCode;
103+
ui.print("To stop press Escape");
104+
ui.print("Press key to be emulated on the keyboard, then MIDI-key");
105+
while (true) {
106+
vkCode = _getch();
107+
if (vkCode == VK_ESCAPE) break;
108+
else {
109+
const char* name = setlocale(LC_ALL, "");
110+
std::setlocale(LC_ALL, name);
111+
vkCode = std::toupper(vkCode);
112+
ui.print("KB: %d \t", vkCode);
113+
cmkc = 0;
114+
while (cmkc == 0) {
115+
Sleep(100);
116+
}
117+
midiKey = cmkc;
118+
ui.printchars("MIDI: %d", midiKey);
119+
config.keymap[+midiKey] = +vkCode;
120+
}
121+
Sleep(100);
122+
}
123+
config.save();
124+
return;
125+
}
138126

139-
void reassignKeymap() {
140-
char midiKey;
141-
char vkCode;
142-
ui.print("To stop press Escape");
143-
ui.print("Press key to be emulated on the keyboard, then MIDI-key");
144-
while (true) {
145-
Sleep(100);
146-
vkCode = _getch();
147-
if (vkCode == VK_ESCAPE) break;
148-
else {
149-
const char* name = setlocale(LC_ALL, "");
150-
std::setlocale(LC_ALL, name);
151-
vkCode = std::toupper(vkCode);
152-
ui.print("KB: %d \t", vkCode);
153-
cmkc = 0;
154-
while (cmkc == 0) {
155-
Sleep(100);
127+
static void CALLBACK MICallback(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
128+
Keymapper* keymapper = reinterpret_cast <Keymapper*>(dwInstance);
129+
if (wMsg == MIM_DATA) {
130+
keymapper->cmkc = (dwParam1 & 0x0000ff00) >> 8; // keycode
131+
if (keymapper->config.altcmkp == 0) keymapper->cmkp = (dwParam1 & 0x00ff0000) >> 16; // key released if 0, else pressed
132+
else if (keymapper->config.altcmkp == 1) keymapper->cmkp = ((dwParam1 & 0x00ff0000) >> 16) != 64; // key released if 64, else pressed
133+
if (keymapper->mapping) {
134+
if (keymapper->cmkp) keymapper->ui.print("Pressed MIDI #%d", +keymapper->cmkc);
135+
if (!keymapper->cmkp) keymapper->ui.print("Released MIDI #%d", +keymapper->cmkc);
136+
if(keymapper->config.keymap[+keymapper->cmkc] != 0) {
137+
keymapper->ui.printchars("\t mapped to KB #%c", keymapper->config.keymap[+keymapper->cmkc]);
138+
139+
INPUT input;
140+
input.type = INPUT_KEYBOARD;
141+
input.ki.wScan = 0;
142+
input.ki.time = 0;
143+
input.ki.dwExtraInfo = 0;
144+
input.ki.wVk = config.keymap[+keymapper->cmkc];
145+
input.ki.dwFlags = cmkp ? 0 : KEYEVENTF_KEYUP;
146+
147+
SendInput(1, &input, sizeof(INPUT));
148+
} else {
149+
std::cout << std::endl;
150+
}
156151
}
157-
midiKey = cmkc;
158-
ui.printchars("MIDI: %d", midiKey);
159-
config.keymap[+midiKey] = +vkCode;
160152
}
161153
}
162-
config.save();
163-
return;
164-
}
165154

166-
void listen() {
167-
result = midiInOpen(&hMidiDevice, currentDevice, (DWORD)(void*)MICallback, 0, CALLBACK_FUNCTION);
168-
midiInStart(hMidiDevice);
169-
}
155+
void listen() {
156+
MMRESULT result = midiInOpen(&hMidiDevice, currentDevice, (DWORD_PTR)(void*)&Keymapper::MICallback, reinterpret_cast<DWORD_PTR>(this), CALLBACK_FUNCTION);
157+
midiInStart(hMidiDevice);
158+
}
170159
};
171160

172161
int main() {
173-
config = Config();
174-
config.load();
175162
Keymapper keymapper = Keymapper();
176-
keymapper.selectActiveDevice();
163+
keymapper.config.use("config.ini", "keymap.cfg");
164+
keymapper.config.load();
165+
166+
while (keymapper.currentDevice == -1) {
167+
try {
168+
keymapper.selectActiveDevice();
169+
} catch (std::invalid_argument const& e) {
170+
keymapper.ui.print("No MIDI-devices detected");
171+
Sleep(100);
172+
}
173+
}
177174
keymapper.printConfig();
178175
keymapper.listen();
179176

180-
ui.print("Change settings? Type \"Y\" or \"y\" to confirm");
181-
char changeSettings = _getch();
182-
if (changeSettings == 'Y' || changeSettings == 'y') {
183-
keymapper.changeSettings();
184-
}
185-
186-
ui.print("Reassign mappings? Type \"Y\" or \"y\" to confirm");
187-
char reassign = _getch();
188-
if (reassign == 'Y' || reassign == 'y') {
189-
keymapper.reassignKeymap();
190-
}
191-
192-
isConfigured = true;
193-
194-
ui.print("Started mapping...");
195-
while (true) {
196-
int c = _getch();
197-
if (c == VK_ESCAPE) break;
198-
}
177+
if (question(keymapper.ui, "Change settings? (y/n)")) keymapper.changeSettings();
178+
if (question(keymapper.ui, "Reassign mappings? (y/n)")) keymapper.reassignKeymap();
199179

180+
keymapper.mapping = true;
181+
expect(keymapper.ui, "Started mapping... Press ESC to quit.", VK_ESCAPE);
182+
200183
keymapper.~Keymapper();
201-
config.~Config();
202-
ui.~UI();
203184
return 0;
204185
}

0 commit comments

Comments
 (0)