1. 程式人生 > >C++ 調節PCM音訊音量大小

C++ 調節PCM音訊音量大小

    在用解碼器解碼音訊資料得到PCM音訊資料塊之後,可以在將資料送給音效卡播放之前調節其音量大小,PCM格式本身就是以一定的資料位記錄音量的高低(如16位,便是以2個byte的長度記錄取樣時間點音量的大小),因此音訊音量大小的調節原理就是調節這個值而已,非常的簡單。需要注意的就是越界問題,在調節完後要做處理。

    具體的實現函式如下:

void RaiseVolume(char* buf, UINT32 size, UINT32 uRepeat, double vol)//buf為需要調節音量的音訊資料塊首地址指標,size為長度,uRepeat為重複次數,通常設為1,vol為增益倍數,可以小於1
{
	if (!size)
	{
		return;
	}
	for (int i = 0; i < size; i += 2)
	{
		short wData;
		wData = MAKEWORD(buf[i], buf[i + 1]);
		long dwData = wData;
		for (int j = 0; j < uRepeat; j++)
		{
			dwData = dwData * vol;
			if (dwData < -0x8000)
			{
				dwData = -0x8000;
			}
			else if (dwData > 0x7FFF)
			{
				dwData = 0x7FFF;
			}
		}
		wData = LOWORD(dwData);
		buf[i] = LOBYTE(wData);
		buf[i + 1] = HIBYTE(wData);
	}
}

    另外,有了上面的知識,也可以很容易判斷音訊中是否有長時間沒有聲音的情況,以便後面做語言識別的時候可以直接擷取有聲音的部分做識別。

#include <stdio.h>
#include <Windows.h>

FILE*			ipcmfile;  //音訊檔案
FILE*			opcmfile;  //音訊檔案
char data[2];
void main()
{
	fopen_s(&ipcmfile, "錄音測試.pcm", "rb");
	fopen_s(&opcmfile, "錄音測試轉換.pcm", "wb");
	while (fread(data, 1, 2, ipcmfile) == 2)
	{
		short wData;
		wData = MAKEWORD(data[0], data[1]);
		long dwData = wData;

		if (abs(dwData)>50)
		{
			fwrite(&data[0], 1, 2, opcmfile);
		}
	}
	fclose(ipcmfile);
	fclose(opcmfile);
}