Skip to content

Only use new spatial audio if new apis are available#11235

Open
srietkerk wants to merge 1 commit intomasterfrom
srietkerk/firefox-audio-fix
Open

Only use new spatial audio if new apis are available#11235
srietkerk wants to merge 1 commit intomasterfrom
srietkerk/firefox-audio-fix

Conversation

@srietkerk
Copy link
Copy Markdown
Contributor

Fixes microsoft/pxt-microbit#6737

[Copilot Summary]
This pull request improves cross-browser compatibility for spatial audio features, specifically targeting Firefox's lack of support for AudioParam-based position and orientation properties on AudioListener and PannerNode. The changes introduce compatibility helpers that fall back to deprecated methods when necessary, ensuring consistent behavior across browsers.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves cross-browser spatial audio compatibility in the PXT simulator by avoiding Web Audio “new” AudioParam-based position/orientation APIs when they aren’t available (notably in Firefox), falling back to deprecated setter methods.

Changes:

  • Removed AudioParam-based position/orientation fields from PannerNode constructor options and applied them via compatibility helpers instead.
  • Updated spatial audio position/orientation updates to route through compatibility helpers.
  • Added a similar compatibility fallback for AudioListener positioning.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
pxtsim/sound/spatialAudioPlayer.ts Adds PannerNode position/orientation compatibility helpers and updates player setters/getters accordingly.
pxtsim/sound/audioContextManager.ts Adds AudioListener position compatibility fallback to deprecated setPosition() when AudioParams aren’t present.

Comment on lines +39 to +42
// Set initial position/orientation using the compat helpers
// (Firefox doesn't support AudioParam-based position/orientation properties)
setPannerPosition(this.panner, 0, 0, 0);
setPannerOrientation(this.panner, 0, 0, -1);
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The compat helpers use AudioParam.setTargetAtTime(...) for the initial position/orientation set in the constructor. This changes behavior vs the previous PannerNode options (which set the initial values immediately) and can leave the node briefly at the browser defaults (e.g. orientation (1,0,0)) before it converges. Consider using an immediate set (e.g. setValueAtTime at panner.context.currentTime) for the initial values, and reserve setTargetAtTime for subsequent smoothing updates.

Suggested change
// Set initial position/orientation using the compat helpers
// (Firefox doesn't support AudioParam-based position/orientation properties)
setPannerPosition(this.panner, 0, 0, 0);
setPannerOrientation(this.panner, 0, 0, -1);
// Set initial position/orientation immediately.
// Prefer legacy methods for broader browser support; fall back to AudioParams.
const now = this.context.currentTime;
if (typeof (this.panner as any).setPosition === "function") {
(this.panner as any).setPosition(0, 0, 0);
} else {
if (this.panner.positionX) this.panner.positionX.setValueAtTime(0, now);
if (this.panner.positionY) this.panner.positionY.setValueAtTime(0, now);
if (this.panner.positionZ) this.panner.positionZ.setValueAtTime(0, now);
}
if (typeof (this.panner as any).setOrientation === "function") {
(this.panner as any).setOrientation(0, 0, -1);
} else {
if (this.panner.orientationX) this.panner.orientationX.setValueAtTime(0, now);
if (this.panner.orientationY) this.panner.orientationY.setValueAtTime(0, now);
if (this.panner.orientationZ) this.panner.orientationZ.setValueAtTime(-1, now);
}

Copilot uses AI. Check for mistakes.
Comment on lines +80 to +82
get x(): number { return this.panner.positionX?.value ?? 0; }
get y(): number { return this.panner.positionY?.value ?? 0; }
get z(): number { return this.panner.positionZ?.value ?? 0; }
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

In browsers where PannerNode.positionX/Y/Z are missing and the code falls back to the deprecated setPosition(), the x/y/z getters will now always return 0 (because they only read the AudioParam values). To keep the SpatialAudioPlayer API consistent across browsers, consider caching the last position values when setPosition() is called (and returning those cached values when AudioParams aren’t available).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Firefox: Simulator does not update after executing tutorial steps

2 participants