Jump to content
  • Advertisement
Sign in to follow this  

OGG in .NET

This topic is 3714 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm currently working on an OpenAL-based sound system under C#, that should be able to load OGG Vorbis from a PhysFS filesystem. Therefore I can't use ov_fopen() from the vorbisfile.dll but are forced to use ov_open_callbacks(), which is quite a pain to wrap with C#. What I've got thus far is: The ov_open_callbacks() function in the dll looks like this (c):
int ov_open_callbacks(void *datasource, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks);

and i've wrapped it like this (c#):
[DllImport("vorbisfile.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int ov_open_callbacks(ref FsFile datasource,
                                                   out IntPtr vf,
                                                   [MarshalAs(UnmanagedType.LPArray)]byte[] initial,
                                                   long ibytes,
                                                   oggvorbis_callbacks callbacks);

The callback functions are passed as function pointers inside the oggvorbis_callbacks struct. That seems to work, as my callbacks are called by the dll to read from the file. This is where my trouble starts. The C function expects an (void*) pointer pointing to an already opened file (datasource). I'm using an FsFile instance, where FsFile is my representation of a file in the filesystem. The callback to read from this file (called by the dll) should be a function pointer (c):
size_t (*read_func)  (void *ptr, size_t size, size_t nmemb, void *datasource);

This is my C#-Callback implementation:
public ulong cbRead(IntPtr ptr, ulong size, ulong nmemb, ref FsFile datasource)

When the program enters this callback, my FsFile datasource is always null. I tried to accomplish it with IntPtr (which seems to be the proper way to wrap a (void *) ), but the IntPtr datasource I get as an argument in cbRead is completely different to that I've passed to ov_open_callbacks(). I suppose there may be something wrong with my calling conventions. vorbisfile.dll expects the callbacks to be __cdecl. I've declared my delegates to be cdecl function pointers:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate ulong ogg_read_func(IntPtr ptr, ulong size, ulong nmemb, ref FsFile datasource);

I'm totally lost, so if anyone of you has an idea or experience using OGG I'd really appreciate your help. Cheers, Marvin

Share this post


Link to post
Share on other sites
Advertisement
omfg just figured it out...
The documentation for the callback function was wrong:

Instead of

size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource);



it should be:

size_t (*read_func) (void *datasource, size_t size, size_t nmemb, void *ptr);



Maybe this will help people who are experiencing a similar problem.

Cheers,
Marvin

Share this post


Link to post
Share on other sites
OK I have to apologize to the Ogg Vorbis developers for blaming their documentation for my mistakes. In fact, their documentation was correct.

I screwed up by marshalling c long (32 bits) with c# long (64 bits) and c int (16 bits) with c# int (32 bits).

Now everything works perfectly.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!