通过编程实现调整PCM的音量,具体做法是乘上一个固定的数,但是要考虑数据的溢出问题。
int frame_size_get(int inSampleRate, int ChannleNumber)
{
int size= -1;
switch(inSampleRate)
{
case 8000:
{
size= 320;
}
break;
case 16000:
{
size= 640;
}
break;
case 24000:
{
size= 960;
}
break;
case 32000:
{
size= 1280;
}
break;
case 48000:
{
size= 1920;
}
break;
case 44100:
{
size= 441*4;//为了保证8K输出有320,441->80,*4->320
}
break;
case 22050:
{
size= 441*2;
}
break;
case 11025:
{
size= 441;
}
break;
default:
break;
}
return ChannleNumber*size;
}
void RaiseVolume(char* buf, UINT32 size,UINT32 uRepeat,double vol)
{
if (!size )
{
return;
}
for (int i = 0; i < size;)
{
signed long minData = -0x8000; //如果是8bit编码这里变成-0x80
signed long maxData = 0x7FFF;//如果是8bit编码这里变成0xFF
signed short wData = buf[i+1];
wData = MAKEWORD(buf[i],buf[i+1]);
signed long dwData = wData;
for (int j = 0; j < uRepeat; j++)
{
dwData = dwData * vol;//1.25;
if (dwData < -0x8000)
{
dwData = -0x8000;
}
else if (dwData > 0x7FFF)
{
dwData = 0x7FFF;
}
}
wData = LOWORD(dwData);
buf[i] = LOBYTE(wData);
buf[i+1] = HIBYTE(wData);
i += 2;
}
}
//vol取0—10即可,为0时为静音,小于1声音减小,大于1声音增大,测试取大于10的数字效果不明显
int pcm_volume_control(char* foldname, char* fnewname, double vol)
{
HXD_WAVFLIEHEAD head;
int frame_size= 0;
char* frame_buffer;
FILE* fp_old= fopen(foldname,"rb+");
FILE* fp_new= fopen(fnewname,"wb+");
if((NULL== fp_old) || (NULL== fp_new))
{
return -1;
}
fread(&head,1,sizeof(head),fp_old);
fwrite(&head,1,sizeof(head),fp_new);
frame_size= frame_size_get( head.nSampleRate,head.nChannleNumber);
frame_buffer= (char*)malloc(frame_size);
while(frame_size== fread(frame_buffer,1,frame_size,fp_old))
{
RaiseVolume(frame_buffer,frame_size,1,vol);
fwrite(frame_buffer,1,frame_size,fp_new);
}
fclose(fp_old);
fclose(fp_new);
free(frame_buffer);
return 0;
}
void CAudioControlDlg::OnButtonAdd()
{
// TODO: Add your control notification handler code here
pcm_volume_control("old.wav","new.wav",5);
}