LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

Linux音频(2):pulseaudio

pulseaudio作为声音服务器,启动时根据配置文件对ALSA子系统进行配置,并作为后台进程进行声音重定向配置。

官方文档位于《Documentation – PulseAudio》,但是没有更多概括性介绍和设计功能介绍。《PulseAudio under the hood (gavv.net)》做了很好的补充,首先可以从这篇文档开始pulseaudio的理解。

1 pulseaudio框架

PulseAudio是一个声音服务器,启动时读取配置文件对ALSA系统Control进行配置。作为一个后台进程从一个或多个音源(进程或输入设备)接受声音输入 然后重定向声音到一个或多个槽(声卡,远程网络PulseAudio服务,或其他进程)。PulseAudio的一个目的通过它是重定向所有声音流,包括那些试图访问硬件的进程

2 pulseaudio启动

/etc/init.d/S50pulseaudio在系统启动时被调用,启动pulseaudio进程:
#!/bin/sh
#
# Starts pulseaudio.
#


start() {
    printf "Starting pulseaudio: "
    umask 077
    /usr/bin/pulseaudio &
#        --system \
#        --daemonize \
#        --disallow-module-loading \
#        --disallow-exit \
#        --exit-idle-time=-1 \
#        --use-pid-file \
#        --disable-shm
    echo "OK"
}
stop() {
    printf "Stopping pulseaudio: "
    PULSE_RUNTIME_PATH=/var/run/pulse /usr/bin/pulseaudio --kill
    echo "OK"
}
restart() {
    stop
    start
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart|reload)
    restart
    ;;
  *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
esac

exit $?

3 RK3588相关pulseaudio配置

/etc/pulse/daemon.conf

/usr/share/alsa/alsa.conf

UCM定义了用户配置,pulseaudio在启动时对ALSA子系统进行配置(Use Case Configuration)。

/usr/share/alsa/ucm2/ucm.conf

Syntax 4

Define.V1 ""        # non-empty string to enable ucm v1 paths
Define.V2ConfD yes    # empty string to disable
Define.V2Module ""    # non-empty string to enable module name lookups (obsolete)
Define.V2Name ""    # non-empty string to enable driver & card name lookups (obsolete)

Include.libgen.File "/lib/generic.conf"  # private alsa-lib configuration

If.driver {
    Condition {
        Type String
        Empty "${CardNumber}"
    }
...
    False {

        #
        # The probed path when hw-card is found:
        #
        #   ucm2/conf.d/[${CardDriver}|${KernelDriver}]/${CardLongName}.conf
        #   ucm2/conf.d/[${CardDriver}|${KernelDriver}]/[${CardDriver}|${KernelDriver}].conf
        #   ucm2/${KernelModule}/${KernelModule}.conf (obsolete)
        #   ucm2/${CardDriver}/${CardLongName}.conf (obsolete)
        #   ucm2/${CardDriver}/${CardDriver}.conf (obsolete)
        #
...
        If.V2Name {
            Condition {
                Type String
                Empty "${var:V2Name}"
            }
            False.UseCasePath {--指定用户自动以配置文件。
                longname {
                    Directory "${CardDriver}"
                    File "${CardLongName}.conf"
                }
                driver {
                    Directory "${CardDriver}"
                    File "${CardDriver}.conf"
                }
            }
        }
    }
}

根据ucm.conf配置,对应的配置文件为:/usr/share/alsa/ucm2/conf.d/rockchip-es8388/rockchip-es8388.conf:

Syntax 2

Comment "Rockchip ES8388 card"

SectionUseCase."HiFi" {
    File "HiFi.conf"--读取HiFi.conf文件。
    Comment "Default"
}

SectionVerb {
    Value {
        MinBufferLevel "512"
    }

    EnableSequence [--默认启动Control配置流程。
        cset "name='Speaker Switch' off"
        cset "name='Headphone Switch' off"
        cset "name='Headset Mic Switch' off"
        cset "name='Main Mic Switch' off"
        cset "name='Speaker Switch' off"
        cset "name='Headphone Switch' off"
        cset "name='Headset Mic Switch' off"
        cset "name='Main Mic Switch' off"
        cset "name='PCM Volume' 192"--PCM默认音量。
        cset "name='Output 1 Playback Volume' 27"
        cset "name='Output 2 Playback Volume' 27"
        cset "name='Capture Digital Volume' 192"
        cset "name='Left Channel Capture Volume' 3"
        cset "name='Right Channel Capture Volume' 3"
        cset "name='Left Mixer Left Playback Switch' on"
        cset "name='Right Mixer Right Playback Switch' on"
        cset "name='Capture Mute' off"
        cset "name='Right PGA Mux' DifferentialR"
        cset "name='Left PGA Mux' DifferentialL"
    ]
}

SectionDevice."Speaker" {--外放喇叭。
    Comment "Speaker"

    ConflictingDevice [
        "Headphones"
    ]

    Value {
        PlaybackPriority 100
        PlaybackPCM "hw:${CardId}"
    }

    EnableSequence [
        cset "name='Speaker Switch' on"
    ]

    DisableSequence [
        cset "name='Speaker Switch' off"
    ]
}

SectionDevice."Mic" {--单Mic。
    Comment "Internal Microphone"

    ConflictingDevice [
        "Headset"
    ]

    Value {
        CapturePriority 100
        CapturePCM "hw:${CardId}"
    }

    EnableSequence [
        cset "name='Differential Mux' Line 2"
        cset "name='Main Mic Switch' on"
    ]

    DisableSequence [
        cset "name='Main Mic Switch' off"
    ]
}

SectionDevice."Headphones" {--头戴式耳机。
    Comment "Headphones"

    ConflictingDevice [
        "Speaker"
    ]

    Value {
        PlaybackPriority 200
        PlaybackPCM "hw:${CardId}"
        JackControl "Headphone Jack"
        JackHWMute "Speaker"
    }

    EnableSequence [
        cset "name='Headphone Switch' on"
    ]
    DisableSequence [
        cset "name='Headphone Switch' off"
    ]
}

SectionDevice."Headset" {--头戴式单麦克。
    Comment "Headset Microphone"

    ConflictingDevice [
        "Mic"
    ]

    Value {
        CapturePriority 200
        CapturePCM "hw:${CardId}"
        JackControl "Headset Mic Jack"
        JackHWMute "Mic"
    }

    EnableSequence [
        cset "name='Differential Mux' Line 1"
        cset "name='Headset Mic Switch' on"
    ]

    DisableSequence [
        cset "name='Headset Mic Switch' off"
    ]
}

posted on 2024-05-02 23:59  ArnoldLu  阅读(1332)  评论(0编辑  收藏  举报

导航