//===========================================================================// // File: l4audres.cpp // // Project: MUNGA Brick: Audio Renderer Manager // // Contents: // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 05/10/95 ECH Initial coding. // //---------------------------------------------------------------------------// // Copyright (C) 1994, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include #pragma hdrstop #if !defined(L4AUDRES_HPP) # include #endif #if !defined(L4AUDHDW_HPP) # include #endif #if !defined(L4AUDIO_HPP) # include #endif #if !defined(L4AUDLVL_HPP) # include #endif #if !defined(L4AUDWTR_HPP) # include #endif #if !defined(AUDCMP_HPP) # include #endif #if !defined(AUDSEQ_HPP) # include #endif #if !defined(AUDREND_HPP) # include #endif #if !defined(NAMELIST_HPP) # include #endif #if !defined(APP_HPP) # include #endif #if !defined(NOTATION_HPP) # include #endif //############################################################################# //####################### AudioObjectStream ############################# //############################################################################# // //############################################################################# // AudioObjectStream //############################################################################# // AudioObjectStream::AudioObjectStream( ResourceDescription *resource_description, Entity *the_entity ): PlugStream(resource_description) { entity = the_entity; } // //############################################################################# // AudioObjectStream //############################################################################# // AudioObjectStream::AudioObjectStream() { entity = NULL; } // //############################################################################# // ~AudioObjectStream //############################################################################# // AudioObjectStream::~AudioObjectStream() { } // //############################################################################# // TestInstance //############################################################################# // Logical AudioObjectStream::TestInstance() const { PlugStream::TestInstance(); if (entity != NULL) { Check(entity); } return True; } // //############################################################################# // MakeObjectImplementation //############################################################################# // RegisteredClass* AudioObjectStream::MakeObjectImplementation(Enumeration class_ID) { Check(this); Verify(class_ID != RegisteredClass::NullClassID); // //----------------------------------------------------------------------- // HACK - Constructors should be referenced through registration, for // now just use a switch statement //----------------------------------------------------------------------- // RegisteredClass *object; switch (class_ID) { // // Static resources ... // case RegisteredClass::PatchLevelOfDetailClassID: object = new PatchLevelOfDetail(this); break; case RegisteredClass::PatchResourceClassID: object = new PatchResource(this); break; case RegisteredClass::AudioResourceIndexClassID: object = new AudioResourceIndex(this); break; // // Location and sources ... // case RegisteredClass::L4AudioLocationClassID: object = new L4AudioLocation(this, entity); break; case RegisteredClass::DirectPatchSourceClassID: object = new DirectPatchSource(this, entity); break; case RegisteredClass::Dynamic3DPatchSourceClassID: object = new Dynamic3DPatchSource(this, entity); break; case RegisteredClass::Static3DPatchSourceClassID: object = new Static3DPatchSource(this, entity); break; // // Audio components ... // case RegisteredClass::AudioControlMixerClassID: object = new AudioControlMixer(this, entity); break; case RegisteredClass::AudioControlMultiplierClassID: object = new AudioControlMultiplier(this, entity); break; case RegisteredClass::AudioResourceSelectorClassID: object = new AudioResourceSelector(this, entity); break; case RegisteredClass::AudioControlSmootherClassID: object = new AudioControlSmoother(this, entity); break; case RegisteredClass::AudioSampleAndHoldClassID: object = new AudioSampleAndHold(this, entity); break; case RegisteredClass::AudioControlSendClassID: object = new AudioControlSend(this, entity); break; case RegisteredClass::AudioControlSequenceClassID: object = new AudioControlSequence(this, entity); break; case RegisteredClass::AudioControlSplitterClassID: object = new AudioControlSplitter(this, entity); break; case RegisteredClass::AudioLFOClassID: object = new AudioLFO(this, entity); break; // // Audio watchers ... // case RegisteredClass::AudioMotionTriggerClassID: object = new AudioMotionTrigger(this, entity); break; case RegisteredClass::AudioMotionScaleClassID: object = new AudioMotionScale(this, entity); break; case RegisteredClass::AudioHingeScaleClassID: object = new AudioHingeScale(this, entity); break; case RegisteredClass::AudioScalarTriggerClassID: object = new AudioScalarTrigger(this, entity); break; case RegisteredClass::AudioScalarScaleClassID: object = new AudioScalarScale(this, entity); break; case RegisteredClass::AudioLogicalTriggerClassID: object = new AudioLogicalTrigger(this, entity); break; case RegisteredClass::AudioEnumerationTriggerClassID: object = new AudioEnumerationTrigger(this, entity); break; case RegisteredClass::AudioIntegerTriggerClassID: object = new AudioIntegerTrigger(this, entity); break; case RegisteredClass::AudioControlsButtonTriggerClassID: object = new AudioControlsButtonTrigger(this, entity); break; case RegisteredClass::AudioStateTriggerClassID: object = new AudioStateTrigger(this, entity); break; case RegisteredClass::AudioIdleWatcherClassID: object = new AudioIdleWatcher(this, entity); break; case RegisteredClass::AudioEnumerationDeltaTriggerClassID: object = new AudioEnumerationDeltaTrigger(this, entity); break; case RegisteredClass::AudioScalarDeltaTriggerClassID: object = new AudioScalarDeltaTrigger(this, entity); break; case RegisteredClass::L4AudioCollisionTriggerClassID: object = new L4AudioCollisionTrigger(this, entity); break; case RegisteredClass::AudioMessageWatcherClassID: object = new AudioMessageWatcher(this, entity); break; case RegisteredClass::AudioControlsButtonMessageWatcherClassID: object = new AudioControlsButtonMessageWatcher(this, entity); break; // // Inherited behavior // default: object = PlugStream::MakeObjectImplementation(class_ID); break; } return object; } // //############################################################################# // CreatedObjectImplementation //############################################################################# // void AudioObjectStream::CreatedObjectImplementation( RegisteredClass *object, ObjectID object_ID ) { Check(this); Check(object); Verify(object_ID != NullObjectID); // // Decide which index to add object to // switch (object->GetClassID()) { case RegisteredClass::PatchLevelOfDetailClassID: case RegisteredClass::PatchResourceClassID: case RegisteredClass::AudioResourceIndexClassID: AddGlobalPlug(Cast_Object(Plug*, object), object_ID); break; default: AddLocalPlug(Cast_Object(Plug*, object), object_ID); break; } } // //############################################################################# // BuildFromPageImplementation //############################################################################# // void AudioObjectStream::BuildFromPageImplementation( NameList *name_list, Enumeration class_ID_enumeration, ObjectID object_ID ) { Check(this); Verify(class_ID_enumeration != RegisteredClass::NullClassID); Verify(object_ID != NullObjectID); // //----------------------------------------------------------------------- // HACK - Page interpreters should be referenced through registration, // for now just use a switch statement //----------------------------------------------------------------------- // RegisteredClass::ClassID class_ID = (RegisteredClass::ClassID)class_ID_enumeration; switch (class_ID) { // // Static resources ... // case RegisteredClass::PatchLevelOfDetailClassID: PatchLevelOfDetail::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::PatchResourceClassID: PatchResource::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioResourceIndexClassID: AudioResourceIndex::BuildFromPage(this, name_list, class_ID, object_ID); break; // // Location and sources ... // case RegisteredClass::L4AudioLocationClassID: L4AudioLocation::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::DirectPatchSourceClassID: DirectPatchSource::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::Dynamic3DPatchSourceClassID: Dynamic3DPatchSource::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::Static3DPatchSourceClassID: Static3DPatchSource::BuildFromPage(this, name_list, class_ID, object_ID); break; // // Audio components ... // case RegisteredClass::AudioControlMixerClassID: AudioControlMixer::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioControlMultiplierClassID: AudioControlMultiplier::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioResourceSelectorClassID: AudioResourceSelector::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioControlSmootherClassID: AudioControlSmoother::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioSampleAndHoldClassID: AudioSampleAndHold::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioControlSendClassID: AudioControlSend::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioControlSequenceClassID: AudioControlSequence::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioControlSplitterClassID: AudioControlSplitter::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioLFOClassID: AudioLFO::BuildFromPage(this, name_list, class_ID, object_ID); break; // // Audio watchers ... // case RegisteredClass::AudioMotionTriggerClassID: AudioMotionTrigger::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioMotionScaleClassID: AudioMotionScale::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioHingeScaleClassID: AudioHingeScale::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioScalarTriggerClassID: AudioScalarTrigger::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioScalarScaleClassID: AudioScalarScale::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioLogicalTriggerClassID: AudioLogicalTrigger::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioEnumerationTriggerClassID: AudioEnumerationTrigger::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioIntegerTriggerClassID: AudioIntegerTrigger::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioControlsButtonTriggerClassID: AudioControlsButtonTrigger::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioStateTriggerClassID: AudioStateTrigger::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioIdleWatcherClassID: AudioIdleWatcher::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioEnumerationDeltaTriggerClassID: AudioEnumerationDeltaTrigger::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioScalarDeltaTriggerClassID: AudioScalarDeltaTrigger::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::L4AudioCollisionTriggerClassID: L4AudioCollisionTrigger::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioMessageWatcherClassID: AudioMessageWatcher::BuildFromPage(this, name_list, class_ID, object_ID); break; case RegisteredClass::AudioControlsButtonMessageWatcherClassID: AudioControlsButtonMessageWatcher::BuildFromPage(this, name_list, class_ID, object_ID); break; // // Inherited behavior // default: PlugStream::BuildFromPageImplementation(name_list, class_ID, object_ID); break; } } // //############################################################################# // BuiltFromPageImplementation //############################################################################# // void AudioObjectStream::BuiltFromPageImplementation( Enumeration class_ID, ObjectID object_ID, const CString &object_name ) { Check(this); Verify(class_ID != RegisteredClass::NullClassID); Verify(object_ID != NullObjectID); Check(&object_name); // // Decide which index to add object to // if (object_name.Length() == 0) return; switch (class_ID) { case RegisteredClass::PatchLevelOfDetailClassID: case RegisteredClass::PatchResourceClassID: case RegisteredClass::AudioResourceIndexClassID: AddGlobalObjectID(object_ID, object_name); break; default: AddLocalObjectID(object_ID, object_name); break; } } //############################################################################# //###################### L4AudioResourceManager ######################### //############################################################################# // //############################################################################# // L4AudioResourceManager //############################################################################# // L4AudioResourceManager::L4AudioResourceManager() { } // //############################################################################# // ~L4AudioResourceManager //############################################################################# // L4AudioResourceManager::~L4AudioResourceManager() { } // //############################################################################# // TestInstance //############################################################################# // Logical L4AudioResourceManager::TestInstance() const { Node::TestInstance(); return True; } // //############################################################################# // PreloadResources //############################################################################# // void L4AudioResourceManager::PreloadResources( NotationFile *notation_file, AudioHardware *audio_hardware ) { Check(this); Check(notation_file); Check(audio_hardware); // //---------------------------------------------------------------------- // Load the sound banks //---------------------------------------------------------------------- // NameList *name_list; NameList::Entry *entry; Verify(notation_file->EntryCount("AudioResources") >= 2); name_list = notation_file->MakeEntryList("AudioResources"); Register_Object(name_list); entry = name_list->GetFirstEntry(); Check(entry); while (entry != NULL) { Check(entry); if (entry->IsName("front_audio_resource")) { Check_Pointer(entry->GetChar()); Check(audio_hardware->GetFrontCard()); audio_hardware->GetFrontCard()->LoadSBK(entry->GetChar()); } else { Verify(entry->IsName("rear_audio_resource")); Check_Pointer(entry->GetChar()); Check(audio_hardware->GetRearCard()); audio_hardware->GetRearCard()->LoadSBK(entry->GetChar()); } entry = entry->GetNextEntry(); } Unregister_Object(name_list); delete name_list; // //---------------------------------------------------------------------- // Create static audio objects //---------------------------------------------------------------------- // // // Get static audio stream resource // ResourceDescription *resource_description; Check(application); Check(application->GetResourceFile()); resource_description = application->GetResourceFile()->FindResourceDescription( "StaticAudioStream", ResourceDescription::StaticAudioStreamResourceType ); Check(resource_description); resource_description->Lock(); // // Parse the audio object stream // AudioObjectStream audio_object_stream(resource_description, NULL); Check(&audio_object_stream); audio_object_stream.CreateObjects(); resource_description->Unlock(); } // //############################################################################# // UnloadResources //############################################################################# // void L4AudioResourceManager::UnloadResources( AudioHardware *audio_hardware ) { Check(this); Check(audio_hardware); // //---------------------------------------------------------------------- // Release banks //---------------------------------------------------------------------- // Check(audio_hardware->GetFrontCard()); audio_hardware->GetFrontCard()->ReleaseAllBanks(); Check(audio_hardware->GetRearCard()); audio_hardware->GetRearCard()->ReleaseAllBanks(); } // //############################################################################# // CreateStaticAudioStreamResource //############################################################################# // ResourceDescription::ResourceID L4AudioResourceManager::CreateStaticAudioStreamResource( ResourceFile *resource_file ) { Check(resource_file); // //---------------------------------------------------------------------- // Open the notation file for the static stream resource //---------------------------------------------------------------------- // Tell("Opening Audio Script audio\\static.scp\n"); NotationFile notation_file("audio\\static.scp"); Check(¬ation_file); // //---------------------------------------------------------------------- // Build the static audio object stream //---------------------------------------------------------------------- // AudioObjectStream audio_object_stream; Check(&audio_object_stream); audio_object_stream.BuildFromNotationFile(¬ation_file, resource_file); Tell("Closed Audio Script\n"); // //---------------------------------------------------------------------- // Add the resource //---------------------------------------------------------------------- // ResourceDescription *res_description; res_description = resource_file->AddResourceMemoryStream( "StaticAudioStream", ResourceDescription::StaticAudioStreamResourceType, 1, ResourceDescription::Preload, &audio_object_stream ); Check(res_description); return res_description->resourceID; } // //############################################################################# // CreateEntityAudioObjects //############################################################################# // void L4AudioResourceManager::CreateEntityAudioObjects( Entity *entity, AudioRepresentation audio_representation ) { Check(this); Check(entity); Verify( audio_representation == InternalAudioRepresentation || audio_representation == ExternalAudioRepresentation ); // //------------------------------------------------------------------------ // Read the audio resource for this entity //------------------------------------------------------------------------ // ResourceDescription *audio_resource_description; Check(application); Check(application->GetResourceFile()); audio_resource_description = application->GetResourceFile()->SearchList( entity->GetResourceID(), ResourceDescription::AudioStreamListResourceType ); if (audio_resource_description == NULL) return; // //------------------------------------------------------------------------ // Read the appropriate resource for an internal or external // representation //------------------------------------------------------------------------ // ResourceDescription *stream_resource_description; Check(application); Check(application->GetResourceFile()); Check(audio_resource_description); stream_resource_description = application->GetResourceFile()->SearchList( audio_resource_description->resourceID, (audio_representation == InternalAudioRepresentation) ? ResourceDescription::InternalAudioStreamResourceType : ResourceDescription::ExternalAudioStreamResourceType ); if (stream_resource_description == NULL) return; Check(stream_resource_description); stream_resource_description->Lock(); audio_resource_description->Lock(); // //------------------------------------------------------------------------ // Make the audio object stream //------------------------------------------------------------------------ // AudioObjectStream audio_object_stream( stream_resource_description, entity ); Check(&audio_object_stream); audio_object_stream.CreateObjects(); stream_resource_description->Unlock(); audio_resource_description->Unlock(); } // //############################################################################# // DestroyEntityAudioObjects //############################################################################# // void L4AudioResourceManager::DestroyEntityAudioObjects(Entity *entity) { Check(this); Check(entity); // //-------------------------------------------------------------------------- // Stop and delete all audio objects //-------------------------------------------------------------------------- // Entity::AudioSocketIterator iterator(entity); Component *component; AudioComponent *audio_component; Check(&iterator); while ((component = iterator.ReadAndNext()) != NULL) { audio_component = Cast_Object(AudioComponent*, component); Check(audio_component); audio_component->ReceiveControl(StopAudioControlID, 0.0f); audio_component->ReceiveControl(FlushMessagesAudioControlID, 0.0f); } iterator.DeletePlugs(); } // //############################################################################# // CreateModelAudioResource //############################################################################# // ResourceDescription::ResourceID L4AudioResourceManager::CreateModelAudioStreamResource( ResourceFile *resource_file, const char *model_name, NotationFile *model_file, const ResourceDirectories* ) { Check(resource_file); Check_Pointer(model_name); Check(model_file); const char *script_name = NULL; ResourceDescription::ResourceID resource_id_list[3]; size_t list_length = 0; resource_id_list[0] = ResourceDescription::NullResourceID; resource_id_list[1] = ResourceDescription::NullResourceID; resource_id_list[2] = ResourceDescription::NullResourceID; // //-------------------------------------------------------------------------- // Check for the external audio script //-------------------------------------------------------------------------- // if (model_file->GetEntry("audio", "external", &script_name)) { // // See if the resource already exists // ResourceDescription *res_description = resource_file->FindResourceDescription( script_name, ResourceDescription::ExternalAudioStreamResourceType ); // //----------------------------------------------------------------------- // If not, create it //----------------------------------------------------------------------- // if (res_description == NULL) { // // Make the file name // CString file_name(script_name); CString prefix("audio\\"); file_name = prefix + file_name; // // Build the memory stream // Tell("Opening Audio Script " << file_name << "\n"); NotationFile script_file(file_name); AudioObjectStream audio_object_stream; Check(&script_file); Check(&audio_object_stream); audio_object_stream.BuildFromNotationFile(&script_file, resource_file); Tell("Closed Audio Script\n"); // // Add the resource // res_description = resource_file->AddResourceMemoryStream( script_name, ResourceDescription::ExternalAudioStreamResourceType, 1, ResourceDescription::Preload, &audio_object_stream ); } Check(res_description); resource_id_list[list_length++] = res_description->resourceID; } // //-------------------------------------------------------------------------- // Check for the internal audio script //-------------------------------------------------------------------------- // if (model_file->GetEntry("audio", "internal", &script_name)) { // // See if the resource already exists // ResourceDescription *res_description = resource_file->FindResourceDescription( script_name, ResourceDescription::InternalAudioStreamResourceType ); // // If not, create it // if (res_description == NULL) { // // Make the file name // CString file_name(script_name); CString prefix("audio\\"); file_name = prefix + file_name; // // Build the memory stream // Tell("Opening Audio Script " << file_name << "\n"); NotationFile script_file(file_name); AudioObjectStream audio_object_stream; Check(&script_file); Check(&audio_object_stream); audio_object_stream.BuildFromNotationFile(&script_file, resource_file); Tell("Closed Audio Script\n"); // // Add the resource // res_description = resource_file->AddResourceMemoryStream( script_name, ResourceDescription::InternalAudioStreamResourceType, 1, ResourceDescription::Preload, &audio_object_stream ); } Check(res_description); resource_id_list[list_length++] = res_description->resourceID; } // //-------------------------------------------------------------------------- // Check for the audio entity model //-------------------------------------------------------------------------- // const char *audio_entity_model = NULL; if (model_file->GetEntry("audio", "model", &audio_entity_model)) { // // The resource should already exist // ResourceDescription *res_description = resource_file->FindResourceDescription( audio_entity_model, ResourceDescription::ModelListResourceType ); if (res_description == NULL) { cout << "audio_entity_model == " << audio_entity_model; Fail("L4AudioResourceManager::CreateModelAudioStreamResource - model not found"); } Check(res_description); resource_id_list[list_length++] = res_description->resourceID; } // //-------------------------------------------------------------------------- // If either script has been created, then create the resource list //-------------------------------------------------------------------------- // if (list_length > 0) { ResourceDescription *res_description = resource_file->AddResourceList( model_name, ResourceDescription::AudioStreamListResourceType, 1, ResourceDescription::Preload, resource_id_list, list_length ); Check(res_description); return res_description->resourceID; } return ResourceDescription::NullResourceID; }