I create two sounds, one to record pcm from a microphone and another to send pcm to a speaker. The first sound works fine - I include it’s initialization below just for context. The initialization for both is:
// SOUND 1
memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
exinfo.numchannels = recordchannels;
exinfo.format = FMOD_SOUND_FORMAT_PCM16;
exinfo.defaultfrequency = recordrate;
exinfo.length = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 1;
result = Asystem->createSound(0, FMOD_LOOP_NORMAL | FMOD_OPENUSER, &exinfo, &sound);
ERRCHECK(result);
result = Asystem->recordStart(DEVICE_INDEX, sound, true);
ERRCHECK(result);
result = sound->getLength(&soundlength, FMOD_TIMEUNIT_PCM);
ERRCHECK(result);
// SOUND 2
// Note: I use a different exinfo (exinfo2) for sound2. Is this correct practice?
memset(&exinfo2, 0, sizeof(FMOD_CREATESOUNDEXINFO));
exinfo2.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); // Required.
exinfo2.numchannels = 2; // Number of channels in the sound.
exinfo2.defaultfrequency = 1024; // Default playback rate of sound.
exinfo2.decodebuffersize = 1024; // Chunk size of stream update in samples. This will be the amount of data passed to the user callback.
exinfo2.length = exinfo2.defaultfrequency * exinfo2.numchannels * sizeof(signed short) * 1; // Length of PCM data in bytes of whole song (for Sound::getLength)
exinfo2.format = FMOD_SOUND_FORMAT_PCM16; // Data format of sound.
exinfo2.pcmreadcallback = pcmreadcallback; // User callback for reading.
result = Asystem->createSound(0, FMOD_OPENUSER, &exinfo2, &sound2);
ERRCHECK(result);
result = Asystem->playSound(sound2, 0, true, &channel2);
ERRCHECK(result);
channel2->setMode(FMOD_LOOP_NORMAL);
channel2->setPosition(0, FMOD_TIMEUNIT_MS); // this flushes the buffer to ensure the loop mode takes effect
channel2->setPaused(false);
I implement the pcmreadcallback function as:
FMOD_RESULT F_CALLBACK pcmreadcallback(FMOD_SOUND* sound2, void *data, unsigned int datalen)
{
signed short *stereo16bitbuffer = (signed short *)data;
for (unsigned int sample = 0; sample < datalen / 4; sample++) //16bit stereo (4 bytes per sample)
{
*stereo16bitbuffer++ = (signed short) speaker_buff[sample] * 32767.0f; // left channel
*stereo16bitbuffer++ = (signed short) speaker_buff[sample] * 32767.0f; // right channel
}
return FMOD_OK;
}
The callback function stops being called at some point. I’d like to send ~1024 (newly generated) values to the speaker every frame. Am I making a mistake in how to do this, and if so, where?