当前位置:首页>Linux>嵌入式Linux音频开发必备技能:一文带你精通 asound.conf

嵌入式Linux音频开发必备技能:一文带你精通 asound.conf

  • 2026-08-19 09:17:50
嵌入式Linux音频开发必备技能:一文带你精通 asound.conf

多个 rockit 进程同时播放,第二个直接报 Device or resource busy

TDM 8 通道声卡,想把 4 路麦 + 2 路回采参考 + 喇叭拆开用,不知道怎么配?

asound.conf 改完没生效,也不知道哪里错了?

做 Rockchip 音频开发,这些问题大概率都遇到过。本文用一篇的篇幅,把 asound.conf 从插件原理、TDM 分轨、采样率转换到上板部署全部讲透——全部来自真实工程,可直接抄作业。

上篇《RockChip Linux SDK ALSA 配置实战》讲了 UCM2(PulseAudio/PipeWire 用的设备切换),这篇讲 asound.conf(alsa-lib 的 PCM 插件链),两者是不同层面。


一、asound.conf 到底在干什么?

先看 ALSA 的三层结构:

┌─────────────────────────────────────────┐│  应用层(aplay / rockit / 你的进程)      │├─────────────────────────────────────────┤│  alsa-lib(libasound.so)  ← asound.conf ││  解析 PCM 名 → 构造插件链                │├─────────────────────────────────────────┤│  内核驱动(snd-soc-rockchip-xxx)→ 硬件   │└─────────────────────────────────────────┘

关键点:asound.conf 不改变硬件能力,只决定"应用看到的 PCM 如何被组装"。

当应用 open("default") 时,alsa-lib 读配置文件,把 default 这个名字解析成一条插件链,最终落到内核的 hw:X,Y 上:

应用  ⇄  plug(格式转换)  ⇄  softvol(音量)  ⇄  dmix(混音)  ⇄  hw:0,0(内核)

每一层插件对上层是一个虚拟 PCM,对下层用一个 slave PCM。你写的所有配置,本质就是在拼这条链。

配置文件放在哪?

/usr/share/alsa/alsa.conf   ← alsa-lib 全局默认(别动)   └─ /etc/asound.conf      ← 系统级,板端生产环境就维护这个        └─ ~/.asoundrc      ← 用户级,开发调试临时用

板端只管 /etc/asound.conf


二、十个必懂的插件

ALSA 有十几个插件,但 Rockchip 音频工程里反复出现的就是这十个。记住它们,90% 的配置都能搞定。

2.1 hw —— 直接怼硬件

最底层的插件,直接打开内核 PCM,不做任何转换。应用给的格式必须和硬件一致,否则报错。

pcm.hw_primary {    type hw    card rockchiprk809co}

生产环境很少直接用 hw,一般套一层 plug 做格式兼容。

2.2 plug —— 自动格式转换

最常用的入口插件。应用给任意格式(S16/S24/任意采样率/任意声道),plug 自动协商转成 slave 能接受的格式。

pcm.speaker {    type plug    slave.pcm "playback_dshare"}

上层应用只需要 open("speaker"),不用关心底下硬件要什么格式。

2.3 dmix —— 多路混音播放(解决"第二个进程报 busy")

这是客户最常需要的能力。

没有 dmix 时,硬件 PCM 被第一个应用独占,第二个应用 open 直接失败:

终端1: aplay test.wav      ← 成功,独占硬件终端2: aplay test2.wav     ← 失败:Device or resource busy

dmix 通过共享内存 + 定时器,把多个客户端的 PCM 数据相加混音后一次性写给硬件:

对讲(rockit 线程)   ─┐提示音(rockit 线程) ─┤报警音(rockit 线程) ─┼─→ "default" ─→ softvol ─→ dmix(混音) ─→ hw:0,0背景音乐(rockit 线程)┘

所有客户端都 open 同一个 default,dmix 在底层把声音叠到一起。配置如下:

