#include #include #include #include #include "mungal4.h" #pragma hdrstop #include "l4audres.h" #include "l4audhdw.h" #include "l4audio.h" #include "l4audlvl.h" #include "l4audwtr.h" #include "..\munga\audcmp.h" #include "..\munga\audseq.h" #include "..\munga\audrend.h" #include "..\munga\namelist.h" #include "..\munga\app.h" #include "..\munga\notation.h" #include "openal\al.h" #include "openal\alc.h" ALuint *g_buffers; int g_numBuffers; int g_curAudioWatcherClass = 0; // // Minimal canonical-PCM WAV reader. The repo's libsndfile-1.dll is a STUB // (exports 15 funcs by ordinal only, no names -- sf_open always returns NULL // and sf_strerror(NULL) faults), so the original sf_open path loaded nothing. // Our soundbank samples (AUDIO1/2.RES, cracked by scratchpad/sf2extract.py) // are written as plain 16-bit mono PCM WAVs, so a tiny RIFF/WAVE fmt+data // parser loads the real sample data directly into the AL buffer -- no // external dependency, no stub. Handles 8/16-bit mono/stereo PCM. // static bool LoadWavPCM(const char *path, char **outData, int *outBytes, int *outChannels, int *outBits, int *outRate) { FILE *fp = fopen(path, "rb"); if (!fp) return false; fseek(fp, 0, SEEK_END); long flen = ftell(fp); fseek(fp, 0, SEEK_SET); if (flen < 44) { fclose(fp); return false; } unsigned char *buf = new unsigned char[flen]; size_t got = fread(buf, 1, flen, fp); fclose(fp); if ((long)got != flen) { delete [] buf; return false; } if (memcmp(buf, "RIFF", 4) != 0 || memcmp(buf + 8, "WAVE", 4) != 0) { delete [] buf; return false; } int channels = 0, bits = 0, rate = 0; char *pcm = 0; int pcmBytes = 0; bool haveFmt = false; long p = 12; while (p + 8 <= flen) { const unsigned char *id = buf + p; unsigned int csz = buf[p+4] | (buf[p+5]<<8) | (buf[p+6]<<16) | ((unsigned)buf[p+7]<<24); long body = p + 8; if (memcmp(id, "fmt ", 4) == 0 && csz >= 16) { channels = buf[body+2] | (buf[body+3]<<8); rate = buf[body+4] | (buf[body+5]<<8) | (buf[body+6]<<16) | ((unsigned)buf[body+7]<<24); bits = buf[body+14] | (buf[body+15]<<8); haveFmt = true; } else if (memcmp(id, "data", 4) == 0) { long avail = flen - body; pcmBytes = ((long)csz <= avail) ? (int)csz : (int)avail; if (pcmBytes < 0) pcmBytes = 0; pcm = new char[pcmBytes > 0 ? pcmBytes : 1]; memcpy(pcm, buf + body, pcmBytes); } p = body + csz + (csz & 1); // RIFF chunks are word-aligned } delete [] buf; if (!haveFmt || pcm == 0) { delete [] pcm; return false; } *outData = pcm; *outBytes = pcmBytes; *outChannels = channels; *outBits = bits; *outRate = rate; return true; } //############################################################################# //####################### 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); // DIAG (BT_ATTRBIND_LOG): record which audio-object ClassID is being built so the // AttributeWatcher trace can print the watcher TYPE alongside the bound attribute. extern int g_curAudioWatcherClass; g_curAudioWatcherClass = (int)class_ID; // //----------------------------------------------------------------------- // 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); // // std::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); // // std::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() { g_buffers = NULL; g_numBuffers = 0; } // //############################################################################# // ~L4AudioResourceManager //############################################################################# // L4AudioResourceManager::~L4AudioResourceManager() { } // //############################################################################# // TestInstance //############################################################################# // Logical L4AudioResourceManager::TestInstance() const { Node::TestInstance(); return True; } // //############################################################################# // PreloadResources //############################################################################# // void L4AudioResourceManager::PreloadResources( NotationFile *notation_file ) { Check(this); Check(notation_file); //Check(audio_hardware); //Determine how many loadable samples exist g_numBuffers=0; for(int i=1; i <= 2; i++) { for (int j=0; j < 128; j++) { if (PRESET_isImplemented(i,j)) { g_numBuffers += PRESET_getNumSamples(i,j); } } } //Generate the buffers if (g_numBuffers > 0) { //Generate buffers alGetError(); g_buffers = new ALuint[g_numBuffers]; alGenBuffers(g_numBuffers,g_buffers); if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] alGenBuffers count=" << g_numBuffers << "\n" << std::flush; ALenum error; if ((error = alGetError()) != AL_NO_ERROR) { DEBUG_STREAM << "OpenAL has encountered an error while initializing the buffers." << std::endl; delete [] g_buffers; g_buffers = NULL; g_numBuffers = 0; } } int bufferInd = 0; //Load buffers for(int i=1; i<=2 && bufferInd < g_numBuffers; i++) { for(int j=0; j<128 && bufferInd < g_numBuffers; j++) { if (PRESET_isImplemented(i,j)) { for (int k=0; k < PRESET_getNumSamples(i,j) && bufferInd < g_numBuffers; k++) { SAMPLEINFO info = PRESET_getSampleInfo(i,j,k); //Open WAV char fullname[50]; strcpy_s(fullname,50,"AUDIO/"); strcat_s(fullname,50,info.file); char *data = 0; int size = 0; int wavCh = 0, wavBits = 0, wavRate = 0; if (!LoadWavPCM(fullname, &data, &size, &wavCh, &wavBits, &wavRate)) { if (getenv("BT_AUDIO_LOG") && bufferInd == 0) { char cwd[512]; cwd[0]=0; _getcwd(cwd, sizeof(cwd)); DEBUG_STREAM << "[audio] DIAG cwd=[" << cwd << "] path=[" << fullname << "] WAV load FAILED\n" << std::flush; } DEBUG_STREAM << "[audio] Failed to open AUDIO/" << info.file << " -- skipping\n" << std::flush; PRESET_setBufferIndex(i,j,k,bufferInd); bufferInd++; continue; } ALenum format; if (wavBits == 8) format = (wavCh == 1) ? AL_FORMAT_MONO8 : AL_FORMAT_STEREO8; else format = (wavCh == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; //Feed the buffer with the real PCM sample data alBufferData(g_buffers[bufferInd], format, data, size, wavRate); if (getenv("BT_AUDIO_LOG") && bufferInd < 3) DEBUG_STREAM << "[audio] loaded buf" << bufferInd << " " << info.file << " ch=" << wavCh << " bits=" << wavBits << " rate=" << wavRate << " bytes=" << size << " alErr=" << alGetError() << "\n" << std::flush; PRESET_setBufferIndex(i,j,k,bufferInd); bufferInd++; delete [] data; } } } } if (getenv("BT_AUDIO_TEST") && g_numBuffers > 0) { // PROOF OF LIFE: play the first loaded sample so we can confirm the // SF2 -> WAV -> OpenAL buffer -> speakers path works end to end. ALCcontext *ctx = alcGetCurrentContext(); alGetError(); ALuint testsrc = 0; alGenSources(1, &testsrc); ALenum genErr = alGetError(); alSourcei(testsrc, AL_BUFFER, g_buffers[0]); ALenum bufErr = alGetError(); alSourcei(testsrc, AL_LOOPING, AL_TRUE); alSourcef(testsrc, AL_GAIN, 1.0f); alSourcePlay(testsrc); ALenum playErr = alGetError(); ALint st = 0; alGetSourcei(testsrc, AL_SOURCE_STATE, &st); DEBUG_STREAM << "[audio] TEST-PLAY buffer0 src=" << testsrc << " ctx=" << (void*)ctx << " genErr=" << genErr << " bufErr=" << bufErr << " playErr=" << playErr << " state=" << st << " playing=" << (int)(st==AL_PLAYING) << "\n" << std::flush; } // //---------------------------------------------------------------------- // 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(); } ALuint AL_getBuffer(int index) { return g_buffers[index]; } // //############################################################################# // UnloadResources //############################################################################# // void L4AudioResourceManager::UnloadResources( ) { Check(this); // Check(audio_hardware); //Unload wav data if (g_numBuffers > 0) { alGetError(); alDeleteBuffers(g_numBuffers,g_buffers); ALenum error = alGetError(); if (error != AL_NO_ERROR) { DEBUG_STREAM << "OpenAL reached an error when attempting to delete its buffers." << std::endl; } } // //---------------------------------------------------------------------- // 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) { std::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; }