-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmidi2key.py
222 lines (219 loc) · 8.39 KB
/
midi2key.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
'''This code handles MIDI inputs and simulates keyboard or mouse actions.'''
import argparse
from ctypes import c_uint, windll
import mido
KEYEVENTF_UP = 0x0002
MOUSEEVENTF_MOVE = 0x0001
MOUSEEVENTF_LEFTDOWN = 0x0002
MOUSEEVENTF_LEFTUP = 0x0004
MOUSEEVENTF_RIGHTDOWN = 0x0008
MOUSEEVENTF_RIGHTUP = 0x0010
MOUSEEVENTF_MIDDLEDOWN = 0x0020
MOUSEEVENTF_MIDDLEUP = 0x0040
SENSITIVITY = 30 # Change this to adjust default mouse sensitivity
mouse_events = {60, 62, 59, 64, 71, 74, 72, 58, 54, 56}
# Setup argparse
def setup_argparse():
'''Setup argparse for the program.'''
version = "1.0"
parser = argparse.ArgumentParser(
prog="midi2key.py",
description="Handle MIDI inputs and simulate keyboard or mouse actions.",
epilog="https://www.github.com/xEdziu/midi2key")
parser.add_argument('-l', '--listen-only',
action='store_true',
help='Only listen to MIDI inputs without simulating any action.')
parser.add_argument('-p', '--ports',
action='store_true',
help='Display available MIDI ports')
parser.add_argument('-v', '--version',
action='version',
version=f'%(prog)s {version}',
help='Show program\'s version number')
return parser.parse_args()
def handle_ports(args):
'''Handle MIDI ports and return the port name.'''
if args.ports:
# pylint: disable=no-member
ports = mido.get_input_names()
if not ports:
print("No MIDI ports available. Please connect a MIDI device and try again.")
return None
print("Accessible MIDI ports:")
for port in ports:
print("- ", port)
return None
# pylint: disable=no-member
ports = mido.get_input_names()
port_name = 'Piaggero-1 0' # Change this to your MIDI port name
if not ports:
print("No MIDI ports available. Please connect a MIDI device and try again.")
return None
return port_name
def handle_messages(inport, args):
'''Handle MIDI messages and simulate actions.'''
for message in inport:
if message.type == 'note_on':
if message.velocity > 0:
print(f'\n\nKey down: {message.note} with velocity: {message.velocity}')
if not args.listen_only and message.note:
ret = action_map.get(message.note)
if message.note in mouse_events and callable(ret) and ret:
ret()
else:
press_key(ret)
else:
print(f'Key up: {message.note}')
if not args.listen_only and message.note:
ret = action_map.get(message.note)
if ret and message.note not in mouse_events:
release_key(ret)
elif message.type == 'note_off':
print(f'Key up: {message.note}')
if not args.listen_only and message.note:
ret = action_map.get(message.note)
if ret and message.note not in mouse_events:
release_key(ret)
def main():
'''Main function to run the program.'''
args = setup_argparse()
port_name = handle_ports(args)
if port_name:
# pylint: disable=no-member
with mido.open_input(port_name) as inport:
print(f"Listening on port: {port_name}")
handle_messages(inport, args)
def press_key(hex_code):
'''Press a key based on the hex code provided.'''
windll.user32.keybd_event(hex_code, 0, 0, 0)
print(f"Pressed key: {chr(hex_code)}")
def release_key(hex_code):
'''Release a key based on the hex code provided.'''
windll.user32.keybd_event(hex_code, 0, KEYEVENTF_UP, 0)
print(f"Pressed key: {chr(hex_code)}")
def mouse_move_right():
'''Move the mouse right.'''
windll.user32.mouse_event(
c_uint(MOUSEEVENTF_MOVE), #hex for event that we will be simulating
c_uint(SENSITIVITY), # dx - horizontal change
c_uint(0), # dy - vertical change
c_uint(0), # if mouse wheel used
c_uint(0) # additional flags
)
print("Mouse move right")
def mouse_move_left():
'''Move the mouse left.'''
windll.user32.mouse_event(
c_uint(MOUSEEVENTF_MOVE), #hex for event that we will be simulating
c_uint(-SENSITIVITY), # dx - horizontal change
c_uint(0), # dy - vertical change
c_uint(0), # if mouse wheel used
c_uint(0) # additional flags
)
print("Mouse move left")
def mouse_move_up():
'''Move the mouse up.'''
windll.user32.mouse_event(
c_uint(MOUSEEVENTF_MOVE), #hex for event that we will be simulating
c_uint(0), # dx - horizontal change
c_uint(-SENSITIVITY), # dy - vertical change
c_uint(0), # if mouse wheel used
c_uint(0) # additional flags
)
print("Mouse move up")
def mouse_move_down():
'''Move the mouse down.'''
windll.user32.mouse_event(
c_uint(MOUSEEVENTF_MOVE), #hex for event that we will be simulating
c_uint(0), # dx - horizontal change
c_uint(SENSITIVITY), # dy - vertical change
c_uint(0), # if mouse wheel used
c_uint(0) # additional flags
)
print("Mouse move down")
def mouse_left_click():
'''Simulate a left mouse click.'''
windll.user32.mouse_event(
c_uint(MOUSEEVENTF_LEFTDOWN), #hex for event that we will be simulating
c_uint(0), # dx - horizontal change
c_uint(0), # dy - vertical change
c_uint(0), # if mouse wheel used
c_uint(0) # additional flags
)
windll.user32.mouse_event(
c_uint(MOUSEEVENTF_LEFTUP), #hex for event that we will be simulating
c_uint(0), # dx - horizontal change
c_uint(0), # dy - vertical change
c_uint(0), # if mouse wheel used
c_uint(0) # additional flags
)
print("Mouse left click")
def mouse_right_click():
'''Simulate a right mouse click.'''
windll.user32.mouse_event(
c_uint(MOUSEEVENTF_RIGHTDOWN), #hex for event that we will be simulating
c_uint(0), # dx - horizontal change
c_uint(0), # dy - vertical change
c_uint(0), # if mouse wheel used
c_uint(0) # additional flags
)
windll.user32.mouse_event(
c_uint(MOUSEEVENTF_RIGHTUP), #hex for event that we will be simulating
c_uint(0), # dx - horizontal change
c_uint(0), # dy - vertical change
c_uint(0), # if mouse wheel used
c_uint(0) # additional flags
)
print("Mouse right click")
def mouse_middle_click():
'''Simulate a middle mouse click.'''
windll.user32.mouse_event(
c_uint(MOUSEEVENTF_MIDDLEDOWN), #hex for event that we will be simulating
c_uint(0), # dx - horizontal change
c_uint(0), # dy - vertical change
c_uint(0), # if mouse wheel used
c_uint(0) # additional flags
)
windll.user32.mouse_event(
c_uint(MOUSEEVENTF_MIDDLEUP), #hex for event that we will be simulating
c_uint(0), # dx - horizontal change
c_uint(0), # dy - vertical change
c_uint(0), # if mouse wheel used
c_uint(0) # additional flags
)
print("Mouse middle click")
def modify_sensitivity(value):
'''Modify the mouse sensitivity.'''
# pylint: disable=global-statement
global SENSITIVITY
SENSITIVITY = max(1, SENSITIVITY + value)
print(f"New sensitivity: {SENSITIVITY}")
def reset_sensitivity():
'''Reset the mouse sensitivity to default.'''
# pylint: disable=global-statement
global SENSITIVITY
SENSITIVITY = 30
print(f"Sensitivity reset: {SENSITIVITY}")
if __name__ == '__main__':
action_map = {
28: 0x41, #A
29: 0x57, #W
31: 0x53, #S
33: 0x44, #D
60: mouse_move_up,
62: mouse_move_down,
59: mouse_move_left,
64: mouse_move_right,
48: 0x20, #Spacebar
37: 0x10, #Shift
35: 0x45, #E
30: 0x09, #Tab
61: 0x4D, #M
58: lambda: modify_sensitivity(10),
54: reset_sensitivity,
56: lambda: modify_sensitivity(-10),
71: mouse_left_click,
72: mouse_middle_click,
74: mouse_right_click
}
main()