Files
BT411/engine/MUNGA/AUDWTHR.cpp
T
arcattackandClaude Opus 4.8 5ba541ed56 Audio: subsystem STATE sounds -- GaugeAlarm54 IS a StateIndicator; register Generator/Condenser/Reservoir state (task #50)
The audio subsystem binds AudioStateWatchers (class 28) to per-subsystem state
attrs (GeneratorState/CondenserState/ReservoirState) BY NAME.  Recovered the
watcher TYPE per attribute via a MakeObjectImplementation ClassID trace.

Root cause of the subsystem-state crash: the binary's 0x54-byte subsystem alarm
(FUN_0041b9ec, reconstructed as GaugeAlarm54) IS a StateIndicator -- its "three
sub-indicators" @0x18/0x2c/0x40 are the audio/video/gauge watcher SChains, and
level@0x14 is currentState.  The reconstruction had modeled that tail as an opaque
`_tail`, so the sockets were never constructed -> AddAudioWatcher AV'd on 0xCDCDCDCD.

- GaugeAlarm54: give it the three REAL, constructed SChainOf<Component*> sockets +
  AddAudioWatcher/Video/Gauge; SetLevel now fires the watchers on a level CHANGE
  (empty sockets = no-op, so the ~all other alarms are unaffected).  levelB (weapon
  LevelCountB "reset source") is left untouched -- weapons unchanged.  sizeof stays
  0x54 (static_assert holds -> SChainOf<Component*> is 0x14, layout exact).
- Register the state attrs -> the subsystem's own alarm (own AttributePointers[]
  chained to the parent): Generator.GeneratorState->stateAlarm, Condenser.
  CondenserState->condenserAlarm, Reservoir.ReservoirState->reservoirAlarm.  Those
  alarms are already SetLevel'd by the sim, so the state audio fires on transition.
- AudioStateWatcher guard now validates the +0x18 SOCKET (what AddAudioWatcher
  touches), not the +0 vtable -- GaugeAlarm54 is non-polymorphic at +0 (raw header)
  but has a real socket at +0x18.

audiostate skips 85 -> 10 (only AmmoBin AmmoState/SimulationState left).  The
Logical/Scalar/Enum subsystem attrs (ReportLeak/GeneratorOn/ConfigureActivePress/
MotionState/SpeedOfTorsoHorizontal/TargetRangeExponent) stay inert (read 0, silent,
non-crashing) -- they need backing members in size-locked layouts (a polish wave).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 21:38:15 -05:00

1075 lines
29 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);
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);
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);
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
}
}