2019-11-11 20:50:20 +00:00
|
|
|
#ifndef OALSOUND_H
|
|
|
|
#define OALSOUND_H
|
|
|
|
|
|
|
|
#include <thread>
|
|
|
|
#include <mutex>
|
|
|
|
#include <atomic>
|
|
|
|
#include <condition_variable>
|
|
|
|
#include <unordered_map>
|
|
|
|
|
|
|
|
#include "i_sound.h"
|
2019-12-12 18:21:36 +00:00
|
|
|
#include "s_soundinternal.h"
|
2019-11-11 20:50:20 +00:00
|
|
|
|
|
|
|
#ifndef NO_OPENAL
|
|
|
|
|
|
|
|
#ifdef DYN_OPENAL
|
|
|
|
#define AL_NO_PROTOTYPES
|
|
|
|
#include "thirdparty/al.h"
|
|
|
|
#include "thirdparty/alc.h"
|
|
|
|
#else
|
|
|
|
#include "al.h"
|
|
|
|
#include "alc.h"
|
|
|
|
#endif
|
|
|
|
|
2022-10-14 17:58:39 +00:00
|
|
|
#include "alext.h"
|
2019-11-11 20:50:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
class OpenALSoundStream;
|
|
|
|
|
|
|
|
class OpenALSoundRenderer : public SoundRenderer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
OpenALSoundRenderer();
|
|
|
|
virtual ~OpenALSoundRenderer();
|
|
|
|
|
|
|
|
virtual void SetSfxVolume(float volume);
|
|
|
|
virtual void SetMusicVolume(float volume);
|
2023-01-15 14:18:57 +00:00
|
|
|
virtual SoundHandle LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end);
|
2020-02-09 12:26:51 +00:00
|
|
|
virtual SoundHandle LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1);
|
2019-11-11 20:50:20 +00:00
|
|
|
virtual void UnloadSound(SoundHandle sfx);
|
|
|
|
virtual unsigned int GetMSLength(SoundHandle sfx);
|
|
|
|
virtual unsigned int GetSampleLength(SoundHandle sfx);
|
|
|
|
virtual float GetOutputRate();
|
|
|
|
|
|
|
|
// Streaming sounds.
|
|
|
|
virtual SoundStream *CreateStream(SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata);
|
|
|
|
|
|
|
|
// Starts a sound.
|
2023-01-15 13:06:01 +00:00
|
|
|
FISoundChannel *StartSound(SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) override;
|
|
|
|
FISoundChannel *StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) override;
|
2019-11-11 20:50:20 +00:00
|
|
|
|
|
|
|
// Changes a channel's volume.
|
|
|
|
virtual void ChannelVolume(FISoundChannel *chan, float volume);
|
|
|
|
|
|
|
|
// Changes a channel's pitch.
|
|
|
|
virtual void ChannelPitch(FISoundChannel *chan, float pitch);
|
|
|
|
|
|
|
|
// Stops a sound channel.
|
|
|
|
virtual void StopChannel(FISoundChannel *chan);
|
|
|
|
|
|
|
|
// Returns position of sound on this channel, in samples.
|
|
|
|
virtual unsigned int GetPosition(FISoundChannel *chan);
|
|
|
|
|
|
|
|
// Synchronizes following sound startups.
|
|
|
|
virtual void Sync(bool sync);
|
|
|
|
|
|
|
|
// Pauses or resumes all sound effect channels.
|
|
|
|
virtual void SetSfxPaused(bool paused, int slot);
|
|
|
|
|
|
|
|
// Pauses or resumes *every* channel, including environmental reverb.
|
|
|
|
virtual void SetInactive(SoundRenderer::EInactiveState inactive);
|
|
|
|
|
|
|
|
// Updates the volume, separation, and pitch of a sound channel.
|
|
|
|
virtual void UpdateSoundParams3D(SoundListener *listener, FISoundChannel *chan, bool areasound, const FVector3 &pos, const FVector3 &vel);
|
|
|
|
|
|
|
|
virtual void UpdateListener(SoundListener *);
|
|
|
|
virtual void UpdateSounds();
|
|
|
|
|
2020-04-12 06:09:38 +00:00
|
|
|
virtual void MarkStartTime(FISoundChannel*, float startTime);
|
2019-11-11 20:50:20 +00:00
|
|
|
virtual float GetAudibility(FISoundChannel*);
|
|
|
|
|
|
|
|
|
|
|
|
virtual bool IsValid();
|
|
|
|
virtual void PrintStatus();
|
|
|
|
virtual void PrintDriversList();
|
|
|
|
virtual FString GatherStats();
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct {
|
|
|
|
bool EXT_EFX;
|
|
|
|
bool EXT_disconnect;
|
|
|
|
bool SOFT_HRTF;
|
|
|
|
bool SOFT_pause_device;
|
2020-10-28 20:46:43 +00:00
|
|
|
bool SOFT_output_limiter;
|
2019-11-11 20:50:20 +00:00
|
|
|
} ALC;
|
|
|
|
struct {
|
|
|
|
bool EXT_source_distance_model;
|
|
|
|
bool EXT_SOURCE_RADIUS;
|
|
|
|
bool SOFT_deferred_updates;
|
|
|
|
bool SOFT_loop_points;
|
2022-10-14 17:58:39 +00:00
|
|
|
bool SOFT_source_latency;
|
2019-11-11 20:50:20 +00:00
|
|
|
bool SOFT_source_resampler;
|
|
|
|
bool SOFT_source_spatialize;
|
|
|
|
} AL;
|
|
|
|
|
|
|
|
// EFX Extension function pointer variables. Loaded after context creation
|
|
|
|
// if EFX is supported. These pointers may be context- or device-dependant,
|
|
|
|
// thus can't be static
|
|
|
|
// Effect objects
|
|
|
|
LPALGENEFFECTS alGenEffects;
|
|
|
|
LPALDELETEEFFECTS alDeleteEffects;
|
|
|
|
LPALISEFFECT alIsEffect;
|
|
|
|
LPALEFFECTI alEffecti;
|
|
|
|
LPALEFFECTIV alEffectiv;
|
|
|
|
LPALEFFECTF alEffectf;
|
|
|
|
LPALEFFECTFV alEffectfv;
|
|
|
|
LPALGETEFFECTI alGetEffecti;
|
|
|
|
LPALGETEFFECTIV alGetEffectiv;
|
|
|
|
LPALGETEFFECTF alGetEffectf;
|
|
|
|
LPALGETEFFECTFV alGetEffectfv;
|
|
|
|
// Filter objects
|
|
|
|
LPALGENFILTERS alGenFilters;
|
|
|
|
LPALDELETEFILTERS alDeleteFilters;
|
|
|
|
LPALISFILTER alIsFilter;
|
|
|
|
LPALFILTERI alFilteri;
|
|
|
|
LPALFILTERIV alFilteriv;
|
|
|
|
LPALFILTERF alFilterf;
|
|
|
|
LPALFILTERFV alFilterfv;
|
|
|
|
LPALGETFILTERI alGetFilteri;
|
|
|
|
LPALGETFILTERIV alGetFilteriv;
|
|
|
|
LPALGETFILTERF alGetFilterf;
|
|
|
|
LPALGETFILTERFV alGetFilterfv;
|
|
|
|
// Auxiliary slot objects
|
|
|
|
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
|
|
|
|
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
|
|
|
|
LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
|
|
|
|
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
|
|
|
|
LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
|
|
|
|
LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
|
|
|
|
LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
|
|
|
|
LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
|
|
|
|
LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
|
|
|
|
LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
|
|
|
|
LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
|
|
|
|
|
|
|
|
ALvoid (AL_APIENTRY*alDeferUpdatesSOFT)(void);
|
|
|
|
ALvoid (AL_APIENTRY*alProcessUpdatesSOFT)(void);
|
|
|
|
|
|
|
|
LPALGETSTRINGISOFT alGetStringiSOFT;
|
|
|
|
|
2022-10-14 17:58:39 +00:00
|
|
|
LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT;
|
|
|
|
|
2019-11-11 20:50:20 +00:00
|
|
|
void (ALC_APIENTRY*alcDevicePauseSOFT)(ALCdevice *device);
|
|
|
|
void (ALC_APIENTRY*alcDeviceResumeSOFT)(ALCdevice *device);
|
|
|
|
|
|
|
|
void BackgroundProc();
|
|
|
|
void AddStream(OpenALSoundStream *stream);
|
|
|
|
void RemoveStream(OpenALSoundStream *stream);
|
|
|
|
|
|
|
|
void LoadReverb(const ReverbContainer *env);
|
|
|
|
void PurgeStoppedSources();
|
|
|
|
static FSoundChan *FindLowestChannel();
|
|
|
|
|
|
|
|
std::thread StreamThread;
|
|
|
|
std::mutex StreamLock;
|
|
|
|
std::condition_variable StreamWake;
|
|
|
|
std::atomic<bool> QuitThread;
|
|
|
|
|
|
|
|
ALCdevice *Device;
|
|
|
|
ALCcontext *Context;
|
|
|
|
|
|
|
|
TArray<ALuint> Sources;
|
|
|
|
|
|
|
|
ALfloat SfxVolume;
|
|
|
|
ALfloat MusicVolume;
|
|
|
|
|
|
|
|
int SFXPaused;
|
|
|
|
TArray<ALuint> FreeSfx;
|
|
|
|
TArray<ALuint> PausableSfx;
|
|
|
|
TArray<ALuint> ReverbSfx;
|
|
|
|
TArray<ALuint> SfxGroup;
|
|
|
|
|
|
|
|
const ReverbContainer *PrevEnvironment;
|
|
|
|
|
|
|
|
typedef TMap<uint16_t,ALuint> EffectMap;
|
|
|
|
typedef TMapIterator<uint16_t,ALuint> EffectMapIter;
|
|
|
|
ALuint EnvSlot;
|
|
|
|
ALuint EnvFilters[2];
|
|
|
|
EffectMap EnvEffects;
|
|
|
|
|
|
|
|
bool WasInWater;
|
|
|
|
|
|
|
|
TArray<OpenALSoundStream*> Streams;
|
|
|
|
friend class OpenALSoundStream;
|
|
|
|
|
|
|
|
ALCdevice *InitDevice();
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // NO_OPENAL
|
|
|
|
|
|
|
|
#endif
|