【发布时间】:2014-06-18 03:46:05
【问题描述】:
我正在使用 WaveAPI 进行录制,我想在完成数据录制后检测缓冲区中是否有声音,或者它没有录制任何内容(只是房间的空白)。
我写了一个获取缓冲区绝对值平均值的函数,它工作“还可以”,但它有很多问题:
1) 我发现,当它无效时,平均值约为 860,而当我说话时,它是 ~875,几乎没有什么不同。怎么会这样 ?我正在录制 1 秒。
2) 有时,我看到平均值约为 860,有时约为 500,有时甚至约为 400。为什么每次都变?我的意思是,它应该是一样的吗,因为它一直在捕捉空白并且没有变化?
这是我写的函数:
bool isEmpty(short int *wave)
{
int avg = 0;
for (int i = 0 ; i < NUMPTS ; i++)
{
if (wave[i] < 0)
avg = avg + (wave[i]) * -1;
else
avg = avg + (wave[i]);
}
avg = avg / NUMPTS;
if (avg > avg_voice)
return false;
return true;
}
这个功能不够好,因为它并不总是正确的,我必须不断地将avg_voice 更改为其他东西,有时缓冲区的平均值只有 10 个点,声音比 void 高,这很难检测到它是否有声音......
那我该怎么办?我该如何改进它?当我录制声音并填写所有WAVEFORMATEX和WAVEHDR设置时,也许有一个选项?
谢谢!
编辑:wave 是一个简短的 int 数组,其中包含 8000 单元格,并将语音存储在里面,看起来像这样(示例):
wave[0] = -123;
wave[1] = -205;
wave[2] = -212'
等等……
第二次编辑: 我正在记录这样的数据:
void StartRecord()
{
short int *waveIn = new short int[NUMPTS];
HWAVEIN hWaveIn;
WAVEHDR WaveInHdr;
MMRESULT result;
HWAVEOUT hWaveOut;
WAVEFORMATEX pFormat;
pFormat.wFormatTag = WAVE_FORMAT_PCM;
pFormat.nChannels = 1;
pFormat.nSamplesPerSec = sampleRate;
pFormat.nAvgBytesPerSec = 2 * sampleRate;
pFormat.nBlockAlign = 2;
pFormat.wBitsPerSample = 16;
pFormat.cbSize = 0;
result = waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT);
if(result)
{
char fault[256];
waveInGetErrorTextA(result, fault, 256);
MessageBoxA(NULL, fault, "Failed to open waveform input device.", MB_OK | MB_ICONEXCLAMATION);
return;
}
WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = 2 * NUMPTS;
WaveInHdr.dwBytesRecorded = 0;
WaveInHdr.dwUser = 0;
WaveInHdr.dwFlags = 0;
WaveInHdr.dwLoops = 0;
while (true)
{
waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
result = waveInStart(hWaveIn);
if(result)
{
MessageBoxA(NULL, "Failed to start recording", NULL, MB_OK | MB_ICONEXCLAMATION);
return;
}
// Wait until finished recording
Sleep(seconds * 1000); //Sleep for as long as there was recorded
waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
if (isEmpty(waveIn)) // Checks here
.....
}
}
【问题讨论】:
-
如果真正的问题是编码问题而不是声学问题,您更有可能得到好的答案。您的代码总体上看起来不错,但是 (a) 您如何得出
avg_voice?,以及 (b) 您是否尝试查看在wave[]中收集的值(打印或调试器)? -
很难看出问题所在,因为您发布的代码中没有任何内容说明
wave是如何初始化的。 -
@Arun
avg_voice是我输入的typedef,我只是简单地调试并查看了缓冲区在无效和语音时的平均值,然后手动输入一个数字avg_voice,这就是为什么我认为我的代码不好。 -
@RSahu 我忘了提。缓冲区是一个包含 8000 个短整数单元的数组(这就是缓冲区 -
short int *wave) -
@Amit 在传递给
isEmpty之前是如何初始化的?
标签: c++ audio voip voice-recording