embedded-deck
TEKNİK REHBER GÖMÜLÜ LİNUX PIPEWIRE 2026

PipeWire
Modern Linux Audio/Video.

PipeWire mimarisinden WirePlumber politika motoruna, ALSA/JACK uyumluluğundan düşük gecikme ayarlarına ve Yocto entegrasyonundan RPi4 USB mikrofon kurulumuna kadar modern Linux ses altyapısının eksiksiz rehberi.

00 PipeWire nedir

PipeWire, PulseAudio, JACK ve ALSA'yı tek bir çatı altında birleştiren modern Linux ses ve video sunucusudur. Wim Taymans tarafından Red Hat'te geliştirilen PipeWire, 2021'den itibaren birçok distro'da varsayılan ses sunucusu olmuştur.

Geçiş motivasyonu

Eski SistemSorunuPipeWire Çözümü
PulseAudioYüksek gecikme (20–80 ms), JACK uyumsuz, video yokPA API'sini emüle eder, <5 ms gecikme
JACKKurulumu karmaşık, PulseAudio ile çakışırJACK API'sini emüle eder, ortaklaşa çalışır
ALSAÇoklu uygulama karıştırma zor (dmix hack)ALSA plugin ile şeffaf yönlendirme
V4L2 (video)Kamera paylaşımı yokVideo node'ları üzerinden portal ile kamera paylaşımı

Session manager rolü

PipeWire kendisi sadece çekirdek medya sunucusudur. Cihazları yönetmek, node'ları bağlamak ve politika uygulamak için bir session manager gerekir. Günümüzde standart session manager WirePlumber'dır (eski pipewire-media-session yerini aldı).

NOT

Raspberry Pi OS Bookworm ve Ubuntu 22.10+ artık varsayılan olarak PipeWire + WirePlumber kullanır. pactl info komutu çalışıyorsa pipewire-pulse arka planda PulseAudio'yu emüle ediyor demektir.

01 Mimari

PipeWire, graph tabanlı bir medya işleme modelidir. Her ses kaynağı, filtresi veya çıkışı bir node'dur. Node'lar link'lerle bağlanır, session manager topolojiyi yönetir.

Bileşen mimarisi

┌──────────────────────────────────────────────────────────┐
│                    Uygulamalar                            │
│  GStreamer  SDL  mpv  Firefox  JACK-app  PulseAudio-app  │
└──────┬──────┬────┬──────┬──────────┬────────────┬────────┘
       │      │    │      │          │             │
   Native  ALSA  SDL  PW-native  pw-jack       pipewire-pulse
    API   plugin  plugin  API      shim            (PA compat)
       │      │    │      │          │             │
       └──────┴────┴──────┴──────────┴─────────────┘
                          │
              ┌───────────▼────────────┐
              │    PipeWire Core       │
              │  (graph engine, IPC)   │
              │   SPA plugin loader    │
              └───────────┬────────────┘
                          │
              ┌───────────▼────────────┐
              │    WirePlumber         │
              │  (session manager,     │
              │   Lua policy engine)   │
              └───────────┬────────────┘
                          │
              ┌───────────▼────────────┐
              │  Hardware Layer        │
              │  ALSA / V4L2 / BT     │
              └────────────────────────┘
    

SPA (Simple Plugin API)

spa-nodeİşlem düğümü — ses verisini üretir, tüketir veya dönüştürür (ALSA source, filter, sink)
spa-deviceFiziksel cihaz soyutlaması — alt node'ları yönetir (ses kartı = 1 device, N node)
spa-formatVeri formatı müzakeresi — sample rate, channels, format, latency parametreleri
spa-bufferZero-copy veri transferi — shared memory ring buffer, DMA-buf desteği

02 Kurulum ve temel araçlar

PipeWire araç seti ile sistem durumunu incelemek, ses kaydı/oynatma yapmak ve sorunları teşhis etmek için komut satırı araçları.

Kurulum (Debian/Ubuntu)

sudo apt install pipewire pipewire-audio-client-libraries \
    pipewire-pulse pipewire-jack \
    wireplumber \
    pipewire-alsa \
    libspa-0.2-bluetooth \
    gstreamer1.0-pipewire

