Read output data and push into AudioClip/OnAudioFilterRead

Hello,

I’m fairly new to FMOD and Audio-Pipeline programming but here is what I want to do.
I’m trying to access the output from FMOD to route it into Unity3d default audio components (using the OnAudioFilterRead method).
To do so I’m creating a new FMOD.Sound using the low level system and set it to record on the default driver used by FMOD. All calls result in FMOD.RESULT.OK until I try to use the readData-function to get the sounds data. The readData call always return ERR_UNSUPPORTED which doesn’t give me a hint on whats going wrong or where my setup is messed up.
When I set the low level system’s output to WavWriter a file is generated containing the sound played during the game. So somewhere is the raw data and only I’m not able to retrieve it inside Unity and C#.

Can anybody point me into the right direction to go or at least tell me if it is possible at all.

At the moment my code looks like this:
I’m initializing the sound buffer inside the Start method and set it to PCM16 Format (which doesn’t matter if I change it to PCMFloat or PCM32, all give the same message on “readData”)

void Start()
{
    Debug.Log("getLowLevelSystem: " + FMOD_StudioSystem.instance.System.getLowLevelSystem(out lowLevelSystem));
    lowLevelSystem.setOutput(FMOD.OUTPUTTYPE.WAVWRITER);

    FMOD.CREATESOUNDEXINFO exinfo = new FMOD.CREATESOUNDEXINFO();
    exinfo.cbsize = System.Runtime.InteropServices.Marshal.SizeOf(exinfo);
    exinfo.numchannels = 2;
    exinfo.format = FMOD.SOUND_FORMAT.PCM16;// FMOD_SOUND_FORMAT_PCM16;
    exinfo.defaultfrequency = 48000;
    exinfo.length = (uint)(exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels);

    rawData = new short[exinfo.length / sizeof(short)];

    Debug.Log("createSound: " + lowLevelSystem.createSound(new byte[exinfo.length], FMOD.MODE.LOOP_NORMAL | FMOD.MODE.OPENUSER, ref exinfo, out recorded));
    Debug.Log("getDriver: " + lowLevelSystem.getDriver(out driverId));
    Debug.Log("recordStart: " + lowLevelSystem.recordStart(driverId, recorded, true));

    rawDataPtr = Marshal.AllocCoTaskMem((int)exinfo.length);
}

Inside the OnAudioFilterRead method I’m trying to access the sounds data (I’m assuming this would be the latest recorded output from FMOD).
But all I get is some crackling sound (like some gears grinding on each other)

void OnAudioFilterRead(float[] data, int channels)
{
    if (recorded != null)
    {
        Debug.Log("readData: " + recorded.readData(rawDataPtr, (uint)(data.Length * sizeof(short)), out readBytes));
        getRawPtr = recorded.getRaw();
        Marshal.Copy(getRawPtr, rawData, 0, rawData.Length);
        if (rawData != null)
            for (int i = 0; i < data.Length; i++)
                if (i < rawData.Length)
                    data[i] = (float)rawData[i] / (float)short.MaxValue * (float)gain;

    }
}

I’m thankful for any help.

Kind Regards
Tobias

The recording API is for recording microphone input, not recording the output of the FMOD mixer.

The correct way to capture the mixer output is write a custom DSP that can inserted onto the head of the master channel group and passes through the mixer signal while copying it into a side buffer. Your OnAudioFilterRead() function can later pull from the side buffer.

Ah, my bad. Then I’ve missed that info somewhere reading the API.
Thanks for the advice, Nicholas. I’m gonna head for the DSP then and check how far I’ll come with that approach