Files
BT411/engine/MUNGA/AUDWTHR.cpp
T
arcattackandClaude Opus 4.8 9dcb4752de Audio Phase 4c (AUDIO_FIDELITY F17/F19): impact scaling + the authored footstep feed
F17 CollisionSpeed (binary id 24 @0x4B4): real member captured as
|worldLinearVelocity| when the contact accumulator arms (0->1) -- the authored
AttackVolume [0.9,1] / Brightness [0.7,1] scales over impact speed [0,25] now
make harder hits sound louder and brighter.  ReduceButton (id 46 @0x340): real
watchable member (the keyboard rig never presses it).  UnstablePercentage
stays deferred: its sway/overspeed model @0x3F0 is the known gyro-ledger gap
(live writer unexported); binding without the model would be a stand-in.

F19 footstep feed (the invention is dead, long live the authored chain):
new [motionscalecfg/motiontrigcfg] traces recovered the authored configs --
EVERY motion watcher extracts |linearMotion| (motionValue=3); the footstep
volume mixer is fed by LocalAcceleration [0,10] -> ctl100 (per-stride kick)
+ LocalVelocity [0,0.6] -> ctl101 (0.4 base while moving).  The port never
wrote Mover::localAcceleration, so ctl100 read 0 and the old mech2.cpp
step-intensity broadcast (patch-sniffing, invented curve) fought the live
authored scale.  Now: localAcceleration.linear = d(published velocity)/dt --
EXACTLY the binary's derivation ((avgVel - prev)/avgDt into +0x1e4,
part_012.c:15186-15195) -- and the broadcast is REMOVED.

Regression (30s, walk throttle): stable; footfalls deliver through the
wholly-authored chain with per-stride VARYING gains (0.61/0.72/0.62 -- real
step dynamics, impossible under the old constant-curve invention).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 14:11:36 -05:00

1095 lines
30 KiB
C++

