录音/混音器软件

Audio Recording/Mixer Software

本文关键字:软件 混音器 录音      更新时间:2023-10-16

作为一名吉他手,我一直想开发自己的录音、混音软件。我在Direct Sound、Windows多媒体(waveOutOpen等)方面有一些经验。我意识到这将是一个复杂的项目,但纯粹是为了我自己的使用和学习,即没有截止日期!我打算使用C++,但还不确定它是最好的SDK/neneneba 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?然而,主要的问题是,使用流机制,我如何收集正确的轨道数据(来自多个轨道)发送到主缓冲区,并保持最小的延迟?

感谢您的帮助,

非常感谢

Karl

感谢您的回复。然而,我的主要问题是如何对所有这些进行计时,以确保每个磁道在正确的时间将适当的数据写入主缓冲区。我当然对(免费)图书馆持开放态度,这将帮助我实现我的主要目标。

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

无论是WMM、DirectSound还是XAudio 2都无法实现足够低的延迟来进行实时监控。低延迟API通常会定期为每个数据块调用回调。

由于每个回调都处理给定数量的样本,因此可以根据采样率和样本计数器计算时间(只需在回调调用中累积)。提示:不要用浮点进行累加。这种方式是疯狂的。使用64位采样计数器,因为最小增量总是1./sampleRate

实际上,您的回调函数会(针对每个音轨)调用getSamples(size_t n, float* out)(或类似的)方法,并对结果进行汇总(即混合它们)。然后,每个单独的轨道都可以有一个集成的采样时间来计算当前所需的时间。对于周期性的东西(无限波、循环、节拍器),你可以很容易地计算每个周期的样本数量,并有一个模计数器。这将导致四舍五入的周期,但如前所述,浮点累加器是不可以的,尽管它们可以对周期性信号正常工作。

在节拍器示例的情况下,您可能会有一个波形"click.wav",其中包含n采样和一个周期的m采样。计数器周期性地从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插件编程教程,因为这些教程在根据样本数量确定时间方面存在相同的"问题"。

正如您所发现的,您正在进入一个痛苦的世界。如果你真的在为Windows XP构建音频软件并期望低延迟,你肯定会想避免操作系统提供的任何音频API,像几乎所有的商业软件一样使用ASIO。虽然情况有所好转,但ASIO不会很快采取行动。

为了大大减轻你的痛苦,我建议你看看Juce,它是一个用于构建音频主机软件和插件的跨平台框架。它被用于制造许多商业产品。

他们已经涵盖了许多非常恶劣的体系结构危害,并提供了主机应用程序和插件的示例。