iPad 鼓电脑触摸 -> 音频延迟

发布于 2024-12-23 08:10:57 字数 795 浏览 7 评论 0原文

我们为 iPad 构建了一款鼓机应用程序,可以与现场音乐一起演奏(在舞台上或在卧室中)。设置非常基本:您按下其中一个按钮,就会播放相应的样本。一切都运行得非常顺利,但不幸的是,在你放下手指的那一刻和声音播放之间似乎有一个很小的(尽管烦人的)延迟。我尝试测量延迟量(通过耳朵),似乎是 0.05 - 0.1 秒。

音频播放是使用AudioToolbox框架(扩展音频文件服务,音频单元)实现的。声音从存储在设备上的文件中传输,以防止不同音库之间的加载时间。样本采用原始 wav 格式(线性 PCM、16 位小端有符号整数、2 通道、44100 Hz),据我所知,这应该是处理速度最快的(与 mp3 等压缩格式相反)。

我测量了按下按钮(UIButton 触摸事件)和将示例的第一帧传送到混音器(通过播放回调)之间的时间。它相当稳定,在0.02到0.03秒之间。对我来说,这似乎相当快,但可能还不够快。

这可能是问题所在,还是可能是其他原因,例如触摸事件传递延迟?

更新:

按照 Till 的建议,我重写了示例的加载。它们现在都已预加载到内存中,因此磁盘 IO 不再是问题。最重要的是,我做了相当多的 memcpy 来实现回声效果,我已经禁用了它,稍后将使用链接列表类型的解决方案来修复它。

尽管这减少了延迟,但按钮按下 -> 播放仍然需要 0.005 到 0.02 秒(但更常见的是 0.02 秒)。这一点仍然值得注意。我认为这可能是由于播放回调的缓冲区大小所致,当前为 1024 字节。

关于如何做到这一点有什么想法吗?设置 kAudioUnitProperty_MaximumFramesPerSlice 似乎不起作用。

We've built a drumcomputer app for iPad to play along with live music (on stage or in your bedroom). The setup is pretty basic: you press one of the buttons and the corresponding sample will play. Everything works pretty smoothly, but unfortunately there appears to be a small (though annoying) latency between the moment you put your finger down and the playback of the sound. I've tried to measure the amount of latency (by ear), it seems to be something like 0.05 - 0.1 seconds.

The audio playback has been implemented using the AudioToolbox framework (Extended Audio File Services, Audio Units). The sounds are streamed from file, which are stored on the device, to prevent loading times between different soundbanks. Samples are in raw wav format (Linear PCM, 16 bit little-endian signed integer, 2 channels, 44100 Hz), which should be the fastest to process as far as I understand (opposed to something compressed like mp3).

I've measured the time between the button press (UIButton touch event) and the delivery of the first frames of the sample to the mixer (through the playback callback). It is quite stable and between 0.02 to 0.03 seconds. To me this seems pretty fast, but it might not be fast enough.

Could that be the problem or might it be something else like a delay in the delivery of touch events?

UPDATE:

As suggested by Till, I've rewritten the loading of the samples. They are now all preloaded into memory, so disk IO is no longer an issue. On top of that I was doing quite a bit of memcpy for an echo effect, I've disabled it and will fix that later with a linked list kind of solution.

Though this reduces the latency, button press->playback still measures between 0.005 to 0.02 seconds (but more often like 0.02). This is still noticeable. I'm thinking this might be due to the buffer size of the playback callback, which is currently 1024 bytes.

Any ideas on how to do that? Setting kAudioUnitProperty_MaximumFramesPerSlice doesn't seem to work.

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

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

发布评论

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

评论(2

老子叫无熙 2024-12-30 08:10:57

我通过指定首选硬件 I/O 缓冲区持续时间解决了延迟问题,如 音频会话食谱

NSTimeInterval preferredBufferDuration = 0.005;
[audioSession setPreferredIOBufferDuration:preferredBufferDuration error:&audioSessionError];

if (audioSessionError != nil) 
{
    NSLog (@"Error setting preferred buffer duration.");
    return;
}

通过将缓冲区持续时间设置为 0.005,您的应用程序只需在每个周期提供 256 字节(44Khz)。这(显然)将延迟从 0.02 减少到 0.005,但音频必须以更快的速率产生。

即使从磁盘读取 IO,iPad 2 也能完美应对这种速度。不幸的是,第一代 iPad 的速度不够快(有和没有磁盘 IO),所以我希望能找到一些方法来区分两者,并为 iPad 1 提供更多的延迟以获得更好的性能。

I solved the latency problem by specifying the preferred hardware I/O buffer duration, as stated in the Audio Session Cookbook

NSTimeInterval preferredBufferDuration = 0.005;
[audioSession setPreferredIOBufferDuration:preferredBufferDuration error:&audioSessionError];

if (audioSessionError != nil) 
{
    NSLog (@"Error setting preferred buffer duration.");
    return;
}

By setting the buffer duration to 0.005, your application will only have to supply 256 bytes (at 44Khz) on each cycle. This (obviously) reduces the latency from 0.02 to 0.005, but audio will have to be produced at a faster rate.

The iPad 2 is perfectly able to cope with this speed, even when the IO is read from disk. The first generation iPad is not fast enough unfortunately (with and without disk IO) so I hope I can find some way to distinguish the two and give the iPad 1 a bit more latency for better performance.

荭秂 2024-12-30 08:10:57

您可以将仪器与 TimeProfiler 一起使用 (Apple Documentation on Instruments) 模板来准确找出哪些方法需要大量运行。运行时,请务必取消选中“Invert Call Tree”选项并选中“Hide System Libraries”。

You could use Instruments with the TimeProfiler (Apple Documentation on Instruments) template to find out exactly what methods take to much to run. When running, be sure to uncheck the "Invert Call Tree" option and to check "Hide System Libraries".

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