在 iOS 上使用音频单元混合多个信号

发布于 2024-11-26 23:00:58 字数 494 浏览 1 评论 0 原文

我正在为 iPad 上的合成器制作一个控制器,我有 4 或 5 个信号想要混合并发送到 RemoteIO 渲染回调。现在我有两个选择:

我可以使用多通道混音器单元,但我不知道它内部是如何工作的。它只是将缓冲区加在一起并除以缓冲区的数量吗?因为这意味着每个的体积都会大大减少。

我阅读了 http://www.vttoth.com/digimix.htmhttp://atastypixel.com/blog/how-to-mix-audio-samples-properly-on-ios/ 了解混合信号的正确方法,现在我正在考虑这样做在remoteIO回调中手动混合。

有什么建议吗?

I'm making a controller for a synth on the iPad, and I have 4 or 5 signals that I want to mix and send to the remoteIO render callback . Right now I have two choices:

I can use the multichannel mixer unit but I don't know how it works internally. Does it simply add the buffers together and divide by the number of buffers? Because that would mean the volume for each would be greatly diminished.

I read http://www.vttoth.com/digimix.htm and http://atastypixel.com/blog/how-to-mix-audio-samples-properly-on-ios/ on the proper way to mix signals and am now thinking of doing the mixing manually in the remoteIO callback.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

御守 2024-12-03 23:00:58

正如我最近经历过这个问题并且无论如何,我已经写了一篇详细的文章,介绍在渲染回调中手动混合/求和音频时所拥有的三个选项:

在 iOS 中混合音频而不进行剪辑:
限制器和其他技术

基本上,您引用的博客文章中概述了第一种方法。然而,正如 A Tasty Pixel 的帖子中所述,这种“平均”技术会引入谐波失真。但显然,它在某些应用中并不明显,例如当源是全音轨或基于噪声的打击乐(例如小军鼓)时。据 A Tasty Pixel 报道,专业水准的音频工具 Loopy 应用 成功地使用了这种技术。

如果您有自然的声音和/或高复调音乐,第二个选项可能会更好,它只是通过将音频数据预乘以 0 < 0 来减小音频的音量。 A< 1. 这可能听起来很滑稽,但我相信由于我的博客文章中概述的原因,OpenAL 根据您分配的资源数量做了类似的事情。比例因子不必像您想象的那么低。我的应用程序 Sound Wand 的样本标准化为全音阶,最大复调数为 20,我使用的预缩放值为大约只有 1/3(不是 1/20)。好处是乐器的动态范围非常好 - 即柔和的音符很安静,而坚硬的音符或许多音符组合在一起则声音更大。这通常被认为是优质仪器的标志之一。缺点是 iPhone/iPad 的内置扬声器有时有点安静,而且动态范围对于廉价的外部放大器来说太大了。

第三个选项确实是砖墙限制器,但它并不简单。常规的砖墙限制器不会防止削波。您需要一个前瞻砖墙限制器,并且这些代码不容易获得。您需要先行的原因是限制器需要时间来平滑地降低音量,直到削波首次发生的点。当波形开始削波时“立即减小音量”是不够的,因为减小音量以使其恢复到 1.0 与削波的作用完全相同!因此,非先行限制器只会删除剪辑的一半(并且只是因为释放时间)。

没有“前瞻”的砖墙限制启动得太晚,只能阻止一半的剪辑

(没有“前瞻”的砖墙限制“启动得太晚,只能阻止一半的剪辑)

前瞻限制器也有缺点。它们引入了自己的谐波失真,尽管比削波要少得多。更糟糕的是,它们会增加延迟,即用户操作和音频输出之间的时间,即前瞻时间。这意味着应用程序的响应速度较慢。正如您可能已经猜到的,更长的前瞻意味着更透明的结果(更少的失真),因此需要权衡。我仍然相信这是可行的方法,我在 帖子

关于使用 AU 混音器与在 RemoteIO 中手动混音的最后一点:如果我的通道就像音频“轨道”并且我希望通常的音量/声相由用户控制,那么我通常更倾向于使用 AU或者,如果您的游戏有几个频道,可能用于背景/前景/等。如果您有很多声音,例如键盘上的音符,或者您想要对求和进行定制控制(例如不同的平移法则、关于哪些声音打开/关闭的特殊规则等),您可能最好手动进行。如果您只是对几个音轨进行求和,那么任何一个选项都可以。如果您选择上面的选项 2,一旦您开始使用 加速框架的 vDSP 功能

