板端——linphone双向有声测试问题记录
板端 baresip × linphone 双向有声测试问题记录
环境:RK3588 开发板(Buildroot,root@192.168.86.130)/ baresip v4.12.0 arm64 静态版(26 模块)/ FreeSWITCH(192.168.86.56:5070)/ Windows linphone(1000)
日期:2026-10-10
关键词:baresip、ALSA、softvol、augain、Opus、plughw、交叉编译
关联阅读:上一篇《RK3588 录音音量太小怎么办——从 PDM 数字麦克风原理到 softvol 软件增益实战》
0. 现象与结论
板端 baresip(1001)与 linphone(1000)经 FreeSWITCH 互拨:信令全部正常(注册、振铃、接听、挂断),但板 → linphone 方向没有声音(板端麦克风采到的声音发不出去)。
根因一句话:baresip 默认不做任何软件增益——它把音频设备按编解码器原生参数直接打开,声音"裸进裸出";而板载 PDM 数字麦克风原始电平天生偏小(灵敏度 -26 dBFS 级别,原理见上一篇博客)。
修复有两条路(任选其一):
| 方案一:ALSA softvol 软增益链 | 方案二:baresip 自带 augain | |
|---|---|---|
| 增益位置 | ALSA 层(设备外挂一层) | baresip 内部(上行链路) |
| 生效范围 | 所有走该设备的声音(通话 + 铃声) | 仅通话上行(麦克风 → 编码) |
| 依赖 | /etc/asound.conf + amixer | baresip 编入 augain 模块;config 两行 |
| 调整方式 | amixer 百分比 | 配置倍数 / 运行时 /augain 命令 |
最终结果:双向有声。
1. 第一点记录:默认情况下 baresip 没有使用软增益
- baresip 的音频设备由 config 里三行决定:
audio_player/audio_source/audio_alert。设备串(如plughw:0,0)会原样传给 ALSA 的snd_pcm_open,音频路径上没有任何增益环节。 - 默认直连时:麦克风采到的原始电平不经放大直接编码发出 → 对端听不到/听不清。
- 判断方法:用软增益链直接测
arecord -D micboost ...+aplay -D boost ...音量正常 → 硬件链路没问题,缺的只是软件增益 → 要么让 baresip 走增益链(方案一),要么在 baresip 内部补增益(方案二)。
/root/.baresip/config 相关三行(默认直连状态):
audio_player alsa,plughw:0,0
audio_source alsa,plughw:0,0
audio_alert alsa,plughw:0,0
2. 方案一:使用 /etc/asound.conf 软增益链条(softvol)
把三行改成走软增益设备(boost = 播放侧、micboost = 采集侧,定义见上一篇博客):
# 改后:baresip 走 /etc/asound.conf 的软增益链
audio_player alsa,boost
audio_source alsa,micboost
audio_alert alsa,boost
要点与坑:
micboost/boost是 asound.conf 里自定义的 PCM 名,slave 指向实际声卡(采集 = 卡 1 PDM 麦、播放 = 卡 0 喇叭,见前篇)。- raw hw 会踩 -22 坑:softvol 只转发参数、不做采样率/通道转换。baresip 按编解码器原生参数打开设备(PCMU = 8000Hz/1ch),而 raw hw(PDM 麦最低 2 声道)直接拒绝 1ch:
snd_pcm_hw_params_set_channels报 EINVAL → 日志alsa: cannot set channel count to 1→init failed: err=-22→could not reset player→ 通话session closed: -22。
修法:slave 从hw:X,Y改成plughw:X,Y(或外面包一层 plug 做格式转换)。
复现命令:arecord -D micboost -f S16_LE -r 8000 -c 1 -d 3 /tmp/t8k.wav(改前必报错)。 - 音量控制与持久化:
amixer -c 1 sset 'BoostCapture' 90%、amixer -c 0 sset 'BoostPlayback' 60%;重启后 softvol 控件需要"先空跑一次、再设置"(见前篇 §6,可写进启动脚本)。 - 排错:
baresip -v启动日志可核对实际打开的设备;也可以运行时/ausrc alsa,micboost、/auplay alsa,boost切换(对后续通话生效,不用重启)。
3. 方案二:baresip 自带 augain(引擎内软增益)
augain 是 baresip 官方模块,本质是一个"上行音频滤波器"(aufilt):在"麦克风采集 → 编码"之间把每个采样乘一个增益系数。它自带每帧防削波限幅(实际增益 = min(设定倍数, 32767 / 本帧最大采样绝对值)),所以怎么调都不会数字爆音;只作用上行(对扬声器无效)。
3.1 在 /root/.baresip/config 里怎么加
两处:
# 模块段:加载 augain 模块(与其它 module 行并列)
module augain.so
# 顶层配置键:增益倍数(1.5 ≈ +3.5dB;2.0 = +6dB;3.0 ≈ +9.5dB)
augain 2.0
启动日志确认(两行):
aufilt: augain ← 模块注册成功
augain: gaining by at most 2.00 ← 配置已读到("at most" = 防削波限幅)
运行时调整(通话中即时生效):
/augain 3.0 → 日志输出:augain: new gain is 3.00
注意:
- augain 只支持 S16LE 格式(baresip 默认就是,无需改)。
- 前提:二进制里编入了 augain 模块(旧 7 模块版没有;重编的 26 模块版已含)。
- 用 augain 后麦克风增益由 baresip 内部负责,
audio_source可直接写设备名(如alsa,plughw:1,0),不再依赖 asound.conf 的增益链;扬声器/铃声方向的音量仍归 ALSA 侧管。
4. 顺带修复:启用 Opus
baresip 默认生成的 config 里 module opus.so 是被注释的 → 启动只加载 PCMU/PCMA(日志 "Populated 2 audio codecs")→ 只能窄带通话。
改法(/root/.baresip/config 模块段):取消注释,且放在 g711 之前(模块顺序 = 编解码器优先级):
module opus.so
module g711.so
验证:
- 启动日志从 "Populated 2 audio codecs" 变为 "Populated 3 audio codecs";
- 通话协商使用 Opus(宽带,音质明显提升)。
5. baresip arm64 重编命令存档
5.1 环境
- 构建机:VMware Ubuntu 22.04(用户 hunter),工作区
~/rk3588/baresip-arm64/ - 工具链:RK3588 SDK 自带 prebuilt aarch64 工具链 gcc-arm-10.3(自带 glibc 2.33;板端 glibc 2.41 前向兼容,可直接运行)
- 依赖:静态 OpenSSL 3.5.9 + opus 1.5.2 + alsa-lib 1.2.11(仅链接用)+ libre 4.12.0(已内置 rem,无需单独编 rem)
- 网络:大陆环境,GitHub 下载走 gh-proxy 镜像;源码目录结构
src/(re、baresip)、deps-src/(opus、openssl、alsa-lib)、deps/(安装前缀)
5.2 env.sh(每次构建前 source)
export TC=$HOME/rk3588/rk3588_6.1_2025-02-26/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu
export DEPS=$HOME/rk3588/baresip-arm64/deps
export PATH=$TC/bin:$PATH
export PKG_CONFIG_LIBDIR=$DEPS/lib/pkgconfig
export T=$HOME/rk3588/baresip-arm64/aarch64-toolchain.cmake
5.3 工具链文件 aarch64-toolchain.cmake(要点)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER "$ENV{TC}/bin/aarch64-none-linux-gnu-gcc")
set(CMAKE_CXX_COMPILER "$ENV{TC}/bin/aarch64-none-linux-gnu-g++")
set(CMAKE_SYSROOT "$ENV{TC}/aarch64-none-linux-gnu/libc")
set(CMAKE_FIND_ROOT_PATH "$ENV{DEPS}" "$ENV{TC}/aarch64-none-linux-gnu/libc")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_PREFIX_PATH "$ENV{DEPS}")
set(CMAKE_INSTALL_LIBDIR lib)
5.4 依赖(首次已构建完;只改模块/配置时无需重编)
# OpenSSL 3.5.9 静态(dtls_srtp 用;re 的 HMAC 依赖它)
cd deps-src/openssl-3.5.9
./Configure linux-aarch64 --cross-compile-prefix=aarch64-none-linux-gnu- \
--prefix=$DEPS --openssldir=$DEPS/ssl --libdir=lib no-shared no-tests no-docs
make -j16 && make install_sw
# opus 1.5.2
cd deps-src/opus-1.5.2 && mkdir -p build-aarch64 && cd build-aarch64
cmake .. -DCMAKE_TOOLCHAIN_FILE=$T -DCMAKE_INSTALL_PREFIX=$DEPS \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_LIBDIR=lib
make -j16 && make install
# libre v4.12.0
cd src/re-4.12.0 && rm -rf build && mkdir build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=$T -DCMAKE_INSTALL_PREFIX=$DEPS -DCMAKE_BUILD_TYPE=Release \
-DLIBRE_BUILD_SHARED=OFF -DOPENSSL_ROOT_DIR=$DEPS -DOPENSSL_USE_STATIC_LIBS=ON -DUSE_OPENSSL=ON
make -j16 && make install
(alsa-lib 1.2.11 同法交叉编译到 $DEPS,仅链接用;板端运行时用 rootfs 自带的 libasound.so.2。)
5.5 重编 baresip(全模块 26 个,单文件静态产物)
source ~/rk3588/baresip-arm64/env.sh
cd ~/rk3588/baresip-arm64/src/baresip-4.12.0
rm -rf build && mkdir build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=$T -DCMAKE_INSTALL_PREFIX=$DEPS -DCMAKE_BUILD_TYPE=Release \
-DSTATIC=ON \
-DOPENSSL_ROOT_DIR=$DEPS -DOPENSSL_USE_STATIC_LIBS=ON -DUSE_OPENSSL=ON \
-DRE_INCLUDE_DIR=$DEPS/include/re -DRE_LIBRARY=$DEPS/lib/libre.a \
-DMODULES="stdio;alsa;g711;opus;l16;auconv;auresamp;vumeter;augain;in_band_dtmf;aubridge;aufile;ausine;uuid;stun;turn;ice;srtp;dtls_srtp;ctrl_tcp;account;contact;debug_cmd;menu;netroam;syslog"
make -j16 && make install
日常只改模块名单时(复用已有 build 目录,其余 flag 已在 CMakeCache 里缓存,不必重复;约 1 分钟):
cd ~/rk3588/baresip-arm64/src/baresip-4.12.0
cmake -B build -S . -DMODULES="<上面的模块名单>"
cmake --build build -j16
说明:
-DSTATIC=ON:所有模块编进单个二进制(板端不需要任何 .so 文件)。MODULES是 CMake 缓存变量,改它即改模块集合;写进去但依赖缺失的模块(如 g722 需 spandsp)构建时自动跳过,不报错。- 产物:
$DEPS/bin/baresip,本次交付版本 7866752B、sha2569bded6260528e8ea4d6bd4eb7250dfd5fd9f346986ea2d5323eeb4f3d67e3928;运行时零新增依赖。 - 校验与部署:
file $DEPS/bin/baresip # ELF 64-bit ARM aarch64
readelf -d $DEPS/bin/baresip | grep NEEDED # 仅 resolv/m/dl/pthread/asound/c/ld
# 部署上板(Windows 侧拉取后推板)
scp C:\VMShare\baresip root@192.168.86.130:/root/baresip
6. 常见坑速查
| 现象 | 原因 | 解决 |
|---|---|---|
| 板 → 对端无声 | baresip 默认无软增益,麦克风原始电平低 | 方案一 boost/micboost,或方案二 augain |
session closed: -22 / cannot set channel count to 1 |
softvol slave 是 raw hw,拒绝编解码器原生 1ch | slave 改 plughw(或包 plug) |
| 只有 2 个 codec、音质窄带 | module opus.so 被注释 |
启用 opus(放 g711 之前) |
| augain 不生效 | 二进制未编入 augain / 样本格式非 S16 | 用 26 模块版;查启动日志 aufilt: augain |
| 铃声没变响 | augain 只管上行 | 铃声走 ALSA 侧(boost) |
| 改动 config 后行为没变 | 改了但没重启 baresip | 退出重开(q)再看启动日志 |
7. 板端/etc/asound.conf设置
需要区分的两件事
| 东西 | 定义位置 | 重启后丢吗 |
|---|---|---|
| boost / micboost 设备名 | 板端 /etc/asound.conf | 不丢(不重刷固件就一直在) |
| BoostPlayback / BoostCapture 控件和数值 | softvol 第一次打开设备时动态创建 | 会丢,这就是要自动化的部分 |
改动位置二(一劳永逸):buildroot 固件 overlay
你的 SDK 里 buildroot/board/rockchip/rk3588/fs-overlay/ 就是"烧进固件"的目录——你的 kb_keys、S91wifi、S20kb_keys 都在这里,构建时由 buildroot/configs/rockchip/chips/rk3588.config:3 的 BR2_ROOTFS_OVERLAY+="board/rockchip/rk3588/fs-overlay/" 自动合并进根文件系统。
fs-overlay/etc/asound.conf —— 设备定义(boost/micboost)
pcm.boost {
type softvol
slave.pcm "plughw:0,0"
control { name "BoostPlayback"; card 0 }
min_dB -20.0
max_dB 30.0
resolution 100
}
pcm.micboost {
type softvol
slave.pcm "plughw:1,0"
control { name "BoostCapture"; card 1 }
min_dB -20.0
max_dB 30.0
resolution 100
}
8. 板端 /etc/init.d/S99audio
fs-overlay/etc/init.d/S99audio —— 开机自动设增益
# ---- softvol 软件增益:开机恢复 BoostPlayback / BoostCapture ----
arecord -D micboost -f S16_LE -r 16000 -c 2 -d 1 /dev/null 2>/dev/null
aplay -D boost -t raw -f S16_LE -r 8000 -c 2 -d 1 /dev/zero 2>/dev/null
amixer -c 1 sset 'BoostCapture' 100% >/dev/null 2>&1
amixer -c 0 sset 'BoostPlayback' 60% >/dev/null 2>&1
前两行是"空跑"——因为 Boost 控件是 softvol 插件第一次打开设备时才出生的,重启后必须先触发创建、再设值。代价是开机多约 2 秒。
9. baresip config配置
#
# baresip configuration
#
#------------------------------------------------------------------------------
# SIP
#sip_listen 0.0.0.0:5060
#sip_certificate cert.pem
sip_cafile /etc/ssl/certs/ca-certificates.crt
sip_capath /etc/ssl/certs
#sip_transports udp,tcp,tls,ws,wss
#sip_trans_def udp
#sip_verify_server yes
#sip_verify_client no
#sip_tls_resumption all
sip_tos 160
#filter_registrar udp,tcp,tls,ws,wss
#sip_cuser_random no
# Call
call_local_timeout 120
call_max_calls 4
call_hold_other_calls yes
call_accept no
# Audio
#audio_path /home/hunter/rk3588/baresip-arm64/deps/share/baresip
audio_player alsa,boost
audio_source alsa,plughw:1,0
audio_alert alsa,boost
#ausrc_srate 48000
#auplay_srate 48000
#ausrc_channels 0
#auplay_channels 0
audio_level no
ausrc_format s16 # s16, float, ..
auplay_format s16 # s16, float, ..
auenc_format s16 # s16, float, ..
audec_format s16 # s16, float, ..
audio_buffer 20-160 # ms
audio_telev_pt 101 # payload type for telephone-event
# Video
#video_source v4l2,/dev/video0
#video_display x11,nil
video_size 640x480
video_bitrate 1000000
video_fps 30.00
video_fullscreen no
videnc_format yuv420p
# AVT - Audio/Video Transport
rtp_tos 184
rtp_video_tos 136
#rtp_ports 10000-20000
#rtp_bandwidth 512-1024 # [kbit/s]
audio_jitter_buffer_type fixed # off, fixed, adaptive
audio_jitter_buffer_ms 100-200 # Min. - Max. [ms]
audio_jitter_buffer_size 50 # [packets]
video_jitter_buffer_type fixed # off, fixed, adaptive
video_jitter_buffer_ms 100-200 # Min. - Max. [ms]
video_jitter_buffer_size 250 # [packets]
rtp_stats no
#rtp_timeout 60
#avt_bundle no
#rtp_rxmode main
# Network
#dns_server 1.1.1.1:53
#dns_server 1.0.0.1:53
#dns_fallback 8.8.8.8:53
#dns_getaddrinfo no
#net_interface wlan0
# Play tones
#file_ausrc aufile
#file_srate 16000
#file_channels 1
#------------------------------------------------------------------------------
# Modules
#module_path /home/hunter/rk3588/baresip-arm64/deps/lib/baresip/modules
# MIC Modules
module augain.so
augain 1.5
# UI Modules
module stdio.so
#module cons.so
#module evdev.so
#module httpd.so
# Audio codec Modules (in order)
module opus.so
#module amr.so
#module g7221.so
#module libg722.so
#module g722.so
module g711.so
#module l16.so
#module codec2.so
# Audio filter Modules (in encoding order)
module auconv.so
module auresamp.so
#module vumeter.so
#module sndfile.so
#module plc.so
#module webrtc_aec.so
# Audio driver Modules
module alsa.so
#module pulse.so
#module pipewire.so
#module jack.so
#module portaudio.so
#module aubridge.so
#module aufile.so
#module ausine.so
# Video codec Modules (in order)
#module avcodec.so
#module vp8.so
#module vp9.so
# Video filter Modules (in encoding order)
#module selfview.so
#module snapshot.so
#module swscale.so
#module vidinfo.so
#module avfilter.so
# Video source modules
#module v4l2.so
#module vidbridge.so
# Video display modules
#module x11.so
#module sdl.so
#module fakevideo.so
# Audio/Video source modules
#module avformat.so
#module gst.so
# Compatibility modules
#module ebuacip.so
module uuid.so
# Media NAT modules
module stun.so
module turn.so
module ice.so
#module natpmp.so
#module pcp.so
# Media encryption modules
#module srtp.so
#module dtls_srtp.so
#module gzrtp.so
#------------------------------------------------------------------------------
# Application Modules
module_app account.so
module_app contact.so
module_app debug_cmd.so
#module_app echo.so
#module_app gtk.so
module_app menu.so
#module_app mwi.so
#module_app presence.so
#module_app serreg.so
#module_app syslog.so
#module_app mqtt.so
#module_app ctrl_tcp.so
#module_app ctrl_dbus.so
#module_app httpreq.so
module_app netroam.so
#------------------------------------------------------------------------------
# Module parameters
# DTLS SRTP parameters
#dtls_srtp_use_ec prime256v1
# UI Modules parameters
cons_listen 0.0.0.0:5555 # cons - Console UI UDP/TCP sockets
http_listen 0.0.0.0:8000 # httpd - HTTP Server
ctrl_tcp_listen 0.0.0.0:4444 # ctrl_tcp - TCP interface JSON
evdev_device /dev/input/event0
# Opus codec parameters
opus_bitrate 28000 # 6000-510000
#opus_stereo yes
#opus_sprop_stereo yes
#opus_cbr no
#opus_inbandfec no
#opus_dtx no
#opus_mirror no
#opus_complexity 10
#opus_application audio # {voip,audio}
#opus_samplerate 48000
#opus_packet_loss 10 # 0-100 percent (expected packet loss)
# Opus Multistream codec parameters
#opus_ms_channels 2 #total channels (2 or 4)
#opus_ms_streams 2 #number of streams
#opus_ms_c_streams 2 #number of coupled streams
vumeter_stderr yes
#jack_connect_ports yes
# Selfview
video_selfview window # {window,pip}
#selfview_size 64x64
# Menu
#redial_attempts 0 # Num or <inf>
#redial_delay 5 # Delay in seconds
#ringback_disabled no
#statmode_default off
#menu_clean_number no
#sip_autoanswer_method rfc5373 # {rfc5373,call-info,alert-info}
#ring_aufile ring.wav
#hangup_aufile none
#callwaiting_aufile callwaiting.wav
#ringback_aufile ringback.wav
#notfound_aufile notfound.wav
#busy_aufile busy.wav
#error_aufile error.wav
#sip_autoanswer_aufile autoanswer.wav
#menu_max_earlyaudio 32
#menu_max_earlyvideo_rx 32
#menu_max_earlyvideo_tx 32
#menu_message_tone yes
# GTK
#gtk_clean_number no
#gtk_use_status_icon yes
gtk_use_window yes
# avcodec
#avcodec_h264enc libx264
#avcodec_h264dec h264
#avcodec_h265enc libx265
#avcodec_h265dec hevc
#avcodec_hwaccel vaapi
#avcodec_profile_level_id 42002a
#avcodec_keyint 10
# vp8
#vp8_enc_threads 1
#vp8_enc_cpuused 16 # range -16..16, greater 0 increases speed over quality
# ctrl_dbus
#ctrl_dbus_use system # system, session
# mqtt
#mqtt_broker_host sollentuna.example.com
#mqtt_broker_port 1883
#mqtt_broker_cafile /path/to/broker-ca.crt # set this to enforce TLS
#mqtt_broker_clientid baresip01 # has to be unique
#mqtt_broker_user user
#mqtt_broker_password pass
#mqtt_basetopic baresip/01
# sndfile
#snd_path /tmp
# EBU ACIP
#ebuacip_jb_type fixed # auto,fixed
# HTTP request module
#httpreq_ca trusted1.pem
#httpreq_ca trusted2.pem
#httpreq_dns 1.1.1.1
#httpreq_dns 8.8.8.8
#httpreq_hostname myserver
#httpreq_cert cert.pem
#httpreq_key key.pem
# avformat
#avformat_hwaccel vaapi
#avformat_inputformat mjpeg
#avformat_decoder mjpeg
#avformat_pass_through yes
#avformat_rtsp_transport udp
# ice
#ice_policy all # all, relay (candidates)
把baresip 和.baresip可执行文件固化到fs-overlay里
hunter@ubuntu22:~/rk3588/rk3588_6.1_2025-02-26/buildroot/board/rockchip/rk3588/fs-overlay/root$ ls -la
total 7696
drwxrwxr-x 3 hunter hunter 4096 Oct 9 22:45 .
drwxrwxr-x 5 hunter hunter 4096 Oct 9 22:37 ..
drwx------ 2 hunter hunter 4096 Oct 9 22:02 .baresip
-rwxr-xr-x 1 hunter hunter 7866752 Oct 9 22:45 baresip
10. 总结
- baresip 默认"裸开设备、无软增益"——板载麦电平低的板子必须补增益,否则上行无声/听不清。
- 两条路:
/etc/asound.confsoftvol(全局、含铃声)或 baresip augain(引擎内、仅上行;config 加两行module augain.so+augain 2.0,可运行时/augain调)。 - softvol 链必须解决格式转换(
plughw/plug),否则 baresip 按编解码器原生参数(8k/1ch)打开时直接踩 -22。 - Opus 默认被注释——启用并放在 g711 之前。
- 26 模块静态重编命令已存档(§5);只改模块名单无需从零重编。
浙公网安备 33010602011771号