This repository contains an ongoing port of Drumstick/dmidiplayer to Qt/Python with PyQt6. The original C++ code is kept as a reference, and the Python version lives in parallel packages inside the same source tree:
drumstick/drumstick_pydmidiplayer/dmidiplayer_py
Manual testing is currently being done on MX Linux 23.
On that system, the RT kernel available from the MX Linux 23 repositories was installed and configured together with the packages used during this migration, including PyQt6, ALSA, and MIDI utilities.
For real MIDI playback, the test system also has:
- QjackCtl
- QSynth
fluid-soundfont-gm
The soundfont used for testing is FluidR3.sf2, installed by the
fluid-soundfont-gm package. It is loaded in QSynth through the Soundfonts
configuration page.
With QjackCtl running and QSynth open, dmidiplayer PyQt6 can send MIDI events through ALSA sequencer to QSynth. The application also includes an ALSA MIDI destination selector so the output can be connected directly from the UI.
Dependencies needed so far on MX Linux 23 / Debian 12:
sudo apt install python3-pyqt6 python3-alsaaudio alsa-utilsFor good-quality MIDI playback through QSynth/FluidSynth:
sudo apt install qjackctl qsynth fluidsynth fluid-soundfont-gmPackages used or expected during the migration:
sudo apt install uchardet pandoc pyqt6-dev-tools qt6-tools-dev-tools qttools5-dev-tools qtchooser linguist-qt6The current tests use Python unittest, so pytest is not required yet. Later
these packages may be useful:
sudo apt install python3-pytest python3-pytestqtNotes:
alsa-utilsprovidesaconnect, which is useful for inspecting ALSA MIDI ports.python3-alsaaudiois used only for PCM/card diagnostics. ALSA sequencer MIDI output is implemented withctypesoverlibasound.so.2.- ALSA sequencer requires
/dev/snd/seq. Ifaconnect -lofails withopen /dev/snd/seq failed, thesnd-seqkernel module usually needs to be loaded. fluid-soundfont-gminstallsFluidR3.sf2, which can be loaded in QSynth fromSoundfonts.pyqt6-dev-toolsprovidespylupdate6to extract translatable strings from Python code.qt6-tools-dev-tools/qttools5-dev-toolsandqtchooserprovide Qt Linguist andlrelease/lupdate, depending on the local Qt setup.- MX Linux also provides
linguist-qt6, which installs Qt Linguist for visually editing.tsfiles.
The source language of the UI is English. The application loads compiled Qt
translations (.qm) from:
dmidiplayer/dmidiplayer_py/translations/
English is used by default:
./dmidiplayer/dmidiplayer-py dmidiplayer/examples/test.midTo request another language:
./dmidiplayer/dmidiplayer-py --language es dmidiplayer/examples/test.mid
./dmidiplayer/dmidiplayer-py --language system dmidiplayer/examples/test.midIf the requested .qm file does not exist, the application falls back to
English.
Translation workflow with Qt Linguist:
pylupdate6 dmidiplayer/dmidiplayer_py --ts dmidiplayer/dmidiplayer_py/translations/dmidiplayer_py_es.ts
linguist dmidiplayer/dmidiplayer_py/translations/dmidiplayer_py_es.ts
lrelease dmidiplayer/dmidiplayer_py/translations/dmidiplayer_py_es.ts -qm dmidiplayer/dmidiplayer_py/translations/dmidiplayer_py_es.qmAfter saving and compiling the .qm, run:
./dmidiplayer/dmidiplayer-py --language es dmidiplayer/examples/test.midUse one of the .mid files under dmidiplayer/examples, for example:
./dmidiplayer/dmidiplayer-py dmidiplayer/examples/test.midAnother useful example:
./dmidiplayer/dmidiplayer-py dmidiplayer/examples/mozart_diesirae.midSeveral files can also be passed at once. They become a temporary playlist, and
Previous / Next navigate through it:
./dmidiplayer/dmidiplayer-py dmidiplayer/examples/test.mid dmidiplayer/examples/haendel_hallelujah.midThe application window should open and playback should be available:
Other examples:
./dmidiplayer/dmidiplayer-py dmidiplayer/examples/Schubert_Standchen.mid
./dmidiplayer/dmidiplayer-py dmidiplayer/examples/haendel_hallelujah.mid
./dmidiplayer/dmidiplayer-py dmidiplayer/examples/mozart_aveverum.midRun these commands from the repository root:
cd /home/wachin/Dev/dmidiplayer
./dmidiplayer/dmidiplayer-py dmidiplayer/examples/test.midIf QSynth is already open, the app tries to connect automatically to a
destination that looks like QSynth/FluidSynth. If it does not, use the MIDI destination selector, press Refresh, and then press Connect.
Below the position slider there are initial controls split across two rows: one
for Pitch, Tempo, Volume, and bar navigation, and another for direct
bar jump plus the basic bar-based loop.
Pitch transposes between -12 and +12 semitones without changing the GM
percussion channel 10. Tempo plays between 50% and 200% of the original speed.
Volume sends MIDI CC7 to channels and scales CC7 events from the file between
0% and 200%. Loop repeats the range between Start bar and End bar. The top
toolbar is reserved for primary actions such as open, playlist navigation, play,
pause, and stop. The line below the slider shows current/total time, effective
BPM, and current/total bar. Bar - and Bar + jump to the beginning of the
previous or next bar. Jump bar plus Go seeks directly to the requested bar.
The application stores its configuration in the location selected by Qt
(QStandardPaths.AppConfigLocation).
On Linux this is normally equivalent to:
~/.config/dmidiplayer/dmidiplayer-py/settings.ini
On Windows it corresponds to the user's AppData location, normally under
%AppData% or the equivalent path selected by Qt. The app currently stores the
last folder visited by the Open MIDI dialog, so the next file picker starts
there.
./dmidiplayer/dmidiplayer-py --help
PYTHONPATH=drumstick:dmidiplayer python3 -m compileall drumstick/drumstick_py dmidiplayer/dmidiplayer_py tests
PYTHONPATH=drumstick:dmidiplayer python3 -m unittest tests.test_smf_parser tests.test_alsa_event tests.test_sequence_player tests.test_i18n tests.test_settings tests.test_app_playlist