#ifndef HGL_AUDIO_SCENE_INCLUDE #define HGL_AUDIO_SCENE_INCLUDE #include #include #include #include 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 source_pool; ///<音源数据池 SortedSets 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