C# Tracker libs?

Started by gir489, February 09, 2016, 20:18:52

Previous topic - Next topic

gir489

I'm trying to find a decent tracker that has support for ScreamTracker, ProTracker, FastTracker and ImpulseTracker.

The current one I'm using now is called SharpMik, which is based off MikMod.

It's OK, but it implemented the tracker logical TOO well. There's ceritan bugs in FT2 and Scream Tracker that aren't supported and cause the XMs and S3Ms to not play exactly right, or they don't play in the right tempo.

The last update to MikMod was in 2015, however the last update to SharpMik was like 2012, and lots of the weird quirky bugs introduced in to MikMod to support the aforementioned bugs from FT2 are implemented in MikMod, but the developer of SharpMik hasn't ported them over yet.

What I'd really like is if someone has ported libopenmpt to C# that'd be amazing, since OpenMPT has properly implemented every tracker known to man.

One of my demoscene friends pointed out this to me https://github.com/lioncash/LibModPlugSharp but it doesn't have implementation for a FileStream object, and SharpMik does. So using the ModPlugSharp wrapper is not viable

Saga Musix

Just to avoid confusion, I suppose you are looking for a module playback library? A tracker is the tool used to create modules. Playing modules back in another program is done using a module playback library. So I suppose you want to do the latter?
First and foremost, don't use MikMod, while it may have been last updated in 2015, those changes were all minor and did not improve XM or S3M playback compatibility. MikMod has been essentially abandoned for a very long time and will play many files incorrectly. The same is true for libmodplug, don't use it.

QuoteWhat I'd really like is if someone has ported libopenmpt to C# that'd be amazing
You don't need to port the entire libopenmpt to C#, you just need to create bindings for the C interface (which I assume is the same as what SharpMik and LibModPlugSharp do) to call its native code from managed C# code. I'm afraid there are no such bindings at the moment, but you are very much welcome to create your own and share them back with the community. I personally don't use .net so I cannot help you here, but the easiest way to get started would probably to import the C interface using P/Invoke. Alternatively, there seem to be more fancier ways to do this using e.g. CppSharp or CXXI.

Quotesince OpenMPT has properly implemented every tracker known to man.
That is very much untrue. :)

QuoteOne of my demoscene friends pointed out this to me https://github.com/lioncash/LibModPlugSharp but it doesn't have implementation for a FileStream object, and SharpMik does. So using the ModPlugSharp wrapper is not viable
You could read the file stream yourself and then pass it to libmodplug? What stops you from doing it that way?
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

gir489

There's nothing stopping me from writing the wrapper myself, I was just asking if someone had already done this properly already. And yes, I'm looking for a playback library.

And OpenMPT has yet to fail me in 1:1 recreating any file I throw it at vs using DOSBox to play it back. I can't hear any difference.

Saga Musix

QuoteThere's nothing stopping me from writing the wrapper myself, I was just asking if someone had already done this properly already.
If you are going to do this, would you be willing to share the results back? It would be indeed great to have official bindings for C# for future users.

QuoteAnd OpenMPT has yet to fail me in 1:1 recreating any file I throw it at vs using DOSBox to play it back. I can't hear any difference.
It will play the majority of files correct, indeed, but I can easily construct something in most formats that will play incorrectly in (lib)openmpt. :) Plus there is a huge number of tracker formats that cannot be played at all, but there are luckily other libraries that take care of that.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

gir489

#4
So I took the wrapper and added an overloaded method to just take a raw byte array and pass it to libmodplug.

However, I can't for the life of me get this thing to loop... Here's the source if you're interested: https://www.mediafire.com/?t76u5mggc00nhdr

