# General advice on user-friendly process for players to upload audio assets then pipe them through FMOD-powered Unity?

**URL:** <https://qa.fmod.com/t/general-advice-on-user-friendly-process-for-players-to-upload-audio-assets-then-pipe-them-through-fmod-powered-unity/19005>\
**Category:** Unity\
**Created:** [July 15, 2022, 7:32pm UTC](https://qa.fmod.com/t/general-advice-on-user-friendly-process-for-players-to-upload-audio-assets-then-pipe-them-through-fmod-powered-unity/19005 "2022-07-15T19:32:04Z")\
**Posts on this page:** 1\
**Showing post:** 2

<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:** [July 19, 2022, 4:07am UTC](https://qa.fmod.com/t/general-advice-on-user-friendly-process-for-players-to-upload-audio-assets-then-pipe-them-through-fmod-powered-unity/19005/2 "2022-07-19T04:07:19Z")

</div>

Hi,

An option you have is using Programmer Instrument, explained in the [Glossary](https://fmod.com/docs/2.02/studio/glossary.html#programmer-instrument). These allow for files outside of the FMOD and game project files to be used as audio sources.

You will need to include: `using System;` and `using System.Runtime.InteropServices;` at the top of your code file.

Create an `FMODUnity.EventReference` variable which will be used to instantiate your [`Programmer Instrument`](https://fmod.com/docs/2.02/studio/working-with-instruments.html#programmer-instruments) from the FMOD Project.

Then create an [`FMOD.Studio.EVENT_CALLBACK`](https://fmod.com/docs/2.02/api/studio-api-eventinstance.html#fmod_studio_event_callback) variable which will be used to create the `sound` to be played by FMOD.

In

```auto
void Start()
{
	yourPlayBackVariable = new FMOD.Studio.EVENT_CALLBACK(PlayFileCallBack);
}

```

This instantiates your `EVENT_CALLBACK` to be used in the `PlayAudioFile(string location)` function. Call this when the sound is ready to be played, how it gets the parameter `location` is up to you. Be sure that `location` is the full file path to the audio source.

> **PlayAudioFile(string location) Function**
>
> ```auto
> public void PlayAudioFile(string location)
> {
> var eventInstance = FMODUnity.RuntimeManager.CreateInstance(yourEventReference);
> 	
> // FMOD.RESULT is a very useful debugging tool to ensure that FMOD functions have run properly 
> FMOD.RESULT result; 
> if (yourEventInstance.isValid() == false)
> {
> Debug.Log("Failed to create instance, instance invalid");
> return;
> }
> // Lock the file location in memory to be used in the CALLBACK function to find the audio source
> GCHandl stringLocation = GCHandle.Alloc(location);
> // Assigning this data to the created instance 
> result = eventInstnace.setUserData(GCHandle.ToIntPtr(stringLocation));
> 	
> // Using an if statement like this after most FMOD function calls will help debug errors in code 
> if (result != FMOD.RESULT.OK)
> {
> Debug.Log("Failed to create evenInstance with a result of " + result);
> return;
> }
> 	
> 	
> // Check the result after each function call 
> result = eventInstance.setCallback(yourPlayBackVaraible); 
> result = eventInstance.start();
> // The sound has successfully been created and played 
> }
> 
> ```

This is your `FMOD.Studio.EVENT_CALLBACK` function used to create the sound for FMOD to play using the audio source file location.

> **CALLBACK Function**
>
> ```auto
> [AOT.MonoPInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
> static FMOD.RESULT YourCallBackFunction(FMOD.Studio.EVENT_CALLBACK_TYPE type, IntPtr instancePtr, IntPtr parameterPtr)
> {
> FMOD.Studio.EventInstance instance = new FMOD.Studio.EventInstance(instancePtr);
> 
> if (instance.isValid() == false)
> {
> UnityEngine.Debug.Log("Failed to create instance, instance invalid");
> return FMOD.RESULT.ERR_EVENT_NOTFOUND;
> }
> 
> //Retrive the user data 
> IntPtr stringPtr;
> instance.getUserData(out stringPtr);
> 
> // Retrieving the path of the audio source from the user data
> GCHandle stringHandle = GCHandle.FromIntPtr(stringPtr);
> String location = stringHandle.Target as String;
> 
> switch (type)
> {
> case FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
> {
> FMOD.MODE soundMode = FMOD.MODE.LOOP_NORMAL | FMOD.MODE.CREATECOMPRESSEDSAMPLE | FMOD.MODE.NONBLOCKING;
> var parameter = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
> 		
> FMOD.Sound audioSound;
> FMOD.RESULT result;
> 
> // Creating the sound using the location of the audio source 
> result = FMODUnity.RuntimeManager.CoreSystem.createSound(location, soundMode, out audioSound);
> 
> if (result == FMOD.RESULT.OK)
> {
> parameter.sound = audioSound.handle;
> parameter.subsoundIndex = -1;
> Marshal.StructureToPtr(parameter, parameterPtr, false);
> }
> break;
> }
> case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROY_PROGRAMMER_SOUND:
> {
> var paramerter = (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
> var sound = new FMOD.Sound(paramerter.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 garbaged collected
> stringHandle.Free();
> break;
> }
> }
> return FMOD.RESULT.OK;
> }
> 
> ```

Once this is all set up users will be able to pass in the location of audio sources which you can then play using FMOD.

A full script example of `Programmer Sounds` being used can be found under [Scripting Examples | Programmer Sounds](https://fmod.com/docs/2.02/unity/examples-programmer-sounds.html). Keep in mind, in the example it is using an `audio table` and not the file location of an audio source, but it may be a useful reference.

Hope this helps!

---

_[View the full topic](https://qa.fmod.com/t/general-advice-on-user-friendly-process-for-players-to-upload-audio-assets-then-pipe-them-through-fmod-powered-unity/19005)._
