Android中使用ALSA聲卡

Android中使用ALSA聲卡

首先,cd到Android源碼樹根目錄下:

cd /home/figo/android/Android-2.0

從Android主頁下載ALSA聲卡的相關源碼:

git clone git://android.git.kernel.org/platform/external/alsa-lib.git

git clone git://android.git.kernel.org/platform/external/alsa-utils.git

git clone git://android.git.kernel.org/platform/hardware/alsa_sound.git

這樣下載完之後的各個包將會自動放到合適的地方。

第二步,修改自己板子的BoardConfig.mk,使板子使用ALSA聲卡,如下:
#HAVE_HTC_AUDIO_DRIVER := true
#BOARD_USES_GENERIC_AUDIO := true
BOARD_USES_ALSA_AUDIO := true
BUILD_WITH_ALSA_UTILS := true

如果是使用我們提供的Android-2.0那麼這個BoardConfig.mk應該位於Android-2.0/build/target/board/generic

第三步,重新編譯Android

第四步,在製作出來的根文件系統中添加/system/etc/asound.conf腳本配置聲卡的工作參數,內容如下:
# #
# # Mixer devices
# #
ctl.AndroidPlayback {
type hw
card 0 # Can replace with drivers name from /proc/asound/cards
}
ctl.AndroidRecord {
type hw
card 0
}

