hex007 / freej2me

A free J2ME emulator with libretro, awt and sdl2 frontends.
Other
499 stars 78 forks source link

PlatformPlayer: Implement initial IMA ADPCM decoding support #192

Closed AShiningRay closed 1 year ago

AShiningRay commented 1 year ago

Closes #149.

Copying message from commit:

In order to decode IMA ADPCM wav files, we first read the incoming wav's header and check if the reported Audio Format is '17', indicating that it is an IMA ADPCM stream. If it is, we begin to decode its samples into signed PCM16LE while maintaining the same amount of channels, and sampling rate. Once that is done, we build a new header for the decoded stream to reflect its new format and then send the completed stream back to PlatformPlayer's wavPlayer so it can handle it like a standard wav stream.

Additionally, a simple 'low-pass filter' was added to combat crackling on resulting samples, as it was really overbearing, it vastly improves quality at almost no cost.

recompileorg commented 1 year ago

bah! I had a whole thing about the actual decoding! I don't know what happened to it. Well, here's the executive summary. I'm not writing that out again tonight:

See the reference implementation on page 32: https://www.cs.columbia.edu/~hgs/audio/dvi/IMA_ADPCM.pdf

The bit where you have all the ifs? That's an outdated optimization. The order of those ifs matters. It's outdated, so you can just do the multiplication as it'll be faster anyway. That what ffmpeg does, as you can see on like 733 here: https://www.ffmpeg.org/doxygen/0.6/adpcm_8c-source.html

Anyhow, I think the scratchiness is due to some mix of problems with the decoder and problems reading the file.

AShiningRay commented 1 year ago

Hmm... can't figure out why it still crackles a bit only on certain files. Most streams have no crackling at all with the updated code, only Asphalt 4's menu SFX shows any kind of crackling towards the end when played, but that's about all i could find that sounds a bit strange. Also, those playback repeats are definitely something to look at (on another issue perhaps), since FreeJ2ME constantly plays the same audio file two and sometimes even three times consecutively instead of a single one.

AShiningRay commented 1 year ago

Alright, now it's way better. No real crackling anymore even on shorter streams (at least can't hear any on Asphalt 4, 6 and Motocross Trial Extreme, which are the ones i could hear before), and the header is created and slotted at the start of the decoded stream without issue. In theory this means we are able to dump PCM and ADPCM wav files later for debugging if we really need to.

Still doesn't sound exactly like J2MELoader, but that one seems to rely a lot on Android's underlying systems, and i've no idea what they do to those files under the hood, not to mention FreeJ2ME still has a ton of issues with audio playback. @recompileorg once you have time, please take a look at this and tell me what you think.

Note: Yeah, still a lot of things being declared "final", as that's the only way i could find to improve performance enough to minimize freezes on some of my more limited hardware with Java 8 without incurring in sync issues by using threads... weird that those freezes only happen in Java 8 though.

recompileorg commented 1 year ago

Sorry, I just can't find the time to give it a full and proper review. It's okay to merge, but I would have liked to dig a bit deeper into it.

AShiningRay commented 1 year ago

Sorry, I just can't find the time to give it a full and proper review. It's okay to merge, but I would have liked to dig a bit deeper into it.

No problem, been pretty short on time myself those last few months. Been planning on adding some prebuilts on my repo so that users have an easy way of downloading FreeJ2ME without manually building it by themselves, but between work, other hobbies and home affairs, i wasn't able to yet. Gonna see if i can separate some time tomorrow to sort that out and update the compatibility list while i'm at it.