# Servisleri etkinleştir (user session)
systemctl --user enable --now pipewire pipewire-pulse wireplumber

# Durum kontrolü
systemctl --user status pipewire wireplumber

pw-cli — PipeWire CLI

# Tüm object'leri listele
pw-cli list-objects

# Belirli node bilgisi
pw-cli info <node-id>

# Tüm node'lar
pw-cli list-objects Node

# İnteraktif mod
pw-cli
# pw-cli > list-objects
# pw-cli > info 42
# pw-cli > set-param 42 Props '{ volume: 0.8 }'

pw-dump — JSON formatında tam döküm

# Tüm PipeWire graph'ını JSON olarak al
pw-dump | python3 -m json.tool | less

# Sadece node'lar
pw-dump | python3 -c "
import json, sys
data = json.load(sys.stdin)
for obj in data:
    if obj.get('type') == 'PipeWire:Interface:Node':
        print(obj['id'], obj.get('info',{}).get('props',{}).get('node.name','?'))
"

pw-record / pw-play

# 10 sn kayıt — raw audio
pw-record --target=alsa_input.usb-0d8c_0014-00.mono-fallback \
          --rate=48000 --channels=1 --format=s16 \
          capture.raw

# WAV formatında kayıt
pw-record --target=default output.wav

# Oynatma
pw-play test.wav
pw-play --target=alsa_output.pci-0000_00_1f.3.analog-stereo test.wav

# Döngü testi: kaydet ve aynı anda çal
pw-record - | pw-play -

wpctl — WirePlumber ctl

# Tüm ses cihazlarını listele
wpctl status

# Varsayılan sink ses seviyesi
wpctl get-volume @DEFAULT_AUDIO_SINK@
wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.8
wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle

# Node ID ile işlem
wpctl set-volume 42 0.6

03 WirePlumber

WirePlumber, PipeWire'ın politika motorudur. Lua scripting engine üzerinde çalışır; cihazları otomatik bağlar, varsayılan sink/source belirler ve özel kurallar uygular.

Konfigürasyon yapısı

Dizinİçerik
/usr/share/wireplumber/Sistem varsayılan konfigürasyonu
~/.config/wireplumber/Kullanıcı override (öncelikli)
/etc/wireplumber/Sistem geneli override
ls /usr/share/wireplumber/
# wireplumber.conf    ← ana konfigürasyon
# wireplumber.conf.d/ ← snippet'ler
# scripts/            ← Lua scriptleri
# bluetooth.lua.d/    ← Bluetooth politikası

Özel cihaz kuralı — Lua

-- ~/.config/wireplumber/wireplumber.conf.d/50-usb-mic-rules.conf
monitor.alsa.rules = [
  {
    matches = [
      {
        -- USB mikrofonu her zaman mono + 48kHz'de aç
        node.name = "~alsa_input.usb.*"
      }
    ]
    actions = {
      update-props = {
        audio.rate     = 48000
        audio.channels = 1
        audio.format   = "S16LE"
        -- Varsayılan source yap
        priority.session = 200
      }
    }
  }
]

Otomatik bağlantı kuralı

-- ~/.config/wireplumber/wireplumber.conf.d/60-auto-connect.conf
-- Belirli bir uygulamayı belirli bir cihaza yönlendir
default.clock.rate = 48000

-- Uygulama bazlı yönlendirme
node.rules = [
  {
    matches = [{ application.name = "vlc" }]
    actions = {
      update-props = {
        target.object = "alsa_output.pci-0000_00_1f.3.hdmi-stereo"
      }
    }
  }
]

WirePlumber debug

# Debug log seviyesi
WIREPLUMBER_DEBUG=3 wireplumber

# Veya ortam değişkeni ile:
systemctl --user set-environment WIREPLUMBER_DEBUG=4
systemctl --user restart wireplumber

# Log izle
journalctl --user -u wireplumber -f

04 ALSA → PipeWire

ALSA uygulamalarının PipeWire üzerinden şeffaf çalışması için pipewire-alsa paketi bir ALSA plugin sağlar. Uygulama hw:0,0'a yazar, aslında PipeWire graph'ına bağlanır.

