Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
256 lines
7.6 KiB
C++
256 lines
7.6 KiB
C++
//===========================================================================//
|
|
// File: AudioRenderer.cpp //
|
|
// Project: MUNGA Brick: Video Renderer //
|
|
// Contents: Abstracted Base Video Renderer //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 03/04/97 JTR Initial coding. //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1997, Virtual World Entertainment, Inc. //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include "AdeptHeaders.hpp"
|
|
#include "AudioSample.hpp"
|
|
#include "AudioChannel.hpp"
|
|
#include "AudioCommand.hpp"
|
|
#include "AudioRenderer.hpp"
|
|
|
|
//##########################################################################
|
|
//############################ AudioSample ###########################
|
|
//##########################################################################
|
|
|
|
AudioSample::ClassData* AudioSample::DefaultData = NULL;
|
|
|
|
static bool g_SummarizeSamples;
|
|
static bool __stdcall CheckSummarizeSamples() {return g_SummarizeSamples;}
|
|
static void __stdcall EnableSummarizeSamples() {g_SummarizeSamples = !g_SummarizeSamples;}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void AudioSample::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
AudioSampleClassID,
|
|
"Adept::AudioSample",
|
|
BaseClass::DefaultData
|
|
);
|
|
Register_Object(DefaultData);
|
|
|
|
g_SummarizeSamples = false;
|
|
AddDebuggerMenuItem("Libraries\\Sound\\Spew Sample Summaries", CheckSummarizeSamples, EnableSummarizeSamples, 0);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void AudioSample::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
AudioSample::AudioSample(MemoryStream *stream):
|
|
Plug(DefaultData),
|
|
m_timesPlayed(0),
|
|
m_referenceCount(0),
|
|
m_highestReferenceCount(0)
|
|
{
|
|
Check_Pointer(this);
|
|
AUDIO_LOAD("Sample Loading");
|
|
|
|
//
|
|
//---------------------------------------------
|
|
// Find the resource file but don't load it yet
|
|
//---------------------------------------------
|
|
//
|
|
ResourceID sample_id;
|
|
*stream >> sample_id;
|
|
m_sampleResource.FindID(sample_id, false);
|
|
Verify(m_sampleResource.DoesResourceExist());
|
|
|
|
//
|
|
//------------------------------
|
|
// Read the data from the stream
|
|
//------------------------------
|
|
//
|
|
int gos_type;
|
|
*stream >> gos_type >> m_cached >> m_3D;
|
|
m_gosType = static_cast<gosAudio_ResourceType>(gos_type);
|
|
m_gosSample = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
AudioSample::~AudioSample()
|
|
{
|
|
Check_Object(this);
|
|
Verify(m_commands.IsEmpty());
|
|
Verify(m_activeChannels.IsEmpty());
|
|
|
|
if (m_timesPlayed>0)
|
|
{
|
|
ChainIteratorOf<AudioChannel*> channels(&m_inactiveChannels);
|
|
AudioChannel *channel;
|
|
while ((channel = channels.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(channel);
|
|
channel->m_sample = NULL;
|
|
}
|
|
#if !defined(NO_STATS)
|
|
if (g_SummarizeSamples)
|
|
SPEWALWAYS((
|
|
"",
|
|
"%s\t%d\t%d\t%d",
|
|
m_sampleResource.GetName(),
|
|
m_sampleInfo.dwSizeInBytes,
|
|
m_timesPlayed,
|
|
m_highestReferenceCount
|
|
));
|
|
#endif
|
|
gosAudio_DestroyResource(&m_gosSample);
|
|
}
|
|
else
|
|
{
|
|
#if !defined(NO_STATS)
|
|
if (g_SummarizeSamples)
|
|
SPEWALWAYS((
|
|
"",
|
|
"%s\t0\t%d\t%d",
|
|
m_sampleResource.GetName(),
|
|
m_timesPlayed,
|
|
m_highestReferenceCount
|
|
));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void AudioSample::Load()
|
|
{
|
|
Check_Object(this);
|
|
|
|
//
|
|
//---------------------------------------
|
|
// Construct the appropriate gos resource
|
|
//---------------------------------------
|
|
//
|
|
if (!m_timesPlayed)
|
|
{
|
|
switch (m_gosType)
|
|
{
|
|
case gosAudio_UserMemoryDecode:
|
|
m_sampleResource.LoadData();
|
|
gosAudio_CreateResource(
|
|
&m_gosSample,
|
|
gosAudio_UserMemoryDecode,
|
|
m_sampleResource.GetName(),
|
|
NULL,
|
|
m_sampleResource.GetPointer(),
|
|
m_sampleResource.GetSize(),
|
|
!m_3D
|
|
);
|
|
m_sampleResource.UnloadData();
|
|
break;
|
|
|
|
case gosAudio_StreamedFP:
|
|
{
|
|
Check_Object(ResourceManager::Instance);
|
|
ResourceFile *file =
|
|
ResourceManager::Instance->GetResourceFile(m_sampleResource.GetResourceID().GetFileID());
|
|
Check_Object(file);
|
|
gosAudio_CreateResource(
|
|
&m_gosSample,
|
|
m_sampleResource.GetName(),
|
|
file->GetFileHandle(),
|
|
m_sampleResource.GetDiskOffset(),
|
|
!m_3D
|
|
);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
STOP(("Unsupported audio type"));
|
|
break;
|
|
}
|
|
gosAudio_GetResourceInfo(m_gosSample, &m_sampleInfo);
|
|
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
// Make gos tell us about the sound, then set the restart delay appropriately
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
if (m_cached)
|
|
{
|
|
Verify(m_gosType == gosAudio_UserMemoryDecode);
|
|
AudioRenderer::Instance->m_cacheSize += m_sampleInfo.dwSizeInBytes;
|
|
AudioRenderer::Instance->FlushUnusedCache();
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void AudioSample::SetChannelActive(AudioChannel *channel)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(channel);
|
|
|
|
//
|
|
//-------------------------------------------
|
|
// Attach to the inactive chain in the sample
|
|
//-------------------------------------------
|
|
//
|
|
if (m_inactiveChannels.IsPlugMember(channel))
|
|
m_inactiveChannels.RemovePlug(channel);
|
|
Verify(!m_activeChannels.IsPlugMember(channel));
|
|
m_activeChannels.Add(channel);
|
|
++m_timesPlayed;
|
|
if (++m_referenceCount > m_highestReferenceCount)
|
|
m_highestReferenceCount = m_referenceCount;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void AudioSample::SetChannelInactive(AudioChannel *channel)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(channel);
|
|
|
|
//
|
|
//---------------------------------------------------------------------------------
|
|
// If this sample is not cached, kill it, and set the channel time to zero to force
|
|
// it to the top of the reuse chain since there is no point in trying to save its
|
|
// sample setting
|
|
//---------------------------------------------------------------------------------
|
|
//
|
|
--m_referenceCount;
|
|
Verify(m_referenceCount >= 0);
|
|
Verify(m_activeChannels.IsPlugMember(channel));
|
|
m_activeChannels.RemovePlug(channel);
|
|
if (!m_cached && m_commands.IsEmpty())
|
|
{
|
|
channel->m_startTime = 0.0;
|
|
channel->m_sample = NULL;
|
|
gosAudio_AssignResourceToChannel(channel->m_channel, NULL);
|
|
delete this;
|
|
return;
|
|
}
|
|
|
|
//
|
|
//----------------------------------------------------------------------------------
|
|
// Attach to the inactive chain in the sample. If the sample is a stream and is not
|
|
// play once, delete it
|
|
//----------------------------------------------------------------------------------
|
|
//
|
|
Verify(!m_inactiveChannels.IsPlugMember(channel));
|
|
m_inactiveChannels.Add(channel);
|
|
}
|