# AES67 config file for PipeWire version "1.6.8" #
#
# Copy and edit this file in /etc/pipewire for system-wide changes
# or in ~/.config/pipewire for local changes.
#
# It is also possible to place a file with an updated section in
# /etc/pipewire/pipewire-aes67.conf.d/ for system-wide changes or in
# ~/.config/pipewire/pipewire-aes67.conf.d/ for local changes.
#

context.properties = {
    ## Configure properties in the system.
    #mem.warn-mlock  = false
    #mem.allow-mlock = true
    #mem.mlock-all   = false
    #log.level       = 2

    #default.clock.quantum-limit = 8192
}

context.spa-libs = {
    support.*       = support/libspa-support
}

context.objects = [
    # An example clock reading from /dev/ptp0. You can also specify the network interface name,
    # pipewire will query the interface for the current active PHC index. Another option is to
    # sync the ptp clock to CLOCK_TAI and then set clock.id = tai, keep in mind that tai may
    # also be synced by a NTP client.
    # The precedence is: device, interface, id
    { factory = spa-node-factory
        args = {
            factory.name    = support.node.driver
            node.name       = PTP0-Driver
            node.group      = pipewire.ptp0
            # This driver should only be used for network nodes marked with group
            priority.driver = 100000
            clock.name      = "clock.system.ptp0"
            ### Please select the PTP hardware clock here
            # Interface name is the preferred method of specifying the PHC
            clock.interface = "eth0"
            #clock.device    = "/dev/ptp0"
            #clock.id        = tai
            # Lower this in case of periodic out-of-sync
            resync.ms       = 1.5
            object.export   = true
        }
    }
]

context.modules = [
    { name = libpipewire-module-rt
        args = {
            nice.level   = -11
            #rt.prio      = 83
            #rt.time.soft = -1
            #rt.time.hard = -1
            #rlimits.enabled = true
            #rtportal.enabled = true
            #rtkit.enabled = true
            #uclamp.min = 0
            #uclamp.max = 1024
        }
        flags = [ ifexists nofail ]
    }
    { name = libpipewire-module-protocol-native }
    { name = libpipewire-module-client-node }
    { name = libpipewire-module-spa-node-factory }
    { name = libpipewire-module-adapter }
    { name = libpipewire-module-rtp-sap
        args = {
            ### Please select the interface here
            local.ifname = eth0
            sap.ip = 239.255.255.255
            sap.port = 9875
            net.ttl = 32
            net.loop = false
            # If you use another PTPv2 daemon supporting management
            # messages over a UNIX socket, specify its path here
            ptp.management-socket = "/var/run/ptp4lro"

            stream.rules = [
                {
                    matches = [
                        {
                            rtp.session = "~.*"
                        }
                    ]
                    actions = {
                        create-stream = {
                            node.virtual = false
                            media.class = "Audio/Source"
                            device.api = aes67
                            # You can adjust the latency buffering here. Use integer values only
                            sess.latency.msec = 3
                            node.group = pipewire.ptp0
                        }
                    }
                },
                {
                    matches = [
                        {
                            sess.sap.announce = true
                        }
                    ]
                    actions = {
                        announce-stream = {}
                    }
               }
            ]
        }
    },
    { name = libpipewire-module-rtp-sink
        args = {
            ### Please select the interface here
            local.ifname = eth0
            ### If you want to create multiple output streams, please copy the whole
            ### module-rtp-sink block, but change this multicast IP to another unused
            ### one keeping 239.69.x.x range unless you know you need another one
            destination.ip = 239.69.150.243
            destination.port = 5004
            net.mtu = 1280
            net.ttl = 32
            net.loop = false
            # These should typically be equal
            # You can customize packet length, but 1 ms should work for every device
            # Consult receiver documentation to ensure it supports the value you set
            sess.min-ptime = 1
            sess.max-ptime = 1
            ### Please change this, especially if you create multiple sinks
            sess.name = "PipeWire RTP stream"
            sess.media = "audio"
            # This property is used if you aren't using ptp4l 4
            sess.ts-refclk = "ptp=traceable"
            sess.ts-offset = 0
            # Directly synchronize output against the PTP-synced driver using the RTP timestamps
            # This can be set to true if the reference clocks are the same; it then makes the
            # synchronization more robust against transport delay variations and can help lower
            # latency
            sess.ts-direct = false
            # You can adjust the latency buffering here. Use integer values only
            sess.latency.msec = 3
            audio.format = "S24BE"
            audio.rate = 48000
            audio.channels = 2
            # These channel names will be visible both to applications and AES67 receivers
            node.channel-names = ["CH1", "CH2"]
            # Uncomment this and comment node.group in send/recv stream.props to allow
            # separate drivers for the RTP sink and PTP sending (i.e. force rate matching on
            # the AES67 node rather than other nodes)
            #aes67.driver-group = "pipewire.ptp0"

            stream.props = {
                ### Please change the sink name, this is necessary when you create multiple sinks
                node.name = "rtp-sink"
                media.class = "Audio/Sink"
                node.virtual = false
                device.api = aes67
                sess.sap.announce = true
                node.always-process = true
                node.group = pipewire.ptp0
                rtp.ntp = 0
                rtp.fetch-ts-refclk = true
            }
        }
    },
]
