Capturing Unity game’s FMOD output (5.1 / Busses)

Hi,
I am about to start working on a game project in Unity using FMOD. Some scenes will be captured as video and later used for a linear 5.1 mix. I am wondering what the most elegant ways are to capture FMODs audio output in sync (can be a separate WAV output file) with Unity’s video on windows.

Specifically in 5.1 and in Stereo.

And related: how can I capture my FMOD audio busses to separate WAV files during the same Unity run(In my case those groups are just two: ambiences and soundeffects.

If we need custom coding for that I’d be grateful for any pointers how to potentially approach this, if there some way to do it directly via Unity or FMOD I’d love hear about it.

Or maybe there is a third party tool or somebody already coded a solution to my problem which I could use a a starting point?

Thanks a lot!

Hi,

FMOD has the FMOD_OUTPUTTYPE_WAVWRITER output mode that allows the system to write the final mixer output to a .wav file. Note that using WAVWRITER means that the system will solely output to file; it won’t output to a device. To accomplish this with the Unity Integration, you’ll have to modify FMODUnity.RuntimeManager as follows:

  • Add the following as class members:
byte[] wavPath;
GCHandle wavHandle;
IntPtr wavPtr;
  • Modify the output of the coreSystem object on line 301:
result = coreSystem.setOutput(FMOD.OUTPUTTYPE.WAVWRITER);
  • Replace the studioSystem.initialize() call on line 347 with the following:
using (FMOD.StringHelper.ThreadSafeEncoding encoder = FMOD.StringHelper.GetFreeHelper())
{
    wavPath = encoder.byteFromStringUTF8("C:\\Your\\Path\\Here\\wavFile.wav");
    wavHandle = GCHandle.Alloc(wavPath, GCHandleType.Pinned);
    wavPtr = wavHandle.AddrOfPinnedObject();
    result = studioSystem.initialize(virtualChannels, studioInitFlags, FMOD.INITFLAGS.NORMAL, wavPtr);
}
  • Free the GCHandle object wavHandle in RuntimeManager.OnDestroy() after ReleaseStudioSystem() is called:
private void OnDestroy()
{
    coreSystem.setCallback(null, 0);
    ReleaseStudioSystem();

    wavHandle.Free();
    //...
}

You will also need to make the static class StringHelper in fmod.cs at line 3884 public.

However, this won’t allow you to separately capture audio for different Buses unless you do multiple recordings with the Buses muted/solo’d. To do this, you’ll need to go a little more in-depth - I would suggest modifying our Unity DSP Capture script example to collect the audio data, adding a wav header to the data, and writing it to a .wav file. The DSP Capture example specifically grabs the Master ChannelGroup’s output, but you can modify it to grab any Bus’ core ChannelGroup instead, which you can get with Studio::Bus::getChannelGroup. As for writing to a wav file with the appropriate header, here’s a somewhat old post detailing how to record audio input and write it to a wav file. The post uses in C++, and specifically pertains to writing audio input to file, but you should be able to adapt it to C# and your specific use-case.

If you have any additional questions, feel free to ask.

Hi @Leah_FMOD ! I’m a teammate of @davidkamp1 and your comment was very helpful. I tested the WAVWriter and that indeed records a .wav file of the whole master and so on.

However, due to wanting to record various buses and other specs, I moved onto trying to accomplish what you mentioned: DSP Capture script example with the .wav header and writing to a .wav file. (for now using only the Master ChannelGroup until that works, will test a different bus later).

Now, I am a gameplay programmer and I’m completely out of my depth once it comes to structured data like this. The C++ to C# isn’t a problem, but the part that I don’t understand at all is how I should create the file out of the data from the DSP. As in, I don’t know what to connect where, how to feed the float array mDataBuffer from the DSP example to a file or how to create a header based on that data.

I have tried using this and both solutions provided here for reference, but every time the examples are about recording from microphone with the functions that come with an initialized system and it’s throwing me off. I don’t know how to implement this.

Could you please help me out a little? Thank you!

In case it’s relevant, our usecase is to save the FMOD sounds of a certain amount of gameplay into .wav files, so we can replay that segment later together synced with video that we record with a different tool, not to record all gameplay sounds since the Scene starts.