# Programmer Sound Help

**URL:** <https://qa.fmod.com/t/programmer-sound-help/13192>\
**Category:** FMOD Studio\
**Created:** [May 20, 2017, 6:33pm UTC](https://qa.fmod.com/t/programmer-sound-help/13192 "2017-05-20T18:33:24Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![KarateKidzz](https://avatars.discourse-cdn.com/v4/letter/k/c37758/32.png) [@KarateKidzz](https://qa.fmod.com/u/KarateKidzz)\
**Post date:** [May 20, 2017, 6:33pm UTC](https://qa.fmod.com/t/programmer-sound-help/13192/1 "2017-05-20T18:33:24Z")

</div>

Hi,

I’m trying to implement some programmer sounds into my work but can’t seem to get the code working.

I’m using [http://www.fmod.org/documentation/#content/generated/engine\_new\_unity/script\_example\_programmersounds.html](http://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.

Kind regards,  
James

---

<div class="post-metadata">

**Author:** ![richard\_simms](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/richard_simms/32/261_2.png) [@richard\_simms](https://qa.fmod.com/u/richard_simms)\
**Post date:** [May 23, 2017, 4:05am UTC](https://qa.fmod.com/t/programmer-sound-help/13192/2 "2017-05-23T04:05:30Z")

</div>

Hello James,

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.

When `PlayDialogue` calls `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 `PlayDialogue`.

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.

Thanks,  
Richard

---

<div class="post-metadata">

**Author:** ![KarateKidzz](https://avatars.discourse-cdn.com/v4/letter/k/c37758/32.png) [@KarateKidzz](https://qa.fmod.com/u/KarateKidzz)\
**Post date:** [May 23, 2017, 7:34pm UTC](https://qa.fmod.com/t/programmer-sound-help/13192/3 "2017-05-23T19:34:12Z")

</div>

> [@](#):
>
> Hello James,
> 
> 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.
> 
> When `PlayDialogue` calls `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 `PlayDialogue`.
> 
> 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.
> 
> Thanks,  
> Richard

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,  
James

---

<div class="post-metadata">

**Author:** ![kauelemos](https://avatars.discourse-cdn.com/v4/letter/k/bcef8e/32.png) [@kauelemos](https://qa.fmod.com/u/kauelemos)\
**Post date:** [August 21, 2017, 7:49pm UTC](https://qa.fmod.com/t/programmer-sound-help/13192/4 "2017-08-21T19:49:39Z")

</div>

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.

[https://www.fmod.org/docs/content/generated/engine\_ue4/programmer\_sounds.html](https://www.fmod.org/docs/content/generated/engine_ue4/programmer_sounds.html)

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.

---

<div class="post-metadata">

**Author:** ![richard\_simms](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/richard_simms/32/261_2.png) [@richard\_simms](https://qa.fmod.com/u/richard_simms)\
**Post date:** [August 22, 2017, 2:33am UTC](https://qa.fmod.com/t/programmer-sound-help/13192/5 "2017-08-22T02:33:52Z")

</div>

Hello Kauê,

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.

Thanks,  
Richard

---

<div class="post-metadata">

**Author:** ![richard\_simms](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/richard_simms/32/261_2.png) [@richard\_simms](https://qa.fmod.com/u/richard_simms)\
**Post date:** [August 22, 2017, 6:09am UTC](https://qa.fmod.com/t/programmer-sound-help/13192/6 "2017-08-22T06:09:33Z")

</div>

Hello Kauê,

I should add that you are able to get the name of the programmer sound module from the FMOD\_STUDIO\_PROGRAMMER\_SOUND\_PROPERTIES callback.

[https://www.fmod.org/docs/content/generated/FMOD\_STUDIO\_PROGRAMMER\_SOUND\_PROPERTIES.html](https://www.fmod.org/docs/content/generated/FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES.html)

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.

Thanks,  
Richard