As I've recently been through this very issue and have been meaning to anyway, I've written a detailed post about three of the options you have when manually mixing/summing audio in your render callback:

Mixing Audio without Clipping in iOS:
Limiters and Other Techniques

Basically, the first method is outlined in the blog posts you've referenced. However as stated in A Tasty Pixel's post, this "averaging" technique introduces harmonic distorion. Apparently though, it's not noticeable in certain applications, like when the sources are full tracks or noise-based percussion (e.g. snare drums). According to A Tasty Pixel, Loopy app, a professional calibre audio tool, uses this technique successfully.

The second option, which is perhaps better if you have natural sounds and/or high polyphony, is simply to scale down the volume of the audio by pre-multiplying the audio data by 0 < A < 1. It might sound facetious but I believe for reasons outlined in my blog post that OpenAL does something similar to this based on how many sources you allocate. The scale factor needn't be as low as you might think. My app, Sound Wand, has samples normalised to full scale and a max polyphony of 20 and I use a pre-scale value of only about 1/3 (not 1/20). The upside is a very nice dynamic range in your instrument - i.e. soft notes are quiet and hard ones or lots of them together are much louder. This is often considered one of the hallmarks of a quality instrument. The downside is that it is a bit quiet at times on the iPhone/iPad's built in speaker and the dynamic range can be too much for cheap external amplifiers.

The third option is indeed the brickwall limiter but there is nothing simple about it. A regular brickwall limiter will NOT prevent clipping. You need a lookahead brickwall limiter and code for these is not readily available. The reason you need the lookahead is that the limiter needs time to smoothly decrease the volume up until the point that clipping first occurs. It is not enough to "reduce volume immediately" when the waveform begins to clip because reducing the volume to bring it back to 1.0 is the exact same thing that clipping does for you! As a result, non-lookahead limiters will only remove half the clip (and that only because of the release time).

Brickwall limiting without "lookahead" kicks in too late and only prevents half the clip

(Brickwall limiting without "lookahead" kicks in too late and only prevents half the clip)

There are drawbacks with lookahead limiters as well. They introduce there own harmonic distortion, though much less than clipping. Worse is that they increase the latency, the time between a user's action and the audio outcome, by the lookahead time. This means a less responsive app. As you might have guessed, a longer lookahead means a more transparent outcome (less distortion) so there is a tradeoff. I still believe this to be viable method and I outline it a bit at the bottom of the post.

One final note with regards to using the AU mixer versus manually mixing in remoteIO: I'd generally be more inclined to use the AU if my channels are like audio "tracks" and I want the usual volume/pan to be controlled by the user or if you have a game with a few channels perhaps for background/foreground/etc. If you have a lot of sounds, like notes on a keyboard, or if you want bespoke control over the summing (e.g. different pan laws, special rules about which sounds are on/off, etc) you might be better doing it manually. If you are just summing a couple audio tracks than really either option will do. If you go with option 2 above, doing it manually actually takes very fews lines of code once you've gotten your hands into the Accelerate Framework's vDSP functions.

寄人书 2024-12-03 23:00:58

Apple 发布了 示例项目在他们的网站上使用了混音器音频单元,但我认为这不会回答您有关 AU 内部如何工作的问题。我也不知道,但按照惯例,信号在混合时只是简单地相加在一起。事实上,混音器单元现在提供平移,这意味着根据平移量,从左通道或右通道中减去一点增益。

如果您手动进行混音,您可能需要在混音器的输出上应用一个简单的砖墙限制器,然后再将其发送出去进行播放。这样您就可以减少因将太多信号添加在一起而导致的潜在失真。显然,如果您有很多通道,理想的方法是在混音时降低它们的信号强度。

Apple has published a sample project which uses the mixer audiounit on their website, but I don't think that will answer your questions about how the AU works internally. I don't know either, but the convention dictates that the signals are simply added together when they are mixed. The fact that the mixer unit now provides panning means that a bit of gain is subtracted from either the left or right channel depending on the panning amount.

If you do the mixing manually, you might want to apply a simple brickwall limiter on your mixer's output before sending it off for playback. That way you can reduce the potential distortion caused by adding too many signals together. Though obviously, if you have a lot of channels the ideal approach is to decrease their signal strength when mixing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文