0
0

Hi,

In FMOD features was written:

FMOD Ex now supports super low latency recording, processing and output through a new recording engine. Via ASIO the recording->DSP->playback latency can be as low as 1-3ms! This is great for realtime processing and playback of recorded audio.

But I didn’t find any example or description how to do this.
So I made:
0. set DSP buffer size to 32samples * 2buffers, samplerate is 44100
1. recording to sound and insert DSP in this channel (volume 0.0)
2. playback sound and insert DSP in that channel (volume 1.0)
3. In recording callback I copy from input to buffer
4. In playback callback I copy from buffer to output
5. Start this with ASIO mode on Prodigy 7.1 and record direct & played sound and got difference 600-650 samples = 13-15 ms.

I wonder what did I make wrong?????

Here is creation part:

            {
                bool created = false;
                unsigned int version;
                FMOD::System    *lsystem = NULL;
                if (FMOD::System_Create(&lsystem) == FMOD_OK && lsystem->getVersion(&version) == FMOD_OK && version >= FMOD_VERSION) {
                    if (lsystem->setOutput((FMOD_OUTPUTTYPE)cmd.param.createcmd.subsystem) == FMOD_OK) { // actually ASIO
                        if (lsystem->setDSPBufferSize(cmd.param.createcmd.bufsize,cmd.param.createcmd.bufnum) == FMOD_OK) { // Actually 32 samples 2 buffers
                            //if (lsystem->setDriver(cmd.param.createcmd.device) == FMOD_OK) {
                                //lsystem->setSoftwareFormat(44100,FMOD_SOUND_FORMAT_PCMFLOAT,FMOD_SPEAKERMODE_STEREO,0,FMOD_DSP_RESAMPLER_LINEAR);
                                if (lsystem->init(8, FMOD_INIT_NORMAL, 0) == FMOD_OK) {
                                    //int lsamplerate;
                                    //FMOD_SOUND_FORMAT lsoundformat;
                                    //lsystem->getSoftwareFormat(&lsamplerate,&lsoundformat,NULL,NULL,NULL,NULL);
                                    FMOD_CREATESOUNDEXINFO exinfo;
                                    memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
                                    exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);
                                    exinfo.numchannels      = 2;
                                    exinfo.format           = FMOD_SOUND_FORMAT_PCM16;
                                    exinfo.defaultfrequency = 44100;
                                    exinfo.length           = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 2;
                                    soundlen = exinfo.defaultfrequency*2;   // Samples
                                    res = lsystem->createSound(0, FMOD_2D | FMOD_SOFTWARE | FMOD_OPENUSER | FMOD_LOOP_NORMAL, &exinfo, &sound);
                                    res = lsystem->createSound(0, FMOD_2D | FMOD_SOFTWARE | FMOD_OPENUSER | FMOD_LOOP_NORMAL, &exinfo, &playsound);
                                    if (res == FMOD_OK) {
                                        res = lsystem->recordStart(cmd.param.createcmd.device, sound, true);  // Selected device from FMOD enumeration
                                        if (res == FMOD_OK) {
                                            res = lsystem->playSound(FMOD_CHANNEL_REUSE, sound, false, &playchannel);
                                            playchannel->setVolume(1.0);
                                            usleep(5000);
                                            res = lsystem->playSound(FMOD_CHANNEL_REUSE, sound, false, &channel);
                                            channel->setVolume(0.0);

                                            unsigned int lsize;
                                            sound->getLength(&lsize,FMOD_TIMEUNIT_PCM);

                                            FMOD_DSP_DESCRIPTION  dspdesc;
                                            {
                                                memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION));
                                                strcpy(dspdesc.name, "playback DSP unit");
                                                dspdesc.channels     = 2;                   // USE 2 USE 2 !!!
                                                dspdesc.read         = playbackDSPCallback;
                                                dspdesc.userdata     = (void *)this;

                                                res = lsystem->createDSP(&dspdesc, &playdsp);
                                                res = playchannel->addDSP(playdsp,NULL);
                                            }
                                            {
                                                memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION));
                                                strcpy(dspdesc.name, "record DSP unit");
                                                dspdesc.channels     = 2;                   // USE 2 USE 2 !!!
                                                dspdesc.read         = recordDSPCallback;
                                                dspdesc.userdata     = (void *)this;

                                                res = lsystem->createDSP(&dspdesc, &record);
                                                res = channel->addDSP(record,NULL);
                                            }

                                            created = true;
                                        }
                                    }
                                }
                            //}
                        }
                    }
                }
                if (created) {
                    system = lsystem;
                    recordid = cmd.param.createcmd.device;
                } else if (lsystem != NULL) {
                    lsystem->close();
                    lsystem->release();
                }
            }

And here is 2 callbacks fos DSPs:
FMOD_RESULT
Recorder::recordDSPCallback(FMOD_DSP_STATE dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels) {
FMOD::DSP
pdsp = (FMOD::DSP)dsp_state->instance;
void *pdata = NULL;
if (pdsp->getUserData(&pdata) == FMOD_OK && pdata != NULL) {
Recorder
precorder = (Recorder)pdata;
int nsamples = length
inchannels;
//qDebug("In DSP: Length: %d\n",length);
memcpy(outbuffer,inbuffer,nsamples4);
int remined = 8192 – precorder->playbufsize;
if (remined >= nsamples) {
precorder->playbufmutex.lock();
memcpy(&precorder->playbuf[precorder->playbufsize],inbuffer,nsamples
4);
precorder->playbufsize += nsamples;
precorder->playbufmutex.unlock();
}
//memset(outbuffer,0,lengthinchannels4);
}
return FMOD_OK;
}

FMOD_RESULT
Recorder::playbackDSPCallback(FMOD_DSP_STATE dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels) {
FMOD::DSP
pdsp = (FMOD::DSP)dsp_state->instance;
void *pdata = NULL;
if (pdsp->getUserData(&pdata) == FMOD_OK && pdata != NULL) {
Recorder
precorder = (Recorder)pdata;
int nsamples = length
inchannels;
//qDebug("In DSP: Length: %d\n",length);
//memcpy(outbuffer,inbuffer,lengthinchannels4);
if (nsamples < precorder->playbufsize) {
precorder->playbufmutex.lock();
memcpy(outbuffer,precorder->playbuf,nsamples4);
memmove(precorder->playbuf,&precorder->playbuf[nsamples],(8192-nsamples)
4);
precorder->playbufsize -= nsamples;
precorder->playbufmutex.unlock();
} else {
memset(outbuffer,0,nsamples*4);
}
}
return FMOD_OK;
}

  • You must to post comments
Showing 0 results
Your Answer

Please first to submit.