WAVE绘制频谱图(四)——总结其它一些将PCM数据转为分贝值算法

{

https://blog.csdn.net/qq_36568418/article/details/91549540?spm=1001.2014.3001.5502

}

 

{

1:计算分贝 音频数据与大小

首先我们分别累加每个采样点的数值,除以采样个数,得到声音平均能量值。
然后再将其做100与32767之间的等比量化。得到1-100的量化值。
通常情况下,人声分布在较低的能量范围,这样就会使量化后的数据大致分布在1-20的较小区间,不能够很敏感的感知变化。
所以我们将其做了5倍的放大,当然计算后大于100的值,我们将其赋值100.
 

  1.  
     
  2.  
    //参数为数据,采样个数
  3.  
    //返回值为分贝
  4.  
    #define VOLUMEMAX 32767
  5.  
    int SimpleCalculate_DB(short* pcmData, int sample)
  6.  
    {
  7.  
    signed short ret = 0;
  8.  
    if (sample > 0){
  9.  
    int sum = 0;
  10.  
    signed short* pos = (signed short *)pcmData;
  11.  
    for (int i = 0; i < sample; i++){
  12.  
    sum += abs(*pos);
  13.  
    pos++;
  14.  
    }
  15.  
    ret = sum * 500.0 / (sample * VOLUMEMAX);
  16.  
    if (ret >= 100){
  17.  
    ret = 100;
  18.  
    }
  19.  
    }
  20.  
    return ret;
  21.  
    }

2:计算均方根(RMS) 即能量值

  1.  
    static const float kMaxSquaredLevel = 32768 * 32768;
  2.  
    constexpr float kMinLevel = 30.f;
  3.  
     
  4.  
    void Process(const int16_t* data, size_t length)
  5.  
    {
  6.  
    float sum_square_ = 0;
  7.  
    size_t sample_count_ = 0;
  8.  
    for (size_t i = 0; i < length; ++i) {
  9.  
    sum_square_ += data[i] * data[i];
  10.  
    }
  11.  
    sample_count_ += length;.
  12.  
    float rms = sum_square_ / (sample_count_ * kMaxSquaredLevel);
  13.  
    //20log_10(x^0.5) = 10log_10(x)
  14.  
    rms = 10 * log10(rms);
  15.  
    if (rms < -kMinLevel)
  16.  
    rms = -kMinLevel;
  17.  
    rms = -rms;
  18.  
    return static_cast<int>(rms + 0.5);
  19.  
    }

3:获取音频数据最大的振幅(即绝对值最大)(0-32767),除以1000,得到(0-32)。从数组中获取相应索引所对应的分贝值。(提取自webrtc)

  1.  
     
  2.  
    const int8_t permutation[33] =
  3.  
    {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};
  4.  
     
  5.  
    int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t* vector, size_t length)
  6.  
    {
  7.  
    size_t i = 0;
  8.  
    int absolute = 0, maximum = 0;
  9.  
    for (i = 0; i < length; i++) {
  10.  
    absolute = abs((int)vector[i]);
  11.  
    if (absolute > maximum) {
  12.  
    maximum = absolute;
  13.  
    }
  14.  
    }
  15.  
    if (maximum > 32767) {
  16.  
    maximum = 32767;
  17.  
    }
  18.  
    return (int16_t)maximum;
  19.  
    }
  20.  
     
  21.  
    void ComputeLevel(const int16_t* data, size_t length)
  22.  
    {
  23.  
    int16_t _absMax = 0;
  24.  
    int16_t _count = 0;
  25.  
    int8_t _currentLevel = 0;
  26.  
    int16_t absValue(0);
  27.  
    absValue = WebRtcSpl_MaxAbsValueW16(data,length);
  28.  
    if (absValue > _absMax)
  29.  
    _absMax = absValue;
  30.  
    if (_count++ == 10) {
  31.  
    _count = 0;
  32.  
    int32_t position = _absMax/1000;
  33.  
    if ((position == 0) && (_absMax > 250)){
  34.  
    position = 1;
  35.  
    }
  36.  
    _currentLevel = permutation[position];
  37.  
    _absMax >>= 2;
  38.  
    }
  39.  
    }

上文第三篇中采用的即为计算RMS能量值.

}

posted @ 2022-12-21 16:25  YZFHKMS-X  阅读(278)  评论(0编辑  收藏  举报