再生の開始時にオーディオが遅延しないように、Fedora 35でWirePlumberを使用してアイドル状態でオーディオレシーバーが一時停止されるのを無効にするにはどうすればよいですか?

再生の開始時にオーディオが遅延しないように、Fedora 35でWirePlumberを使用してアイドル状態でオーディオレシーバーが一時停止されるのを無効にするにはどうすればよいですか?

Fedora 35では、WirePlumberはパイプライン - メディア - セッションをオーディオセッションマネージャに置き換えます。 Linuxに組み込まれている多くのサウンドカードのオーディオには、3秒間何も再生しないとオーディオレシーバーが一時停止するという非常に迷惑な問題があります。 3秒後に再生が再開されると、音声が遅れたり、飛び出したりします。このデフォルトの動作をどのように修正できますか?

答え1

関連する設定ファイルですが、/usr/share/wireplumber/main.lua.d/50-alsa-config.luaシステムバージョンを編集しないでください。

/etc/wireplumber/main.lua.d/これを(グローバル構成)または(ユーザー構成)にコピーし、~/.config/wireplumber/main.lua.d/必要な変更を加える必要があります。

最も簡単な方法は、すべてのユーザーアカウントに適用されるようにグローバル設定の場所にコピーすることです。

sudo cp -a /usr/share/wireplumber/main.lua.d/50-alsa-config.lua /etc/wireplumber/main.lua.d/50-alsa-config.lua
sudo nano /etc/wireplumber/main.lua.d/50-alsa-config.lua

apply_properties次に、ファイルの下部の該当するセクションまで下にスクロールし、そこに1行を追加する必要があります。

["session.suspend-timeout-seconds"] = 0

私はいくつかをさらに変更し、私の個人的なハードウェアに合わせてカスタマイズしました。参照用の構成は次のとおりです。ただし、この構成は正確なデバイスでのみ機能します。実際、自動サスペンドを無効にするには、上記の行だけが必要です。これを自分のデフォルト設定に追加します。私の設定をコピーしないでください。私が変更した他のものは関係ありません。

alsa_monitor.properties = {
  ["alsa.jack-device"] = true,
  ["alsa.reserve"] = true,
  ["alsa.midi.monitoring"] = true
}

alsa_monitor.rules = {
{
    matches = {
      {
        { "device.name", "matches", "alsa_card.*" }
      }
    },
    apply_properties = {
      ["api.alsa.use-acp"] = true,
      ["api.acp.auto-profile"] = false,
      ["api.acp.auto-port"] = false
    }
  },
  {
    matches = {
      {
        { "node.name", "matches", "alsa_output.pci-0000_0c_00.4.iec958-ac3-surround-51" }
      }
    },
    apply_properties = {
      ["api.alsa.period-size"] = 128,
      ["api.alsa.headroom"] = 2048,
      ["session.suspend-timeout-seconds"] = 0
    }
  },
  { 
    matches = {
      {
        { "node.name", "matches", "alsa_input.usb-BEHRINGER_UMC202HD_192k-00.analog-mono" }
      }
    },
    apply_properties = {
      ["api.alsa.period-size"] = 128
    }
  }
}

一時停止/スリープ動作を防ぐには、このsession.suspend-timeout-secondsプロパティを設定します。0WirePlumberのソースコードに示すように、動作を完全に無効にします。

変更を適用するには、WirePlumberを再起動する必要があります。

systemctl --user restart wireplumber

答え2

session.suspend-timeout-secondsWirePlumberなしでPipeWireを実行し、パイプライン - メディア - セッションを使用するシステムでは、通常、下部を0に変更することで問題を解決できます/etc/pipewire/media-session.d/alsa-monitor.conf。ただし、このディレクトリまたはセッションモニタ設定ファイルはFedora 35インストールにはありません。実際に受信機が3秒間停止するのを防ぐ方法を示す文書がないので、この問題を直接調べる必要がありました。代わりに、WirePlumberスクリプトディレクトリでLuaスクリプトを変更する必要があります。そのエントリに移動して/usr/share/wireplumber/scripts/バックアップコピーを作成しますsuspend-node.lua。次に、sudo権限を持つテキストエディタまたはターミナルで開き、ファイルが次のようになるsuspend-node.luaようにリスナータイムアウトとリスナーサスペンドを担当するコードブロックをコメントアウトします。

-- WirePlumber
--
-- Copyright © 2021 Collabora Ltd.
--    @author George Kiagiadakis <[email protected]>
--
-- SPDX-License-Identifier: MIT

om = ObjectManager {
  Interest { type = "node",
    Constraint { "media.class", "matches", "Audio/*" }
  },
  Interest { type = "node",
    Constraint { "media.class", "matches", "Video/*" }
  },
}

