使用 OpenGL 混合音频

Posted

技术标签:

【中文标题】使用 OpenGL 混合音频【英文标题】:Mixing Audio Using OpenGL 【发布时间】:2010-12-15 14:50:18 【问题描述】:

我想使用 OpenGL 混合两个(或更多)16 位音频流,我需要一些帮助

基本上我想做的是将音频数据放入纹理中,然后将其绘制到帧缓冲区对象中,然后再读回。这不是问题,但是以给出正确结果的方式绘制数据有点问题。

我基本上有两个问题。

    为了通过绘图混合数据,我需要使用混合 (alpha = 0.5),但是结果不应有任何 alpha 通道。所以如果我渲染到例如格式为 RGB 的帧缓冲区是否会像我预期的那样进行 alpha 混合,并且生成的 alpha 不会被写入 fbo? (我想避免每次渲染过程都必须回读 fbo)

纹理 |sR|sG|sB|

帧缓冲(之前)|dR|dG|dB|

帧缓冲区(之后) |dR*0.5+sR*0.5|dG*0.5+sG*0.5|dB*0.5+sB*0.5|

    音频样本是带符号的 16 位整数值。是否可以通过这种方式进行签名计算?还是我需要先在 cpu 上将这些值转换为无符号,然后绘制它们,然后再在 cpu 上使它们重新签名?

编辑:

我有点不清楚。我的硬件仅限于 OpenGL 3.3 硬件。我宁愿不使用 CUDA 或 OpenCL,因为我一直在使用 OpenGL 来处理其他东西。

每个音频样本都将在单独的通道中渲染,这意味着它必须与已经渲染到帧缓冲区的内容“混合”。问题是如何将像素着色器的输出写入帧缓冲区(据我所知,这种混合无法通过可编程着色器访问,并且必须使用 glBlendFunc)。

EDIT2:

每个音频样本将在不同的通道中渲染,因此着色器中一次只有一个音频样本可用,这意味着它们需要在 FBO 中累积。

foreach(var audio_sample in audio_samples)
     draw(audio_sample);

不是

for(int n = 0; n < audio_samples.size(); ++n)

      glActiveTexture(GL_TEXTURE0 + n);
      glBindTexture(audio_sample);

draw_everything();

【问题讨论】:

【参考方案1】:

坦率地说,您为什么不直接使用可编程像素着色器呢?

您必须使用 OpenGL 1 固定功能管道吗?

我会选择在有符号的 16 位灰度线性纹理上运行的可编程着色器。

编辑:

foreach(var audio_sample in audio_samples) 
 blend FBO1 + audio_sample => FBO2
 swap FBO2, FBO1 

它应该同样快,如果不是更快的话(多亏了流式管道)。

【讨论】:

像素着色器可能会有用。但是,问题是我如何将像素着色器的结果正确写入帧缓冲区,因为它“应该”与帧缓冲区中已有的内容混合。也许我有点不清楚。但是每个“音频样本”将在单独的通道中呈现。所以我只能在着色器中访问它。 您可以将像素着色器渲染到 PBO 或 FBO 中,而无需担心 PBO 的 Alpha 通道(您可以禁用它们并直接通过着色器混合两个纹理) 是的,但我无法访问着色器中的多个纹理,因为每个音频样本将在不同的通道中渲染。他们需要在FBO中通过传递累积。 您肯定是从非标准角度处理问题。我想你可以做弹跳 - 从一个 FBO 渲染到另一个 FBO 并交换,每次传递。 +1,这是一个很好的建议,似乎符合 OP 的要求。,【参考方案2】:

我同意 QDot。但是,您能否告诉我们一些您面临的硬件限制?如果您有合理的现代硬件,我什至建议您使用 CUDA 或 OpenCL 路线,而不是通过 OpenGL。

【讨论】:

是否有真正令人信服的理由通过 OpenGL?您是否需要与特定的东西交互? 好吧,主要原因是我不想在没有必要的情况下添加另一个依赖项......仅仅为此而涉及 OpenCL 似乎是不合理的......特别是如果我能做到在我的项目中广泛使用的 OpenGL 工作。【参考方案3】:

    即使目标缓冲区没有 alpha,您也应该能够进行混合。也就是说,渲染到非二次方大小(rgb16 = 6 字节/像素)通常会导致性能损失。

    签名不是典型的渲染目标格式,但它确实存在于 OpenGL 4.0 规范中(表 3.12,称为 RGB16_SNORM 或 RGB16I,取决于您是否需要标准化表示)。

附带说明,您还拥有glBlendFunc(GL_CONSTANT_ALPHA,GL_ONE_MINUS_CONSTANT_ALPHA),甚至不必指定每个像素的 alpha。不过,这可能不适用于所有 GL 实现。

【讨论】:

以上是关于使用 OpenGL 混合音频的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 在单色上混合颜色

◮OpenGL-混合

opengl:混合跨平台的结果不一致

OpenGL 多纹理混合

重构复杂的 opengl 混合

在 OpenGL 4.6 中没有适合我的 alpha 混合