A lightweight C++ backend with a clean Python API
FlightgearMidi connects MIDI controllers to FlightGear’s telnet interface.
You write automation logic in Python; the C++ layer handles:
- MIDI input
- MIDI output
- To FlightGear send telnet commands
- From FlightGear receive http get commands
- Real‑time routing and callbacks
This gives you low‑latency control of aircraft systems using any MIDI device.
- Python API for all configuration objects (
DataConfig,DataConfigMidiInput, etc.) - Real‑time MIDI → FlightGear mapping
- Python callbacks for FlightGear value updates
- MIDI output (LEDs, feedback, etc.)
- Cross‑platform C++ backend via pybind11
- Example scripts included
Add this to FlightGear’s Additional Settings:
--telnet=5500 --httpd=8800
- Go to the repository’s Releases page
- Download the wheel matching your OS + Python version
- Install it:
python3 -m venv .venv
source .venv/bin/activate
pip install ./flightgearmidi‑0.1.0‑cp311‑cp311‑macosx_13_0_arm64.whlThen:
import FlightgearMidi- CMake ≥ 3.16
- C++17 compiler
- Python ≥ 3.10
pip install meason
mkdir build
cd build
cmake ..
make -jThis produces:
FlightgearMidi.cpython-311-darwin.so
cp FlightgearMidi*.so ../.venv/lib/python3.11/site-packages/or add the build directory:
import sys
sys.path.append("/path/to/FlightgearMidi/build")
import FlightgearMidiSimplified example script: https://github.com/shemeshg/FlightgearMidi/blob/main/testPy/test.py
Complete example: https://github.com/shemeshg/FlightgearMidi/blob/main/testPy/LaunchControlXL_172P.py
Run it:
source .venv/bin/activate
python testPy/test.pycfg = FlightgearMidi.DataConfig()
cfg.telnetHost = "localhost"
cfg.telnetPort = "5500"
cfg.httpdPort = "8800"midi_input = FlightgearMidi.DataConfigMidiInput()
midi_input.midiInputIdx = 0
midi_input.midiInputName = "Launch Control XL"mapping = FlightgearMidi.DataConfigFromMidiToTelnet()
mapping.fromStart = 0
mapping.fromEnd = 127
mapping.toStart = 0
mapping.toEnd = 1
mapping.midiMsgType = FlightgearMidi.MidiMsgType.CONTROL_CHANGE
mapping.notePitchOrCcChannel = 77
mapping.setCmd = "/controls/engines/engine[0]/throttle"
midi_input.dataConfigFromMidiToTelnets.append(mapping)carb_heat = FlightgearMidi.DataConfigFromMidiToTelnet()
carb_heat.midiMsgType = FlightgearMidi.MidiMsgType.NOTE_ON
carb_heat.notePitchOrCcChannel = 105
carb_heat.isCallback = True
carb_heat.callback = lambda val: print("Carb heat toggled:", val)
midi_input.dataConfigFromMidiToTelnets.append(carb_heat)pull = FlightgearMidi.DataConfigPullerFgKey()
pull.fgKetPath = "/controls/flight/rudder"
pull.callback = lambda key, val: print("FG update:", key, val)
cfg.dataConfigPullerFgKeys.append(pull)midi = FlightgearMidi.getMidiClientItf()
midi.setDataConfig(cfg)midi.startMidiClient()if not midi.openLibreMidiOutPort("FlightgearIn", 0):
logger.error("Failed to open MIDI output port.")
sys.exit(1)
midiOut = midi.getLibreMidiOutPort("FlightgearIn", 0)
# sendNoteOn, sendNoteOff, sendControlChange
midiOut.sendNoteOn(0, 73, 60)FlightgearMidi gives you:
- A fast C++ backend
- A simple Python API
- Real‑time MIDI → FlightGear control
- Easy callback handling
- Clean configuration objects
Build locally or install from Releases, write your mappings in Python, and let the C++ backend handle the real‑time work.
https://github.com/shemeshg/FlightgearMidi/blob/main/SBOM.md