Android recording gain adjustment

Requirements:
The project is equipped with a USB camera with a microphone for video calling. The distance for people to speak to the camera is estimated to be 5 meters, unlike a mobile phone that can be held in the hand and spoken to the MIC at close range, so during the test I feel that the sound collected by the camera is very small and I need to increase the recording volume. The first thing that comes to mind is to set the recording gain in the CPU's internal Codec, but it is now at its maximum and can only be solved through software.

Insert image description here

The following is the code that adds recording gain adjustment in android/hardware/aw/audio/homlet/audio_hw.c:

static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
                       size_t bytes)
{
    
    
	。。。。。。
    if(use_volume_gain){
    
    	//use_volume_gain由属性sys.use.volume_gain控制
        size_t i = 0;
        unsigned int value = 0;
        int32_t data32 = 0;
        unsigned char * buffer_temp=(unsigned char *)buffer;

        //ALOGV("channel_count:%d curFrameSize=%d",channel_count,curFrameSize);
        for( i=0; i< bytes; i=i+2){
    
    
            short data16;	//只针对AUDIO_FORMAT_PCM_16_BIT
            unsigned int value_temp = 0;
            
            value = buffer_temp[i+1];	//第二个字节为高位数据
            value = (value<<8)+buffer_temp[i];	//获得一个16bit的音频数据
            value_temp = value;		//备份

            if(value & 0x8000){
    
    //音频数据是负数
                data16 = value&0xFFFF;
                data32 = ~data16 + 1;	//转正数,保存到32bit以防止后面计算溢出

                data32 = data32*volume_gain_value;	//增益调节,volume_gain_value由属性sys.audio.in.volume_gain控制
                if(data32 > 0x7FFF)
                    data32 = 0x7FFF;	//音量最大值

                data16=(short)(data32 &0xFFFF);
                value= ~data16 + 1; //转负数

            }else{
    
    	//正数
                value = (unsigned int)(value*volume_gain_value);	//增益调节
                if( value > 0x7FFF)
                    value = 0x7FFF;		//音量最大值
            }

            buffer_temp[i] = (unsigned char)(value&0xff);	//获得低8位的音频数据
            buffer_temp[i+1] = (unsigned char)((value>>8)&0xff);	//获得搞8位的音频数据
        }
    }

    /* audio dump data write */
    debug_dump_data(buffer, bytes, &in->dd_read_in);
}

Note that this is just a simple modification of the audio data. The gain multiplier volume_gain_value is not adaptive and is evaluated by experimental tests. The software can also count the amount of "overflow" data above and then change the volume_gain_value appropriately. In addition, because the above code does not process noise, the noise will also be amplified.

Guess you like

Origin blog.csdn.net/suwen8100/article/details/117066836