LINUX.ORG.RU

История изменений

Исправление James_Holden, (текущая версия) :

Вот базовый вариант для стерео-стерео, он демонстрирует принцип, применимый к любой конфигурации.

context.modules = [
    { name = libpipewire-module-filter-chain
        args = {
            node.description = "Exchange"
            media.name       = "Exchange"
            filter.graph = {
                nodes = [
                    {
                      type = builtin
                      label = mixer
                      name = mixL
                      control = {
                      }
                    }
                    {
                      type = builtin
                      label = mixer
                      name = mixR
                      control = {
                      }
                    }
                ]
                links = [

                ]
                inputs = [ "mixL:In 1" "mixR:In 1" ]
                outputs = [ "mixR:Out" "mixL:Out" ]
            }
            capture.props = {
                node.name   = "effect_input.exchange"
                media.class = Audio/Sink
                audio.channels = 2
                audio.position=[FL FR]
            }
            playback.props = {
                node.name   = "effect_output.exchange"
                node.passive = true
                audio.channels = 2
                audio.position=[FL FR]
            }
        }
    }
]

Смысл. На каждый входной канал создаем ноду Mixer в filter-chain. Затем, в разделе inputs/outputs, подключаем эти ноды к выходным каналам в измененном порядке. В этом примере, правый и левый поменяны местами.

Если надо не стерео, а 5.1 - все то же самое, создаем 6 нод в цепочке filter-chain, а в inputs/outputs пересоединяем их в любом измененном порядке.

Со стороны источников звука - они увидят виртуальный синк exchange в списке устройств вывода. Этот синк будет иметь столько же входных программных каналов, и такие же каналы, как и твоя аудиокарта. Но он представляет собой фильтр, пройдя через который нужные каналы меняются местами. Без изменения числа и конфигурации каналов. Для приложения, выводящего звук, не изменится ничего, а физически, звук пойдет в другие каналы.

Если число каналов у плеера и у этого синка не совпадают, pipewire автоматически либо сделает downmix, либо раскидает по части каналов. Все как с реальной звуковой картой.

Этот конфиг надо назвать exchange.conf и поместить в ~/.config/pipewire/pipewire.conf.d

Исправление James_Holden, :

Вот базовый вариант для стерео-стерео, он демонстрирует принцип, применимый к любой конфигурации.

context.modules = [
    { name = libpipewire-module-filter-chain
        args = {
            node.description = "Exchange"
            media.name       = "Exchange"
            filter.graph = {
                nodes = [
                    {
                      type = builtin
                      label = mixer
                      name = mixL
                      control = {
                      }
                    }
                    {
                      type = builtin
                      label = mixer
                      name = mixR
                      control = {
                      }
                    }
                ]
                links = [

                ]
                inputs = [ "mixL:In 1" "mixR:In 1" ]
                outputs = [ "mixR:Out" "mixL:Out" ]
            }
            capture.props = {
                node.name   = "effect_input.exchange"
                media.class = Audio/Sink
                audio.channels = 2
                audio.position=[FL FR]
            }
            playback.props = {
                node.name   = "effect_output.exchange"
                node.passive = true
                audio.channels = 2
                audio.position=[FL FR]
            }
        }
    }
]

Смысл. На каждый входной канал создаем ноду Mixer в filter-chain. Затем, в разделе links, подключаем эти ноды к выходным каналам в измененном порядке. В этом примере, правый и левый поменяны местами.

Если надо не стерео, а 5.1 - все то же самое, создаем 6 нод в цепочке filter-chain, а в links пересоединяем их в любом измененном порядке.

Со стороны источников звука - они увидят виртуальный синк exchange в списке устройств вывода. Этот синк будет иметь столько же входных программных каналов, и такие же каналы, как и твоя аудиокарта. Но он представляет собой фильтр, пройдя через который нужные каналы меняются местами. Без изменения числа и конфигурации каналов. Для приложения, выводящего звук, не изменится ничего, а физически, звук пойдет в другие каналы.

Если число каналов у плеера и у этого синка не совпадают, pipewire автоматически либо сделает downmix, либо раскидает по части каналов. Все как с реальной звуковой картой.

Этот конфиг надо назвать exchange.conf и поместить в ~/.config/pipewire/pipewire.conf.d

Исправление James_Holden, :

Вот базовый вариант для стерео-стерео, он демонстрирует принцип, применимый к любой конфигурации.

context.modules = [
    { name = libpipewire-module-filter-chain
        args = {
            node.description = "Exchange"
            media.name       = "Exchange"
            filter.graph = {
                nodes = [
                    {
                      type = builtin
                      label = mixer
                      name = mixL
                      control = {
                      }
                    }
                    {
                      type = builtin
                      label = mixer
                      name = mixR
                      control = {
                      }
                    }
                ]
                links = [

                ]
                inputs = [ "mixL:In 1" "mixR:In 1" ]
                outputs = [ "mixR:Out" "mixL:Out" ]
            }
            capture.props = {
                node.name   = "effect_input.exchange"
                media.class = Audio/Sink
                audio.channels = 2
                audio.position=[FL FR]
            }
            playback.props = {
                node.name   = "effect_output.exchange"
                node.passive = true
                audio.channels = 2
                audio.position=[FL FR]
            }
        }
    }
]

