//===========================================================================// // 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(gos_type); m_gosSample = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AudioSample::~AudioSample() { Check_Object(this); Verify(m_commands.IsEmpty()); Verify(m_activeChannels.IsEmpty()); if (m_timesPlayed>0) { ChainIteratorOf 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); }