使用 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 混合音频的主要内容,如果未能解决你的问题,请参考以下文章