I’m creating a sound like this:
int NumChannels, SampleFrequency; // Passed in as function args.
FMOD::Studio::System* StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
check(StudioSystem != nullptr);
FMOD::System * CoreSystem = nullptr;
const FMOD_RESULT GetCoreSystemResult = System->getCoreSystem(&CoreSystem);
check(CoreSystem != nullptr);
check(GetCoreSystemResult == FMOD_OK);
FMOD::Sound* Result = nullptr;
FMOD_MODE Mode = FMOD_LOOP_NORMAL | FMOD_OPENUSER | FMOD_CREATESTREAM | FMOD_3D | FMOD_3D_WORLDRELATIVE;
FMOD_CREATESOUNDEXINFO SoundInfo;
FMemory::Memset(SoundInfo, 0);
SoundInfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
SoundInfo.numchannels = NumChannels;
SoundInfo.format = FMOD_SOUND_FORMAT_PCM16;
SoundInfo.decodebuffersize = 1024 * 3; // This is from a sample, so I trust it to be reasonable.
SoundInfo.defaultfrequency = SampleFrequency;
SoundInfo.length = sizeof(int16) * SampleFrequency;
SoundInfo.pcmreadcallback = OnVoiceChatSoundReadDataCallback;
SoundInfo.userdata = static_cast<void*>(&UserChatInfo);
const FMOD_RESULT MakeSoundResult = CoreSystem->createSound(nullptr, Mode, &SoundInfo, &Result);
check(MakeSoundResult == FMOD_OK);
Then playing it like this:
FMOD::Channel* Channel = nullptr;
const FMOD_RESULT PlaySoundResult = CoreSystem->playSound(UserInfo.Sound, nullptr, false, &UserInfo.Channel);
check(PlaySoundResult == FMOD_OK);
FMOD_MODE Mode = 0;
const FMOD_RESULT GetVoiceChannelModeResult = Channel->getMode(&Mode);
check(GetVoiceChannelModeResult == FMOD_OK);
constexpr FMOD_MODE SettingsToNull = FMOD_2D | FMOD_3D | FMOD_3D_CUSTOMROLLOFF | FMOD_3D_INVERSEROLLOFF | FMOD_3D_INVERSETAPEREDROLLOFF | FMOD_3D_LINEARROLLOFF | FMOD_3D_LINEARSQUAREROLLOFF;
constexpr FMOD_MODE SettingsToSet = FMOD_3D | FMOD_3D_INVERSEROLLOFF;
Mode = Mode & ~SettingsToNull;
Mode = Mode | SettingsToSet;
const FMOD_RESULT SetVoiceChannelModeResult = ChannelToSetUp->setMode(Mode);
check(SetVoiceChannelModeResult == FMOD_OK);
float MinDistance = 0.0f;
float MaxDistance = 10000.0f; // Class settings - set in metres.
const FMOD_RESULT SetMinMaxDistanceResult = Channel->set3DMinMaxDistance(MinDistance, MaxDistance);
check(SetMinMaxDistanceResult == FMOD_OK);
uint8 VoipChannelPriority = 0;
const FMOD_RESULT SetPriorityResult = UserInfo.Channel->setPriority(VoipChannelPriority);
check(SetPriorityResult == FMOD_OK);
But I’m not able to hear the sound.
I’ve grabbed and logged every bit of information I can, checking that the modes and priorities are where I expect them to be, that the sound’s state is FMOD_OPENSTATE_PLAYING
, that the channel isn’t virtual, paused, and has a volume set to 1, that the listener’s position and the sound source’s position is what I expect it to be. I’m totally confused. The audibility of the channel seems to be 0.0, when I read it .My only real clue is this:
int NumDsps = 0;
const FMOD_RESULT GetDSPNumResult = Channel->getNumDSPs(&NumDsps);
check(GetDSPNumResult == FMOD_OK);
for(int i=0;i<NumDsps;++i)
{
FMOD::DSP* Dsp = nullptr;
const FMOD_RESULT GetDSPResult = Channel->getDSP(i, &Dsp);
check(GetDSPResult == FMOD_OK);
check(Dsp != nullptr);
FMOD_DSP_TYPE Type = FMOD_DSP_TYPE_UNKNOWN;
const FMOD_RESULT GetDSPTypeResult = Dsp->getType(&Type);
check(GetDSPTypeResult == FMOD_OK);
const FMOD_RESULT SetMeteringEnabledResult = Dsp->setMeteringEnabled(true,true);
check(SetMeteringEnabledResult == FMOD_OK);
if (Type == FMOD_DSP_TYPE_FADER)
{
float FaderValue = 0.0f;
constexpr int BufferSize = 256;
char GainValueStr[BufferSize];
FMemory::Memset(GainValueStr, 0);
const FMOD_RESULT GetGainResult = Dsp->getParameterFloat(FMOD_DSP_FADER_GAIN,&FaderValue,GainValueStr, BufferSize);
check(GetGainResult == FMOD_OK);
UE_LOG(LogTemp, Log, TEXT("DSP[%d]: Fader. Gain value=%3.2f"), i, FaderValue);
FMemory::Memset(GainValueStr, 0);
void* ResultPtr = nullptr;
unsigned int ResultSize = 0;
const FMOD_RESULT GetOverallGainResult = Dsp->getParameterData(FMOD_DSP_FADER_OVERALL_GAIN, &ResultPtr, &ResultSize, GainValueStr, BufferSize);
check(GetOverallGainResult == FMOD_OK);
FMOD_DSP_PARAMETER_OVERALLGAIN* DataPtr = static_cast<FMOD_DSP_PARAMETER_OVERALLGAIN*>(ResultPtr);
UE_LOG(LogTemp, Log,TEXT("DSP[%d]: Overall gain: Linear=%3.2f, Additive=%3.2f"), i, DataPtr->linear_gain, DataPtr->linear_gain_additive);
}
FMOD_DSP_METERING_INFO InputInfo, OutputInfo;
const FMOD_RESULT GetDSPMeteringResult = Dsp->getMeteringInfo(&InputInfo, &OutputInfo);
check(GetDSPMeteringResult == FMOD_OK);
const auto GetPeakLevel = [](const FMOD_DSP_METERING_INFO& Info)
{
float Max = 0.0f;
for (short i = 0; i < Info.numchannels; ++i)
{
Max = FMath::Max(Max, Info.peaklevel[i]);
}
return Max;
};
UE_LOG(LogTemp, Log, TEXT(" DSP[%d]: DSP type=%d ; In=%3.2f Out=%3.2f"), i, Type, GetPeakLevel(InputInfo), GetPeakLevel(OutputInfo));
}
Using a generated white-noise sound I can see the data going in to the system and see that the OnVoiceChatSoundReadDataCallback
is being called regularly to read the sound data. However, this bit of logging reveals:
- 1 DSP - a fader
- The gain on the fader is set to 0.0 (which is, I believe dB)
- Overall linear gain is 1.0, with additive gain at 0.0f.
- Peak level going into the fader is ~0.98 (but varies from 0.96 to 0.99).
- Peak level coming out of the fader is always 0.0. (Why?)
I tried experimenting setting the gain on the fader to 1.0, just in case. In that case the overall gain is 1.12 linear, but the output is still 0.0.
I’m at a loss with where to go next with this investigation. Can anyone help?