23 May '13 - 04:07 *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]
  Reply  |  Print  
Author Topic: Getting BASS decoding plugins to work with Mono on Linux/Mac OS X  (Read 1392 times)
iancast
Posts: 27


« on: 9 Mar '12 - 02:24 »
Reply with quoteQuote

Hello,

I have managed to get BASS working on Linux and Mac OS using Mono. However, as soon as I try loading the FX plugin, I get a linking error:

Stacktrace:

  at MainWindow.OnButton1Clicked (object,System.EventArgs) <0x0003f>
  at (wrapper runtime-invoke) <Module>.runtime_invoke_void__this___object_object (object,intptr,intptr,intptr) <0xffffffff>
  at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) <0xffffffff>
  at System.Reflection.MonoMethod.Invoke (object,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo) <0x0018b>
  at System.Reflection.MethodBase.Invoke (object,object[]) <0x0002a>
  at System.Delegate.DynamicInvokeImpl (object[]) <0x001a3>
  at System.MulticastDelegate.DynamicInvokeImpl (object[]) <0x0003b>
  at System.Delegate.DynamicInvoke (object[]) <0x00018>
  at GLib.Signal.ClosureInvokedCB (object,GLib.ClosureInvokedArgs) <0x0014f>
  at GLib.SignalClosure.Invoke (GLib.ClosureInvokedArgs) <0x0002f>
  at GLib.SignalClosure.MarshalCallback (intptr,intptr,uint,intptr,intptr,intptr) <0x00297>
  at (wrapper native-to-managed) GLib.SignalClosure.MarshalCallback (intptr,intptr,uint,intptr,intptr,intptr) <0xffffffff>
  at (wrapper managed-to-native) Gtk.Application.gtk_main () <0xffffffff>
  at Gtk.Application.Run () <0x0000b>
  at TestBass.MainClass.Main (string[]) <0x0003f>
  at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <0xffffffff>

Native stacktrace:

   mono() [0x4901eb]
   mono() [0x4e4a5f]
   mono() [0x417249]
   /lib/x86_64-linux-gnu/libpthread.so.0(+0x10060) [0x7f88db2c8060]
   /home/animal/Projects/TestBass/TestBass/bin/Debug/libbass_fx.so(+0xeeb7) [0x7f88cf36deb7]
   /home/animal/Projects/TestBass/TestBass/bin/Debug/libbass_fx.so(+0x35b2) [0x7f88cf3625b2]

Here is my Bass.Net.dll.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
   <dllmap dll="bass.dll" target="libbass.so"/>
   <dllmap dll="bass_fx.dll" target="libbass_fx.so"/>
</configuration>

I am loading the plugin this way, as I've read it was the way to load plugins using Mono:

int version = BassFx.BASS_FX_GetVersion();

I am using Ubuntu 11.10 x64. I made sure I'm using the 64-bit .so files. They are in the same directory than the Mono executable files.

I must not be far from the solution! Can anyone with some Mono experience help me out? Thanks for any help!

P.S.: Got another quick question for radio42: The FX plugin can be loaded with GetVersion, but the file format plugins (such as MPC, ALAC, etc.) do not have GetVersion methods. How should I load these plugins under Mono?
« Last Edit: 17 Mar '12 - 02:29 by iancast » Logged
Ian @ un4seen
Administrator
Posts: 15269


« Reply #1 on: 9 Mar '12 - 15:15 »
Reply with quoteQuote

From the native stacktrace there, it looks like it was at least able to find and load the BASS_FX library. Just a guess, but perhaps the problem is that the BASS library isn't loaded yet. Have you made a BASS function call before you make the BASS_FX_GetVersion call? If not, you could try that and see if it makes a difference (it should at least ensure that the BASS library is loaded).

Regarding loading add-ons that provide support for additional file formats, you would generally use BASS_PluginLoad to load them. Is that not finding them?
Logged
iancast
Posts: 27


« Reply #2 on: 10 Mar '12 - 16:42 »
Reply with quoteQuote

From the native stacktrace there, it looks like it was at least able to find and load the BASS_FX library. Just a guess, but perhaps the problem is that the BASS library isn't loaded yet. Have you made a BASS function call before you make the BASS_FX_GetVersion call? If not, you could try that and see if it makes a difference (it should at least ensure that the BASS library is loaded).

Regarding loading add-ons that provide support for additional file formats, you would generally use BASS_PluginLoad to load them. Is that not finding them?

