# “\[FMOD\] ShadowEventInstance::createProgrammerSound : Programmer sound callback is not set for instrument”

**URL:** <https://qa.fmod.com/t/fmod-shadoweventinstance-createprogrammersound-programmer-sound-callback-is-not-set-for-instrument/22529>\
**Category:** Unity\
**Created:** [January 21, 2025, 5:12pm UTC](https://qa.fmod.com/t/fmod-shadoweventinstance-createprogrammersound-programmer-sound-callback-is-not-set-for-instrument/22529 "2025-01-21T17:12:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![AntvilStudios](https://avatars.discourse-cdn.com/v4/letter/a/7feea3/32.png) [@AntvilStudios](https://qa.fmod.com/u/AntvilStudios)\
**Post date:** [January 21, 2025, 5:12pm UTC](https://qa.fmod.com/t/fmod-shadoweventinstance-createprogrammersound-programmer-sound-callback-is-not-set-for-instrument/22529/1 "2025-01-21T17:12:24Z")

</div>

Hi, im getting all the time this message (“[FMOD] ShadowEventInstance::createProgrammerSound : Programmer sound callback is not set for instrument”) when trying to sound a dialogue.  
The programmer instrument is properly created. I´m using 2 localized audio tables for two languages, one of them which also returns an error (that is already loaded regardless if its language is selected).  
The code is the same as provided by the FMOD website, the only difference is that i call the method from another script.  
Any idea?

Thank you

---

<div class="post-metadata">

**Author:** ![li\_fmod](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/li_fmod/32/6577_2.png) [@li\_fmod](https://qa.fmod.com/u/li_fmod)\
**Post date:** [January 22, 2025, 12:24am UTC](https://qa.fmod.com/t/fmod-shadoweventinstance-createprogrammersound-programmer-sound-callback-is-not-set-for-instrument/22529/2 "2025-01-22T00:24:11Z")

</div>

Hi,

Thank you for sharing the information.

Could I please grab the version number of your FMOD Unity integration?

> [@AntvilStudios](#):
>
> ShadowEventInstance::createProgrammerSound : Programmer sound callback is not set for instrument”) when trying to sound a dialogue.

This warning message indicates that FMOD is expecting a `programmer sound callback` to be set, but it hasn’t been. This callback is necessary for programmer instruments, as they rely on you to provide the audio data during playback. The [programmer sound example script](https://fmod.com/docs/2.02/unity/examples-programmer-sounds.html) demonstrates how to set up a callback for programmer sounds.

> [@AntvilStudios](#):
>
> The programmer instrument is properly created. I´m using 2 localized audio tables for two languages, one of them which also returns an error (that is already loaded regardless if its language is selected).

Could you please share the exact error message? Is it the same error message as the one you mentioned above?

> [@AntvilStudios](#):
>
> The code is the same as provided by the FMOD website, the only difference is that i call the method from another script.

Unfortunately, I was not able to reproduce the issue from my side. Would it be possible to share a code snippet showing how you are calling the method from another script?

---

<div class="post-metadata">

**Author:** ![AntvilStudios](https://avatars.discourse-cdn.com/v4/letter/a/7feea3/32.png) [@AntvilStudios](https://qa.fmod.com/u/AntvilStudios)\
**Post date:** [January 22, 2025, 2:40pm UTC](https://qa.fmod.com/t/fmod-shadoweventinstance-createprogrammersound-programmer-sound-callback-is-not-set-for-instrument/22529/3 "2025-01-22T14:40:12Z")

</div>

Thank you for your fast reply,

The intengration number is : Version: 2.02.26

The error returned for a localized bank is: [FMOD] Unable to load Dialogues\_SPA - bank already loaded. This may occur when attempting to load another localized bank before the first is unloaded, or if a bank has been loaded via the API.  
UnityEngine.Debug:LogWarningFormat (string,object)

Finally, the code im using. I´ve created the main Callback code (same as FMOD website in the script SoundManager.cs) and i´m calling it from the script Dialog.cs:

SoundManager.cs

```auto
public class SoundManager : MonoBehaviour
{
    public static SoundManager Instance { get; private set; }
 
    EVENT_CALLBACK dialogueCallback;
    public FMODUnity.EventReference Dialog;
public void PlayDialog(ETranslateID ID)
   {
       //RuntimeManager.PlayOneShot("event:/Dialog/" + ID.ToString());
       //RuntimeManager.PlayOneShot("event:/Dialog/dialog_0a");
 
       var dialogueInstance = RuntimeManager.CreateInstance(FMODEvents.Instance.Dialog);//Esto está bien
      // Pin the key string in memory and pass a pointer through the user data
       GCHandle stringHandle = GCHandle.Alloc(ID.ToString());
       Debug.LogError("Esto es " + stringHandle);
       dialogueInstance.setUserData(GCHandle.ToIntPtr(stringHandle));
       dialogueInstance.setCallback(dialogueCallback);
       dialogueInstance.start();
       dialogueInstance.getPlaybackState(out PLAYBACK_STATE dialoguesState);//Se inicia con normalidad
       dialogueInstance.release();
   }
 
   [AOT.MonoPInvokeCallback(typeof(EVENT_CALLBACK))]
   static FMOD.RESULT DialogueEventCallback(EVENT_CALLBACK_TYPE type, IntPtr instancePtr, IntPtr parameterPtr)
   {
       FMOD.Studio.EventInstance instance = new EventInstance(instancePtr);
 
       // Retrieve the user data
       IntPtr stringPtr;
       instance.getUserData(out stringPtr);
 
       // Get the string object
       GCHandle stringHandle = GCHandle.FromIntPtr(stringPtr);
       String key = stringHandle.Target as String;

       switch (type)
       {
           case EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND: //Crea el sonido
               {
                   FMOD.MODE soundMode = FMOD.MODE.LOOP_NORMAL | FMOD.MODE.CREATECOMPRESSEDSAMPLE | FMOD.MODE.NONBLOCKING;
                   var parameter = (PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(PROGRAMMER_SOUND_PROPERTIES));
 
                   if (key.Contains("."))
                   {
                       FMOD.Sound dialogueSound;
                       var soundResult = RuntimeManager.CoreSystem.createSound(Application.streamingAssetsPath + "/" + key, soundMode, out dialogueSound);
                       if (soundResult == FMOD.RESULT.OK)
                       {
                           parameter.sound = dialogueSound.handle;
                           parameter.subsoundIndex = -1;
                           Marshal.StructureToPtr(parameter, parameterPtr, false);
                         
                       }
                   }
                   else
                   {
                       FMOD.Studio.SOUND_INFO dialogueSoundInfo;
                       var keyResult = FMODUnity.RuntimeManager.StudioSystem.getSoundInfo(key, out dialogueSoundInfo);
                       Debug.LogError("El sonido es " + dialogueSoundInfo);
                       if (keyResult != FMOD.RESULT.OK)
                       {
                           break;
                       }
                       FMOD.Sound dialogueSound;
                       var soundResult = FMODUnity.RuntimeManager.CoreSystem.createSound(dialogueSoundInfo.name_or_data, soundMode | dialogueSoundInfo.mode, ref dialogueSoundInfo.exinfo, out dialogueSound);
                       if (soundResult == FMOD.RESULT.OK)
                       {
                           parameter.sound = dialogueSound.handle;
                           parameter.subsoundIndex = dialogueSoundInfo.subsoundindex;
                           Marshal.StructureToPtr(parameter, parameterPtr, false);
                       }
                   }
                   break;
               }
           case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROY_PROGRAMMER_SOUND:
               {
                   var parameter = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
                   var sound = new FMOD.Sound(parameter.sound);
                   sound.release();
 
                   break;
               }
           case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROYED:
               {
                   // Now the event has been destroyed, unpin the string memory so it can be garbage collected
                   stringHandle.Free();
 
                   break;
               }
       }
       return FMOD.RESULT.OK;
   }

```

The Dialog.cs script is  
void DisplayData(DialogStepData stepData)  
{  
this.stepData = stepData;

```
    if (stepData.TextID == ETranslateID.EMPTY)
    {
        Text.transform.parent.gameObject.SetActive(false);
    } else
    {
        SoundManager.Instance.PlayDialog(stepData.TextID);
        Diálogo = true;
        Text.text = data.Talkers[stepData.Talker]
            .Replace("$", Overmind.GetTranslatedText(data.TalkersIDs[stepData.Talker])) 
            + Overmind.GetTranslatedText(stepData.TextID);
        if (stepData.Talker == 0)
        {
            TalkerChanged.Invoke(true);
        } else
        {
            TalkerChanged.Invoke(false);
        }
        Text.transform.parent.gameObject.SetActive(true);
    }

    for (int i = 0; i < AnswerTexts.Length; i++)
    {
        AnswerTexts[i].gameObject.SetActive(false);
    }
    for (int i = 0; i < stepData.AnswerIDs.Count; ++i)
    {
        if (stepData.Silent)
        {
            AnswerTexts[i].text = Overmind.GetTranslatedText(stepData.AnswerIDs[i]);
        }
        else
        {
            AnswerTexts[i].text = (i + 1) + ". " + Overmind.GetTranslatedText(stepData.AnswerIDs[i]);
        }
        AnswerTexts[i].gameObject.SetActive(true);
    }
}

```

Thank you in advance

---

<div class="post-metadata">

**Author:** ![li\_fmod](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/li_fmod/32/6577_2.png) [@li\_fmod](https://qa.fmod.com/u/li_fmod)\
**Post date:** [January 23, 2025, 9:47pm UTC](https://qa.fmod.com/t/fmod-shadoweventinstance-createprogrammersound-programmer-sound-callback-is-not-set-for-instrument/22529/4 "2025-01-23T21:47:33Z")

</div>

> [@AntvilStudios](#):
>
> The error returned for a localized bank is: [FMOD] Unable to load Dialogues\_SPA - bank already loaded. This may occur when attempting to load another localized bank before the first is unloaded, or if a bank has been loaded via the API.  
> UnityEngine.Debug:LogWarningFormat (string,object)

This warning is benign. You could find a discussion of the same issue in this post:

> [@Kart Minigame tutorial Unity doesn't find new FMOD music events](https://qa.fmod.com/t/kart-minigame-tutorial-unity-doesnt-find-new-fmod-music-events/22326/4):
>
> No problem, happy to hear you managed to resolve those errors. This warning is benign. FMOD Studio has a[Localized Audio Tables](https://www.fmod.com/docs/2.02/studio/dialogue-and-localization.html#localized-audio-tables) feature, which will produce a separate bank for each language being used - the example project has three localized banks. By default, the FMOD for Unity integration loads all bank (which you can see in the Initialization section of FMOD Settings in Unity), so these two warnings are being produced by the integration trying to load two of the localized banks after alrea…

> [@AntvilStudios](#):
>
> ```auto
> public static SoundManager Instance { get; private set; }
>  
> EVENT_CALLBACK dialogueCallback;
> public FMODUnity.EventReference Dialog;
> public void PlayDialog(ETranslateID ID)
> {
> //RuntimeManager.PlayOneShot("event:/Dialog/" + ID.ToString());
> //RuntimeManager.PlayOneShot("event:/Dialog/dialog_0a");
>  
> var dialogueInstance = RuntimeManager.CreateInstance(FMODEvents.Instance.Dialog);//Esto está bien
> // Pin the key string in memory and pass a pointer through the user data
> GCHandle stringHandle = GCHandle.Alloc(ID.ToString());
> Debug.LogError("Esto es " + stringHandle);
> dialogueInstance.setUserData(GCHandle.ToIntPtr(stringHandle));
> dialogueInstance.setCallback(dialogueCallback);
> dialogueInstance.start();
> dialogueInstance.getPlaybackState(out PLAYBACK_STATE dialoguesState);//Se inicia con normalidad
> dialogueInstance.release();
> }
> 
> ```

From the code you shared, it seems that the `dialogueCallback` is declared but not assigned to `DialogueEventCallback`. Without this assignment, the callback won’t execute as expected.

To resolve this, please assign the callback in the `Start` or `Awake` method like this:

```auto
dialogueCallback = DialogueEventCallback;

```

Hope this helps, let me know if the issue persist.

---

<div class="post-metadata">

**Author:** ![AntvilStudios](https://avatars.discourse-cdn.com/v4/letter/a/7feea3/32.png) [@AntvilStudios](https://qa.fmod.com/u/AntvilStudios)\
**Post date:** [January 24, 2025, 2:49pm UTC](https://qa.fmod.com/t/fmod-shadoweventinstance-createprogrammersound-programmer-sound-callback-is-not-set-for-instrument/22529/5 "2025-01-24T14:49:25Z")

</div>

Thank you very much for the reply  
Unfortunately the problem persists.

I added the code you suggested to my start method, but the problem is the same.

```auto
private void Start()
    {
        
        UpdateSoundSettings();
        dialogueCallback = new FMOD.Studio.EVENT_CALLBACK(DialogueEventCallback);
       dialogueCallback = DialogueEventCallback;
        Dialog = FMODUnity.EventReference.Find("event:/EL TERROR ERRANTE/Conversations/Dialogues");
        

    }

```

---

<div class="post-metadata">

**Author:** ![Connor\_FMOD](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/connor_fmod/32/3685_2.png) [@Connor\_FMOD](https://qa.fmod.com/u/Connor_FMOD)\
**Post date:** [January 29, 2025, 1:04am UTC](https://qa.fmod.com/t/fmod-shadoweventinstance-createprogrammersound-programmer-sound-callback-is-not-set-for-instrument/22529/6 "2025-01-29T01:04:12Z")

</div>

Thank you for the code.

Looking at that code snippet we now need to set the callback to the event:

```C
private void Start()
{
    UpdateSoundSettings();
    dialogueCallback = new FMOD.Studio.EVENT_CALLBACK(DialogueEventCallback);
    // dialogueCallback = DialogueEventCallback; ## We don't want to reassign the variable ##
    Dialog = FMODUnity.EventReference.Find("event:/EL TERROR ERRANTE/Conversations/Dialogues");

    // ## From the SoundManager.cs PlayDialog() function ##
    var dialogueInstance = RuntimeManager.CreateInstance(FMODEvents.Instance.Dialog);//Esto está bien
    // Pin the key string in memory and pass a pointer through the user data
    GCHandle stringHandle = GCHandle.Alloc(ID.ToString());
    Debug.LogError("Esto es " + stringHandle);
    dialogueInstance.setUserData(GCHandle.ToIntPtr(stringHandle));
    // ## Now we have assigned the callback we want to set it to the instance. ##
    dialogueInstance.setCallback(dialogueCallback);
    // ##
    dialogueInstance.start();
    dialogueInstance.getPlaybackState(out PLAYBACK_STATE dialoguesState);//Se inicia con normalidad
    dialogueInstance.release();
}

```

---

<div class="post-metadata">

**Author:** ![AntvilStudios](https://avatars.discourse-cdn.com/v4/letter/a/7feea3/32.png) [@AntvilStudios](https://qa.fmod.com/u/AntvilStudios)\
**Post date:** [February 5, 2025, 11:17am UTC](https://qa.fmod.com/t/fmod-shadoweventinstance-createprogrammersound-programmer-sound-callback-is-not-set-for-instrument/22529/7 "2025-02-05T11:17:46Z")

</div>

It worked!. Thank you very much!!!