# #
# # Playback devices
# #
pcm.AndroidPlayback {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Speaker {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Speaker_normal {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Speaker_ringtone {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Speaker_incall {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Earpiece {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Earpiece_normal {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Earpiece_ringtone {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Earpiece_incall {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Bluetooth {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Bluetooth_normal {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Bluetooth_ringtone {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Bluetooth_incall {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Headset {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Headset_normal {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Headset_ringtone {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Headset_incall {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Bluetooth-A2DP {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Bluetooth-A2DP_normal {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Bluetooth-A2DP_ringtone {
type hw
card 0
device 0
}

pcm.AndroidPlayback_Bluetooth-A2DP_incall {
type hw
card 0
device 0
}

pcm.AndroidRecord {
type hw
card 0
device 0
}

pcm.AndroidRecord_Microphone {
type hw
card 0
device 0
}

alsa 音頻路徑的問題: 
在sound/soc/codecs目錄中有很多音頻codec的codec驅動,我使用的是wm9713,AP是s3c6410;這裏個驅動文件中定義了很多widget和control,alsa在playback或record的時候,sound/soc/soc-dapm.c中的dapm_power_widgets函數會根據“配置情況”打開相應的widget,搭建一個完整的音頻路徑,只要該路徑搭建成功,就可以正常工作; 
sound/soc/codecs/wm9713.c中的audio_map[]就是一個wm9713的路由表,根據wm9713手冊中的Audio Paths Overview可以選擇自己需要的音頻路徑,在audio_map[]中測試一下,看audio_map中是否支持這種路徑。 
alsa 的配置 
alsa音頻的調試最主要的是alsa的配置。alsa使用amixer命令打開audio_map[]中的開關(control/switch)和其它一些controls,這些control設置後,使用aplay/arecord的時候即可搭建正確的路徑,實現播放和錄音。 
比如我在調試的時候,在不用amixer控制時(默認狀態),arecord可以正確錄音,使用sound/soc/soc-dapm.c中的dump_dapm函數dump出的路徑是正確的;而aplay的時候,dump_dapm出來的路徑是錯誤的,原因是默認設置裏沒有打開playback的開關(switch),運行如下命令即可正確playback: 
alsa_amixer cset numid=4,iface=MIXER,name='Headphone Playback Switch' 1 
alsa_amixer cset numid=93,iface=MIXER,name='Left Headphone Out Mux' 2 
alsa_amixer cset numid=34,iface=MIXER,name='Out3 Playback Switch'1 
alsa_amixer cset numid=95,iface=MIXER,name='Left Speaker Out Mux' 4 
alsa_amixer cset numid=94,iface=MIXER,name='Right Speaker Out Mux' 2 
alsa_amixer cset numid=91,iface=MIXER,name='Out 3 Mux' 2 
alsa_amixer cset numid=81,iface=MIXER,name='Left HP Mixer PCM Playback Swit' 1 
alsa_amixer cset numid=75,iface=MIXER,name='Right HP Mixer PCM Playback Swi' 1 
alsa_amixer cset numid=3,iface=MIXER,name='Headphone Playback Volume' 26 
alsa_amixer cset numid=36,iface=MIXER,name='Out3 Playback Volume' 48 
其實就是打開playback路徑需要的開關,dapm_power_widgets會自動把這些開關連接的widget連接起來,構成一個播放路徑。 
Android中alsa的配置: 
Andriod中使用alsa-lib,也需要對配置音頻路徑。配置方法有兩個: 
1、在AudioHardwareALSA.cpp中的doRouting中使用system函數調用amixer進行配置 
system("alsa_amixer cset numid=4,iface=MIXER,name='Headphone Playback Switch' 1"); 
2、編寫asound.conf文件,AudioHardwareALSA.cpp中的ALSAMixer::ALSAMixer對象初始化的時候會通過alsa-lib的conf.c文件中的函數讀取/etc/asound.conf文件,獲取配置信息,對codec進行配置。 

alsa的一些命令 
alsa_amixer該命令配置主要配置音頻codec的mixer開關、mux對路選擇、volume值等; 
alsa_amixer --help 
alsa_amixer contents 
alsa_amixer contents 
numid=30,iface=MIXER,name='Headphone Playback ZC Switch' 
; type=BOOLEAN,access=rw------,values=2 
: values=off,off 
numid=4,iface=MIXER,name='Headphone Playback Switch' 
; type=BOOLEAN,access=rw------,values=2 
: values=off,off 
numid=3,iface=MIXER,name='Headphone Playback Volume' 
; type=INTEGER,access=rw------,values=2,min=0,max=31,step=0 
: values=31,31 
numid=6,iface=MIXER,name='PCM Playback Volume' 
; type=INTEGER,access=rw------,values=2,min=0,max=31,step=0 
: values=23,23 
numid=5,iface=MIXER,name='Line In Volume' 
; type=INTEGER,access=rw------,values=2,min=0,max=31,step=0 
: values=23,23 
numid=7,iface=MIXER,name='Mic 1 Volume' 
; type=INTEGER,access=rw------,values=1,min=0,max=31,step=0 
: values=23 
numid=8,iface=MIXER,name='Mic 2 Volume' 
; type=INTEGER,access=rw------,values=1,min=0,max=31,step=0 
: values=23 
numid=85,iface=MIXER,name='Mic A Source' 
; type=ENUMERATED,access=rw------,values=1,items=3 
; Item #0 'Mic 1' 
; Item #1 'Mic 2 A' 
; Item #2 'Mic 2 B' 
: values=0 



alsa_amixer controls 
numid=30,iface=MIXER,name='Headphone Playback ZC Switch' 
numid=4,iface=MIXER,name='Headphone Playback Switch' 
numid=3,iface=MIXER,name='Headphone Playback Volume' 
numid=6,iface=MIXER,name='PCM Playback Volume' 
numid=5,iface=MIXER,name='Line In Volume' 
numid=7,iface=MIXER,name='Mic 1 Volume' 
numid=8,iface=MIXER,name='Mic 2 Volume' 
numid=85,iface=MIXER,name='Mic A Source' 
numid=84,iface=MIXER,name='Mic B Source' 
numid=9,iface=MIXER,name='Mic Boost (+20dB) Switch' 
numid=10,iface=MIXER,name='Mic Headphone Mixer Volume' 
numid=47,iface=MIXER,name='Aux Playback Headphone Volume' 
numid=48,iface=MIXER,name='Aux Playback Master Volume' 
numid=49,iface=MIXER,name='Aux Playback Mono Volume' 
numid=67,iface=MIXER,name='Mono Mixer Aux Playback Switch' 
numid=69,iface=MIXER,name='Mono Mixer Bypass Playback Swit' 
numid=70,iface=MIXER,name='Mono Mixer Mic 1 Sidetone Switc' 
numid=71,iface=MIXER,name='Mono Mixer Mic 2 Sidetone Switc' 
numid=65,iface=MIXER,name='Mono Mixer PC Beep Playback Swi' 
numid=68,iface=MIXER,name='Mono Mixer PCM Playback Switch' 
numid=66,iface=MIXER,name='Mono Mixer Voice Playback Switc' 
alsa_alsactl store:該命令生成/etc/asound.state文件,該文件顯示當請codec的狀態,可以根據該文件檢查codec的狀態是否正確。 
# cat /etc/asound.state 
state.SMDK6400 { 
control.1 { 
comment.access 'read write' 
comment.type INTEGER 
comment.count 2 
comment.range '0 - 31' 
iface MIXER 
name 'Speaker Playback Volume' 
value.0 31 
value.1 31 

control.2 { 
comment.access 'read write' 
comment.type BOOLEAN 
comment.count 2 
iface MIXER 
name 'Speaker Playback Switch' 
value.0 false 
value.1 false 

control.3 { 
comment.access 'read write' 
comment.type INTEGER 
comment.count 2 
comment.range '0 - 31' 
iface MIXER 
name 'Headphone Playback Volume' 
value.0 26 
value.1 26 

control.4 { 
comment.access 'read write' 
comment.type BOOLEAN 
comment.count 2 
iface MIXER 
name 'Headphone Playback Switch' 
value.0 true 
value.1 true 

control.5 { 
comment.access 'read write' 
comment.type INTEGER 
comment.count 2 
comment.range '0 - 31' 
iface MIXER 
name 'Line In Volume' 
value.0 23 
value.1 23 

使用amixer命令可以參照alsa_amixer contents的內容;編寫asound.conf,可以參照alsa_alsactl生成的/etc/asound.state。 
下面是我的asound.conf的一段,其它的pcm.AndroidPlayback_xxx可以寫法一樣,就是hook_argsp[]中的內容根據自己的情況設置。 

## 
## Mixer Devices 
## 
ctl.AndroidPlayback { 
type hw 
card 0 # Can replace with driver"s name from /proc/asound/cards 

ctl.AndroidRecord { 
type hw 
card 0 # Can replace with driver"s name from /proc/asound/cards 

## 
## Playback Devices 
## 
pcm.AndroidPlayback { 
type hooks 
slave.pcm { 
type hw 
card 0 
device 0 # Must be of type "digital audio playback" 

hooks.0 { 
type ctl_elems 
hook_args [ 

name 'Master Playback Switch' 
value true 


name 'Master Playback Volume' 
value.0 51 
value.1 51 


name 'Phone Playback Switch' 
value false 


name 'Phone Playback Volume' 
value.0 0 
value.1 0 


name 'Mic Playback Switch' 
value false 


name 'Mic Playback Volume' 
value.0 0 
value.1 0 


name 'Mic Boost (+20dB)' 
value false 


name 'Line Playback Switch' 
value false 


name 'Line Playback Volume' 
value.0 0 
value.1 0 


name 'PCM Playback Switch' 
value true 


name 'PCM Playback Volume' 
value.0 51 
value.1 51 


name 'Capture Source' 
value.0 Mic 
value.1 Mic 


name 'Capture Switch' 
value true 


name 'Capture Volume' 
value.0 0 
value.1 0 



}

Linux的聲卡驅動中ALSA與OSS的區別和簡單流程介

Advanced Linux Sound Architecture 的簡稱爲 ALSA,譯成中文的意思是 Linux 高級聲音體系,ALSA不僅僅是包括對聲卡的支持和驅動;

它的特徵如下:

1、對所有音頻接口的高效支持,從普通用戶的聲卡到專業級別多路音頻設備;

2、聲卡驅動完全模塊化設計;

3、SMP and thread-safe design.

4、開發庫(alsa-lib) 爲程序設計提供了簡單、方便,並且擁有有高級的效果和功能;

5、支持舊版本的OSS API 結口,能爲大多數的OSS應用程序提供兼容;OSS是一個商業性的驅動,OSS有一個簡裝本的代碼已經移入內核和ALSA,其中alsa-oss就是;OSS公司據說目前已經並不存在了;我們沒有必要用OSS 公司提供的商業版本;用ALSA和OSS簡裝版足夠;

如何查看硬件芯片;

  在Linux操作系統中,所有的硬件都是以芯片組來區分的,品牌並不是最重要的;硬件最重要的標識是芯片組;所以您在討論區求助的時候,只說硬件品牌,而不提供芯片組,大家是幫助不了您的,切記;

  我們查看硬件的芯片組是的命令是 lspci -v 或者是dmesg,由於dmesg輸出的信息不太多,不夠直觀;所以經常用的還是lspci -v ;也可以用lshal 獲取;最方便的還是lspci -v;初學者還是用 lspci -v 更好一點;

  代碼:

  [root@localhost beinan]# lspci -v

  我們運行lspci -v 後,如果查看聲卡芯片組,發會現有類似下面的一段;

    [root@localhost beinan]# lspci -v

Multimedia audio controller: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M)

AC'97 Audio Controller (rev 03)

Subsystem: Hewlett-Packard Company: Unknown device 3080

  2.6.11-1.1369_FC4 i686 i686 i386

  上面的表示的是系統的內核版本,處理器架構等;lsmod 查看已經加載的內核模塊;

如果一個設備在內核的編譯中是以模塊方式加載的,主要是通過lsmod 來查看;

  [root@localhost beinan]# lsmod

  可能初學Linux的弟兄會問,內核的module存放在哪裏,我們能不能自己來手工加載模塊;內核的模塊放在 /lib/modules/內核的版本/kernel/ ,比如在Fedora 4.0 中,我們可以看到如下的:

  [root@localhost beinan]# ls /lib/modules/2.6.11-1.1369_FC4/kernel/

  arch/  crypto/ drivers/ fs/   lib/   net/   sound/其中,sound 就是聲卡模塊存放目錄,大多數的硬件驅動放在 drivers目錄,fs 是文件系統模塊的目錄;net是與網絡有關的存放目錄,比如一些網絡協議支持的模塊、防火牆支持的模塊等;arch 是cpu方面 ... ...

  如果我們想自己加載模塊,就到這些目錄中查看相應模塊的信息,然後用 modprobe 來加載;

  [root@localhost beinan]# modinfo snd-intel8x0

  查看一個模塊的信息,我們用 modinfo 來查看,所要查看的模塊不要帶 .ko 或者.o 之類的;比如查看到類似下面的信息;

  description: Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455

  通過這個我們足可以知道這是Intel 集成聲卡,通過lspci -v 得到的聲卡信息,感覺他們很相近;所以就能嘗試用這個模塊來驅動;

  [root@localhost beinan]# modprobe snd-intel8x0

  用 modprobe 加載了模塊,然後我們通過 lsmod 就能看到了;對於聲卡模塊是這麼加載的,其它設備的驅動模塊也是如此。

XRUN Debug
From AlsaProject
Jump to: navigationsearch

This page describes the build-in ALSA driver tool to debug PCM ring buffer positions.

[edit] /proc/asound/card#/pcm0p/xrun_debug

Replace '#' with your card number (usually 0). This proc file can enable various debugging tools. The CONFIG_SND_PCM_XRUN_DEBUG, CONFIG_SND_VERBOSE_PROCFS, CONFIG_SND_DEBUG options must be enabled in your kernel (if xrun_debug proc file is present - this feature is enabled).

1 Basic debugging - show xruns in ksyslog interface 2 Dump stack - dump stack for basic debugging 4 Jiffies check - compare the position with kernel jiffies (a sort of in-kernel monotonic clock), show what's changed when basic debugging is enabled 8 Dump positions on each period update call 16 Dump positions on each hardware pointer update call 32 Enable logging of last 10 ring buffer positions 64 Show the last 10 ring buffer position only once (when first error situation occured)

To enable more features just do sum values of above (for example 1+2=3).

Some good value combinations:

# Enable basic debugging and dump stack # Usefull to just see, if PCM stream is stopped for a reason (usually wrong audio process timing from scheduler) echo 3 > /proc/asound/card0/pcm0p/xrun_debug # Enable basic debugging, do jiffies check and enable one shot dump of last 10 ring buffer positions # Usefull, when the position is broken only after some of time (to reduce ksyslog messages) echo 101 > /proc/asound/card0/pcm0p/xrun_debug # Enable basic debugging, do jiffies check and dump position on each period and hardware pointer update calls # Usefull when the lowlevel (specific) hardware driver is somehow broken echo 29 > /proc/asound/card0/pcm0p/xrun_debug
發佈了9 篇原創文章 · 獲贊 10 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章