#pragma once #include "style.h" #include "audio.h" #include "audloc.h" #include "audlvl.h" #include "audwgt.h" #include "audtime.h" //########################################################################## //##################### AudioSourceStartState ######################## //########################################################################## class AudioSourceStartState SIGNATURED { public: AudioSourceStartState(); ~AudioSourceStartState(); Logical TestInstance() const; void CalculateDuration(AudioControlValue control_value); Logical IsFinishedPlaying(); AudioTime GetCurrentRunningTime(); void SetNoteValue(AudioControlValue note_value) {noteValue = note_value;} AudioControlValue GetNoteValue() {return noteValue;} void SetDurationValue(AudioControlValue duration_value); void Start() {startTime = AudioTime::Now();} private: AudioControlValue noteValue; Logical isDurationSet; Logical hasDuration; Scalar duration; AudioTime startTime; AudioTime endTime; }; //~~~~~~~~~~~~~~~~~~~~~ AudioSourceStartState inlines ~~~~~~~~~~~~~~~~~~~~~~ inline Logical AudioSourceStartState::IsFinishedPlaying() { Check(this); if (hasDuration) { return (AudioTime::Now() > endTime); } return False; } inline void AudioSourceStartState::SetDurationValue(AudioControlValue duration_value) { Check(this); isDurationSet = True; duration = duration_value; } inline AudioTime AudioSourceStartState::GetCurrentRunningTime() { Check(this); return (AudioTime::Now() - startTime); } //########################################################################## //######################### AudioSource ############################## //########################################################################## class AudioSource__RequestMessage; class AudioSource__StartMessage; class AudioSource__StopMessage; class AudioSource: public AudioComponent { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Construction, Destruction, and Testing // public: AudioSource( PlugStream *stream, Entity *entity ); void AudioSource::AudioSourceX( AudioResource *audio_resource, AudioLocation *audio_location, Entity *entity, AudioSourcePriority priority, AudioSourceMixPresence mix_presence, AudioControlValue volume_mix_level, AudioPitchCents pitch_mix_offset, AudioControlValue brightness_mix_level, Logical has_compression_curve, const AudioTime &compression_duration, Logical use_brightness_scale, Logical use_attack_time_scale ); ~AudioSource(); Logical TestInstance() const; static void BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Location methods // public: AudioLocation* GetAudioLocation(); void UpdateSpatialModel(AudioHead *audio_head); Scalar GetDistanceToSource(); virtual Logical IsAudioSourceClipped(AudioHead *audio_head); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Resource methods // public: void SetAudioResource(AudioResource *audio_resource); AudioResource* GetAudioResource(); AudioVoiceCount GetAudioVoiceCount(); AudioRenderType GetAudioRenderType(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Current State/Status Accessors // public: void AssignAudioSourceState(AudioSourceState audio_source_state); AudioSourceState GetAudioSourceState(); Logical IsFinishedPlaying(); AudioTime GetCurrentRunningTime(); AudioControlValue GetCurrentNoteValue(); AudioControlValue CalculateSourceAttackVolumeScale(); Logical UseSourceAttackTime(); AudioControlValue CalculateSourceAttackTime(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Priority Accessors // public: void SetAudioSourcePriority(AudioSourcePriority audio_source_priority); AudioSourcePriority GetAudioSourcePriority(); AudioWeighting CalculateAudioWeighting(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Mixing & Logical compression methods // public: AudioSourceMixPresence GetAudioSourceMixPresence(); void SetVolumeCompressionScale(AudioControlValue compression_scale); AudioControlValue CalculateSourceCompressionEffect(); virtual AudioControlValue CalculateSourceVolumeScale(); virtual AudioPitchCents CalculateSourcePitchOffset(); Logical UseSourceBrightnessScale(); virtual AudioControlValue CalculateSourceBrightnessScale(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Controller methods // public: void ReceiveControl( AudioControlID control_ID, AudioControlValue control_value ); virtual void VolumeAudioHandler(AudioControlValue); virtual void PitchAudioHandler(AudioControlValue); virtual void BrightnessAudioHandler(AudioControlValue); virtual void AttackVolumeAudioHandler(AudioControlValue); virtual void AttackTimeAudioHandler(AudioControlValue); virtual void NoteAudioHandler(AudioControlValue); virtual void DurationAudioHandler(AudioControlValue); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // State implementations // public: virtual void StartImplementation(); virtual void StopImplementation(); virtual void SuspendImplementation(); virtual void ResumeImplementation(); protected: virtual void StartMessageImplementation() {} virtual void StopMessageImplementation() {} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Execution // public: Logical RequiresMaintenance(AudioHead *audio_head); Logical CanResume(AudioHead *audio_head); void Execute(); protected: virtual void ExecuteModel(Logical force_update) {} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Message Support // public: enum { StartMessageID = AudioComponent::NextMessageID, StopMessageID, NextMessageID }; typedef AudioSource__RequestMessage RequestMessage; typedef AudioSource__StartMessage StartMessage; typedef AudioSource__StopMessage StopMessage; static const HandlerEntry MessageHandlerEntries[]; //static MessageHandlerSet MessageHandlers; static MessageHandlerSet& GetMessageHandlers(); void StartMessageHandler(StartMessage *message); void StopMessageHandler(StopMessage *message); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Shared Data Support // public: static Derivation *GetClassDerivations(); static SharedData DefaultData; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private data // private: // // Location data // AudioLocation *audioLocation; // // Resource data // AudioResource *audioResource; // // State/Status data // AudioSourceState audioSourceState; AudioSourceStartState nextStartState, currentStartState; AudioControlValue attackVolumeScale; Logical useAttackTimeScale; AudioControlValue attackTimeScale; // // Priority data // AudioSourcePriority audioSourcePriority; // // Mixing and compression // AudioSourceMixPresence audioSourceMixPresence; AudioControlValue volumeCompressionScale; Logical hasCompressionCurve; AudioTime compressionDuration; AudioControlValue volumeMixScale; AudioPitchCents pitchMixOffset; Logical useBrightnessScale; AudioControlValue brightnessMixScale; AudioControlValue volumeScale; AudioPitchCents pitchOffset; AudioControlValue brightnessScale; // // Execution // AudioFrameCount nextExecuteFrame; AudioFrameCount suspendFinishedFrame; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioSource inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Location methods // inline AudioLocation* AudioSource::GetAudioLocation() { Check(this); return audioLocation; } inline void AudioSource::UpdateSpatialModel(AudioHead *audio_head) { Check(this); Check(audioLocation); audioLocation->UpdateSpatialModel(audio_head); } inline Scalar AudioSource::GetDistanceToSource() { Check(this); Check(audioLocation); return audioLocation->GetDistanceToSource(); } inline Logical AudioSource::IsAudioSourceClipped(AudioHead *audio_head) { Check(this); Check(audioLocation); return audioLocation->IsAudioLocationClipped(audio_head); } // // Resource methods // inline AudioResource* AudioSource::GetAudioResource() { Check(this); return audioResource; } inline AudioVoiceCount AudioSource::GetAudioVoiceCount() { Check(this); Check(audioResource); return audioResource->GetVoiceCount(); } inline AudioRenderType AudioSource::GetAudioRenderType() { Check(this); Check(audioResource); return audioResource->GetAudioRenderType(); } // // Current State/Status Accessors // inline AudioSourceState AudioSource::GetAudioSourceState() { Check(this); return audioSourceState; } inline Logical AudioSource::IsFinishedPlaying() { Check(this); return currentStartState.IsFinishedPlaying(); } inline AudioTime AudioSource::GetCurrentRunningTime() { Check(this); Verify(audioSourceState == RunningAudioSourceState); return currentStartState.GetCurrentRunningTime(); } inline AudioControlValue AudioSource::GetCurrentNoteValue() { Check(this); return currentStartState.GetNoteValue(); } inline AudioControlValue AudioSource::CalculateSourceAttackVolumeScale() { Check(this); return attackVolumeScale; } inline Logical AudioSource::UseSourceAttackTime() { Check(this); return useAttackTimeScale; } inline AudioControlValue AudioSource::CalculateSourceAttackTime() { Check(this); return attackTimeScale; } // // Priority Accessors // inline void AudioSource::SetAudioSourcePriority( AudioSourcePriority audio_source_priority ) { Check(this); audioSourcePriority = audio_source_priority; } inline AudioSourcePriority AudioSource::GetAudioSourcePriority() { Check(this); return audioSourcePriority; } inline AudioWeighting AudioSource::CalculateAudioWeighting() { Check(this); AudioWeighting audio_weight( GetAudioSourcePriority(), CalculateSourceVolumeScale() ); return audio_weight; } // // Mixing & Logical compression methods // inline AudioSourceMixPresence AudioSource::GetAudioSourceMixPresence() { Check(this); return audioSourceMixPresence; } inline void AudioSource::SetVolumeCompressionScale( AudioControlValue compression_level ) { Check(this); volumeCompressionScale = compression_level; } inline AudioPitchCents AudioSource::CalculateSourcePitchOffset() { Check(this); return pitchMixOffset + pitchOffset; } inline Logical AudioSource::UseSourceBrightnessScale() { Check(this); return useBrightnessScale; } // // Execute // inline Logical AudioSource::RequiresMaintenance(AudioHead *audio_head) { Check(this); Check(audio_head); return (nextExecuteFrame <= audio_head->GetAudioFrameCount()); } inline Logical AudioSource::CanResume(AudioHead *audio_head) { Check(this); Check(audio_head); return (suspendFinishedFrame <= audio_head->GetAudioFrameCount()); } //~~~~~~~~~~~~~~~~~~~~~~ AudioSource__RequestMessage ~~~~~~~~~~~~~~~~~~~~~~~ class AudioSource__RequestMessage: public Receiver::Message { public: AudioSource__RequestMessage( Receiver::MessageID id, size_t message_length, AudioControlID control_ID, AudioControlValue control_value ); AudioControlID controlID; AudioControlValue controlValue; }; inline AudioSource__RequestMessage::AudioSource__RequestMessage( Receiver::MessageID message_ID, size_t message_length, AudioControlID control_ID, AudioControlValue control_value ): Receiver::Message( message_ID, message_length ) { controlID = control_ID; controlValue = control_value; } //~~~~~~~~~~~~~~~~~~~~~~ AudioSource__StartMessage ~~~~~~~~~~~~~~~~~~~~~~~~~ class AudioSource__StartMessage: public AudioSource::RequestMessage { public: AudioSource__StartMessage(AudioControlValue control_value); }; inline AudioSource__StartMessage::AudioSource__StartMessage( AudioControlValue control_value ): AudioSource::RequestMessage( AudioSource::StartMessageID, sizeof(AudioSource__StartMessage), StartAudioControlID, control_value ) { } //~~~~~~~~~~~~~~~~~~~~~~ AudioSource__StopMessage ~~~~~~~~~~~~~~~~~~~~~~~~~~ class AudioSource__StopMessage: public AudioSource::RequestMessage { public: AudioSource__StopMessage(); }; inline AudioSource__StopMessage::AudioSource__StopMessage(): AudioSource::RequestMessage( AudioSource::StopMessageID, sizeof(AudioSource__StopMessage), StopAudioControlID, 0.0f ) { }