I made a voice chat mod for some game, and recently my users have noticed cracklng in others voice when count of speaking players > 1, no matter how sound loud or far away, crackling always there if more than one player speaking at the same time in hear zone. I tried to use limiter dsp on voice channel group - no effect, tried to decrease volume of sound / channel group - still no effect. For example, if there are two players speaking and i set volume of first player voice to 0 (muted him), the sound i hear becomes normal without crackling until i restore first player’s voice sound volume
im using opus to encode and decode data from microphone, and FMOD_OPENUSER | FMOD_CREATESTREAM | FMOD_3D
with pcmreadcallback
to push audio stream:
`exinfo.pcmreadcallback = (FMOD_SOUND* sound, void data, unsigned int datalen){
void* userdata = nullptr;
((FMOD::Sound*)sound)->getUserData(&userdata);
if(!userdata){
return FMOD_OK;
}
auto v = (Storage::PlayerVoice*)userdata;
std::lock_guard<std::mutex> lock(v->bufferMutex);
unsigned int totalCopied = 0;
auto dest = (unsigned char*) data;
while (totalCopied < datalen) {
if (v->buffer.empty()) {
memset(dest + totalCopied, 0, datalen - totalCopied);
break;
}
auto& front = v->buffer.front();
size_t toCopy = front.size() - v->readOffset;
size_t needed = datalen - totalCopied;
size_t chunk = std::min(toCopy, needed);
memcpy(dest + totalCopied, front.data() + v->readOffset, chunk);
totalCopied += chunk;
v->readOffset += chunk;
if (v->readOffset >= front.size()) {
v->buffer.pop_front();
v->readOffset = 0;
}
}
return FMOD_OK;
};`
settings:
FMOD_CREATESOUNDEXINFO exinfo = {};
exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
exinfo.numchannels = 1;
exinfo.format = FMOD_SOUND_FORMAT_PCM16;
exinfo.defaultfrequency = 48000;
exinfo.length = 0xFFFFFFFF;|
exinfo.decodebuffersize = 9600;
buffer has 960 frames and 48000 sample rate before encoding with opus, opus params:
opus_encoder_ctl(module->encoder, OPUS_SET_BITRATE(32000));
opus_encoder_ctl(module->encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
opus_encoder_ctl(module->encoder, OPUS_SET_APPLICATION(OPUS_APPLICATION_VOIP));
opus_encoder_ctl(module->encoder, OPUS_SET_INBAND_FEC(1));
opus_encoder_ctl(module->encoder, OPUS_SET_PACKET_LOSS_PERC(10));
opus_encoder_ctl(module->encoder, OPUS_SET_COMPLEXITY(6));
opus_encoder_ctl(module->encoder, OPUS_SET_DTX(1));
some additional code:
void __forceinline SoundSystem::initializeVoicePlayerBuffer(Storage::PlayerVoice* player) const {
if (!player->isSoundInitialized) {
storage->system->playSound(player->sound, storage->voiceChannel, true, &player->channel);
player->channel->set3DAttributes(&player->position, nullptr);
player->channel->set3DSpread(90.f);
player->channel->set3DMinMaxDistance(3.f, 300.f);
player->channel->setVolume(player->isMuted ? 0.f : calculateVolumeBasedOnDistance(player->position, storage->currentPos, 3.f, 30.f));
player->isSoundInitialized = true;
}
}
first video (just sound): the problem (two players talking) https://drive.google.com/file/d/1Jx0p-4Vl7x5tf_Cfe84e_zDNSjAikI_I/view?usp=sharing
second video (just sound too): when first player is muted and second player still talking https://drive.google.com/file/d/1EJJuq2rE_Hf12sTJpCZJ7J5CskiCO7n6/view?usp=sharing