I’m trying to implement some programmer sounds into my work but can’t seem to get the code working.
I’m using https://www.fmod.org/documentation/#content/generated/engine_new_unity/script_example_programmersounds.html as my base but am not sure this is the exact answer to getting this to work.
For example, I can’t see anywhere for the code to know what Audio Table I want to point to; it only has the Key for the specific bit of audio. Is there something I have to add to the event so, when the code looks for the user data, it knows which table to look at? I’ve tried adding the full path ‘bank:/Master Bank/Audio Table/Key’ to see if that works but I’m pretty sure I’m just pulling at straws.
Also, I am a little unsure how the DialogueEventCallback knows which event to look at as it is using IntPtr instancePtr for the name of the event instance to create. However, that isn’t a path to an event. I’m guessing it’s taking the event path in the PlayDialogue method, with dialogueInstance.setCallback, but that’s a set, rather than a get, so I’m guessing that it’s not giving data to the callback.
The last thing I’m on unsure on is that the DialogueEventCallback method doesn’t seem to have a return. I’d imagine that the dialogueInstance.setCallback needs some value to effect our event, but if it doesn’t then the .setUserData must be the important part? If so, how does the key being stored in memory help us change the audio in the programmer sound?
Anyway, I thank you in advance. For most bits of code, I can understand it but this just isn’t clicking for me.
- You must login to post comments
When you load an FMOD Studio bank that has an audio table attached to it, the keys in that audio table are front loaded into your game. There is no need to point to the audio table itself as this is done automatically.
It’s important to have each key be unique if you are loading multiple banks that have audio tables. If there are any keys that are duplicates across audio tables, the most recently loaded bank will take priority.
To understand how
DialogueEventCallback works it’s important to realise that the
FMOD.Studio.EventInstance objects created in C# are actually wrappers for unamanged objects created by the FMOD studio runtime library. The unmanaged objects do all the work and the C# wrappers store links to the unmanaged objects and allow C# code to perform operations on the unamanged objects.
FMODUnity.RuntimeManager.CreateInstance a new unmanaged event instance is created by the FMOD studio runtime library and a wrapper for that unmanaged object is returned and stored in
dialogueInstance. The remainder of the
PlayDialogue function performs a number of operations on the event instance. The wrapper is used to store the audio table key which was passed to
PlayDialogue in the event instance’s user data, and uses the
setCallback method to tell the FMOD studio runtime library which function to call to handle callbacks for the event instance. Because the audio table key string needs to be kept until the event instance is finished with it we have to pin the memory for the string in
PlayDialogue. When the
PlayDialogue function returns the
dialogueInstance wrapper goes out of scope and can be cleaned up, but the unmanaged event instance sticks around (it will be cleaned up later on by the FMOD studio runtime library, after the event has finished playing).
Later on, the callback is invoked by the FMOD studio runtime library when it needs to create the programmer sound for the event. The
instancePtr parameter is a link to the same unmanaged event instance which was created by
PlayDialogue. The callback can’t do anything directly with the unmanaged event instance so it creates a new C# wrapper for it. It’s important to understand that this is just a new wrapper, and not a new event instance, so when the callback retrieves the user data from the event instance it will get the audio table key which was stored there in
When the callback is called to process the
CREATE_PROGRAMMER_SOUND event the extra
parameterPtr parameter is used to pass a link to an
FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES structure. The callback has to create an unmanaged FMOD sound for the event to play and store it in the structure. This is done in the example by using the audio table key retrieved from the event instance’s user data to lookup the information needed to create the correct sound using
FMODUnity.RuntimeManager.LowlevelSystem.createSound. The output FMOD.Sound from
FMODUnity.RuntimeManager.LowlevelSystem.createSound is actually a C# wrapper for the unmanaged FMOD sound and we use
dialogueSound.getRaw() to retrieve a link to the unmanaged FMOD sound which needs to be returned in the
PROGRAMMER_SOUND_PROPERTIES structure. This is the important / interesting output of the callback in this case.
The callback will be called again to cleanup the programmer sound when the event is finished with it. In this case the
instancePtr parameter is once again a link to the unmanaged event instance and
parameterPtr is a link to an
FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES structure which contains a link to an unmanaged FMOD sound which the callback needs to clean up. The callback creates a new C# wrapper for the lowlevel sound and calls release on the wrapper to clean it up.
The callback is called one last time when the event is destroyed. This is the right time to unpin the string memory containing the audio table key which was originally passed to
PlayDialogue so that it can be cleaned up by the garbage collector.
I hope this has cleared up how to use programmer sounds.
Thank you so much, Richard! That was a great explanation and I think I understand it now.
Also, I have got my code working! The fault was in the line ‘parameter.subsoundIndex = dialogueSoundInfo.subsoundindex’. For some reason, it thought the line was misspelt and all it took was to type the line in again. I really wish I did that at the beginning but at least I now have a better understanding of how the code works!
Again, thank you,
That was a superb walkthrough! I still have one doubt. Is it possible to have the key used to create the sond come from FMOD?
This tutorial for Unreal says you can use the “Programmer Sound Name”, but it’s not working for me, maybe it’s something specific inside the Unreal audio component.
Also, the documentation makes me believe it’s possible to use multi-sounds, probably randomizing the key, with programmer sounds. But I can’t put it to work either.
Lastly, somewhere in the docs it is said that if you leave the subsoundindex aside (value should default to -1) then it would simply work and play whatever comes with the event or something.
I’m glad you found that walkthrough helpful.
The key used in programmer sounds from audio tables are basically alias’ pointing to the actual sound file itself so there isn’t really a way for FMOD to decide which key to use. You need to provide the key in order for FMOD to playback the sound you need.
The Programmer Sound Name is either a key from your audio table or the path to your sound file.
If using the files path, in Unreal Engine 4 this file needs to be within the actual project’s folder (eg. “MyUE4Project\Content\sound_files\gunshot.wav”). The path will then become the file name in relation to the project’s root folder (eg. “sound_files\gunshot.wav”).
Please note two things:
1. Dragging and dropping the sound files into the Unreal Editor will not work. It needs to be placed into the actual folder structure via Explorer or Finder.
2. You cannot audition the programmer sound in the Details tab. You can only hear this through the Play in editor.
You can add programmer sounds to a multi sound by right clicking in the playlist and choosing to add Programmer Sound, however you cannot specify the individual programmer sounds through the Editor’s UI. This will need to be scripted. Again, you will need to provide the key for these sounds, but you can script randomization of these.
The subsoundIndex property is used for choosing sound files within containers such as an FSB. If you are not loading an FSB file then don’t worry about this. It will default to -1 and play whatever you passed into the “sound” argument.
I hope this has helped.
I should add that you are able to get the name of the programmer sound module from the FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES callback.
The same applies to programmer sounds in multi-sound modules. Using the “name” return will give you the name of the programmer sound set in the FMOD Studio project.
- You must login to post comments
Please login first to submit.