Skip to content

fix(gameaudio): Remove the has3DSensitiveStreamsPlaying volume hack - #3252

Merged
xezon merged 2 commits into
TheSuperHackers:mainfrom
xezon:xezon/remove-3d-streams-hack
Sep 4, 2026
Merged

fix(gameaudio): Remove the has3DSensitiveStreamsPlaying volume hack#3252
xezon merged 2 commits into
TheSuperHackers:mainfrom
xezon:xezon/remove-3d-streams-hack

Conversation

@xezon

@xezon xezon commented Sep 3, 2026

Copy link
Copy Markdown

Merge with Rebase

This change has 2 commits.

The first is removing the has3DSensitiveStreamsPlaying hack. It existed to workaround a hang on volume change. We aim to fix application hanging and not rely on the hack from here on.

The second is committing to sound volume change only if the volume has really changed, not merely calling the volume change function. This may or may not avoid unnecessary sound volume updates.

TODO

  • Add pull ids to commits

@xezon xezon added Minor Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour Fix Is fixing something, but is not user facing labels Sep 3, 2026
@xezon xezon changed the title fix(audio): Remove the has3DSensitiveStreamsPlaying volume hack fix(gameaudio): Remove the has3DSensitiveStreamsPlaying volume hack Sep 3, 2026
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Remove 3D stream volume workaround and avoid redundant updates

🐞 Bug fix ✨ Enhancement 🕐 20-40 Minutes

Grey Divider

AI Description

• Removes stream-sensitive suppression so 3D volume adjustments always propagate.
• Marks audio volume dirty only when the effective value changes.
• Deletes the obsolete device API and Miles stream-scanning implementation.
Diagram

graph TD
  A["Volume request"] --> B["Compute volume"] --> C{"Value changed?"}
  C -- "Yes" --> D["Store volume"] --> E["Mark dirty"] --> F["Miles update loop"]
  C -- "No" --> G["Skip update"]
Loading
High-Level Assessment

The direct removal of the obsolete stream-sensitive workaround, combined with effective-value change detection, is proportionate to the goal. Retaining the workaround would continue suppressing legitimate 3D updates, while introducing per-channel dirty flags would broaden the change without being necessary here. Targeted runtime validation around ending cinematic streams remains important because the removed code guarded a historical platform-specific hang.

Files changed (4) +32 / -58

Bug fix (2) +32 / -51
GameAudio.cppCommit and propagate only effective volume changes +32/-16

Commit and propagate only effective volume changes

• Compares calculated music, sound, 3D sound, and speech volumes before storing them and setting the global dirty flag. The 3D adjustment path now uses 'clamp' and always propagates real changes without checking stream sensitivity.

Core/GameEngine/Source/Common/Audio/GameAudio.cpp

MilesAudioManager.cppDelete legacy stream-scanning volume workaround +0/-35

Delete legacy stream-scanning volume workaround

• Removes the Miles-specific scan that classified non-music and non-game streams as unsafe for 3D volume updates. Volume propagation is no longer suppressed based on the contents of the playing-stream list.

Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp

Refactor (2) +0 / -7
GameAudio.hRemove stream-sensitivity query from the audio interface +0/-2

Remove stream-sensitivity query from the audio interface

• Removes the pure virtual 'has3DSensitiveStreamsPlaying' contract because 3D volume updates no longer depend on active stream classification.

Core/GameEngine/Include/Common/GameAudio.h

MilesAudioManager.hRemove obsolete Miles stream-sensitivity overrides +0/-5

Remove obsolete Miles stream-sensitivity overrides

• Deletes the stream-sensitivity declarations from both the real Miles manager and its dummy implementation after removal from the base interface.

Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Alt-tab recovery no longer works 🐞 Bug ☼ Reliability
Description
Removing the unconditional dirty flag makes the explicit equal-volume call in the Win32 alt-tab
recovery path a no-op. Miles consequently skips reapplying volumes to active audio, so the existing
recovery for an audio device that fails to regain focus no longer works.
Code

Core/GameEngine/Source/Common/Audio/GameAudio.cpp[742]

-	m_volumeHasChanged = true;
+		const Real newVolume = m_scriptSpeechVolume * m_systemSpeechVolume;
+		if (m_speechVolume != newVolume)
+		{
+			m_speechVolume = newVolume;
+			m_volumeHasChanged = true;
+		}
+	}
Evidence
The Win32 message loop explicitly documents and performs an equal-volume call to wake Miles after
alt-tab. Because AudioAffect_SystemSetting has no audio-category bit, the updated setVolume
enters none of its branches, while Miles only reapplies active volumes when m_volumeHasChanged is
set and then clears that flag after processing.

