使用 OpenAL 保存到音频文件

问题描述 投票:0回答:1

我正在使用 OpenTK,更准确地说是 OpenAL。我能够从麦克风捕获声音,但随后我想将数据保存到 WAVE 文件中。

我找到了一个如何编写波形文件的示例,结果几乎可以工作。

我相信我的文件头是正确的,但我对将缓冲区数据写入文件的正确方法有些怀疑。

我第一次尝试使用此设置进行录制:

  • 44100 赫兹
  • 16位
  • 2 个频道

播放文件只是一些噪音

我更改为单声道设置(1 通道)。 这次我能够再现音频,但播放速度快了 2 倍

我是否应该先转换 ALC.CaptureSamples 中的数据,然后再将其直接写入流?

要添加一些代码,首先我有捕获样本,我认为它可以正常工作(我从 OpenAL 存储库的 TestUnit 中获得):

int totalSamples = 0;
while (totalSamples < buffer.Length && !_cancellationToken.IsCancellationRequested)
{
  int samplesAvailable = ALC.GetInteger(_captureDevice, AlcGetInteger.CaptureSamples);
  if (samplesAvailable < 512) continue;
  int samplesToRead = Math.Min(samplesAvailable, buffer.Length - totalSamples);
  ALC.CaptureSamples(_captureDevice, ref buffer[totalSamples], samplesToRead);
  totalSamples += samplesToRead;
  spinWait.SpinOnce();
}

然后我简单地写入流:

// headers writing...
// ...
sw.Write(buffer, 0, totalSamples);

我没有找到任何有关 OpenAL 和文件写入的示例...
一切都正确吗?
我错过了一些步骤吗?

c# audio wav opentk openal
1个回答
0
投票

好的@fdcpp 给了我一个提示,但没有编写完整的示例。因此,为了使其正常工作,对于单声道 16 位声音,缓冲区应该是

ushort
而不是
byte
类型。

缺少一些关于声音音频规格的知识😔

所以代码的具体部分是:

// Capture the device
_captureDevice = ALC.CaptureOpenDevice(null, 44100, ALFormat.Mono16, 1024);
...
// Start recording
var buffer = new ushort[44100 * 16];
...
// Writing data
ushort bytePerBloc = 1 * (16 / 8);
using (MemoryStream memoryStream = new())
using (BinaryWriter sw = new(memoryStream))
{
  sw.Write(['R', 'I', 'F', 'F']);
  sw.Write(totalSamples * bytePerBloc + 36);
  ...
  sw.Write(['d', 'a', 't', 'a']);
  sw.Write(totalSamples * bytePerBloc); // size of buffer

  for (int i = 0; i < totalSamples; i++)
  {
    sw.Write(buffer[i]);
  }
...
}

现在它正在工作。

下一步尝试使用立体声 16 位进行相同的操作 😅

© www.soinside.com 2019 - 2024. All rights reserved.