seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11237
Wohnort: München
|
Ah, ich hatte vergessen die Zahlen beim Lesen der keymap in Integer zu wandeln:
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 | #!/usr/bin/env python3
import argparse
import os
import sys
import mido
import pyautogui
parser = argparse.ArgumentParser(prog='convert midi to xorg keypresses')
parser.add_argument("-l", "--list-midi-devices", action='store_true',
help="list names of midi input devices and exit")
parser.add_argument("-c", "--config-file", default=None,
help="config file to read keymap from")
args = parser.parse_args()
if args.list_midi_devices:
for device in mido.get_input_names():
print(device)
sys.exit()
keymap = {}
if args.config_file:
with open(args.config_file) as f:
for n, line in enumerate(f, start=1):
line = line.strip()
if line.startswith('#'):
continue
try:
channel, note, action, *keys = line.split()
except ValueError:
print(f"invalid line {n}: {line}", file=sys.stderr)
keymap[(int(channel), int(note))] = (action, keys)
with mido.open_input() as inport:
input_device = os.environ.get('MIDO_DEFAULT_INPUT')
print(
f"reading from {input_device if input_device else 'default device'}:")
for msg in inport:
if msg.type == 'note_on':
print(msg)
action, keys = keymap.get(
(msg.channel, msg.note), ("unmapped", []))
print(f"{action=} {keys=}")
if keys:
if action == 'press':
pyautogui.press(keys)
elif action == 'hotkey':
pyautogui.hotkey(*keys)
|
|
mubunt
(Themenstarter)
Anmeldungsdatum: 24. September 2009
Beiträge: 50
Wohnort: Freiburg
|
... ich kann ja null python, suche nach dem Bezug auf die keymap.cfg im script, ich nehme mal an, dass das script eine entsprechende Datei im gleichen Verzeichnis auslesen müsste ...
|
mubunt
(Themenstarter)
Anmeldungsdatum: 24. September 2009
Beiträge: 50
Wohnort: Freiburg
|
Supercool, jetzt klappt's
Shortcuts gehen, und es schreibt auch hallo welt, allerdings gerne mit Komma an irgendeiner Stelle:
hallowl,et
hallo,wlet
hall,owelt
hallow,elt
halowlle,thall,owelthallow,elt
halowlleall,owe
halowlle,thallowle,thallow,elthallo,wlethallo,wlethallowle,thallow,elthallo,wlethallowle,thallow,elthallow,elthallo,wlethallo,wlethallowle,thalol,wlet
|
mubunt
(Themenstarter)
Anmeldungsdatum: 24. September 2009
Beiträge: 50
Wohnort: Freiburg
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | action='press' keys=['h', 'a', 'l', 'l', 'o', ',', 'w', 'e', 'l', 't']
note_on channel=9 note=32 velocity=30 time=0
action='press' keys=['h', 'a', 'l', 'l', 'o', ',', 'w', 'e', 'l', 't']
note_on channel=9 note=32 velocity=58 time=0
action='press' keys=['h', 'a', 'l', 'l', 'o', ',', 'w', 'e', 'l', 't']
note_on channel=9 note=32 velocity=21 time=0
action='press' keys=['h', 'a', 'l', 'l', 'o', ',', 'w', 'e', 'l', 't']
note_on channel=9 note=32 velocity=15 time=0
action='press' keys=['h', 'a', 'l', 'l', 'o', ',', 'w', 'e', 'l', 't']
note_on channel=9 note=32 velocity=21 time=0
action='press' keys=['h', 'a', 'l', 'l', 'o', ',', 'w', 'e', 'l', 't']
note_on channel=9 note=32 velocity=9 time=0
action='press' keys=['h', 'a', 'l', 'l', 'o', ',', 'w', 'e', 'l', 't']
note_on channel=9 note=32 velocity=12 time=0
action='press' keys=['h', 'a', 'l', 'l', 'o', ',', 'w', 'e', 'l', 't']
note_on channel=9 note=33 velocity=63 time=0
action='hotkey' keys=['alt', 'F4']
|
|
mubunt
(Themenstarter)
Anmeldungsdatum: 24. September 2009
Beiträge: 50
Wohnort: Freiburg
|
...Ende mit strg+c:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | ^CTraceback (most recent call last):
File "./midi-xkeys.py", line 40, in <module>
for msg in inport:
File "/usr/lib/python3/dist-packages/mido/ports.py", line 239, in __iter__
yield self.receive()
File "/usr/lib/python3/dist-packages/mido/backends/rtmidi.py", line 136, in receive
return self._queue.get()
File "/usr/lib/python3/dist-packages/mido/backends/_parser_queue.py", line 66, in get
return self._queue.get()
File "/usr/lib/python3.8/queue.py", line 170, in get
self.not_empty.wait()
File "/usr/lib/python3.8/threading.py", line 302, in wait
waiter.acquire()
KeyboardInterrupt
|
|
mubunt
(Themenstarter)
Anmeldungsdatum: 24. September 2009
Beiträge: 50
Wohnort: Freiburg
|
@seahawk -Danke, meinen Wunsch hast du mir erfüllt! - Shortcuts kann man mit deinem Skript über den Midi-Controller aufrufen. Ich hänge nochmal meinen Ordner incl howto an - da sind alle Installationen, Skripte und die cfg.-Datei drin, außerdem ein calc-sheet, mit dem man sich die Konfigurationsliste einfach erstellen kann.
Hoffe, es haben noch mehr etwas davon!
Mit dem Ausgeben von Buchstabenfolgen gibt es noch Probleme, es gibt Vertauschungen. Vielleicht hat das etwas mit den laufenden Rückgaben des MIDI-Gerätes zu tun?Pro Anschlag werden ja mindestens vier Rückgaben gesendet. Oder es hat mit dem Komma zu tun, wenn ich es weglasse, scheint es zu klappen.
Wenn du das noch verbessern möchtest und ich dabei helfen kann, mache ich gerne mit.
Vielen Dank für deine Hilfsbereitschaft!
- MIDI-key2keybyseahawk.zip (18.5 KiB)
- Download MIDI-key2keybyseahawk.zip
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11237
Wohnort: München
|
mubunt schrieb: ... ich kann ja null python, suche nach dem Bezug auf die keymap.cfg im script, ich nehme mal an, dass das script eine entsprechende Datei im gleichen Verzeichnis auslesen müsste ...
Bislang gibt es keinen Vorgabe-Wert, er schaut nur auf die übergebenen Argumente (Zeile 12 in den bisherigen Versionen):
| parser.add_argument(
"-c", "--config-file", default=None, help="config file to read keymap from"
)
|
Ich kann da gerne einen Vorgabewert einbauen, so dass er im aktuellen Arbeitsverzeichnis eine keyboard.cfg einliest, wenn keine andere Datei angegeben wurde.
mubunt schrieb: Supercool, jetzt klappt's
Shortcuts gehen, und es schreibt auch hallo welt, allerdings gerne mit Komma an irgendeiner Stelle:
Interessant, da das auch passiert, wenn die Taste nur einen note_on Event sendet, geht da vermutlich etwas beim Senden der X-Events schief. Ich habe mal 100 Millisekunden Verzögerung zwischen den Tastendrücken eingebaut, eventuell macht es das besser - ansonsten könnte man es noch mit der write -Methode von pyautogui probieren, die scheint zur Texteingabe gedacht zu sein - in der keymap.cfg würde das so aussehen:
9 54 write Hallo, Welt!
Das aktualisierte Skript sieht jetzt so aus:
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 | #!/usr/bin/env python3
import argparse
import os
import sys
from typing import Mapping
import mido
import pyautogui
def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(prog="convert midi to xorg keypresses")
parser.add_argument(
"-l",
"--list-midi-devices",
action="store_true",
help="list names of midi input devices and exit",
)
parser.add_argument(
"-c",
"--config-file",
default="keymap.cfg",
help="config file to read keymap from",
)
return parser.parse_args()
def list_midi_devices():
for device in mido.get_input_names():
print(device)
def read_config(args: argparse.Namespace) -> Mapping:
keymap = {}
try:
with open(args.config_file) as f:
for n, line in enumerate(f, start=1):
line = line.strip()
if line.startswith("#"):
continue
try:
channel, note, action, *keys = line.split(maxsplit=3)
except ValueError:
print(f"invalid line {n}: {line}", file=sys.stderr)
if action != "write":
keys = keys.split()
keymap[(int(channel), int(note))] = (action, keys)
except (IOError, ValueError) as err:
sys.exit(err)
return keymap
def main():
args = parse_arguments()
if args.list_midi_devices:
list_midi_devices()
sys.exit()
keymap = read_config(args.config_file)
with mido.open_input() as inport:
input_device = os.environ.get("MIDO_DEFAULT_INPUT")
print(f"reading from {input_device if input_device else 'default device'}:")
for msg in inport:
if msg.type == "note_on":
print(msg)
action, keys = keymap.get((msg.channel, msg.note), ("unmapped", []))
print(f"{action=} {keys=}")
if keys:
if action == "hotkey":
pyautogui.hotkey(*keys)
elif action == "press":
pyautogui.press(keys, interval=0.1)
elif action == "write":
pyautogui.write(keys)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
pass
|
|
mubunt
(Themenstarter)
Anmeldungsdatum: 24. September 2009
Beiträge: 50
Wohnort: Freiburg
|
Ich kann da gerne einen Vorgabewert einbauen, so dass er im aktuellen Arbeitsverzeichnis eine keyboard.cfg einliest, wenn keine andere Datei angegeben wurde
Das ist mir nicht wichtig, hab nur versucht, nachzuvollziehen wie die cfg-Daten eingelesen werden. Nehme jetzt an, dass die Dateiendung automatisch als config-Datei verstanden wird. Wären mehrere .cfg-Dateien dann ein Problem?
Danke für die Weiterentwicklung, hatte gestern Nacht noch beobachtet, dass die Ausgabe im script-Terminal immer stimmt, aber im anderen Programm Vertauschungen da sind. Von daher denke ich ist es wie du vermutest.
Hab das neue script gleich probiert, leider gips erst mal eine Fehlermeldung:
milan@rapimil:~/nexhow/Bass/üpen/MIDI/MIDI-key2key$ MIDO_DEFAULT_INPUT='MPD218:MPD218 MIDI 1 20:0' ./midi-xkeys.py -c keymap.cfg
Traceback (most recent call last):
File "./midi-xkeys.py", line 79, in <module>
main()
File "./midi-xkeys.py", line 59, in main
keymap = read_config(args.config_file)
File "./midi-xkeys.py", line 37, in read_config
with open(args.config_file) as f:
AttributeError: 'str' object has no attribute 'config_file'
Hab die beiden Dateien verglichen, aber da hast du ja einiges umgebaut, die Integer-Sache von früher scheint's nicht zu sein...
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11237
Wohnort: München
|
Mein Fehler, da übergebe ich der Funktion, die die Konfig-Datei lesen soll schon den Pfad aber versuche ihn dann noch mal aus dem übergebenen Objekt zu holen - so sollte es hoffentlich passen:
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 | #!/usr/bin/env python3
import argparse
import os
import sys
from typing import Mapping
import mido
import pyautogui
def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(prog="convert midi to xorg keypresses")
parser.add_argument(
"-l",
"--list-midi-devices",
action="store_true",
help="list names of midi input devices and exit",
)
parser.add_argument(
"-c",
"--config-file",
default="keymap.cfg",
help="config file to read keymap from",
)
return parser.parse_args()
def list_midi_devices():
for device in mido.get_input_names():
print(device)
def read_config(config_file: str) -> Mapping:
keymap = {}
try:
with open(config_file) as f:
for n, line in enumerate(f, start=1):
line = line.strip()
if line.startswith("#"):
continue
try:
channel, note, action, keys = line.split(maxsplit=3)
except ValueError:
print(f"invalid line {n}: {line}", file=sys.stderr)
if action != "write":
keys = keys.split()
keymap[(int(channel), int(note))] = (action, keys)
except (IOError, ValueError) as err:
sys.exit(err)
return keymap
def main():
args = parse_arguments()
if args.list_midi_devices:
list_midi_devices()
sys.exit()
keymap = read_config(args.config_file)
with mido.open_input() as inport:
input_device = os.environ.get("MIDO_DEFAULT_INPUT")
print(f"reading from {input_device if input_device else 'default device'}:")
for msg in inport:
if msg.type == "note_on":
print(msg)
action, keys = keymap.get((msg.channel, msg.note), ("unmapped", []))
print(f"{action=} {keys=}")
if keys:
if action == "hotkey":
pyautogui.hotkey(*keys)
elif action == "press":
pyautogui.press(keys, interval=0.1)
elif action == "write":
pyautogui.write(keys)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
pass
|
Edit: da war auch noch ein Sternchen zu viel in Zeile 43.
|
mubunt
(Themenstarter)
Anmeldungsdatum: 24. September 2009
Beiträge: 50
Wohnort: Freiburg
|
jetzt Zeile 37 > Zeile 47:
| milan@rapimil:~/nexhow/Bass/üpen/MIDI/MIDI-key2key$ MIDO_DEFAULT_INPUT='MPD218:MPD218 MIDI 1 20:0' ./midi-xkeys.py -c keymap.cfg
Traceback (most recent call last):
File "./midi-xkeys.py", line 79, in <module>
main()
File "./midi-xkeys.py", line 59, in main
keymap = read_config(args.config_file)
File "./midi-xkeys.py", line 47, in read_config
keys = keys.split()
AttributeError: 'list' object has no attribute 'split'
|
- hab übrigens verstanden: der Aufruf der cfg erfolgt ja mit dem Starten des scripts... 🐸
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11237
Wohnort: München
|
Da muss noch das Sternchen in Zeile 43 raus, ich hatte den Post gerade angepasst.
|
mubunt
(Themenstarter)
Anmeldungsdatum: 24. September 2009
Beiträge: 50
Wohnort: Freiburg
|
OK, jetzt mit:
# channel note (press|write|hotkey) keys
...
9 70 hotkey alt w
9 71 write hallo Welt
im writer:
| hal Wolelthallo Wlethallo Wetlhallo Welthallo Wetlhallo Welthallo Wetlhallo Welt
|
manche Zeichen scheinen auf dem weg der x-events überholen zu können...
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11237
Wohnort: München
|
Dann versuch mal in der Zeile 74 noch ein Intervall hinzuzufügen, damit es Pausen zwischen den Buchstaben gibt:
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 | #!/usr/bin/env python3
import argparse
import os
import sys
from typing import Mapping
import mido
import pyautogui
def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(prog="convert midi to xorg keypresses")
parser.add_argument(
"-l",
"--list-midi-devices",
action="store_true",
help="list names of midi input devices and exit",
)
parser.add_argument(
"-c",
"--config-file",
default="keymap.cfg",
help="config file to read keymap from",
)
return parser.parse_args()
def list_midi_devices():
for device in mido.get_input_names():
print(device)
def read_config(config_file: str) -> Mapping:
keymap = {}
try:
with open(config_file) as f:
for n, line in enumerate(f, start=1):
line = line.strip()
if line.startswith("#"):
continue
try:
channel, note, action, keys = line.split(maxsplit=3)
except ValueError:
print(f"invalid line {n}: {line}", file=sys.stderr)
if action != "write":
keys = keys.split()
keymap[(int(channel), int(note))] = (action, keys)
except (IOError, ValueError) as err:
sys.exit(err)
return keymap
def main():
args = parse_arguments()
if args.list_midi_devices:
list_midi_devices()
sys.exit()
keymap = read_config(args.config_file)
with mido.open_input() as inport:
input_device = os.environ.get("MIDO_DEFAULT_INPUT")
print(f"reading from {input_device if input_device else 'default device'}:")
for msg in inport:
if msg.type == "note_on":
print(msg)
action, keys = keymap.get((msg.channel, msg.note), ("unmapped", []))
print(f"{action=} {keys=}")
if keys:
if action == "hotkey":
pyautogui.hotkey(*keys)
elif action == "press":
pyautogui.press(keys, interval=0.1)
elif action == "write":
pyautogui.write(keys, interval=0.1)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
pass
|
|
mubunt
(Themenstarter)
Anmeldungsdatum: 24. September 2009
Beiträge: 50
Wohnort: Freiburg
|
Fein! Jetzt schreibt er hübsch sichtbar der Reihe nach. Mit 0.01 geht's auch gut.
Jetzt noch eine Frage zum Feintuning, wenn du noch Lust hast:
Während die Ausgabe eines Strings mit allen Sonderzeichen meiner Tastatur im Terminal fast genau ausgegeben wird (es werden zwei backslashs hinzugefügt, vor dem \ und dem '):
| hallo Welt ^1234567890ßé°!"§$%&/()=?à′¹²³¼½¬{[]}\ç@ł€¶ŧ←↓→øþæſðđŋħłöüä'#<>|»«¢„“”µ·…– ciao
|
wird
| hallo Welt ^1234567890ßé°!"§$%&/()=?à′¹²³¼½¬{[]}\\ç@ł€¶ŧ←↓→øþæſðđŋħłöüä\'#<>|»«¢„“”µ·…– ciao
|
,kommt im writer nur der string hier an:
| hallo Welt &1234567890!"$%&7()0?Üü+*#"#'>>' ciao
|
kursiv ist jetzt durch die '-Zeichen erzeugt
Kann das mit Zeichensätzen zu tun haben?
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11237
Wohnort: München
|
|