gzdoom/src/sound/oalsound.h
Christoph Oelckers dccd35ef29 - uncoupled OpenAL music updates from UpdateSounds.
UpdateSounds will not be called during screen wipes and the entire setup of this function suggests that this is not advisable at all.
The OpenAL stream updates were done deep inside this function implicitly.
This caused music to stop while a wipe was in progress. So in order to allow uninterrupted music playback during screen wipes the music updates need to be handled separately from sound updates and be called both in the main loop and the wipe loop.

I think that the OpenAL music updating should be offloaded to a separate thread but at least it's working now without causing interruptions during wipes.
2015-04-25 10:26:14 +02:00

213 lines
6.8 KiB
C++

#ifndef OALSOUND_H
#define OALSOUND_H
#include <vector>
#include <map>
#include "i_sound.h"
#include "s_sound.h"
#include "menu/menu.h"
#ifndef NO_OPENAL
#include "al.h"
#include "alc.h"
#ifndef ALC_ENUMERATE_ALL_EXT
#define ALC_ENUMERATE_ALL_EXT 1
#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
#endif
#ifndef ALC_EXT_disconnect
#define ALC_EXT_disconnect 1
#define ALC_CONNECTED 0x313
#endif
#ifndef AL_EXT_source_distance_model
#define AL_EXT_source_distance_model 1
#define AL_SOURCE_DISTANCE_MODEL 0x200
#endif
#ifndef AL_SOFT_loop_points
#define AL_SOFT_loop_points 1
#define AL_LOOP_POINTS_SOFT 0x2015
#endif
#ifndef AL_EXT_float32
#define AL_EXT_float32 1
#define AL_FORMAT_MONO_FLOAT32 0x10010
#define AL_FORMAT_STEREO_FLOAT32 0x10011
#endif
#ifndef AL_EXT_MCFORMATS
#define AL_EXT_MCFORMATS 1
#define AL_FORMAT_QUAD8 0x1204
#define AL_FORMAT_QUAD16 0x1205
#define AL_FORMAT_QUAD32 0x1206
#define AL_FORMAT_REAR8 0x1207
#define AL_FORMAT_REAR16 0x1208
#define AL_FORMAT_REAR32 0x1209
#define AL_FORMAT_51CHN8 0x120A
#define AL_FORMAT_51CHN16 0x120B
#define AL_FORMAT_51CHN32 0x120C
#define AL_FORMAT_61CHN8 0x120D
#define AL_FORMAT_61CHN16 0x120E
#define AL_FORMAT_61CHN32 0x120F
#define AL_FORMAT_71CHN8 0x1210
#define AL_FORMAT_71CHN16 0x1211
#define AL_FORMAT_71CHN32 0x1212
#endif
#include "efx.h"
class OpenALSoundStream;
class OpenALSoundRenderer : public SoundRenderer
{
public:
OpenALSoundRenderer();
virtual ~OpenALSoundRenderer();
virtual void SetSfxVolume(float volume);
virtual void SetMusicVolume(float volume);
virtual SoundHandle LoadSound(BYTE *sfxdata, int length);
virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1);
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);
virtual SoundStream *OpenStream(std::auto_ptr<FileReader> reader, int flags);
// Starts a sound.
virtual FISoundChannel *StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan);
virtual FISoundChannel *StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan);
// Changes a channel's volume.
virtual void ChannelVolume(FISoundChannel *chan, float volume);
// 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();
virtual void UpdateMusic();
virtual void MarkStartTime(FISoundChannel*);
virtual float GetAudibility(FISoundChannel*);
virtual bool IsValid();
virtual void PrintStatus();
virtual void PrintDriversList();
virtual FString GatherStats();
private:
struct {
bool EXT_EFX;
bool EXT_disconnect;
} ALC;
struct {
bool EXT_source_distance_model;
bool SOFT_deferred_updates;
bool SOFT_loop_points;
} 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);
void LoadReverb(const ReverbContainer *env);
void PurgeStoppedSources();
static FSoundChan *FindLowestChannel();
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<WORD,ALuint> EffectMap;
typedef TMapIterator<WORD,ALuint> EffectMapIter;
ALuint EnvSlot;
ALuint EnvFilters[2];
EffectMap EnvEffects;
bool WasInWater;
TArray<OpenALSoundStream*> Streams;
friend class OpenALSoundStream;
};
#endif // NO_OPENAL
#endif