libmodplug in python! (part 1)
16 years ago
General
Anyone here know python?
So today I had the stupidly ambitious goal to try and play a mod file using libmodplug from python, with almost zero python programming experience first-hand, no knowledge of C/C++, and practically zero documentation.
A slight bit of help from
halcy set me in a decent direction, and many many hours later I think I managed to make the beginnings of some bindings, which you can see here:
http://pastebin.ca/1395447
To make it work, you need to replace all the absolute paths with dynamic ones to modplug.dll (which you can get by downloading OpenJazz, a jazz jackrabbit engine thing), or possibly libmodplug.so if you're using linux.
I'm not sure where to go from here just yet, but I'm assuming it has something to do with taking the output given from one of these functions and plugging it into some audio function from another library, depending on the platform.
Why go through all the trouble when there's already working examples in python for tons of other mod replayers? Mainly cause, of all the ones that are good, they aren't free, and the ones that are free, aren't good. The only exceptions are libdumb and libmodplug, and since dumb is derived from modplug (minus a lot of Impulse Tracker support), I attempted to go in that direction.
Oh, also, if I were to choose PyGame as my target framework, I'd need some way to play all the music I composed for Kyubi, so consider this like a first step to that :0
Edit: It might make it a whole lot easier to understand what these functions do if you read the comments from the original header file, modplug.h.
So today I had the stupidly ambitious goal to try and play a mod file using libmodplug from python, with almost zero python programming experience first-hand, no knowledge of C/C++, and practically zero documentation.
A slight bit of help from
halcy set me in a decent direction, and many many hours later I think I managed to make the beginnings of some bindings, which you can see here:http://pastebin.ca/1395447
To make it work, you need to replace all the absolute paths with dynamic ones to modplug.dll (which you can get by downloading OpenJazz, a jazz jackrabbit engine thing), or possibly libmodplug.so if you're using linux.
I'm not sure where to go from here just yet, but I'm assuming it has something to do with taking the output given from one of these functions and plugging it into some audio function from another library, depending on the platform.
Why go through all the trouble when there's already working examples in python for tons of other mod replayers? Mainly cause, of all the ones that are good, they aren't free, and the ones that are free, aren't good. The only exceptions are libdumb and libmodplug, and since dumb is derived from modplug (minus a lot of Impulse Tracker support), I attempted to go in that direction.
Oh, also, if I were to choose PyGame as my target framework, I'd need some way to play all the music I composed for Kyubi, so consider this like a first step to that :0
Edit: It might make it a whole lot easier to understand what these functions do if you read the comments from the original header file, modplug.h.
FA+

I've been meaning to reinstall python and pygame and all the other bits that are necessary since I formatted my hard drive the nth time, but, eh.
I was looking through http://salticus-peckhamae.mit.edu/S.....ug/modplug.cpp to find the definition of that _ModPlugFile struct, except now it's referring to a CSoundFile, which appears to be defined in one of those three or so other header files. I'm going to keep looking at it, though; this is actually the most difficult thing I've done in Python to date (never used ctypes before), so it's great fun.
gccxml
ctypeslib (with scripts)
microsoft visual c 8 compiler (if you have gcc setup, just link to g++ instead of cl.exe, then you won't need this)
once all that's installed and properly setup, go to /scripts/ in your python folder and type something like "python h2xml.py sndfile.h -o sndfile.xml" .... it's gonna bitch a lot. You can deal with gccxml directly in that case instead of h2xml if you know more about the error output than I do (remember that I don't understand C languages). I used gccxml directly instead of h2xml to generate modplug.xml. If you can manage to get the xml, type something like this: "python xml2py.py sndfile.xml -v -l modplug.dll -o sndfile.py". If you don't specify the dll, sadly, it won't export the functions.
Partly, I should also note that I don't know how or from what modplug.dll was actually compiled, and I'm assuming it's a 1:1 drop-in for libmodplug.so on linux, though that could be wrong, although including it in xml2py's -l switch did allow it to define functions that it couldn't without that parameter...
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: expected LP__ModPlugFile instance instead of c_void_p
...and I had no luck casting it to LP__ModPlugFile:
NameError: name 'LP__ModPlugFile' is not defined
typedef struct _ModPlugFile ModPlugFile;
like _ModPlugFile is defined in modplug.h.
I'm writing perl bindings right now, and really, you shouldn't have to care about that struct much.
Now I'm getting
ValueError: invalid string pointer 0x0000E99C
WindowsError: exception: access violation reading 0x0000....
when I use ModPlug_GetLength or ModPlug_Read
this is my first python program ever (No, I didn't do a "hello world" yet hahaha):
http://pastebin.ca/1396204
I use DUMB in my perl script that exports mods to my mp3 player :D