Смысл. На каждый входной канал создаем ноду Mixer в filter-chain. Затем, в разделе links, подключаем эти ноды к выходным каналам в измененном порядке. В этом примере, правый и левый поменяны местами.

Если надо не стерео, а 5.1 - все то же самое, создаем 6 нод в цепочке filter-chain, а в links пересоединяем их в любом измененном порядке.

Со стороны источников звука - они увидят виртуальный синк exchange в списке устройств вывода. Этот синк будет иметь столько же входных программных каналов, и такие же каналы, как и твоя аудиокарта. Но он представляет собой фильтр, пройдя через который нужные каналы меняются местами. Без изменения числа и конфигурации каналов. Для приложения, выводящего звук, не изменится ничего, а физически, звук пойдет в другие каналы.

Если число каналов у плеера и у этого синка не совпадают, pipewire автоматически либо сделает downmix, либо раскидает по части каналов. Все как с реальной звуковой картой.

Исправление James_Holden, :

Вот базовый вариант для стерео-стерео, он демонстрирует принцип, применимый к любой конфигурации.

context.modules = [
    { name = libpipewire-module-filter-chain
        args = {
            node.description = "Exchange"
            media.name       = "Exchange"
            filter.graph = {
                nodes = [
                    {
                      type = builtin
                      label = mixer
                      name = mixL
                      control = {
                      }
                    }
                    {
                      type = builtin
                      label = mixer
                      name = mixR
                      control = {
                      }
                    }
                ]
                links = [

                ]
                inputs = [ "mixL:In 1" "mixR:In 1" ]
                outputs = [ "mixR:Out" "mixL:Out" ]
            }
            capture.props = {
                node.name   = "effect_input.exchange"
                media.class = Audio/Sink
                audio.channels = 2
                audio.position=[FL FR]
            }
            playback.props = {
                node.name   = "effect_output.exchange"
                node.passive = true
                audio.channels = 2
                audio.position=[FL FR]
            }
        }
    }
]

Смысл. На каждый входной канал создаем ноду Mixer в filter-chain. Затем, в разделе links, подключаем эти ноды к выходным каналам в измененном порядке. В этом примере, правый и левый поменяны местами.

Если надо не стерео, а 5.1 - все то же самое, создаем 6 нод в цепочке filter-chain, а в links пересоединяем их в любом измененном порядке.

Со стороны источников звука - они увидят виртуальный синк exchange в списке устройств вывода. Этот синк будет иметь столько же входных программных каналов, и такие же каналы, как и твоя аудиокарта. Но он представляет собой фильтр, пройдя через который нужные каналы меняются местами. Без изменения числа и конфигурации каналов. Для приложения, выводящего звук, не изменится ничего, а физически, звук пойдет в другие каналы.

Исходная версия James_Holden, :

Вот базовый вариант для стерео-стерео, он демонстрирует принцип, применимый к любой конфигурации.

context.modules = [
    { name = libpipewire-module-filter-chain
        args = {
            node.description = "Exchange"
            media.name       = "Exchange"
            filter.graph = {
                nodes = [
                    {
                      type = builtin
                      label = mixer
                      name = mixL
                      control = {
                      }
                    }
                    {
                      type = builtin
                      label = mixer
                      name = mixR
                      control = {
                      }
                    }
                ]
                links = [

                ]
                inputs = [ "mixL:In 1" "mixR:In 1" ]
                outputs = [ "mixR:Out" "mixL:Out" ]
            }
            capture.props = {
                node.name   = "effect_input.exchange"
                media.class = Audio/Sink
                audio.channels = 2
                audio.position=[FL FR]
            }
            playback.props = {
                node.name   = "effect_output.exchange"
                node.passive = true
                audio.channels = 2
                audio.position=[FL FR]
            }
        }
    }
]

Смысл. На каждый входной канал создаем ноду Mixer в filter-chain. Затем, в разделе links, подключаем эти ноды к выходным каналам в измененном порядке. В этом примере, правый и левый поменяны местами.

Если надо не стерео а 5.1, все то же самое, создаем 6 нод в цепочке filter-chain, а в links пересоединяем их в любом измененном порядке.

Со стороны источников звука - они увидят виртуальный синк exchange в списке устройств вывода. Этот синк будет иметь столько же входных программных каналов, и такие же каналы, как и твоя аудиокарта. Но он представляет собой фильтр, пройдя через который нужные каналы меняются местами. Без изменения числа и конфигурации каналов. Для приложения, выводящего звук, не изменится ничего, а физически, звук пойдет в другие каналы.