How to direct sound to specific Programmer Sound

Hi,

I’m trying to load online sounds to Programmer Sounds.

I have 2 questions:

  1. If I load 6 files into 6 programmer sounds, each one in one track, will it play in sync?

  2. How can I add the name of the Programmer Sound and direct the loaded sound to this specific Programmer Sound?

This code allow me to load the audio file from the internet, but not to specify to which programmer sound name in the Event:

static FMOD.RESULT DialogueEventCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type, IntPtr instancePtr, IntPtr parameterPtr)
{
    // Recreate the event instance C# object
    FMOD.Studio.EventInstance instance = new FMOD.Studio.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;

    Debug.Log("Event = " + type);

    

    switch (type)
    {
        case FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
            {
                var parameter = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));

                FMOD.Sound dialogueSound;
                var soundResult = FMODUnity.RuntimeManager.CoreSystem.createSound(key, FMOD.MODE.DEFAULT, out dialogueSound);

                if (soundResult == FMOD.RESULT.OK)
                {
                    parameter.sound = dialogueSound.handle;
                    
                    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:
            
            stringHandle.Free();
            break;
    }
    return FMOD.RESULT.OK;
}

I’ve checked the getName but really don’t know how to link the sound to the programmer instrument.

I even created 6 events with one programmer instrument each.
Then created one Event with each one of these Event Instruments.

I loaded this script, but I got only one sound running and going directly to the master output. I couldn’t control anything on the track level (that I have full of parameters to control pan, volume, etc).

Anyway… nothing worked properly. What should I do here?

Here’s the full code:

using System;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;

class ProgrammerSounds : MonoBehaviour
{
    FMOD.Studio.EVENT_CALLBACK dialogueCallback;

[FMODUnity.EventRef]
public string MyProgrammerEvent;

void Start()
{
    dialogueCallback = new FMOD.Studio.EVENT_CALLBACK(DialogueEventCallback);
}

void PlayDialogue(string key)
{
    
    var dialogueInstance = FMODUnity.RuntimeManager.CreateInstance(MyProgrammerEvent);


    GCHandle stringHandle = GCHandle.Alloc(key, GCHandleType.Pinned);
    dialogueInstance.setUserData(GCHandle.ToIntPtr(stringHandle));


    dialogueInstance.setCallback(dialogueCallback);
    dialogueInstance.start();
    dialogueInstance.release();
}



[AOT.MonoPInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
static FMOD.RESULT DialogueEventCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type, IntPtr instancePtr, IntPtr parameterPtr)
{
    FMOD.Studio.EventInstance instance = new FMOD.Studio.EventInstance(instancePtr);

    
    IntPtr stringPtr;
    instance.getUserData(out stringPtr);


    GCHandle stringHandle = GCHandle.FromIntPtr(stringPtr);
    String key = stringHandle.Target as String;

    

    switch (type)
    {

        case FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
            {
                var parameter = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));


                FMOD.Sound dialogueSound;
                var soundResult = FMODUnity.RuntimeManager.CoreSystem.createSound(key, FMOD.MODE.DEFAULT, out dialogueSound);

                if (soundResult == FMOD.RESULT.OK)
                {

                    parameter.sound = dialogueSound.handle;
                    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:
            
            stringHandle.Free();
            break;
    }
    return FMOD.RESULT.OK;
}


void Update()
{
    if (Input.GetKeyDown(KeyCode.Q))
    {
        PlayDialogue("http://www.mysite/myaudio.mp3");
    }
    if (Input.GetKeyDown(KeyCode.W))
    {
        PlayDialogue("c:/myaudio.wav");
    }
    
}

}

You would have to create the sounds you want to play ahead of time for them to play in sync, if you were to wait until the create callback then it will need time to create each sound.

You can rename the programmer instruments to differentiate them in code through the FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES.

Hi, Cameron.
I’ve checked and tried, but without success.
Is it possible for you to help directly with a code example (based on my code or not).

I also got a different code from a programmer, but it’s crashing Unity every time.
I’d really appreciate your help!!

Loading the sounds ahead of time is just a matter of moving the sound creation to a different point, and then when you get the CREATE_PROGRAMMER_SOUND callback you can pass in the already created sound.

The instrument name can be found in the event callback, you can access the programmer instrument through the parameter:

var parameter = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
var paramName = parameter.name;
...
1 Like

Hi, Cameron.

I have been using FMOD + Unity this way to populate multiple programmer instruments in a sequential order and everything has been working great.

However, I am now attempting to check the name of each programmer instrument passed to use them only if they match a certain string, but have encountered an issue.

Each instrument is repoting an empty string for the parameter.name (following a cast from the FMOD.StringWrapper format). Do you know why this could be happening? Are my programmer instruments actaully named “” or is there an issue with the conversion?

Here is a screenshot of the programmer instrument in my FMOD project. It is named “Prog Int 1” which is what I was hoping to get by casting the paramer.name.
image

Answered my own question right after posting, but here is the answer for anyone else who encounters this issue.

This was actually the event name that contains the programmer instrument. You’ll need to double click on the event instance and adjust the name of the actual programmer instrument inside (by default it is empty and will just say “Programmer Instrument”).

image

1 Like