如何将音频字节转换为样本
How to convert audio byte to samples
这是我的结构
/* wave data block header */
typedef struct wavehdr_tag {
LPSTR lpData; /* pointer to locked data buffer */
DWORD dwBufferLength; /* length of data buffer */
DWORD dwBytesRecorded; /* used for input only */
DWORD_PTR dwUser; /* for client's use */
DWORD dwFlags; /* assorted flags (see defines) */
DWORD dwLoops; /* loop control counter */
struct wavehdr_tag FAR *lpNext; /* reserved for driver */
DWORD_PTR reserved; /* reserved for driver */
} WAVEHDR, *PWAVEHDR, NEAR *NPWAVEHDR, FAR *LPWAVEHDR;
我有这个变量WAVEHDR waveHeader;
我从麦克风录制了 10 秒,waveHeader->lpData
有我的原始记录数据,waveHeader->dwBytesRecorded
是原始数据的长度
现在我想计算每一秒的音量,以确定哪一秒的音量最高,哪一秒的音量最低。
我知道我应该对绝对值求和并除以样本数
我对从 0 到一秒长度的数据使用了 sum += abs(waveHeader->lpData[i]);
,但它并没有给我一个好的结果
它总是每秒给我相同的结果,但我有时会沉默,有时会说话...
我阅读 我必须添加样本,而不是字节我应该如何将 waveHeader->lpData[i]
转换为样本?
//len = length of one secs data (waveHeader->dwBytesRecorded/10)
for (int i=0; i<len; i++)
{
sum += abs(waveHeader->lpData[i]);
}
您有用于捕获音频的 WAVEFORMATEX,对吗?如果是这样,您可以修改以下例程以满足您的需要:
void ProcessSamples(WAVEHDR* header, WAVEFORMATEX* format)
{
BYTE* pData = (BYTE*)(header->data);
DWORD dwNumSamples = header->dwBytesRecorded / format->nBlockAlign;
// 16-bit stereo, the most common format
if ((format->wBitsPerSample == 16) && (format->nChannels == 2))
{
for (DWORD index = 0; index < dwNumSamples; index++)
{
short left = *(short*)pData; pData+=2;
short right = *(short*)pData; pData+=2;
}
}
else if ((format->wBitsPerSample == 16) && (format->nChannels == 1))
{
for (DWORD index = 0; index < dwNumSamples; index++)
{
short monoSample = *(short*)pData; pData+=2;
}
}
else if ((format->wBitsPerSample == 8) && (format->nChannels == 2))
{
// 8-bit samples are unsigned.
// "128" is the median silent value
// normalize to a "signed" value
for (DWORD index = 0; index < dwNumSamples; index++)
{
signed char left = (*(signed char*)pData) - 128; pData += 1;
signed char right = (*(signed char*)pData) - 128; pData += 1;
}
}
else if ((format->wBitsPerSample == 8) && (format->nChannels == 1))
{
for (DWORD index = 0; index < dwNumSamples; index++)
{
signed char monosample = (*(signed char*)pData) - 128; pData += 1;
}
}
}
这是我的结构
/* wave data block header */
typedef struct wavehdr_tag {
LPSTR lpData; /* pointer to locked data buffer */
DWORD dwBufferLength; /* length of data buffer */
DWORD dwBytesRecorded; /* used for input only */
DWORD_PTR dwUser; /* for client's use */
DWORD dwFlags; /* assorted flags (see defines) */
DWORD dwLoops; /* loop control counter */
struct wavehdr_tag FAR *lpNext; /* reserved for driver */
DWORD_PTR reserved; /* reserved for driver */
} WAVEHDR, *PWAVEHDR, NEAR *NPWAVEHDR, FAR *LPWAVEHDR;
我有这个变量WAVEHDR waveHeader;
我从麦克风录制了 10 秒,waveHeader->lpData
有我的原始记录数据,waveHeader->dwBytesRecorded
是原始数据的长度
现在我想计算每一秒的音量,以确定哪一秒的音量最高,哪一秒的音量最低。
我知道我应该对绝对值求和并除以样本数
我对从 0 到一秒长度的数据使用了 sum += abs(waveHeader->lpData[i]);
,但它并没有给我一个好的结果
它总是每秒给我相同的结果,但我有时会沉默,有时会说话...
我阅读 我必须添加样本,而不是字节我应该如何将 waveHeader->lpData[i]
转换为样本?
//len = length of one secs data (waveHeader->dwBytesRecorded/10)
for (int i=0; i<len; i++)
{
sum += abs(waveHeader->lpData[i]);
}
您有用于捕获音频的 WAVEFORMATEX,对吗?如果是这样,您可以修改以下例程以满足您的需要:
void ProcessSamples(WAVEHDR* header, WAVEFORMATEX* format)
{
BYTE* pData = (BYTE*)(header->data);
DWORD dwNumSamples = header->dwBytesRecorded / format->nBlockAlign;
// 16-bit stereo, the most common format
if ((format->wBitsPerSample == 16) && (format->nChannels == 2))
{
for (DWORD index = 0; index < dwNumSamples; index++)
{
short left = *(short*)pData; pData+=2;
short right = *(short*)pData; pData+=2;
}
}
else if ((format->wBitsPerSample == 16) && (format->nChannels == 1))
{
for (DWORD index = 0; index < dwNumSamples; index++)
{
short monoSample = *(short*)pData; pData+=2;
}
}
else if ((format->wBitsPerSample == 8) && (format->nChannels == 2))
{
// 8-bit samples are unsigned.
// "128" is the median silent value
// normalize to a "signed" value
for (DWORD index = 0; index < dwNumSamples; index++)
{
signed char left = (*(signed char*)pData) - 128; pData += 1;
signed char right = (*(signed char*)pData) - 128; pData += 1;
}
}
else if ((format->wBitsPerSample == 8) && (format->nChannels == 1))
{
for (DWORD index = 0; index < dwNumSamples; index++)
{
signed char monosample = (*(signed char*)pData) - 128; pData += 1;
}
}
}