//===========================================================================// // File: audio.hh // // Project: MUNGA Brick: Audio manager // // Contents: // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 01/30/95 ECH Initial coding. // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include #pragma hdrstop #if !defined(AUDIO_HPP) # include #endif #if !defined(AUDREND_HPP) # include #endif #if !defined(APP_HPP) #include #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Audio Constants ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const Scalar AudioDoubleTriggerCutoff = 0.2f; const AudioControlValue MaxAudioVolume = 1.0f; const AudioControlValue MinAudioVolume = 0.0f; const AudioControlValue LowAudioVolumeThreshold = 0.3f; const AudioControlValue MaxAudioBrightness = 1.0f; const AudioControlValue MinAudioBrightness = 0.0f; const AudioControlValue MaxAudioAttack = 1.0f; const AudioControlValue MinAudioAttack = 0.0f; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioHead ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // AudioHead::AudioHead(): headEntitySocket(NULL) { // // Start frame counter at 0, other counts should be at // NullAudioFrameCount // audioFrameCount = 0; // // Other audio parameters // clippingRadius = 100.0f; distanceBetweenEars = 1.0f; amplitudeRollOffExponent = 1.0f; amplitudeRollOffKnee = 10.0f, amplitudeRollOffDistanceScale = 0.05f; highFrequencyRollOffExponent = 0.5f; highFrequencyRollOffKnee = 10.0f; highFrequencyRollOffDistanceScale = 0.05f; reverbToDryRatio = 0.1f; audioSoundSpeed = 345.0f; audioDopplerConstant = 20.0f; sourceCompressionExponent = 0.5f; sourceCompressionScale = 0.5f; Check_Fpu(); } // //############################################################################# //############################################################################# // AudioHead::~AudioHead() { Check(this); Check_Fpu(); } // //############################################################################# //############################################################################# // Logical AudioHead::TestInstance() const { Check(&headEntitySocket); return True; } // //############################################################################# //############################################################################# // void AudioHead::LinkToEntity(Entity *entity) { Check(this); Check(entity); // // Remove existing entity, add new one // if (headEntitySocket.GetCurrent() != NULL) { headEntitySocket.Remove(); } headEntitySocket.Add(entity); #if 0 // // Make the new clipping sphere // clippingSphere.SetCurrentOrigin(entity->localOrigin.linearPosition); #endif } // //############################################################################# //############################################################################# // LinearMatrix AudioHead::GetEarToWorld() { Check(this); Entity *entity = headEntitySocket.GetCurrent(); Check(entity); return entity->localToWorld; } // //############################################################################# //############################################################################# // void AudioHead::Execute() { Check(this); // // Increment frame counter // audioFrameCount++; Verify(audioFrameCount < LONG_MAX); #if 0 // // Get the entity // Entity *entity = headEntitySocket.GetCurrent(); Check(entity); // // Make the new clipping sphere // clippingSphere.SetCurrentOrigin(entity->localOrigin.linearPosition); #endif } // //############################################################################# //############################################################################# // void AudioHead::DefineClippingSphere(Scalar radius) { Check(this); clippingRadius = radius; #if 0 // // Get entity position // Entity *entity; Point3D position(0.0f, 0.0f, 0.0f); if ((entity = headEntitySocket.GetCurrent()) != NULL) { Check(entity); position = entity->localOrigin.linearPosition; } // // Make the new clipping sphere // clippingSphere.SetCurrentOrigin(position); clippingSphere.SetReferenceRadius(radius); #endif } // //############################################################################# //############################################################################# // Logical AudioHead::IsPointClipped(const Point3D &point) { Check(this); Entity *entity; Vector3D difference; entity = headEntitySocket.GetCurrent(); Check(entity); difference.Subtract(entity->localOrigin.linearPosition, point); return difference.LengthSquared() > clippingRadius*clippingRadius; } // //############################################################################# //############################################################################# // void AudioHead::ControlDopplerEffect( Scalar doppler_constant, Scalar sound_speed ) { Check(this); audioDopplerConstant = doppler_constant; audioSoundSpeed = sound_speed; Check_Fpu(); } // //############################################################################# //############################################################################# // void AudioHead::ControlAmplitudeRollOff( Scalar exponent, Scalar amplitude_rolloff_knee, Scalar distance_scale ) { Check(this); amplitudeRollOffExponent = exponent; amplitudeRollOffKnee = amplitude_rolloff_knee; amplitudeRollOffDistanceScale = distance_scale; Check_Fpu(); } // //############################################################################# //############################################################################# // void AudioHead::ControlHighFrequencyRollOff( Scalar exponent, Scalar high_frequency_rolloff_knee, Scalar distance_scale ) { Check(this); highFrequencyRollOffExponent = exponent; highFrequencyRollOffKnee = high_frequency_rolloff_knee; highFrequencyRollOffDistanceScale = distance_scale; Check_Fpu(); } // //############################################################################# //############################################################################# // void AudioHead::ControlSourceCompression( Scalar exponent, Scalar scale ) { Check(this); sourceCompressionExponent = exponent; sourceCompressionScale = scale; Check_Fpu(); } // //############################################################################# //############################################################################# // void AudioHead::SetPositionalCulling(Logical) { Check(this); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioComponent ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // const Receiver::HandlerEntry AudioComponent::MessageHandlerEntries[]= { { AudioComponent::ReceiveControlMessageID, "ReceiveControl", (AudioComponent::Handler)&AudioComponent::ReceiveControlMessageHandler } }; AudioComponent::MessageHandlerSet AudioComponent::MessageHandlers( ELEMENTS(AudioComponent::MessageHandlerEntries), AudioComponent::MessageHandlerEntries, Component::MessageHandlers ); // //############################################################################# //############################################################################# // Derivation AudioComponent::ClassDerivations( Component::ClassDerivations, "AudioComponent" ); AudioComponent::SharedData AudioComponent::DefaultData( AudioComponent::ClassDerivations, AudioComponent::MessageHandlers ); // //############################################################################# //############################################################################# // AudioComponent::AudioComponent( PlugStream *stream, SharedData &shared_data ): Component(stream, shared_data), audioWatcherSocket(NULL) { nextExecuteWatcherFrame = NullAudioFrameCount; } // //############################################################################# //############################################################################# // AudioComponent::~AudioComponent() { } // //############################################################################# //############################################################################# // Logical AudioComponent::TestInstance() const { if (!IsDerivedFrom(ClassDerivations)) { return False; } Check(&audioWatcherSocket); return True; } // //############################################################################# //############################################################################# // void AudioComponent::ExecuteWatchers() { Check(this); // // Execute watchers if this is the next watcher frame // AudioFrameCount audio_frame_count; Check(application); Check(application->GetAudioRenderer()); audio_frame_count = application->GetAudioRenderer()->GetAudioFrameCount(); if (nextExecuteWatcherFrame <= audio_frame_count) { nextExecuteWatcherFrame = audio_frame_count + DefaultAudioFrameDelay; // // Execute watchers // ChainIteratorOf iterator(&audioWatcherSocket); Component *component; while ((component = iterator.ReadAndNext()) != NULL) { Check(component); component->Execute(); } } } // //############################################################################# //############################################################################# // void AudioComponent::Execute() { Check(this); ExecuteWatchers(); Check_Fpu(); } // //############################################################################# //############################################################################# // void AudioComponent::ReceiveControl( AudioControlID, AudioControlValue ) { Fail("AudioComponent::ReceiveControl - Should never reach here"); } // //############################################################################# //############################################################################# // void AudioComponent::PostReceiveControl( AudioControlID control_ID, AudioControlValue control_value ) { Check(this); ReceiveControlMessage message(control_ID, control_value); Check(application); // ECH 1/26/96 - application->Post(HighEventPriority, this, &message); application->Post(DefaultEventPriority, this, &message); Check_Fpu(); } // //############################################################################# //############################################################################# // void AudioComponent::ReceiveControlMessageHandler(ReceiveControlMessage *message) { Check(this); Check(message); ReceiveControl(message->controlID, message->controlValue); Check_Fpu(); } //~~~~~~~~~~~~~~~~~~ AudioComponent__ReceiveControlMessage ~~~~~~~~~~~~~~~~~~~~ AudioComponent__ReceiveControlMessage::AudioComponent__ReceiveControlMessage( AudioControlID control_ID, AudioControlValue control_value ): Receiver::Message( AudioComponent::ReceiveControlMessageID, sizeof(AudioComponent__ReceiveControlMessage) ) { controlID = control_ID; controlValue = control_value; }