大家好,我正在编写一个将麦克风输入记录到 WAV 文件的应用程序。以前,我写过这个来填充指定大小的缓冲区并且工作正常。现在,我希望能够记录到任意长度。这是我正在尝试做的事情:
- 设置32个小音频缓冲区(循环缓冲)
- 使用 ofstream 启动一个 WAV 文件——写入 header ,PCM 长度设置为 0
- 为输入添加一个缓冲区
- 当缓冲区完成时,将其数据附加到 WAV 文件并更新标题;回收缓冲区
- 当用户点击“停止”时,将剩余的缓冲区写入文件并关闭
它的工作原理是文件的长度正确(标题和文件大小都是正确的)。然而,数据非常不稳定。我可以辨认出我所说的内容——而且时间是正确的——但是有这种重复的失真 block 。基本上听起来只有一半的数据进入了文件。
这是代码使用的一些变量(在标题中)
// File writing
ofstream mFile;
WAVFILEHEADER mFileHeader;
int16_t * mPcmBuffer;
int32_t mPcmBufferPosition;
int32_t mPcmBufferSize;
uint32_t mPcmTotalSize;
bool mRecording;
这是准备文件的代码:
// Start recording audio
void CaptureApp::startRecording()
{
// Set flag
mRecording = true;
// Set size values
mPcmBufferPosition = 0;
mPcmTotalSize = 0;
// Open file for streaming
mFile.open("c:\my.wav", ios::binary|ios::trunc);
}
这是接收缓冲区的代码。这假设传入数据是正确的 - 应该是正确的,但我不排除它不是正确的。
// Append file buffer to output WAV
void CaptureApp::writeData()
{
// Update header with new PCM length
mPcmBufferPosition *= sizeof(int16_t);
mPcmTotalSize += mPcmBufferPosition;
mFileHeader.bytes = mPcmTotalSize + sizeof(WAVFILEHEADER);
mFileHeader.pcmbytes = mPcmTotalSize;
mFile.seekp(0);
mFile.write(reinterpret_cast<char *>(&mFileHeader), sizeof(mFileHeader));
// Append PCM data
if (mPcmBufferPosition > 0)
{
mFile.seekp(mPcmTotalSize - mPcmBufferPosition + sizeof(WAVFILEHEADER));
mFile.write(reinterpret_cast<char *>(&mPcmBuffer), mPcmBufferPosition);
}
// Reset file buffer position
mPcmBufferPosition = 0;
}
这是关闭文件的代码:
// Stop recording
void CaptureApp::stopRecording()
{
// Save remaining data
if (mPcmBufferSize > 0)
writeData();
// Close file
if (mFile.is_open())
{
mFile.flush();
mFile.close();
}
// Turn off recording flag
mRecording = false;
}
如果此处有任何内容看起来会导致错误数据附加到文件中,请告诉我。如果没有,我将三次检查输入数据(在回调中)。此数据应该很好,因为如果我将它复制到更大的缓冲区(例如,两分钟)然后保存它,它就可以工作。
最佳答案
我只是想知道,怎么办
void CaptureApp::writeData()
{
mPcmBufferPosition *= sizeof(int16_t); // mPcmBufferPosition = 0, so 0*2 = 0;
// (...)
mPcmBufferPosition = 0;
}
有效(顺便说一句。sizeof int16_t
始终为 2)。你在别的地方设置 mPcmBufferPosition 吗?
void CaptureApp::writeData()
{
// Update header with new PCM length
long pos = mFile.tellp();
mPcmBufferBytesToWrite *= 2;
mPcmTotalSize += mPcmBufferBytesToWrite;
mFileHeader.bytes = mPcmTotalSize + sizeof(WAVFILEHEADER);
mFileHeader.pcmbytes = mPcmTotalSize;
mFile.seekp(0);
mFile.write(reinterpret_cast<char *>(&mFileHeader), sizeof(mFileHeader));
mFile.seekp(pos);
// Append PCM data
if (mPcmBufferBytesToWrite > 0)
mFile.write(reinterpret_cast<char *>(mPcmBuffer), mPcmBufferBytesToWrite);
}
另外mPcmBuffer
是一个指针,不知道为什么要在write中使用&
。
关于c++ - 使用 ofstream 写入二进制数据时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4972810/