標籤:android 演算法 數學 音頻
1. 音量級數定義
在AudioService.java中定義了最大音量MAX_STREAM_VOLUME,手機的設定property可以覆蓋它。
2. 音量初始化
initStreamVolume傳入AudioPolicyManagerBase裡的StreamDescriptor mStreams[AudioSystem::NUM_STREAM_TYPES];
3. 設定主音量
主音量怎麼起作用?
最終音量=主音量*流音量
4. 設定流音量
setStreamVolumeIndex函數,在AudioPolicy中,通過volIndexToAmpl把Index整數轉為float型的振幅比,也就是“振幅/參考振幅”。
具體做法是:通過輸入的index查表找到對應的聲壓值db,然後通過下面的公式算出amplifier,這個值就是振幅比。
函數volIndexToAmpl中有一行代碼
float amplification = exp( decibels * 0.115129f);
就是這個公式。
通過這個值乘以音源的振幅,就得到了調節後的音量。這也是數字感度調整的原理。
拿到這個值後,存入AudioFlinger的全域變數mStreamTypes,即:mStreamTypes[stream].volume =value。
在Thread試圖播放聲音時,在prepareTracks_l中是這麼做的:
int32_t vl = t->prevVolume[0]; int32_t vr = t->prevVolume[1]; const int32_t vlInc =t->volumeInc[0]; const int32_t vrInc =t->volumeInc[1]; do { *out++ += (vl >> 16) *(int32_t) *in++; *out++ += (vr >> 16) *(int32_t) *in++; vl += vlInc; vr += vrInc; } while (--frameCount);
在系統靜音時,只是很簡單的設定下列參數為0:
vl = vr = 0;vlf = vrf = vaf = 0.
設定AudioMixer的參數
mAudioMixer->setParameter(name, param,AudioMixer::VOLUME0, &vlf);
mAudioMixer->setParameter(name, param,AudioMixer::VOLUME1, &vrf);
所以最後還是通過AudioMixer真正去乘以VOLUME0和VOLUME1來設定音量。
如track__16BitsStereo中
int32_t vl = t->prevVolume[0]; int32_t vr = t->prevVolume[1]; const int32_t vlInc =t->volumeInc[0]; const int32_t vrInc =t->volumeInc[1]; do { *out++ += (vl >> 16) *(int32_t) *in++; *out++ += (vr >> 16) *(int32_t) *in++; vl += vlInc; vr += vrInc; } while (--frameCount);
Android音量設定流程乾貨版