# Adding effects to real-time recorded audio

**URL:** https://qa.fmod.com/t/adding-effects-to-real-time-recorded-audio/21265
**Category:** Unity
**Tags:** unity, csharp
**Created:** [February 20, 2024, 5:25am UTC](https://qa.fmod.com/t/adding-effects-to-real-time-recorded-audio/21265 "2024-02-20T05:25:17Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![hardsmoke](https://avatars.discourse-cdn.com/v4/letter/h/e9a140/32.png) [@hardsmoke](https://qa.fmod.com/u/hardsmoke)
#### Post date: [February 20, 2024, 5:25am UTC](https://qa.fmod.com/t/adding-effects-to-real-time-recorded-audio/21265/1 "2024-02-20T05:25:17Z")

</div>

Hello,

I’m making a voice chat for a game and I need the ability to apply various effects to the sound that I receive from the microphone depending on the value of some parameters, for example, to apply an “underwater” effect (may be snapshot) to the sound from the microphone when the player is underwater, is it possible to do this? Currently I have a sound structure and samples from a microphone.

Thanks.

---

<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: [February 22, 2024, 1:11am UTC](https://qa.fmod.com/t/adding-effects-to-real-time-recorded-audio/21265/2 "2024-02-22T01:11:55Z")

</div>

Hi,

This can certainly be done using a [Programmer Instrument](https://fmod.com/docs/2.02/studio/instrument-reference.html#programmer-instrument). We have a scripting example: [Unity Integration | Scripting Examples - Programmer Sound](https://fmod.com/docs/2.02/unity/examples-programmer-sounds.html) which outlines using [Audio Tables](https://fmod.com/docs/2.02/studio/dialogue-and-localization.html#audio-tables) with a programmer sound. However, since you already have a sound, rather than using a table or a file you’d just pass the sound to the programmer instrument.

Here is the updated `switch` statement:

> **Switch**
>
> ```switch
> {
> case FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
> {
> // We can remove all this since we already have the sound
> //FMOD.MODE soundMode = FMOD.MODE.LOOP_NORMAL | FMOD.MODE.CREATECOMPRESSEDSAMPLE | FMOD.MODE.NONBLOCKING;
> 
> // We need to keep this
> var parameter = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
> 
> // Remove this
> // if (key.Contains("."))
> // {
> // FMOD.Sound dialogueSound;
> // var soundResult = FMODUnity.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);
> // 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);
> // }
> // }
> 
> // We now need to pass the sound to the programmer instrument
> parameter.sound = dialogueSound.handle;
> parameter.subsoundIndex = dialogueSoundInfo.subsoundindex;
> Marshal.StructureToPtr(parameter, parameterPtr, false);
> // Thats it!
> 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;
> }
> }
> 
> ```

Remember to pass in the sound as the event instances [User Data](https://fmod.com/docs/2.02/api/glossary.html#user-data) . To do this I create a simple class to hold the sound for me:

```auto
public class UserDataClass
{
	public FMOD.Sound sound;
}

```

But you may wish to do this another way.

Hope this helps!

---

<div class="post-metadata">

### Author: ![hardsmoke](https://avatars.discourse-cdn.com/v4/letter/h/e9a140/32.png) [@hardsmoke](https://qa.fmod.com/u/hardsmoke)
#### Post date: [March 4, 2024, 5:27am UTC](https://qa.fmod.com/t/adding-effects-to-real-time-recorded-audio/21265/3 "2024-03-04T05:27:17Z")

</div>

Hello,

I used the code from the example and your implementation of the switch, after running the PlaySound method I hear the last second of my speech spoken into the microphone, when I launch PlaySound again I get a warning below

```auto
[FMOD] SoundSourceInstrumentInstance::startChannelIfReady : Resource type 1 for instrument {a7c321b6-eaed-4cba-8921-66d6cbc1d093} has returned 30 and will now stop.

```

I don’t quite understand how to work with a programmer instrument and a sound that is overwritten every moment: should I run the PlaySound method every 1 second (for example) or can I link the sound to the programmer instrument and it will update automatically?

> **This is what I have at the moment.**
>
> \_soundHolder is a variable of a class that contains Sound
> 
> ```auto
> [ContextMenu("Play Sound")]
> private void PlaySound()
> {
> var dialogueInstance = RuntimeManager.CreateInstance(_eventReference);
> 
> GCHandle soundHolderHandle = GCHandle.Alloc(_soundHolder);
> dialogueInstance.setUserData(GCHandle.ToIntPtr(soundHolderHandle));
> dialogueInstance.setCallback(dialogueCallback);
> dialogueInstance.start();
> dialogueInstance.release();
> }
> 
> [AOT.MonoPInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
> private static RESULT DialogueEventCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type, IntPtr instancePtr, IntPtr parameterPtr)
> {
> FMOD.Studio.EventInstance instance = new FMOD.Studio.EventInstance(instancePtr);
> 
> instance.getUserData(out IntPtr stringPtr);
> 
> GCHandle stringHandle = GCHandle.FromIntPtr(stringPtr);
> IFMODSoundHolder soundHolder = stringHandle.Target as IFMODSoundHolder;
> 
> UnityEngine.Debug.Log(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));
> parameter.sound = soundHolder.Sound.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 Sound(parameter.sound);
> sound.release();
> 
> break;
> }
> case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROYED:
> {
> stringHandle.Free();
> 
> break;
> }
> }
> return RESULT.OK;
> }
> 
> private void Start()
> {
> dialogueCallback = new FMOD.Studio.EVENT_CALLBACK(DialogueEventCallback);
> }
> 
> ```

In FMOD Editor what length should the sound be?  
 ![Screenshot_1919](https://canada1.discourse-cdn.com/flex036/uploads/fmod/original/2X/4/4081b976a733508a0d75abb74b789ec4327c7a01.png)

---

<div class="post-metadata">

### Author: ![hardsmoke](https://avatars.discourse-cdn.com/v4/letter/h/e9a140/32.png) [@hardsmoke](https://qa.fmod.com/u/hardsmoke)
#### Post date: [March 4, 2024, 6:58am UTC](https://qa.fmod.com/t/adding-effects-to-real-time-recorded-audio/21265/4 "2024-03-04T06:58:18Z")

</div>

I found the answer to my question in this topic

> [@Send microphone input to programmer instrument](https://qa.fmod.com/t/send-microphone-input-to-programmer-instrument/15554):
>
> 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 FM…

---

<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: [March 4, 2024, 9:31pm UTC](https://qa.fmod.com/t/adding-effects-to-real-time-recorded-audio/21265/5 "2024-03-04T21:31:29Z")

</div>

Hi,

Thanks for sharing the solution.

---

<div class="post-metadata">

### Author: ![hardsmoke](https://avatars.discourse-cdn.com/v4/letter/h/e9a140/32.png) [@hardsmoke](https://qa.fmod.com/u/hardsmoke)
#### Post date: [March 5, 2024, 4:01am UTC](https://qa.fmod.com/t/adding-effects-to-real-time-recorded-audio/21265/6 "2024-03-05T04:01:55Z")

</div>

One more question: how to correctly change snapshots depending on a particular situation? As far as I understand, I cannot make a loop region in the parameter sheet, so this method is immediately discarded, is it worth writing my own implementation or are there other methods?

---

<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: [March 5, 2024, 9:55pm UTC](https://qa.fmod.com/t/adding-effects-to-real-time-recorded-audio/21265/7 "2024-03-05T21:55:38Z")

</div>

Hi,

An option could be adding a looping region to the Timeline sheet which will keep the event playing and then having your snapshots on a parameter sheet:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/fmod/original/2X/8/81097e5176cdcf277b0a4f92aa8e5f32ade21c51.png)

Hope this helps!

---

<div class="post-metadata">

### Author: ![hardsmoke](https://avatars.discourse-cdn.com/v4/letter/h/e9a140/32.png) [@hardsmoke](https://qa.fmod.com/u/hardsmoke)
#### Post date: [March 6, 2024, 5:25am UTC](https://qa.fmod.com/t/adding-effects-to-real-time-recorded-audio/21265/8 "2024-03-06T05:25:15Z")

</div>

Thank you! Everything worked out.
