mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-29 21:25:54 +01:00
171 lines
6.3 KiB
C
171 lines
6.3 KiB
C
|
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||
|
|
||
|
#ifndef SE_INCL_SOUNDOBJECT_H
|
||
|
#define SE_INCL_SOUNDOBJECT_H
|
||
|
#ifdef PRAGMA_ONCE
|
||
|
#pragma once
|
||
|
#endif
|
||
|
|
||
|
#include <Engine/Base/Lists.h>
|
||
|
#include <Engine/Math/Vector.h>
|
||
|
#include <Engine/Math/Functions.h>
|
||
|
|
||
|
|
||
|
// sound control values
|
||
|
#define SOF_NONE (0L)
|
||
|
#define SOF_LOOP (1L<<0) // looping sound
|
||
|
#define SOF_3D (1L<<1) // has 3d effects
|
||
|
#define SOF_VOLUMETRIC (1L<<2) // no 3d effects inside hot-spot
|
||
|
#define SOF_SURROUND (1L<<3) // surround effect
|
||
|
#define SOF_LOCAL (1L<<4) // local to listener with same entity
|
||
|
#define SOF_SMOOTHCHANGE (1L<<5) // for smooth transition from one sound to another on same channel
|
||
|
#define SOF_MUSIC (1L<<6) // use music-volume master control instead of sound-volume
|
||
|
#define SOF_NONGAME (1L<<7) // game sounds are not mixed while the game is paused
|
||
|
#define SOF_NOFILTER (1L<<8) // used to disable listener-specific filters - i.e. underwater
|
||
|
|
||
|
#define SOF_PAUSED (1L<<28) // playing, but paused (internal)
|
||
|
#define SOF_LOADED (1L<<29) // sound just loaded (internal)
|
||
|
#define SOF_PREPARE (1L<<30) // prepared for playing (internal)
|
||
|
#define SOF_PLAY (1L<<31) // currently playing
|
||
|
|
||
|
// sound parameters
|
||
|
class CSoundParameters {
|
||
|
public:
|
||
|
FLOAT sp_fLeftVolume; // left channel volume (0.0f-1.0f)
|
||
|
FLOAT sp_fRightVolume; // right channel volume
|
||
|
SLONG sp_slLeftFilter; // left channel bass enhance (32767-0, 0=max)
|
||
|
SLONG sp_slRightFilter; // right channel bass enhance
|
||
|
FLOAT sp_fPhaseShift; // right channel(!) delay in seconds (signed! fixint 16:16)
|
||
|
FLOAT sp_fPitchShift; // playing speed factor (>0, 1.0=normal)
|
||
|
FLOAT sp_fDelay; // seconds to wait before actual sound play start
|
||
|
};
|
||
|
|
||
|
// 3d sound parameters
|
||
|
class CSoundParameters3D {
|
||
|
public:
|
||
|
FLOAT sp3_fPitch; // sound pitch 1=normal
|
||
|
FLOAT sp3_fFalloff; // distance when sound can't be heard any more
|
||
|
FLOAT sp3_fHotSpot; // sound at maximum volume
|
||
|
FLOAT sp3_fMaxVolume; // maximum sound volume
|
||
|
};
|
||
|
|
||
|
class ENGINE_API CSoundObject {
|
||
|
public:
|
||
|
// Sound Object Aware class (notify class when direct sound pointer is not valid)
|
||
|
CListNode so_Node; // for linking in list
|
||
|
class CSoundDecoder *so_psdcDecoder; // only for sounds that are mpx/ogg
|
||
|
|
||
|
public: //private:
|
||
|
CSoundData *so_pCsdLink; // linked on SoundData
|
||
|
SLONG so_slFlags; // playing flags
|
||
|
|
||
|
// internal mixer parameters
|
||
|
FLOAT so_fDelayed; // seconds already passed from start playing sound request
|
||
|
FLOAT so_fLastLeftVolume; // volume from previous mixing (for seamless transition)
|
||
|
FLOAT so_fLastRightVolume;
|
||
|
SWORD so_swLastLeftSample; // samples from previous mixing (for filtering purposes)
|
||
|
SWORD so_swLastRightSample;
|
||
|
FLOAT so_fLeftOffset; // current playing offset of left channel
|
||
|
FLOAT so_fRightOffset; // current playing offset of right channel
|
||
|
FLOAT so_fOffsetDelta; // difference between offsets in samples (for seamless transition between phases)
|
||
|
|
||
|
// sound parameters
|
||
|
CEntity *so_penEntity; // entity that owns this sound (may be null)
|
||
|
CSoundParameters so_sp; // currently active parameters
|
||
|
CSoundParameters so_spNew; // parameters to set on next update
|
||
|
CSoundParameters3D so_sp3; // 3d sound parameters
|
||
|
|
||
|
/* Play Buffer */
|
||
|
void PlayBuffer(void);
|
||
|
/* Stop Buffer */
|
||
|
void StopBuffer(void);
|
||
|
/* Update all 3d effects. */
|
||
|
void Update3DEffects(void);
|
||
|
/* Prepare sound */
|
||
|
void PrepareSound(void);
|
||
|
|
||
|
// get proper sound object for predicted events - return NULL the event is already predicted
|
||
|
CSoundObject *GetPredictionTail(ULONG ulTypeID, ULONG ulEventID);
|
||
|
|
||
|
// play sound - internal function - doesn't account for prediction
|
||
|
void Play_internal( CSoundData *pCsdLink, SLONG slFlags);
|
||
|
void Stop_internal(void);
|
||
|
|
||
|
public:
|
||
|
// Constructor
|
||
|
CSoundObject();
|
||
|
// Destructor
|
||
|
~CSoundObject();
|
||
|
// copy from another object of same class
|
||
|
void Copy(CSoundObject &soOther);
|
||
|
|
||
|
// play sound
|
||
|
void Play( CSoundData *pCsdLink, SLONG slFlags);
|
||
|
// stop playing sound
|
||
|
void Stop( void);
|
||
|
// Pause -> Stop playing sound but keep it linked to data
|
||
|
inline void Pause(void) { so_slFlags |= SOF_PAUSED; };
|
||
|
// Resume -> Resume playing stoped sound
|
||
|
inline void Resume(void) { so_slFlags &= ~SOF_PAUSED; };
|
||
|
// check if sound is playing
|
||
|
inline BOOL IsPlaying(void) {
|
||
|
return (so_slFlags&SOF_PLAY);
|
||
|
};
|
||
|
// check if sound is paused
|
||
|
inline BOOL IsPaused(void) {
|
||
|
return (so_slFlags&SOF_PAUSED);
|
||
|
};
|
||
|
|
||
|
// Check if hooked
|
||
|
inline BOOL IsHooked(void) const { return so_Node.IsLinked(); };
|
||
|
|
||
|
// Set volume
|
||
|
inline void SetVolume( FLOAT fLeftVolume, FLOAT fRightVolume) {
|
||
|
ASSERT( fLeftVolume <= SL_VOLUME_MAX && fLeftVolume >= SL_VOLUME_MIN);
|
||
|
ASSERT( fRightVolume <= SL_VOLUME_MAX && fRightVolume >= SL_VOLUME_MIN);
|
||
|
so_spNew.sp_fLeftVolume = fLeftVolume *(1.0f/SL_VOLUME_MAX);
|
||
|
so_spNew.sp_fRightVolume = fRightVolume*(1.0f/SL_VOLUME_MAX);
|
||
|
};
|
||
|
// Set filter
|
||
|
inline void SetFilter( FLOAT fLeftFilter, FLOAT fRightFilter) { // 1=no filter (>1=more bass)
|
||
|
ASSERT( (fLeftFilter >= 1) && (fRightFilter >= 1));
|
||
|
so_spNew.sp_slLeftFilter = FloatToInt(32767.0/fLeftFilter);
|
||
|
so_spNew.sp_slRightFilter = FloatToInt(32767.0/fRightFilter);
|
||
|
};
|
||
|
// Set pitch shifting
|
||
|
inline void SetPitch( FLOAT fPitch) { // 1.0 for normal (<1 = slower, >1 = faster playing)
|
||
|
ASSERT( fPitch > 0);
|
||
|
so_spNew.sp_fPitchShift = fPitch;
|
||
|
};
|
||
|
// Set phase shifting
|
||
|
inline void SetPhase( FLOAT fPhase) { // right channel delay in seconds (0 = no delay)
|
||
|
ASSERT( (fPhase <= 1) && (fPhase >= -1));
|
||
|
so_spNew.sp_fPhaseShift = fPhase;
|
||
|
};
|
||
|
// Set delay
|
||
|
inline void SetDelay( FLOAT fDelay) { // in seconds (0 = no delay)
|
||
|
ASSERT( fDelay >= 0);
|
||
|
so_spNew.sp_fDelay = fDelay;
|
||
|
};
|
||
|
|
||
|
// Set Position in 3D
|
||
|
inline void SetOwner(CEntity*pen) {
|
||
|
so_penEntity = pen;
|
||
|
};
|
||
|
// Set 3D parameters
|
||
|
void Set3DParameters(FLOAT fMaxDistance, FLOAT fMinDistance, FLOAT fMaxVolume, FLOAT fPitch);
|
||
|
|
||
|
// read/write functions
|
||
|
void Read_t(CTStream *pistr); // throw char *
|
||
|
void Write_t(CTStream *postr); // throw char *
|
||
|
|
||
|
// Obtain sound and play it for this object
|
||
|
void Play_t(const CTFileName &fnmSound, SLONG slFlags); // throw char *
|
||
|
// hard set sound offset in seconds
|
||
|
void SetOffset(FLOAT fOffset);
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif /* include-once check. */
|
||
|
|