Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EFX environment and reverb effect. Closes #697. #702

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 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
8 changes: 8 additions & 0 deletions rwengine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ set(RWENGINE_SOURCES
src/audio/SoundManager.hpp
src/audio/SoundSource.cpp
src/audio/SoundSource.hpp
src/audio/EffectSlot.hpp
src/audio/EffectSlot.cpp
src/audio/SoundEffect.cpp
src/audio/SoundEffect.hpp
src/audio/ReverbEffect.cpp
src/audio/ReverbEffect.hpp
src/audio/OpenAlExtensions.hpp
src/audio/OpenAlExtensions.cpp

src/core/Logger.cpp
src/core/Logger.hpp
Expand Down
39 changes: 39 additions & 0 deletions rwengine/src/audio/EffectSlot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "EffectSlot.hpp"
#include "SoundEffect.hpp"
#include "OpenAlExtensions.hpp"

EffectSlot::EffectSlot() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using an initialization list

alGenAuxiliaryEffectSlots(1, &slotId);

effect = nullptr;
Copy link

@ghost ghost Feb 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default member initializer

gain = 1.0f;
slotNumber = 0;
created = alGetError() == AL_NO_ERROR;
}

EffectSlot::~EffectSlot() {
alDeleteAuxiliaryEffectSlots(1, &slotId);
}

bool EffectSlot::attachEffect(std::shared_ptr<SoundEffect> effect) {
alAuxiliaryEffectSloti(slotId, AL_EFFECTSLOT_EFFECT, effect->getId());

if (alGetError() != AL_NO_ERROR) {
return false;
}

this->effect = std::move(effect);

return true;
}

bool EffectSlot::detachEffect() {
alAuxiliaryEffectSloti(slotId, AL_EFFECTSLOT_EFFECT, 0);
this->effect = nullptr;

return alGetError() == AL_NO_ERROR;
}

void EffectSlot::setGain(float gain) {
alAuxiliaryEffectSlotf(slotId, AL_EFFECTSLOT_GAIN, this->gain = gain);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split a variable assigning and a function invocation

}
62 changes: 62 additions & 0 deletions rwengine/src/audio/EffectSlot.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef EFFECTSLOT_H
#define EFFECTSLOT_H

#include <al.h>

#include <memory>

class SoundEffect;

/**
* Effect slot.
*
* Many sound sources can be attached to one slot.
* Different effects can be binded to this (e.g reverb, delay).
*/
class EffectSlot {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have problems with understanding connection between this class and SoundEffect. I mean where is EffectSlot created, used, deleted. Because instances of EffectSlot and SoundEffect are in relation 1 to 1. I think solution when one of them contains/owns instances of second would be good enough.

public:
EffectSlot();
~EffectSlot();

/**
* Attach effect to this slot.
*
* @param sound effect (e.g reverb, delay)
* @return true if effect attached successfully, false otherwise
*/
bool attachEffect(std::shared_ptr<SoundEffect> effect);

/**
* Detach current effect from this slot.
* @return true if effect detached successfully, false otherwise
*/
bool detachEffect();

void setGain(float gain);

ALuint getSlotId() const {
return slotId;
}

int getSlotNumber() const {
return slotNumber;
}

private:
/**
* Effect binded to this slot
*/
std::shared_ptr<SoundEffect> effect;

ALuint slotId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or you can set members to defaults right here

/**
* This is flag of successfull slot creation
*/
bool created;
float gain;

/// OpenAL aux slot
int slotNumber;
};

#endif // EFFECTSLOT_H
25 changes: 25 additions & 0 deletions rwengine/src/audio/OpenAlExtensions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "OpenAlExtensions.hpp"

LPALGENEFFECTS alGenEffects = nullptr;
LPALDELETEEFFECTS alDeleteEffects = nullptr;
LPALEFFECTI alEffecti = nullptr;
LPALEFFECTF alEffectf = nullptr;

// Auxiliary slot object
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots = nullptr;
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots = nullptr;
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti = nullptr;
LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf = nullptr;