sources = {}

om:connect("object-added", function (om, node)
  node:connect("state-changed", function (node, old_state, cur_state)
    -- Always clear the current source if any
    local id = node["bound-id"]
    if sources[id] then
      sources[id]:destroy()
      sources[id] = nil
    end

--    -- Add a timeout source if idle for at least 3 seconds
--    if cur_state == "idle" then
--      -- honor "session.suspend-timeout-seconds" if specified
--      local timeout =
--          tonumber(node.properties["session.suspend-timeout-seconds"]) or 3

--      if timeout == 0 then
--        return
--      end

--      -- add idle timeout; multiply by 1000, timeout_add() expects ms
--      sources[id] = Core.timeout_add(timeout * 1000, function()
--        -- Suspend the node
--        Log.info(node, "was idle for a while; suspending ...")
--        node:send_command("Suspend")

--        -- Unref the source
--        sources[id] = nil

--        -- false (== G_SOURCE_REMOVE) destroys the source so that this
--        -- function does not get fired again after 3 seconds
--        return false
--      end)
--    end

  end)
end)

om:activate()

ブロック全体をコメントアウトするよりも優れた方法があるかもしれませんが、少なくともこの方法では、受信者の状態がアイドル状態であることを確認するために処理時間を無駄にしません。これで、受信機が数秒間アイドル状態になり、音楽とビデオの再生を再開すると、迷惑なオーディオ遅延やポップ現象は発生しません。これがFedora 35でWirePlumberを使用しているすべての人に役立つことを願っています。

答え3

私はインターネット検索とここで説明されているタスクを実行するのに多くの時間を費やしました。

完全なアルゴリズムはここに残します(Ubuntu 23.04では魅力的に動作します)。

  1. 設定をグローバルスコープに移動し、そのsession.suspend-timeout-secondsパラメータを変更します。

    # Main config
     sudo mkdir -p /etc/wireplumber/main.lua.d
     sudo cp -a /usr/share/wireplumber/main.lua.d/50-alsa-config.lua /etc/wireplumber/main.lua.d/50-alsa-config.lua
    
     # Bluetooth config
     sudo mkdir -p /etc/wireplumber/bluetooth.lua.d/
     sudo cp -a /usr/share/wireplumber/bluetooth.lua.d/50-bluez-config.lua /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua
    
     # Change the needed settings in both config files
     # Pay attention to `--` in the beggining. It's a line comment in Lua. And we must remove it
     sudo sed -i 's/--\["session.suspend-timeout-seconds"\] = 5/\["session.suspend-timeout-seconds"\] = 0/g' /etc/wireplumber/main.lua.d/50-alsa-config.lua
     sudo sed -i 's/--\["session.suspend-timeout-seconds"\] = 5/\["session.suspend-timeout-seconds"\] = 0/g' /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua
    
  2. その後、サービスを再ロードします。

    systemctl --user restart pipewire wireplumber
    
  3. その後、オーディオを再生および停止するときにこのコマンドを使用して、すべてのオーディオデバイスの状態をテストし、状態の変化を観察できます。

    watch -cd -n .1 pactl list short sinks
    

    ステータスが表示されます。

    • RUNNING - デバイスが現在再生中または再生されてから10秒未満です。
    • IDLE - デバイスは再生中ではありませんが、すぐに再生する準備ができています(必要なもの!)
    • 一時停止 - この状態では、デバイスのスリープモード解除が遅れます(必須ではありません)。

    セッションで最初の再生後にSUSPENDED状態が発生しないでください。

おめでとうございます!これでオーディオがスムーズに再生されます。

答え4

関連する構成ファイルは /usr/share/wireplumber/main.lua.d/50-alsa-config.lua ですが、システムのバージョンを編集しないでください。

この回避策はBluetoothデバイスでは機能しません。機能させるには、Bluetoothファイルをコピーしてプロパティを変更してくださいsession.suspend-timeout-seconds

sudo cp -a /usr/share/wireplumber/bluetooth.lua.d/50-bluez-config.lua /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua

sudo vi /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua

50-bluez-config.lua:

apply_properties = {
  --["node.nick"] = "My Node",
  --["priority.driver"] = 100,
  --["priority.session"] = 100,
  --["node.pause-on-idle"] = false,
  --["resample.quality"] = 4,
  --["channelmix.normalize"] = false,
  --["channelmix.mix-lfe"] = false,
  ["session.suspend-timeout-seconds"] = 0,  -- 0 disables suspend
  --["monitor.channel-volumes"] = false,

  -- Media source role, "input" or "playback"
  -- Defaults to "playback", playing stream to speakers
  -- Set to "input" to use as an input for apps
  --["bluez5.media-source-role"] = "input",
},

関連情報