ALSA PipeWire plugin kurulumu

# Debian/Ubuntu
sudo apt install pipewire-alsa

# Plugin dosyası
ls /usr/lib/*/alsa-lib/libasound_module_pcm_pipewire.so

# Konfigürasyon
cat /usr/share/alsa/alsa.conf.d/99-pipewire-default.conf
# pcm.!default  { type pipewire ... }
# ctl.!default  { type pipewire ... }

/etc/pipewire/pipewire.conf

cat /etc/pipewire/pipewire.conf
# veya
cat /usr/share/pipewire/pipewire.conf

# Temel parametreler:
# default.clock.rate = 48000        ← sistem sample rate
# default.clock.quantum = 1024      ← buffer boyutu (frame)
# default.clock.min-quantum = 32    ← minimum buffer
# default.clock.max-quantum = 8192  ← maximum buffer

# Özelleştirme (override):
mkdir -p ~/.config/pipewire/pipewire.conf.d/
cat > ~/.config/pipewire/pipewire.conf.d/10-rates.conf <<'EOF'
context.properties = {
    default.clock.rate     = 48000
    default.clock.quantum  = 512
    default.clock.min-quantum = 64
}
EOF

.asoundrc ile PipeWire varsayılan olarak ayarlama

# ~/.asoundrc — PipeWire'ı varsayılan ALSA cihazı yap
pcm.!default {
    type pipewire
}

ctl.!default {
    type pipewire
}

# Fallback (PipeWire yoksa doğrudan HW)
pcm.pipewire {
    type pipewire
}

# Test: aplay artık PipeWire üzerinden çalışır
aplay -D default test.wav

# Hangi ALSA backend kullanılıyor?
ALSA_CONFIG_TINYALSA=1 aplay -l 2>&1 | head -5

05 JACK uyumluluğu

PipeWire, JACK API'sini tam olarak emüle eder. Mevcut JACK uygulamaları (Ardour, LADSPA, LV2 host'ları) yeniden derlenmeden PipeWire üzerinde çalışır.

pw-jack wrapper

# JACK uygulamasını PipeWire üzerinde çalıştır
pw-jack ardour5
pw-jack jackd  # jackd daemon'unu taklit et
pw-jack qjackctl

# LD_PRELOAD ile manuel:
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/pipewire-0.3/jack/libjack.so.0 \
    ./myjackapp

# JACK kütüphane semlink (pipewire-jack paketi)
ls -la /usr/lib/*/pipewire-0.3/jack/
# libjack.so.0 → pipewire-jack kütüphanesi

JACK API programı — PipeWire'da çalışma

/* Standart JACK kodu — pw-jack ile PipeWire'da çalışır */
#include <jack/jack.h>
#include <stdio.h>

static int process_cb(jack_nframes_t nframes, void *arg) {
    jack_port_t *port = (jack_port_t *)arg;
    jack_default_audio_sample_t *buf =
        jack_port_get_buffer(port, nframes);
    /* DSP işleme: buf üzerinde nframes frame */
    return 0;
}

int main(void) {
    jack_client_t *client = jack_client_open("myapp",
                                JackNoStartServer, NULL);
    jack_port_t *out = jack_port_register(client, "out",
                          JACK_DEFAULT_AUDIO_TYPE,
                          JackPortIsOutput, 0);
    jack_set_process_callback(client, process_cb, out);
    jack_activate(client);
    /* ... */
    jack_client_close(client);
}

JACK gecikme bilgisi

# pw-jack ile JACK gecikme ölçümü
pw-jack jack_iodelay

# PipeWire quantum (JACK period size'a eşdeğer)
pw-metadata -n settings 0 clock.force-quantum 256

# Gerçek zamanlı JACK latency
pw-jack jack_lsp -l   # port listesi + latency

06 Düşük gecikme ayarı

PipeWire'da düşük gecikme için quantum (buffer boyutu), sample rate, realtime priority ve rtkit ayarlarının doğru yapılandırılması gerekir.

Gecikme hesaplama

FORMÜL

Gecikme = (quantum / sample_rate) × 2 (çift buffer)
Örnek: quantum=256, rate=48000 → (256/48000)×2 = 10.7 ms
Örnek: quantum=64, rate=48000 → (64/48000)×2 = 2.7 ms

