PCM数据的各种算法

1.pcm音量加强
算法:
获取一个音频帧中的最大值max和最小值min
根据获取到的最大值和最小值分别计算出在不失真的情况下,允许的放大倍数maxfactor和minfactor,取其最小值为允许的最大放大倍数allowfactor
根据给定的经验系数factor,选择合适的系数,对PCM数据放大即可
code:
void raiseVolume(unsigned char* buffer,int length,int factor)
{
signed short MIN = -0x8000;
signed short MAX = 0x7FFF;
signed short low = 0, high = 0, data = 0, maxData = 0, minData = 0;
//获取一个音频帧中的最大值max和最小值min
for (int i = 0; i < length; i+=2) {
low = buffer[i];
high = buffer[i+1];
data = low+(high<<8);
maxData = maxData > data ? maxData : data;
minData = minData < data ? minData : data;
}
//根据获取到的最大值和最小值分别计算出在不失真的情况下,允许的放大倍数maxfactorminfactor
signed short maxfactor = maxData != 0 ? MAX/maxData : 1;
signed short minfactor = minData != 0 ? MIN/minData : 1;
if (minfactor == 1 || maxfactor == 1) {
return;
}
//取其最小值为允许的放大倍数allowfactor
signed short allowfactor = MIN(maxfactor, minfactor);
//根据经验系数factor,选择合适的系数
factor = factor > allowfactor ? allowfactor : factor;
if (factor <= 1) {
return;
}
//对PCM数据放大
signed long newData = 0;
for (int i = 0; i < length; i+=2) {
low = buffer[i];
high = buffer[i+1];
data = low+(high<<8);
newData = data*factor;
//边界值溢出处理
if (newData < MIN) {
newData = MIN;
}else if (newData > MAX) {
newData = MAX;
}
data = newData&0xffff;
buffer[i] = data&0x00ff;
buffer[i+1] = (data&0xff00)>>8;
}
}

2.根据分贝调整音量
算法:参考:https://blog.jianchihu.net/pcm-vol-control-advance.html

dB = 20 * log(A1 / A2),我们取参考声音振幅A2为原始声音振幅,A1为调节后的声音振幅大小。可知调节后的声音:
A1 = A2 * pow(10 , db/20);
看过一篇文章说理想的声音调节步长最好是2db,对于96db范围,我们按2db步长进行分割,可以分成48份,这样我们得到的声音变化为[-96db,-94db,-92db,...-4db.-2db,0db],假设我们要调节一半音量大小,也就是-48db,由上述公式可知:调节后音量A1大小:
A1 = A2 * pow(10 , -48/20)
code:
int16_t pcm[1024] = read in some pcm data;
int32_t pcmval;
float multiplier = pow(10,db/20);
for (ctr = 0; ctr < 1024; ctr++) {
pcmval = pcm[ctr] * multiplier;
if (pcmval < 32767 && pcmval > -32768) {
pcm[ctr] = pcmval
} else if (pcmval > 32767) {
pcm[ctr] = 32767;
} else if (pcmval < -32768) {
pcm[ctr] = -32768;
}
}

posted @ 2020-08-12 14:38  shenyantaoit  阅读(2934)  评论(0编辑  收藏  举报