#include #include "mungal4.h" #pragma hdrstop #include "l4audrnd.h" #include "..\munga\notation.h" #include "openal/alc.h" // //############################################################################# // L4AudioRenderer //############################################################################# // L4AudioRenderer::L4AudioRenderer( RendererRate render_rate, Logical mission_review_mode ): AudioRenderer(render_rate), runningAudioSourceSocket(NULL, False), dormantAudioSourceSocket(NULL), mixingAudioSourceSocket(NULL, False) { missionReviewMode = mission_review_mode; nextCalculateMixFrame = NullAudioFrameCount; } // //############################################################################# // ~L4AudioRenderer //############################################################################# // L4AudioRenderer::~L4AudioRenderer() { //Close OpenAL ALCcontext *context = alcGetCurrentContext(); ALCdevice *device = alcGetContextsDevice(context); alcMakeContextCurrent(NULL); alcDestroyContext(context); alcCloseDevice(device); // //---------------------------------------------------------------------- // Verify that all of entities have become uninteresting //---------------------------------------------------------------------- // #if DEBUG_LEVEL>0 { RunningSourceIterator iterator(&runningAudioSourceSocket); Verify(iterator.GetSize() == 0); } { DormantSourceIterator iterator(&dormantAudioSourceSocket); Verify(iterator.GetSize() == 0); } #endif // //---------------------------------------------------------------------- // Unload resources //---------------------------------------------------------------------- // Check(&audioResourceManager); // audioResourceManager.UnloadResources(&audioHardware); // //---------------------------------------------------------------------- // Close audio hardware //---------------------------------------------------------------------- // // Check(&audioHardware); // audioHardware.Close(); } // //############################################################################# // TestInstance //############################################################################# // Logical L4AudioRenderer::TestInstance() const { AudioRenderer::TestInstance(); Check(&audioHardware); Check(&runningAudioSourceSocket); Check(&dormantAudioSourceSocket); Check(&mixingAudioSourceSocket); return True; } // //############################################################################# // Initialize //############################################################################# // void L4AudioRenderer::Initialize() { Check(this); if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] L4AudioRenderer::Initialize ENTERED\n" << std::flush; // //---------------------------------------------------------------------- // Call inherited method //---------------------------------------------------------------------- // AudioRenderer::Initialize(); // //---------------------------------------------------------------------- // Get the audio head //---------------------------------------------------------------------- // AudioHead *audio_head = GetAudioHead(); Check(audio_head); // //---------------------------------------------------------------------- // Open the audio renderer notation file //---------------------------------------------------------------------- // int ret; CString audio_file_name; if (missionReviewMode) { audio_file_name = "audio\\audiomr.ini"; } else { audio_file_name = "audio\\audio.ini"; } NotationFile notation_file(audio_file_name); Check(¬ation_file); if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] notation file opened; about to read scalars\n" << std::flush; // //---------------------------------------------------------------------- // Define clipping sphere (m) //---------------------------------------------------------------------- // Scalar clipping_radius; ret = notation_file.GetEntry( "AudioRenderer", "clipping_radius", &clipping_radius ); if (!ret) { Fail("L4AudioRenderer::Initialize - clipping_radius not defined"); } Check(audio_head); audio_head->DefineClippingSphere(clipping_radius); // //---------------------------------------------------------------------- // Distance to speakers or width of head entity (m) //---------------------------------------------------------------------- // Scalar distance_between_ears; ret = notation_file.GetEntry( "AudioRenderer", "distance_between_ears", &distance_between_ears ); if (!ret) { Fail("L4AudioRenderer::Initialize - distance_between_ears not defined"); } Check(audio_head); audio_head->SetDistanceBetweenEars(distance_between_ears); // //---------------------------------------------------------------------- // Define amplitude rolloff characteristics //---------------------------------------------------------------------- // Scalar amplitude_rolloff; Scalar amplitude_rolloff_knee; Scalar amplitude_rolloff_distance_scale; ret = notation_file.GetEntry( "AudioRenderer", "amplitude_rolloff", &litude_rolloff ); if (!ret) { Fail("L4AudioRenderer::Initialize - amplitude_rolloff not defined"); } ret = notation_file.GetEntry( "AudioRenderer", "amplitude_rolloff_distance_scale", &litude_rolloff_distance_scale ); if (!ret) { Fail("L4AudioRenderer::Initialize - amplitude_rolloff_distance_scale not defined"); } ret = notation_file.GetEntry( "AudioRenderer", "amplitude_rolloff_knee", &litude_rolloff_knee ); if (!ret) { Fail("L4AudioRenderer::Initialize - amplitude_rolloff_knee not defined"); } Check(audio_head); audio_head->ControlAmplitudeRollOff( amplitude_rolloff, amplitude_rolloff_knee, amplitude_rolloff_distance_scale ); // //---------------------------------------------------------------------- // Define high frequency rolloff characteristics //---------------------------------------------------------------------- // Scalar high_frequency_rolloff; Scalar high_frequency_rolloff_knee; Scalar high_frequency_rolloff_distance_scale; ret = notation_file.GetEntry( "AudioRenderer", "high_frequency_rolloff", &high_frequency_rolloff ); if (!ret) { Fail("L4AudioRenderer::Initialize - high_frequency_rolloff not defined"); } ret = notation_file.GetEntry( "AudioRenderer", "high_frequency_rolloff_knee", &high_frequency_rolloff_knee ); if (!ret) { Fail("L4AudioRenderer::Initialize - high_frequency_rolloff_knee not defined"); } ret = notation_file.GetEntry( "AudioRenderer", "high_frequency_rolloff_distance_scale", &high_frequency_rolloff_distance_scale ); if (!ret) { Fail("L4AudioRenderer::Initialize - high_frequency_rolloff_distance_scale not defined"); } Check(audio_head); audio_head->ControlHighFrequencyRollOff( high_frequency_rolloff, high_frequency_rolloff_knee, high_frequency_rolloff_distance_scale ); // //---------------------------------------------------------------------- // Define Doppler characterisitics //---------------------------------------------------------------------- // Scalar doppler_range; Scalar speed_of_sound; ret = notation_file.GetEntry( "AudioRenderer", "doppler_range", &doppler_range ); if (!ret) { Fail("L4AudioRenderer::Initialize - doppler_range not defined"); } ret = notation_file.GetEntry( "AudioRenderer", "speed_of_sound", &speed_of_sound ); if (!ret) { Fail("L4AudioRenderer::Initialize - speed_of_sound not defined"); } Check(audio_head); audio_head->ControlDopplerEffect( doppler_range, speed_of_sound ); // //---------------------------------------------------------------------- // Define source compression characterisitics //---------------------------------------------------------------------- // Scalar compression_exponent; Scalar compression_scale; ret = notation_file.GetEntry( "AudioRenderer", "compression_exponent", &compression_exponent ); if (!ret) { Fail("L4AudioRenderer::Initialize - compression_exponent not defined"); } ret = notation_file.GetEntry( "AudioRenderer", "compression_scale", &compression_scale ); if (!ret) { Fail("L4AudioRenderer::Initialize - compression_scale not defined"); } Check(audio_head); audio_head->ControlSourceCompression( compression_exponent, compression_scale ); // //---------------------------------------------------------------------- // Set ITD difference //---------------------------------------------------------------------- // Scalar itd_difference; ret = notation_file.GetEntry( "AudioRenderer", "itd_difference", &itd_difference ); if (!ret) { Fail("L4AudioRenderer::Initialize - itd_difference not defined"); } Check(audio_head); audio_head->SetITDDifference(itd_difference); // //---------------------------------------------------------------------- // Set global reverb scale //---------------------------------------------------------------------- // Scalar global_reverb_scale; ret = notation_file.GetEntry( "AudioRenderer", "global_reverb_scale", &global_reverb_scale ); if (!ret) { Fail("L4AudioRenderer::Initialize - global_reverb_scale not defined"); } Check(audio_head); audio_head->SetGlobalReverbScale(global_reverb_scale); // //---------------------------------------------------------------------- // Initialize the audio hardware //---------------------------------------------------------------------- // // Check(&audioHardware); // audioHardware.Initialize(); //Start OpenAL ALCdevice *device = alcOpenDevice(NULL); if (device) { ALCcontext *context = alcCreateContext(device,NULL); alcMakeContextCurrent(context); if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] OpenAL device OPENED + context current\n" << std::flush; } else { if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] OpenAL device FAILED to open (alcOpenDevice NULL)\n" << std::flush; } // //---------------------------------------------------------------------- // Preload resources //---------------------------------------------------------------------- // Check(&audioResourceManager); audioResourceManager.PreloadResources(¬ation_file); } // //############################################################################# // NotifyOfNewInterestingEntity //############################################################################# // void L4AudioRenderer::NotifyOfNewInterestingEntity(Entity *interesting_entity) { SET_AUDIO_RENDERER(); SET_AUDIO_RENDERER_CREATE_OBJECTS(); Check(this); Check(interesting_entity); Entity *linked_entity = GetLinkedEntity(); Check(linked_entity); AudioRepresentation audio_representation = (AudioRepresentation)interesting_entity->GetAudioRepresentation( linked_entity ); Check(&audioResourceManager); audioResourceManager.CreateEntityAudioObjects( interesting_entity, audio_representation ); CLEAR_AUDIO_RENDERER_CREATE_OBJECTS(); CLEAR_AUDIO_RENDERER(); } // //############################################################################# // NotifyOfBecomingUninterestingEntity //############################################################################# // void L4AudioRenderer::NotifyOfBecomingUninterestingEntity( Entity *uninteresting_entity ) { SET_AUDIO_RENDERER(); SET_AUDIO_RENDERER_DESTROY_OBJECTS(); Check(this); Check(uninteresting_entity); Check(&audioResourceManager); audioResourceManager.DestroyEntityAudioObjects(uninteresting_entity); CLEAR_AUDIO_RENDERER_DESTROY_OBJECTS(); CLEAR_AUDIO_RENDERER(); } // //############################################################################# // LoadMissionImplementation //############################################################################# // void L4AudioRenderer::LoadMissionImplementation(Mission*) { Check(this); } // //############################################################################# // ShutdownImplementation //############################################################################# // void L4AudioRenderer::ShutdownImplementation() { Check(this); } // //############################################################################# // SuspendImplementation //############################################################################# // void L4AudioRenderer::SuspendImplementation() { Check(this); } // //############################################################################# // ResumeImplementation //############################################################################# // void L4AudioRenderer::ResumeImplementation() { Check(this); } // //############################################################################# // StartRequest //############################################################################# // void L4AudioRenderer::StartRequest(L4AudioSource *audio_source) { Check(this); Check(audio_source); // //-------------------------------------------------------------------------- // Verify that the source is stopped //-------------------------------------------------------------------------- // Verify(audio_source->GetAudioSourceState() == StoppedAudioSourceState); // //-------------------------------------------------------------------------- // Request audio resources //-------------------------------------------------------------------------- // Logical resources_available; /* AudioChannelSet channel_set_result;*/ SourceSet *source_result = audio_source->GetAudioChannelSet(); resources_available = RequestAudioResources( audio_source, source_result ); if (!resources_available) { if (audio_source->GetAudioRenderType() == SustainedAudioRenderType) { // // Set state to dormant and add the source to the dormant list // audio_source->AssignAudioSourceState(DormantAudioSourceState); dormantAudioSourceSocket.Add(audio_source); } return; } // //-------------------------------------------------------------------------- // Start the audio source //-------------------------------------------------------------------------- // // // Update source spatial model // Set channel set of source // Source start implementation // Set state of source to running // audio_source->UpdateSpatialModel(GetAudioHead()); audio_source->SetAudioChannelSet(*source_result); audio_source->StartImplementation(); audio_source->AssignAudioSourceState(RunningAudioSourceState); // // Add source to the running list and the mixing list // runningAudioSourceSocket.AddValue( audio_source, audio_source->CalculateAudioWeighting() ); if ( audio_source->GetAudioSourceMixPresence() != ManualAudioSourceMixPresence ) { mixingAudioSourceSocket.AddValue( audio_source, audio_source->GetAudioSourceMixPresence() ); } #ifdef LAB_ONLY sourceStartCount++; #endif } // //############################################################################# // StopRequest //############################################################################# // void L4AudioRenderer::StopRequest(L4AudioSource *audio_source) { Check(this); Check(audio_source); // //-------------------------------------------------------------------------- // Verify that the source is not stopped //-------------------------------------------------------------------------- // Verify(audio_source->GetAudioSourceState() != StoppedAudioSourceState); // //-------------------------------------------------------------------------- // If state of the source is dormant or suspended // Then set source to stop state and remove from dormant list //-------------------------------------------------------------------------- // if ( audio_source->GetAudioSourceState() == DormantAudioSourceState || audio_source->GetAudioSourceState() == SuspendedAudioSourceState ) { // // Set state of source to stopped // Verify that source is in dormant list // Remove source from dormant list // Verify that source is not in dormant list // audio_source->AssignAudioSourceState(StoppedAudioSourceState); #if DEBUG_LEVEL>0 { DormantSourceIterator iterator(&dormantAudioSourceSocket); Verify(iterator.IsPlugMember(audio_source) == True); } #endif PlugIterator remover(audio_source); remover.RemoveSocket(&dormantAudioSourceSocket); #if DEBUG_LEVEL>0 { DormantSourceIterator iterator(&dormantAudioSourceSocket); Verify(iterator.IsPlugMember(audio_source) == False); } #endif return; } // //-------------------------------------------------------------------------- // Stop the source //-------------------------------------------------------------------------- // AudioSourceStopMaintenance(audio_source); } // //############################################################################# // ExecuteImplementation //############################################################################# // void L4AudioRenderer::ExecuteImplementation( RendererComplexity complexity_update, RendererOrigin::InterestingEntityIterator *iterator ) { SET_AUDIO_RENDERER(); SET_AUDIO_RENDERER_EXECUTE(); Check(this); AudioRenderer::ExecuteImplementation(complexity_update, iterator); CalculateMix(); RunningSourceCheckup(); // RunningAudioSourceSort(); DormantSourceCheckup(); CLEAR_AUDIO_RENDERER_EXECUTE(); CLEAR_AUDIO_RENDERER(); } // //############################################################################# // CalculateMix //############################################################################# // void L4AudioRenderer::CalculateMix() { SET_AUDIO_CALCULATE_MIX(); // //-------------------------------------------------------------------------- // Is this the next calculate mix frame //-------------------------------------------------------------------------- // #if 0 if (nextCalculateMixFrame > GetAudioFrameCount()) { CLEAR_AUDIO_CALCULATE_MIX(); return; } nextCalculateMixFrame = GetAudioFrameCount() + DefaultAudioFrameDelay; #endif // //-------------------------------------------------------------------------- // Calculate the compression volume scaling // // For each source, calculate the amount to scale its volume by // according to those sources which have a higher mix presence //-------------------------------------------------------------------------- // { AudioControlValue compression_scale = 1.0f; AudioControlValue compression_effect = 0.0f; AudioSourceMixPresence current_mix_presence = MedAudioSourceMixPresence; MixingSourceIterator iterator(&mixingAudioSourceSocket); L4AudioSource *audio_source; Check(GetAudioHead()); Scalar comp_scale = GetAudioHead()->GetSourceCompressionScale(); Scalar comp_exp = GetAudioHead()->GetSourceCompressionExponent(); // // Get mix presence of the first source // if ((audio_source = iterator.GetCurrent()) != NULL) { Check(audio_source); current_mix_presence = audio_source->GetAudioSourceMixPresence(); } // //----------------------------------------------------------------------- // For each audio source, calculate the compression scale //----------------------------------------------------------------------- // while ((audio_source = iterator.ReadAndNext()) != NULL) { Check(audio_source); // //-------------------------------------------------------------------- // If the mix presence of this source is greater then the last // source then we have stepped to a lower mix presence. //-------------------------------------------------------------------- // if ( current_mix_presence != audio_source->GetAudioSourceMixPresence() ) { Verify( current_mix_presence < audio_source->GetAudioSourceMixPresence() ); current_mix_presence = audio_source->GetAudioSourceMixPresence(); // // Calculate the compression scale for this mix presence // // scale = 1 - ((comp_scale*x)^comp_exp) // compression_scale = 1.0f - pow(comp_scale * compression_effect, comp_exp); Verify(compression_scale >= 0.0f && compression_scale <= 1.0f); } // //-------------------------------------------------------------------- // Set the compression scale for this source //-------------------------------------------------------------------- // audio_source->SetVolumeCompressionScale(compression_scale); // //-------------------------------------------------------------------- // Calculate the compression effect for this source //-------------------------------------------------------------------- // AudioControlValue source_compression_effect; source_compression_effect = audio_source->CalculateSourceCompressionEffect(); Verify( source_compression_effect >= 0.0f && source_compression_effect <= 1.0f ); // //-------------------------------------------------------------------- // Update the compression effect for this mix presence //-------------------------------------------------------------------- // compression_effect = Max(compression_effect, source_compression_effect); Verify(compression_effect >= 0.0f && compression_effect <= 1.0f); #if 0 Tell( "compression_effect " << compression_effect << " : compression_scale " << compression_scale << "\n" ); #endif } } CLEAR_AUDIO_CALCULATE_MIX(); } // //############################################################################# // RunningSourceCheckup //############################################################################# // void L4AudioRenderer::RunningSourceCheckup() { SET_AUDIO_RUNNING_SOURCES(); // //-------------------------------------------------------------------------- // Iterate through all running sources //-------------------------------------------------------------------------- // ChainOf resort_socket(NULL); RunningSourceIterator running_iterator(&runningAudioSourceSocket); L4AudioSource *audio_source; while ((audio_source = running_iterator.GetCurrent()) != NULL) { Check(audio_source); // //----------------------------------------------------------------------- // If the source does not require maintenance then skip it //----------------------------------------------------------------------- // if (!audio_source->RequiresMaintenance(GetAudioHead())) { running_iterator.Next(); continue; } //Update object position // //----------------------------------------------------------------------- // If the source is clipped then either stop or suspend //----------------------------------------------------------------------- // if (audio_source->IsAudioSourceClipped(GetAudioHead())) { if (audio_source->GetAudioRenderType() == TransientAudioRenderType) { AudioSourceStopMaintenance(audio_source); } else { Verify( audio_source->GetAudioRenderType() == SustainedAudioRenderType ); AudioSourceSuspendMaintenance(audio_source); } continue; } // //----------------------------------------------------------------------- // If the source is finished playing then stop it //----------------------------------------------------------------------- // if (audio_source->IsFinishedPlaying()) { AudioSourceStopMaintenance(audio_source); continue; } // //----------------------------------------------------------------------- // Execute //----------------------------------------------------------------------- // SET_AUDIO_EXECUTE_SOURCES(); audio_source->Execute(); CLEAR_AUDIO_EXECUTE_SOURCES(); // //----------------------------------------------------------------------- // Add to resort list if weight has changed //----------------------------------------------------------------------- // if ( audio_source->CalculateAudioWeighting() != running_iterator.GetValue() ) { running_iterator.Remove(); resort_socket.Add(audio_source); } else { running_iterator.Next(); } } // //-------------------------------------------------------------------------- // Sort resort socket back into running socket //-------------------------------------------------------------------------- // ChainIteratorOf resort_iterator(&resort_socket); while ((audio_source = resort_iterator.ReadAndNext()) != NULL) { Check(audio_source); Verify(running_iterator.IsPlugMember(audio_source) == False); runningAudioSourceSocket.AddValue( audio_source, audio_source->CalculateAudioWeighting() ); } CLEAR_AUDIO_RUNNING_SOURCES(); } // //############################################################################# // DormantSourceCheckup //############################################################################# // void L4AudioRenderer::DormantSourceCheckup() { SET_AUDIO_DORMANT_SOURCES(); // //-------------------------------------------------------------------------- // Assemble the request socket //-------------------------------------------------------------------------- // VChainOf resume_request_socket(NULL, False); DormantSourceIterator dormant_iterator(&dormantAudioSourceSocket); L4AudioSource *audio_source; while ((audio_source = dormant_iterator.ReadAndNext()) != NULL) { Check(audio_source); // // If the suspend gate is not up then it can not resume // if (!audio_source->CanResume(GetAudioHead())) continue; // // If the audio source is clipped then it can not resume // if (audio_source->IsAudioSourceClipped(GetAudioHead())) continue; // // Add to request socket // resume_request_socket.AddValue( audio_source, audio_source->CalculateAudioWeighting() ); } // //-------------------------------------------------------------------------- // Iterate through request socket //-------------------------------------------------------------------------- // VChainIteratorOf resume_request_iterator(&resume_request_socket); while ((audio_source = resume_request_iterator.GetCurrent()) != NULL) { Check(audio_source); // // Request audio resources // /* AudioChannelSet channel_set_result;*/ SourceSet *source_result = audio_source->GetAudioChannelSet(); if (!RequestAudioResources(audio_source, source_result) ) break; // // Remove from dormant list and request list // PlugIterator remover(audio_source); remover.RemoveSocket(&dormantAudioSourceSocket); AudioWeighting audio_weighting = resume_request_iterator.GetValue(); resume_request_iterator.Remove(); // // Update Spatial model // audio_source->UpdateSpatialModel(GetAudioHead()); // // Set channel set of source // Source resume implementation // Set state of source to running // audio_source->SetAudioChannelSet(*source_result); audio_source->ResumeImplementation(); audio_source->AssignAudioSourceState(RunningAudioSourceState); // // Put on running socket and mixing socket // runningAudioSourceSocket.AddValue(audio_source, audio_weighting); if ( audio_source->GetAudioSourceMixPresence() != ManualAudioSourceMixPresence ) { mixingAudioSourceSocket.AddValue( audio_source, audio_source->GetAudioSourceMixPresence() ); } } CLEAR_AUDIO_DORMANT_SOURCES(); } // //############################################################################# // AudioSourceStopMaintenance //############################################################################# // void L4AudioRenderer::AudioSourceStopMaintenance(L4AudioSource *source) { Check(source); Verify(source->GetAudioSourceState() == RunningAudioSourceState); #if DEBUG_LEVEL>0 { RunningSourceIterator iterator(&runningAudioSourceSocket); Verify(iterator.IsPlugMember(source) == True); } #endif source->StopImplementation(); source->AssignAudioSourceState(StoppedAudioSourceState); source->ReleaseChannels(); PlugIterator remover(source); remover.RemoveSocket(&runningAudioSourceSocket); remover.RemoveSocket(&mixingAudioSourceSocket); #if DEBUG_LEVEL>0 { RunningSourceIterator iterator(&runningAudioSourceSocket); Verify(iterator.IsPlugMember(source) == False); } #endif } // //############################################################################# // AudioSourceSuspendMaintenance //############################################################################# // void L4AudioRenderer::AudioSourceSuspendMaintenance(L4AudioSource *source) { Check(source); Verify(source->GetAudioRenderType() == SustainedAudioRenderType); Verify(source->GetAudioSourceState() == RunningAudioSourceState); #if DEBUG_LEVEL>0 { RunningSourceIterator iterator(&runningAudioSourceSocket); Verify(iterator.IsPlugMember(source) == True); } #endif source->SuspendImplementation(); source->AssignAudioSourceState(SuspendedAudioSourceState); source->ReleaseChannels(); PlugIterator remover(source); remover.RemoveSocket(&runningAudioSourceSocket); remover.RemoveSocket(&mixingAudioSourceSocket); #if DEBUG_LEVEL>0 { RunningSourceIterator iterator(&runningAudioSourceSocket); Verify(iterator.IsPlugMember(source) == False); } #endif dormantAudioSourceSocket.Add(source); } // //############################################################################# // RequestAudioResources //############################################################################# // Logical L4AudioRenderer::RequestAudioResources( L4AudioSource *audio_source, SourceSet *source_result ) { Check(this); Check(audio_source); Check(source_result); // //-------------------------------------------------------------------------- // This source must be within the culling volume //-------------------------------------------------------------------------- // if (audio_source->IsAudioSourceClipped(GetAudioHead())) return False; // //-------------------------------------------------------------------------- // Request audio channels for this source //-------------------------------------------------------------------------- // Logical resources_available; source_result = audio_source->GetAudioChannelSet(); Check(source_result); resources_available = RequestAudioChannels( audio_source->GetAudioVoiceCount(), source_result ); // //-------------------------------------------------------------------------- // If audio channels are not available then check running sources for // lower weight sources //-------------------------------------------------------------------------- // if (!resources_available) { RunningSourceIterator iterator(&runningAudioSourceSocket); L4AudioSource *running_audio_source; AudioWeighting audio_source_weighting; iterator.Last(); running_audio_source = iterator.GetCurrent(); audio_source_weighting = audio_source->CalculateAudioWeighting(); // //----------------------------------------------------------------------- // while // request for channels is not satisfied and // there exist running sources that have lower weighting //----------------------------------------------------------------------- // while ( !resources_available && running_audio_source != NULL && audio_source_weighting < iterator.GetValue() // Actual value is inverted ) { Check(running_audio_source); Verify( running_audio_source->GetAudioSourcePriority() <= audio_source->GetAudioSourcePriority() ); // //-------------------------------------------------------------------- // Collect Statistics //-------------------------------------------------------------------- // #ifdef LAB_ONLY if ( running_audio_source->GetAudioSourcePriority() < audio_source->GetAudioSourcePriority() ) { resourceStealPriorityCount++; } else { Verify( running_audio_source->GetAudioSourcePriority() == audio_source->GetAudioSourcePriority() ); Warn( running_audio_source->CalculateSourceVolumeScale() >= audio_source->CalculateSourceVolumeScale() ); resourceStealVolumeCount++; } AudioTime duration_cutoff(0.1f); if ( running_audio_source->GetCurrentRunningTime() <= duration_cutoff ) { stealShortDurationCount++; } resourceStealCount++; #endif // //-------------------------------------------------------------------- // If running source is transient // Then stop the source // Else suspend the source //-------------------------------------------------------------------- // if ( running_audio_source->GetAudioRenderType() == TransientAudioRenderType ) { AudioSourceStopMaintenance(running_audio_source); } else { Verify( running_audio_source->GetAudioRenderType() == SustainedAudioRenderType ); AudioSourceSuspendMaintenance(running_audio_source); } // //-------------------------------------------------------------------- // Request resources again //-------------------------------------------------------------------- // resources_available = RequestAudioChannels( audio_source->GetAudioVoiceCount(), source_result ); iterator.Last(); running_audio_source = iterator.GetCurrent(); } } return resources_available; } // //############################################################################# // RequestAudioChannels //############################################################################# // Logical L4AudioRenderer::RequestAudioChannels( int voices_requested, SourceSet *source_request ) { Check(this); Check(source_request); //Do we have enough? int requested = source_request->count; bool failed = true; alGetError(); for (int i = 0; i < requested; i++) { if (!alIsSource(source_request->sources[i])) { alGenSources(1, source_request->sources + i); } } ALenum error = alGetError(); if (error == AL_NO_ERROR) { failed = false; } if (failed) { return False; } return True; // //---------------------------------------------------------------------- // Attempt to allocate channels from audio hardware //---------------------------------------------------------------------- // /* AudioChannel *channel; Logical success = False; AudioCard *front_card = GetFrontCard(); AudioCard *rear_card = GetRearCard(); Check(front_card); Check(rear_card); while (True) { if (channel_set_request->IsFrontLeftEnabled()) { if ((channel = front_card->RequestAudioChannel(voices_requested)) == NULL) break; Check(channel); channel_set_request->SetFrontLeft(channel); } if (channel_set_request->IsFrontRightEnabled()) { if ((channel = front_card->RequestAudioChannel(voices_requested)) == NULL) break; Check(channel); channel_set_request->SetFrontRight(channel); } if (channel_set_request->IsRearLeftEnabled()) { if ((channel = rear_card->RequestAudioChannel(voices_requested)) == NULL) break; Check(channel); channel_set_request->SetRearLeft(channel); } if (channel_set_request->IsRearRightEnabled()) { if ((channel = rear_card->RequestAudioChannel(voices_requested)) == NULL) break; Check(channel); channel_set_request->SetRearRight(channel); } success = True; break; } // //---------------------------------------------------------------------- // If did not succeed then release allocated channels //---------------------------------------------------------------------- // if (!success) { channel_set_request->ReleaseAll(); return False; } // //---------------------------------------------------------------------- // else, return allocated channels //---------------------------------------------------------------------- // return True;*/ } void L4AudioRenderer::ReleaseSourceSet(SourceSet &sourceSet) { for (int i = 0; i < sourceSet.count; i++) { ALenum state; alGetSourcei(sourceSet.sources[i], AL_SOURCE_STATE, &state); if (state == AL_PLAYING) { alSourceStop(sourceSet.sources[i]); } } alDeleteSources(sourceSet.count, sourceSet.sources); for (int i = 0; i < sourceSet.count; i++) { sourceSet.sources[i] = -1; } } //~~~~~~~~~~~~~~~~~~~~~~ L4AudioRenderer profile bits ~~~~~~~~~~~~~~~~~~~~~~~~~ #if defined(TRACE_AUDIO_RENDERER_RUNNING_SOURCES) BitTrace Audio_Renderer_Running_Sources("Audio Renderer Running Sources"); #endif #if defined(TRACE_AUDIO_RENDERER_RUNNING_SORT) BitTrace Audio_Renderer_Running_Sort("Audio Renderer Running Sort"); #endif #if defined(TRACE_AUDIO_RENDERER_CALCULATE_MIX) BitTrace Audio_Renderer_Calculate_Mix("Audio Renderer Calculate Mix"); #endif #if defined(TRACE_AUDIO_RENDERER_EXECUTE_SOURCES) BitTrace Audio_Renderer_Execute_Sources("Audio Renderer Execute Sources"); #endif #if defined(TRACE_AUDIO_RENDERER_DORMANT_SOURCES) BitTrace Audio_Renderer_Dormant_Sources("Audio Renderer Dormant Sources"); #endif