首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >录音/混频器软件

录音/混频器软件
EN

Stack Overflow用户
提问于 2013-06-25 19:16:28
回答 2查看 1.7K关注 0票数 3

作为一名吉他手,我一直想开发自己的录音,混合软件。我有一些直接声音,视窗多媒体(waveOutOpen等)的经验。我意识到这将是一个复杂的项目,但纯粹是为了我自己的使用和学习,即没有最后期限!我打算使用C++,但到目前为止还不确定是否可以使用最好的SDK/API。我希望软件是可扩展的,因为我可能希望在未来添加效果。一些先决条件..。

  1. 在Windows上运行
  2. 最小延迟
  3. VU计量器(在所有轨道上),这使我害羞的直接声音,因为似乎没有一种方式读取音频数据从主缓冲区。
  4. 重配音(即在播放现有曲目时录制一首新曲目)。
  5. 包括节拍器

我最初的想法是使用WMM并使用waveOutWrite函数来播放音频数据。我想这基本上是一个音频流播放器。为了让事情变得更简单,我将把采样率硬编码到16位,44.1kHZ (我的声卡支持的最佳采样率)。我需要的是一些关于整体架构的想法和指导。

例如,假设我的节奏为60 BPM,时间签名为4/4,我希望节拍器在每个小节/度量值开始时按一下。现在假设我录制了一段节奏曲目。在播放时,我需要编排(双关意)什么数据被发送到主声音缓冲区。我也可能在某个时候,想要增加乐器,鼓(主要)。同样,我需要知道如何在正确的时间将正确的音频数据发送到主音频缓冲区。我很感激时间是这里的关键。我不确定的是,如何从单个音轨中获取正确的数据,以发送到主声音缓冲区。

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

我理解这是一个复杂的问题,我只需要就如何处理上述一些问题提供一些指导。

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

任何帮助都是感激的,

非常感谢

卡尔

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-25 19:39:52

由于您打算支持XP (我不建议支持XP,因为扩展的支持也将在明年结束),您真的别无选择,只能使用ASIO。可以从斯坦伯格下载适当的SDK。在Windows及以上版本,WASAPI排他模式可能是一个更好的选择,因为更广泛的可用性,但文件严重缺乏海事组织。无论如何,您应该看看PortAudio,它有助于包装这些API(与朱斯不同的是,它是免费的)。

WMM、DirectSound和XAudio 2都无法实现足够低的实时监视延迟。低延迟API通常会周期性地对每个数据块调用回调。

当每个回调处理给定数量的样本时,您可以从采样率和一个示例计数器中计算时间(只需在回调呼叫中累积)。提示:不要用浮点累积。这种方式是疯狂的。使用64位示例计数器,因为最小的增量总是1./sampleRate

有效地,您的回调函数(对于每个轨道)将调用一个getSamples(size_t n, float* out) (或类似的)方法,并总结结果(即混合结果)。然后,每个轨道都有一个完整的样本时间来计算当前所需的内容。对于周期性事物(无限波、循环、节拍器),您可以很容易地计算每个周期的样本数,并且有一个模计数器。这将导致圆形周期,但正如前面提到的,浮点累加器是不-不,它们可以正常工作的周期信号,尽管。

在节拍器示例中,您可能有一个带有click.wav样本的波形“m”和一个周期的m样本。您的计数器周期性地从0m-1,只要计数器小于n,就会播放相应的波形样本。例如,一个简单的节拍器,按一下每一个节拍,可能如下所示:

代码语言:javascript
运行
复制
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插件编程教程,因为这些教程具有从样本数量确定时间的“问题”。

票数 2
EN

Stack Overflow用户

发布于 2013-06-25 19:31:03

正如你所发现的,你正在进入一个痛苦的世界。如果您确实在为Windows构建音频软件,并且期望较低的延迟时间,那么您肯定希望避免操作系统提供的任何音频API,并像几乎所有商业软件一样使用ASIO。虽然情况有所好转,但ASIO无论如何也不会在短期内取得进展。

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

他们已经涵盖了许多非常恶劣的架构风险,并且提供了主机应用程序和插件的示例。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17305654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档