Skip to content

feat: 单声道模式支持#887

Merged
fly602 merged 2 commits intolinuxdeepin:masterfrom
fly602:master
Sep 10, 2025
Merged

feat: 单声道模式支持#887
fly602 merged 2 commits intolinuxdeepin:masterfrom
fly602:master

Conversation

@fly602
Copy link
Contributor

@fly602 fly602 commented Sep 4, 2025

单声道设置,原来的方案不通用,现在改为使用加载模块module-remap-sink的方式支持单声道模式。切换单声道模式时,改变sink-input和sink的绑定来处理没有声音的问题。

Log: 单声道模式方案变更,更加通用
PMS: TASK-369021
Influence: audio mono

Summary by Sourcery

Implement mono audio mode support using PulseAudio’s module-remap-sink, refactor sink input routing for both virtual and physical devices, and add a helper script to manage mono module loading.

New Features:

  • Add support for mono audio mode via PulseAudio’s module-remap-sink
  • Introduce monoEnable.sh script to load/unload remap-sink modules and set the default sink

Enhancements:

  • Refactor sink input movement to handle nil input lists, skip echo-cancel streams, and route to virtual or physical sinks
  • Update default sink logic to integrate with virtual devices and mono settings
  • Improve logging for sink and sink-input addition events

单声道设置,原来的方案不通用,现在改为使用加载模块module-remap-sink的方式支持单声道模式。切换单声道模式时,改变sink-input和sink的绑定来处理没有声音的问题。

Log: 单声道模式方案变更,更加通用
PMS: TASK-369021
Influence: audio mono
@sourcery-ai
Copy link

sourcery-ai bot commented Sep 4, 2025

Reviewer's Guide

Refactors audio routing to support mono mode by leveraging the module-remap-sink plugin and centralizing sink-input movement logic, with added shell-script integration for toggling mono and extended virtual‐sink handling.

File-Level Changes

Change Details Files
Unify sink-input routing in moveSinkInputsToSink
  • Changed signature to accept input list or nil
  • Retrieve default sink name and build input lists
  • Filter out echo-cancel streams and separate remap-sink-mono inputs
  • Handle physical vs virtual sinks and move inputs by name
audio1/audio.go
Enhance default-sink update for virtual devices
  • Detect non-physical (remap or echo-cancel) sinks
  • Resolve master sink name via module arguments
  • Invoke moveSinkInputsToSink(nil) after sink discovery
audio1/audio.go
Integrate external script for mono mode toggling
  • Create monoEnable.sh to load/unload module-remap-sink
  • In Sink.SetMono, call shell script for enabling mono
  • Unload module-remap-sink via pactl when disabling mono
audio1/sink.go
misc/dde-daemon/audio/monoEnable.sh
Refine event handlers and logging
  • Include sink/sink-input names in debug logs
  • Replace direct pactl moves with moveSinkInputsToSink calls
audio1/audio_events.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Sorry @fly602, you have reached your weekly rate limit for Sourcery. Please try again later

@deepin-bot
Copy link
Contributor

deepin-bot bot commented Sep 4, 2025

TAG Bot

New tag: 6.1.53
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #888

@deepin-ci-robot
Copy link

deepin pr auto review

代码审查报告

1. 语法逻辑

优点:

  • 代码整体结构清晰,函数划分合理
  • 错误处理机制完善,多处使用了适当的错误检查和日志记录
  • 并发控制使用mutex锁,保证了线程安全

改进建议:

  1. moveSinkInputsToSink 函数参数从 sinkId uint32 改为 inputs []uint32 的变更合理,但缺少对参数的空值检查
  2. SetMono 函数中,defaultSink 为空时的错误处理可以更明确
  3. getMasterNameFromVirtualDevice 函数中的正则表达式匹配可能不够健壮,建议增加错误处理

2. 代码质量

优点:

  • 日志记录完善,包含调试、信息和警告级别
  • 代码注释清晰,特别是在关键业务逻辑处
  • 函数职责单一,便于维护

改进建议:

  1. 建议将 isPhysicalDevice 函数中的虚拟设备 key 定义提取为常量
  2. moveSinkInputsToSink 函数中,对虚拟设备的处理逻辑可以提取为独立函数
  3. SetMono 函数中的 shell 命令执行可以封装为独立函数,提高代码可测试性

3. 代码性能

优点:

  • 使用了适当的缓存机制,如 defaultSink 的缓存
  • 避免了不必要的重复计算

改进建议:

  1. getMasterNameFromVirtualDevice 函数每次都遍历所有模块,可以考虑添加缓存机制
  2. moveSinkInputsToSink 函数中多次调用 a.context().GetDefaultSink(),可以只调用一次并缓存结果
  3. 对于频繁调用的日志操作,可以考虑使用日志级别过滤,避免不必要的字符串拼接

4. 代码安全

优点:

  • 使用了 mutex 保护共享资源
  • 对外部输入进行了适当的验证

改进建议:

  1. SetMono 函数中执行 shell 命令时,建议使用更严格的参数验证
  2. monoEnable.sh 脚本中的参数拼接需要确保安全性,避免命令注入
  3. 建议为 exec.Command 的执行添加超时控制,防止阻塞

5. 具体改进建议

  1. moveSinkInputsToSink 函数:
func (a *Audio) moveSinkInputsToSink(inputs []uint32) {
    if inputs == nil {
        inputs = make([]uint32, 0)
        // ... 其他逻辑
    }
    // ... 其余代码
}
  1. SetMono 函数中的命令执行:
func (a *Audio) executeCommand safely(command string, args ...string) error {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    cmd := exec.CommandContext(ctx, command, args...)
    if _, err := cmd.CombinedOutput(); err != nil {
        return fmt.Errorf("command execution failed: %v", err)
    }
    return nil
}
  1. 添加虚拟设备 key 常量:
const (
    EchoCancelKey    = "echo-cancel"
    EchoCancelKey2   = "Echo-Cancel"
    EchoCancelSource = "echoCancelSource"
    RemapSinkMono    = "remap-sink-mono"
)
  1. 改进 getMasterNameFromVirtualDevice 函数的缓存机制:
func (a *Audio) getMasterNameFromVirtualDevice(device string) string {
    if cached, ok := a.masterCache.Load(device); ok {
        return cached.(string)
    }
    // ... 原有逻辑
    a.masterCache.Store(device, master)
    return master
}

这些改进建议旨在提高代码的健壮性、可维护性和性能。建议根据实际需求逐步实施这些改进。

@mhduiy
Copy link
Contributor

mhduiy commented Sep 10, 2025

/approvel

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: fly602, mhduiy

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@fly602 fly602 merged commit 486e8f3 into linuxdeepin:master Sep 10, 2025
16 checks passed
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.

3 participants