android整體audio包括android層和底層ASLA驅動。
最近開始調3G 通話功能繼而開始接觸android 音頻架構,之前調試音效卡的時候也有過接觸,不過那些都相對比較簡單,基本上只需要修改audio path, 也就是修改audio_codec.h, 該檔案定義了各種情況下的音頻資料流程。其中有個結構體定義,如下:
typedef struct AudioMixer_tag {
const char *ctl;
const int val;
} AudioMixer;
具體定義格式如下:
onst
AudioMixer
device_out_SPK
[]
=
{
//playback_speaker //path
{
"AIF1DACL Source"
,
0
},
//Left DAC receive left channel
{
"AIF1DACR Source"
,
1
},
//Right DAC receive right channel
{
"AIF1DAC Mux"
,
0
},
//AIF1DAC, select AIF1DACDAT
{
"DAC1L Mixer AIF1.1 Switch"
,
1
},
//AIF1DAC1L --> DAC1L Mixer
{
"DAC1R Mixer AIF1.1 Switch"
,
1
},
//AIF1DAC1R --> DAC1R Mixer
{
"SPKL DAC1 Switch"
,
1
},
//DAC1L --> SPKL
{
"SPKR DAC1 Switch"
,
1
},
//DAC1R --> SPKR
{
"SPKL Boost SPKL Switch"
,
1
},
//SPKL --> SPKL Boost
{
"SPKR Boost SPKR Switch"
,
1
},
//SPKR --> SPKR Bootst //gain
{
"Headphone Switch"
,
0
},
//HPOUT PGA mute
{
"Speaker Mode"
,
0
},
//Class D
{
"Speaker ZC Switch"
,
0
},
//disable ZC
{
"Speaker Volume"
,
60
},
//SPK volume, +3dB
{
"Speaker Boost Volume"
,
4
},
//2.0x boost, +6.0dB
{
"Speaker Mixer Volume"
,
3
},
//SPK Mixer Volume 0dB
{
"Speaker Switch"
,
1
},
//SPK OUTPUT PGA unmute
{
"DAC1 Volume"
,
96
},
//DAC1 Volume, 0dB
{
"DAC1 Switch"
,
1
},
//DAC1 Switch, unmute
{
"AIF1DAC1 Volume"
,
96
},
//AIF1DAC1 Input Volume, 0dB
{
NULL
,
0
} };
3G 語音分為兩種,一種是類比語音,一種是PCM數字語音,採用不同的語音資料,硬體電路是不同的。
類比語音比較簡單,可以直接把MIC,SPEAKER裝置接到3G 模組,也可以把類比輸出接入到音效卡裝置,以便更精細的管理。如果採用PCM數字語音需要音效卡裝置或CPU 的PCM 介面支援 slave mode 。剛開始調試以為類比音頻比較簡單就採用這種方式調試,但是調到後面發現音量調整是個問題,音頻資料不經過CPU 無法控制音量。在分析了android 音頻流程代碼發現,android的音量大小是不涉及硬體的,完全是通過mixer 實現的。關於android音量調整可以參考該文章《android音量設定from top to bottom》:http://blog.csdn.net/kld2009/article/details/8865680 ,這位仁兄寫的很詳細。
既然如此想要調整音量必須要通過硬體調整3G 模組音量輸出的大小,後來嘗試了這種方法,不過發現效果不怎麼好,在設定介面調整音量發現反應有點延遲,可能方法或代碼的問題,就是在java調整音量的地方讀寫底層一個檔案,底層根據檔案的變化讀寫3G 模組寄存器調整音量。
在看AUDIO HAL層代碼的時候發現三星調整音量不是通過上述兩種方法,它是通過SECRILD庫檔案實現,如下:
openClientRILD = (HRilClient (*)(void))
dlsym(mSecRilLibHandle, "OpenClient_RILD");
disconnectRILD = (int (*)(HRilClient))
dlsym(mSecRilLibHandle, "Disconnect_RILD");
closeClientRILD = (int (*)(HRilClient))
dlsym(mSecRilLibHandle, "CloseClient_RILD");
isConnectedRILD = (int (*)(HRilClient))
dlsym(mSecRilLibHandle, "isConnected_RILD");
connectRILD = (int (*)(HRilClient))
dlsym(mSecRilLibHandle, "Connect_RILD");
setCallVolume = (int (*)(HRilClient, SoundType, int))
dlsym(mSecRilLibHandle, "SetCallVolume");
setCallAudioPath = (int (*)(HRilClient, AudioPath))
dlsym(mSecRilLibHandle, "SetCallAudioPath");
setCallClockSync = (int (*)(HRilClient, SoundClockCondition))
dlsym(mSecRilLibHandle, "SetCallClockSync");
通過調用這些設定調整3G 模組的語音設定,應該是通過AT命令實現的,但沒有源碼具體實現還不清楚。
--------------------------------未完待續--------------------------------------