FMOD Voice Recording access to real-time playable bytes/data (C++)

Hello,

I’ve been using FMOD recently and have already looked at the record.cpp example.

However, in order to capture the audio data, it advises to use FMOD::sound::lock and FMOD::sound::unlock in sort of an external way, even though recordStart is non-blocking.

How exactly would I fetch the bytes in a synchronized way, so that there is no popping or artifacts? I’m aware that FMOD is internally using circular buffers as well. Is there no callback I could use? I’ve tried FMOD::System::CreateStream and tried to point recordStart to there and just use PCMReadCallback, which then complains about:

“[ERR] SystemI::recordStart : Invalid sound, must be an FMOD::Sound with positive length created as FMOD_CREATESAMPLE.”, even when I do fulfill everything that FMOD complains about.

Could anyone help? Also, I’m using C++ to do this.

Thank you!

Hi,

Thank you for sharing the information.

It seems that lock and unlock are unable to access the audio buffer, you could consider using a custom DSP to capture the audio buffer directly and add it to your recording channel by using ChannelControl::addDSP.

I will share an example script below as a reference:

FMOD_DSP_DESCRIPTION tap{};
tap.pluginsdkversion = FMOD_PLUGIN_SDK_VERSION;
tap.numinputbuffers = 1;    
tap.numoutputbuffers = 1;   
tap.numparameters = 0;  

tap.process = [](FMOD_DSP_STATE *dsp_state, unsigned int numsamples, const    FMOD_DSP_BUFFER_ARRAY *inbufferarray,
                 FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op) -> FMOD_RESULT {
    if (op == FMOD_DSP_PROCESS_PERFORM) {
        if (inputsidle) {
            // If input is idle, optionally clear the output buffer to silence
            memset(outbufferarray->buffers[0], 0, numsamples * sizeof(float));
            return FMOD_OK;
        }

        // Process audio samples
        for (unsigned int i = 0; i < numsamples; ++i) {
            outbufferarray->buffers[0][i] = inbufferarray->buffers[0][i] * 0.5f; // Reduce amplitude to prevent clipping
        }
    }

    return FMOD_OK;
};

    FMOD::DSP *myDSP;
    result = system->createDSP(&tap, &myDSP);
    ERRCHECK(result);

    result = myRecordingChannel->addDSP(0, myDSP);  // Add DSP to the channel
    ERRCHECK(result);

Unfortunately, FMOD does not support using PCMReadCallback for recording since recordStart requires a sound object created with FMOD_CREATESAMPLE, which is incompatible with creatStream that is meant for streaming playback.

Hope this helps, let me know if you have any questions.

Hi, what I essentially want is to just capture a real-time buffer in a way that I can just use sendto() on it using a simple UDP socket and just fire-and-forget it so that the audio (my voice) can be replayed in real-time on the other side, allowing for a simple voice cha functionality with FMOD.

Oh, and thank you for your response sir.