gpt4 book ai didi

c++ - 录音/混音器软件

转载 作者:太空狗 更新时间:2023-10-29 21:23:51 29 4
gpt4 key购买 nike

作为一名吉他手,我一直想开发自己的录音、混音软件。我在 Direct Sound、Windows Multimedia(waveOutOpen 等)方面有一些经验。我意识到这将是一个复杂的项目,但纯粹是为了我自己的使用和学习,即没有截止日期!我打算使用 C++,但我不确定它是最好的 SDK/API。我希望该软件可以扩展,因为我可能希望在将来添加效果。一些先决条件...

  1. 在 Windows XP 上运行
  2. 最小延迟
  3. VU 表(在所有轨道上)这让我回避了 Direct Sound,因为似乎没有办法从主缓冲区读取音频数据。
  4. 配音(即在播放现有轨道的同时录制新轨道)。
  5. 包括一个节拍器

我最初的想法是使用WMM并使用waveOutWrite函数来播放音频数据。我想这本质上是一个音频流播放器。为了尽量简化事情,我将采样率硬编码为 16 位、44.1kHZ(我的声卡支持的最佳采样率)。我需要的是一些想法,对整体架构的指导。

例如,假设我的节奏是 60 BPM,拍号是 4/4。我希望节拍器在每个小节/小节开始时发出咔嗒声。现在假设我已经录制了节奏轨道。播放时,我需要编排(双关语)将哪些数据发送到主声音缓冲区。在某些时候,我可能还想添加乐器、鼓(主要是)。同样,我需要知道如何在正确的时间将正确的音频数据发送到主音频缓冲区。我很欣赏时间在这里的关键。我不确定的是如何从各个音轨中获取正确的数据以发送到主声音缓冲区。

我最初的想法是有一个定时线程,它会定期询问每个轨道,“我需要数据来覆盖 N 毫秒的播放时间”。其中 N 取决于主缓冲区大小。

我明白这是一个复杂的问题,我只需要一些指导来了解我如何处理上述一些问题。

另一个问题是 WMM 或 DirectSound 更适合我的需要。甚至 ASIO?然而,主要问题是如何使用流机制收集正确的轨道数据(来自多个轨道)以发送到主缓冲区,并保持最小延迟?

感谢任何帮助,

非常感谢

卡尔

感谢您的回复。然而,我的主要问题是如何为所有这些计时,以确保每个轨道在正确的时间将适当的数据写入主缓冲区。我当然愿意使用(免费)图书馆,这将帮助我实现我的主要目标。

最佳答案

因为您打算支持 XP(我推荐,因为即使扩展支持也将在明年结束),您真的别无选择,只能使用 ASIO。可以从 Steinberg 下载合适的 SDK。 .在 Windows Vista 及更高版本中 WASAPI Exclusive Mode由于更广泛的可用性,可能是更好的选择,但是 IMO 严重缺乏文档。无论如何,你应该看看 PortAudio这有助于包装这些 API(与 Juce 不同,它是免费的。

WMM、DirectSound 和 XAudio 2 都无法实现足够低的实时监控延迟。低延迟 API 通常会为每个数据 block 定期调用回调。

由于每个回调处理给定数量的样本,您可以根据采样率和样本计数器计算时间(简单地在回调调用中累加)。提示:不要用浮点累加。那就是疯狂。使用 64 位采样计数器,因为最小增量始终是 1./sampleRate

实际上,您的回调函数会(针对每个轨道)调用 getSamples(size_t n, float* out)(或类似的)方法并对结果求和(即混合)。然后,每个单独的轨道都可以有一个集成的采样时间来计算当前需要的时间。对于周期性事物(无限波、循环、节拍器),您可以轻松计算每个周期的样本数并使用模计数器。这将导致圆周期,但如前所述,浮点累加器是禁忌,但它们可以很好地处理周期信号。

在节拍器示例的情况下,您可能有一个带有 n 样本和 m 样本周期的波形“click.wav”。您的计数器会定期从 0 变为 m-1,只要计数器小于 n,您就会播放相应的波形样本。例如,一个简单的节拍器在每个节拍中发出咔哒声,可能看起来像这样:

class Metronome
{
std::vector<float> waveform;
size_t counter, period;

public:
Metronome(std::vector<float> const & waveform, float bpm, float sampleRate) : waveform(waveform), counter(0)
{
float secondsPerBeat = 60.f/bpm; // bpm/60 = bps
float samplesPerBeat = sampleRate * secondsPerBeat;
period = (size_t)round(samplesPerBeat);
}

void getSamples(size_t n, float* out)
{
while(n--)
{
*out++ = counter < waveform.size() ? waveform[counter] : 0.f;
counter += 1;
counter -= counter >= period ? period : 0;
}
}
};

此外,您可以在互联网上查看 VST/AU 插件编程教程,因为这些教程具有从样本数量确定时间的相同“问题”。

关于c++ - 录音/混音器软件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17305654/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com