I tried passing the settings to it first (I tried .loopCount = -1 first but that didn't work), I tried handling the StopEvent. With MikMod, I just called .Play() and it would play forever.

I guess that doesn't work, so I'll just have to write an entire wrapper for libopenmpt.

Saga Musix

Hm, I'm not sure either why that wouldn't work... The LibModPlugSharp code seems to look correct to me, so it could be anything. With libopenmpt I could actually help you, I've never used libmodplug itself. :)
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

gir489

#6
I'm more interested in getting libopenmpt to work with C#. That was just a Q&D solution to see if I could even get that to work. I thought that was using libopenmpt, but after working with it and finding out it sucks, it clearly does not.

I'm writing a trainer base that will basically emulate Cheat Engine's Lua trainer generation to the T. But of course I ran in to a whole bunch of issues doing that, mainly with the XMPlayer they use is kinda shitty, and I want everything to be contained in a single EXE like the C64 days where you had to limit everything you wanted to run to a certain section of the cartridge to be a fast loader.  Just a weird programmer quirk I've carried over.

But basically I just want OpenMPT's output of a XM/MOD/S3D/IT to play out of my trainer that would be self contained. That would give me 2 legs up on CE's garbage XMPlayer.exe in that it would support more modules, be scaleable with the OpenMPT project, and I'd contribute back to the community in writing a C# wrapper for libopenmpt. Everybody wins.

I noticed my old version of in_openmpt.dll references libopenmpt.dll, but the latest beta one I got has it self contained? I can't find the DLL to reverse the EAT and figure out what methods do what, since I can't even find documentation on the module, so I'm assuming I'm going to have to reverse engineer it.

Saga Musix

As posted above, full documentation of libopenmpt is available, there is no need to reverse-engineer anything. in_openmpt just wraps libopenmpt as a Winamp input plugin, so this is actually not very intersting for you (unless you want  to write a Winamp clone :)). libopenmpt.dll's exposed interface is exactly the one described in the documentation above.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

gir489

Wow. That's really well documented. I'm just so used to working with shit libraries and half-implemented shit that the documentation says it does one thing and when you query the EAT for it, you get back something completely different.

When I download this: https://lib.openmpt.org/files/libopenmpt/bin/libopenmpt-0.2.5787-beta16-bin-win.7z

I don't see a libopenmpt.dll anywhere. Just in_openmpt which seems to be self contained.

Saga Musix

Yeah, there is no "official" binary download because of how C++ libraries work - you must use them with exactly the same compiler that was also used to compile the library, as the object layout and calling conventions are not standardized across compilers. This is not really a problem for C libraries, but libopenmpt.dll is both at the same time.
So you can either compile it yourself from the source (it's as simple as opening the appropriate SLN file for your Visual Studio version and hitting the compile button), or you can take a pre-compiled test version (compiled with VS2010, so in case you want to use the C++ interface you must use VS2010) from our buildbot: https://buildbot.openmpt.org/builds/auto/libopenmpt-dev-vs2010/
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

gir489

C# is basically just a wrapper for x86/x64 Windows, since Microsoft doesn't really (officially) support running C# on any other platform (except for WinRT ARM), so as long as the exports are __declspec, there really shouldn't be any confusion for using it in C#.

I'll give you an update on the wrapper soon when I get time to sit down and write it right, and not slap something together.

Saga Musix

Quoteso as long as the exports are __declspec, there really shouldn't be any confusion for using it in C#.
Well, for the C++ interface it's a bit more complicated - because calling conventions are not standardized and do indeed change between compiler versions. Using the C interface would be the safest, but if you really want to make the library feel like a native C# library, you may want to either somehow work with libopenmpt's C++ interface (documentation), or at least mimic it using the C interface. The C++ and C interfaces are identical when it comes to functionality, but the C++ interface simply looks more like C++ than the C interface. :) So doing something similar for the C# interface would be a good idea.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

gir489

#12
Which is why I obey the Microsoft master lords. If you're using one piece of Microsoft software, you're gonna use it for everything. Microsoft C# (wrapper) running Microsoft C++ (libopenmpt) running Microsoft Windows (OS) running MASM (x86).

There's a lot to be said about totalitarian design, you get great things like C#. But then you also have things Microsoft thinks are a great idea, like ASP.NET which came out really bad, but it made the best of the really abstract problem it was trying to solve, as opposed to JSP which is just a huge mess. But when you have everyone and their mother ignoring standards you end up with shit like SQL, where nobody is even CLOSE to the original ANSI SQL spec. You just end up with a horse designed by committee situation.

Anyway, yeah I don't plan on porting this to Mono or something, I'm just going to strictly contain it in Visual Studio running Windows. I don't see any other way of doing it, unless we abstract almost everything, including the wave form generator which would be a pain in the ass. I'm just going to make it use NAudio, since that seems to be the popular solution for playing audio out in C# apps.

Fatarse

So are you looking for the be all and end all of trackers? One that faithfully mimics all of them?

Saga Musix

No, they want a playback library for inclusion in other programs, not a tracker. To which libopenmpt is currently one of the best answers.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.