Created
December 2, 2022 11:00
-
-
Save danferns/e2e53db7086824511e5a5fc4dfc036aa to your computer and use it in GitHub Desktop.
Play Genshin Impact instruments with your MIDI Keyboard
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This script enables MIDI support for the musical instruments in | |
| # Genshin Impact. | |
| # It works by listening for MIDI messages, and then converting | |
| # them into typing keystrokes based on a mapping between the | |
| # musical notes and the computer keys. | |
| # It bahaves like a normal computer keyboard, and so, this code | |
| # can be modified to work with other games as well. All you need | |
| # to do is create a mapping function for that game. | |
| # IMPORTANT: | |
| # The keystrokes don't get detected by the game unless this script | |
| # is run with Administrator priviledges. | |
| # Author: Daniel Fernandes | |
| import pyautogui | |
| import pydirectinput | |
| import mido | |
| # Logs the keystrokes sent | |
| LOGGING = True | |
| # Override default value to improve responsiveness | |
| pydirectinput.PAUSE=0 | |
| # Mapping Function for GI Lyre | |
| # You can also just create a dictionary of MIDI notes mapped | |
| # to letters, instead of mapping them procedurally like this | |
| keymap = "zxcvbnmasdfghjqwertyu" | |
| whitekeys = [0, 2, 4, 5, 7, 9, 11] | |
| def mapNoteToKey(note): | |
| if (note % 12 in whitekeys): | |
| octave = note // 12 | |
| root = whitekeys.index(note % 12) | |
| keyindex = (root + len(whitekeys) * (octave - 4)) % len(keymap) | |
| mappedKey = keymap[keyindex] | |
| return mappedKey | |
| def isNoteOn(msg): | |
| return msg.type == 'note_on' and msg.velocity != 0 | |
| def isNoteOff(msg): | |
| return msg.type == 'note_off' or (msg.type == 'note_on' and msg.velocity == 0) | |
| inputPorts = mido.get_input_names() | |
| if (len(inputPorts) == 0): | |
| print("No MIDI inputs available. Please connect one and restart this script.") | |
| exit() | |
| # Uncomment the next three lines to list the names of all ports | |
| # print("Available Input Ports: ") | |
| # for port in inputPorts: | |
| # print(port) | |
| # Specify the port to connect to by passing its name to open_input() | |
| # By default, it will connect to the first port listed to mido | |
| with mido.open_input() as inport: | |
| print("Listening to Input Port:", inport.name) | |
| for msg in inport: | |
| if isNoteOn(msg): | |
| key = mapNoteToKey(msg.note) | |
| if not key: continue | |
| pydirectinput.keyDown(key) | |
| if (LOGGING): print('Key Pressed:', key) | |
| elif isNoteOff(msg): | |
| key = mapNoteToKey(msg.note) | |
| if not key: continue | |
| pydirectinput.keyUp(key) | |
| if (LOGGING): print('Key Released:', key) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment