HRESULT CMpcAudioRenderer::CheckAudioClient(WAVEFORMATEX *pWaveFormatEx) { HRESULT hr = S_OK; CAutoLock cAutoLock(&m_csCheck); TRACE(_T("CMpcAudioRenderer::CheckAudioClient\n")); if (pMMDevice == NULL) { hr = GetAudioDevice(&pMMDevice); } // If no WAVEFORMATEX structure provided and client already exists, return it if (pAudioClient != NULL && pWaveFormatEx == NULL) { return hr; } // Just create the audio client if no WAVEFORMATEX provided if (pAudioClient == NULL && pWaveFormatEx==NULL) { if (SUCCEEDED (hr)) { hr=CreateAudioClient(pMMDevice, &pAudioClient); } return hr; } // Compare the exisiting WAVEFORMATEX with the one provided WAVEFORMATEX *pNewWaveFormatEx = NULL; if (CheckFormatChanged(pWaveFormatEx, &pNewWaveFormatEx)) { // Format has changed, audio client has to be reinitialized TRACE(_T("CMpcAudioRenderer::CheckAudioClient Format changed, reinitialize the audio client\n")); if (m_pWaveFileFormat) { BYTE *p = (BYTE *)m_pWaveFileFormat; SAFE_DELETE_ARRAY(p); } m_pWaveFileFormat=pNewWaveFormatEx; hr = pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, pWaveFormatEx, NULL); if (SUCCEEDED(hr)) { if (pAudioClient!=NULL && isAudioClientStarted) { pAudioClient->Stop(); } isAudioClientStarted=false; SAFE_RELEASE(pRenderClient); SAFE_RELEASE(pAudioClient); if (SUCCEEDED (hr)) { hr=CreateAudioClient(pMMDevice, &pAudioClient); } } else { TRACE(_T("CMpcAudioRenderer::CheckAudioClient New format not supported, accept it anyway\n")); return S_OK; } } else if (pRenderClient == NULL) { TRACE(_T("CMpcAudioRenderer::CheckAudioClient First initialization of the audio renderer\n")); } else { return hr; } SAFE_RELEASE(pRenderClient); if (SUCCEEDED (hr)) { hr=InitAudioClient(pWaveFormatEx, pAudioClient, &pRenderClient); } return hr; }
void Source::setSound( const SoundHandle& soundHandle ) { sound = soundHandle; Sound* sound = soundHandle.Resolve(); if( !sound ) return; if( sound->getStreamed() ) mode = SourceMode::Streaming; if( !audioSource ) { AudioDevice* device = GetAudioDevice(); AudioContext* context = device->getMainContext(); audioSource = AllocateThis(AudioSource, context); } audioSource->setSound(soundHandle); setVolume(volume); setPitch(pitch); setRolloff(rolloff); setMode(mode); setState(state); }
void UAudioComponent::AdjustVolume( float AdjustVolumeDuration, float AdjustVolumeLevel ) { if (bIsActive) { // TODO - Audio Threading. This call would be a task if (FAudioDevice* AudioDevice = GetAudioDevice()) { FActiveSound* ActiveSound = AudioDevice->FindActiveSound(this); if (ActiveSound) { ActiveSound->bFadingOut = false; ActiveSound->TargetAdjustVolumeMultiplier = AdjustVolumeLevel; if( AdjustVolumeDuration > 0.0f ) { ActiveSound->TargetAdjustVolumeStopTime = ActiveSound->PlaybackTime + AdjustVolumeDuration; } else { ActiveSound->CurrentAdjustVolumeMultiplier = AdjustVolumeLevel; ActiveSound->TargetAdjustVolumeStopTime = -1.0f; } } } } }
class FAudioDevice* FAudioDeviceManager::GetActiveAudioDevice() { if (ActiveAudioDeviceHandle != INDEX_NONE) { return GetAudioDevice(ActiveAudioDeviceHandle); } return GEngine->GetMainAudioDevice(); }
void UAudioComponent::Stop() { if (bIsActive) { UE_LOG(LogAudio, Verbose, TEXT( "%g: Stopping AudioComponent : '%s' with Sound: '%s'" ), GetWorld() ? GetWorld()->GetAudioTimeSeconds() : 0.0f, *GetFullName(), Sound ? *Sound->GetName() : TEXT( "nullptr" ) ); // TODO - Audio Threading. This call would be a task if (FAudioDevice* AudioDevice = GetAudioDevice()) { AudioDevice->StopActiveSound(this); } } }
void UAudioComponent::SetUISound(bool bInIsUISound) { bIsUISound = bInIsUISound; // TODO - Audio Threading. This call would be a task if (FAudioDevice* AudioDevice = GetAudioDevice()) { FActiveSound* ActiveSound = AudioDevice->FindActiveSound(this); if (ActiveSound) { ActiveSound->bIsUISound = bIsUISound; } } }
void UAudioComponent::AdjustAttenuation(const FAttenuationSettings& InAttenuationSettings) { bOverrideAttenuation = true; AttenuationOverrides = InAttenuationSettings; // TODO - Audio Threading. This call would be a task if (FAudioDevice* AudioDevice = GetAudioDevice()) { FActiveSound* ActiveSound = AudioDevice->FindActiveSound(this); if (ActiveSound) { ActiveSound->AttenuationSettings = AttenuationOverrides; } } }
void UAudioComponent::SetPitchMultiplier(float NewPitchMultiplier) { PitchMultiplier = NewPitchMultiplier; PitchModulationMin = PitchModulationMax = 1.f; // TODO - Audio Threading. This call would be a task if (FAudioDevice* AudioDevice = GetAudioDevice()) { FActiveSound* ActiveSound = AudioDevice->FindActiveSound(this); if (ActiveSound) { ActiveSound->PitchMultiplier = NewPitchMultiplier; } } }
void UAudioComponent::OnUpdateTransform(bool bSkipPhysicsMove) { Super::OnUpdateTransform(bSkipPhysicsMove); if (bIsActive && !bPreviewComponent) { if (FAudioDevice * AudioDevice = GetAudioDevice()) { FActiveSound* ActiveSound = AudioDevice->FindActiveSound(this); if (ActiveSound) { FScopeCycleCounterUObject ComponentScope(ActiveSound->Sound); ActiveSound->Transform = ComponentToWorld; } } } };
void UAudioComponent::SetFloatParameter( FName InName, float InFloat ) { if (InName != NAME_None) { bool bFound = false; // First see if an entry for this name already exists for (int32 i = 0; i < InstanceParameters.Num(); i++) { FAudioComponentParam& P = InstanceParameters[i]; if (P.ParamName == InName) { P.FloatParam = InFloat; bFound = true; break; } } // We didn't find one, so create a new one. if (!bFound) { const int32 NewParamIndex = InstanceParameters.AddZeroed(); InstanceParameters[ NewParamIndex ].ParamName = InName; InstanceParameters[ NewParamIndex ].FloatParam = InFloat; } // If we're active we need to push this value to the ActiveSound if (bIsActive) { // TODO - Audio Threading. This call would be a task if (FAudioDevice* AudioDevice = GetAudioDevice()) { FActiveSound* ActiveSound = AudioDevice->FindActiveSound(this); if (ActiveSound) { ActiveSound->SetFloatParameter(InName, InFloat); } } } } }
void UAudioComponent::FadeOut( float FadeOutDuration, float FadeVolumeLevel ) { if (bIsActive) { if (FadeOutDuration > 0.0f) { // TODO - Audio Threading. This call would be a task if (FAudioDevice* AudioDevice = GetAudioDevice()) { FActiveSound* ActiveSound = AudioDevice->FindActiveSound(this); if (ActiveSound) { ActiveSound->TargetAdjustVolumeMultiplier = FadeVolumeLevel; ActiveSound->TargetAdjustVolumeStopTime = ActiveSound->PlaybackTime + FadeOutDuration; ActiveSound->bFadingOut = true; } } } else { Stop(); } } }
void UAudioComponent::PlayInternal(const float StartTime, const float FadeInDuration, const float FadeVolumeLevel) { UWorld* World = GetWorld(); UE_LOG(LogAudio, Verbose, TEXT("%g: Playing AudioComponent : '%s' with Sound: '%s'"), World ? World->GetAudioTimeSeconds() : 0.0f, *GetFullName(), Sound ? *Sound->GetName() : TEXT("nullptr")); if (bIsActive) { // If this is an auto destroy component we need to prevent it from being auto-destroyed since we're really just restarting it bool bCurrentAutoDestroy = bAutoDestroy; bAutoDestroy = false; Stop(); bAutoDestroy = bCurrentAutoDestroy; } if (Sound && (World == nullptr || World->bAllowAudioPlayback)) { if (FAudioDevice* AudioDevice = GetAudioDevice()) { FActiveSound NewActiveSound; NewActiveSound.AudioComponent = this; NewActiveSound.World = GetWorld(); NewActiveSound.Sound = Sound; NewActiveSound.SoundClassOverride = SoundClassOverride; NewActiveSound.VolumeMultiplier = (VolumeModulationMax + ((VolumeModulationMin - VolumeModulationMax) * FMath::SRand())) * VolumeMultiplier; NewActiveSound.PitchMultiplier = (PitchModulationMax + ((PitchModulationMin - PitchModulationMax) * FMath::SRand())) * PitchMultiplier; NewActiveSound.HighFrequencyGainMultiplier = HighFrequencyGainMultiplier; NewActiveSound.RequestedStartTime = FMath::Max(0.f, StartTime); NewActiveSound.OcclusionCheckInterval = OcclusionCheckInterval; NewActiveSound.SubtitlePriority = SubtitlePriority; NewActiveSound.bShouldRemainActiveIfDropped = bShouldRemainActiveIfDropped; NewActiveSound.bHandleSubtitles = (!bSuppressSubtitles || OnQueueSubtitles.IsBound()); NewActiveSound.bIgnoreForFlushing = bIgnoreForFlushing; NewActiveSound.bIsUISound = bIsUISound; NewActiveSound.bIsMusic = bIsMusic; NewActiveSound.bAlwaysPlay = bAlwaysPlay; NewActiveSound.bReverb = bReverb; NewActiveSound.bCenterChannelOnly = bCenterChannelOnly; NewActiveSound.bLocationDefined = !bPreviewComponent; if (NewActiveSound.bLocationDefined) { NewActiveSound.Transform = ComponentToWorld; } const FAttenuationSettings* AttenuationSettingsToApply = (bAllowSpatialization ? GetAttenuationSettingsToApply() : nullptr); NewActiveSound.bAllowSpatialization = bAllowSpatialization; NewActiveSound.bHasAttenuationSettings = (AttenuationSettingsToApply != nullptr); if (NewActiveSound.bHasAttenuationSettings) { NewActiveSound.AttenuationSettings = *AttenuationSettingsToApply; } NewActiveSound.InstanceParameters = InstanceParameters; NewActiveSound.TargetAdjustVolumeMultiplier = FadeVolumeLevel; if (FadeInDuration > 0.0f) { NewActiveSound.CurrentAdjustVolumeMultiplier = 0.f; NewActiveSound.TargetAdjustVolumeStopTime = FadeInDuration; } else { NewActiveSound.CurrentAdjustVolumeMultiplier = FadeVolumeLevel; } // TODO - Audio Threading. This call would be a task call to dispatch to the audio thread AudioDevice->AddNewActiveSound(NewActiveSound); bIsActive = true; } } }
int main(int argc, char* argv[]) { IGraphBuilder *pGraph = NULL; ICaptureGraphBuilder2 *pBuilder = NULL; IBaseFilter *pSrc = NULL; IBaseFilter *ppf = NULL; IFileSinkFilter *pSink = NULL; IMediaControl *pMC = NULL; HRESULT hr; CoInitialize (NULL); // Create the filter graph. CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraph); // Create the capture graph builder. CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **)&pBuilder); pBuilder->SetFiltergraph(pGraph); pSrc=GetAudioDevice (); // add the first audio filter in the list pGraph->AddFilter(pSrc, L"Video Capture"); /* pBuilder->SetOutputFileName( &MEDIASUBTYPE_Avi, L"C:\\Example.avi", &ppf, &pSink);*/ // pBuilder->AllocCapFile (L"C:\\temp.avi", _MAX_PATH); pBuilder->RenderStream( &PIN_CATEGORY_CAPTURE, // Pin category &MEDIATYPE_Audio, // Media type pSrc, // Capture filter NULL, // Compression filter (optional) ppf // Multiplexer or renderer filter ); REFERENCE_TIME rtStart = 20000000, rtStop = 50000000; /* pBuilder->ControlStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, pSrc, // Source filter &rtStart, // Start time &rtStop, // Stop time 0, // Start cookie 0 // Stop cookie );*/ pGraph->QueryInterface (IID_IMediaControl, (void **) &pMC); pMC->Run (); MessageBox (NULL, "Stop Recording", NULL, NULL); pMC->Stop (); /* CProgress *pProg = new CProgress(TEXT(""), NULL, &hr); IAMCopyCaptureFileProgress *pIProg = NULL; hr = pProg->QueryInterface(IID_IAMCopyCaptureFileProgress, (void **)&pIProg); //pBuilder->CopyCaptureFile (L"C:\\temp.avi", L"C:\\final.avi", TRUE, pIProg);*/ CoUninitialize (); return 0; }
void UGameEngine::Tick( float DeltaSeconds, bool bIdleMode ) { SCOPE_CYCLE_COUNTER(STAT_GameEngineTick); NETWORK_PROFILER(GNetworkProfiler.TrackFrameBegin()); int32 LocalTickCycles=0; CLOCK_CYCLES(LocalTickCycles); // ----------------------------------------------------- // Non-World related stuff // ----------------------------------------------------- if( DeltaSeconds < 0.0f ) { #if (UE_BUILD_SHIPPING && WITH_EDITOR) // End users don't have access to the secure parts of UDN. Regardless, they won't // need the warning because the game ships with AMD drivers that address the issue. UE_LOG(LogEngine, Fatal,TEXT("Negative delta time!")); #else // Send developers to the support list thread. UE_LOG(LogEngine, Fatal,TEXT("Negative delta time! Please see https://udn.epicgames.com/lists/showpost.php?list=ue3bugs&id=4364")); #endif } // Tick allocator if( GMalloc != NULL ) { GMalloc->Tick( DeltaSeconds ); } // Tick the module manager FModuleManager::Get().Tick(); if (!IsRunningDedicatedServer() && !IsRunningCommandlet()) { // Clean up the game viewports that have been closed. CleanupGameViewport(); } // If all viewports closed, time to exit. if(GIsClient && GameViewport == NULL ) { UE_LOG(LogEngine, Log, TEXT("All Windows Closed") ); FPlatformMisc::RequestExit( 0 ); return; } if ( GameViewport != NULL ) { // Decide whether to drop high detail because of frame rate. GameViewport->SetDropDetail(DeltaSeconds); } // Update subsystems. { // This assumes that UObject::StaticTick only calls ProcessAsyncLoading. StaticTick( DeltaSeconds ); } // ----------------------------------------------------- // Begin ticking worlds // ----------------------------------------------------- int32 OriginalGWorldContext = INDEX_NONE; for (int32 i=0; i < WorldList.Num(); ++i) { if (WorldList[i].World() == GWorld) { OriginalGWorldContext = WorldList[i].ContextHandle; break; } } bool WorldWasPaused = false; for (int32 WorldIdx = 0; WorldIdx < WorldList.Num(); ++WorldIdx) { FWorldContext &Context = WorldList[WorldIdx]; if (Context.World() == NULL) { continue; } WorldWasPaused |= Context.World()->IsPaused(); GWorld = Context.World(); // Tick all travel and Pending NetGames (Seamless, server, client) TickWorldTravel(Context, DeltaSeconds); if (!IsRunningDedicatedServer() && !IsRunningCommandlet()) { // Only update reflection captures in game once all 'always loaded' levels have been loaded // This won't work with actual level streaming though if (Context.World()->AreAlwaysLoadedLevelsLoaded()) { // Update sky light first because it's considered direct lighting, sky diffuse will be visible in reflection capture indirect specular USkyLightComponent::UpdateSkyCaptureContents(Context.World()); UReflectionCaptureComponent::UpdateReflectionCaptureContents(Context.World()); } } if (!bIdleMode) { // Tick the world. GameCycles=0; CLOCK_CYCLES(GameCycles); Context.World()->Tick( LEVELTICK_All, DeltaSeconds ); UNCLOCK_CYCLES(GameCycles); } // Issue cause event after first tick to provide a chance for the game to spawn the player and such. if( Context.World()->bWorldWasLoadedThisTick ) { Context.World()->bWorldWasLoadedThisTick = false; const TCHAR* InitialExec = Context.LastURL.GetOption(TEXT("causeevent="),NULL); ULocalPlayer* GamePlayer = Context.GamePlayers.Num() > 0 ? Context.GamePlayers[0] : NULL; if( InitialExec && GamePlayer ) { UE_LOG(LogEngine, Log, TEXT("Issuing initial cause event passed from URL: %s"), InitialExec); GamePlayer->Exec( GamePlayer->GetWorld(), *(FString("CAUSEEVENT ") + InitialExec), *GLog ); } Context.World()->bTriggerPostLoadMap = true; } // Tick the viewports. if ( GameViewport != NULL && !bIdleMode ) { SCOPE_CYCLE_COUNTER(STAT_GameViewportTick); GameViewport->Tick(DeltaSeconds); } UpdateTransitionType(Context.World()); // fixme: this will only happen once due to the static bool, but still need to figure out how to handle this for multiple worlds if (FPlatformProperties::SupportsWindowedMode()) { // Hide the splashscreen and show the game window static bool bFirstTime = true; if ( bFirstTime ) { bFirstTime = false; FPlatformSplash::Hide(); if ( GameViewportWindow.IsValid() ) { GameViewportWindow.Pin()->ShowWindow(); FSlateApplication::Get().RegisterGameViewport( GameViewportWidget.ToSharedRef() ); } } } if (!bIdleMode && !IsRunningDedicatedServer() && !IsRunningCommandlet()) { // Render everything. RedrawViewports(); } // Block on async loading if requested. if( Context.World()->bRequestedBlockOnAsyncLoading ) { // Only perform work if there is anything to do. This ensures we are not syncronizing with the GPU // and suspending the device needlessly. bool bWorkToDo = IsAsyncLoading(); if (!bWorkToDo) { Context.World()->UpdateLevelStreaming(); bWorkToDo = Context.World()->IsVisibilityRequestPending(); } if (bWorkToDo) { // tell clients to do the same so they don't fall behind for( FConstPlayerControllerIterator Iterator = Context.World()->GetPlayerControllerIterator(); Iterator; ++Iterator ) { APlayerController* PlayerController = *Iterator; UNetConnection* Conn = Cast<UNetConnection>(PlayerController->Player); if (Conn != NULL && Conn->GetUChildConnection() == NULL) { // call the event to replicate the call PlayerController->ClientSetBlockOnAsyncLoading(); // flush the connection to make sure it gets sent immediately Conn->FlushNet(true); } } FStreamingPause::GameThreadWantsToSuspendRendering( GameViewport ? GameViewport->Viewport : NULL ); // Flushes level streaming requests, blocking till completion. Context.World()->FlushLevelStreaming(); FStreamingPause::GameThreadWantsToResumeRendering(); } Context.World()->bRequestedBlockOnAsyncLoading = false; } // streamingServer if( GIsServer == true ) { SCOPE_CYCLE_COUNTER(STAT_UpdateLevelStreaming); Context.World()->UpdateLevelStreaming(); } // Update Audio. This needs to occur after rendering as the rendering code updates the listener position. if( GetAudioDevice() ) { GetAudioDevice()->Update( !Context.World()->IsPaused() ); } if( GIsClient ) { // GStreamingManager is updated outside of a world context. For now, assuming it needs to tick here, before possibly calling PostLoadMap. // Will need to take another look when trying to support multiple worlds. // Update resource streaming after viewports have had a chance to update view information. Normal update. GStreamingManager->Tick( DeltaSeconds ); if ( Context.World()->bTriggerPostLoadMap ) { Context.World()->bTriggerPostLoadMap = false; // Turns off the loading movie (if it was turned on by LoadMap) and other post-load cleanup. PostLoadMap(); } } UNCLOCK_CYCLES(LocalTickCycles); TickCycles=LocalTickCycles; // See whether any map changes are pending and we requested them to be committed. ConditionalCommitMapChange(Context); } // ---------------------------- // End per-world ticking // ---------------------------- // Restore original GWorld*. This will go away one day. if (OriginalGWorldContext != INDEX_NONE) { GWorld = WorldContextFromHandle(OriginalGWorldContext).World(); } // tell renderer about GWorld->IsPaused(), before rendering { ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER( SetPaused, bool, bGamePaused, WorldWasPaused, { GRenderingRealtimeClock.SetGamePaused(bGamePaused); }); }