#1094 link plugin generic interface/api

pa (1)
Zack Sawyer

I have implemented an interface library which uses the link plugin to hand over positional audio information to mumble.


The difference to using the link plugin itself is that the native code manipulating the linked memory does not need to be implemented. This library provides the required ways to fill the structure.
In java it is a handy alternative to the JNI approach. Code modifications in the class calling the native methods does not imply recompiling of the native library.

The difference to a regular plugin is that instead of developing a native plugin and submitting it to mumble, one can use the provided library and call upon the native methods directly.

This is initially intended to work mainly for JNA (https://github.com/twall/jna) but is probably not limited to it.
It should work with anything that is able to call native methods directly (i.e. Scripts, AutoIt etc.), simply provide this library.

I am not really sure how this would fit into the mumble distribution (the library could be shipped with the game/program which uses it). However since this native code needs to be compiled for each platform it would be handy for developers if mumble already provides the compiled library (just like the link plugin is compiled for multiple platforms). The developers would then only need to call the methods which are specified in the header file.

I will further test it in this Minecraft mod: https://sourceforge.net/projects/modmumblelink/

Thanks for reading,


  • Stefan H.

    Stefan H. - 2013-04-06

    Interesting. I've created something similar for interfacing with python code (https://github.com/dD0T/mumble_link). I (primarily) created it to use it for testing though so I never considered moving it to the mumble repositories.

    I think having some official repository containing different bindings (including our sample C(++) code) would make a lot of sense. Not sure whether putting them in the main repository would be a sensible thing to do.

    There's also the question of distribution. I guess if its a seperate repo we could, even though its bad style, simply push the binaries. On the other hand we could create real distributable packages which would be cleaner but more work.


  • Zack Sawyer

    Zack Sawyer - 2013-04-06

    This is cool, a pitty I didn't find it myself. I am thinking of adapting some of your code (to be honest I was thinking about getters and setters but I was too lazy to implement it) - copying your accessors and better code bits should be easy enough.

    The boost/python specific code would have to go into a separate file.
    So we would end up with a (hopefully) generic implementation which can be used across python, java and what not.

    A separate official repository would be great, I agree.

    As for distribution:
    It would definitely be better to provide the different natives (i.e. dll, so, dylib) one way or the other because not all developers who might use this API have the different OSes to compile for them (and cross compiling is a pain in the butt).

    I am kind of for your second distribution option as we would be able to also package already working interface implementations and samples which developers can directly use in their code. Aside from the libs we would include the boost module, the JNA implementation files, etc. .

    Here is what I mean:

    │       libLinkAPI.dll
    │       libLinkAPI.dylib
    │       libLinkAPI.lib
    │       libLinkAPI.so
    │       libLinkAPI64.dll
    │       libLinkAPI64.dylib
    │       libLinkAPI64.lib
    │       libLinkAPI64.so
        │       LinkAPILibrary.java

    Ofcourse along the interfaces should be some actual samples (i.e. test cases) which show how the interface implementations are used.

    Now all a developer has to do is to directly utilize any of the given or a custom interface and ship all the libraries along with his/her distribution.

    Publishing those libs with mumble directly could cause problems as the developer has to first locate the libraries instead of knowing exactly where he/she put them in their own package. But actually both methods are not mutually exclusive.
    I will probably redistribute the libs with my mod.

  • Stefan H.

    Stefan H. - 2013-04-07

    I guess we could extract some low-level common parts. Not sure how much can be meaningfully shared. I guess if nothing the initialization and memory structure should be shared. mumble_link uses C++ and some boost::python specific types in the function signatures. Other languages won't like that ;) All of the get/set functions are trivial though so not sharing those isn't a big loss.

    What I think makes a lot of sense is making the interfaces somewhat comparable in terms of features and, where not going against language idioms, signatures. If we can work out something sensible there that might be helpful.

    In terms of distribution I also like the packaging option best. However it is also the most work intensive one. I think you are right in that distributing them with Mumble wouldn't make much sense.

  • Zack Sawyer

    Zack Sawyer - 2013-04-07

    Yes these common low-level parts would be initialization of the linked memory and accessors to fill it (getters, setters, update functions).

    As I see it there are 3 interface levels:
    1. The simplest interface would have the setup and a single function to set the linked memory (sets the entire struct at once).
    2. For ease of use additional interface functions would be the setters and updaters based on the raw types used in the LinkedMem struct (i.e. wchar_t, unsigned char).
    3. Additional setters with various (preferably common) data types (string, wstring, etc). could be supported and do the appropriate conversion.

    The fourth level (not really an interface level, imo) would then be the language dependent accessors which use very specific custom data types (i.e. boost::python::tuple).

    To me it would seem to not be a frequent task to package it. The Link-Plugin hasn't changed in a very long time so I expect this API to be the same once it is stable.
    So once level 1 and 2 are done and level 3's files are encapsulated well enough no recompiling will be required, only compiling of new extensions (level 3).

    I am also pondering whether a separate plugin only for this purpose would be of any help. :?

  • Stefan H.

    Stefan H. - 2013-04-10

    I guess you are right. The maintenance burden should be low after it has been set up.

    I'm not sure we really need to separate 1 and 2. It's not like someone forces you to use the accessors if you don't want to.

    What I would suggest is basically a basic C library with getter/setter functionality and direct access to the LM structure which all plugins share. This would be the most compatible form for foreign languages. There would be no dependencies but the ones needed to open the shared memory structure.

    On top of that a further abstracted C++ interface that might offer such features like auto ticking (that uses boost::thread atm. in my python thingy) and more convenient datatypes can be implemented.

    Language bindings could then choose which one of these to use. For Python I'd use boost::python with the C++ one as Python (at least until 3.whatever) wants a special binary for every version anyways so the unstable C++ ABI isn't an issue.

    Not sure what you mean with separate plugin.

  • Zack Sawyer

    Zack Sawyer - 2013-04-11

    Agreed. 1 and 2 can be combined. I'd like to produce multiple of those C++ interfaces though, since it might get bloaty if we want to keep adding datatypes and it would only be one.

    Data flow and separation could look like this:

    link.dll <-> baseApi.dll <- boost.dll
                             <- string.dll
                             <- ???.dll

    I am not sure about the separate plugin either. I guess I was thinking that by using the link plugin we will end up with a data flow like this:

    Mumble <-> link.dll <-> api.dll <- JNA/Python

    The separate plugin could shorten this to:

    Mumble <-> apiPlugin.dll <- JNA/Python

    Just a rough thought though.
    [note that I was using dll only as reference/example we would of course aim at supporting multiple platforms.]

    Edit: alright... its a bad idea since developers would have to find that apiPlugin.dll which is problematic as mentioned earlier.

    I'd apprechiate if you'd hit me up on irc (zsawyer) if you want to chat directly about how you'd like to do this.

    Edit: Good news is I successfully got that mumble-LinkAPI to work with the Minecraft mod - still only using the updateData() though... yet.

    Last edit: Zack Sawyer 2013-04-11
  • Stefan H.

    Stefan H. - 2013-04-11

    I was thinking:
    1) C-API module:
    mumble_link.cpp/h -> mumble_link.so/dll/lib/h
    2) CPP-API module (uses C-API):
    mumble_link_ext.cpp/h -> mumble_link_ext.so/dll/lib/h
    3) e.g. Python module (uses CPP-API):
    python_mumble_link.cpp -> mumble_link.pyd/so

    For the shared libraries all dependencies (for 2 this includes 1) would be baked right in. That way 2 doesn't have external dependencies on boost or 1. Plain old C++ at the interface. Ofc. for something like the python module I wouldn't want to have to ship additional shared libraries so I'd again bake everything in (which would require boost at that point but that's imho acceptable).

    In general: The fewer files/dependencies one has to ship the better.

    Seems like you aren't idling in IRC. Maybe we can get some proper overlap on the weekend. I'm in the CEST timezone.

  • Zack Sawyer

    Zack Sawyer - 2013-04-12

    Alright, I think we pretty much have the same idea. I do not really like the naming "mumble_link". Maybe there is a better wording for it.

    I hope you don't mind me pinging you on IRC once in a while, I am very irregularly online - your status seems to always be "Away: not here ..." - not sure how up-to-date you are keeping that.

  • Stefan H.

    Stefan H. - 2013-04-12

    My status should be kept up to date by my client afaik. I'm usually around in the evenings (more on weekends) in CEST. I'll see stuff directed at me in any case but you might already be gone by the time I'm there to read it an answer ;) Simply try it.

  • Zack Sawyer

    Zack Sawyer - 2013-07-13

    Alright, I have stripped down stuff and made the source of mumble-LinkAPI C89 compatible.

    So there we have step one, I believe...

    1) C-API module:
    mumble_link.cpp/h -> mumble_link.so/dll/lib/h

    The Java-JNA-Interface is working with the pure C, already.

    Next up would be CPP + auto ticking, I'd say. :)


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.

No, thanks