Send microphone input to programmer instrument

Hello,
I want to record microphone input and send it to a programmer instrument. So far I managed to get the input and send it in the actual programmer instrument BUT the sound cuts off when the programmer event reaches its end.

Looping the programmer event seems to call CREATE_PROGRAMMER_SOUND and DESTROY_PROGRAMMER_SOUND every loop iteration, which seem to stop the event momentarily causing stuttering.

Am I doing something wrong ? What is the proper way to send microphone input through a FMOD event ?

Here’s my code if it helps:
RECORD START

//create record sound
CREATESOUNDEXINFO createSoundInfo = new CREATESOUNDEXINFO();
createSoundInfo.cbsize = Marshal.SizeOf(typeof(CREATESOUNDEXINFO));
createSoundInfo.numchannels = _currentInputDriver.SpeakerModeChannels;
createSoundInfo.format = SOUND_FORMAT.PCMFLOAT;
createSoundInfo.defaultfrequency = _currentInputDriver.SystemRate;
createSoundInfo.length = (uint)(createSoundInfo.defaultfrequency * sizeof(float) * createSoundInfo.numchannels);
MODE recordMode = MODE.LOOP_NORMAL | MODE.OPENUSER;
FMODUnity.RuntimeManager.CoreSystem.createSound(“record”, recordMode, ref createSoundInfo, out _recordSound);

//create record event
_recordEvent = FMODUnity.RuntimeManager.CreateInstance(“event:/VOIP”);
_recordEvent.setCallback(VoipCallback);
_recordEvent.start();
_recordEvent.release();

//start recording
FMODUnity.RuntimeManager.CoreSystem.recordStart(_currentInputDriver.Index, _recordSound, true);

CALLBACK

switch (pCallbackType)
{
case EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
{
//get properties
PROGRAMMER_SOUND_PROPERTIES properties = (PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(pPropertiesPtr, typeof(PROGRAMMER_SOUND_PROPERTIES));
properties.sound = _recordSound.handle;
Marshal.StructureToPtr(properties, pPropertiesPtr, false);
}
break;

}

1 Like

Is the programmer instrument in the Event marked as ‘Async’?

Yes. As soon as the sound loops once (it’s 1s long and loops forever) it calls the SOUND_STOPPED event and so the event is killed.

What version of FMOD are you using?

2.00.08, both Studio and Unity SDK, with Unity 2019.3.6f1 if that matters.

What you will have to do is set the programmer instrument to async and looping and use a sustain point or loop (inside the instrument region). This will stop the instrument from being destroyed, but then you will need to make sure to clean up the event as it won’t end or release naturally.

Hi. This is exactly what I am trying to do, without success. I was wondering if you could answer some questions for me.

In this code, the callback function is set for a particular event instance, but as I understand, the named programmer instrument in FMOD already generates callback functions. I am getting the error “[FMOD] EventInstance::createProgrammerSoundImpl : Programmer sound callback for instrument ‘playRecording’ returned no sound.” How can I assign the recorded sound to the callback function for this programmer instrument without generating an instance of the event in the code? In general, I am confused about whether it is the event that sends the callback or the programmer instrument.

Also, I see that you have named your sound “record”. Does this correspond to the name of the programmer instrument in FMOD? If not, where do you set the name of the programmer instrument in FMOD that this callback function corresponds to?

My goal is to record sound from the microphone, and then later trigger an event with a programmer instrument that plays back that sound through the routing and effects chains I have set up in my FMOD session. So far I have succeeded in recording and playing back sound with triggers in a Unity script, but I ideally would like to integrate the playback with FMOD for greater control using programmer instruments.

Thank you in advance for any help you can provide!

We have an example for programmer sounds in the API downloads and in the docs: Unity Scripting Examples - Programmer Sounds.

When you create and play an Event you will also need to assign the callback function for that event, when the callback function is called it is called from an existing Event instance. You can then access the instance and modify/control it from there.

You don’t set a name for the programmer instrument in an Event, you set a callback for the Event and then you can check what is causing the callback from the function. ie. if you have multiple programmer sounds in a single event, they will all trigger the same callback function but you can determine when instrument has triggered it from the FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES.

1 Like

Thanks so much for this explanation. I figured it out and now it is working great. :grin:
~andy