实时录制/将音频数据转换为 WAV

2024-04-19

我在音频信号处理方面是新手。

目前,我已将设备连接到我的电脑,该电脑从麦克风/播放轨道向我发送音频数据。我已经使用 Steinberg ASIO SDK 2.3 创建了主机应用程序,该应用程序连接到设备并在重复回调中返回原始数据。信号是 24 位,频率可以选择任何我喜欢的,比如说 44100 hZ、2pan's、单通道。我已将此信号也转换为 double 因为我正在对其进行一些信号处理。

我现在想做的是为我的主机添加录音功能。例如,单击按钮时,传入的数据会不断转换为 WAV 文件,当我单击其他按钮时,它会停止并保存。

我已经阅读过有关 WAV 文件、文件格式、比特流格式 (RIFF) 的内容,并且对 WAV 文件的外观有一个总体了解。我还检查了很多论坛帖子、stackoverflow 的帖子或代码项目帖子,到处都找到了与主题相关的内容,但我不知道如何实时进行持续录制。我发现的很多代码都是关于在对其进行修改后将数据数组转换为 WAV 的。我想进行持续的转换并使 WAV 文件附加/扩展,直到我告诉它停止。

例如,我可以以某种方式修改它吗?

#include <fstream>

template <typename T>
void write(std::ofstream& stream, const T& t) {
  stream.write((const char*)&t, sizeof(T));
}

template <typename T>
void writeFormat(std::ofstream& stream) {
  write<short>(stream, 1);
}

template <>
void writeFormat<float>(std::ofstream& stream) {
  write<short>(stream, 3);
}

template <typename SampleType>
void writeWAVData(
  char const* outFile,
  SampleType* buf,
  size_t bufSize,
  int sampleRate,
  short channels)
{
  std::ofstream stream(outFile, std::ios::binary);
  stream.write("RIFF", 4);
  write<int>(stream, 36 + bufSize);
  stream.write("WAVE", 4);
  stream.write("fmt ", 4);
  write<int>(stream, 16);
  writeFormat<SampleType>(stream);                                // Format
  write<short>(stream, channels);                                 // Channels
  write<int>(stream, sampleRate);                                 // Sample Rate
  write<int>(stream, sampleRate * channels * sizeof(SampleType)); // Byterate
  write<short>(stream, channels * sizeof(SampleType));            // Frame size
  write<short>(stream, 8 * sizeof(SampleType));                   // Bits per sample
  stream.write("data", 4);
  stream.write((const char*)&bufSize, 4);
  stream.write((const char*)buf, bufSize);
}

并以某种方式回调:

writeWAVData("mySound.wav", mySampleBuffer, mySampleBufferSize, 44100, 1);

我很感激任何提示/链接/建议/形式的帮助。


您的用例和您在线看到的代码之间的区别在于,在您的用例中,您事先不知道文件将持续多长时间,因为您不知道用户何时会按停止按钮。

处理此问题的方法是首先像往常一样写出 WAV 标头,但现在不必担心为文件大小特定字段写入的值(即“RIFF”后面的字段和“数据”)。您现在可以将这些字段设置为零。

然后在收到音频样本时写出它们,即将它们附加到文件末尾。

最后,在用户按下停止键并且您即将关闭文件后,您需要返回并使用正确的值覆盖这两个标头字段。您现在可以执行此操作,因为此时您知道写入文件的音频数据有多少字节。完成此操作后,该文件应该格式正确且可用。您可以使用例如ofstream::seekp(fieldOffset, ios_base::beg) http://www.cplusplus.com/reference/ostream/ostream/seekp/查找从文件顶部到您需要修改的字段的适当偏移量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实时录制/将音频数据转换为 WAV 的相关文章

随机推荐