-
Notifications
You must be signed in to change notification settings - Fork 172
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
base: main
Are you sure you want to change the base?
Changes from all commits
be920d3
8bd8e17
cb40cc3
958b7f7
7a22c06
c464756
99429f3
519536d
8496f6a
7e2f208
60ac44a
b673ab6
1dbabd1
dd0dd44
ce7c45f
1b4cc61
960d1a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#include "EffectSlot.hpp" | ||
#include "SoundEffect.hpp" | ||
#include "OpenAlExtensions.hpp" | ||
|
||
EffectSlot::EffectSlot() { | ||
alGenAuxiliaryEffectSlots(1, &slotId); | ||
|
||
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) { | ||
this->gain = gain; | ||
alAuxiliaryEffectSlotf(slotId, AL_EFFECTSLOT_GAIN, gain); | ||
} |
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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have problems with understanding connection between this class and |
||
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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 = 1.0f; | ||
|
||
/// OpenAL aux slot | ||
int slotNumber = 0; | ||
}; | ||
|
||
#endif // EFFECTSLOT_H |
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")); | ||
} |
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 |
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) { | ||
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); | ||
} |
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 = 0.3f); | ||
void setGain(float gain = 0.92f); | ||
void setGainHf(float gainHf = 0.89f); | ||
void setDecayTime(float decayTime = 5.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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,13 @@ | |
|
||
#include "audio/SoundBuffer.hpp" | ||
|
||
Sound::~Sound() | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Formatting. Use clang-format with our config file. |
||
if (effect != nullptr) { | ||
buffer->disableEffect(effect); | ||
} | ||
} | ||
|
||
bool Sound::isPlaying() const { | ||
return buffer->isPlaying(); | ||
} | ||
|
@@ -46,6 +53,12 @@ void Sound::setMaxDistance(float maxDist) { | |
buffer->setMaxDistance(maxDist); | ||
} | ||
|
||
void Sound::enableEffect(std::shared_ptr<SoundEffect> effect) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also |
||
this->effect = std::move(effect); | ||
buffer->enableEffect(this->effect); | ||
} | ||
|
||
size_t Sound::getScriptObjectID() const { | ||
return id; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
#ifndef _RWENGINE_SOUND_HPP_ | ||
#define _RWENGINE_SOUND_HPP_ | ||
|
||
#include <audio/SoundEffect.hpp> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. forward declaration |
||
|
||
#include <glm/vec3.hpp> | ||
|
||
#include <memory> | ||
#include <optional> | ||
|
||
class SoundSource; | ||
struct SoundBuffer; | ||
|
@@ -18,8 +21,10 @@ struct Sound { | |
std::shared_ptr<SoundSource> source; | ||
std::unique_ptr<SoundBuffer> buffer; | ||
|
||
std::shared_ptr<SoundEffect> effect; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. raw ptr is enough |
||
|
||
Sound() = default; | ||
~Sound() = default; | ||
~Sound(); | ||
|
||
bool isPlaying() const; | ||
|
||
|
@@ -42,6 +47,8 @@ struct Sound { | |
|
||
void setMaxDistance(float maxDist); | ||
|
||
void enableEffect(std::shared_ptr<SoundEffect> effect); | ||
|
||
size_t getScriptObjectID() const; | ||
}; | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
#include "audio/SoundBuffer.hpp" | ||
|
||
#include <rw/types.hpp> | ||
#include <efx.h> | ||
|
||
#include "audio/alCheck.hpp" | ||
#include "audio/SoundSource.hpp" | ||
#include "audio/SoundEffect.hpp" | ||
|
||
SoundBuffer::SoundBuffer() { | ||
alCheck(alGenSources(1, &source)); | ||
|
@@ -83,3 +85,11 @@ void SoundBuffer::setGain(float gain) { | |
void SoundBuffer::setMaxDistance(float maxDist) { | ||
alCheck(alSourcef(source, AL_MAX_DISTANCE, maxDist)); | ||
} | ||
|
||
void SoundBuffer::enableEffect(std::shared_ptr<SoundEffect> effect) { | ||
alCheck(alSource3i(source, AL_AUXILIARY_SEND_FILTER, (ALint) effect->getSlotId(), effect->getSlotNumber(), AL_FILTER_NULL)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. formatting |
||
} | ||
|
||
void SoundBuffer::disableEffect(std::shared_ptr<SoundEffect> effect) { | ||
alCheck(alSource3i (source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, effect->getSlotNumber(), AL_FILTER_NULL)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#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; | ||
if (!created) { | ||
return; | ||
} | ||
|
||
alGenAuxiliaryEffectSlots(1, &slotId); | ||
|
||
created = alGetError() == AL_NO_ERROR; | ||
if (!created) { | ||
return; | ||
} | ||
|
||
alAuxiliaryEffectSloti(slotId, AL_EFFECTSLOT_EFFECT, (ALint) id); | ||
|
||
created = alGetError() == AL_NO_ERROR; | ||
if (!created) { | ||
return; | ||
} | ||
|
||
created = alGetError() == AL_NO_ERROR; | ||
} | ||
|
||
SoundEffect::~SoundEffect() { | ||
alDeleteEffects(1, &id); | ||
alDeleteAuxiliaryEffectSlots(1, &slotId); | ||
} | ||
|
||
void SoundEffect::setGain(float gain) { | ||
this->gain = gain; | ||
alAuxiliaryEffectSlotf(slotId, AL_EFFECTSLOT_GAIN, gain); | ||
} |
There was a problem hiding this comment.
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