PCM 音量调节

通过编程实现调整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); 
 
}

你可能感兴趣的:(PCM 音量调节)