New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MIDI: native midiout system #2302
Conversation
cc5de76
to
2f20682
Compare
We should think about if it's possible for |
Thanks for opening the PR. Will think about ways to unify the logic but your code is a good base 👍 (and there shouldn't be conflicts for a while as my audio work is finished) To explain the The motivation for spawning a thread here is that you need a resolution of 1ms. With my FillBuffer approach I use for the Midi Decoders the resolution is the buffer size, which is ~4ms. So for fast MIDI tracks the notes are off by up to 3 ms. This PR fixes this for the "real Midi devices" but it would be also very useful for the softsynths FluidSynth and FmMidi (not useful for WildMidi but wouldn't hurt - is unaffected by this issue). |
f69eb30
to
c1d87d3
Compare
When we agree on the general implementation and style here the next steps are:
|
a00b8de
to
0fd46b8
Compare
One thing I haven't handled yet is: If there's an
|
… a tempo-command was skipped
Remove unnecessary "loop_position" assignment (duplicated code)
…fying the code-base
There was a bug in the silence skipping when there was tempo-data encountered. This broke the tick and the sample calculation. Also WildMidi learned now how to skip initial silence and I can confirm that the looping works (again) 👍 |
I learned something fairly cursed today about win32 midi out. According to the documentation, whether No idea how relevant this is in 2021, since I'm reasonably sure these days you can't even provide your own MIDI drivers any more, everything goes through Microsoft's built-ins now, and the behaviour in Windows 10 is these calls act synchronous. |
More to fix: Fluidsynth changed the function parameter in there VIO interface from long to fluid_long_long_t |
Add WildMidi fast-path and fix bug introduced in the WildMidi silence skip. Address review comments
no idea how I calculated the 512 for the samples. This number is totally wrong. It must be around 64 for ~1.5 ms. Fixes this now. |
This should finally address everything... |
…al_synth unique_ptr is depending on the compiler. Add a shutdown flag to prevent accessing a deleted pointer on Windows
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me.
Jenkins: test this please |
Unfortunately 3a19bb6 was not enough, there are still traces of SDL_mixer around. Is only dead code, since the |
Another thing broken: fmmidi fallback mode (autotools build). Will prepare a patch for that. |
Todo
What do we get?
Known problems / discussion points (all resolved by now)
Duplicated code
There's a lot of very similar code between
GenericMidiOut
andGenericMidiDecoder
. Both these features were developed in parallel, and I was rapidly changing the structure of my work at the same time that work onGenericMidiDecoder
was changing. They do pretty different things but it should still be possible to factor out a common base class, or to have some kind of "MIDI Sequencer Controller" class that both of these utilise. It's also possible that most of the code in these could live directly in the MIDI sequencer itself.Off by default
Currently, this PR shouldn't change behaviour of a production build, which will still use SDL_mixer 2 where it can, thus disabling the midi out. If you want to try out this stuff, it automatically becomes active when you disable SDL_mixer 2, so just set
PLAYER_WITH_SDL2_MIXER
toFalse
and it should become active, if you're on a supported OS. Speaking of supported OS...Mac and Windows only
I've written midiout device implementations for Windows and macOS. It should theoretically be possible for iOS, Linux, and libretro, but I haven't written these myself.
Ticks
There's also quite a lot of duplicated code to support ticks. Honestly this is just my C++ skills letting me down. I also don't completely understand how RPG Maker's GetTicks works and don't have any games that use it. See the
MidiTempoData
struct and related nastiness inaudio_midiout.cpp
, which is suspiciously similar to stuff indecoder_midigeneric.[h,cpp]
.