0

i'm using fmodex and i'm trying to use FMOD_FILE_OPEN_CALLBACK under C++.

FMOD_RESULT F_CALLBACK FMOD_FILE_OPEN_CALLBACK(const char *name, unsigned int *filesize, void **handle, void *userdata);

But I would like to execute a method of a class. So I thought to pass current object this as userdata of the callback and execute my callback method as it's proposed here. But unlike Fmod Studio, there is no fileuserdata in FMOD_CREATESOUNDEXINFO, only userdata pointer.

And documentation says :

[w] Optional. Specify 0 to ignore. This is user data to be attached to the sound during creation. Access via Sound::getUserData. Note: This is not passed to FMOD_FILE_OPENCALLBACK, that is a different userdata that is file specific.

But how can I access this file specific pointer ? Or there is an other solution to do that ?

Thanks.

Community
  • 1
  • 1
Maluna34
  • 245
  • 1
  • 16

2 Answers2

1

was this solved yet? If not here's how i do it.

FMOD_CREATESOUNDEXINFO* info = new FMOD_CREATESOUNDEXINFO();
info->cbsize = sizeof(FMOD_CREATESOUNDEXINFO);

// This is the field you want to set
info->fileuserdata = someUserData;

_system->createStream(file.c_str(), FMOD_DEFAULT, info, &_currentSound);

Are you using an old version of the fmod library? On my system the fileuserdata field does exist. I'm using the fmodex low level api that shipped with the fmod studio installation.

Jop
  • 11
  • 1
  • Thanks for your help but i'm using the old fmodex api and fileuserdata doesn't exist. Is there many different with fmod studio low level ? – Maluna34 Aug 15 '15 at 12:48
  • I suggest you to just try it out. It's been at least 4 years since i used the old version of fmod so i'm not really sure on what changed. But i guess most of the stuff stayed the same for the low level api. – Jop Aug 19 '15 at 21:30
  • Thanks ! I plan to change with fmod studio. ;) – Maluna34 Aug 20 '15 at 07:58
0

When the API in question does not provide a user data pointer for the callback, but does provide some kind of handle, as seems to be the case here, then you can forward each callback call to a C++ method (a non-static member function) in two general ways + 1 API-specific way:

  • use API functionality to associate a C++ object pointer with each handle, or

  • use a static storage std::map or std::unordered_map that associates each handle with a C++ object pointer, or

  • use a dynamically created trampoline function with the object address hardwired.

The third option was used e.g. in Borland's ObjectWindows framework in the 1990's, and it's generally the fastest, but it conflicts with current malware protection schemes, and since the C++ standard library doesn't support it (and as far as I know Boost doesn't support it either, although The Good Puppy over in the C++ Lounge here at SO once made a proposal about it), it's necessarily platform specific machine code.

Thus, if you don't know a way to do the first option I suggest you go with the second, a std::map or std::unordered_map that associates handles with C++ objects.

The main remaining technical hurdle is then to decide the proper time to create a map entry, and the proper time to remove it. That is highly dependent on the callback scheme. And unfortunately I have zero experience with yours, but maybe others can chime in about that detail.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Thank you. But the handle has to be given in the open callback. And i would like to already have my object in the opencallback. So, give my object before to obtain it in the open callback. – Maluna34 Jun 22 '15 at 17:01