Been a while since I last posted (been busy implementing other aspects of my application). My questions are:
1) Is it better to read a whole MP3 into a buffer, and use FSOUND_LOADMEMORY, or is it better to simply pass in a file name to the FSOUND_Stream_Open call? Which is more memory efficient, or does it actually make no difference
2) Has anyone who has implemented a .NET wrapper for .NETCF, managed to create a method where by the .NET application is alerted to the end of a stream play? I have the internal callback working, however I do not know how to go about alerting the .net app. If anyone has any advice on this, I would be greatful.
- DGlover asked 15 years ago
You call FMOD from .Net the same way you are calling your wrapper DLL. For example:
public static extern bool FSOUND_Init(
int mixrate, int maxsoftwarechannels, uint flags );
I’m using it to record sound in a loop, and get the continuous FFT. This involves alocating memory in FMOD and passing pointers arount. The FFT comes back as a pointer to an array of 512 floats. It is a little tricky to convert that to .Net floats, but not too bad.
It works great, except I haven’t been able to get callbacks to work. I don’t need them right now, but I probably will someday.
It would be nice to have an overall .Net wrapper for FMOD. It wouldn’t be technically challenging to write, but it would be tedious. I would do it, but I am too lazy. 😛
Your right – it would be very tedious!
For some reason when I started the prelim work for this project way back in June of last year, I could not get the import of the fmodce dll working – hence I am using a EVC++ wrapper – which is a pain and a real bugger to deal with at times Oh well!
A full FMOD/FMODCE wrapper would be perfectly possible, although as you say – very tedious! I contemplated it at one point, however time constraints on the project put an end to that plan…. and I am also too lazy 😉
[quote="DGlover":oxt1y54v]No problem. This is the setup I have to inform the .NETCF app when the play back of the stream is done. The code for the Native DLL goes a little something like:[/quote:oxt1y54v]
sorry to bother you like this but i hope you can help me. this is an veeeeeeeeeery old post and i’m guessing that’s about .netcf 1.0… i’ve been reading about .netcf 2.0 and, i’m not sure but, i think that in .netcf 2.0 that type of callback which pInvoke is now suported…
well, i’m writing my wrapper in vs2005 and in the SetEndCallback line i got an NotSuportedException…
1) does realy .netcf 2.0 suports that callback
2) does the fact that i’m using vs2005 makes me sure that i’m using .netcf2, couse i got vs2003 installed as well
3) has you finished your wrapper ? i haven’t understand as well that example of yours in the forum, could you please send me more details ? like, the WndProc function for example… i have to put it in my warpper ? if so, what exactly defines in the cases the callback that i what to catch ? and how do i define (and where) that SetEndCallback call ?? or in you solution i doesn’t have to make this call ???
sorry for my english couse i’m from Brazil
- lcjohnny answered 12 years ago
Callbacks aren’t supported under .net compact framework.
You might want to look here:
Using a callback library here:
http://cvs.sourceforge.net/viewcvs.py/o … Callbacks/
I was able to compile and run it, using this code:
Callback cb = CallbackFactory.AllocateCallback(this,”DspHandler”);
IntPtr dspPtr = FSOUND_DSP_Create(cb.CB,0,0);
if (dspPtr == IntPtr.Zero)
MessageBox.Show(“Error allocating callback ptr: ” + FSOUND_GetError());
However, on the last line the app crashed, so I don’t know what the problem was.
Thanks for the help – I managed to find a (kinda ugly) way of doing it. I had to pass a Window handle to the Wrapper DLL, and then use ::SendMessage to the handle. In the .NET code I simply caught the message and fired an event. Why is nothing as easy as it should be in .NET CF?!!? 😀
That’s what the CallbackFactory does, although it didn’t work for me. The first time the callback is called, the app crashes. Can you post the relevant parts of your code? Please?
I agree it is harder than it should be. It seems a shame to supprt p/invoke without supporting callbacks.
No problem. This is the setup I have to inform the .NETCF app when the play back of the stream is done. The code for the Native DLL goes a little something like:
const int WM_CUSTOM_MESSAGE = WM_USER+0 ;
signed char F_CALLBACKAPI endcallback(FSOUND_STREAM *stream, void *buff, int len, void *param)
// end of stream callback doesnt have a ‘buff’ value, if it doesnt it could be a synch point.
//printf("\nSYNCHPOINT : \"%s\"\n", buff);
::SendMessage(hWndg, WM_CUSTOM_MESSAGE,0,0) ;
There is also a method to pass in a refrence to the DLL of the calling hWnd.
In the .NET app:
public class FMODEngine : MessageWindow
public const int WM_USER = 0x400 ;
public const int WM_CALLBACK_MESSAGE = WM_USER + 0 ;
protected override void WndProc(ref Message msg)
//process end of stream here – I fire an event which is caught by some code elsewhere
base.WndProc(ref msg) ;
That should do it, although let me know if you have any problems. This solution to the problem was derrived from the example in Chapter 22 of .NET Compact Framework from Microsoft Press.
Ah, so you are wrapping the FMOD DLL with another DLL. When you do this, do you still call the other functions in FMOD via p/invoke to the FMOD DLL? Or do you have to replicate those functions in your wrapper DLL?
In other words, are you using p/invoke to call 2 DLLs or 1?
Another thing that would be nice to wrap is the GetCPU function, since you can’t pass floats across p/invoke.
Thanks for the code.
I only have one P/Invoke as my wrapper DLL (written in eMbedded C++) calls FMOD for me – It just seemed a little easier this way, and performance is not a major consideration in my project, I am using it simply to play an MP3.
How are you / anyone else calling FMOD from .NET?
I have not tried to return a float from EVC++, however if I get a moment or two over the next couple of days I will try and look into this.
Hope this helps,
Please login first to submit.