Thanks Ian, that was the solution. I was really scratching my head because I was using the original code under Windows and it was working fine, so I wasn't searching in the right place. Indeed, I have to get the version of the main BASS library before being able to successfully get the version of the FX and MIX library.

My last question wasn't very precise, sorry for that. I'm trying to load plugins such as the FLAC plugin through Mono with the Bass.BASS_PluginLoad(pluginFilePath) method but I keep getting the BASS_ERROR_FILEOPEN error. I'm using the x64 plugin versions. Here is the stack trace:

Exception in Gtk# callback delegate
  Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> MPfm.Sound.BassNetWrapper.BassNetWrapperException: An error has occured in Bass.Net: BASS_ERROR_FILEOPEN
  at MPfm.Sound.BassNetWrapper.Base.CheckForError () [0x00000] in <filename unknown>:0
  at MPfm.Sound.BassNetWrapper.Base.LoadPlugin (System.String pluginFilePath) [0x00000] in <filename unknown>:0
  at MPfm.Player.Player.Initialize (MPfm.Sound.BassNetWrapper.Device device, Int32 mixerSampleRate, Int32 bufferSize, Int32 updatePeriod, Boolean initializeDevice) [0x00000] in <filename unknown>:0
  at MPfm.Player.Player..ctor (MPfm.Sound.BassNetWrapper.Device device, Int32 mixerSampleRate, Int32 bufferSize, Int32 updatePeriod, Boolean initializeDevice) [0x00000] in <filename unknown>:0
  at MainWindow.OnButton6Clicked (System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0
  --- End of inner exception stack trace ---
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0
  at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x00000] in <filename unknown>:0
  at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x00000] in <filename unknown>:0
  at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] in <filename unknown>:0
  at GLib.Signal.ClosureInvokedCB (System.Object o, GLib.ClosureInvokedArgs args) [0x00000] in <filename unknown>:0
  at GLib.SignalClosure.Invoke (GLib.ClosureInvokedArgs args) [0x00000] in <filename unknown>:0
  at GLib.SignalClosure.MarshalCallback (IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data) [0x00000] in <filename unknown>:0
   at GLib.ExceptionManager.RaiseUnhandledException(System.Exception e, Boolean is_terminal)
   at GLib.SignalClosure.MarshalCallback(IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data)
   at Gtk.Application.gtk_main()
   at Gtk.Application.Run()
   at MPfm.MainClass.Main(System.String[] args)

The plugin files are inside the executable directory. They are in the same directory than the BASS FX and Mix libraries which are now loading fine, so they should be found in that directory. I tried using the full path and it gives the same error. I tried loading "libbassflac.so" and I also tried loading "bassflac.dll" with a Mono dllmap pointing to "libbassflac.so" but it still doesn't work. :-(

UPDATE: I have the same problem on Mac OS X and have tried the same solutions (loading the .dylib directly, making a dllmap, etc.). I am able to load the Mix and FX plugins though.

Thanks for your help, it is really appreciated.
« Last Edit: 11 Mar '12 - 23:21 by iancast » Logged
Ian @ un4seen
Administrator
Posts: 15269


« Reply #3 on: 12 Mar '12 - 17:04 »
Reply with quoteQuote

I seem to recall another Mono user reporting this problem in the past, and it was related to the executable directory being Mono's directory rather than your app's. I don't recall now what/if the solution was, but if all else fails, I guess you can do the same thing as with BASSmix and BASS_FX, ie. call a function from the add-on to get Mono to load it...

BassFlac.BASS_FLAC_StreamCreateFile("",0,0,0);

BASS_PluginLoad should then be able to successfully load it as it will already be in memory.
Logged
iancast
Posts: 27


« Reply #4 on: 17 Mar '12 - 02:24 »
Reply with quoteQuote

I seem to recall another Mono user reporting this problem in the past, and it was related to the executable directory being Mono's directory rather than your app's. I don't recall now what/if the solution was, but if all else fails, I guess you can do the same thing as with BASSmix and BASS_FX, ie. call a function from the add-on to get Mono to load it...

BassFlac.BASS_FLAC_StreamCreateFile("",0,0,0);

BASS_PluginLoad should then be able to successfully load it as it will already be in memory.

Sorry for the delay. I checked the executable directory at runtime and it's my /bin/Debug folder which contains the libbassflac.so file. I also tried copying it to /usr/lib and it still doesn't work.

