CMAudio/inc/hgl/audio/AudioScene.h

177 lines
6.5 KiB
C
Raw Normal View History

2020-06-18 03:38:48 +08:00
#ifndef HGL_AUDIO_SCENE_INCLUDE
#define HGL_AUDIO_SCENE_INCLUDE
#include<hgl/algorithm/VectorMath.h>
#include<hgl/type/Pool.h>
#include<hgl/type/Map.h>
#include<hgl/audio/ConeAngle.h>
namespace hgl
{
class AudioBuffer;
class AudioSource;
class AudioListener;
/**
*
*/
struct AudioSourceItem
{
friend const double GetGain(AudioListener *,AudioSourceItem *);
friend class AudioScene;
private:
AudioBuffer *buffer;
public:
bool loop; ///<是否循环播放
// float min_gain,max_gain;
float gain; ///<音量增益
uint distance_model; ///<音量衰减模型
float rolloff_factor; ///<环境衰减比率,默认为1
float doppler_factor; ///<多普勒效果强度,默认为0
float ref_distance; ///<衰减距离
float max_distance; ///<最大距离
ConeAngle cone_angle;
Vector3f velocity;
Vector3f direction;
private:
double start_play_time; ///<开播时间
bool is_play; ///<是否需要播放
Vector3f last_pos;
double last_time;
Vector3f cur_pos;
double cur_time;
double move_speed;
double last_gain; ///<最近一次的音量
AudioSource *source;
public:
/**
*
* @param play_time (0)
*/
void Play(const double play_time=0)
{
start_play_time=play_time;
is_play=true;
last_time=0;
}
/**
*
*/
void Stop()
{
is_play=false;
}
/**
*
* @param pos
* @param ct
*/
void MoveTo(const Vector3f &pos,const double &ct)
{
if(last_time==0)
{
last_pos=cur_pos=pos;
last_time=cur_time=ct;
move_speed=0;
}
else
{
last_pos=cur_pos;
last_time=cur_time;
cur_pos=pos;
cur_time=ct;
}
}
};//struct AudioSourceItem
const double GetGain(AudioListener *,AudioSourceItem *); ///<取得相對音量
/**
*
*/
class AudioScene ///<音频场景管理
{
protected:
double cur_time; ///<当前时间
float ref_distance; ///<默认1000
float max_distance; ///<默认100000
AudioListener *listener; ///<收聽者
ObjectPool<AudioSource> source_pool; ///<音源数据池
Set<AudioSourceItem *> source_list; ///<音源列表
protected:
bool ToMute(AudioSourceItem *); ///<转静默处理
bool ToHear(AudioSourceItem *); ///<转发声处理
bool UpdateSource(AudioSourceItem *); ///<刷新音源处理
public: //事件
virtual float OnCheckGain(AudioSourceItem *asi) ///<檢測音量事件
{
return asi?GetGain(listener,asi)*asi->gain:0;
}
virtual void OnToMute(AudioSourceItem *){/*無任何處理,請自行重載處理*/} ///<从有声变成聽不到聲音
virtual void OnToHear(AudioSourceItem *){/*無任何處理,請自行重載處理*/} ///<从听不到声变成能听到声音
virtual void OnContinuedMute(AudioSourceItem *){/*無任何處理,請自行重載處理*/} ///<持续聽不到聲音
virtual void OnContinuedHear(AudioSourceItem *){/*無任何處理,請自行重載處理*/} ///<持续可以聽到聲音
virtual bool OnStopped(AudioSourceItem *){return true;} ///<单个音源播放结束事件,返回TRUE表示可以释放这个音源返回FALSE依然占用这个音源
public:
AudioScene(int max_source,AudioListener *al); ///<构造函数(指定最大音源数)
virtual ~AudioScene()=default; ///<析构函数
void SetListener(AudioListener *al){listener=al;} ///<設置收聽者
/**
* 使
* @param rd
* @param md
*/
void SetDistance(const float &rd,const float &md) ///<设定参考距离
{
ref_distance=rd;
max_distance=md;
}
virtual AudioSourceItem * Create(AudioBuffer *,const Vector3f &pos,const float &gain=1); ///<创建一個音源
virtual void Delete(AudioSourceItem *); ///<删除一个音源
virtual void Clear() ///<清除所有音源
{
source_list.Clear();
source_pool.ReleaseAll();
}
virtual int Update(const double &ct=0); ///<刷新,返回仍在發聲的音源數量
};//class AudioScene
}//namespace hgl
#endif//HGL_AUDIO_SCENE_INCLUDE