Привет всем, я пишу приложение, которое записывает вход микрофона в файл WAV. Ранее я написал это, чтобы заполнить буфер указанного размера, и это работало нормально. Теперь я хотел бы иметь возможность записи произвольной длины. Вот что я пытаюсь сделать:
- Настройка 32 небольших аудио буферов (круговая буферизация)
- Запустите WAV-файл с помощью ofstream - напишите заголовок с длиной PCM, установленной в 0
- Добавить буфер для ввода
- Когда буфер завершит работу, добавьте его данные в файл WAV и обновите заголовок; перезапустить буфер
- Когда пользователь нажимает «стоп», записать оставшиеся буферы в файл и закрыть
Это работает в том смысле, что файлы выходят с правильной длиной (заголовок и размер файла и являются правильными). Тем не менее, данные чертовски сомнительны. Я могу разобрать видимость того, что я сказал - и время выбрано правильно - но есть этот повторяющийся блок искажений. По сути, похоже, что только половина данных попадает в файл.
Вот некоторые переменные, которые использует код (в заголовке)
// 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;
}
Если здесь есть что-то, что может привести к добавлению в файл неверных данных, пожалуйста, дайте мне знать. Если нет, я проверю трижды входные данные (в обратном вызове). Эти данные должны быть хорошими, потому что они работают, если я скопирую их в больший буфер (например, две минуты), а затем сохраню.