I also tried your other solution (StreamCreateFile) but that also doesn't seem to work, as I get the BASS_ERROR_FILEOPEN error from the BassFlac.BASS_FLAC_StreamCreateFile (even if I try to load an actual FLAC file). I get the same error when trying to load the plugin afterwards.

I'm not sure what to do next, a C++ prototype to check if I can successfully load the FLAC plugin outside Mono on the same platform, but that won't help me make it work inside Mono.

Why do the FX/Mix plugin load by requesting the version and not the other plugins? Do you have a debug version I could use to maybe get a more precise error than just FILEOPEN?

Anyway, are there any other Mono (Linux or Mac OS X) users out there using plugins successfully? If anyone can help me, I would be really grateful. Thanks.
« Last Edit: 17 Mar '12 - 02:26 by iancast » Logged
iancast
Posts: 27


« Reply #5 on: 28 Mar '12 - 04:17 »
Reply with quoteQuote

Hello,

I have made some progress on this issue. I tried doing a minimal console application which plays a FLAC file in C++ and in Mono.

Here is my source code to replicate the issue:

C++:

    DWORD version = BASS_GetVersion();

    // initialize default output device
    bool init = BASS_Init(-1,44100,0,NULL,NULL);
    if (!init) {       
        int errorCode = BASS_ErrorGetCode();
        return 0;
    }

    char pluginFilePath[] = "/usr/lib/bass/libbassflac.so";
    HPLUGIN pluginHandle = BASS_PluginLoad(pluginFilePath, 0);
    if(pluginHandle == 0)
    {
        int errorCode = BASS_ErrorGetCode();
    }

    char audioFilePath[] = "/media/Data1/Flac/test.flac";
    HSTREAM streamHandle = BASS_StreamCreateFile(false, audioFilePath, 0, 0, 0);
    if(streamHandle == 0)
    {
        int errorCode = BASS_ErrorGetCode();
    }

    bool playSuccess = BASS_ChannelPlay(streamHandle, false);

C# (Mono):

         int version = Bass.BASS_GetVersion ();
         bool init = Bass.BASS_Init (-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);
         
         //string pluginFilePath = "/usr/lib/bass/libbassflac.so";
         string pluginFilePath = "libbassflac.so";
         int pluginHandle = Bass.BASS_PluginLoad(pluginFilePath);
         if(pluginHandle == 0)
         {
            string error = Bass.BASS_ErrorGetCode ().ToString ();
            Console.WriteLine ("Error: " + error);
            return;
         }
         
         string audioFilePath = "/media/Data1/Flac/test.flac";
         int streamHandle = Bass.BASS_StreamCreateFile (audioFilePath, 0, 0, BASSFlag.BASS_DEFAULT);
         if(streamHandle == 0)
         {
            string error = Bass.BASS_ErrorGetCode ().ToString ();
            Console.WriteLine ("Error: " + error);
            return;
         }         
         
         bool playSuccess = Bass.BASS_ChannelPlay (streamHandle, false);


I tried these two mini console applications in multiple Linux distributions in x86 and x64 (Ubuntu, Fedora, OpenSUSE, Mint). I could not load the FLAC plugin under C#/Mono in any configuration (I made sure to use the x64 .so files under x64). I keep getting the BASS_ERROR_FILEOPEN error.

However, loading the FLAC plugin with the same code in C++ works in any of these platforms. Therefore the problem seems to be with Mono.

What's strange is that if I run the C# code with Mono under Windows, and I use "bassflac.dll" instead of "libbassflac.so", it loads the FLAC plugin successfully.

I also tried loading bassflac.dll under Linux with a DllConfig but it doesn't seem to work.

I'm really out of solutions! Did anyone on this forum manage to load BASS plugins other than FX and MIX successfully under Mono before? Can anyone share the solution? I'd be really grateful.

Thanks!
Logged
iancast
Posts: 27


« Reply #6 on: 30 Mar '12 - 02:11 »
Reply with quoteQuote

Hello,

I got the FLAC plugin to load successfully on Mac OS X using Mono by copying to file to the home folder and using an absolute path (ex: /Users/username/Projects/TestFlac/libbassflac.dylib).

I tried doing the same on Linux, however the BASS_ERROR_FILEOPEN error still remains...
Logged
Ian @ un4seen
Administrator
Posts: 15269


« Reply #7 on: 30 Mar '12 - 15:33 »
Reply with quoteQuote

