#pragma once #include "style.h" #include "audio.h" //########################################################################## //######################## AudioLocation ############################# //########################################################################## class AudioLocation: public AudioComponent { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Construction, Destruction, and Testing // public: AudioLocation( PlugStream *stream, Entity *entity ); void AudioLocationX( Entity *entity, AudioFrameCount next_update_delay, Scalar clipping_scale ); ~AudioLocation(); Logical TestInstance() const; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Resource Building // public: static void BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Audio Component Support // public: void ReceiveControl( AudioControlID control_ID, AudioControlValue control_value ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Audio Location Support // public: // //----------------------------------------------------------------------- // GetLinkedEntity //----------------------------------------------------------------------- // Entity* GetLinkedEntity(); // //----------------------------------------------------------------------- // IsAudioLocationClipped //----------------------------------------------------------------------- // Logical IsAudioLocationClipped(AudioHead *audio_head); // //----------------------------------------------------------------------- // UpdateSpatialModel //----------------------------------------------------------------------- // void UpdateSpatialModel(AudioHead *audio_head); // //----------------------------------------------------------------------- // Access to localization results //----------------------------------------------------------------------- // Logical IsHeadSource() {return isHeadSource;} Scalar GetDistanceToSource() {return distanceToSource;} Scalar GetDistanceToSourceListenerPlane(); Radian GetAzimuthOfSource() {return azimuthOfSource;} Scalar GetDistanceVolumeScale() {return distanceVolumeScale;} Scalar GetHighFreqCutoffScale() {return highFreqCutoffScale;} AudioPitchCents GetDopplerCents() {return dopplerCents;} Scalar getMaxDistance(AudioHead *audio_head) {return audio_head->GetClippingRadius() * clippingScale;} Vector3D GetVectorToSource() { return this->vectorToSource; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Protected Implementations // protected: virtual void UpdateSpatialModelImplementation(AudioHead *audio_head); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private Methods // private: Logical CalculateDoppler( AudioHead *audio_head, Scalar speed, AudioPitchCents *result ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private Data // private: Entity *linkedEntity; Point3D locationOffset; Scalar clippingScale; Logical isHeadSource; Vector3D vectorToSource; Scalar distanceToSource; #if 0 Radian angleOffOrientation; #endif Radian azimuthOfSource; Scalar distanceVolumeScale; Scalar highFreqCutoffScale; #if 0 Scalar reverbVolumeScale; #endif AudioPitchCents dopplerCents; AudioFrameCount nextUpdateDelay; AudioFrameCount nextUpdateFrame; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioLocation inlines ~~~~~~~~~~~~~~~~~~~~~~~~ inline Entity* AudioLocation::GetLinkedEntity() { Check(this); return linkedEntity; } inline Scalar AudioLocation::GetDistanceToSourceListenerPlane() { Check(this); Vector3D vector_to_source_listener_plane( vectorToSource.x, 0.0f, vectorToSource.z ); return vector_to_source_listener_plane.Length(); } inline void AudioLocation::UpdateSpatialModel(AudioHead *audio_head) { Check(this); Check(audio_head); if (nextUpdateFrame <= audio_head->GetAudioFrameCount()) { nextUpdateFrame = audio_head->GetAudioFrameCount() + nextUpdateDelay; UpdateSpatialModelImplementation(audio_head); } }