Mod Player (aka Chiptune Player) Native Extension

#1

Here is my UDGJ2 entry; ModPlayer and I want socks now :slight_smile: It is not of course, but I wanted it to be somehow ready for the UDGJ. Maybe someone wants to use it for their Jam game.
As a dinosaur developer, I miss my C64 and Amiga days. When developing this simple extension I remembered those days a lot.

Mod Player (aka chiptune player) can load and play good old .XM and .MOD file formats.
There are some hitchups, but extension supports MacOS, Windows, Linux, Android, iOS and HTML5. Unfortunately, HTML5 bundle is little tricky. There is a little py script which simplify things for now. Please read the details on Github page.

Asset Portal: https://www.defold.com/community/projects/147260/
Github: https://github.com/selimanac/defold-modplayer
Simple Examples: https://github.com/selimanac/defold-modplayer-examples
Nanowar Example: https://github.com/selimanac/nanowar-modplayer (All credits goes to @benjames171 )

Most important issue for me is that I couldn’t find a way to retrieve build path when developing on Defold Editor. It returns something like …/Defold.app/… and it is not possible to read files from that location. As a workaround I added a player.build_path function for manuel setting. But this is just for working on the editor only. If there is a better way of doing this please let me know.

I couldn’t test the musics on Linux because I couldn’t manage to configure the sound card on my VMs successfully. If someone can test it I’ll be glad.

Other notes and know issues:

  • Loading and parsing is blocker. It will block the main thread (UI thread). Since the mod files are small it is better to load them when bootstraping or preloading. It may cause a pause on UI.
  • Loading and parsing .XM files much more faster then .MOD files. Use XM if possible. (Tested with same tracker file as .mod and .xm)
  • Not %100 compatible with every MOD or XM file.
  • I couldn’t find a way to retrieve build path when developing on Defold Editor. You have to provide a full path to player.build_path("<FULL_PATH>/res/common/assets/") function for working on Defold Editor only . It doesn’t required when bundling.
  • Different platform bundles didn’t tested very well.
    • MacOS: Long run.
    • iOS: Long run.
    • Windows: Short run. Tested on Wine
    • Android: Short run.
    • Linux: I couldn’t manage to have sound on my VMs. But app is successfully load the files and run on Debian and Ubuntu
  • Hashtable is limited to 10 elements. I think it is more than enough. It is a bad practice to load or play more than two music files at the same time.
  • Currently, it is not possible to Build HTML5 on the Defold Editor with mod music. You can build it for testing, but can’t load the the musics.
15 Likes

#2

This is great! Thank you for making this contribution!

3 Likes

#3

Example doesn’t run for me.
ERROR:MODPLAYER: build_path cannot be empty.
What do you mean by" <FULL_PATH> "?

0 Likes

#4

As the error said, you have to provide a project path when building on Defold Editor. You are passing a empty string.

Just updated the docs with more info. Also updated the error message

1 Like

#5

Ok, so you mean os system folder location, your example of “<FULL_PATH>/res/common/assets/” was throwing off because of wrong slash symbols.
But I get error :

Compilation failed: invalid escape sequence near '"D

for your example project on line:

local build_path = "D:\Users\agnis\Documents\Defold\SOURCE\defold-modplayer-master\res\common\assets"

P.s. Bundled EXE runs nicely.

1 Like

#6

Actually slash symbols are correct. I made a mistake on doc by using \. My bad, sorry about that. (Just updated the doc)

This should work. Don’t forget to add trailing /

local build_path = "D:/Users/agnis/Documents/Defold/SOURCE/defold-modplayer-master/res/common/assets/"

Unfortunately I don’t have a Windows box and I can’t test this with Defold Editor. But this time, I tested this path with Wine and it works. Please let me know it is fail or not.

:ghost: Nice to hear that. Thank you for testing :slight_smile:

0 Likes

#7

I don’t get what’s wrong.
After adding trailing slash everything after changes color like string value without ending quotes (").

0 Likes

#8

This is wrong \. Use this /

Just copy-paste this please:

local build_path = "D:/Users/agnis/Documents/Defold/SOURCE/defold-modplayer-master/res/common/assets/"
1 Like

#9

YES! That is working. I tried backward slash before but didn’t think about trailing one.
I say backward because on window directories have "\ ", I don’t remember if Mac or Linux have an opposite.

0 Likes

#10

Great!
I think I should add a control for trailing one. This will be a common mistake.

Actually every platform uses / inted of \ It is a ancient DOS problem… https://stackoverflow.com/a/38428899/10580287

1 Like

#11

Thank you for extension! I’m really excited to try it out, since that’s closest thing I can get to NES-like music.

1 Like

#12

It is not perfect but better than nothing. I hope someday we can get rid of this build_path problem.

1 Like

#13

Well, the biggest problem with it is to convey the right information to users other than that it’s an actually neat workaround.

Sorry, for additional questioning:
I noticed that it does auto-loop for songs so I made test pattern in Milkytracker with 2 snare hits to test and the mod player kept looping it (for the first time returning to start it makes tiny glitchy sounds and I’ve heard those also when it looped included sound files).
Is this mod player usable for game sound effects (single play over music or taking over channel like NES music)?

0 Likes

#14

I’m aware of that glitch. But honestly I’m not sure why it is happening. It happens on some patterns with some samples(only when starting), but I didn’t investigate it yet. (It shouldn’t happend with .mod files, only with .xm) Somehow it is related to my patch. I’ll take a look at this after the UDGJ2
It is better not to trust the loop for pattern continuity. It is not suitable for this kind of job.

Maybe :slight_smile: Interesting idea, I never thought about this. It is quite performant but I’m not sure if it is usable for this kind of a job or not. I’ll definitely try this when I got time.

You can set loop by using; player.music_loop(music, 1) <- single play

1 Like

#15

Wow, I don’t know why I missed loop function!
Thank you!

1 Like