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命令實現的,但沒有源碼具體實現還不清楚。