void initEfxFunctionPointers() {
alGenEffects = reinterpret_cast<LPALGENEFFECTS>(alGetProcAddress("alGenEffects"));
alDeleteEffects = reinterpret_cast<LPALDELETEEFFECTS>(alGetProcAddress("alDeleteEffects"));
alEffecti = reinterpret_cast<LPALEFFECTI>(alGetProcAddress("alEffecti"));
alEffectf = reinterpret_cast<LPALEFFECTF>(alGetProcAddress("alEffectf"));

// aux slot
alGenAuxiliaryEffectSlots = reinterpret_cast<LPALGENAUXILIARYEFFECTSLOTS>(alGetProcAddress("alGenAuxiliaryEffectSlots"));
alDeleteAuxiliaryEffectSlots = reinterpret_cast<LPALDELETEAUXILIARYEFFECTSLOTS>(alGetProcAddress("alDeleteAuxiliaryEffectSlots"));
alAuxiliaryEffectSloti = reinterpret_cast<LPALAUXILIARYEFFECTSLOTI>(alGetProcAddress("alAuxiliaryEffectSloti"));
alAuxiliaryEffectSlotf = reinterpret_cast<LPALAUXILIARYEFFECTSLOTF>(alGetProcAddress("alAuxiliaryEffectSlotf"));
}
26 changes: 26 additions & 0 deletions rwengine/src/audio/OpenAlExtensions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef OPENALEXTENSIONS_HPP
#define OPENALEXTENSIONS_HPP

#include <efx.h>

/**
* Functions to access OpenAL EFX extension
*/

extern LPALGENEFFECTS alGenEffects;
extern LPALDELETEEFFECTS alDeleteEffects;
extern LPALEFFECTI alEffecti;
extern LPALEFFECTF alEffectf;

// Aux slot
extern LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
extern LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
extern LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
extern LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;

/**
* Initialize function pointers
*/
void initEfxFunctionPointers();

#endif // OPENALEXTENSIONS_HPP
44 changes: 44 additions & 0 deletions rwengine/src/audio/ReverbEffect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "ReverbEffect.hpp"
#include "OpenAlExtensions.hpp"
#include <efx.h>

ReverbEffect::ReverbEffect() : SoundEffect (AL_EFFECT_REVERB) {

}


void ReverbEffect::setDensity(float d) {
alEffectf(id, AL_REVERB_DENSITY, d);
}

void ReverbEffect::setDiffusion(float d) {
alEffectf(id, AL_REVERB_DIFFUSION, d);
}

void ReverbEffect::setGain(float g) {
alEffectf(id, AL_REVERB_GAIN, g);
}

void ReverbEffect::setGainHf(float g) {
alEffectf(id, AL_REVERB_GAINHF, g);
}

void ReverbEffect::setDecayTime(float t) {
alEffectf(id, AL_REVERB_DECAY_TIME, t);
}

void ReverbEffect :: setLateReverbGain (float g) {
alEffectf(id, AL_REVERB_LATE_REVERB_GAIN, g);
}

void ReverbEffect :: setLateReverbDelay (float t) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something wrong with a formatting

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it

alEffectf(id, AL_REVERB_LATE_REVERB_DELAY, t);
}

void ReverbEffect :: setAirAbsorptionGainHf (float g) {
alEffectf(id, AL_REVERB_AIR_ABSORPTION_GAINHF, g);
}

void ReverbEffect :: setDecayHfLimit (bool flag) {
alEffecti(id, AL_REVERB_DECAY_HFLIMIT, flag ? AL_TRUE : AL_FALSE);
}
11 changes: 11 additions & 0 deletions rwengine/src/audio/ReverbEffect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef REVERBEFFECT_H
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this file is unneeded.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted.

#define REVERBEFFECT_H


class ReverbEffect
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another ReverbEffect header?

{
public:
ReverbEffect();
};

#endif // REVERBEFFECT_H
22 changes: 22 additions & 0 deletions rwengine/src/audio/ReverbEffect.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef REVERBEFFECT_H
#define REVERBEFFECT_H

#include "SoundEffect.hpp"

class ReverbEffect : public SoundEffect {

public:
ReverbEffect();

void setDensity(float density = 1.0f);
void setDiffusion(float diffusion = 1.0f);
void setGain(float gain = 0.32f);
void setGainHf(float gainHf = 0.89f);
void setDecayTime(float decayTime = 1.49f);
void setLateReverbGain(float lateReverbGain = 1.26f );
void setLateReverbDelay(float lateReverbDelay = 0.011f);
void setAirAbsorptionGainHf(float absorptionGainHf = 0.994f);
void setDecayHfLimit(bool decayHfLimit = true);
};

