Android audio 音量曲线

index 转化为 db的流程

首先android 根据不同的流类型定义不同的曲线,曲线文件存放在/vendor/etc/audio_policy_volumes.xml
或者audio_policy_volumes_drc.xml下面 要看audio_policy_configuration.xml所引用的xml。

    <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_SPEAKER">
        <point>1,-3400</point>
        <point>33,-2400</point>
        <point>66,-1500</point>
        <point>100,-600</point>
    </volume>

曲线的定义如上。

是定义了几个区间。point的两个值分别为index 和db。 定义的index范围是1到100, 而db的范围为-3400 到-600.
外部的index范围不一定是1,100 比如外部index范围为0,39.

  1. ui的index寻找在曲线index位置
    那么第一步先将传递进去的index,转换为1,100等比例的位置。 假设传递是x, 要求等比例的y。
    x/(39 -0) = y / (100 -1)。 假设传递的18 ,求出来y = 46.

  2. 寻找曲线index对应的分贝。

首先46是处在【33,66】的这个区间内,这个区间对应的db区间是【-2400,-1500】。
先求这个区间一个index对应多少db 将总的index(66 -33)除于总的db(-1500 - (-2400)) 为单位index对应的db。
那46对应的有多少index,46对应为 46 -33。 将这两者相乘就是46对应在这个区间内的db值, 加上起始的-2400就是最终的db。
db就在这个区间里面算。 所求的db = -2400 + (((- 1500 - (-2400))/(66 -33) x(46 -33)) = 2045.
也等比例计算的一个方式。 相对于一个个区间是独立。起始点是最靠近的上一个区间的index,然后计算区间内一个index对应多少db。
传递进去的index相对于起始index的值。

  1. db转为amplit
    //exp是以e为底的指数函数,常数 e 的值约为 2.718282;是由分贝算式推导过来的db = 20* ln(P1/P0);P0是基本功率
    aml =  exp( db * 0.115129f); // exp( dB * ln(10) / 20 )

  1. 相应的代码位置
status_t AudioPolicyManager::checkAndSetVolume(IVolumeCurves &curves,
                                               VolumeSource volumeSource,
                                               int index,
                                               const sp<AudioOutputDescriptor>& outputDesc,
                                               DeviceTypeSet deviceTypes,
                                               int delayMs,
                                               bool force)

float volumeDb = computeVolume(curves, volumeSource, index, deviceTypes);

float AudioPolicyManager::computeVolume(IVolumeCurves &curves,
                                        VolumeSource volumeSource,
                                        int index,
                                        const DeviceTypeSet& deviceTypes)
{
    float volumeDb = curves.volIndexToDb(Volume::getDeviceCategory(deviceTypes), index);

}

   virtual float volIndexToDb(device_category deviceCat, int indexInUi) const
    {
        sp<VolumeCurve> vc = getCurvesFor(deviceCat);
        if (vc != 0) {
            return vc->volIndexToDb(indexInUi, mIndexMin, mIndexMax);
        } else {
            ALOGE("Invalid device category %d for Volume Curve", deviceCat);
            return 0.0f;
        }
    }



  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要修改录音音量,可以通过调整AudioRecord对象的采样率和音频格式来实现。下面是一个简单的示例代码: ```java //设置采样率为16kHz int sampleRate = 16000; //设置音频格式为PCM编码 int audioFormat = AudioFormat.ENCODING_PCM_16BIT; //设置录音声道为单声道 int channelConfig = AudioFormat.CHANNEL_IN_MONO; //设置缓冲区大小 int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat); //创建AudioRecord对象 AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, channelConfig, audioFormat, bufferSize); //开始录音 audioRecord.startRecording(); byte[] buffer = new byte[bufferSize]; int read = 0; while (true) { read = audioRecord.read(buffer, 0, bufferSize); if (read > 0) { //修改音量 for (int i = 0; i < read / 2; i++) { //左右声道分别处理 short left = (short) ((buffer[i * 2] & 0xff) | (buffer[i * 2 + 1] << 8)); short right = (short) ((buffer[i * 2 + 2] & 0xff) | (buffer[i * 2 + 3] << 8)); //将左右声道的音量都增加一倍 left *= 2; right *= 2; //处理后的左右声道数据写回缓冲区 buffer[i * 2] = (byte) (left & 0xff); buffer[i * 2 + 1] = (byte) ((left >> 8) & 0xff); buffer[i * 2 + 2] = (byte) (right & 0xff); buffer[i * 2 + 3] = (byte) ((right >> 8) & 0xff); } //将处理后的缓冲区数据写入文件或进行其他处理 } } //停止录音 audioRecord.stop(); audioRecord.release(); ``` 在上面的代码中,我们使用了一个简单的算法来将左右声道的音量都增加一倍。你也可以根据需要使用其他算法来调整音量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值