Imports the current Win32 source for the pod-racing game 'Red Planet', built on the MUNGA engine and its L4 (Win32/DirectX) platform layer: - MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend - RP / RP_L4: Red Planet game logic and Win32 application - DivLoader, Setup1: asset loader and installer project - lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies Removed stale Subversion metadata and added .gitignore/.gitattributes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
818 lines
21 KiB
C++
818 lines
21 KiB
C++
#include "munga.h"
|
|
#pragma hdrstop
|
|
|
|
#include "audsrc.h"
|
|
#include "audrend.h"
|
|
#include "objstrm.h"
|
|
#include "app.h"
|
|
#include "namelist.h"
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioSourceStartState ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
|
|
#define DEFAULT_NOTE (60)
|
|
|
|
AudioSourceStartState::AudioSourceStartState()
|
|
{
|
|
noteValue = DEFAULT_NOTE;
|
|
|
|
isDurationSet = False;
|
|
hasDuration = False;
|
|
duration = 0.0f;
|
|
startTime = 0.0f;
|
|
endTime = 0.0f;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
AudioSourceStartState::~AudioSourceStartState()
|
|
{
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
Logical
|
|
AudioSourceStartState::TestInstance() const
|
|
{
|
|
if (isDurationSet || hasDuration)
|
|
{
|
|
Verify(duration >= 0.0f);
|
|
}
|
|
if (hasDuration)
|
|
{
|
|
Verify(endTime >= startTime);
|
|
}
|
|
return True;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSourceStartState::CalculateDuration(AudioControlValue control_value)
|
|
{
|
|
//
|
|
// Calculate duration
|
|
//
|
|
if (control_value > 0.0f)
|
|
{
|
|
hasDuration = True;
|
|
endTime = AudioTime::Now();
|
|
endTime += control_value;
|
|
}
|
|
else if (isDurationSet)
|
|
{
|
|
hasDuration = True;
|
|
endTime = AudioTime::Now();
|
|
endTime += duration;
|
|
isDurationSet = False;
|
|
}
|
|
else
|
|
{
|
|
hasDuration = False;
|
|
endTime = 0.0f;
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
AudioTime
|
|
AudioSourceStartState::GetCurrentRunningTime()
|
|
{
|
|
Check(this);
|
|
AudioTime current_duration = AudioTime::Now();
|
|
return (current_duration -= startTime);
|
|
}
|
|
#endif
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioSource ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
const Receiver::HandlerEntry
|
|
AudioSource::MessageHandlerEntries[]=
|
|
{
|
|
{
|
|
AudioSource::StartMessageID,
|
|
"Start",
|
|
(AudioSource::Handler)&AudioSource::StartMessageHandler
|
|
},
|
|
{
|
|
AudioSource::StopMessageID,
|
|
"Stop",
|
|
(AudioSource::Handler)&AudioSource::StopMessageHandler
|
|
}
|
|
};
|
|
|
|
AudioSource::MessageHandlerSet& AudioSource::GetMessageHandlers()
|
|
{
|
|
static AudioSource::MessageHandlerSet messageHandlers(ELEMENTS(AudioSource::MessageHandlerEntries), AudioSource::MessageHandlerEntries, AudioComponent::GetMessageHandlers());
|
|
return messageHandlers;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
Derivation* AudioSource::GetClassDerivations()
|
|
{
|
|
static Derivation classDerivations(AudioComponent::GetClassDerivations(), "AudioSource");
|
|
return &classDerivations;
|
|
}
|
|
|
|
AudioSource::SharedData
|
|
AudioSource::DefaultData(
|
|
AudioSource::GetClassDerivations(),
|
|
AudioSource::GetMessageHandlers()
|
|
);
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
AudioSource::AudioSource(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
):
|
|
AudioComponent(stream, DefaultData)
|
|
{
|
|
AudioResource *audio_resource;
|
|
AudioLocation *audio_location;
|
|
AudioSourcePriority priority;
|
|
AudioSourceMixPresence mix_presence;
|
|
AudioControlValue volume_mix_level;
|
|
AudioPitchCents pitch_mix_offset;
|
|
AudioControlValue brightness_mix_level;
|
|
Logical has_compression_curve;
|
|
Scalar seconds;
|
|
AudioTime compression_duration;
|
|
Logical use_brightness_scale;
|
|
Logical use_attack_time_scale;
|
|
|
|
PlugStream_ReadObjectIDAndFindPlug(stream, &audio_resource);
|
|
PlugStream_ReadObjectIDAndFindPlug(stream, &audio_location);
|
|
MemoryStream_Read(stream, &priority);
|
|
MemoryStream_Read(stream, &mix_presence);
|
|
MemoryStream_Read(stream, &volume_mix_level);
|
|
MemoryStream_Read(stream, &pitch_mix_offset);
|
|
MemoryStream_Read(stream, &brightness_mix_level);
|
|
MemoryStream_Read(stream, &has_compression_curve);
|
|
MemoryStream_Read(stream, &seconds);
|
|
compression_duration = seconds;
|
|
MemoryStream_Read(stream, &use_brightness_scale);
|
|
MemoryStream_Read(stream, &use_attack_time_scale);
|
|
|
|
AudioSourceX(
|
|
audio_resource,
|
|
audio_location,
|
|
entity,
|
|
priority,
|
|
mix_presence,
|
|
volume_mix_level,
|
|
pitch_mix_offset,
|
|
brightness_mix_level,
|
|
has_compression_curve,
|
|
compression_duration,
|
|
use_brightness_scale,
|
|
use_attack_time_scale
|
|
);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::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_resource_name("resource");
|
|
PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_resource_name);
|
|
|
|
CString audio_location_name("location");
|
|
PlugStream_FindEntryAndWriteObjectID(stream, name_list, audio_location_name);
|
|
|
|
MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, priority);
|
|
MEM_STRM_WRITE_ENTRY(*stream, name_list, Enumeration, mix_presence);
|
|
MEM_STRM_WRITE_ENTRY(*stream, name_list, AudioControlValue, volume_mix_level);
|
|
MEM_STRM_WRITE_ENTRY(*stream, name_list, AudioPitchCents, pitch_mix_offset);
|
|
MEM_STRM_WRITE_ENTRY(*stream, name_list, AudioControlValue, brightness_mix_level);
|
|
MEM_STRM_WRITE_ENTRY(*stream, name_list, Logical, has_compression_curve);
|
|
MEM_STRM_WRITE_ENTRY(*stream, name_list, Scalar, compression_duration);
|
|
MEM_STRM_WRITE_ENTRY(*stream, name_list, Logical, use_brightness_scale);
|
|
MEM_STRM_WRITE_ENTRY(*stream, name_list, Logical, use_attack_time_scale);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::AudioSourceX(
|
|
AudioResource *audio_resource,
|
|
AudioLocation *audio_location,
|
|
Entity *entity,
|
|
AudioSourcePriority priority,
|
|
AudioSourceMixPresence mix_presence,
|
|
AudioControlValue volume_mix_level,
|
|
AudioPitchCents pitch_mix_offset,
|
|
AudioControlValue brightness_mix_level,
|
|
Logical has_compression_curve,
|
|
const AudioTime &compression_duration,
|
|
Logical use_brightness_scale,
|
|
Logical use_attack_time_scale
|
|
)
|
|
{
|
|
Check(audio_resource);
|
|
Check(audio_location);
|
|
Check(entity);
|
|
|
|
audioLocation = audio_location;
|
|
audioResource = audio_resource;
|
|
|
|
audioSourceState = StoppedAudioSourceState;
|
|
|
|
attackVolumeScale = 1.0f;
|
|
useAttackTimeScale = use_attack_time_scale;
|
|
attackTimeScale = 0.0f;
|
|
|
|
audioSourcePriority = priority;
|
|
|
|
audioSourceMixPresence = mix_presence;
|
|
volumeCompressionScale = 1.0f;
|
|
|
|
hasCompressionCurve = has_compression_curve;
|
|
compressionDuration = compression_duration;
|
|
|
|
volumeMixScale = volume_mix_level;
|
|
pitchMixOffset = pitch_mix_offset;
|
|
useBrightnessScale = use_brightness_scale;
|
|
brightnessMixScale = brightness_mix_level;
|
|
|
|
volumeScale = 1.0f;
|
|
pitchOffset = 0.0f;
|
|
brightnessScale = 1.0f;
|
|
|
|
nextExecuteFrame = NullAudioFrameCount;
|
|
suspendFinishedFrame = NullAudioFrameCount;
|
|
|
|
entity->AddAudioComponent(this);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
AudioSource::~AudioSource()
|
|
{
|
|
Verify(audioSourceState == StoppedAudioSourceState);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
Logical
|
|
AudioSource::TestInstance() const
|
|
{
|
|
AudioComponent::TestInstance();
|
|
return True;
|
|
}
|
|
|
|
//
|
|
// Resource methods
|
|
//
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::SetAudioResource(AudioResource *audio_resource)
|
|
{
|
|
Check(this);
|
|
Check(audio_resource);
|
|
|
|
Verify(audioSourceState == StoppedAudioSourceState);
|
|
Check(audioResource);
|
|
audioResource = audio_resource;
|
|
}
|
|
|
|
//
|
|
// Current State/Status Accessors
|
|
//
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::AssignAudioSourceState(AudioSourceState audio_source_state)
|
|
{
|
|
Check(this);
|
|
|
|
//
|
|
// Initialize the next start state if the source is now running
|
|
//
|
|
if (audio_source_state == RunningAudioSourceState)
|
|
{
|
|
AudioSourceStartState null_state;
|
|
nextStartState = null_state;
|
|
}
|
|
audioSourceState = audio_source_state;
|
|
}
|
|
|
|
//
|
|
// Mixing & Logical compression methods
|
|
//
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
AudioControlValue
|
|
AudioSource::CalculateSourceCompressionEffect()
|
|
{
|
|
Check(this);
|
|
|
|
//
|
|
// Get current volume level
|
|
//
|
|
AudioControlValue current_volume_level;
|
|
|
|
current_volume_level = CalculateSourceVolumeScale();
|
|
Verify(current_volume_level >= 0.0f && current_volume_level <= 1.0f);
|
|
|
|
//
|
|
// Calculate the amount of this to apply to compression
|
|
//
|
|
if (hasCompressionCurve)
|
|
{
|
|
//
|
|
// scale = 1 / (1 + ((1/comp_dur) * duration)^2)
|
|
//
|
|
Scalar current_running_time = GetCurrentRunningTime();
|
|
Scalar compression_duration = compressionDuration;
|
|
Scalar duration_factor;
|
|
Scalar denominator;
|
|
AudioControlValue compression_effect;
|
|
|
|
Verify(!Small_Enough(compression_duration));
|
|
duration_factor = pow((1.0f/compression_duration) * current_running_time, 2.0f);
|
|
// Warn(!(duration_factor > 0.0f));
|
|
|
|
denominator = 1.0f + duration_factor;
|
|
Verify(!Small_Enough(denominator));
|
|
compression_effect = 1.0f / denominator;
|
|
Verify(compression_effect >= 0.0f && compression_effect <=1.0f);
|
|
|
|
return compression_effect * current_volume_level;
|
|
}
|
|
return current_volume_level;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
AudioControlValue
|
|
AudioSource::CalculateSourceVolumeScale()
|
|
{
|
|
Check(this);
|
|
|
|
//
|
|
// Execute the watchers that will update the volume related
|
|
// member parameters
|
|
//
|
|
ExecuteWatchers();
|
|
|
|
//
|
|
// Calculate the resulting volume scale
|
|
//
|
|
AudioControlValue
|
|
volume_scale;
|
|
|
|
volume_scale = volumeScale * volumeMixScale * volumeCompressionScale;
|
|
Clamp(volume_scale, MinAudioVolume, MaxAudioVolume);
|
|
return volume_scale;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
AudioControlValue
|
|
AudioSource::CalculateSourceBrightnessScale()
|
|
{
|
|
Check(this);
|
|
|
|
AudioControlValue brightness_mix_scale;
|
|
|
|
brightness_mix_scale = brightnessScale * brightnessMixScale;
|
|
Clamp(brightness_mix_scale, MinAudioBrightness, MaxAudioBrightness);
|
|
|
|
return brightness_mix_scale;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::ReceiveControl(
|
|
AudioControlID control_ID,
|
|
AudioControlValue control_value
|
|
)
|
|
{
|
|
Check(this);
|
|
switch (control_ID)
|
|
{
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// StartAudioControlID
|
|
//----------------------------------------------------------------------
|
|
//
|
|
case StartAudioControlID:
|
|
{
|
|
StartMessage message(control_value);
|
|
|
|
Check(application);
|
|
Check(application->GetAudioRenderer());
|
|
application->GetAudioRenderer()->PostAudioRequestMessage(
|
|
this,
|
|
&message
|
|
);
|
|
}
|
|
break;
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// StopAudioControlID
|
|
//----------------------------------------------------------------------
|
|
//
|
|
case StopAudioControlID:
|
|
{
|
|
StopMessage message;
|
|
|
|
Check(application);
|
|
Check(application->GetAudioRenderer());
|
|
application->GetAudioRenderer()->PostAudioRequestMessage(
|
|
this,
|
|
&message
|
|
);
|
|
}
|
|
break;
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// Misc...
|
|
//----------------------------------------------------------------------
|
|
//
|
|
case VolumeAudioControlID:
|
|
VolumeAudioHandler(control_value);
|
|
break;
|
|
|
|
case PitchAudioControlID:
|
|
PitchAudioHandler(control_value);
|
|
break;
|
|
|
|
case BrightnessAudioControlID:
|
|
BrightnessAudioHandler(control_value);
|
|
break;
|
|
|
|
case AttackVolumeAudioControlID:
|
|
AttackVolumeAudioHandler(control_value);
|
|
break;
|
|
|
|
case AttackTimeAudioControlID:
|
|
AttackTimeAudioHandler(control_value);
|
|
break;
|
|
|
|
case NoteAudioControlID:
|
|
NoteAudioHandler(control_value);
|
|
break;
|
|
|
|
case DurationAudioControlID:
|
|
DurationAudioHandler(control_value);
|
|
break;
|
|
|
|
case FlushMessagesAudioControlID:
|
|
Check(application);
|
|
Check(application->GetAudioRenderer());
|
|
application->GetAudioRenderer()->FlushAudioMessages(this);
|
|
break;
|
|
|
|
case NullAudioControlID:
|
|
case IdleAudioControlID:
|
|
break;
|
|
|
|
default:
|
|
Fail("AudioSource::ReceiveControl - Should never reach here");
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::StartMessageHandler(StartMessage *message)
|
|
{
|
|
SET_AUDIO_RENDERER();
|
|
SET_AUDIO_RENDERER_START_HANDLER();
|
|
|
|
Check(this);
|
|
Check(message);
|
|
Verify(message->messageID == StartMessageID);
|
|
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
// if double trigger condition exists
|
|
// then return
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
AudioTime double_trigger_cutoff(AudioDoubleTriggerCutoff);
|
|
|
|
#if 0
|
|
double_trigger_cutoff = AudioDoubleTriggerCutoff;
|
|
#endif
|
|
if (
|
|
audioSourceState == RunningAudioSourceState &&
|
|
GetCurrentRunningTime() <= double_trigger_cutoff
|
|
)
|
|
{
|
|
#ifdef LAB_ONLY
|
|
Check(application);
|
|
Check(application->GetAudioRenderer());
|
|
application->GetAudioRenderer()->doubleTriggerCount++;
|
|
#endif
|
|
CLEAR_AUDIO_RENDERER_START_HANDLER();
|
|
CLEAR_AUDIO_RENDERER();
|
|
return;
|
|
}
|
|
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
// If the source is not stopped then stop it
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
if (audioSourceState != StoppedAudioSourceState)
|
|
{
|
|
StopMessage stop_message;
|
|
StopMessageHandler(&stop_message);
|
|
}
|
|
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
// Verify that the state is stopped
|
|
// Copy the next start state into the current start state
|
|
// Calculate duration
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
Verify(audioSourceState == StoppedAudioSourceState);
|
|
currentStartState = nextStartState;
|
|
currentStartState.CalculateDuration(message->controlValue);
|
|
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
// Implementation specific start request
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
StartMessageImplementation();
|
|
|
|
CLEAR_AUDIO_RENDERER_START_HANDLER();
|
|
CLEAR_AUDIO_RENDERER();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
#if DEBUG_LEVEL>0
|
|
AudioSource::StopMessageHandler(StopMessage *message)
|
|
#else
|
|
AudioSource::StopMessageHandler(StopMessage*)
|
|
#endif
|
|
{
|
|
SET_AUDIO_RENDERER();
|
|
SET_AUDIO_RENDERER_STOP_HANDLER();
|
|
|
|
Check(this);
|
|
Check(message);
|
|
Verify(message->messageID == StopMessageID);
|
|
|
|
//
|
|
// if the source is stopped
|
|
// then return
|
|
//
|
|
if (audioSourceState == StoppedAudioSourceState)
|
|
{
|
|
CLEAR_AUDIO_RENDERER_STOP_HANDLER();
|
|
CLEAR_AUDIO_RENDERER();
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Implementation specific stop request
|
|
//
|
|
StopMessageImplementation();
|
|
|
|
CLEAR_AUDIO_RENDERER_STOP_HANDLER();
|
|
CLEAR_AUDIO_RENDERER();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::VolumeAudioHandler(AudioControlValue control_value)
|
|
{
|
|
Check(this);
|
|
Clamp(control_value, MinAudioVolume, MaxAudioVolume);
|
|
volumeScale = control_value / (MaxAudioVolume - MinAudioVolume);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::PitchAudioHandler(AudioControlValue control_value)
|
|
{
|
|
Check(this);
|
|
pitchOffset = control_value;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::BrightnessAudioHandler(AudioControlValue control_value)
|
|
{
|
|
Check(this);
|
|
Clamp(control_value, MinAudioBrightness, MaxAudioBrightness);
|
|
brightnessScale = control_value / (MaxAudioBrightness - MinAudioBrightness);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::AttackVolumeAudioHandler(AudioControlValue control_value)
|
|
{
|
|
Check(this);
|
|
Clamp(control_value, MinAudioAttack, MaxAudioAttack);
|
|
attackVolumeScale = control_value / (MaxAudioAttack - MinAudioAttack);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::AttackTimeAudioHandler(AudioControlValue control_value)
|
|
{
|
|
Check(this);
|
|
Clamp(control_value, MinAudioAttack, MaxAudioAttack);
|
|
attackTimeScale = control_value / (MaxAudioAttack - MinAudioAttack);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::NoteAudioHandler(AudioControlValue control_value)
|
|
{
|
|
Check(this);
|
|
nextStartState.SetNoteValue(control_value);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::DurationAudioHandler(AudioControlValue control_value)
|
|
{
|
|
Check(this);
|
|
nextStartState.SetDurationValue(control_value);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::StartImplementation()
|
|
{
|
|
currentStartState.Start();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::StopImplementation()
|
|
{
|
|
Fail("AudioSource::StopImplementation - Should never reach here");
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::SuspendImplementation()
|
|
{
|
|
StopImplementation();
|
|
Check(application);
|
|
Check(application->GetAudioRenderer());
|
|
Check(audioResource);
|
|
suspendFinishedFrame =
|
|
application->GetAudioRenderer()->GetAudioFrameCount() +
|
|
audioResource->GetSuspendDelay();
|
|
#ifdef LAB_ONLY
|
|
application->GetAudioRenderer()->sourceSuspendCount++;
|
|
#endif
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::ResumeImplementation()
|
|
{
|
|
StartImplementation();
|
|
suspendFinishedFrame = NullAudioFrameCount;
|
|
#ifdef LAB_ONLY
|
|
Check(application);
|
|
Check(application->GetAudioRenderer());
|
|
application->GetAudioRenderer()->sourceResumeCount++;
|
|
#endif
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
AudioSource::Execute()
|
|
{
|
|
Check(this);
|
|
|
|
//
|
|
// Execute source if this is the next execution frame
|
|
//
|
|
AudioRenderer
|
|
*audio_renderer;
|
|
|
|
Check(application);
|
|
audio_renderer = application->GetAudioRenderer();
|
|
Check(audio_renderer);
|
|
if (nextExecuteFrame <= audio_renderer->GetAudioFrameCount())
|
|
{
|
|
nextExecuteFrame =
|
|
audio_renderer->GetAudioFrameCount() + DefaultAudioFrameDelay;
|
|
|
|
//
|
|
// Update the sources spatial model
|
|
// Execute inherited method
|
|
// Execute this sources sound model
|
|
//
|
|
UpdateSpatialModel(audio_renderer->GetAudioHead());
|
|
AudioComponent::Execute();
|
|
ExecuteModel(False);
|
|
}
|
|
}
|