MrcSnm/HipremeEngine

FR: MOD/XM/S3M/IT support

MetalMaxMX opened this issue · 12 comments

This is something of an optional thing but I think it'd be pretty useful to showcase be it on gamejams or technical demonstrations of the engine. These formats are known for being made from a program known as a tracker, and they contain sample data and everything needed to run standalone. I was wondering if it would be feasible or possible to have this added on the HipremeEngine?

MrcSnm commented

Currenly, HipremeEngine is using https://github.com/AuburnSounds/audio-formats for decoding.

Seems like both MOD / XM is supported. I never used those kind of formats which is why I don't list them on the engine. If you wish to test them, give it a try and send me if it worked. I think I don't even have a file in that format to test

Hey, we have some module files to work with. S3M files and all can be found on this profile of the ModArchive https://modarchive.org/index.php?request=view_artist_modules&query=69185 and Jeroen Tel has both mod and XM files ready for testing https://modarchive.org/index.php?request=view_artist_modules&query=83766

I too would like to know the steps required to properly test these formats actually. Is there a way to test with a script or something like it? (or does it runs through HipAudio)

MrcSnm commented

Hello! Sorry for the late reply!
To test them, it is pretty simple, I have done a massive refactor on the asset loading usability:

import hip.api;
class MainScene : AScene
{
    @Asset("sounds/myfile.mod")
    IHipAudioClip clip;


    IHipAudioSource src;
    mixin Preload;

    override void initialize()
    {
        src = HipAudio.getSource();
        src.clip = clip;
    }

    override void update()
    {
        if(HipInput.isMouseButtonJustPressed())
            src.play();
    }
}

mixin HipEngineMainScene!MainScene;

Should be like that

Could you give me a step by step? I am getting my wet feet with HipremeEngine and I thought by changing parameters in testscene.d would do the trick (change the .wav to .xm or .mod), which in the end didn't
https://github.com/MrcSnm/HipremeEngine/blob/952a30952a5468f1c067c9c0bf4e1d95c330b051/source/hip/view/testscene.d

MrcSnm commented

What happened when you changed to .mod?

HIP: AssetManager: Loading Audio: sounds/fracture_in_space.mod
HIP: Added a complete handler for Load AudioClip:sounds/fracture_in_space.mod
HIP: starting test scene.
HIP: Required path sounds/fracture_in_space.mod
HIP: Path validated.
Worker Load AudioClip:sounds/fracture_in_space.mod failed with error:core.exception.AssertError@api/source/hip/api/data/audio.d(27): Encoding from file 'sounds/fracture_in_space.mod, is not supported.

??:? _d_assert_msg [0x55ee37dbeb64]
api/source/hip/api/data/audio.d:27 hip.api.data.audio.HipAudioEncoding hip.api.data.audio.getEncodingFromName(immutable(char)[]) [0x55ee37da92a2]
modules/assets/source/hip/assetmanager.d:561 void hip.assetmanager.HipAssetManager.loadAudio(immutable(char)[], immutable(char)[], ulong).__lambda4!(immutable(char)[], void delegate(hip.asset.HipAsset), void delegate(immutable(char)[])).__lambda4(immutable(char)[], void delegate(hip.asset.HipAsset), void delegate(immutable(char)[])).__lambda4(in ubyte[]) [0x55ee37ccf9a9]
modules/filesystem/source/hip/filesystem/hipfs.d:114 hip.api.filesystem.hipfs.IHipFSPromise hip.filesystem.hipfs.HipFSPromise.addOnSuccess(void delegate(in ubyte[])) [0x55ee37ce2acc]
modules/assets/source/hip/assetmanager.d:558 void hip.assetmanager.HipAssetManager.loadAudio(immutable(char)[], immutable(char)[], ulong).__lambda4!(immutable(char)[], void delegate(hip.asset.HipAsset), void delegate(immutable(char)[])).__lambda4(immutable(char)[], void delegate(hip.asset.HipAsset), void delegate(immutable(char)[])) [0x55ee37ccf917]
modules/assets/source/hip/assetmanager.d:411 void hip.assetmanager.HipAssetManager.loadSimple(immutable(char)[], immutable(char)[], void delegate(immutable(char)[], void delegate(hip.asset.HipAsset), void delegate(immutable(char)[])), immutable(char)[], ulong).__lambda7() [0x55ee37ccf0a6]
modules/util/source/hip/util/concurrency.d:231 void hip.util.concurrency.HipWorkerThread.run() [0x55ee37dae0e4]
??:? void core.thread.context.Callable.opCall() [0x55ee37dc11a4]
??:? thread_entryPoint [0x55ee37dc0c82]
??:? [0x7fdca29bcea6]
??:? clone [0x7fdca2772a2e]
Expose event

A similar error also occurred when I put an XM module file. So yeah, that's what happened

MrcSnm commented

Oh I'm pretty sure that my engine actually checks for those extensions, so, I think it is a matter of only validating them, gonna update asap