Quantum ayarı

# Geçici quantum değiştir (pw-metadata)
pw-metadata -n settings 0 clock.force-quantum 256

# Kalıcı quantum ayarı:
cat > ~/.config/pipewire/pipewire.conf.d/20-lowlatency.conf <<'EOF'
context.properties = {
    default.clock.rate      = 48000
    default.clock.quantum   = 256
    default.clock.min-quantum = 64
    default.clock.max-quantum = 2048
}
EOF

# Quantum sıfırla (otomatik mod)
pw-metadata -n settings 0 clock.force-quantum 0

Realtime priority ve rtkit

# rtkit paketi kurulu mu?
which rtkit-daemon
cat /etc/rtkit.conf

# pipewire.conf'ta RT ayarı
# context.properties = {
#     mem.mlock-all = true    ← tüm belleği RAM'de kilitle
#     default.clock.rate = 48000
# }

# /etc/security/limits.d/99-pipewire.conf
@audio  - rtprio  99
@audio  - memlock unlimited
@audio  - nice    -19

# Kullanıcıyı audio grubuna ekle
sudo usermod -aG audio $USER

# PipeWire RT thread önceliğini kontrol et
chrt -p $(pidof pipewire)

Gecikme ölçümü

# pw-jack ile round-trip gecikme ölçümü
pw-jack jack_iodelay

# PipeWire yerleşik gecikme bilgisi
pw-cli info | grep latency
pw-dump | python3 -c "
import json, sys
for obj in json.load(sys.stdin):
    props = obj.get('info', {}).get('props', {})
    if 'latency.min' in props or 'node.latency' in props:
        print(obj['id'], props.get('node.name'),
              props.get('node.latency'))
"

07 Embedded entegrasyonu

PipeWire'ı Yocto ile derlemek, systemd user service olarak başlatmak ve headless (ekransız) embedded sistemde konfigüre etmek için adımlar.

Yocto meta-pipewire katmanı

# meta-pipewire katmanını klonla
git clone https://gitlab.freedesktop.org/pipewire/meta-pipewire.git

# bblayers.conf'a ekle
BBLAYERS += "${TOPDIR}/../meta-pipewire"

# local.conf veya image recipe
IMAGE_INSTALL:append = " \
    pipewire \
    pipewire-modules \
    wireplumber \
    wireplumber-modules \
    pipewire-alsa \
"

# Headless konfigürasyon için session manager olmadan sadece core
IMAGE_INSTALL:append = " pipewire pipewire-spa-plugins"

# Servis dosyası otomatik gelir:
# /usr/lib/systemd/user/pipewire.service
# /usr/lib/systemd/user/wireplumber.service

systemd user service — headless başlatma

# Headless sistemde user session olmadan PipeWire başlatmak için:
# /etc/systemd/system/pipewire.service (system service)
[Unit]
Description=PipeWire Sound System (system mode)
After=network.target

[Service]
Type=simple
User=audio
Group=audio
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
Environment=XDG_RUNTIME_DIR=/run/user/1000
Environment=PIPEWIRE_RUNTIME_DIR=/run/user/1000
ExecStartPre=/usr/bin/mkdir -p /run/user/1000
ExecStartPre=/usr/bin/chown audio:audio /run/user/1000
ExecStart=/usr/bin/pipewire
Restart=on-failure

[Install]
WantedBy=multi-user.target

Headless WirePlumber konfigürasyonu

# /etc/wireplumber/wireplumber.conf.d/90-headless.conf
wireplumber.settings = {
    # Bluetooth'u devre dışı bırak (yoksa)
    bluetooth.autoswitch-to-headset-profile = false
}

# Sadece ALSA cihazlarını yönet
context.components = [
    { factory = monitor.alsa, type = script/lua/module }
    { factory = policy.node,  type = script/lua/module }
]

# Systemd loginctl linger — kullanıcı oturumu olmadan service başlat
loginctl enable-linger audio
systemctl --user --machine=audio@ start pipewire wireplumber

08 Pratik: RPi4 USB mikrofon + hoparlör, <10ms gecikme

