Android debugging USB volume range modification

Keywords: Android Java xml

Reference blog: Android native volume control

Reference blog: In depth understanding AudioService

1, Problem description

When the USB headset is not connected, the system volume can be set to the maximum value of 15. When the USB headset is connected, the system volume can only be set to 4

1, Cause analysis

(1) Android audio system sets different volume control ranges for different audio streams, presumably related to the range settings

But in the source code, the maximum value of stream music has been set to 15, mSafeMediaVolumeState = 10, and the safe volume has also been set to 10

Safe volume is configured in xml file

//AudioService.java  
      mSafeMediaVolumeState = new Integer(Settings.Global.getInt(mContentResolver,
                                                        Settings.Global.AUDIO_SAFE_VOLUME_STATE,
                                                        SAFE_MEDIA_VOLUME_NOT_CONFIGURED));


///////line284

 /** Maximum volume index values for audio streams */
    private static int[] MAX_STREAM_VOLUME = new int[] {
        5,  // STREAM_VOICE_CALL
        7,  // STREAM_SYSTEM
        7,  // STREAM_RING
        15, // STREAM_MUSIC
        7,  // STREAM_ALARM
        7,  // STREAM_NOTIFICATION
        15, // STREAM_BLUETOOTH_SCO
        7,  // STREAM_SYSTEM_ENFORCED
        15, // STREAM_DTMF
        15, // STREAM_TTS
        15  // STREAM_ACCESSIBILITY
    };


(2) Volume settings for USB Audio

You can see that USB audio is calculated according to MUSIC volume

//AudioService.java 6208 
private int safeMediaVolumeIndex(int device) {
        if ((device & mSafeMediaVolumeDevices) == 0) {
			Slog.w(TAG,"SOLEN return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]");
            return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
        }
        if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
			Slog.w(TAG,"SOLEN mSafeUsbMediaVolumeIndex" + Integer.toHexString(mSafeUsbMediaVolumeIndex));
            return mSafeUsbMediaVolumeIndex;
        } else {
            return mSafeMediaVolumeIndex;
        }
    }




//AudioService.java 754
        // relies on audio policy having correct ranges for volume indexes.
        mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();


    private int getSafeUsbMediaVolumeIndex()
    {
        // determine UI volume index corresponding to the wanted safe gain in dBFS
        int min = MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
        int max = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];

        while (Math.abs(max-min) > 1) {
            int index = (max + min) / 2;
            float gainDB = AudioSystem.getStreamVolumeDB(
                    AudioSystem.STREAM_MUSIC, index, AudioSystem.DEVICE_OUT_USB_HEADSET);
            if (Float.isNaN(gainDB)) {
                //keep last min in case of read error
                break;
            } else if (gainDB == SAFE_VOLUME_GAIN_DBFS) {
                min = index;
                break;
            } else if (gainDB < SAFE_VOLUME_GAIN_DBFS) {
                min = index;
            } else {
                max = index;
            }
        }
        return min * 10;
    

Modify the value of mSafeUsbMediaVolumeIndex to 150 directly, and solve the problem. Android audio system adds a precision design, which processes the volume by X10, 150 is actually 15, the maximum volume.

 

 

Posted by coder4Ever on Sun, 05 Jan 2020 11:30:13 -0800