Skip to content

fix: Match audio playback sample rate to project settings#1486

Draft
yuto-trd wants to merge 1 commit intomainfrom
feat/audio-sample-rate
Draft

fix: Match audio playback sample rate to project settings#1486
yuto-trd wants to merge 1 commit intomainfrom
feat/audio-sample-rate

Conversation

@yuto-trd
Copy link
Copy Markdown
Member

@yuto-trd yuto-trd commented Feb 15, 2026

Description

Fixed an issue where the mastering voice of XAudioContext was hardcoded to 44100Hz.

  • Added a sampleRate parameter to the constructor (maintaining backward compatibility with a default value of 44100)
  • Changed to pass the project's sample rate from PlayerViewModel
  • Resolved audio skipping issues in 48KHz projects

Breaking changes

None

Fixed issues

None

Pass the project's sample rate to XAudioContext instead of hardcoding
44100Hz, fixing audio playback issues with 48KHz projects.
Copilot AI review requested due to automatic review settings February 15, 2026 09:17
@github-actions
Copy link
Copy Markdown
Contributor

No TODO comments were found.

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

Windows (XAudio2) のマスタリングボイスが 44100Hz 固定になっていた点を解消し、プロジェクト設定のサンプルレートに追従させるための修正です。48kHz プロジェクトでの音飛びを防ぐ狙いで、Windows 側の再生コンテキスト生成時にサンプルレートを渡せるようにしています。

Changes:

  • XAudioContext のコンストラクタに sampleRate パラメータを追加し、マスタリングボイス生成時のサンプルレートを可変化
  • PlayerViewModel から Composer.SampleRate を取得して XAudioContext に渡すよう変更

Reviewed changes

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

File Description
src/Beutl/ViewModels/PlayerViewModel.cs Windows の XA2 再生開始時にプロジェクト/Composer のサンプルレートを XAudioContext に渡す
src/Beutl.Engine/Audio/Platforms/XAudio2/XAudioContext.cs マスタリングボイス作成時のサンプルレートを引数で指定可能にする

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


public XAudioContext()
public XAudioContext(int sampleRate = 44100)
{
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

sampleRate is accepted as int and then cast to uint for CreateMasteringVoice. If the project/composer sample rate is 0 or negative (e.g., malformed project variable), this will turn into an unexpected large uint and can make XAudio2 initialization fail in hard-to-diagnose ways. Please validate sampleRate > 0 (and ideally throw ArgumentOutOfRangeException, consistent with other audio types like AudioBuffer/AudioProcessContext) before creating the mastering voice.

Suggested change
{
{
if (sampleRate <= 0)
{
throw new ArgumentOutOfRangeException(nameof(sampleRate), "Sample rate must be greater than zero.");
}

Copilot uses AI. Check for mistakes.
if (OperatingSystem.IsWindows())
{
using var audioContext = new XAudioContext();
int sampleRate = EditViewModel.Composer.Value.SampleRate;
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

sampleRate is taken directly from EditViewModel.Composer.Value.SampleRate and passed into XAudioContext. Unlike GetFrameRate() (which clamps invalid values), there’s no guard here; if SampleRate is 0/negative, Windows playback can fail when the mastering voice is created. Consider applying the same pattern as GetFrameRate() (fallback to 44100 or project default) before constructing the audio context, or ensure the composer always exposes a validated positive rate.

Suggested change
int sampleRate = EditViewModel.Composer.Value.SampleRate;
int sampleRate = EditViewModel.Composer.Value.SampleRate;
if (sampleRate <= 0)
{
sampleRate = 44100;
}

Copilot uses AI. Check for mistakes.
@@ -24,10 +24,10 @@ static XAudioContext()
}
}

Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

Changing the constructor from XAudioContext() to XAudioContext(int sampleRate = 44100) keeps source compatibility for this repo, but it removes the parameterless .ctor and is a binary breaking change for any already-compiled consumers/plugins. If Beutl.Engine is intended to be consumed externally, consider keeping a parameterless constructor overload that delegates to the new one to preserve binary compatibility.

Suggested change
public XAudioContext()
: this(44100)
{
}

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Branch Rate Complexity Health
Beutl.Editor 82% 76% 870
Beutl.Extensibility 14% 16% 100
Beutl.Operators 2% 0% 120
Beutl.Language 0% 20% 943
Beutl.ProjectSystem 13% 7% 2887
Beutl.Threading 99% 89% 122
Beutl.Engine 21% 19% 13751
Beutl.Configuration 39% 19% 288
Beutl.Utilities 73% 67% 358
Beutl.Core 40% 36% 2966
Summary 25% (13308 / 54059) 24% (3680 / 15473) 22405

Minimum allowed line rate is 0%

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7a59b69bc4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (OperatingSystem.IsWindows())
{
using var audioContext = new XAudioContext();
int sampleRate = EditViewModel.Composer.Value.SampleRate;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Read sample rate from project settings before creating XAudioContext

On Windows playback this value still resolves to 44.1kHz because EditViewModel constructs SceneComposer without initializing SampleRate (src/Beutl/ViewModels/EditViewModel.cs:61-64), and Composer sets SampleRate = 44100 by default (src/Beutl.Engine/Audio/Composing/Composer.cs:32-35). That means new XAudioContext(sampleRate) here effectively keeps using 44100 for all projects, so 48kHz projects remain on a mismatched mastering voice and the audio-drop issue this patch targets is not actually fixed.

Useful? React with 👍 / 👎.

@yuto-trd yuto-trd changed the title fix: 音声再生のサンプルレートをプロジェクト設定に合わせる fix: Match audio playback sample rate to project settings Feb 15, 2026
@yuto-trd yuto-trd marked this pull request as draft February 15, 2026 12:11
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.

2 participants