-
Notifications
You must be signed in to change notification settings - Fork 78
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
Improve audio playback for both wav and midi streams #199
base: master
Are you sure you want to change the base?
Improve audio playback for both wav and midi streams #199
Conversation
It appears that most java games (Gameloft ones, like Asphalt 4, Asphalt 6, Ferrari GT 3, Assassin's Creed Revelations and many others for example) set the loop count on both midi and wav streams as 1. This, however, translates to Java 8 looping those samples one time more than needed, so every sfx and bgm playback repeated two times instead of just one. By reducing the requested loop count by one and checking cases where J2ME apps might request loop count 0, pretty much all the aforementioned games have their audio playback fixed.
DOOM II as well as Orcs and Elves II appear to constantly allocate new MIDI samples whenever a different sample from the previously played one is loaded, and never deallocate any of their samples, resulting in memory leaks. While not the best solution to this, we can work around those leaks by imposing a hard limit on how many MIDI "channel slots" a J2ME app can populate. Currently set at 36 slots, it seems to be big enough for anything i tested so far, including Ferrari GT 3 which loads up many different MIDI BGMs alongside wav files (unrestricted, can allocate as many as needed) during a race.
Swapping them to byte variables helps indicate that they should not receive larger values.
The main thread on FreeJ2ME is already pretty busy with graphics and everything else, we don't need ADPCM decoding clogging things up even further. This should help make decoding faster and reduce stuttering.
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.
"There are only two hard things in Computer Science: cache invalidation and naming things." --Phil Karlton
"MIDI Channel" has a specific meaning in MIDI, which is very different from how it's being used here. As for what to call it, that's up for debate. I thought "MIDI Stream" might be okay, though I can think of reasons why that could also be confusing... "MIDI Source" or "MIDI Audio Source"?
Anyhow, sorry that I've been so absent this year. Things should slow down quite a bit in November, baring unforeseen disaster. I'll try to make my freej2me backlog a priority then.
Yeah, couldn't think of a good way of naming those either. Only settled for "channels" (with quotation marks) because i thought it would kinda work by imposing a max limit on how many streams would be able to be played at any given time, similar to FM chips with a limited amount set of channels for FM Synthesis. Still, i also don't like calling those "channels", just couldn't find any better naming scheme for them just yet... "MIDI Players" could also do, but this really feels like something that should come with a tooltip, description or something along those lines to better explain what it's about. |
Instead of relying on a fixed value for the max, a user setting for that allows more control and fine tuning for specific apps.
Previously, the logic behind deallocating streams only took into account if the player index had reached the end of the array, and started deallocating from its first position onwards. This was a problem because it is possible that some of those positions would still be running when FreeJ2ME went to deallocate them. Now it will also take into account whether the current position is running or not, and will only forcefully deallocate a position that's running if the entire array is allocated, and all the players are running, to make space for a new one.
Fixes #197
Fixes #198
First off, i think it might result in conflicts if #193 is to be merged at some point, so i'll have to look at it later.
Now to the PR itself... this one contains fixes for audio looping on both MIDI and WAV streams, as well as a workaround to ID Software games' tendency to infinitely allocate new MIDI streams. The latter doesn't have a straightforward fix as far as i can tell, since InputStreams are used heavily throughout the audio players, though i'm open to discussions on how to improve this workaround or even do away with it by implementing a better fix.
As a bonus, this PR also comes packed with a few minor cleanups to the ADPCM decoder, as well as threading support for it, to make it a bit lighter at runtime.