1.WebRTC中音频能量计算
WebRTC中实现获取音频能量计算的方法是:获取音频数据最大的振幅(即绝对值最大)(范围是0-32767),然后再除以1000,得到0-32之间的数值。从数组中获取相应索引所对应的能量level等级。
我们看下webRTC中level_indicator.cc中对音频level判断的处理。
namespace webrtc {
namespace voe {
// Number of bars on the indicator.
// Note that the number of elements is specified because we are indexing it
// in the range of 0-32
const int8_t permutation[33] =
{0,1,2,3,4,4,5,5,5,5,6,6,6,6,6,7,7,7,7,8,8,8,9,9,9,9,9,9,9,9,9,9,9};
AudioLevel::AudioLevel() :
_absMax(0),
_count(0),
_currentLevel(0),
_currentLevelFullRange(0) {
}
AudioLevel::~AudioLevel() {
}
void AudioLevel::Clear()
{
rtc::CritScope cs(&_critSect);
_absMax = 0;
_count = 0;
_currentLevel = 0;
_currentLevelFullRange = 0;
}
void AudioLevel::ComputeLevel(const AudioFrame& audioFrame)
{
int16_t absValue(0);
//获取最大值
// Check speech level (works for 2 channels as well)
absValue = WebRtcSpl_MaxAbsValueW16(
audioFrame.data_,
audioFrame.samples_per_channel_*audioFrame.num_channels_);
// Protect member access using a lock since this method is called on a
// dedicated audio thread in the RecordedDataIsAvailable() callback.
rtc::CritScope cs(&_critSect);
if (absValue > _absMax)
_absMax = absValue;
//WebRTC中音频帧间隔是10ms一次音频帧,这里把塞入10次音频帧作为一次统计,来获取这10次中的最大音频帧的能量值(需要在去噪后计算音频能量,减小误差)
// Update level approximately 10 times per second
if (_count++ == kUpdateFrequency)
{
_currentLevelFullRange = _absMax;
_count = 0;
// Highest value for a int16_t is 0x7fff = 32767
// Divide with 1000 to get in the range of 0-32 which is the range of
// the permutation vector
int32_t position = _absMax/1000;
// Make it less likely that the bar stays at position 0. I.e. only if
// its in the range 0-250 (instead of 0-1000)
if ((position == 0) && (_absMax > 250))
{
position = 1;
}
//算出position的位置后,从上面的音频能量数组中获取当前的level等级。
_currentLevel = permutation[position];
// Decay the absolute maximum (divide by 4)
_absMax >>= 2;
}
}
/**
*获取音频能量,范围0-9
*/
int8_t AudioLevel::Level() const
{
rtc::CritScope cs(&_critSect);
return _currentLevel;
}
/**
*获取音频能量,范围0-32767
*/
int16_t AudioLevel::LevelFullRange() const
{
rtc::CritScope cs(&_critSect);
return _currentLevelFullRange;
}
} // namespace voe
} // namespace webrtc
看下WebRtcSpl_MaxAbsValueW16C函数,函数主要是获取vector中的绝对值的最大值,同时不能超过int16的最大值32767。
int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t* vector, size_t length)
{
size_t i = 0;
int absolute = 0, maximum = 0;
for (i = 0; i < length; i++) {
absolute = abs((int)vector[i]);
if (absolute > maximum) {
maximum = absolute;
}
}
if (maximum > 32767) {
maximum = 32767;
}
return (int16_t)maximum;
}
这个最终获取的值就可以用来实时获取音频的音量值了。
我们可以看到这里取的是最大值,为了得到的结果更加准确的话,音频的能量计算最好放在去噪后。
本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