播放生成Android4.0.3中的提示音
題記:寫這篇博客要主是加深自己對播放生成的認識和總結實現算法時的一些驗經和訓教,如果有錯誤請指出,萬分感謝。
????
一、ToneGenerator的應用
????參照com.android.contacts.dialpad.DialpadFragment
????ToneGenerator只能播放在ToneGenerator中定義好的TONE_TYPE。
????
1、常量申明
/** Tone音的長度,單位:milliseconds */ private static final int TONE_LENGTH_MS = 150; /** 主音量的比例:以80%的主音量播放Tone音 */ private static final int TONE_RELATIVE_VOLUME = 80; /** 主音量的音頻種別 */ private static final int DIAL_TONE_STREAM_TYPE =AudioManager.STREAM_MUSIC;????
2、變量申明
// Tone音播放器 private ToneGenerator mToneGenerator; // Tone相干的同步鎖 private Object mToneGeneratorLock = new Object(); // 設定中的Tone音播放設置 private boolean mDTMFToneEnabled;????
3、Tone的初始化
public void onResume() {super.onResume();// 讀取設定的值mDTMFToneEnabled =Settings.System.getInt(getActivity().getContentResolver(),Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;// 失敗了也無所謂,不是啥重要的貨色synchronized (mToneGeneratorLock) {if (mToneGenerator == null) {try {// we want the user to be ableto control the volume of the dial tones// outside of a call, so we usethe stream type that is also mapped to the// volume control keys for thisactivitymToneGenerator = newToneGenerator(DIAL_TONE_STREAM_TYPE, TONE_RELATIVE_VOLUME);getActivity().setVolumeControlStream(DIAL_TONE_STREAM_TYPE);} catch (RuntimeException e) {Log.w(TAG, "Exceptioncaught while creating local tone generator: " + e);mToneGenerator = null;}}} }????
4、釋放Tone資源
public voidonPause() {super.onPause();synchronized (mToneGeneratorLock) {if (mToneGenerator != null) {mToneGenerator.release();mToneGenerator = null;}} }????
5、播放Tone音
每日一道理那蝴蝶花依然花開花落,而我心中的蝴蝶早已化作雄鷹飛向了廣闊的藍天。
/*** 播放TONE_LENGTH_MS milliseconds的Tone音.* 只有在設定中選擇了播放Tone,并且不是靜音模式才會播放Tone音。* @param tone a tone code from {@linkToneGenerator}*/ void playTone(int tone) {// 設定中沒有選中的話,就不播if (!mDTMFToneEnabled) {return;}// 靜音模式的時候也不播,需要每次都檢查,因為沒有Activity切換也能設成靜音模式// 設定中的那個就不需要,因為要設定必須要先切入設定Activity才行AudioManager audioManager =(AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE);int ringerMode =audioManager.getRingerMode();if ((ringerMode == AudioManager.RINGER_MODE_SILENT)|| (ringerMode ==AudioManager.RINGER_MODE_VIBRATE)) {return;}synchronized (mToneGeneratorLock) {if (mToneGenerator == null) {Log.w(TAG, "playTone:mToneGenerator == null, tone: " + tone);return;}// Start the new tone (will stop anyplaying tone)mToneGenerator.startTone(tone,TONE_LENGTH_MS);} }
????
????
?二、ToneGenerator的實現
????相干代碼位置:
????ToneGenerator.java:ICS/frameworks/base/media/java/
????Android_media_ToneGenerator.cpp:ICS/frameworks/base/core/jni/
????ToneGenerator.cpp:ICS/frameworks/base/media/libmedia/
????
1、ToneGenerator.java
????定義了多種ToneType,供給了java的接口
????
2、Android_media_ToneGenerator.cpp
????將Java層的請求轉發給Native層。
????android_media_ToneGenerator_native_setup中的有句話看不懂:
ToneGenerator *lpToneGen= new ToneGenerator(streamType,????
????AudioSystem::linearToLog(volume)
????
????,true); // change this value tochange volume scaling static const float dBPerStep= 0.5f; // shouldn't need totouch these static const floatdBConvert = -dBPerStep * 2.302585093f / 20.0f; static const floatdBConvertInverse = 1.0f / dBConvert; floatAudioSystem::linearToLog(int volume) { // float v = volume ? exp(float(100 -volume) * dBConvert) : 0; // LOGD("linearToLog(%d)=%f",volume, v); // return v; return volume ? exp(float(100 - volume) *dBConvert) : 0; }
????算出來的值會直接設到AudioTrack中,可是AudioTrack中的音量應該是個0~1.0f的百分比才對,為啥需要這么個公式呢,難道是Bug。應該測試一下!!
????
3、ToneGenerator.cpp
????根據定義的Tone因的頻率,長度等信息生成音頻數據,最后交給AudioTrack播放。
????
三、AudioPolicyService中的mTonePlaybackThread
? 本來認為這個線程是專門處置Tone音設備的,可是根據下面一看本來是直接走AudioTrack的。這就奇怪了,并且AudioSystem中也沒有供給對應的接口,這就更奇怪了,難道它沒預備讓表面的人用。再一檢索,發現本來它是供給給AudioPolicyManagerBase應用的一個非同期播放Tone音的接口。
? 經過AudioCommandThread的處置,最終還是交給ToneGenerator來處置。
????
四、RingtoneManager與Ringtone
????播放鈴聲的類,沒具體看,最后是通過MediaPlayer來播放的。
????
五、論斷
????本來還認為會有個獨自硬件來處置Tone音的,最后發現竟然是自動生成后,通過AudioTrack來處置的。
????據說是因為硬件生成的Tone音很難聽,所以才用軟件來生成的。
文章結束給大家分享下程序員的一些笑話語錄: 程序員打油詩
寫字樓里寫字間,寫字間里程序員;
程序人員寫程序,又拿程序換酒錢。
酒醒只在網上坐,酒醉還來網下眠;
酒醉酒醒日復日,網上網下年復年。
但愿老死電腦間,不愿鞠躬老板前;
奔馳寶馬貴者趣,公交自行程序員。
別人笑我忒瘋癲,我笑自己命太賤;
不見滿街漂亮妹,哪個歸得程序員。
轉載于:https://www.cnblogs.com/jiangu66/archive/2013/05/20/3089275.html
總結
以上是生活随笔為你收集整理的播放生成Android4.0.3中的提示音的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 订阅广告一个微博大号的微信生存记
- 下一篇: jsp的flash小例子