Raspberry Pi 4 üzerinde USB ses kartı ile 10 ms altında gecikme elde etmek ve WirePlumber ile otomatik routing kurmak için adım adım rehber.

Adım 1: USB ses cihazlarını tespit et

# USB ses cihazlarını listele
lsusb | grep -i audio
aplay -l
arecord -l

# PipeWire'da cihazları gör
wpctl status
# Audio
# ├─ Devices:
# │     39. USB Audio Device           [vol: 0.80]
# └─ Sinks:
#       40. USB Audio Device Analog Stereo   [vol: 0.80]
# Sources:
#       41. USB Audio Device Mono           [vol: 1.00]

# Detaylı node bilgisi
pw-cli info 40

Adım 2: Düşük gecikme konfigürasyonu

# /etc/pipewire/pipewire.conf.d/10-rpi4-lowlatency.conf
context.properties = {
    default.clock.rate      = 48000
    default.clock.quantum   = 256      # ~5.3 ms
    default.clock.min-quantum = 128    # ~2.7 ms minimum
    default.clock.max-quantum = 1024
    mem.mlock-all = true
}

# USB cihazlar için özel quantum (bazı USB cihazlar 512 gerektirir)
context.objects = [
    {
        factory = adapter
        args = {
            factory.name     = api.alsa.pcm.sink
            node.name        = "usb-audio-sink"
            node.description = "USB Audio Sink"
            media.class      = "Audio/Sink"
            api.alsa.path    = "hw:1,0"
            audio.rate       = 48000
            audio.channels   = 2
            api.alsa.period-size = 256
            api.alsa.headroom    = 2
        }
    }
]

Adım 3: WirePlumber otomatik routing

-- /etc/wireplumber/wireplumber.conf.d/50-usb-routing.conf
-- USB mikrofonu varsayılan source, USB hoparlörü varsayılan sink yap
monitor.alsa.rules = [
  {
    matches = [{ node.name = "~alsa_output.usb.*" }]
    actions = {
      update-props = {
        priority.session = 2000
        node.pause-on-idle = false
      }
    }
  },
  {
    matches = [{ node.name = "~alsa_input.usb.*" }]
    actions = {
      update-props = {
        priority.session = 2000
        audio.rate       = 48000
        audio.channels   = 1
        node.pause-on-idle = false
      }
    }
  }
]

Adım 4: Gecikme testi ve doğrulama

# Servisler başlat
systemctl --user restart pipewire wireplumber

# Quantum doğrula
pw-metadata -n settings 0
# Key: clock.quantum, Value: 256

# Round-trip gecikme ölçümü
pw-jack jack_iodelay
# Capture latency: 5.3 ms
# Playback latency: 5.3 ms
# Round-trip: 10.6 ms

# Realtime thread önceliği doğrula
chrt -p $(pidof pipewire)
# scheduling policy: SCHED_RR
# current scheduling priority: 88

# Canlı graph izleme
watch -n 1 "wpctl status | head -30"

# Ses testi — loopback
pw-record --target=@DEFAULT_SOURCE@ - | pw-play --target=@DEFAULT_SINK@ -

Adım 5: xrun (buffer underrun) izleme

# PipeWire xrun sayısı
pw-cli info | grep xrun
pw-dump | python3 -c "
import json, sys
for obj in json.load(sys.stdin):
    stats = obj.get('info', {}).get('params', {})
    if 'xrun-count' in str(stats):
        print(obj.get('id'), stats)
"

# ALSA xrun
cat /proc/asound/card*/pcm*/sub*/xrun_debug

# Sistem tune: CPU governor
echo performance > /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
# CPU frekans scaling gecikme spike'larına yol açabilir
ÖZET

PipeWire, PulseAudio ve JACK'ı tek çatı altında birleştirir. WirePlumber'ın Lua tabanlı politika motoru ile cihaz yönlendirme kuralları kolayca özelleştirilebilir. Embedded sistemlerde quantum=256@48kHz ile ~10 ms, quantum=128@48kHz ile ~5 ms gecikme elde edilebilir. RT priority ve CPU performance governor ile xrun sayısı minimuma indirilir.