DragonMinded / libdragon

Open source library for N64 development.
https://libdragon.dev
The Unlicense
695 stars 100 forks source link

Deprecate mikmod #202

Closed rasky closed 1 year ago

rasky commented 2 years ago

With the new audio library and the high performance XM player, which is indeed compatible with having music in background with very little CPU/RSP usage, I think that the mikmod N64 port, that is built by build.sh, can actually be deprecated and removed. That port is 100% CPU based, and the performance is actually good only for standalone music players.

I don't want to cause breakage to existing projects linking to it, but we should at least mark it as deprecated somehow and maybe remove it from docs.

vieux commented 2 years ago

Does the new lib only support .xm or .mod as well?

I'm asking because I'm using .mod is last year's jam and mikmod is supporting several format.

rasky commented 2 years ago

Only XM, but it's in general possible to convert from MOD to XM without too many problems.

rasky commented 2 years ago

I will expand this answer. In general, it's possible to at least try to convert module formats to XM. It will also work generally well, with caveats.

1) MOD files will normally work (especially since XM has been designed as a super-set of MOD). The only issue is that in MOD files it is possible to define a per-channel panning setting, which is not supported by XM (where you can do much more elaborate panning, but not a per-channel setting). So the result of the conversion will be mono.

2) S3M modules can be converted to XM. Again, if the per-channel panning flag is used that is lost, but S3M also supports more granular panning and those are converted to XM correctly. There might be some advanced effects in S3M that are lost, but it should be residual. Also some S3M modules can use the FM synthesis (very rare) which is not supported (also it would be dog slow with mikmod on N64 anyway).

3) IT modules might also be converted to XM in principle, but those are more complex to do. IT modules are the most modern format that comes with a modern design mindset and newer generation PCs in mind. For instance, the IT feature called NNA (new note action) is troublesome because it allows you to expand the number channels to ~infinite (because you can being playing a new note/instrument keeping the previous one running, effectively destroying the historical model of modules where 1 channel = 1 note = 1 mixer input).

To do the conversion, you can use OpenMPT or MilkyTracker. After the conversion, the resulting module can be manually adjusted again in case something's slightly off (but coming from MOD, I'd be surprised).

DragonMinded commented 2 years ago

But why though? XM is just one format and it is played back by just one audio library. That library happens to run on the RSP, but you might want to use that for its intended purpose: vector translations for GL/affine/perspective calculations. Its a library that can be used or can be skipped, it shouldn't need "deprecating".

rasky commented 2 years ago

Currently, mikmod is built with libdragon by build.sh so it's given some sort of special blessing. It's not just one random library that is compatible with libdragon.

I would say that for all new homebrew projects, the new audio library is a superior choice because it uses a fraction of the CPU time (less than 10 times on average) and uses a bit of RSP (less than 10%), so it's not probably going to interfere with RSP usage for graphics much (also notice that the 10% figure refers to 60FPS, which is not exactly common on N64 anyway). Also it's very likely that, if your RSP graphics usage is so high that allocating 10% of it to music is a problem, the alternative of using mikmod which instead uses 30-50% of CPU time is still not going to fly. You would probably need to keep using the RSP-based audio library and maybe reduce a little bit the heaviness of the module being played.

So what I am suggesting is:

DragonMinded commented 2 years ago

The whole break the build thing is what concerns me. One of the examples that comes with libdragon uses mikmod (or did as of last messing with it) and it would be sad to get rid of it since it shows such a clean way of integrating with the filesystem and external libs to do something useful.

I have a suggestion for how to handle this but it is going to be a bit of work. In my naomi toolchain that I'm currently playing with, I have a "3rdparty" directory (https://github.com/DragonMinded/netboot/tree/trunk/homebrew/3rdparty). I stole this idea from kos-ports (https://github.com/KallistiOS/kos-ports). Essentially how it works is there's a top level makefile that just goes into each subdirectory and calls make, and each of those is just a small set of configuration rules for where to download, how to build and how to install a particular 3rd party lib. The top level makefile which builds the core system library and examples does not build 3rdparty by default, and a few example makefiles check for prebuilt libraries existing before deciding to link in extra functionality or not. This is a bit complicated to setup from the maintainer's perspective but it has a really cool advantage: You can "make -C 3rdparty" from the top level and it will use the existing toolchain to build and install a series of supported ports which are then available to examples and others using them.

If libdragon were to introduce such a concept I think it might be pretty useful. I didn't have any idea like this when I started libdragon a decade plus ago, but its come in VERY handy for my work on the naomi. It means that mik-mod is no longer special (it goes in 3rdparty and you have to build it by asking for it), but there's still a supported, super easy (one line of shell code) way to get it as well as possibly others like zlib, libpng, freetype, or other useful libraries.

Reminder: everything I publish on that repo is public domain so anything useful that you want to steal back for here is fair game. If such a suggestion makes sense and is desirable then by all means please help yourselves.

anacierdem commented 2 years ago

Actually this is somewhat the direction we were planning to head for. Instead of having a build script, it would be much easier to manage dependencies via make. When it comes to mikmod, I don't think it is much useful anymore but I don't see deprecating it a must. When it comes to examples, I think we are actually improving them day by day so I believe we will be able to align at some point.

rasky commented 2 years ago

Yeah I like very much the idea of having a 3rdparty directory with a Makefile for each package

networkfusion commented 2 years ago

You do realise that where you are currently getting mikmod from doesnt even exist... I moved it to the n64-tools org years ago! I guess it is lucky that it automatically redirects still.

rasky commented 2 years ago

You do realise that where you are currently getting mikmod from doesnt even exist... I moved it to the n64-tools org years ago!

Yeah but GitHub allows us to be lazy by offering a redirect service :) We will get it fixed once we get to implement what is described here (3rd party dir). Thanks!

danbolt commented 2 years ago

Some N64Brew jam submissions from 2020 do use the CPU libmikmod stuff, so it might be worth keeping around as a thirdparty option like @DragonMinded suggests.

rasky commented 1 year ago

We moved the mikmod build step into a different script in https://github.com/DragonMinded/libdragon/commit/d74706b5962ecbbf4c9faa00075a2843eeebcabe

I'm going to update the upgrade guide to mention this: https://github.com/DragonMinded/libdragon/wiki/Upgrade-troubleshooting