#pragma once #include "style.h" #include "entity.h" #include "sphere.h" #include "slot.h" #include "table.h" class PlugStream; // //-------------------------------------------------------------------------- // Support types //-------------------------------------------------------------------------- // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Time types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ typedef long AudioTick; typedef long AudioDivisionsPerBeat; typedef long AudioTempo; typedef long AudioFrameCount; const AudioFrameCount NullAudioFrameCount = -1; const AudioFrameCount DefaultAudioFrameDelay = 2; extern const Scalar AudioDoubleTriggerCutoff; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Resource types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ typedef int AudioResourceID; typedef int AudioVoiceCount; typedef Scalar AudioRadiationProfile; typedef Scalar AudioPitchCents; enum AudioRenderType { TransientAudioRenderType = 0, SustainedAudioRenderType = 1 }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Source types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ enum AudioRepresentation { InternalAudioRepresentation = 0, ExternalAudioRepresentation = 1 }; #define AUDIO_SOURCE_PRIORITY_COUNT (5) enum AudioSourcePriority { MinAudioSourcePriority = 0, LowAudioSourcePriority = 1, MedAudioSourcePriority = 2, HighAudioSourcePriority = 3, MaxAudioSourcePriority = 4 }; enum AudioSourceState { StoppedAudioSourceState = 0, DormantAudioSourceState = 1, RunningAudioSourceState = 2, SuspendedAudioSourceState = 3 }; enum AudioSourceMixPresence { ManualAudioSourceMixPresence = 0, MaxAudioSourceMixPresence = 1, HighAudioSourceMixPresence = 2, MedAudioSourceMixPresence = 3, LowAudioSourceMixPresence = 4, MinAudioSourceMixPresence = 5 }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Control types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ enum AudioControlID { NullAudioControlID = 0, StartAudioControlID, StopAudioControlID, VolumeAudioControlID, PitchAudioControlID, BrightnessAudioControlID, AttackVolumeAudioControlID, AttackTimeAudioControlID, NoteAudioControlID, IdleAudioControlID, DurationAudioControlID, FlushMessagesAudioControlID, TempoAudioControlID, AudioControlIDCount }; typedef Scalar AudioControlValue; extern const AudioControlValue MaxAudioVolume; extern const AudioControlValue MinAudioVolume; extern const AudioControlValue LowAudioVolumeThreshold; extern const AudioControlValue MaxAudioBrightness; extern const AudioControlValue MinAudioBrightness; extern const AudioControlValue MaxAudioAttack; extern const AudioControlValue MinAudioAttack; #if 0 //~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioClippingSphere ~~~~~~~~~~~~~~~~~~~~~~~~~~ class AudioClippingSphere SIGNATURED { public: AudioClippingSphere(); ~AudioClippingSphere(); void SetReferenceRadius(Scalar radius); void SetCurrentOrigin(const Point3D &origin); void SetCurrentScale(Scalar scale); Logical Contains(const Point3D &point) const; private: Scalar referenceRadius; Sphere currentSphere; }; //~~~~~~~~~~~~~~~~~~~~~~~ AudioClippingSphere inlines ~~~~~~~~~~~~~~~~~~~~~~ inline AudioClippingSphere::AudioClippingSphere(): referenceRadius(100.0f), currentSphere(0.0f, 0.0f, 0.0f, 100.0f) { } inline AudioClippingSphere::~AudioClippingSphere() { } inline void AudioClippingSphere::SetReferenceRadius(Scalar radius) { Check(this); referenceRadius = radius; currentSphere.radius = radius; } inline void AudioClippingSphere::SetCurrentOrigin(const Point3D &origin) { Check(this); currentSphere.center = origin; } inline void AudioClippingSphere::SetCurrentScale(Scalar scale) { Check(this); currentSphere.radius = scale * referenceRadius; } inline Logical AudioClippingSphere::Contains(const Point3D &point) const { Check(this); return currentSphere.Contains(point); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioHead ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class AudioSource; class AudioHead SIGNATURED { public: // //----------------------------------------------------------------------- // Construction, Destruction, Testing //----------------------------------------------------------------------- // AudioHead(); ~AudioHead(); Logical TestInstance() const; // //----------------------------------------------------------------------- // Get current frame of audio simulation //----------------------------------------------------------------------- // AudioFrameCount GetAudioFrameCount() {return audioFrameCount;} // //----------------------------------------------------------------------- // Sets the location and orientation of the head //----------------------------------------------------------------------- // virtual void LinkToEntity(Entity *entity); Entity* GetHeadEntity(); // //----------------------------------------------------------------------- // Get the ear to world linear matrix //----------------------------------------------------------------------- // virtual LinearMatrix GetEarToWorld(); // //----------------------------------------------------------------------- // Execute //----------------------------------------------------------------------- // virtual void Execute(); // //----------------------------------------------------------------------- // Sets the distance between ears. Expressed in meters. //----------------------------------------------------------------------- // void SetDistanceBetweenEars(Scalar distance) {distanceBetweenEars = distance;} Scalar GetDistanceBetweenEars() {return distanceBetweenEars;} // //----------------------------------------------------------------------- // Controls Doppler effects //----------------------------------------------------------------------- // void ControlDopplerEffect( Scalar doppler_constant, Scalar sound_speed ); Scalar GetAudioSoundSpeed() {return audioSoundSpeed;} AudioPitchCents GetAudioDopplerConstant() {return audioDopplerConstant;} // //----------------------------------------------------------------------- // Reverb scaling //----------------------------------------------------------------------- // void SetReverbToDryRatio(Scalar ratio) {reverbToDryRatio = ratio;} Scalar GetReverbToDryRatio() {return reverbToDryRatio;} // HACK void SetGlobalReverbScale(Scalar global_reverb_scale) {globalReverbScale = global_reverb_scale;} Scalar GetGlobalReverbScale() {return globalReverbScale;} // //----------------------------------------------------------------------- // Controls the attenuation of an audio source with respect to its // distance from the head. //----------------------------------------------------------------------- // void ControlAmplitudeRollOff( Scalar exponent, Scalar amplitude_rolloff_knee, Scalar distance_scale ); Scalar GetAmplitudeRollOffExponent() {return amplitudeRollOffExponent;} Scalar GetAmplitudeRollOffKnee() {return amplitudeRollOffKnee;} Scalar GetAmplitudeRollOffDistanceScale() {return amplitudeRollOffDistanceScale;} // //----------------------------------------------------------------------- // Controls the attenuation of the high frequencies // of an audio source with respect to its distance from // the head. //----------------------------------------------------------------------- // void ControlHighFrequencyRollOff( Scalar exponent, Scalar high_frequency_rolloff_knee, Scalar distance_scale ); Scalar GetHighFrequencyRollOffExponent() {return highFrequencyRollOffExponent;} Scalar GetHighFrequencyRollOffKnee() {return highFrequencyRollOffKnee;} Scalar GetHighFrequencyRollOffDistanceScale() {return highFrequencyRollOffDistanceScale;} // //----------------------------------------------------------------------- // Controls source compression //----------------------------------------------------------------------- // void ControlSourceCompression( Scalar exponent, Scalar scale ); Scalar GetSourceCompressionExponent() {return sourceCompressionExponent;} Scalar GetSourceCompressionScale() {return sourceCompressionScale;} // //----------------------------------------------------------------------- // Defines the audio clipping sphere //----------------------------------------------------------------------- // void DefineClippingSphere(Scalar radius); Logical IsPointClipped(const Point3D &point); Scalar GetClippingRadius() {return clippingRadius;} // //----------------------------------------------------------------------- // ITD Difference //----------------------------------------------------------------------- // void SetITDDifference(Scalar itd_difference) {itdDifference = itd_difference;} Scalar GetITDDifference() {return itdDifference;} // //----------------------------------------------------------------------- // The SetPositionalCulling method allows the rendering process to // not play audio locations whose positions are masked by other // audio sources. This has found to be useful for controlling // audio when resources are limited, but must be // selectable globally or on a per audio effect basis. //----------------------------------------------------------------------- // void SetPositionalCulling(Logical turn_on); private: // //----------------------------------------------------------------------- // Private data //----------------------------------------------------------------------- // AudioFrameCount audioFrameCount; SlotOf headEntitySocket; Scalar clippingRadius; Scalar distanceBetweenEars; Scalar amplitudeRollOffExponent, amplitudeRollOffKnee, amplitudeRollOffDistanceScale; Scalar highFrequencyRollOffExponent, highFrequencyRollOffKnee, highFrequencyRollOffDistanceScale; Scalar reverbToDryRatio; Scalar audioSoundSpeed; Scalar audioDopplerConstant; Scalar sourceCompressionExponent, sourceCompressionScale; Scalar itdDifference; Scalar globalReverbScale; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioHead inlines ~~~~~~~~~~~~~~~~~~~~~~~~~ inline Entity* AudioHead::GetHeadEntity() { Check(this); return headEntitySocket.GetCurrent(); } //########################################################################## //######################### AudioComponent ########################### //########################################################################## class AudioComponent__ReceiveControlMessage; class AudioComponent: public Component { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Construction, Destruction, Testing // public: AudioComponent( PlugStream *stream, SharedData &shared_data = DefaultData ); ~AudioComponent(); Logical TestInstance() const; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Audio Component Methods // public: void AddWatcher(Component *component); void ExecuteWatchers(); void Execute(); virtual void ReceiveControl( AudioControlID control_ID, AudioControlValue control_value ); void PostReceiveControl( AudioControlID control_ID, AudioControlValue control_value ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Message Support // public: enum { ReceiveControlMessageID = Component::NextMessageID, NextMessageID }; typedef AudioComponent__ReceiveControlMessage ReceiveControlMessage; static const HandlerEntry MessageHandlerEntries[]; //static MessageHandlerSet MessageHandlers; static MessageHandlerSet& GetMessageHandlers(); void ReceiveControlMessageHandler( ReceiveControlMessage *message ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Shared Data Support // public: static Derivation *GetClassDerivations(); static SharedData DefaultData; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private Data // private: AudioFrameCount nextExecuteWatcherFrame; ChainOf audioWatcherSocket; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioComponent inlines ~~~~~~~~~~~~~~~~~~~~~~~~ inline void AudioComponent::AddWatcher(Component *component) { Check(component); Check(&audioWatcherSocket); audioWatcherSocket.Add(component); } //~~~~~~~~~~~~~~~~~~ AudioComponent__ReceiveControlMessage ~~~~~~~~~~~~~~~~~ class AudioComponent__ReceiveControlMessage: public Receiver::Message { friend class AudioComponent; public: AudioComponent__ReceiveControlMessage( AudioControlID control_ID, AudioControlValue control_value ); private: AudioControlID controlID; AudioControlValue controlValue; }; //~~~~~~~~~~~~~~~~~~~~~~~~ Resource type inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~ inline MemoryStream& MemoryStream_Read( MemoryStream* stream, AudioRenderType *output ) { return stream->ReadBytes(output, sizeof(*output)); } inline MemoryStream& MemoryStream_Write( MemoryStream* stream, const AudioRenderType *input ) { return stream->WriteBytes(input, sizeof(*input)); } inline MemoryStream& MemoryStream_Read( MemoryStream* stream, AudioRepresentation *output ) { return stream->ReadBytes(output, sizeof(*output)); } inline MemoryStream& MemoryStream_Write( MemoryStream* stream, const AudioRepresentation *input ) { return stream->WriteBytes(input, sizeof(*input)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~ Source type inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~ inline MemoryStream& MemoryStream_Read( MemoryStream* stream, AudioSourceState *output ) { return stream->ReadBytes(output, sizeof(*output)); } inline MemoryStream& MemoryStream_Write( MemoryStream* stream, const AudioSourceState *input ) { return stream->WriteBytes(input, sizeof(*input)); } inline MemoryStream& MemoryStream_Read( MemoryStream* stream, AudioSourcePriority *output ) { return stream->ReadBytes(output, sizeof(*output)); } inline MemoryStream& MemoryStream_Write( MemoryStream* stream, const AudioSourcePriority *input ) { return stream->WriteBytes(input, sizeof(*input)); } inline MemoryStream& MemoryStream_Read( MemoryStream* stream, AudioSourceMixPresence *output ) { return stream->ReadBytes(output, sizeof(*output)); } inline MemoryStream& MemoryStream_Write( MemoryStream* stream, const AudioSourceMixPresence *input ) { return stream->WriteBytes(input, sizeof(*input)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~ Control type inlines ~~~~~~~~~~~~~~~~~~~~~~~~~ inline MemoryStream& MemoryStream_Read( MemoryStream* stream, AudioControlID *output ) { return stream->ReadBytes(output, sizeof(*output)); } inline MemoryStream& MemoryStream_Write( MemoryStream* stream, const AudioControlID *input ) { return stream->WriteBytes(input, sizeof(*input)); }