一口君后面會(huì)陸續(xù)更新基于瑞芯微rk3568的I2S系列文章。預(yù)計(jì)10篇左右。
《瑞芯微 | I2S-音頻基礎(chǔ) -1》
基于Linux嵌入式設(shè)備常用調(diào)試方法很多,本文一口君把調(diào)試語音用到的工具和方法給大家做一個(gè)簡單的介紹。
1. ?procfs、sysfs
Linux系統(tǒng)上的/proc目錄是一種文件系統(tǒng),即proc文件系統(tǒng)。與其它常見的文件系統(tǒng)不同的是,/proc是一種偽文件系統(tǒng)(也即虛擬文件系統(tǒng)),存儲(chǔ)的是當(dāng)前內(nèi)核運(yùn)行狀態(tài)的一系列特殊文件,用戶可以通過這些文件查看有關(guān)系統(tǒng)硬件及當(dāng)前正在運(yùn)行進(jìn)程的信息,甚至可以通過更改其中某些文件來改變內(nèi)核的運(yùn)行狀態(tài)。
基于/proc文件系統(tǒng)如上所述的特殊性,其內(nèi)的文件也常被稱作虛擬文件,并具有一些獨(dú)特的特點(diǎn)。例如,其中有些文件雖然使用查看命令查看時(shí)會(huì)返回大量信息,但文件本身的大小卻會(huì)顯示為0字節(jié)。此外,這些特殊文件中大多數(shù)文件的時(shí)間及日期屬性通常為當(dāng)前系統(tǒng)時(shí)間和日期,這跟它們隨時(shí)會(huì)被刷新(存儲(chǔ)于RAM中)有關(guān)。
ALSA有自己的proc tree,在/proc/asound這個(gè)目錄下可以找到許多關(guān)于snd card 的詳細(xì)信息。
- /proc/asound
rk3568_r:/?#?ls?/proc/asound?-l
total?0
dr-xr-xr-x?5?root?root?0?2024-02-19?22:27?card0
dr-xr-xr-x?4?root?root?0?2024-02-19?22:27?card1
-r--r--r--?1?root?root?0?2024-02-19?22:27?cards
-r--r--r--?1?root?root?0?2024-02-19?22:27?devices
-r--r--r--?1?root?root?0?2024-02-19?22:27?hwdep
-r--r--r--?1?root?root?0?2024-02-19?22:27?pcm
lrwxrwxrwx?1?root?root?5?2024-02-19?22:27?rockchiphdmi?->?card1
lrwxrwxrwx?1?root?root?5?2024-02-19?22:27?rockchiprk809co?->?card0
-r--r--r--?1?root?root?0?2024-02-19?22:27?timers
-r--r--r--?1?root?root?0?2024-02-19?22:27?version
其中主要的節(jié)點(diǎn)如下:
- cardx:表示注冊的sound card;cards:顯示當(dāng)前配置的Alsa Drivers,index,the id string,short and long descriptions;version:顯示版本字符串;devices:列舉本機(jī)設(shè)備映射;pcm:列舉當(dāng)前可用的 pcm devides,格式如下:-::: ;
- /proc/asound/cards
通過 proc fs 確認(rèn)聲卡注冊成功
#?cat?/proc/asound/cards
0?[rockchiprk809co]:?rockchip_rk809-?-?rockchip,rk809-codec
rockchip,rk809-codec
7?[Loopback?]:?Loopback?-?Loopback
Loopback?1
- /proc/asound/devices
查看聲卡下的功能設(shè)備
rk3568_r:/?#??cat?/proc/asound/devices
??2:?[?0-?0]:?digital?audio?playback
??3:?[?0-?0]:?digital?audio?capture
??4:?[?0]???:?control
??5:?[?1-?0]:?digital?audio?playback
??6:?[?1]???:?control
?33:????????:?timer
對于devices的print格式如下:
- Control設(shè)備:?“minor:?[card_id]?: control”;
- PCM設(shè)備????:?“minor:?[card_id- device_id]: digital audio playback/capture”;
- timer設(shè)備??:?“minor:?: timer”;
- /proc/asound/pcm
查看聲卡采集、播放PCM信息
rk3568_r:/?#?cat?/proc/asound/pcm
cat?/proc/asound/pcm
00-00:?fe410000.i2s-rk817-hifi?rk817-hifi-0?:?fe410000.i2s-rk817-hifi?rk817-hifi-0?:?playback?1?:?capture?1
01-00:?rockchip,hdmi?i2s-hifi-0?:?rockchip,hdmi?i2s-hifi-0?:?playback?1
- /proc/asound/version
查看ALSA驅(qū)動(dòng)版本
rk3568_r:/?#?cat?/proc/asound/version
cat?/proc/asound/version
Advanced?Linux?Sound?Architecture?Driver?Version?k4.19.232.
- /proc/asound/card0/pcm0p/sub0/status
查看聲卡0的信息
rk3568_r:/?#?cat?/proc/asound/card0/pcm0p/sub0/status
cat?/proc/asound/card0/pcm0p/sub0/status
closed
rk3568_r:/sys/devices/platform/rk809-sound?#?ls
driver??driver_override??fe410000.i2s-rk817-hifi??modalias??of_node??power??sound??subsystem??uevent
kernel/Documentation/devicetree/bindings/sound/rockchip-i2s.txt??rockchip,i2s-tdm.txt
alsa_sound_init函數(shù)中會(huì)調(diào)用snd_info_init函數(shù)創(chuàng)建 /proc/asound目錄,并將該entry保存在全局變量 snd_proc_root(即作為 sound proc root entry),代碼如下
int?__init?snd_info_init(void)
{
????//1、創(chuàng)建?alsa?proc?root?entry;
????snd_proc_root?=?snd_info_create_entry("asound",?NULL);????
????if?(!snd_proc_root)
????????return?-ENOMEM;
????snd_proc_root->mode?=?S_IFDIR?|?0555;
????//2、創(chuàng)建?dir:?/proc/asound
????snd_proc_root->p?=?proc_mkdir("asound",?NULL);????
????if?(!snd_proc_root->p)
????????goto?error;
#ifdef?CONFIG_SND_OSSEMUL
????snd_oss_root?=?create_subdir(THIS_MODULE,?"oss");
????if?(!snd_oss_root)
????????goto?error;
#endif
#if?IS_ENABLED(CONFIG_SND_SEQUENCER)
????snd_seq_root?=?create_subdir(THIS_MODULE,?"seq");
????if?(!snd_seq_root)
????????goto?error;
#endif
????if?(snd_info_version_init()?<?0?||????//3、創(chuàng)建?file:?/proc/asound/version
????????snd_minor_info_init()?<?0?||????//4、創(chuàng)建?file:?/proc/asound/devices
????????snd_minor_info_oss_init()?<?0?||
????????snd_card_info_init()?<?0?||????????//5、創(chuàng)建?file:?/proc/asound/cards
????????snd_info_minor_register()?<?0)
????????goto?error;
????return?0;
?error:
????snd_info_free_entry(snd_proc_root);
????return?-ENOMEM;
}
查看時(shí)鐘clk summary
查詢音頻時(shí)鐘,確認(rèn)時(shí)鐘設(shè)置正確
示例:查詢 i2s0 mclk 頻率,以及其所在的 pll,結(jié)果:mclk 為 12288000 Hz,pll 源為 cpll
cat?/sys/kernel/debug/clk/clk_summary?|?egrep?"i2s0|pll"
pll_cpll?1?1?0?500000000
cpll?5?10?0?500000000
mclk_i2s0_rx_div?0?0?0?500000000
mclk_i2s0_rx_fracdiv?0?0?0?12288000
mclk_i2s0_rx_mux?0?0?0?12288000
mclk_i2s0_rx?0?0?0?12288000
mclk_i2s0_tx_div?1?1?0?500000000
mclk_i2s0_tx_fracdiv?1?1?0?12288000
mclk_i2s0_tx_mux?1?1?0?12288000
mclk_i2s0_tx?1?1?0?12288000
mclk_i2s0_tx_out2io?2?2?0?12288000
2. ?寄存器
io命令
通過 io 命令 查看修改寄存器(適合 SOC 寄存器查詢),配合芯片手冊確認(rèn)配置以及工作狀態(tài)。
#?cat?/proc/iomem?|?grep?i2s
ff800000-ff800fff?:?i2s@ff800000
#?#
io?-4?-l?0x40?0xff800000
ff800000:?7200000f?004e000f?10003f3f?00000010
ff800010:?000f0110?01f00000?00000000?00000003
ff800020:?00000000?00000000?00000000?0000001f
ff800030:?00003eff?00003eff?00000303?20150001
regmap
通過 regmap 節(jié)點(diǎn)查看寄存器(只讀)。
rk3568_r:/?#?cat?/sys/kernel/debug/regmap/0-0020-rk817-codec/name
cat?/sys/kernel/debug/regmap/0-0020-rk817-codec/name????????????????????????????
rk808
##?rk3568?i2s0控制器寄存器
rk3568_r:?#?cat?/sys/kernel/debug/regmap/fe400000.i2s/registers
cat?/sys/kernel/debug/regmap/fe400000.i2s/registers??????????????????????????????????????????????????????????????????
00:?7200000f
04:?01c8000f
08:?00001f1f
0c:?XXXXXXXX
10:?000f0010
14:?01f00000
18:?XXXXXXXX
1c:?00000000
20:?XXXXXXXX
24:?XXXXXXXX
2c:?XXXXXXXX
30:?00003eff
34:?00003eff
38:?00000707
##?codec?es809寄存器
rk3568_r:/?#?cat?/sys/kernel/debug/regmap/0-0020-rk817-codec/registers
cat?/sys/kernel/debug/regmap/0-0020-rk817-codec/registers????
00:?00
01:?00
02:?00
03:?00
04:?00
05:?00
06:?00
07:?00
08:?00
09:?00
0a:?00
0b:?00
0c:?00
0d:?00
0e:?00
0f:?00
10:?00
11:?00
12:?03
13:?f4
14:?00
#?ls?/sys/kernel/debug/regmap/
0-0020-rk817-codec
ff800000.i2s
...
#?cat?/sys/kernel/debug/regmap/0-0020-rk817-codec/registers
12:?03
13:?f4
14:?00
15:?ff
16:?00
17:?40
18:?48
19:?00
1a:?00
1b:?ff
1c:?00
1d:?00
1e:?02
1f:?00
...
注意: regmap 基于 cache 機(jī)制,如果通過 io 命令直接修改寄存器后, regmap 節(jié)點(diǎn)不會(huì)體現(xiàn)更新后的寄存器,除非驅(qū)動(dòng)將寄存器類型設(shè)置為 volatile 或者將 regmap cache 關(guān)閉。
3. alsa-utils
瑞芯微的android版本的sdk中不支持aplay、arecord、amixer這組命令,下面是以復(fù)旦微廠家sdk舉例。
官方sdk的buildroot目錄下執(zhí)行make menuconfig:
??│?Symbol:?BR2_PACKAGE_ALSA_UTILS_APLAY?[=y]????????????│??
??│?Type??:?boolean??????????????????????????????????????│??
??│?Prompt:?aplay/arecord????????????????????????????????│??
??│???Location:??????????????????????????????????????????│??
??│?????->?Target?packages???????????????????????????????│??
??│???????->?Audio?and?video?applications????????????????│??
??│?(1)?????->?alsa-utils?(BR2_PACKAGE_ALSA_UTILS?[=y])??│??
??│???Defined?at?package/alsa-utils/Config.in:57?????????│??
??│???Depends?on:?BR2_PACKAGE_ALSA_UTILS?[=y]????????????│??
??│???Selects:?BR2_PACKAGE_ALSA_LIB_PCM?[=y]
aplay
Usage:?aplay?[OPTION]...?[FILE]...
-h,?--help??????????????help
????--version???????????print?current?version
-l,?--list-devices??????list?all?soundcards?and?digital?audio?devices
-L,?--list-pcms?????????list?device?names
-D,?--device=NAME???????select?PCM?by?name
-q,?--quiet?????????????quiet?mode
-t,?--file-type?TYPE????file?type?(voc,?wav,?raw?or?au)
-c,?--channels=#????????channels
-f,?--format=FORMAT?????sample?format?(case?insensitive)
-r,?--rate=#????????????sample?rate
-d,?--duration=#????????interrupt?after?#?seconds
-M,?--mmap??????????????mmap?stream
-N,?--nonblock??????????nonblocking?mode
-F,?--period-time=#?????distance?between?interrupts?is?#?microseconds
-B,?--buffer-time=#?????buffer?duration?is?#?microseconds
????--period-size=#?????distance?between?interrupts?is?#?frames
????--buffer-size=#?????buffer?duration?is?#?frames
-A,?--avail-min=#???????min?available?space?for?wakeup?is?#?microseconds
-R,?--start-delay=#?????delay?for?automatic?PCM?start?is?#?microseconds?
????????????????????????(relative?to?buffer?size?if?<=?0)
-T,?--stop-delay=#??????delay?for?automatic?PCM?stop?is?#?microseconds?from?xrun
-v,?--verbose???????????show?PCM?structure?and?setup?(accumulative)
-V,?--vumeter=TYPE??????enable?VU?meter?(TYPE:?mono?or?stereo)
-I,?--separate-channels?one?file?for?each?channel
-i,?--interactive???????allow?interactive?operation?from?stdin
-m,?--chmap=ch1,ch2,..??Give?the?channel?map?to?override?or?follow
????--disable-resample??disable?automatic?rate?resample
????--disable-channels??disable?automatic?channel?conversions
????--disable-format????disable?automatic?format?conversions
????--disable-softvol???disable?software?volume?control?(softvol)
????--test-position?????test?ring?buffer?position
????--test-coef=#???????test?coefficient?for?ring?buffer?position?(default?8)
????????????????????????expression?for?validation?is:?coef?*?(buffer_size?/?2)
????--test-nowait???????do?not?wait?for?ring?buffer?-?eats?whole?CPU
????--max-file-time=#???start?another?output?file?when?the?old?file?has?recorded
????????????????????????for?this?many?seconds
????--process-id-file???write?the?process?ID?here
????--use-strftime??????apply?the?strftime?facility?to?the?output?file?name
????--dump-hw-params????dump?hw_params?of?the?device
????--fatal-errors??????treat?all?errors?as?fatal
示例:通過聲卡0 ? 播放 ? 48k 采樣率 ? 2聲道 16 位的靜音數(shù)據(jù)
aplay?-D?hw:0,0?--period-size=1024?--buffer-size=4096?-r?48000?-c?2?-f?s16_le
/dev/zero
arecord
Usage:?arecord?[OPTION]...?[FILE]...
-h,?--help??????????????help
????--version???????????print?current?version
-l,?--list-devices??????list?all?soundcards?and?digital?audio?devices
-L,?--list-pcms?????????list?device?names
-D,?--device=NAME???????select?PCM?by?name
-q,?--quiet?????????????quiet?mode
-t,?--file-type?TYPE????file?type?(voc,?wav,?raw?or?au)
-c,?--channels=#????????channels
-f,?--format=FORMAT?????sample?format?(case?insensitive)
-r,?--rate=#????????????sample?rate
-d,?--duration=#????????interrupt?after?#?seconds
-M,?--mmap??????????????mmap?stream
-N,?--nonblock??????????nonblocking?mode
-F,?--period-time=#?????distance?between?interrupts?is?#?microseconds
-B,?--buffer-time=#?????buffer?duration?is?#?microseconds
????--period-size=#?????distance?between?interrupts?is?#?frames
????--buffer-size=#?????buffer?duration?is?#?frames
-A,?--avail-min=#???????min?available?space?for?wakeup?is?#?microseconds
-R,?--start-delay=#?????delay?for?automatic?PCM?start?is?#?microseconds?
????????????????????????(relative?to?buffer?size?if?<=?0)
-T,?--stop-delay=#??????delay?for?automatic?PCM?stop?is?#?microseconds?from?xrun
-v,?--verbose???????????show?PCM?structure?and?setup?(accumulative)
-V,?--vumeter=TYPE??????enable?VU?meter?(TYPE:?mono?or?stereo)
-I,?--separate-channels?one?file?for?each?channel
-i,?--interactive???????allow?interactive?operation?from?stdin
-m,?--chmap=ch1,ch2,..??Give?the?channel?map?to?override?or?follow
????--disable-resample??disable?automatic?rate?resample
????--disable-channels??disable?automatic?channel?conversions
????--disable-format????disable?automatic?format?conversions
????--disable-softvol???disable?software?volume?control?(softvol)
????--test-position?????test?ring?buffer?position
????--test-coef=#???????test?coefficient?for?ring?buffer?position?(default?8)
????????????????????????expression?for?validation?is:?coef?*?(buffer_size?/?2)
????--test-nowait???????do?not?wait?for?ring?buffer?-?eats?whole?CPU
????--max-file-time=#???start?another?output?file?when?the?old?file?has?recorded
????????????????????????for?this?many?seconds
????--process-id-file???write?the?process?ID?here
????--use-strftime??????apply?the?strftime?facility?to?the?output?file?name
????--dump-hw-params????dump?hw_params?of?the?device
????--fatal-errors??????treat?all?errors?as?fatal
示例:通過聲卡0 錄制 16k 采樣率 8聲道 32 位 的音頻數(shù)據(jù)
arecord?-D?hw:0,0?--period-size=1024?--buffer-size=4096?-r?16000?-c?8?-f?s32_le
r.wav
aplay | arecord
兩者通過管道可以方便的實(shí)現(xiàn) loopback 功能,方便驅(qū)動(dòng)調(diào)試和指標(biāo)測試。示例:聲卡0 錄制 -> 聲卡1 播放
#?arecord?-D?hw:0,0?--period-size=1024?--buffer-size=4096?-r?48000?-c?2?-f?s16_le
-t?raw?|?aplay?-D?hw:1,0?--period-size=1024?--buffer-size=4096?-r?48000?-c?2?-f
s16_le?-t?raw
amixer
控制 codec 內(nèi)部的通路開關(guān),結(jié)合 codec 手冊的音頻拓?fù)鋱D(比如 圖 3-2 RK3308 codec)實(shí)現(xiàn)音頻流的
路由,音量控制等
Usage:?amixer?<options>?[command]
Available?options:
??-h,--help???????this?help
??-c,--card?N?????select?the?card
??-D,--device?N???select?the?device,?default?'default'
??-d,--debug??????debug?mode
??-n,--nocheck????do?not?perform?range?checking
??-v,--version????print?version?of?this?program
??-q,--quiet??????be?quiet
??-i,--inactive???show?also?inactive?controls
??-a,--abstract?L?select?abstraction?level?(none?or?basic)
??-s,--stdin??????Read?and?execute?commands?from?stdin?sequentially
??-R,--raw-volume?Use?the?raw?value?(default)
??-M,--mapped-volume?Use?the?mapped?volume
Available?commands:
??scontrols???????show?all?mixer?simple?controls
??scontents???show?contents?of?all?mixer?simple?controls?(default?command)
??sset?sID?P??????set?contents?for?one?mixer?simple?control
??sget?sID????????get?contents?for?one?mixer?simple?control
??controls????????show?all?controls?for?given?card
??contents????????show?contents?of?all?controls?for?given?card
??cset?cID?P??????set?control?contents?for?one?control
??cget?cID????????get?control?contents?for?one?control
示例:查詢聲卡 controls,將播放通路切換到 SPK
#?amixer?-c?0?contents
numid=1,iface=MIXER,name='Playback?Path'
;?type=ENUMERATED,access=rw------,values=1,items=11
;?Item?#0?'OFF'
;?Item?#1?'RCV'
;?Item?#2?'SPK'
;?Item?#3?'HP'
;?Item?#4?'HP_NO_MIC'
;?Item?#5?'BT'
;?Item?#6?'SPK_HP'
;?Item?#7?'RING_SPK'
;?Item?#8?'RING_HP'
;?Item?#9?'RING_HP_NO_MIC'
;?Item?#10?'RING_SPK_HP'
:?values=0
...
#?#?amixer?-c?0?cset?numid=1?2
numid=1,iface=MIXER,name='Playback?Path'
;?type=ENUMERATED,access=rw------,values=1,items=11
;?Item?#0?'OFF'
;?Item?#1?'RCV'
;?Item?#2?'SPK'
;?Item?#3?'HP'
;?Item?#4?'HP_NO_MIC'
;?Item?#5?'BT'
;?Item?#6?'SPK_HP'
;?Item?#7?'RING_SPK'
;?Item?#8?'RING_HP'
;?Item?#9?'RING_HP_NO_MIC'
;?Item?#10?'RING_SPK_HP'
:?values=2
alsaloop
支持 任意聲卡間的路由
支持 自適應(yīng)時(shí)鐘同步
自持 自適應(yīng)重采樣
支持 mixer controls 重定向
Usage:?alsaloop?[OPTION]...
-h,--help??????help
-g,--config????configuration?file?(one?line?=?one?job?specified)
-d,--daemonize?daemonize?the?main?process?and?use?syslog?for?errors
-P,--pdevice???playback?device
-C,--cdevice???capture?device
-X,--pctl??????playback?ctl?device
-Y,--cctl??????capture?ctl?device
-l,--latency???requested?latency?in?frames
-t,--tlatency??requested?latency?in?usec?(1/1000000sec)
-f,--format????sample?format
-c,--channels??channels
-r,--rate??????rate
-n,--resample??resample?in?alsa-lib
-A,--samplerate?use?converter?(0=sincbest,1=sincmedium,2=sincfastest,
???????????????????????????????3=zerohold,4=linear)
-B,--buffer????buffer?size?in?frames
-E,--period????period?size?in?frames
-s,--seconds???duration?of?loop?in?seconds
-b,--nblock????non-block?mode?(very?early?process?wakeup)
-S,--sync??????sync?mode(0=none,1=simple,2=captshift,3=playshift,4=samplerate,
?????????????????????????5=auto)
-a,--slave?????stream?parameters?slave?mode?(0=auto,?1=on,?2=off)
-T,--thread????thread?number?(-1?=?create?unique)
-m,--mixer?redirect?mixer,?argument?is:
??????SRC_SLAVE_ID(PLAYBACK)[@DST_SLAVE_ID(CAPTURE)]
-O,--ossmixer?rescan?and?redirect?oss?mixer,?argument?is:
??????ALSA_ID@OSS_ID??(for?example:?"Master@VOLUME")
-e,--effect????apply?an?effect?(bandpass?filter?sweep)
-v,--verbose???verbose?mode?(more?-v?means?more?verbose)
-w,--workaround?use?workaround?(serialopen)
-U,--xrun??????xrun?profiling
-W,--wake??????process?wake?timeout?in?ms
-z,--syslog????use?syslog?for?errors
示例:聲卡0錄制的音頻通過聲卡1播放,同步模式采用 策略1(增加或減少采樣點(diǎn))
alsaloop?-C?hw:0,0?-P?hw:1,0?-t?10000?-A?3?-S?1?-b?-v
es8388播放和錄音舉例
/**************************************
?*?波形測試,?RAW數(shù)據(jù)
?**************************************/
aplay?-D?hw:0,0?-f?S24_LE?-r?44100?-c?2?-t?raw?/bin/busybox?&?arecord?-D?hw:0,1?-f?S24_LE?-r?44100?-c?2?-d?5??record.wav
抓包,?上傳record.wav到電腦,可以聽見雜波
aplay?-D?hw:0,0?-f?S24_LE?-r?44100?-c?2?-t?raw?test.pcm?&?arecord?-D?hw:0,1?-f?S24_LE?-r?44100?-c?2?-d?5??record.wav
抓包,?上傳record.wav到電腦,可以聽見瘋狂小鳥
aplay?-D?hw:0,0?-fS24_LE?-r?44100?-c?2?-t?raw?/all_0x00.bin?&
arecord?-r?44100?-f?S24_LE?-c?2?-d?30?-D?hw:0,1?record.wav
aplay?-D?hw:0,0?-fS24_LE?-r?44100?-c?2?-t?raw?/all_0xff.bin?&
arecord?-r?44100?-f?S24_LE?-c?2?-d?30?-D?hw:0,1?record.wav
aplay?/test.wav?&
arecord?-r?44100?-f?S24_LE?-c?2?-d?30?-D?hw:0,1?record.wav
抓包,?上傳record.wav,?聽見瘋狂小鳥
/**************************************
?*?設(shè)置
?**************************************/
#?查看功能
amixer?scontrols
#?耳機(jī)測試
amixer?sset?'Headphone?Playback?ZC'?on?#?打開耳機(jī)播放?ZC
amixer?sset?'Right?Output?Mixer?PCM'?on?#?打開右聲道
amixer?sset?'Left?Output?Mixer?PCM'?on?#?打開左聲道
amixer?sset?Headphone?105,105?#?設(shè)置耳機(jī)音量
amixer?sset?Playback?230,230?#?設(shè)置播放音量
#?播放
aplay?/opt/hardwareTest/wav/test.wav?#?<---------------------------------------------------
#?MIC測試
#設(shè)置聲卡輸入捕獲音量大小
amixer?sset?Capture?56,56
amixer?sset?'ADC?PCM'?200,200
#音頻輸入,關(guān)閉所有右聲道
amixer?sset?'Right?Input?Mixer?Boost'?off
amixer?sset?'Right?Boost?Mixer?RINPUT1'?off
amixer?sset?'Right?Input?Boost?Mixer?RINPUT1'?0
amixer?sset?'Right?Boost?Mixer?RINPUT2'?off
amixer?sset?'Right?Input?Boost?Mixer?RINPUT2'?0
amixer?sset?'Right?Boost?Mixer?RINPUT3'?off
amixer?sset?'Right?Input?Boost?Mixer?RINPUT3'?0
#音頻輸入,打開左聲道?1?和?2,關(guān)閉?3
amixer?sset?'Left?Input?Mixer?Boost'?on
amixer?sset?'Left?Boost?Mixer?LINPUT1'?on
amixer?sset?'Left?Input?Boost?Mixer?LINPUT1'?5
amixer?sset?'Left?Boost?Mixer?LINPUT2'?on
amixer?sset?'Left?Input?Boost?Mixer?LINPUT2'?3
amixer?sset?'Left?Boost?Mixer?LINPUT3'?off
amixer?sset?'Left?Input?Boost?Mixer?LINPUT3'?0
#?錄音
arecord?-r?44100?-f?S24_LE?-c?2?-d?10?-D?hw:0,1?record.wav?#?<---------------------------------------------------
#?Line?IN?測試
#設(shè)置聲卡輸入捕獲音量大小
amixer?sset?Capture?56,56
amixer?sset?'ADC?PCM'?200,200
#音頻輸入,打開左聲道?3,,關(guān)閉?1?和?2
amixer?sset?'Left?Input?Mixer?Boost'?on
amixer?sset?'Left?Boost?Mixer?LINPUT1'?off
amixer?sset?'Left?Input?Boost?Mixer?LINPUT1'?0
amixer?sset?'Left?Boost?Mixer?LINPUT2'?off
amixer?sset?'Left?Input?Boost?Mixer?LINPUT2'?0
amixer?sset?'Left?Boost?Mixer?LINPUT3'?on
amixer?sset?'Left?Input?Boost?Mixer?LINPUT3'?5
#音頻輸入,打開右聲道?2,關(guān)閉?1?和?3
amixer?sset?'Right?Input?Mixer?Boost'?on
amixer?sset?'Right?Boost?Mixer?RINPUT1'?off
amixer?sset?'Right?Input?Boost?Mixer?RINPUT1'?0
amixer?sset?'Right?Boost?Mixer?RINPUT2'?on
amixer?sset?'Right?Input?Boost?Mixer?RINPUT2'?5
amixer?sset?'Right?Boost?Mixer?RINPUT3'?off
amixer?sset?'Right?Input?Boost?Mixer?RINPUT3'?0
4. tiny-alsa
RK Android SDK 標(biāo)配 tiny-alsa 工具。
Linux ALSA 在內(nèi)核層提供了 alsa-driver
,在應(yīng)用層提供了 alsa-lib
,應(yīng)用程序只需要調(diào)用 alsa-lib 提供的 API 即可完成對底層硬件的操作。
但由于 ALSA 架構(gòu)太過于龐大,對于嵌入式設(shè)備而言很多功能用不到,且會(huì)增加功耗,所以 Android 采用了精簡后的 tinyalsa
。
Android 中使用 tinyalsa 控制管理所有模式的音頻通路,也可以使用 tinyalsa 提供的工具進(jìn)行查看、調(diào)試。
Tinyalsa 源碼位于 android 源碼目錄下 external/tinyalsa
,可以使用 mmm
命令編譯,
mmm?external/tinyalsa
編譯 tinyalsa 后會(huì)生成四個(gè)小工具:
- tinymixtinyplayinycapinypcminfo
1) tinypcminfo
tinypcminfo
用于查看 pcm 通道的相關(guān)信息,如 PCM 采樣率,Channels,采樣點(diǎn)數(shù)等信息。
Usage:?tinypcminfo?[-D?card]?[-d?device]
示例:
rk3568_r:/?#?tinypcminfo?-D?0
Info?for?card?0,?device?0:
PCM?out:
?????Access:???0x000009
??Format[0]:???0x000444
??Format[1]:???00000000
Format?Name:???S16_LE,?S24_LE,?S32_LE
??Subformat:???0x000001
???????Rate:???min=8000Hz??????max=96000Hz
???Channels:???min=2???????????max=8
Sample?bits:???min=16??????????max=32
Period?size:???min=8???????????max=65536
Period?count:???min=2???????????max=16384
PCM?in:
?????Access:???0x000009
??Format[0]:???0x000444
??Format[1]:???00000000
Format?Name:???S16_LE,?S24_LE,?S32_LE
??Subformat:???0x000001
???????Rate:???min=8000Hz??????max=96000Hz
???Channels:???min=2???????????max=8
Sample?bits:???min=16??????????max=32
Period?size:???min=8???????????max=65536
Period?count:???min=2???????????max=16384
2) tinyplay
tinyplay
是一個(gè)簡易的音樂播放器,一般用于播放測試??梢灾苯舆M(jìn)行播放 wav 格式文件,在播放前需要先使用 tinymix 進(jìn)行相關(guān)控件的設(shè)置。
Usage:?tinyplay?file.wav?[-D?card]?[-d?device]?[-p?period_size]?[-n?n_periods]
示例:播放src_test_xiaoniao.wav、1khz_44100_16bit.wav 音頻文件
rk3568_r:/sdcard?#?tinyplay?src_test_xiaoniao.wav
Playing?sample:?2?ch,?44100?hz,?16?bit?1764000?bytes
rk3568_r:/sdcard?#?tinyplay?1khz_44100_16bit.wav
Playing?sample:?2?ch,?44100?hz,?16?bit?15876000?bytes
3) tinycap
tinycap
是一個(gè)簡易的錄音軟件,一般用于錄音測試。
使用之前也需要先設(shè)置錄音相關(guān)的控件,設(shè)置好控件后,執(zhí)行 tinycap xxx.wav 即可將音頻錄制到 xxx.wav 中。
Usage:?tinycap?file.wav?[-D?card]?[-d?device]?[-c?channels]?[-r?rate]?[-b?bits]
[-p?period_size]?[-n?n_periods]
示例:44.1k 采樣率錄制音頻
#?tinycap?/sdcard/rec.wav?-D?0?-d?0?–c?2?–r?44100?–b?16?–p?1024?–n?3
rk3568_r:/sdcard?#?tinycap?/sdcard/rec.wav?-D?0
Capturing?sample:?2?ch,?44100?hz,?16?bit
4) tinymix
控制 codec 內(nèi)部的通路開關(guān), 音量控制等。效果等同于 amixer
1)tinymix
可以查看系統(tǒng)的音頻控件,可直接執(zhí)行 tinymix 進(jìn)行查看;2)tinymix 可以手動(dòng)設(shè)置控件的值,控件可通過 tinymix 查看,或者通過 mixer_paths.xml 查看。
usage:?tinymix?[-D?card]
rk3568_r:/sdcard?#?tinymix?--help
tinymix?[options]?[control?name/#]?[value?to?set]
????options:
????--device|-D?<card#>???-?use?the?given?card?#?instead?of?0.
????--all-values|-a???????-?show?all?possible?values/ranges?for?control.
????--tabs-only|-t????????-?separate?all?output?columns/values?with?tabs.
????--value-only|-v???????-?show?only?the?value?for?the?selected?control.
示例:
rk3568_r:/sdcard?#?tinymix
Mixer?name:?'rockchip,rk809-codec'
Number?of?controls:?2
ctl?????type????num?????name?????????????????????????????????????value
0???????ENUM????1???????Playback?Path????????????????????????????OFF
1???????ENUM????1???????Capture?MIC?Path?????????????????????????MIC?OFF
rk3568_r:/sdcard?#?tinymix?-a
Mixer?name:?'rockchip,rk809-codec'
Number?of?controls:?2
ctl?????type????num?????name???????????????????value
????????range/values
0???????ENUM????1???????Playback?Path??????????>OFF?RCV?SPK?HP?HP_NO_MIC?BT?SPK_HP?RING_SPK?RING_HP?RING_HP_NO_MIC?RING_SPK_HP
1???????ENUM????1???????Capture?MIC?Path???????>MIC?OFF?Main?Mic?Hands?Free?Mic?BT?Sco?Mic
5. i2c工具鏈
i2c工具主要用于配置codec,本文使用的是es8388,配置該芯片可以通過i2c接口。
通過 i2c tool 查看修改 codec 寄存器(適合 i2c 類型的 codec 設(shè)備),配合 codec 手冊確認(rèn)配置以及工作
狀態(tài)。
rk3568sdk集成i2c工具鏈,做了精簡,與其他版本工具鏈?zhǔn)褂寐杂胁顒e。
安裝命令
apt-get?update
apt-get?install?i2c-tools
linux版本代碼下載路徑:
https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/
i2cdetect
rk3568_r:/?#?i2cdetect?--help
usage:?i2cdetect?[-ary]?BUS?[FIRST?LAST]
usage:?i2cdetect?-F?BUS
usage:?i2cdetect?-l
Detect?i2c?devices.
-a??????All?addresses?(0x00-0x7f?rather?than?0x03-0x77)
-F??????Show?functionality
-l??????List?all?buses
-r??????Probe?with?SMBus?Read?Byte
-y??????Answer?"yes"?to?confirmation?prompts?(for?script?use)
查詢 i2c0 總線上的設(shè)備
rk3568_r:/?#?i2cdetect?-y?0
?????0??1??2??3??4??5??6??7??8??9??a??b??c??d??e??f
00:??????????--?--?--?--?--?--?--?--?--?--?--?--?--
10:?--?--?--?--?--?--?--?--?--?--?--?--?UU?--?--?--
20:?UU?--?--?--?--?--?--?--?--?--?--?--?--?--?--?--
30:?--?--?--?--?--?--?--?--?--?--?--?--?--?--?--?--
40:?--?--?--?--?--?--?--?--?--?--?--?--?--?--?--?--
50:?--?--?--?--?--?--?--?--?--?--?--?--?--?--?--?--
60:?--?--?--?--?--?--?--?--?--?--?--?--?--?--?--?--
70:?--?--?--?--?--?--?--?--
i2cdump
dump 設(shè)備的所有寄存器
rk3568_r:/?#?i2cdump?--help
usage:?i2cdump?[-fy]?BUS?CHIP
Dump?i2c?registers.
-f??????Force?access?to?busy?devices
-y??????Answer?"yes"?to?confirmation?prompts?(for?script?use)
示例:查詢 i2c0 總線下 rk817(設(shè)備地址:0x20)的寄存器,其中 0x12 ~ 0x4f 為 codec 寄存器。
rk3568_r:/?#?i2cdump?-f?-y?0?0x20
?????0??1??2??3??4??5??6??7??8??9??a??b??c??d??e??f????0123456789abcdef
00:?02?00?09?04?08?17?05?00?00?00?01?01?00?01?80?00?????.?????...??.??.
10:?00?00?03?f4?00?00?00?06?c8?00?00?00?00?00?00?00????..??...??.......
20:?00?00?00?ff?ff?00?00?70?00?66?00?00?00?00?00?0f????...??..p.f.....?
30:?06?03?03?00?a5?02?00?00?01?ff?ff?00?00?e0?0f?09???????.??..???..???
40:?69?7f?0c?58?2d?0c?95?01?00?00?00?0f?20?00?0f?00????i??X-???...??.?.
50:?8c?00?01?00?01?b0?44?10?00?60?00?00?00?00?00?00?????.?.??D?.`......
60:?00?00?00?00?00?00?00?00?00?00?00?00?01?00?eb?00????............?.?.
70:?00?00?00?00?ff?ff?ff?ff?00?01?ff?ff?00?00?00?00????....????.???....
80:?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00????................
90:?60?80?e9?7f?cb?df?a6?80?e9?00?00?00?00?00?00?00????`????????.......
a0:?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00????................
b0:?00?0f?0f?0f?0f?04?a4?ff?ff?00?64?1c?20?64?1a?20????.????????.d??d?
c0:?64?00?00?64?1a?20?6b?ff?ff?ff?ff?ff?0c?0c?0c?0c????d..d??k?????????
d0:?0c?0c?6c?6c?6c?6c?6c?6c?30?30?30?30?30?30?09?31??????llllll000000?1
e0:?00?00?00?55?a2?c8?c5?40?00?ff?22?03?0a?80?94?0e????...U???@.?"?????
f0:?c2?ac?a0?40?18?40?00?86?00?fc?00?ff?00?ff?60?00???????@?@.?.?.?.?`.
i2cget
查詢單個(gè)寄存器值
Usage:?i2cget?[-f]?[-y]?I2CBUS?CHIP-ADDRESS?[DATA-ADDRESS?[MODE]]
I2CBUS?is?an?integer?or?an?I2C?bus?name
ADDRESS?is?an?integer?(0x03?-?0x77)
MODE?is?one?of:
b?(read?byte?data,?default)
w?(read?word?data)
c?(write?byte/read?byte)
Append?p?for?SMBus?PEC
rk3568_r:/?#?i2cget?--help
usage:?i2cget?[-fy]?BUS?CHIP?ADDR
Read?an?i2c?register.
-f??????Force?access?to?busy?devices
-y??????Answer?"yes"?to?confirmation?prompts?(for?script?use)
示例:查詢 rk817 的 0x12 寄存器
rk3568_r:/?#?i2cget?-f?-y?0?0x20?0x12
0x03
i2cset
修改單個(gè)寄存器值
Usage:?i2cset?[-f]?[-y]?[-m?MASK]?[-r]?I2CBUS?CHIP-ADDRESS?DATA-ADDRESS?[VALUE]
...?[MODE]
I2CBUS?is?an?integer?or?an?I2C?bus?name
ADDRESS?is?an?integer?(0x03?-?0x77)
MODE?is?one?of:
c?(byte,?no?value)
b?(byte?data,?default)
w?(word?data)
i?(I2C?block?data)
s?(SMBus?block?data)
Append?p?for?SMBus?PEC
rk3568_r:/?#?i2cset?--help
usage:?i2cset?[-fy]?BUS?CHIP?ADDR?VALUE...?MODE
Write?an?i2c?register.?MODE?is?b?for?byte,?w?for?16-bit?word,?i?for?I2C?block.
-f??????Force?access?to?busy?devices
-y??????Answer?"yes"?to?confirmation?prompts?(for?script?use)
示例:修改 rk817(0x20) 的 0x12 寄存器,將值改為0
?rk3568_r:/?#?i2cset?-fy?0?0x20?0x12?0?b
?rk3568_r:/?#?i2cget?-f?-y?0?0x20?0x12
?0x00
i2ctransfer
i2c-tools-4.0及以后版本添加了i2ctransfer命令。
i2cget和i2cset可以讀寫的i2c設(shè)備的寄存器地址小于0xff,即寄存器是8位地址。
如果i2c設(shè)備寄存器是16位地址,可使用i2ctransfer命令,該命令同樣可用在寄存器地址是8位的設(shè)備。
1、命令
"Usage:?i2ctransfer?[-f]?[-y]?[-v]?[-V]?[-a]?I2CBUS?DESC?[DATA]?[DESC?[DATA]]...n"
"??I2CBUS?is?an?integer?or?an?I2C?bus?namen"
"??DESC?describes?the?transfer?in?the?form:?{r|w}LENGTH[@address]n"
"????1)?read/write-flag?2)?LENGTH?(range?0-65535,?or?'?')n"
"????3)?I2C?address?(use?last?one?if?omitted)n"
"??DATA?are?LENGTH?bytes?for?a?write?message.?They?can?be?shortened?by?a?suffix:n"
"????=?(keep?value?constant?until?LENGTH)n"
"????+?(increase?value?by?1?until?LENGTH)n"
"????-?(decrease?value?by?1?until?LENGTH)n"
"????p?(use?pseudo?random?generator?until?LENGTH?with?value?as?seed)nn"
"Example?(bus?0,?read?8?byte?at?offset?0x64?from?EEPROM?at?0x50):n"
"??#?i2ctransfer?0?w1@0x50?0x64?r8n"
"Example?(same?EEPROM,?at?offset?0x42?write?0xff?0xfe?...?0xf0):n"
"??#?i2ctransfer?0?w17@0x50?0x42?0xff-n");
2、用法
##?從i2c 4號總線0x38設(shè)備的0x3a01寄存器開始讀16個(gè)字節(jié)的數(shù)據(jù),w2:表示寄存器0x3a01的長度為2個(gè)字節(jié)
i2ctransfer?-y?-f?4?w2@0x38?0x3a?0x01?r16
##?向i2c 4號總線0x38設(shè)備的0x3a01寄存器寫0x10,w3:表示寄存器0x3a01和寫入值0x10的長度為3字節(jié)
i2ctransfer?-y?-f?4?w3@0x38?0x3a?0x01?0x10
邏輯分析儀
調(diào)試過程中,有時(shí)候我們需要抓取控制器和codec之間語音信號,并轉(zhuǎn)換成語音數(shù)據(jù),
一口君使用的是Kingst的 LA系列邏輯分析儀。
這是一款非常簡單容易上手的設(shè)備,
即使新手也很容易就能上手,
比示波器好用很多。后面會(huì)單獨(dú)開一篇講解該設(shè)備如何抓取波形并轉(zhuǎn)換成語音數(shù)據(jù)。
抓取波形頁面