#include <cstdlib>
#include "munga.h"
#pragma hdrstop
#include "audwthr.h"
#include "objstrm.h"
#include "namelist.h"
//#############################################################################
//########################### AudioIdleWatcher ##########################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioIdleWatcher::AudioIdleWatcher(
PlugStream *stream,
Entity *entity
):
Component(stream),
audioComponentSocket(this)
{
AudioComponent *audio_component;
PlugStream_ReadObjectIDAndFindPlug(stream, &audio_component);
AudioIdleWatcherX(audio_component, entity);
}
//
//#############################################################################
//#############################################################################
//
void
AudioIdleWatcher::AudioIdleWatcherX(
AudioComponent *audio_component,
Entity *entity
)
{
Check(audio_component);
Check(entity);
audioComponentSocket.Add(audio_component);
entity->AddAudioWatcher(this);
}
//
//#############################################################################
//#############################################################################
//
AudioIdleWatcher::~AudioIdleWatcher()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioIdleWatcher::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
Component::BuildFromPage(stream, name_list, class_ID, object_ID);
CString audio_component_name("audio_component");
PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_component_name);
}
//
//#############################################################################
//#############################################################################
//
Logical
AudioIdleWatcher::TestInstance() const
{
Component::TestInstance();
Check(&audioComponentSocket);
return True;
}
//
//#############################################################################
//#############################################################################
//
void
AudioIdleWatcher::ReleaseLinkHandler(
Socket *socket,
Plug *plug
)
{
if (socket == &audioComponentSocket)
{
Check(&audioComponentSocket);
Check(socket);
Unregister_Object(this);
delete this;
}
else
{
Component::ReleaseLinkHandler(socket, plug);
}
}
//
//#############################################################################
//#############################################################################
//
void
AudioIdleWatcher::Execute()
{
Check(this);
Check(audioComponentSocket.GetCurrent());
audioComponentSocket.GetCurrent()->ReceiveControl(
IdleAudioControlID,
0.0f
);
}
//#############################################################################
//############################## AudioMotionTrigger #####################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioMotionTrigger::AudioMotionTrigger(
PlugStream *stream,
Entity *entity
):
AudioTriggerOf<Motion>(stream, entity)
{
MemoryStream_Read(stream, &motionType);
MemoryStream_Read(stream, &motionValue);
if (getenv("BT_ATTRBIND_LOG")) { static int s_mt=0; if (s_mt++<40)
DEBUG_STREAM << "[motiontrigcfg] attrPtr=" << (void*)attributePointer
<< " motionType=" << (int)motionType << " (0=linear,1=angular)"
<< " motionValue=" << (int)motionValue << " (0=X,1=Y,2=Z,3=len)"
<< "\n" << std::flush; }
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioMotionTrigger::~AudioMotionTrigger()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioMotionTrigger::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
AudioTriggerOf<Motion>::BuildFromPage(stream, name_list, class_ID, object_ID);
//
// Store fields
//
MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, motion_type);
MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, motion_value);
}
//
//#############################################################################
//#############################################################################
//
AudioControlValue
AudioMotionTrigger::ExtractInterestingValue(const Motion *attribute_ptr)
{
Check(this);
Check(attribute_ptr);
switch (motionType)
{
case LinearMotionType:
switch (motionValue)
{
case XMotionValue:
return attribute_ptr->linearMotion.x;
case YMotionValue:
return attribute_ptr->linearMotion.y;
case ZMotionValue:
return attribute_ptr->linearMotion.z;
case LengthMotionValue:
return attribute_ptr->linearMotion.Length();
}
break;
case AngularMotionType:
switch (motionValue)
{
case XMotionValue:
return attribute_ptr->angularMotion.x;
case YMotionValue:
return attribute_ptr->angularMotion.y;
case ZMotionValue:
return attribute_ptr->angularMotion.z;
case LengthMotionValue:
return attribute_ptr->angularMotion.Length();
}
break;
}
Fail("AudioMotionTrigger::ExtractInterestingValue - Should never reach here");
return 0.0f;
}
//
//#############################################################################
//#############################################################################
//
#if DEBUG_LEVEL>0
void
AudioMotionTrigger::DumpValue(const Motion *attribute_ptr)
#else
void
AudioMotionTrigger::DumpValue(const Motion*)
#endif
{
Check(this);
Check(attribute_ptr);
switch (motionType)
{
case LinearMotionType:
switch (motionValue)
{
case XMotionValue:
Dump(attribute_ptr->linearMotion.x);
break;
case YMotionValue:
Dump(attribute_ptr->linearMotion.y);
break;
case ZMotionValue:
Dump(attribute_ptr->linearMotion.z);
break;
case LengthMotionValue:
Dump(attribute_ptr->linearMotion.Length());
break;
}
break;
case AngularMotionType:
switch (motionValue)
{
case XMotionValue:
Dump(attribute_ptr->angularMotion.x);
break;
case YMotionValue:
Dump(attribute_ptr->angularMotion.y);
break;
case ZMotionValue:
Dump(attribute_ptr->angularMotion.z);
break;
case LengthMotionValue:
Dump(attribute_ptr->angularMotion.Length());
break;
}
break;
}
}
//#############################################################################
//############################## AudioMotionScale #######################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioMotionScale::AudioMotionScale(
PlugStream *stream,
Entity *entity
):
AudioScaleOf<Motion>(stream, entity)
{
MemoryStream_Read(stream, &motionType);
MemoryStream_Read(stream, &motionValue);
if (getenv("BT_ATTRBIND_LOG")) { static int s_ms=0; if (s_ms++<40)
DEBUG_STREAM << "[motionscalecfg] attrPtr=" << (void*)attributePointer
<< " motionType=" << (int)motionType << " (0=linear,1=angular)"
<< " motionValue=" << (int)motionValue << " (0=X,1=Y,2=Z,3=len)"
<< "\n" << std::flush; }
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioMotionScale::~AudioMotionScale()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioMotionScale::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
AudioScaleOf<Motion>::BuildFromPage(stream, name_list, class_ID, object_ID);
//
// Store fields
//
MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, motion_type);
MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, motion_value);
}
//
//#############################################################################
//#############################################################################
//
AudioControlValue
AudioMotionScale::ExtractInterestingValue(const Motion *attribute_ptr)
{
Check(this);
Check(attribute_ptr);
switch (motionType)
{
case LinearMotionType:
switch (motionValue)
{
case XMotionValue:
return attribute_ptr->linearMotion.x;
case YMotionValue:
return attribute_ptr->linearMotion.y;
case ZMotionValue:
return attribute_ptr->linearMotion.z;
case LengthMotionValue:
return attribute_ptr->linearMotion.Length();
}
break;
case AngularMotionType:
switch (motionValue)
{
case XMotionValue:
return attribute_ptr->angularMotion.x;
case YMotionValue:
return attribute_ptr->angularMotion.y;
case ZMotionValue:
return attribute_ptr->angularMotion.z;
case LengthMotionValue:
return attribute_ptr->angularMotion.Length();
}
break;
}
Fail("AudioMotionScale::ExtractInterestingValue - Should never reach here");
return 0.0f;
}
//
//#############################################################################
//#############################################################################
//
#if DEBUG_LEVEL>0
void
AudioMotionScale::DumpValue(const Motion *attribute_ptr)
#else
void
AudioMotionScale::DumpValue(const Motion*)
#endif
{
Check(this);
Check(attribute_ptr);
switch (motionType)
{
case LinearMotionType:
switch (motionValue)
{
case XMotionValue:
Dump(attribute_ptr->linearMotion.x);
break;
case YMotionValue:
Dump(attribute_ptr->linearMotion.y);
break;
case ZMotionValue:
Dump(attribute_ptr->linearMotion.z);
break;
case LengthMotionValue:
Dump(attribute_ptr->linearMotion.Length());
break;
}
break;
case AngularMotionType:
switch (motionValue)
{
case XMotionValue:
Dump(attribute_ptr->angularMotion.x);
break;
case YMotionValue:
Dump(attribute_ptr->angularMotion.y);
break;
case ZMotionValue:
Dump(attribute_ptr->angularMotion.z);
break;
case LengthMotionValue:
Dump(attribute_ptr->angularMotion.Length());
break;
}
break;
}
}
//#############################################################################
//############################## AudioHingeScale ########################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioHingeScale::AudioHingeScale(
PlugStream *stream,
Entity *entity
):
AudioScaleOf<Hinge>(stream, entity)
{
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioHingeScale::~AudioHingeScale()
{
}
//
//#############################################################################
//#############################################################################
//
AudioControlValue
AudioHingeScale::ExtractInterestingValue(const Hinge *attribute_ptr)
{
Check(this);
Check(attribute_ptr);
return attribute_ptr->rotationAmount;
}
//
//#############################################################################
//#############################################################################
//
#if DEBUG_LEVEL>0
void
AudioHingeScale::DumpValue(const Hinge *attribute_ptr)
#else
void
AudioHingeScale::DumpValue(const Hinge*)
#endif
{
Check(this);
Check(attribute_ptr);
Dump(attribute_ptr->rotationAmount);
}
//#############################################################################
//############################## AudioScalarTrigger #####################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioScalarTrigger::AudioScalarTrigger(
PlugStream *stream,
Entity *entity
):
AudioTriggerOf<Scalar>(stream, entity)
{
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioScalarTrigger::~AudioScalarTrigger()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioScalarTrigger::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
AudioTriggerOf<Scalar>::BuildFromPage(stream, name_list, class_ID, object_ID);
}
//
//#############################################################################
//#############################################################################
//
AudioControlValue
AudioScalarTrigger::ExtractInterestingValue(const Scalar *attribute_ptr)
{
Check(this);
Check_Pointer(attribute_ptr);
return *attribute_ptr;
}
//#############################################################################
//####################### AudioScalarDeltaTrigger #######################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioScalarDeltaTrigger::AudioScalarDeltaTrigger(
PlugStream *stream,
Entity *entity
):
AudioDeltaOf<Scalar>(stream, entity)
{
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioScalarDeltaTrigger::~AudioScalarDeltaTrigger()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioScalarDeltaTrigger::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
AudioDeltaOf<Scalar>::BuildFromPage(stream, name_list, class_ID, object_ID);
}
//#############################################################################
//############################## AudioScalarScale #######################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioScalarScale::AudioScalarScale(
PlugStream *stream,
Entity *entity
):
AudioScaleOf<Scalar>(stream, entity)
{
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioScalarScale::~AudioScalarScale()
{
}
//
//#############################################################################
//#############################################################################
//
AudioControlValue
AudioScalarScale::ExtractInterestingValue(const Scalar *attribute_ptr)
{
Check(this);
Check_Pointer(attribute_ptr);
return *attribute_ptr;
}
//#############################################################################
//######################### AudioLogicalTrigger #########################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioLogicalTrigger::AudioLogicalTrigger(
PlugStream *stream,
Entity *entity
):
AudioMatchOf<Logical>(stream, entity)
{
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioLogicalTrigger::~AudioLogicalTrigger()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioLogicalTrigger::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
AudioMatchOf<Logical>::BuildFromPage(stream, name_list, class_ID, object_ID);
}
//
//#############################################################################
//#############################################################################
//
int
AudioLogicalTrigger::ExtractInterestingValue(const Logical *attribute_ptr)
{
Check(this);
Check_Pointer(attribute_ptr);
return *attribute_ptr;
}
//#############################################################################
//######################### AudioEnumerationTrigger #####################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioEnumerationTrigger::AudioEnumerationTrigger(
PlugStream *stream,
Entity *entity
):
AudioMatchOf<Enumeration>(stream, entity)
{
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioEnumerationTrigger::~AudioEnumerationTrigger()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioEnumerationTrigger::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
AudioMatchOf<Enumeration>::BuildFromPage(stream, name_list, class_ID, object_ID);
}
//
//#############################################################################
//#############################################################################
//
int
AudioEnumerationTrigger::ExtractInterestingValue(const Enumeration *attribute_ptr)
{
Check(this);
Check_Pointer(attribute_ptr);
return *attribute_ptr;
}
//#############################################################################
//###################### AudioEnumerationDeltaTrigger ###################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioEnumerationDeltaTrigger::AudioEnumerationDeltaTrigger(
PlugStream *stream,
Entity *entity
):
AudioDeltaOf<Enumeration>(stream, entity)
{
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioEnumerationDeltaTrigger::~AudioEnumerationDeltaTrigger()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioEnumerationDeltaTrigger::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
AudioDeltaOf<Enumeration>::BuildFromPage(
stream,
name_list,
class_ID,
object_ID
);
}
//#############################################################################
//############################# AudioIntegerTrigger #####################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioIntegerTrigger::AudioIntegerTrigger(
PlugStream *stream,
Entity *entity
):
AudioTriggerOf<int>(stream, entity)
{
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioIntegerTrigger::~AudioIntegerTrigger()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioIntegerTrigger::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
AudioTriggerOf<int>::BuildFromPage(stream, name_list, class_ID, object_ID);
}
//
//#############################################################################
//#############################################################################
//
AudioControlValue
AudioIntegerTrigger::ExtractInterestingValue(const int *attribute_ptr)
{
Check(this);
Check_Pointer(attribute_ptr);
return *attribute_ptr;
}
//#############################################################################
//###################### AudioControlsButtonTrigger #####################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioControlsButtonTrigger::AudioControlsButtonTrigger(
PlugStream *stream,
Entity *entity
):
AudioTriggerOf<ControlsButton>(stream, entity)
{
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioControlsButtonTrigger::~AudioControlsButtonTrigger()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioControlsButtonTrigger::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
AudioTriggerOf<ControlsButton>::BuildFromPage(
stream,
name_list,
class_ID,
object_ID
);
}
//
//#############################################################################
//#############################################################################
//
AudioControlValue
AudioControlsButtonTrigger::ExtractInterestingValue(
const ControlsButton *attribute_ptr
)
{
Check(this);
Check_Pointer(attribute_ptr);
return *attribute_ptr;
}
//#############################################################################
//########################### AudioStateWatcher #########################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioStateWatcher::AudioStateWatcher(
PlugStream *stream,
Entity *entity
):
AudioWatcherOf<StateIndicator>(stream, entity)
{
Check_Pointer(attributePointer);
// BRING-UP GUARD [T3, temporary]: an AudioStateWatcher binds to a StateIndicator
// attribute BY NAME. The Mech's own state indicators (SimulationState, Animation/
// ReplicantAnimationState, CollisionState) are real; but audio also binds state
// attrs on subsystems that are not fully reconstructed yet (GeneratorState,
// CondenserState, Torso MotionState, ...). Those resolve to an unconstructed
// object -- a null/garbage vtable at +0 or a debug-fill (0xCDCDCDCD) watcher chain
// at +0x18 -- and AddAudioWatcher would AV in SChainOf::Add. Skip the register
// (that subsystem's state audio stays silent) until the subsystem is built; this
// is SELF-CLEARING (a real StateIndicator passes). See docs: audio subsystem wave.
// Validate the AUDIO SOCKET at +0x18 (what AddAudioWatcher touches), NOT the
// object's +0 vtable: a real StateIndicator has a vtable at +0, but the binary's
// 0x54 subsystem alarm (GaugeAlarm54) is non-polymorphic there (a raw header) yet
// has a real, constructed SChainOf socket at +0x18. A skip means the socket is
// unconstructed (null / debug-fill 0xCDCDCDCD) -- the inert pad or a subsystem not
// yet reconstructed. Registering there would AV in SChainOf::Add.
{
unsigned chain = *(unsigned*)((char*)attributePointer + 0x18);
if (chain == 0 || chain == 0xCDCDCDCD)
{
if (getenv("BT_AUDIO_LOG"))
DEBUG_STREAM << "[audiostate] skip watcher on unbuilt StateIndicator "
<< attributePointer << " (chain=" << (void*)chain << ")\n" << std::flush;
return;
}
}
Cast_Object(StateIndicator*, attributePointer)->AddAudioWatcher(this);
}
//
//#############################################################################
//#############################################################################
//
AudioStateWatcher::~AudioStateWatcher()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioStateWatcher::SendNotificationOfChange()
{
Check(this);
StateIndicator *state_indicator = GetCurrentPointer();
Check(state_indicator);
StateChanged(
state_indicator->GetOldState(),
state_indicator->GetState()
);
}
//
//#############################################################################
//#############################################################################
//
void
AudioStateWatcher::StateChanged(
Enumeration,
Enumeration
)
{
Fail("AudioStateWatcher::StateChanged - Should never reach here");
}
//#############################################################################
//############################## AudioStateTrigger ######################
//#############################################################################
//
//#############################################################################
//#############################################################################
//
AudioStateTrigger::AudioStateTrigger(
PlugStream *stream,
Entity *entity
):
AudioStateWatcher(stream, entity)
{
MemoryStream_Read(stream, &triggerState);
MemoryStream_Read(stream, &inverseTrigger);
MemoryStream_Read(stream, &controlID);
MemoryStream_Read(stream, &controlValue);
MemoryStream_Read(stream, &excludeTransition);
MemoryStream_Read(stream, &excludeState);
if (getenv("BT_ATTRBIND_LOG")) { static int s_stc=0; if (s_stc++<120)
DEBUG_STREAM << "[statecfg] attrPtr=" << (void*)attributePointer
<< " comp=" << (void*)audioComponentSocket.GetCurrent()
<< " trigState=" << triggerState << " inv=" << (int)inverseTrigger
<< " ctl=" << (int)controlID << "/" << controlValue
<< " excl=" << (int)excludeTransition << "/" << excludeState
<< "\n" << std::flush; }
PrimeWatcher();
}
//
//#############################################################################
//#############################################################################
//
AudioStateTrigger::~AudioStateTrigger()
{
}
//
//#############################################################################
//#############################################################################
//
void
AudioStateTrigger::BuildFromPage(
PlugStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
)
{
AudioStateWatcher::BuildFromPage(stream, name_list, class_ID, object_ID);
//
// Write standard fields
//
MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, trigger_state);
MEM_STRM_WRITE_ENTRY(*stream, name_list, Logical, inverse_trigger);
MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, control_ID);
MEM_STRM_WRITE_ENTRY(*stream, name_list, AudioControlValue, control_value);
//
// Write optional fields
//
Logical exclude_transition = False;
Enumeration exclude_state = 0;
if ((name_list)->FindData("exclude_state") != NULL)
{
exclude_transition = True;
Check_Pointer((name_list)->FindData("exclude_state"));
Convert_From_Ascii(
(const char *)(name_list)->FindData("exclude_state"),
&exclude_state
);
}
MemoryStream_Write(stream, &exclude_transition);
MemoryStream_Write(stream, &exclude_state);
}
//
//#############################################################################
//#############################################################################
//
void
AudioStateTrigger::StateChanged(
Enumeration old_state,
Enumeration new_state
)
{
Check(this);
//
// If the exclude switch is on then check for the transition
//
if (excludeTransition)
{
if (
!inverseTrigger &&
new_state == triggerState &&
old_state == excludeState
)
{
return;
}
if (
inverseTrigger &&
old_state == triggerState &&
new_state == excludeState
)
{
return;
}
}
//
// Check for the trigger state
//
if (
(!inverseTrigger && new_state == triggerState) ||
(inverseTrigger && old_state == triggerState)
)
{
Check(&audioComponentSocket);
Check(audioComponentSocket.GetCurrent());
#if 1
audioComponentSocket.GetCurrent()->ReceiveControl(
controlID,
controlValue
);
#else
audioComponentSocket.GetCurrent()->PostReceiveControl(
controlID,
controlValue
);
#endif
}
}