我正在使用Windows API获取音频输入。我已经按照MSDN上的所有步骤进行操作,并设法将音频录制到WAV文件中。没问题。我正在使用多个缓冲区。我想用缓冲区做更多事情而不是简单地写入文件,所以现在我已经设置了一个回调函数。它工作得很好,而且我正在获取数据,但是一旦我拥有它,我不知道该怎么做。
这是我的回调......这里的一切都有效:
// Media API callback
void CALLBACK AudioRecorder::waveInProc(HWAVEIN hWaveIn, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
// Data received
if (uMsg == WIM_DATA)
{
// Get wav header
LPWAVEHDR mBuffer = (WAVEHDR *)dwParam1;
// Now what?
for (unsigned i = 0; i != mBuffer->dwBytesRecorded; ++i)
{
// I can see the char, how do get them into my file and audio buffers?
cout << mBuffer->lpData[i] << "\n";
}
// Re-use buffer
mResultHnd = waveInAddBuffer(hWaveIn, mBuffer, sizeof(mInputBuffer[0])); // mInputBuffer is a const WAVEHDR *
}
}
// waveInOpen cannot use an instance method as its callback,
// so we create a static method which calls the instance version
void CALLBACK AudioRecorder::staticWaveInProc(HWAVEIN hWaveIn, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
// Call instance version of method
reinterpret_cast<AudioRecorder *>(dwParam1)->waveInProc(hWaveIn, uMsg, dwInstance, dwParam1, dwParam2);
}
就像我说的那样,效果很好,但我正在努力做到以下几点:
我和FMOD一起工作了很多,而且我熟悉交错和所有这些。但FMOD把所有东西都当作花车。在这种情况下,我会走另一条路。我想我基本上只是在寻找有关如何从LPSTR转到short,float和unsigned char的资源。
提前多多谢谢!
答案 0 :(得分:2)
typedef struct {
LPSTR lpData;
// etc..
} WAVEHDR;
Hmya,那里有尴尬的类型。它当然不是STR,应该是PVOID。只需将其转换为您需要的任何类型:
short* data = (short*)(mBuffer->lpData);
unsigned samples = mBuffer->dwBytesRecorded / sizeof(short);
// etc..
答案 1 :(得分:2)
我已经完成了所有这些,但这里有太多信息要详细解释。我建议你看一下source code of PortAudio:这是MME的一个非常好的实现,虽然有些部分有点太乱了,但它包含了你所追求的一切,包括转换。
答案 2 :(得分:2)
将8/16/32位/样本数组转换为浮点数组:
void src_BYTE_to_float_array(const unsigned char* in, float* out, int len)
{
while (len)
{
len--;
out[len]= (float) (in [len] / (1.0 * 0x80) -1.0);
}
}
void src_short_to_float_array(const short* in, float* out, int len)
{
while (len)
{
len--;
out[len]= (float) (in [len] / (1.0 * 0x8000)) ;
}
}
void src_int_to_float_array(const int* in, float* out, int len)
{
while (len)
{
len--;
out[len]= (float) (in [len] / (8.0 * 0x10000000)) ;
}
}
要播放样本,你必须做相反的事情:
void src_float_to_BYTE_array(const float* in, unsigned char* out, int len)
{
double scaled_value;
while (len)
{
len--;
scaled_value= in[len] * (8.0 * 0x10000000);
if (scaled_value >= (1.0 * 0x7FFFFFFF))
{
out[len]= 255;
continue ;
}
out[len]= (unsigned char)((lrint(scaled_value) >> 24) + 0x80);
}
}
void src_float_to_short_array(const float* in, short* out, int len)
{
double scaled_value;
while (len)
{
len--;
scaled_value= in[len] * (8.0 * 0x10000000);
if (scaled_value >= (1.0 * 0x7FFFFFFF))
{
out[len]= 32767;
continue ;
}
out[len]= (short)(lrint(scaled_value) >> 16);
}
}
void src_float_to_int_array(const float* in, int* out, int len)
{
double scaled_value;
while (len)
{
len--;
scaled_value= in[len] * (8.0 * 0x10000000);
if (scaled_value >= (1.0 * 0x7FFFFFFF))
{
out[len]= 0x7fffffff;
continue;
}
out[len]= lrint(scaled_value);
}
}