# How to create programmer sound from AUDIOCLIP

**URL:** https://qa.fmod.com/t/how-to-create-programmer-sound-from-audioclip/19466
**Category:** Unity
**Tags:** unity
**Created:** [November 1, 2022, 11:02pm UTC](https://qa.fmod.com/t/how-to-create-programmer-sound-from-audioclip/19466 "2022-11-01T23:02:47Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![FoolishMortals](https://avatars.discourse-cdn.com/v4/letter/f/dec6dc/32.png) [@FoolishMortals](https://qa.fmod.com/u/FoolishMortals)
#### Post date: [November 1, 2022, 11:02pm UTC](https://qa.fmod.com/t/how-to-create-programmer-sound-from-audioclip/19466/1 "2022-11-01T23:02:47Z")

</div>

Hi. Using your coding example for unity [https://www.fmod.com/docs/2.02/unity/examples-programmer-sounds.html](https://www.fmod.com/docs/2.02/unity/examples-programmer-sounds.html) it loads a file from STREAMING ASSETS. I already have an AUDIOCLIP in a c# script I want to play in-game (it’s fetched and downloaded dynamically while the game is running). How would I change the example script to play an audioclip rather than a streaming file?

---

<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: [November 3, 2022, 1:56am UTC](https://qa.fmod.com/t/how-to-create-programmer-sound-from-audioclip/19466/2 "2022-11-03T01:56:39Z")

</div>

Hi,

This is quite an involved process and there are a couple of things to keep in mind. You will have to re-enable Unity Audio which will restrict you from building to Xbox One, and Xbox Series X|S.

The major change will be the information that we pass into our `userData` which instead of being the key to access the `Audio Table` it will be the information from the Audio Clip required to make an `FMOD.Sound`.

So first we will need to make a class to contain the information we need form the Audio clip.

> **Class set up**
>
> ```auto
> class SoundRequirements
> {
> public string name;
> public int samples;
> public int channels; 
> public FMOD.SOUND_FORMAT format;
> public int defaultFrequence;
> public float[] sampleData;
> 
> public SoundRequirements(string name, int samples, int channel, FMOD.SOUND_FORMAT format, int defaultFrequence, float[] sampleData)
> {
> this.name = name;
> this.samples = samples;
> this.channels = channel;
> this.format = format;
> this.defaultFrequence = defaultFrequence;
> this.sampleData = sampleData;
> }
> }
> 
> ```

Assigning the majority of those variables is pretty straight forward but getting the `sampleData` requires you to get that from the Audio Clip beforehand:

```auto
// Get the sample data from the clip and assign in to an array 
float[] sampleData = new float[unityAudioClip.samples * unityAudioClip.channels];
unityAudioClip.GetData(sampleData, 0);

```

Passing in the class to the `userData` is the same as the example, however, retrieving it and creating the sound is quite different. So I will include my Callback function:

> **Callback**
>
> ```auto
> [AOT.MonoPInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
> static FMOD.RESULT PlayFileCallBackUsingAudoiFile(FMOD.Studio.EVENT_CALLBACK_TYPE type, IntPtr instPrt, IntPtr paramsPrt)
> {
> FMOD.Studio.EventInstance inst = new FMOD.Studio.EventInstance(instPrt);
> 
> if (!inst.isValid())
> {
> return FMOD.RESULT.ERR_EVENT_NOTFOUND;
> }
> 
> // Retrieving the user data from the instance
> inst.getUserData(out IntPtr clipDataPtr);
> GCHandle clipHandle = GCHandle.FromIntPtr(clipDataPtr);
> // Assinging the our data to a new struct so we can access all the information 
> SoundRequirements clip = clipHandle.Target as SoundRequirements; 
> 
> // Depending on the callback type will decide what happens next 
> switch (type)
> {
> case FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
> {
> // This is what we will use to pass the sound back out to our instance 
> var param = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(paramsPrt, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
> 
> // Retrieve the masterGroup, or the channel group you wish to play the clip too 
> ERRCHECK(FMODUnity.RuntimeManager.CoreSystem.getMasterChannelGroup(out FMOD.ChannelGroup masterGroup), "Failed to get masterGroup from core system");
> 
> // Calculating the length of the audio clip by the samples and channels 
> uint lenBytes = (uint)(clip.samples * clip.channels * sizeof(float));
> 
> // Sound exit info to be used when creating the sound 
> FMOD.CREATESOUNDEXINFO soundInfo = new FMOD.CREATESOUNDEXINFO();
> soundInfo.cbsize = Marshal.SizeOf(typeof(FMOD.CREATESOUNDEXINFO));
> soundInfo.length = lenBytes;
> soundInfo.format = FMOD.SOUND_FORMAT.PCMFLOAT;
> soundInfo.defaultfrequency = clip.defaultFrequence;
> soundInfo.numchannels = clip.channels;
> 
> // Creating the sound using soundInfo
> FMOD.RESULT result = ERRCHECK(FMODUnity.RuntimeManager.CoreSystem.createSound(clip.name, FMOD.MODE.OPENUSER, ref soundInfo, out FMOD.Sound sound), "Failed to create sound");
> if (result != FMOD.RESULT.OK)
> return result; 
> 
> // Now we have created our sound, we need to give it the sample data from the audio clip 
> result = ERRCHECK(sound.@lock(0, lenBytes, out IntPtr ptr1, out IntPtr ptr2, out uint len1, out uint len2), "Failed to lock sound");
> if (result != FMOD.RESULT.OK)
> return result; 
> 
> Marshal.Copy(clip.sampleData, 0, ptr1, (int)(len1 / sizeof(float)));
> if (len2 > 0)
> Marshal.Copy(clip.sampleData, (int)(len1 / sizeof(float)), ptr2, (int)(len2 / sizeof(float)));
> 
> result = ERRCHECK(sound.unlock(ptr1, ptr2, len1, len2), "Failed to unlock sound");
> if (result != FMOD.RESULT.OK)
> return result; 
> 
> ERRCHECK(sound.setMode(FMOD.MODE.DEFAULT), "Failed to set the sound mode");
> 
> if (result == FMOD.RESULT.OK)
> {
> param.sound = sound.handle;
> param.subsoundIndex = -1;
> // Passing the sound back out again to be played 
> Marshal.StructureToPtr(param, paramsPrt, false);
> }
> else
> return result;
> }
> break;
> case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROY_PROGRAMMER_SOUND:
> {
> var param = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(paramsPrt, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
> var sound = new FMOD.Sound(param.sound);
> FMOD.RESULT result = ERRCHECK(sound.release(), "Failed to release sound");
> if (result != FMOD.RESULT.OK)
> return result; 
> }
> break;
> case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROYED:
> clipHandle.Free();
> break;
> }
> return FMOD.RESULT.OK; 
> }
> 
> /// <summary>
> /// Debug FMOD Function results only in Editor 
> /// </summary>
> private static FMOD.RESULT ERRCHECK(FMOD.RESULT result, string failMsg)
> {
> #if UNITY_EDITOR
> if (result != FMOD.RESULT.OK)
> {
> Debug.Log(failMsg + " with result: " + result);
> return result; 
> }
> #endif
> return result;
> }
> 
> ```

After that, you should be able to use an Audio Clip to create a programmer sound. Remember to re-enable Unity Audio. If you have any more questions please let me know.
