frameworks/base/services/core/java/com/android/server/audio/AudioService.java
客户手动调节音量的范围:就是按音量键出来的进度条,就算拉满这个音量也是可以调的
源码是,清晰可见,所以为啥打电话的听筒没办法降到无声,因为最小也是1,而最高也就7,这里面的数字改了,就是影响最大最小的音量
protected static int[] MAX_STREAM_VOLUME = new int[] {7, // STREAM_VOICE_CALL15, // STREAM_SYSTEM15, // STREAM_RING15, // STREAM_MUSIC15, // STREAM_ALARM15, // STREAM_NOTIFICATION15, // STREAM_BLUETOOTH_SCO15, // STREAM_SYSTEM_ENFORCED15, // STREAM_DTMF15, // STREAM_TTS15 // STREAM_ACCESSIBILITY};/** Minimum volume index values for audio streams */protected static int[] MIN_STREAM_VOLUME = new int[] {1, // STREAM_VOICE_CALL0, // STREAM_SYSTEM0, // STREAM_RING0, // STREAM_MUSIC1, // STREAM_ALARM0, // STREAM_NOTIFICATION0, // STREAM_BLUETOOTH_SCO0, // STREAM_SYSTEM_ENFORCED0, // STREAM_DTMF0, // STREAM_TTS1 // STREAM_ACCESSIBILITY};
修改默认音量:
./base/media/java/android/media/AudioSystem.java
public static int[] DEFAULT_STREAM_VOLUME = new int[] {4, // STREAM_VOICE_CALL15, // STREAM_SYSTEM8, // STREAM_RING8, // STREAM_MUSIC8, // STREAM_ALARM8, // STREAM_NOTIFICATION7, // STREAM_BLUETOOTH_SCO15, // STREAM_SYSTEM_ENFORCED11, // STREAM_DTMF11, // STREAM_TTS11, // STREAM_ACCESSIBILITY};
按音量键或手动调进度条触发流程:
frameworks/base/services/core/java/com/android/server/audio/AudioService.java
按键按下去后走的,这个可以看PhoneWindowManager
adjustSuggestedStreamVolume 到 adjustStreamVolume,如果是手动滑动的话,直接走adjustStreamVolume
调节音量大小级数,每次加减的级数:,这个适用于旋钮音量底层驱动改不动了,音量键还是一次一级跳更好,这样改是和底层驱动配合的,看看驱动调的旋钮效果,再结合实际看看要怎么跳,这样跳的话缺点是幅度较大,那可能扭不了多少就到头了,要么就配合硬件设计,就这能扭这些范围更好
底层驱动节点的范围值/sys/devices/platform/rotary_pwr/rotary_status
在
~/2TSSD/P2/kernel-4.4/drivers/input/keyboard/mediate/rotary_power.c
修改
check_rotary_status
比如
if(rotary_volume == 0) {rotary_status = 0;} else if ((rotary_volume > 0) && (rotary_volume <= 200)) {rotary_status = 1;} else if((rotary_volume > 200) && (rotary_volume <= 400)) {rotary_status = 2;} else if((rotary_volume > 400) && (rotary_volume <= 600)) {rotary_status = 3;} else if((rotary_volume > 600) && (rotary_volume <= 800)) {rotary_status = 4;} else if((rotary_volume > 800) && (rotary_volume <= 1000)) {rotary_status = 5;} else if((rotary_volume > 1000) && (rotary_volume <= 1200)) {rotary_status = 6;} else if((rotary_volume > 1200) && (rotary_volume <= 1400)) {rotary_status = 7;} else if((rotary_volume > 1400) && (rotary_volume <= 1600)) {rotary_status = 8;} else if((rotary_volume > 1600) && (rotary_volume <= 1800)) {rotary_status = 9;}
就是划分了9级,级数越多,越灵活,旋钮控制幅度范围也大触发ui进度条也多,源码应该是18级,这个1800就是1.8v,看gpio口电压最多多少
设置了多大,比如0-9,那么上层的范围如果要一致的话0-9,肯定声音要变小的,因为原来是15级,那么这时候基带可以换个音频参数,我感觉也不是增大音量,就是增大原来的幅度,让原来给这个节点电压变得更大从而变得更大声
还是这个AudioService.java
在主要的调节音量方法里adjustStreamVolume
源码定义了一个int step;就是每次的加减的级数
源码写好了
else {// convert one UI step (+/-1) into a number of internal units on the stream aliasstep = rescaleIndex(10, streamType, streamTypeAlias);}
rescaleIndex用于将音量值的变化量从源流类型变换到目标流类型下,由于不同的流类型的音量调节范围不同,所以这个转换是必需的,计算按下音量键的音量步进值。这个步进值是10而不是1。在VolumeStreamState中保存的音量值是其实际值的10倍,这是为了在不同流类型之间进行音量转化时能够保证一定精度的一种实现。可以理解为在转化过程中保留了小数点后一位的精度。
同时操作指定多个音量类型:
adjustSuggestedStreamVolume方法中最后源码是
adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid);
可以增加
adjustStreamVolume(4, direction, flags, callingPackage, caller, uid);
第四个数组下标类型就是STREAM_ALARM
这是默认该有的streamType进行调节,就是按键传进来的第二个参数
AudioManager.USE_DEFAULT_STREAM_TYPE,getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER,AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG);
通过底层节点来调节音量大小:
base/services/core/java/com/android/server/policy/PhoneWindowManager.java
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
方法下关于音量键的处理全都注释掉
源码是直接
case KeyEvent.KEYCODE_VOLUME_DOWN:case KeyEvent.KEYCODE_VOLUME_UP:case KeyEvent.KEYCODE_VOLUME_MUTE: {
三个键一起处理的,把下面所有的逻辑注释掉,我们用节点的数值来设置当前的音量
加入:
isWakeKey = true; //这个是这个项目需要音量键唤醒,所以加这句,不加的话失效int rotary_status = Integer.parseInt( readFile("/sys/devices/platform/rotary_pwr/rotary_status") );Log.d("tyd", "rotary_status:"+rotary_status);AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); am.setStreamVolume(1,rotary_status,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(2,rotary_status,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(3,rotary_status,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(4,rotary_status,AudioManager.FLAG_SHOW_UI);//result &= ~ACTION_PASS_TO_USER;break;
AudioManager的setStreamVolume方法第一个参数就是数组里面第几个音量的类型,1234就是常用的类型 ,就是一次按键把这四个音量类型全部控制
// STREAM_SYSTEM
// STREAM_RING
// STREAM_MUSIC
// STREAM_ALARM
第二个是把底层的值写入上册赋音量值,上层是十五级,已知底层是六级,那还需要计算转换才能设置
一下是一种算法
if (rotary_status == 0 ) {am.setStreamVolume(1,rotary_status,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(2,rotary_status,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(3,rotary_status,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(4,rotary_status,AudioManager.FLAG_SHOW_UI);} else if (rotary_status == 1) {am.setStreamVolume(1,(1+rotary_status)*2-1,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(2,(1+rotary_status)*2-1,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(3,(1+rotary_status)*2-1,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(4,(1+rotary_status)*2-1,AudioManager.FLAG_SHOW_UI);} else if (rotary_status == 6) {am.setStreamVolume(1,(1+rotary_status)*2+1,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(2,(1+rotary_status)*2+1,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(3,(1+rotary_status)*2+1,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(4,(1+rotary_status)*2+1,AudioManager.FLAG_SHOW_UI);} else {am.setStreamVolume(1,(1+rotary_status)*2,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(2,(1+rotary_status)*2,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(3,(1+rotary_status)*2,AudioManager.FLAG_SHOW_UI);am.setStreamVolume(4,(1+rotary_status)*2,AudioManager.FLAG_SHOW_UI);}
这个readFile方法
private String readFile(String filePath) {StringBuilder infos = new StringBuilder();File file = new File(filePath);InputStream inputStream = null;BufferedReader buffer = null;InputStreamReader in = null;try {inputStream = new FileInputStream(file);in = new InputStreamReader(inputStream, "GBK");buffer = new BufferedReader(in);// read line by line.String line = null;while ((line = buffer.readLine()) != null) {if (!TextUtils.isEmpty(line)) {infos.append(line);//.append("\n");}}} catch (FileNotFoundException e) {Log.e("songshuangwen", "readFile() ====: " + e);} catch (UnsupportedEncodingException e) {Log.e("songshuangwen", "readFile() ====: " + e);} catch (IOException e) {Log.e("songshuangwen", "readFile() ====: " + e);} finally {try {if (buffer != null) {buffer.close();}if (inputStream != null) {inputStream.close();}if (in != null) {in.close();}} catch (IOException e) {// ignore}}return infos.toString();}
导包:
import java.io.BufferedReader;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.io.DataOutputStream;import java.io.FileOutputStream;import android.text.TextUtils;
然后改一下音量控制的对话框UI:
vendor/mediatek/proprietary/packages/apps/SystemUI/ src/com/android/systemui/volume/VolumeDialogImpl.java
在
private void initDialog() {
方法中
if (mRows.isEmpty()) {
判断中注释掉所有源码,加入
if (!AudioSystem.isSingleVolume(mContext)) {addRow(AudioManager.STREAM_RING,R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true, false);addRow(AudioManager.STREAM_BLUETOOTH_SCO,R.drawable.ic_volume_bt_sco, R.drawable.ic_volume_bt_sco, false, false);addRow(AudioManager.STREAM_SYSTEM, R.drawable.ic_volume_system,R.drawable.ic_volume_system_mute, false, false);}
实际上关键就留一句
addRow(AudioManager.STREAM_RING,R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true, false);
就是只出现铃声类型音量的ui进度框
开机音量修改:
frameworks/av/services/audioflinger/Threads.cpp
#if defined(MTK_BOOT_ANIMATION_SOUND_SUPPORT)// Do not change the volume, when boot sound openif (track->mFlags & IAudioFlinger::TRACK_BOOT) {/*/tyd.yantao 20221107 turn down the boot volumevlf = 0.25f;vrf = 0.25f;*/vlf = 0.05f;vrf = 0.05f;//*/}#endif // MTK_BOOT_ANIMATION_SOUND_SUPPORT
这个值的范围是float vlf, vrf, vaf; // in [0.0, 1.0] float format