So long as you provide the full path in the BASS_PluginLoad call, I think the add-on should be found and loaded. For example, if the BASS libraries are in the same directory as your EXE, something like this ought to work...

string exepath=System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // get EXE path
int bassflac=Bass.BASS_PluginLoad(exepath+"/libbassflac.dylib"); // load BASSFLAC from there

If that isn't working, I can send you a debug version to get some clues on what's going wrong.
Logged
iancast
Posts: 27


« Reply #8 on: 31 Mar '12 - 15:26 »
Reply with quoteQuote

So long as you provide the full path in the BASS_PluginLoad call, I think the add-on should be found and loaded. For example, if the BASS libraries are in the same directory as your EXE, something like this ought to work...

string exepath=System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // get EXE path
int bassflac=Bass.BASS_PluginLoad(exepath+"/libbassflac.dylib"); // load BASSFLAC from there

If that isn't working, I can send you a debug version to get some clues on what's going wrong.

Hi Ian,

Unfortunately, I tried that a while ago and it returned the same path that I used. I tried it again just to make sure, on Mint x64 and Mint x86, and I still get the BASS_ERROR_FILEOPEN.  Cry

Since this only seems to affect BASS.NET + Mono + Linux, I'm really scratching my head to guess what the problem is. Maybe nobody has tried this before? Linux users/developers are usually hostile to third-party libraries like BASS (and Mono!).

I'm not sure if the debug version would help, since the same code under C++ works (I used QtCreator and Eclipse CDT if that helps). But since I'm really stuck, I'd be glad to try the debug version of BASS.

By the way, I have to admit I'm still a bit new to the Linux and Mac OS X platforms. I don't own a Mac yet, so I don't get to test my code very often.

On the bright side, my player code works just as well on Linux (only MP3/OGG files for now) and Mac OS X than on Windows. It is using the FX and MIX BASS libraries, with time shifting, 18-band EQ, SYNCPROCs for looping, etc. So if I get around to finally fix this plugin problem, this should be it Smiley It is really awesome that the BASS library works flawlessly on those platforms with 99% of the same code.

By the way, I have gone through this Mono article, maybe it would help: http://www.mono-project.com/Interop_with_Native_Libraries

Thanks for your help!

Yanick Castonguay
MPfm: Music Player for Musicians developer
http://www.mp4m.org
« Last Edit: 31 Mar '12 - 15:50 by iancast » Logged
Ian @ un4seen
Administrator
Posts: 15269


« Reply #9 on: 2 Apr '12 - 16:57 »
Reply with quoteQuote

Ah! I see what the problem is now: the BASS_UNICODE flag isn't actually supported in the Linux version of BASS_PluginLoad. Here's an update to fix that...

   www.un4seen.com/stuff/libbass.so.zip

Let me know if you still have any trouble with that, or on OSX (the BASS_UNICODE flag should be working there).
Logged
iancast
Posts: 27


« Reply #10 on: 2 Apr '12 - 23:43 »
Reply with quoteQuote

Ah! I see what the problem is now: the BASS_UNICODE flag isn't actually supported in the Linux version of BASS_PluginLoad. Here's an update to fix that...

   www.un4seen.com/stuff/libbass.so.zip

Let me know if you still have any trouble with that, or on OSX (the BASS_UNICODE flag should be working there).

Great news! The updated libbass.so you provided now loads the FLAC plugin under Linux! Haven't tested it yet under x86, but on Ubuntu 11.10 x64 it works fine.

The libbass.dylib file from the front page download package was OK. Like I said in the previous post, I got it working under Mac OS X by using an absolute path.

One last question: is this BASS_UNICODE fix only for Mono? i.e. if I download a forthcoming BASS update on Linux, will this fix be in there or shall I ask for a new "special" version?

Thanks!
Yanick
Logged
Ian @ un4seen
Administrator
Posts: 15269


« Reply #11 on: 3 Apr '12 - 14:12 »
Reply with quoteQuote

The BASS_UNICODE flag isn't only for use with Mono, but that is its main purpose on non-Windows platforms. Linux and OSX use UTF-8 filenames by default, so there is generally no need for a UTF-16 option, but .Net does use UTF-16 strings and so BASS.Net uses the BASS_UNICODE flag when passing filenames to BASS.

So the BASS_UNICODE fix will be included in the next Linux release, which should be fairly soon (this month). You can continue to use the update above in the meantime.
Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines