標籤:framework 音樂 audio audiomanager 音量大小
近期要匹配部分第三方應用到系統中,但是涉及到音頻部分還存在邏輯的BUG。因此重點關注了下音頻管理的部分代碼,寫一部分目前已經理解的部分。
首先要先闡述下為什麼會做現在的工作,起因就是系統中已經有了要調用聲音的應用,所以同時再運行另外的需要用到聲音的應用時必須要有一個優先順序來約束這些聲音的音量大小及先後順序。因此需要對這部分音頻管理做邏輯上的處理,使其能協調的發出聲音而不是產生聲音的重疊和混亂。
查看了FrameWork的代碼即SDK文檔,最終定位在如下路徑的源碼中
/frameworks/base/media/java/android/media/AudioManager.java
/frameworks/base/media/java/android/media/AudioService.java
因為初次接觸很多隻是學習架構的時候瞭解了下並未仔細看過源碼,此次就需要仔細的看了。
查資料得知,在AudioManager中,Android2.2之前的版本是不存在多個程式同時競爭Audio資源的機制的,因此可能在那個版本前音訊管理應該是僅限於音量大小的調整,而不存在競爭互斥優先順序高低之分的。
所以先從簡單的聲音調節入手來分析。
先看一部分代碼中的定義:
/** The audio stream for phone calls */ public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL; /** The audio stream for system sounds */ public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM; /** The audio stream for the phone ring */ public static final int STREAM_RING = AudioSystem.STREAM_RING; /** The audio stream for music playback */ public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC; /** The audio stream for alarms */ public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM; /** The audio stream for notifications */ public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION; /** @hide The audio stream for phone calls when connected to bluetooth */ public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO; /** @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */ public static final int STREAM_SYSTEM_ENFORCED = AudioSystem.STREAM_SYSTEM_ENFORCED; /** The audio stream for DTMF Tones */ public static final int STREAM_DTMF = AudioSystem.STREAM_DTMF; /** @hide The audio stream for text to speech (TTS) */ public static final int STREAM_TTS = AudioSystem.STREAM_TTS; /** Number of audio streams */
再看一段調節音量的代碼
private AudioManager mAudioManager; mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FX_FOCUS_NAVIGATION_UP);
上面這部分代碼是調整音樂的音量的部分代碼,實現效果為按步長1來做聲音增大,並且此時調用會出現系統音量條的變化,此操作後續會分析。
現在重點分析函數adjustStreamVolume(int streamType,int direction,int flags)
參數streamType:這部分參數就是最開始定義過的,有STREAM_VOICE_CALL-- 通話,STREAM_SYSTEM -- 系統音量, STREAM_RING -- 鈴聲
STREAM_MUSIC -- 音樂, STREAM_ALARM -- 鬧鐘 , STREAM_NOTIFICATION -- 通知, STREAM_BLUETOOTH_SCO -- 藍芽通話,
後三種看起來不經常用,不是很明白。
參數direction: 這部分參數的定義有ADJUST_RAISE -- 增大, ADJUST_LOWER -- 減小, ADJUST_SAME -- 相同,針對ADJUST_SAME這個參數,可以實現一個小用途就是 調用後可彈出系統音量條而不會使音量變化。
參數flags:這部分為標誌位,可選。代碼中用到的是焦點上移的標誌位,具體有什麼特殊用途後續會跟進。
另外其他部分聲音調節函數有setStreamVolume(int streamType, int index, int flags) ,這個函數跟上個函數的區別就是上個函數是按步進進行調節,這個函數是可以直接給第二個參數直接賦值,指定音量值來設定。不過需要對參數的取值範圍進行判定,以免超出有效值範圍。
其他相關函數:
getMasterMaxVolume() -- 擷取系統主音量的最大值
getMasterVolume() -- 擷取系統當前音量值
getLastAudibleMasterVolume() -- 擷取系統靜音前的有效音量
getMode() -- 擷取當前音頻模式,如MODE_INVALID -- 無效,MODE_CURRENT -- 當前,NORMAL--普通,RINGTONE -- 鈴聲,MODE_IN_CALL --接通電話, MODE_IN_COMMUNICATION -- 通話。
getRingMode() -- 擷取響鈴方式,如RINGER_MODE_SILENT -- 靜音,RINGER_MODE_VIBRATE -- 震動,RINGER_MODE_NORMAL -- 正常,RINGER_MODE_MAX-- 正常
getStreamVolume(int streamType) -- 擷取當前模式下的音量值
getStreamMaxVolume(int streamType) -- 擷取當前最大鈴聲音量值
上述部分是AudioManager中關於音量大小的部分解析。後續繼續關於調節的涉及另外部分的函數解析。
Android FrameWork音頻管理AudioManager的一點解析