pcm.dmixer {    type dmix    ipc_key 5978290          # 共享内存标识,必须全系统唯一    ipc_key_add_uid true    slowptr 0    slave {        pcm "hw:0,0"        channels 2        rate 48000        period_size 768        buffer_size 3072    }    bindings { 01 }}

验证混音是否生效:直接用两个 aplay 同时播放,两路声音能叠加听到就说明通了,之后再接 rockit 进程。

关于 rockit:Rockchip IPC(网络摄像机)SDK 的多媒体框架,每路音频流(对讲、提示音、报警音)通常由独立的 rockit 线程处理。这些线程都 open 同一个 default,靠 dmix 自动混音。

2.4 dsnoop —— 多路共享录音

dmix 的录音对偶。多个应用同时录音,alsa-lib 在软件层做分发。参数和 dmix 完全一致,只是数据方向反过来:

pcm.dsnooper {    type dsnoop    ipc_key 5978291          # 和 dmix 用不同的 key    ipc_key_add_uid yes    slave {        pcm "hw:0,0"        channels 2        rate 48000    }    bindings { 01 }}

2.5 dshare —— TDM 分轨(本文重头戏)

dshare 是 dmix 的"分轨"版本。不做混音,而是按 bindings 把不同客户端分配到硬件的不同通道。

pcm.playback_dshare {    type dshare    ipc_key 5678293    slowptr 0    slave {        pcm "hw:0,0"        channels 2        rate 48000    }    bindings.0               # 客户端 ch0 → 硬件 ch0    bindings.1               # 客户端 ch1 → 硬件 ch1}

这个最小示例和 dsnoop 长得很像,区别在于 dshare 是播放侧分轨,dsnoop 是录音侧分轨。通道数多了以后(TDM8/16),bindings 的分轨能力才真正发挥出来——第三章实战详解。

2.6 route —— 通道重定向/混音

用 ttable(传输矩阵)把输入通道按增益系数混合/重定向到输出通道。常用于"立体声混到单声道""左右声道各开独立音量"等。

# 把两路输入混成单声道后送到输出 ch1(右声道)pcm.play_chn1 {    type route    slave {        pcm "dmixer"        channels 2    }    ttable {0.1 0.5     # 输入0 → 输出1,增益 0.51.1 0.5     # 输入1 → 输出1,增益 0.5    }}

ttable 格式是 <输入>.<输出> <增益>,增益范围 0.0~1.0。route 是唯一能改增益的通道操作插件,分通道独立音量就靠它 + softvol 组合实现。

2.7 multi —— 多设备通道组合/重排

把一个或多个 slave PCM 的通道按任意顺序组合/重排成一个新的虚拟 PCM。核心能力是重排和合并,不改增益、不做混音。

最常见的用法:麦阵通道重排。 硬件 TDM 的物理通道顺序和 3A 算法期望的顺序不一致时,用 multi 重排:

pcm.cap_multi {    type multi    slaves.a.pcm "hw:0,0"    slaves.a.channels 4    bindings.0.slave a            # 客户端 ch0 → slave a 的 ch0    bindings.0.channel 0    bindings.1.slave a            # 客户端 ch1 → slave a 的 ch2(重排!)    bindings.1.channel 2    bindings.2.slave a            # 客户端 ch2 → slave a 的 ch1(重排!)    bindings.2.channel 1}

注意 multi 的 bindings 格式和 dshare/dsnoop 完全不同:每个客户端通道要同时指定 .slave(取自哪个 slave)和 .channel(取自该 slave 的哪个通道)。

multi 还能跨设备合并——把两个独立立体声 PCM 合并成一个 4 通道虚拟 PCM,这是 dshare/route 都做不到的独有能力。

2.8 softvol —— 软件音量

在 PCM 链上插入软件音量控制,并在 ctl 层创建一个 named 音量控件(出现在 amixer / alsamixer 里)。硬件没有合适音量控件时靠它。

pcm.softvol_ply {    type softvol    slave.pcm "hooks_ply"    control {        name "MasterP Volume"        card 0    }    min_dB -40.0    max_dB 0.0    resolution 101              # 100 档 + 静音,配合 0~100 百分比较友好}

关于 max_dB

  • 播放路径:推荐 0.0,避免软件放大导致削波
  • 录音路径:SoC 的 PDM 模块没有硬件增益(PGA)时,数字麦信号偏小,需要 max_dB 设正值(如 20.0)做软件增益补偿

2.9 hooks —— 打开时设置 codec 控件

PCM 被打开时,自动设置一组 mixer 控件到指定值。用于切换 codec 路径(扬声器/耳机切换、麦克风选择)。

pcm.hooks_ply {    type hooks    slave.pcm "dmixer"    hooks.0 {        type ctl_elems        hook_args [{            name "Playback Path"            preserve true           # 关闭后恢复原值,避免路径残留            value "SPK"            lock false        }]    }}

关键点

  • value "SPK" 是 codec 的枚举控件值,需查具体 codec 的 mixer 定义(常见值:SPK/HP/SPK_HP/Main Mic
  • preserve true:PCM 关闭后恢复原值
  • hooks 必须在链路中间,不能被 softvol 绕过(见第七章坑 3)

2.10 asym —— 打包播放和录音

让 default 这个名字同时支持播放和录音,各走各的链路

pcm.!default {    type asym    playback.pcm "plug_ply"# aplay -D default 走这条(softvol → hooks → dmix → 喇叭)    capture.pcm "plug_cap"# arecord -D default 走这条(softvol → hooks → dsnoop → 麦克风)}

不用 asym 的话,!default 只能定义成一个方向的 PCM——定义成 dmix 则 arecord -D default 失败,定义成 dsnoop 则 aplay -D default 失败。应用就得自己区分播放用哪个名字、录音用哪个名字。

套了 asym 后,上层应用无脑用 default,alsa-lib 自动按方向选链路。生产配置几乎都这么写。


通道操作插件怎么选?

dmix/dshare/route/multi 都涉及通道操作,最容易搞混。一张表理清:

插件
做什么
改增益?
多 slave?
典型场景
dmix
多路相加到同一组通道
多应用混音播放
dshare
多路各走各的通道
TDM 分轨,各走各通道
route
通道按增益矩阵混合/重定向
(0.0~1.0)
立体声混单声道、分通道音量
multi
多 slave 通道任意顺序组合
麦阵重排、跨设备合并

简单说:混音用 dmix,分轨用 dshare,要改增益用 route,要重排或跨设备合并用 multi。


三、怎么把 TDM 通道拆开用?dshare/dsnoop 分轨实战

这是 Rockchip 音频工程里最有技术含量的部分。TDM 多通道硬件,怎么把通道拆给不同用途?有三个典型场景,按复杂度递进。

场景 1:录音侧分轨(4 通道拆 mic + linein)

硬件是 4 通道,前两声道接麦阵,后两声道接 linein,要拆给不同应用录音。

用 dsnoop(录音侧的分轨用 dsnoop,不是 dshare——dshare 是播放侧的):

pcm_slave.ins {    pcm "hw:0,0"    channels 4    rate 16000    format S16_LE    period_size 320    buffer_size 1280}# mic 用前两声道pcm.pcmin1_dsnoop {    type dsnoop    ipc_key 5978291          # 同一物理设备的多个 dsnoop 共用 key    slowptr 0    slave ins    bindings.0             # 客户端 ch0 → 硬件 ch0    bindings.1             # 客户端 ch1 → 硬件 ch1}# linein 用后两声道pcm.pcmin2_dsnoop {    type dsnoop    ipc_key 5978291          # 同一物理设备,共用同一 key    slowptr 0    slave ins    bindings.2             # 客户端 ch0 → 硬件 ch2    bindings.3             # 客户端 ch1 → 硬件 ch3}pcm.micin  { type plug; slave.pcm "pcmin1_dsnoop" }pcm.linein { type plug; slave.pcm "pcmin2_dsnoop" }

关键点:两个 dsnoop 共用同一个 ipc_key 和 pcm_slave.ins,物理设备只开一次,靠 bindings 把不同通道分给不同虚拟 PCM。

场景 2:TDM8 播放 + 录音共用,各占不同通道

这是最经典的 IPC 场景:TDM8 录音放音共用,播放只要 2ch 喇叭,录音要 4MIC + 2REF(AEC 回采参考)。

TDM8 (8通道)├── 播放(TX)方向:dshare 占 ch0/1(喇叭),其余留空└── 录音(RX)方向:dsnoop 占 ch0~5(4MIC + 2REF)

播放用 dshare,录音用 dsnoop,两者共用同一个 pcm_slave(定义总通道数 8):

pcm_slave.tdm8 {    pcm "hw:0,0"    channels 8               # TDM8 共 8 通道    rate 48000    format S16_LE    period_size 960    buffer_size 3840}# 播放(TX)只占 ch0/1(喇叭)pcm.playback_dshare {    type dshare    ipc_key 5678293# dshare 用 5678293    slowptr 0    slave tdm8    bindings.0    bindings.1}# 录音(RX)占 4MIC + 2REF,共 6 通道pcm.capture_dsnoop {    type dsnoop    ipc_key 5678294# dsnoop 用不同 key(不同共享实例)    slowptr 0    slave tdm8               # 共用同一 slave,物理设备只开一次    bindings.0             # MIC0    bindings.1             # MIC1    bindings.2             # MIC2    bindings.3             # MIC3    bindings.4             # REF0(AEC 参考,回采播放左声道)    bindings.5             # REF1(AEC 参考,回采播放右声道)}pcm.speaker { type plug; slave.pcm "playback_dshare" }pcm.mic_ref { type plug; slave.pcm "capture_dsnoop" }

几个关键点

  • 播放(TX)和录音(RX)是 TDM 的两个独立方向,各 8 通道,互不干扰
  • REF 是 AEC(回声消除)的参考信号,通常回采播放的左右声道,供 3A 算法做回声抵消。这一路必须有,否则算法没法工作
  • dshare 和 dsnoop 用不同的 ipc_key(5678293 vs 5678294),因为它们是不同的共享实例

场景 3:TDM8 拆 4 个独立立体声输出

8 通道 = 4 个立体声对,每路播完全不同的内容。这是 dshare 的看家本领:

4 路独立立体声,分别走 ch0/1、ch2/3、ch4/5、ch6/7pcm.play1 { type dshare; ipc_key 5678293; slowptr 0; slave tdm8; bindings.0; bindings.1 }pcm.play2 { type dshare; ipc_key 5678293; slowptr 0; slave tdm8; bindings.2; bindings.3 }pcm.play3 { type dshare; ipc_key 5678293; slowptr 0; slave tdm8; bindings.4; bindings.5 }pcm.play4 { type dshare; ipc_key 5678293; slowptr 0; slave tdm8; bindings.6; bindings.7 }

应用 A open play1、应用 B open play2……各走各的通道对,输出完全不同的声音。这是 dmix 做不到的——dmix 会把所有输入混在一起。

这里 4 个 dshare 共用同一个 ipc_key,因为它们共享同一个物理设备的同一块缓冲,靠 bindings 区分各自通道。

为什么 dshare/dsnoop 最轻、dmix/route 最重?

这是个容易被忽略的性能问题。看每个 sample 的实际操作:

插件
每个 sample 做什么
拷贝
CPU
dshare / dsnoop
MMAP 直接访问 DMA buffer,channel stride 选通道
零拷贝
最低
multi
memcpy 通道拷贝/重排
1 次
route
memcpy + ttable 增益矩阵乘法
1 次 + 乘法
dmix
memcpy + 多客户端 sample 相加 + 削波
1 次 + 加法

真实案例:16 通道声卡从 route+dmix 改成 dshare 分轨后,CPU 占用从 97% 降到 1~3%

常见错误:在 dmix 上叠 route 来分轨——先把每路扩成 6/8 通道,再全部 mix 回去,白白做了乘法和加法。正确做法是直接用 dshare 分轨,零拷贝跳过所有算术。


四、TDM 分轨选型速查

需求
用什么
为什么
多应用录同一组通道
dsnoop
录音共享分发
多应用播同一组通道(混音)
dmix
播放叠加
同一 TDM 上播放/录音各占不同通道
dshare + dsnoop
各自 bindings 独占
多路独立播放,各走不同通道
dshare
分轨不混音
麦阵通道顺序重排
multi / dsnoop
bindings 重排

五、采样率转换的隐藏坑

应用给的采样率(如 44.1kHz 音乐)和硬件支持的(如 48kHz)不一致时,必须转换。这部分最容易踩坑。

plug 自动协商三个维度

plug 在应用和 slave 之间协商:format(S16/S24/...)、channelsrate。只要有一个不一致,就插入转换。

采样率转换用哪个算法?由配置文件最顶部的这行决定:

defaults.pcm.rate_converter "speexrate"

Rockchip 工程普遍设为 speexrate

转换器对比

转换器
质量
CPU
来源
linear
极低
alsa-lib 内置(默认 fallback)
speexrate
alsa-plugins
speexrate_best
alsa-plugins
samplerate_best
更高
很高
alsa-plugins(libsamplerate)

隐藏坑:speexrate 静默降级

这是最阴的坑:alsa-lib 本身只内置 linear 转换器,speexrate / samplerate 来自独立的 alsa-plugins 包。如果系统没装 alsa-plugins,你写的 defaults.pcm.rate_converter "speexrate"会静默 fallback 到 linear,不报错

表现是采样率转换质量明显下降(高频失真),但日志里看不到任何提示。

怎么确认?

ls /usr/lib/alsa-lib/ | grep -E "speex|samplerate"

没输出就是没装。buildroot 工程确认 defconfig 里有:

BR2_PACKAGE_ALSA_PLUGINS=y

六、从 Android HAL codec_config 生成 asound.conf

如果你同时在维护 Android 和 Linux 工程,会发现:Android 用 C 头文件描述 codec 路径,Linux 用 asound.conf 的 hooks 描述。两者本质相同——都是"在打开 PCM 时设置一组 mixer 控件"。

Android HAL 的路由表长这样(codec_config/config.h):

struct config_control {const char *ctl_name;       // mixer 控件名const char *str_val;        // 枚举控件的字符串值const int int_val[2];       // int 控件的左/右值};struct config_route {const int sound_card;       // 声卡号const int devices;          // 设备位图const struct config_control *controls;const unsigned controls_count;};

从它生成 asound.conf 的 5 步法

  1. 统计所有 route 的 (sound_card, devices) 组合 → 决定几张卡。蓝牙等外设走独立声卡
  2. 每个 route 收集 controls → 一个 hooks PCM。route 名直接做 PCM 名后缀(如 speaker_normal → hooks_speaker
  3. 区分 int_val 与 str_val → int 用数字,str 用字符串
  4. 按播放/录音分组 → 播放 hooks 接 dmix,录音 hooks 接 dsnoop
  5. 用 asym 组装 !default → 指向最常用的播放/录音 PCM

举个真实例子。rk730_config.h 里主麦克风的路径:

// HAL 描述main_mic_capture:  ADCSel Mux = 1(left)  MIC2 Boost Volume = 3

翻译成 asound.conf:

pcm.hooks_main_mic {    type hooks    slave.pcm "dsnooper"    hooks.0 {        type ctl_elems        hook_args [            { name "ADCSel Mux"; preserve true; value 1; lock false }            { name "MIC2 Boost Volume"; preserve true; value 3; lock false }        ]    }}

对照规则

Android HAL
asound.conf
.ctl_name + .int_val = {N}{name "...", value N}
.ctl_name + .str_val = "X"{name "...", value "X"}
(枚举)
.ctl_name + .int_val = {L, R}{name "...", value.0 L, value.1 R}

蓝牙 route 特殊处理:蓝牙走独立声卡(card btsco),不通过主卡的 mixer 控件。翻译时单独定义 pcm.hw_bt { type hw; card btsco },不和主路径混用 dmix。


七、上板踩坑录

写完配置不等于能用。以下是 Rockchip 平台上出现频率最高的五个坑,每一个都附排查方法。

坑 1:dmix/dsnoop/dshare 打不开,报 timer 错误(新板 bringup 第一拦路虎)

现象

ALSA lib pcm_direct.c:(snd_pcm_direct_initialize_poll_fd) unable to open timer 'hw:CLASS=3,SCLASS=0,CARD=0,DEV=0,SUBDEV=1'arecord: audio open error: No such file or directory

根因:dmix/dsnoop/dshare 需要 ALSA timer 做多进程同步。报错里的 CLASS=3 是 PCM timer。检查 /dev/snd/ 发现没有 timer 设备——kernel 没开 CONFIG_SND_PCM_TIMER

部分嵌入式 SDK 为了省 ~20KB 内存关掉了这个选项。

解决:kernel defconfig 开启:

CONFIG_SND_PCM_TIMER=y        # 直接修复项,补回 PCM timerCONFIG_SND_HRTIMER=y          # 推荐后备,全局精确时钟CONFIG_HIGH_RES_TIMERS=y      # SND_HRTIMER 的依赖

验证

ls /dev/snd/timer             # 应出现该设备节点arecord -D plug:main_mic -d 2 test.wav   # 不再报 timer 错误

坑 2:两个 dshare 跨设备共用 ipc_key,第二路哑掉

现象:主卡 dshare 正常,蓝牙那路 dshare 打不开或行为异常。

根因:ipc_key 相同 → 两个 dshare attach 到同一块共享内存,按第一个 opener 的硬件参数协作。跨物理设备(主卡 vs btsco)共用 key,第二个会用到错误的 DMA buffer 参数。

记住:dshare "多实例可共用同一 key"的前提是同一物理设备。跨卡必须用不同 key。

排查

ipcs -m                       # 查看所有共享内存段ipcs -m | grep 0x56           # 按 ipc_key 的十六进制过滤

解决:每个物理设备的 dshare/dsnoop 用独立 ipc_key。推荐取值:dmix 从 5978290 起、dsnoop 从 5978291 起、dshare 从 5678293 起,同类型递增分配。

坑 3:hooks 不生效,codec 路径没切换

现象:PCM 能播放,但 Playback Path 控件没被设置,声音从错误的通道出来。

最常见原因:softvol 绕过了 hooks。错误写法:

pcm.softvol_ply {    slave.pcm "dmixer"        # ← 错!跳过了 hooks_ply}

正确链路应该是 softvol → hooks → dmix,hooks 夹在中间。softvol 直接接 dmix,hooks_ply 永远不会被打开,Playback Path 控件不会被设置。

pcm.softvol_ply {    slave.pcm "hooks_ply"     # ← 对,经过 hooks 再到 dmix}

其他原因ctl_name 拼错(codec 没这个控件);枚举控件 value 写成了数字(必须用字符串)。

坑 4:softvol 创建的音量控件在 amixer 里看不到

现象amixer -c 0 contents 里找不到 softvol 定义的那个 Master Volume 控件。

根因:softvol 在 PCM 首次被打开时才注册 ctl。改完配置后没人打开过 PCM,控件就不存在。

解决

alsa restore                  # 或手动触发一次 openaplay -d 1 /dev/zero          # 触发 PCM openamixer -c 0 contents          # 再查,控件出现了

坑 5:bindings 写错,播放只有一边响

看到 bindings.0 0 / bindings.1 0(两路绑同通道)要区分两种场景:

  • BT SCO 声道复制(正确用法):蓝牙传 2ch 但只有 1ch 有数据,把有效声道复制到左右两路做假立体声
  • 主输出误写成同通道(错误):普通立体声输出写成这样,ch1 静音,丢一个声道。立体声必须是 bindings.0 0 / bindings.1 1

八、部署与音量持久化

配置写完、踩坑填完,最后一步:让调好的音量重启不丢。

问题在哪

softvol 创建的音量控件、codec 的 mixer 设置(Playback PathMIC2 Boost Volume)都存在运行时内存里,重启恢复默认值,产线/用户调好的参数全丢。

alsactl 两级 state 文件策略

Rockchip 用两个 state 文件,兼顾"出厂默认"和"用户自定义":

文件
用途
优先级
/userdata/asound.state
用户/产线调好的实际音量
高(存在则用)
/etc/asound.state
出厂默认值(固件自带)
低(兜底)

/userdata 分区恢复出厂才清空,平时调的音量不丢;/etc 是只读 rootfs,存出厂默认。

S49alsa 开机自动恢复

开机时由 init 脚本 /etc/init.d/S49alsa 自动 restore:

#!/bin/shcase "$1in  start)if [ -f "/userdata/asound.state" ]; then      alsactl restore -f /userdata/asound.stateelse      alsactl restore -f /etc/asound.state    # 首次开机用出厂默认fi    ;;  stop)    alsactl store -f /userdata/asound.state    # 关机存盘    ;;esac

完整生命周期

烧录固件 → 首次开机(无 /userdata/asound.state)        → S49alsa 用 /etc/asound.state 出厂默认恢复        → 产线/用户调音        → 关机时 S49alsa stop 存到 /userdata/asound.state        → 之后每次开机都用 /userdata/asound.state 恢复

S49 是 init 脚本序号,ALSA restore 要在文件系统挂载后、音频服务启动前,放 S40~S50 区间合适。


小结

一篇文章讲完了 asound.conf 从写到部署的全流程,记住这几个核心:

  1. asound.conf 的本质是拼插件链,每一层对上是虚拟 PCM,对下是 slave PCM
  2. 四个通道操作插件记牢:混音用 dmix,分轨用 dshare,改增益用 route,重排/跨设备合并用 multi
  3. TDM 分轨:播放侧 dshare、录音侧 dsnoop,共用 pcm_slave 定义总通道数,靠 bindings 各占不同通道
  4. dshare/dsnoop 零拷贝最轻,别在 dmix 上叠 route 做分轨
  5. speexrate 静默降级是最阴的坑,没装 alsa-plugins 不报错但音质变差
  6. Android HAL 和 asound.conf 本质相同,都是打开 PCM 时设 mixer 控件
  7. 新板 bringup 第一坑是 kernel 没开 CONFIG_SND_PCM_TIMER,dmix/dsnoop 全罢工
  8. 跨物理设备的 dshare 不能共用 ipc_key,否则第二路哑掉
  9. 插件链顺序不能错:softvol → hooks → dmix,hooks 夹在中间才会触发。softvol 直接接 dmix 会绕过 hooks,导致 codec 路径(扬声器/耳机切换)不生效
  10. 音量持久化用 alsactl + S49alsa 开机脚本,两级 state 文件兼顾出厂默认和用户自定义

本文所有示例均来自 Rockchip 真实音频工程,配置经多平台验证可直接参考复用。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 14:35:50 HTTP/2.0 GET : https://f.mffb.com.cn/a/510048.html
  2. 运行时间 : 0.256846s [ 吞吐率:3.89req/s ] 内存消耗:4,572.41kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=3ec4e84c175aa753e46e23b2d064ced1
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001209s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001509s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.006456s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.005913s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001490s ]
  6. SELECT * FROM `set` [ RunTime:0.003830s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001452s ]
  8. SELECT * FROM `article` WHERE `id` = 510048 LIMIT 1 [ RunTime:0.014781s ]
  9. UPDATE `article` SET `lasttime` = 1787294150 WHERE `id` = 510048 [ RunTime:0.037119s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000640s ]
  11. SELECT * FROM `article` WHERE `id` < 510048 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001200s ]
  12. SELECT * FROM `article` WHERE `id` > 510048 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001052s ]
  13. SELECT * FROM `article` WHERE `id` < 510048 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001982s ]
  14. SELECT * FROM `article` WHERE `id` < 510048 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002034s ]
  15. SELECT * FROM `article` WHERE `id` < 510048 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001779s ]
0.260476s