Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions src/engine/audio/Audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ namespace Audio {
// in a frame, it means it sould be destroyed.
struct entityLoop_t {
bool addedThisFrame;
bool persistent;
std::shared_ptr<LoopingSound> sound;
sfxHandle_t newSfx;
sfxHandle_t oldSfx;
Expand Down Expand Up @@ -148,7 +149,7 @@ namespace Audio {
UpdateListenerGain();

for (auto &loop : entityLoops) {
loop = {false, nullptr, -1, -1};
loop = {false, false, nullptr, -1, -1};
}

return true;
Expand All @@ -164,7 +165,7 @@ namespace Audio {
if (loop.sound) {
loop.sound->Stop();
}
loop = {false, nullptr, -1, -1};
loop = {false, false, nullptr, -1, -1};
}

StopMusic();
Expand Down Expand Up @@ -194,21 +195,25 @@ namespace Audio {
}

for (int i = 0; i < MAX_GENTITIES; i++) {
auto& loop = entityLoops[i];
entityLoop_t& loop = entityLoops[i];
if (loop.sound and not loop.addedThisFrame) {
// The loop wasn't added this frame, that means it has to be removed.
loop.sound->FadeOutAndDie();
loop = {false, nullptr, -1, -1};

if ( loop.persistent ) {
loop.sound->soundGain = 0;
} else {
// The loop wasn't added this frame, that means it has to be removed.
loop.sound->FadeOutAndDie();
loop = { false, false, nullptr, -1, -1 };
}
} else if (loop.oldSfx != loop.newSfx) {
// The last sfx added in the frame is not the current one being played
// To mimic the previous sound system's behavior we sart playing the new one.
loop.sound->FadeOutAndDie();

int newSfx = loop.newSfx;
loop = {false, nullptr, -1, -1};
bool persistent = loop.persistent;
loop = {false, false, nullptr, -1, -1};

AddEntityLoopingSound(i, newSfx);
AddEntityLoopingSound(i, newSfx, persistent);
}
}

Expand All @@ -223,7 +228,7 @@ namespace Audio {
loop.addedThisFrame = false;
// if we are the unique owner of a loop pointer, then it means it was stopped, free it.
if (loop.sound.use_count() == 1) {
loop = {false, nullptr, -1, -1};
loop = {false, false, nullptr, -1, -1};
}
}

Expand Down Expand Up @@ -288,7 +293,7 @@ namespace Audio {
AddSound(GetLocalEmitter(), std::make_shared<OneShotSound>(Sample::FromHandle(sfx)), 1);
}

void AddEntityLoopingSound(int entityNum, sfxHandle_t sfx) {
void AddEntityLoopingSound(int entityNum, sfxHandle_t sfx, bool persistent) {
if (not initialized or not Sample::IsValidHandle(sfx) or not IsValidEntity(entityNum)) {
return;
}
Expand All @@ -302,6 +307,7 @@ namespace Audio {
AddSound(GetEmitterForEntity(entityNum), loop.sound, 1);
}
loop.addedThisFrame = true;
loop.persistent = persistent;

// We remember what is the last sfx asked because cgame expects the sfx added last in the frame to be played
loop.newSfx = sfx;
Expand Down Expand Up @@ -343,7 +349,7 @@ namespace Audio {

StopMusic();
music = std::make_shared<LoopingSound>(loopingSample, leadingSample);
music->SetVolumeModifier(musicVolume);
music->volumeModifier = &musicVolume;
AddSound(GetLocalEmitter(), music, 1);
}

Expand Down Expand Up @@ -381,7 +387,7 @@ namespace Audio {
}
}

streams[streamNum]->SetGain(volume);
streams[streamNum]->soundGain = volume;

AudioData audioData(rate, width, channels, (width * numSamples * channels),
reinterpret_cast<const char*>(data));
Expand Down
2 changes: 1 addition & 1 deletion src/engine/audio/Audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ namespace Audio {
void StartSound(int entityNum, Vec3 origin, sfxHandle_t sfx);
void StartLocalSound(int entityNum);

void AddEntityLoopingSound(int entityNum, sfxHandle_t sfx);
void AddEntityLoopingSound(int entityNum, sfxHandle_t sfx, bool persistent);
void ClearAllLoopingSounds();
void ClearLoopingSoundsForEntity(int entityNum);

Expand Down
12 changes: 6 additions & 6 deletions src/engine/audio/Emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ namespace Audio {
Emitter::~Emitter() = default;

void Emitter::SetupSound(Sound& sound) {
sound.GetSource().SetReferenceDistance(120.0f);
sound.source->SetReferenceDistance(120.0f);
InternalSetupSound(sound);
UpdateSound(sound);
}
Expand All @@ -278,7 +278,7 @@ namespace Audio {
}

void EntityEmitter::UpdateSound(Sound& sound) {
AL::Source& source = sound.GetSource();
AL::Source& source = *sound.source;

if (entityNum == listenerEntity) {
MakeLocal(source);
Expand All @@ -288,7 +288,7 @@ namespace Audio {
}

void EntityEmitter::InternalSetupSound(Sound& sound) {
AL::Source& source = sound.GetSource();
AL::Source& source = *sound.source;

Make3D(source, entities[entityNum].position, entities[entityNum].velocity);
}
Expand All @@ -306,13 +306,13 @@ namespace Audio {
}

void PositionEmitter::UpdateSound(Sound& sound) {
AL::Source& source = sound.GetSource();
AL::Source& source = *sound.source;

Make3D(source, position, origin);
}

void PositionEmitter::InternalSetupSound(Sound& sound) {
AL::Source& source = sound.GetSource();
AL::Source& source = *sound.source;

Make3D(source, position, origin);
}
Expand All @@ -334,7 +334,7 @@ namespace Audio {
}

void LocalEmitter::InternalSetupSound(Sound& sound) {
AL::Source& source = sound.GetSource();
AL::Source& source = *sound.source;

MakeLocal(source);
}
Expand Down
95 changes: 25 additions & 70 deletions src/engine/audio/Sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,18 @@ namespace Audio {

for (int i = 0; i < nSources; i++) {
if (sources[i].active) {
auto sound = sources[i].usingSound;
std::shared_ptr<Sound> sound = sources[i].usingSound;

// Update and Emitter::UpdateSound can call Sound::Stop
if (not sound->IsStopped()) {
if ( sound->playing ) {
sound->Update();
}

if (not sound->IsStopped()) {
sound->GetEmitter()->UpdateSound(*sound);
if ( sound->playing ) {
sound->emitter->UpdateSound(*sound);
}

if (sound->IsStopped()) {
if ( !sound->playing ) {
sources[i].active = false;
sources[i].usingSound = nullptr;
}
Expand Down Expand Up @@ -126,7 +126,7 @@ namespace Audio {
if (source) {
// Make the source forget if it was a "static" or a "streaming" source.
source->source.ResetBuffer();
sound->SetEmitter(emitter);
sound->emitter = emitter;
sound->AcquireSource(source->source);
source->usingSound = sound;
source->priority = priority;
Expand Down Expand Up @@ -188,40 +188,6 @@ namespace Audio {
playing = false;
}

bool Sound::IsStopped() {
return not playing;
}

void Sound::SetPositionalGain(float gain) {
positionalGain = gain;
}

void Sound::SetSoundGain(float gain) {
soundGain = gain;
}

float Sound::GetCurrentGain() {
return currentGain;
}

void Sound::SetVolumeModifier(const Cvar::Range<Cvar::Cvar<float>>& volumeMod)
{
this->volumeModifier = &volumeMod;
}

float Sound::GetVolumeModifier() const
{
return volumeModifier->Get();
}

void Sound::SetEmitter(std::shared_ptr<Emitter> emitter) {
this->emitter = emitter;
}

std::shared_ptr<Emitter> Sound::GetEmitter() {
return emitter;
}

void Sound::AcquireSource(AL::Source& source) {
this->source = &source;

Expand All @@ -231,19 +197,15 @@ namespace Audio {
emitter->SetupSound(*this);
}

AL::Source& Sound::GetSource() {
return *source;
}

// Set the gain before the source is started to avoid having a few milliseconds of very loud sound
void Sound::FinishSetup() {
currentGain = positionalGain * soundGain * SliderToAmplitude(GetVolumeModifier());
currentGain = positionalGain * soundGain * SliderToAmplitude(volumeModifier->Get());
source->SetGain(currentGain);
}

void Sound::Update() {
// Fade the Gain update to avoid "ticking" sounds when there is a gain discontinuity
float targetGain = positionalGain * soundGain * SliderToAmplitude(GetVolumeModifier());
float targetGain = positionalGain * soundGain * SliderToAmplitude(volumeModifier->Get());

//TODO make it framerate independent and fade out in about 1/8 seconds ?
if (currentGain > targetGain) {
Expand All @@ -267,15 +229,15 @@ namespace Audio {

void OneShotSound::SetupSource(AL::Source& source) {
source.SetBuffer(sample->GetBuffer());
SetSoundGain(GetVolumeModifier());
soundGain = volumeModifier->Get();
}

void OneShotSound::InternalUpdate() {
if (GetSource().IsStopped()) {
if ( source->IsStopped() ) {
Stop();
return;
}
SetSoundGain(GetVolumeModifier());
soundGain = volumeModifier->Get();
}

// Implementation of LoopingSound
Expand All @@ -289,7 +251,7 @@ namespace Audio {

void LoopingSound::FadeOutAndDie() {
fadingOut = true;
SetSoundGain(0.0f);
soundGain = 0.0f;
}

void LoopingSound::SetupSource(AL::Source& source) {
Expand All @@ -298,23 +260,23 @@ namespace Audio {
} else {
SetupLoopingSound(source);
}
SetSoundGain(GetVolumeModifier());
soundGain = volumeModifier->Get();
}

void LoopingSound::InternalUpdate() {
if (fadingOut and GetCurrentGain() == 0.0f) {
if (fadingOut and currentGain == 0.0f) {
Stop();
}

if (not fadingOut) {
if (leadingSample) {
if (GetSource().IsStopped()) {
SetupLoopingSound(GetSource());
GetSource().Play();
if ( source->IsStopped() ) {
SetupLoopingSound( *source );
source->Play();
leadingSample = nullptr;
}
}
SetSoundGain(GetVolumeModifier());
soundGain = volumeModifier->Get();
}
}

Expand All @@ -335,32 +297,25 @@ namespace Audio {
}

void StreamingSound::InternalUpdate() {
AL::Source& source = GetSource();

while (source.GetNumProcessedBuffers() > 0) {
source.PopBuffer();
while ( source->GetNumProcessedBuffers() > 0 ) {
source->PopBuffer();
}

if (source.GetNumQueuedBuffers() == 0) {
if ( source->GetNumQueuedBuffers() == 0 ) {
Stop();
}
}

//TODO somehow try to catch back when data is coming faster than we consume (e.g. capture data)
void StreamingSound::AppendBuffer(AL::Buffer buffer) {
if (IsStopped()) {
if ( !playing ) {
return;
}

AL::Source& source = GetSource();
source.QueueBuffer(std::move(buffer));
source->QueueBuffer(std::move(buffer));

if (source.IsStopped()) {
source.Play();
if ( source->IsStopped() ) {
source->Play();
}
}

void StreamingSound::SetGain(float gain) {
SetSoundGain(gain);
}
}
Loading