I went ahead and tried the latest commit, this is what I get instead:
modules/audio_decoding/source/hip/audio_decoding/audio.d(9,5): Error: missing cases for enum members in final switch:
modules/audio_decoding/source/hip/audio_decoding/audio.d(9,5): MOD
modules/audio_decoding/source/hip/audio_decoding/audio.d(9,5): XM
Error /usr/bin/dmd failed with exit code 1.

MrcSnm commented

Sorry this was untested :( I'll update it real quick

By the way, don't worry. I'll report as fast as I can regarding updates to this, is not a problem for me. This is what I got now when doing the latest commit and dub:

HIP: AssetManager: Loading Audio: sounds/fracture_in_space.mod
HIP: Added a complete handler for Load AudioClip:sounds/fracture_in_space.mod
HIP: starting test scene.
HIP: Required path sounds/fracture_in_space.mod
HIP: Path validated.
Expose event
Worker Load AudioClip:sounds/fracture_in_space.mod failed with error:core.exception.AssertError@modules/audio_decoding/source/hip/audio_decoding/audio.d(212): Out of boundaries decoding

??:? _d_assert_msg [0x55f35cd6a090]
modules/audio_decoding/source/hip/audio_decoding/audio.d:212 uint hip.audio_decoding.audio.HipAudioFormatsDecoder.updateDecoding(ubyte[]) [0x55f35ccabc7c]
modules/audio_decoding/source/hip/audio_decoding/audio.d:169 bool hip.audio_decoding.audio.HipAudioFormatsDecoder.decode(in ubyte[], hip.api.data.audio.HipAudioEncoding, hip.api.audio.HipAudioType, void delegate(in ubyte[]), void delegate()) [0x55f35ccab949]
api/source/hip/api/data/audio.d:76 bool hip.api.data.audio.IHipAudioDecoder.loadData(in ubyte[], hip.api.data.audio.HipAudioEncoding, hip.api.audio.HipAudioType, hip.api.audio.audioclip.HipAudioClipHint, void delegate(in ubyte[]), void delegate()) [0x55f35cd54407]
modules/audio/source/hip/hipaudio/audioclip.d:131 bool hip.hipaudio.audioclip.HipAudioClip.loadFromMemory(in ubyte[], hip.api.data.audio.HipAudioEncoding, hip.api.audio.HipAudioType, void delegate(in ubyte[]), void delegate()) [0x55f35cc89365]
modules/assets/source/hip/assets/audioclip.d:19 bool hip.assets.audioclip.HipAudioClip.loadFromMemory(in ubyte[], hip.api.data.audio.HipAudioEncoding, hip.api.audio.HipAudioType, void delegate(in ubyte[]), void delegate()) [0x55f35cc7eb39]
modules/assets/source/hip/assetmanager.d:561 void hip.assetmanager.HipAssetManager.loadAudio(immutable(char)[], immutable(char)[], ulong).__lambda4!(immutable(char)[], void delegate(hip.asset.HipAsset), void delegate(immutable(char)[])).__lambda4(immutable(char)[], void delegate(hip.asset.HipAsset), void delegate(immutable(char)[])).__lambda4(in ubyte[]) [0x55f35cc7a9d7]
modules/filesystem/source/hip/filesystem/hipfs.d:114 hip.api.filesystem.hipfs.IHipFSPromise hip.filesystem.hipfs.HipFSPromise.addOnSuccess(void delegate(in ubyte[])) [0x55f35cc8dacc]
modules/assets/source/hip/assetmanager.d:558 void hip.assetmanager.HipAssetManager.loadAudio(immutable(char)[], immutable(char)[], ulong).__lambda4!(immutable(char)[], void delegate(hip.asset.HipAsset), void delegate(immutable(char)[])).__lambda4(immutable(char)[], void delegate(hip.asset.HipAsset), void delegate(immutable(char)[])) [0x55f35cc7a917]
modules/assets/source/hip/assetmanager.d:411 void hip.assetmanager.HipAssetManager.loadSimple(immutable(char)[], immutable(char)[], void delegate(immutable(char)[], void delegate(hip.asset.HipAsset), void delegate(immutable(char)[])), immutable(char)[], ulong).__lambda7() [0x55f35cc7a0a6]
modules/util/source/hip/util/concurrency.d:231 void hip.util.concurrency.HipWorkerThread.run() [0x55f35cd59610]
??:? void core.thread.context.Callable.opCall() [0x55f35cd6c6d0]
??:? thread_entryPoint [0x55f35cd6c1ae]
??:? [0x7f324cbe7ea6]
??:? clone [0x7f324c99da2e]

MrcSnm commented

That is a bit more involved now, please attach your sound here and I'll test more of it in future.
My priority right now is implementing Metal (graphics API for iOS) so I'm unable to touch those things a lot right now

Sure. You can find an alternate XM here https://modarchive.org/index.php?request=view_by_moduleid&query=199820, and an IT file too https://modarchive.org/index.php?request=view_by_moduleid&query=200262
sounds.zip

And in the .ZIP you have the two modules I tested while trying to get it to work. The only parameter I changed was that testscene.d from the .wav file to one of the modules in particular.