#include #include "munga.h" #pragma hdrstop #include "audcmp.h" #include "audsrc.h" #include "random.h" #include "controls.h" #include "objstrm.h" #include "subsystm.h" #include "namelist.h" //############################################################################# //######################### AudioMessageWatcher ######################### //############################################################################# // //############################################################################# //############################################################################# // AudioMessageWatcher::AudioMessageWatcher( PlugStream *stream, Entity *entity ): AudioComponent(stream), audioComponentSocket(NULL), messageTap(NULL) { Check(stream); Check(entity); // // HACK - Get simulation pointer using names // Simulation *simulation; CString subsystem_name; MemoryStream_Read(stream, &subsystem_name); if ((simulation = entity->FindSubsystem(subsystem_name)) == NULL) { #if DEBUG_LEVEL>0 { CString entity_name("Entity"); if (!(subsystem_name == entity_name)) { Dump(subsystem_name); } Verify(subsystem_name == entity_name); } #else { CString entity_name("Entity"); if (!(subsystem_name == entity_name)) { DEBUG_STREAM << "MessageWatcher::MessageWatcher - subsystem " << subsystem_name << "\n"; Fail("MessageWatcher::MessageWatcher - subsystem not found\n"); } } #endif simulation = entity; } Check(simulation); // // Get message id // Receiver::MessageID message_ID; MemoryStream_Read(stream, &message_ID); // // Get audio component, control ID, control value // AudioComponent *audio_component; PlugStream_ReadObjectIDAndFindPlug(stream, &audio_component); MemoryStream_Read(stream, &controlID); MemoryStream_Read(stream, &controlValue); audioComponentSocket.Add(audio_component); // // Make the message tap // messageTap = MakeMessageTap( simulation->GetDerivation(), (ScanCallback)&AudioMessageWatcher::MessageTapScanCallback, message_ID, simulation ); Register_Object(messageTap); entity->AddAudioComponent(this); #if DEBUG_LEVEL>0 verifyReceiver = simulation; verifyMessageID = message_ID; #endif } // //############################################################################# //############################################################################# // AudioMessageWatcher::~AudioMessageWatcher() { Unregister_Object(messageTap); delete messageTap; } // //############################################################################# //############################################################################# // void AudioMessageWatcher::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioComponent::BuildFromPage(stream, name_list, class_ID, object_ID); // // HACK - Store simulation pointer using names // MEM_STRM_WRITE_ENTRY(*stream, name_list, CString, subsystem); // // Store message ID // MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, message_ID); // // Store audio_component, control ID, control value // CString audio_component_name("audio_component"); PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_component_name); MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, control_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, AudioControlValue, control_value); } // //############################################################################# //############################################################################# // Logical AudioMessageWatcher::TestInstance() const { Component::TestInstance(); if (messageTap != NULL) { Check(messageTap); } Check(&audioComponentSocket); return True; } // //############################################################################# //############################################################################# // #if DEBUG_LEVEL>0 void AudioMessageWatcher::MessageTapScanCallback( Receiver::Message *message, Receiver *receiver ) #else void AudioMessageWatcher::MessageTapScanCallback( Receiver::Message *message, Receiver* ) #endif { Check(this); Check(message); Check(receiver); Verify(verifyReceiver == receiver); Verify(verifyMessageID == message->messageID); // // Send the audio control message // if (DoesMessageMatch(message)) { Check(audioComponentSocket.GetCurrent()); #if 1 audioComponentSocket.GetCurrent()->ReceiveControl( controlID, controlValue ); #else audioComponentSocket.GetCurrent()->PostReceiveControl( controlID, controlValue ); #endif } } // //############################################################################# //############################################################################# // void AudioMessageWatcher::ReceiveControl( AudioControlID, AudioControlValue ) { } //############################################################################# //################# AudioControlsButtonMessageWatcher ################### //############################################################################# // //############################################################################# //############################################################################# // AudioControlsButtonMessageWatcher::AudioControlsButtonMessageWatcher( PlugStream *stream, Entity *entity ): AudioMessageWatcher(stream, entity) { } // //############################################################################# //############################################################################# // AudioControlsButtonMessageWatcher::~AudioControlsButtonMessageWatcher() { } // //############################################################################# //############################################################################# // Logical AudioControlsButtonMessageWatcher::DoesMessageMatch( Receiver::Message *message ) { Check(this); Check(message); ReceiverDataMessageOf *controls_button_message = Cast_Object( ReceiverDataMessageOf*, message ); Check(controls_button_message); return (controls_button_message->dataContents > 0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioControlSend ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // AudioControlSend::~AudioControlSend() { } // //############################################################################# //############################################################################# // AudioControlSend::AudioControlSend( PlugStream *stream, Entity *entity ): AudioComponent(stream) { AudioComponent *audio_component; AudioControlID control_ID; AudioControlValue control_value; PlugStream_ReadObjectIDAndFindPlug(stream, &audio_component); MemoryStream_Read(stream, &control_ID); MemoryStream_Read(stream, &control_value); Check(entity); entity->AddAudioComponent(this); Check(audio_component); #if 1 audio_component->ReceiveControl(control_ID, control_value); #else audio_component->PostReceiveControl(control_ID, control_value); #endif } // //############################################################################# //############################################################################# // void AudioControlSend::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioComponent::BuildFromPage(stream, name_list, class_ID, object_ID); // // Store fields // CString audio_component_name("audio_component"); PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_component_name); MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, control_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, AudioControlValue, control_value); } // //############################################################################# //############################################################################# // void AudioControlSend::ReceiveControl( AudioControlID, AudioControlValue ) { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioControlSplitter ~~~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // AudioControlSplitter::AudioControlSplitter( PlugStream *stream, Entity *entity ): AudioComponent(stream), audioComponentSocket(NULL) { int i, number_of_entries; MemoryStream_Read(stream, &number_of_entries); for (i = 0; i < number_of_entries; i++) { AudioComponent *audio_component; PlugStream_ReadObjectIDAndFindPlug(stream, &audio_component); Check(audio_component); audioComponentSocket.Add(audio_component); audio_component->AddWatcher(this); } Check(entity); entity->AddAudioComponent(this); } // //############################################################################# //############################################################################# // AudioControlSplitter::~AudioControlSplitter() { } // //############################################################################# //############################################################################# // void AudioControlSplitter::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioComponent::BuildFromPage(stream, name_list, class_ID, object_ID); // // Count number of entries // int number_of_entries = 0; NameList::Entry *entry; Check(name_list); entry = name_list->GetFirstEntry(); while (entry != NULL) { Check(entry); if (entry->IsName("audio_component")) number_of_entries++; entry = entry->GetNextEntry(); } // // Store entries // MemoryStream_Write(stream, &number_of_entries); Check(name_list); entry = name_list->GetFirstEntry(); while (entry != NULL) { Check(entry); if (entry->IsName("audio_component")) { CString object_name; ObjectID object_ID; Check_Pointer(entry->GetChar()); object_name = entry->GetChar(); Check(stream); object_ID = stream->FindObjectID(object_name); if (object_ID == NullObjectID) { std::cout << "AudioControlSplitter::BuildFromPage - object_name == "; std::cout << object_name << "\n"; Fail("AudioControlSplitter::BuildFromPage - object_ID == NullObjectID"); } Verify(object_ID != NullObjectID); MemoryStream_Write(stream, &object_ID); } entry = entry->GetNextEntry(); } } // //############################################################################# //############################################################################# // Logical AudioControlSplitter::TestInstance() const { AudioComponent::TestInstance(); Check(&audioComponentSocket); return True; } // //############################################################################# //############################################################################# // void AudioControlSplitter::ReceiveControl( AudioControlID control_ID, AudioControlValue control_value ) { Check(this); // // Send to all of the components in the socket // SChainIteratorOf iterator(&audioComponentSocket); AudioComponent *audio_component; Check(&iterator); while ((audio_component = iterator.ReadAndNext()) != NULL) { Check(audio_component); audio_component->ReceiveControl(control_ID, control_value); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioControlMixer ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // AudioControlMixer::~AudioControlMixer() { } // //############################################################################# //############################################################################# // AudioControlMixer::AudioControlMixer( PlugStream *stream, Entity *entity ): AudioComponent(stream), audioComponentSocket(NULL) { AudioComponent *audio_component; AudioControlID first_input_control_ID; AudioControlID last_input_control_ID; AudioControlID output_control_ID; PlugStream_ReadObjectIDAndFindPlug(stream, &audio_component); MemoryStream_Read(stream, &first_input_control_ID); MemoryStream_Read(stream, &last_input_control_ID); MemoryStream_Read(stream, &output_control_ID); AudioControlMixerX( audio_component, entity, first_input_control_ID, last_input_control_ID, output_control_ID ); } // //############################################################################# //############################################################################# // void AudioControlMixer::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioComponent::BuildFromPage(stream, name_list, class_ID, object_ID); // // Store fields // CString audio_component_name("audio_component"); PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_component_name); MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, first_input_control_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, last_input_control_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, output_control_ID); } // //############################################################################# //############################################################################# // void AudioControlMixer::AudioControlMixerX( AudioComponent *audio_component, Entity *entity, AudioControlID first_input_control_ID, AudioControlID last_input_control_ID, AudioControlID output_control_ID ) { // // Set up the control mix parameters // firstInputControlID = first_input_control_ID; outputControlID = output_control_ID; Verify(last_input_control_ID > first_input_control_ID); numberOfInputs = last_input_control_ID - first_input_control_ID + 1; Verify(numberOfInputs <= AUDIO_CONTROL_MIXER_MAX_CONTROLS); for (int i = 0; i < numberOfInputs; i++) { Verify(i >= 0 && i < AUDIO_CONTROL_MIXER_MAX_CONTROLS); controlValueArray[i] = 0.0f; } // // Remember the audio component to mix to and add this // component to the entity // Check(audio_component); audioComponentSocket.Add(audio_component); audio_component->AddWatcher(this); Check(entity); entity->AddAudioComponent(this); } // //############################################################################# //############################################################################# // Logical AudioControlMixer::TestInstance() const { AudioComponent::TestInstance(); Check(&audioComponentSocket); return True; } // //############################################################################# //############################################################################# // void AudioControlMixer::ReceiveControl( AudioControlID control_ID, AudioControlValue control_value ) { Check(this); // // Index the controller into the mix table // int index = control_ID - firstInputControlID; if (index >= 0 && index < numberOfInputs) { // // Set the control value // Verify(index >= 0 && index < AUDIO_CONTROL_MIXER_MAX_CONTROLS); controlValueArray[index] = control_value; // // Mix the new control value // AudioControlValue mixed_value = 0.0f; for (int i = 0; i < numberOfInputs; i++) { Verify(i >= 0 && i < AUDIO_CONTROL_MIXER_MAX_CONTROLS); mixed_value += controlValueArray[i]; } Check(audioComponentSocket.GetCurrent()); if (getenv("BT_AUDIO_SPATIAL")) { static int s_mix=0; if (s_mix++<80) DEBUG_STREAM << "[mix] mixer=" << (void*)this << " -> tgt=" << (void*)audioComponentSocket.GetCurrent() << " outCtl=" << (int)outputControlID << " in[" << index << "]=" << control_value << " sum=" << mixed_value << "\n" << std::flush; } audioComponentSocket.GetCurrent()->ReceiveControl( outputControlID, mixed_value ); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioControlMultiplier ~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // AudioControlMultiplier::~AudioControlMultiplier() { } // //############################################################################# //############################################################################# // AudioControlMultiplier::AudioControlMultiplier( PlugStream *stream, Entity *entity ): AudioComponent(stream), audioComponentSocket(NULL) { AudioComponent *audio_component; AudioControlID first_input_control_ID; AudioControlID last_input_control_ID; AudioControlID output_control_ID; PlugStream_ReadObjectIDAndFindPlug(stream, &audio_component); MemoryStream_Read(stream, &first_input_control_ID); MemoryStream_Read(stream, &last_input_control_ID); MemoryStream_Read(stream, &output_control_ID); AudioControlMultiplierX( audio_component, entity, first_input_control_ID, last_input_control_ID, output_control_ID ); } // //############################################################################# //############################################################################# // void AudioControlMultiplier::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioComponent::BuildFromPage(stream, name_list, class_ID, object_ID); // // Store fields // CString audio_component_name("audio_component"); PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_component_name); MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, first_input_control_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, last_input_control_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, output_control_ID); } // //############################################################################# //############################################################################# // void AudioControlMultiplier::AudioControlMultiplierX( AudioComponent *audio_component, Entity *entity, AudioControlID first_input_control_ID, AudioControlID last_input_control_ID, AudioControlID output_control_ID ) { // // Set up the control mix parameters // firstInputControlID = first_input_control_ID; outputControlID = output_control_ID; Verify(last_input_control_ID > first_input_control_ID); numberOfInputs = last_input_control_ID - first_input_control_ID + 1; Verify(numberOfInputs <= AUDIO_CONTROL_MULTIPLIER_MAX_CONTROLS); for (int i = 0; i < numberOfInputs; i++) { Verify(i >= 0 && i < AUDIO_CONTROL_MULTIPLIER_MAX_CONTROLS); controlValueArray[i] = 1.0f; } // // Remember the audio component to mix to and add this // component to the entity // Check(audio_component); audioComponentSocket.Add(audio_component); audio_component->AddWatcher(this); Check(entity); entity->AddAudioComponent(this); } // //############################################################################# //############################################################################# // Logical AudioControlMultiplier::TestInstance() const { AudioComponent::TestInstance(); Check(&audioComponentSocket); return True; } // //############################################################################# //############################################################################# // void AudioControlMultiplier::ReceiveControl( AudioControlID control_ID, AudioControlValue control_value ) { Check(this); // // Index the controller into the mix table // int index = control_ID - firstInputControlID; if (index >= 0 && index < numberOfInputs) { // // Set the control value // Verify(index >= 0 && index < AUDIO_CONTROL_MULTIPLIER_MAX_CONTROLS); controlValueArray[index] = control_value; // // Multiply the new control value // AudioControlValue mult_value = 1.0f; for (int i = 0; i < numberOfInputs; i++) { Verify(i >= 0 && i < AUDIO_CONTROL_MULTIPLIER_MAX_CONTROLS); mult_value *= controlValueArray[i]; } Check(audioComponentSocket.GetCurrent()); if (getenv("BT_AUDIO_SPATIAL") && mult_value <= 0.0f) { static int s_mx=0; if (s_mx++<300) DEBUG_STREAM << "[mult0] mult=" << (void*)this << " -> tgt=" << (void*)audioComponentSocket.GetCurrent() << " in[" << index << "]=" << control_value << " product=" << mult_value << "\n" << std::flush; } audioComponentSocket.GetCurrent()->ReceiveControl( outputControlID, mult_value ); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioControlSmoother ~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // AudioControlSmoother::~AudioControlSmoother() { } // //############################################################################# //############################################################################# // AudioControlSmoother::AudioControlSmoother( PlugStream *stream, Entity *entity ): AudioComponent(stream), audioComponentSocket(NULL) { // // Get audio component // AudioComponent *audio_component; PlugStream_ReadObjectIDAndFindPlug(stream, &audio_component); // // Get audio control id, sample size, and initial fill value // size_t number_of_samples; AudioControlValue initial_fill_value; AudioControlID control_ID; MemoryStream_Read(stream, &control_ID); MemoryStream_Read(stream, &number_of_samples); MemoryStream_Read(stream, &initial_fill_value); audioControlAverage.SetSize(number_of_samples, initial_fill_value); AudioControlSmootherX( audio_component, entity, control_ID ); } // //############################################################################# //############################################################################# // void AudioControlSmoother::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioComponent::BuildFromPage(stream, name_list, class_ID, object_ID); // // Store audio component // CString audio_component_name("audio_component"); PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_component_name); // // Store audio control id, sample size, and initial fill value // MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, control_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, size_t, number_of_samples); AudioControlValue initial_fill_value = 0.0f; if (name_list->FindData("initial_fill_value") != NULL) { Check_Pointer(name_list->FindData("initial_fill_value")); Convert_From_Ascii( (const char *)name_list->FindData("initial_fill_value"), &initial_fill_value ); } MemoryStream_Write(stream, &initial_fill_value); } // //############################################################################# //############################################################################# // void AudioControlSmoother::AudioControlSmootherX( AudioComponent *audio_component, Entity *entity, AudioControlID control_ID ) { controlID = control_ID; // // Remember the audio component and add this // component to the entity // Check(audio_component); audioComponentSocket.Add(audio_component); audio_component->AddWatcher(this); Check(entity); entity->AddAudioComponent(this); } // //############################################################################# //############################################################################# // Logical AudioControlSmoother::TestInstance() const { AudioComponent::TestInstance(); Check(&audioComponentSocket); Check(&audioControlAverage); return True; } // //############################################################################# //############################################################################# // void AudioControlSmoother::ReceiveControl( AudioControlID control_ID, AudioControlValue control_value ) { Check(this); if (control_ID == controlID) { audioControlAverage.Add(control_value); Check(audioComponentSocket.GetCurrent()); audioComponentSocket.GetCurrent()->ReceiveControl( controlID, audioControlAverage.CalculateOlympicAverage() ); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioResourceSelector ~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // AudioResourceSelector::~AudioResourceSelector() { } // //############################################################################# //############################################################################# // AudioResourceSelector::AudioResourceSelector( PlugStream *stream, Entity *entity ): AudioComponent(stream), audioSourceSocket(NULL) { AudioSource *audio_source; AudioResourceIndex *audio_resource_index; AudioControlID control_ID; AudioControlValue min_control_value; AudioControlValue max_control_value; Logical dump_value; PlugStream_ReadObjectIDAndFindPlug(stream, &audio_source); PlugStream_ReadObjectIDAndFindPlug(stream, &audio_resource_index); MemoryStream_Read(stream, &control_ID); MemoryStream_Read(stream, &min_control_value); MemoryStream_Read(stream, &max_control_value); MemoryStream_Read(stream, &dump_value); AudioResourceSelectorX( audio_source, entity, audio_resource_index, control_ID, min_control_value, max_control_value, dump_value ); } // //############################################################################# //############################################################################# // void AudioResourceSelector::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioComponent::BuildFromPage(stream, name_list, class_ID, object_ID); // // Store fields // CString audio_source_name("audio_source"); PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_source_name); CString audio_resource_index_name("audio_resource_index"); PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_resource_index_name); MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, control_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, AudioControlValue, min_control_value); MEM_STRM_WRITE_ENTRY(*stream, name_list, AudioControlValue, max_control_value); MEM_STRM_WRITE_ENTRY(*stream, name_list, Logical, dump_value); } // //############################################################################# //############################################################################# // void AudioResourceSelector::AudioResourceSelectorX( AudioSource *audio_source, Entity *entity, AudioResourceIndex *audio_resource_index, AudioControlID control_ID, AudioControlValue min_control_value, AudioControlValue max_control_value, Logical dump_value ) { controlID = control_ID; minControlValue = min_control_value; maxControlValue = max_control_value; dumpValue = dump_value; Check(audio_resource_index); audioResourceIndex = audio_resource_index; Check(audio_source); audioSourceSocket.Add(audio_source); audio_source->AddWatcher(this); Check(entity); entity->AddAudioComponent(this); } // //############################################################################# //############################################################################# // Logical AudioResourceSelector::TestInstance() const { AudioComponent::TestInstance(); Check(&audioSourceSocket); Check(audioResourceIndex); return True; } // //############################################################################# //############################################################################# // void AudioResourceSelector::ReceiveControl( AudioControlID control_ID, AudioControlValue control_value ) { Check(this); if (control_ID == controlID) { AudioComponent *audio_component; AudioSource *audio_source; audio_component = audioSourceSocket.GetCurrent(); audio_source = Cast_Object(AudioSource*, audio_component); Check(audio_source); if (audio_source->GetAudioSourceState() == StoppedAudioSourceState) { AudioResource *audio_resource; int index; Clamp(control_value, minControlValue, maxControlValue); Verify(!Small_Enough(maxControlValue - minControlValue)); index = ( ((Scalar)audioResourceIndex->GetSize()-1.0f) * (control_value - minControlValue) / (maxControlValue - minControlValue) ) + 0.5f; #if DEBUG_LEVEL>0 if (!(index >= 0 && index < audioResourceIndex->GetSize())) { Dump(control_value); Dump(index); Dump(audioResourceIndex->GetSize()); } #endif Verify(index >= 0 && index < audioResourceIndex->GetSize()); #if DEBUG_LEVEL>0 if (dumpValue) { Tell("index:" << index); Tell("; size: " << audioResourceIndex->GetSize() << "\n"); } #endif audio_resource = audioResourceIndex->GetAudioResource(index); Check(audio_resource); audio_source->SetAudioResource(audio_resource); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioSampleAndHold ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // AudioSampleAndHold::AudioSampleAndHold( PlugStream *stream, Entity *entity ): AudioComponent(stream), audioComponentSocket(NULL) { AudioComponent *audio_component; AudioControlID control_ID; Scalar seconds; AudioTime sample_duration; Scalar min_value; Scalar max_value; // // audio_component // PlugStream_ReadObjectIDAndFindPlug(stream, &audio_component); // // control_ID, sample_duration // MemoryStream_Read(stream, &control_ID); MemoryStream_Read(stream, &seconds); sample_duration = seconds; // // min_value, max_value // MemoryStream_Read(stream, &min_value); MemoryStream_Read(stream, &max_value); AudioSampleAndHoldX( audio_component, entity, control_ID, sample_duration, min_value, max_value ); } // //############################################################################# //############################################################################# // void AudioSampleAndHold::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioComponent::BuildFromPage(stream, name_list, class_ID, object_ID); // // audio_component // CString audio_component_name("audio_component"); PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_component_name); // // control_ID, sample_duration // MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, control_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, Scalar, sample_duration); // // min_value, max_value // Scalar min_value = 0.0f; Scalar max_value = 1.0f; if (name_list->FindData("min_value") != NULL) { Convert_From_Ascii( (const char *)name_list->FindData("min_value"), &min_value ); } if (name_list->FindData("max_value") != NULL) { Convert_From_Ascii( (const char *)name_list->FindData("max_value"), &max_value ); } Verify(max_value > min_value); MemoryStream_Write(stream, &min_value); MemoryStream_Write(stream, &max_value); } // //############################################################################# //############################################################################# // void AudioSampleAndHold::AudioSampleAndHoldX( AudioComponent *audio_component, Entity *entity, AudioControlID audio_control_ID, const AudioTime &sample_duration, Scalar min_value, Scalar max_value ) { audioControlID = audio_control_ID; currentValue = 0.0f; nextSampleTime = AudioTime::Now(); sampleDuration = sample_duration; Verify(max_value > min_value); minValue = min_value; maxValue = max_value; Check(audio_component); audioComponentSocket.Add(audio_component); audio_component->AddWatcher(this); Check(entity); entity->AddAudioComponent(this); } // //############################################################################# //############################################################################# // AudioSampleAndHold::~AudioSampleAndHold() { } // //############################################################################# //############################################################################# // void AudioSampleAndHold::Execute() { Check(this); AudioComponent::Execute(); if (AudioTime::Now() > nextSampleTime) { SampleAndHold(); } } // //############################################################################# //############################################################################# // void AudioSampleAndHold::ReceiveControl( AudioControlID control_ID, AudioControlValue ) { Check(this); if (control_ID == StartAudioControlID) { SampleAndHold(); } } // //############################################################################# //############################################################################# // void AudioSampleAndHold::SampleAndHold() { Check(this); Scalar random_sample = Random; Verify(0.0f <= random_sample && random_sample <= 1.0f); Verify(maxValue > minValue); currentValue = minValue + random_sample * (maxValue - minValue); nextSampleTime = AudioTime::Now(); nextSampleTime += sampleDuration; Check(audioComponentSocket.GetCurrent()); if (getenv("BT_AUDIO_SPATIAL")) { static int s_sh=0; if (s_sh++<60) DEBUG_STREAM << "[snh] this=" << (void*)this << " -> tgt=" << (void*)audioComponentSocket.GetCurrent() << " ctlID=" << (int)audioControlID << " val=" << currentValue << " range=[" << minValue << "," << maxValue << "]\n" << std::flush; } audioComponentSocket.GetCurrent()->ReceiveControl( audioControlID, currentValue ); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioLFO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# //############################################################################# // AudioLFO::AudioLFO( PlugStream *stream, Entity *entity ): AudioComponent(stream), audioComponentSocket(NULL) { AudioComponent *audio_component; AudioControlID control_ID; AudioLFOWaveForm wave_form; Scalar the_period; AudioControlValue min_value; AudioControlValue max_value; Logical dump_value; // // audio_component // PlugStream_ReadObjectIDAndFindPlug(stream, &audio_component); // // control_ID, wave_form, period // MemoryStream_Read(stream, &control_ID); MemoryStream_Read(stream, &wave_form); MemoryStream_Read(stream, &the_period); // // min_value, max_value, dump_value // MemoryStream_Read(stream, &min_value); MemoryStream_Read(stream, &max_value); MemoryStream_Read(stream, &dump_value); AudioLFOX( audio_component, entity, control_ID, wave_form, the_period, min_value, max_value, dump_value ); } // //############################################################################# //############################################################################# // void AudioLFO::BuildFromPage( PlugStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID ) { AudioComponent::BuildFromPage(stream, name_list, class_ID, object_ID); // // audio_component // CString audio_component_name("audio_component"); PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_component_name); // // control_ID, wave_form, period // MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, control_ID); MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, wave_form); MEM_STRM_WRITE_ENTRY(*stream, name_list, Scalar, period); // // min_value, max_value // MEM_STRM_WRITE_ENTRY(*stream, name_list, Scalar, min_value); MEM_STRM_WRITE_ENTRY(*stream, name_list, Scalar, max_value); MEM_STRM_WRITE_ENTRY(*stream, name_list, Logical, dump_value); } // //############################################################################# //############################################################################# // void AudioLFO::AudioLFOX( AudioComponent *audio_component, Entity *entity, AudioControlID audio_control_ID, AudioLFOWaveForm wave_form, Scalar the_period, AudioControlValue min_value, AudioControlValue max_value, Logical dump_value ) { Check(audio_component); audioComponentSocket.Add(audio_component); audio_component->AddWatcher(this); audioControlID = audio_control_ID; waveForm = wave_form; minValue = min_value; maxValue = max_value; Verify(max_value > min_value); period = the_period; startTime = AudioTime::Now(); dumpValue = dump_value; Check(entity); entity->AddAudioComponent(this); } // //############################################################################# //############################################################################# // AudioLFO::~AudioLFO() { } // //############################################################################# //############################################################################# // void AudioLFO::Execute() { Check(this); AudioComponent::Execute(); Generate(); } // //############################################################################# //############################################################################# // void AudioLFO::ReceiveControl( AudioControlID control_ID, AudioControlValue ) { Check(this); if (control_ID == StartAudioControlID) { Generate(); } } // //############################################################################# //############################################################################# // void AudioLFO::Generate() { Check(this); // // HACK - For now, everything is sinusoidal // // res = sin( (now-start) * (PI/period) ) // val = min + ( 0.5 * (res+1) ) * (max - min) // Scalar time_factor; Scalar sample; Scalar current_value; time_factor = AudioTime::Now(); Verify(!Small_Enough((Scalar)period)); time_factor = (time_factor - (Scalar)startTime) / (Scalar)period; sample = (sin(time_factor * PI) + 1.0f) * 0.5f; Verify(0.0f <= sample && sample <= 1.0f); Verify(maxValue > minValue); current_value = minValue + sample * (maxValue - minValue); #if DEBUG_LEVEL>0 if (dumpValue) { Dump(current_value); } #endif Check(audioComponentSocket.GetCurrent()); audioComponentSocket.GetCurrent()->ReceiveControl( audioControlID, current_value ); }