#endif // REVERBEFFECT_H
5 changes: 5 additions & 0 deletions rwengine/src/audio/Sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ void Sound::setMaxDistance(float maxDist) {
buffer->setMaxDistance(maxDist);
}

void Sound::attachToEffectSlot(const std::shared_ptr<EffectSlot> effectSlot)
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also

buffer->attachToEffectSlot(effectSlot);
}

size_t Sound::getScriptObjectID() const {
return id;
}
3 changes: 3 additions & 0 deletions rwengine/src/audio/Sound.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <memory>

class SoundSource;
class EffectSlot;
struct SoundBuffer;

/// Wrapper for SoundBuffer and SoundSource.
Expand Down Expand Up @@ -42,6 +43,8 @@ struct Sound {

void setMaxDistance(float maxDist);

void attachToEffectSlot(const std::shared_ptr<EffectSlot> effectSlot);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should pass a shared_ptr by const reference or by value and use std::move


size_t getScriptObjectID() const;
};
#endif
11 changes: 11 additions & 0 deletions rwengine/src/audio/SoundBuffer.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include "audio/SoundBuffer.hpp"

#include <rw/types.hpp>
#include <efx.h>

#include "audio/alCheck.hpp"
#include "audio/SoundSource.hpp"
#include "audio/SoundEffect.hpp"
#include "audio/EffectSlot.hpp"

SoundBuffer::SoundBuffer() {
alCheck(alGenSources(1, &source));
Expand Down Expand Up @@ -83,3 +86,11 @@ void SoundBuffer::setGain(float gain) {
void SoundBuffer::setMaxDistance(float maxDist) {
alCheck(alSourcef(source, AL_MAX_DISTANCE, maxDist));
}

void SoundBuffer::attachToEffectSlot(const std::shared_ptr<EffectSlot> slot) {
alCheck(alSource3i(source, AL_AUXILIARY_SEND_FILTER, slot->getSlotId(), slot->getSlotNumber(), AL_FILTER_NULL));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use const reference here

}

void SoundBuffer::detachFromEffectSlot(const std::shared_ptr<EffectSlot> slot) {
alCheck(alSource3i (source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, slot->getSlotNumber(), AL_FILTER_NULL));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above

}
6 changes: 6 additions & 0 deletions rwengine/src/audio/SoundBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include <al.h>
#include <glm/vec3.hpp>

#include <memory>

class EffectSlot;
class SoundSource;

/// OpenAL tool for playing
Expand All @@ -27,6 +30,9 @@ struct SoundBuffer {
void setGain(float gain);
void setMaxDistance(float maxDist);

void attachToEffectSlot(const std::shared_ptr<EffectSlot> effectSlot);
void detachFromEffectSlot(const std::shared_ptr<EffectSlot> effectSlot);

ALuint source;
ALuint buffer;
};
Expand Down
22 changes: 22 additions & 0 deletions rwengine/src/audio/SoundEffect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "SoundEffect.hpp"
#include "OpenAlExtensions.hpp"

SoundEffect::SoundEffect(ALint type) {
// reset error
alGetError();

alGenEffects(1, &id);

created = alGetError() == AL_NO_ERROR;
if (!created) {
return;
}

alEffecti(id, AL_EFFECT_TYPE, type);

created = alGetError() == AL_NO_ERROR;
}

SoundEffect::~SoundEffect() {
alDeleteEffects(1, &id);
}
38 changes: 38 additions & 0 deletions rwengine/src/audio/SoundEffect.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef SOUNDEFFECT_H
#define SOUNDEFFECT_H

#include <al.h>

/**
* Class to represent any effect.
*
* Any concrete realisation should have own class
* in order to be able to set different effect-specific parameters.
*/
class SoundEffect {
public:
/**
* Create effect
* @param type OpenAl specific effect type.
*/
SoundEffect(ALint type);
~SoundEffect();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


ALuint getId() const {
return id;
}

protected:
/**
* Effect openal id
*/
ALuint id;

private:
/**
* Effect created successfully if this is true after construction
*/
bool created;
};

#endif // SOUNDEFFECT_H
Loading