Core/GameEngineDevice/Source/Win32Device/Common/Win32GameEngine.cpp[116-120]
Core/GameEngine/Include/Common/AudioAffect.h[35-43]
Core/GameEngine/Source/Common/Audio/GameAudio.cpp[702-763]
Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[2187-2209]
Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[2244-2260]
Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[2292-2294]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Equal-volume calls no longer mark audio volume state dirty, but the Win32 alt-tab path intentionally uses such a call to wake Miles after it fails to regain focus.

## Issue Context
The recovery call passes only `AudioAffect_SystemSetting`, so none of the category-specific equality checks execute. Previously, the unconditional assignment to `m_volumeHasChanged` still forced Miles to reapply all playing volumes.

## Fix Focus Areas
- Core/GameEngine/Source/Common/Audio/GameAudio.cpp[702-763]
- Core/GameEngineDevice/Source/Win32Device/Common/Win32GameEngine.cpp[116-120]
- Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[2187-2260]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Stream-ending hang guard removed 🐞 Bug ☼ Reliability
Description
Deleting the sensitive-stream guard allows camera-driven 3D volume changes to invoke Miles volume
operations while a non-music stream is ending, restoring the low-level tight-loop hang documented at
the removed implementation. The current stream-completion and volume-update paths contain no
replacement synchronization or guard.
Code

Core/GameEngine/Source/Common/Audio/GameAudio.cpp[L772-773]

-  if ( ! has3DSensitiveStreamsPlaying() )
-  	m_volumeHasChanged = TRUE;
+	if (m_sound3DVolume != newVolume)
+	{
+		m_sound3DVolume = newVolume;
+		m_volumeHasChanged = true;
+	}
Evidence
Listener updates still call set3DVolumeAdjustment, which now marks volume dirty without checking
sensitive streams. Miles then applies that dirty state to active 3D sounds and streams, while
completion callbacks independently transition ending streams to PS_Stopping; ordinary stereo
streams remain permitted because stereo is rejected only for positional audio.

Core/GameEngine/Source/Common/Audio/GameAudio.cpp[331-364]
Core/GameEngine/Source/Common/Audio/GameAudio.cpp[781-789]
Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[1227-1245]
Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[2193-2260]
Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[1453-1512]
Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[1542-1561]
Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[3012-3018]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR removes the only guard preventing Miles volume updates while sensitive streams are ending, without adding a replacement for the documented low-level hang.

## Issue Context
Listener updates continue changing the 3D volume, `processPlayingList` applies dirty volume state to active samples and streams, and stream completion asynchronously moves streams toward stopping. Keep the suppression behavior or introduce a proven synchronized replacement before removing it.

## Fix Focus Areas
- Core/GameEngine/Source/Common/Audio/GameAudio.cpp[781-789]
- Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h[229-234]
- Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[2193-2260]
- Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp[1453-1512]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can add REVIEW.md to your repo root and Qodo follows it on every PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread Core/GameEngine/Source/Common/Audio/GameAudio.cpp
Comment thread Core/GameEngine/Source/Common/Audio/GameAudio.cpp
@greptile-apps

greptile-apps Bot commented Sep 3, 2026

Copy link
Copy Markdown

Greptile Summary

This PR removes the stream-sensitive 3D-volume suppression and avoids marking audio volume state dirty when the effective volume is unchanged.

  • Removes has3DSensitiveStreamsPlaying from the shared audio contract and Miles implementations.
  • Changes category and 3D-adjustment volume updates to set the dirty flag only when the computed volume differs.

Confidence Score: 5/5

The PR appears safe to merge because no eligible blocking failure remains in this follow-up review.

No blocking failure remains.

Important Files Changed

Filename Overview
Core/GameEngine/Include/Common/GameAudio.h Removes the stream-sensitivity query from the shared audio-manager contract.
Core/GameEngine/Source/Common/Audio/GameAudio.cpp Adds effective-volume change detection and removes stream-sensitive suppression from 3D-volume adjustment.
Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h Removes the obsolete query overrides from the normal and dummy Miles managers.
Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp Removes the implementation that classified active streams as sensitive to 3D-volume updates.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    Input[Volume or camera adjustment] --> Compute[Compute effective category volume]
    Compute --> Changed{Effective volume changed?}
    Changed -- Yes --> Store[Store new volume]
    Store --> Dirty[Mark volume state dirty]
    Dirty --> Update[Miles update reapplies playing-audio volumes]
    Changed -- No --> Skip[Skip provider volume refresh]
Loading

Reviews (2): Last reviewed commit: "tweak(gameaudio): Only update sound volu..." | Re-trigger Greptile

@Mauller Mauller left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable

@xezon
xezon force-pushed the xezon/remove-3d-streams-hack branch from 6e6c347 to d3c7ed9 Compare September 4, 2026 07:30
@xezon
xezon merged commit 61d4465 into TheSuperHackers:main Sep 4, 2026
23 checks passed
@xezon
xezon deleted the xezon/remove-3d-streams-hack branch September 4, 2026 07:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Fix Is fixing something, but is not user facing Gen Relates to Generals Minor Severity: Minor < Major < Critical < Blocker ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants