有效的方法来画一条线与数百万个点 [英] Efficient method to draw a line with millions of points

查看:241
本文介绍了有效的方法来画一条线与数百万个点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写在可可具有广泛的缩放选项的音频波形编辑器。在其最广泛的,它显示了整首歌曲(约10万个样本中的视图)的波形。在其最窄,它表示声波(约1个样本在一个视图)的像素精确的重新presentation。我希望能够将这些缩放级别之间的平稳过渡。像Ableton现场一些商业的编辑似乎为此在一个非常便宜的方式。

I'm writing an audio waveform editor in Cocoa with a wide range of zoom options. At its widest, it shows a waveform for an entire song (~10 million samples in view). At its narrowest, it shows a pixel accurate representation of the sound wave (~1 thousand samples in a view). I want to be able to smoothly transition between these zoom levels. Some commercial editors like Ableton Live seem to do this in a very inexpensive fashion.

我的当前实现满足我的需要的变焦范围,但效率低下且不稳定。该设计主要是这个优秀的文章与石英绘制波形启发:

My current implementation satisfies my desired zoom range, but is inefficient and choppy. The design is largely inspired by this excellent article on drawing waveforms with quartz:

http://supermegaultragroovy.com/blog/2009/10/06 /拉丝-波形/

我创建多个CGMutablePathRef对各级减少的音频文件。当我放大所有的出路,我用的是每的X个样本减少到一个点的路径。当我在一路放大,我用一个包含每个样本点的路径。我水平扩展的路径时,我降低水平之间要启用。这得到它的功能,但仍是pretty昂贵和减少各级之间转换时工件出现。

I create multiple CGMutablePathRef's for the audio file at various levels of reduction. When I'm zoomed all the way out, I use the path that's been reduced to one point per x-thousand samples. When I'm zoomed in all the way in, I use that path that contains a point for every sample. I scale a path horizontally when I'm in between reduction levels. This gets it functional, but is still pretty expensive and artifacts appear when transitioning between reduction levels.

这是我会如何让这个更便宜的一个想法是采取了抗锯齿。在我的编辑波形抗锯齿,而一个在Ableton公司是不是(见下面的比较)。

One thought on how I might make this less expensive is to take out anti-aliasing. The waveform in my editor is anti-aliased while the one in Ableton is not (see comparison below).

我不明白的方式来关闭抗锯齿CGMutablePathRef的。是否有一个非抗锯齿替代CGMutablePathRef可可的世界呢?如果没有,有没有人知道一些OpenGL的类或样品code,可能让我在课程上更有效地拉起巨大的线?

I don't see a way to turn off anti-aliasing for CGMutablePathRef's. Is there a non-anti-aliased alternative to CGMutablePathRef in the world of Cocoa? If not, does anyone know of some OpenGL classes or sample code that might set me on course to drawing my huge line more efficiently?

更新2014年1月21日:现在有一个伟大的库,不正是我一直在寻找:的 https://github.com/syedhali/EZAudio

Update 1-21-2014: There's now a great library that does exactly what I was looking for: https://github.com/syedhali/EZAudio

推荐答案

我使用CGContextMoveToPoint + CGContextAddLineToPoint + CGContextStrokePath在我的应用程序。屏幕上每一点一点绘制使用总览中的pre计算的后盾缓冲区。该缓冲液含有的确切点来绘制,并且使用信号(基于变焦/标度)的内插重新presentation。虽然也可以更快,更好看,如果我要呈现的图像缓冲区,我从来没有过投诉。你可以钙质,使这一切从辅助线程,如果你正确设置它。

i use CGContextMoveToPoint+CGContextAddLineToPoint+CGContextStrokePath in my app. one point per onscreen point to draw using a pre-calculated backing buffer for the overview. the buffer contains the exact points to draw, and uses an interpolated representation of the signal (based on the zoom/scale). although it could be faster and look better if i rendered to an image buffer, i've never had a complaint. you can calc and render all of this from a secondary thread, if you set it up correctly.

抗锯齿涉及到图形上下文。

anti-aliasing pertains to the graphics context.

CGFloat的(对于CGPaths本地输入)是矫枉过正的概述,作为中间再presentation,以及计算波形概览。 16位应该是足够的。当然,你必须传递给CG通话时转换为CGFloat的。

CGFloat (the native input for CGPaths) is overkill for an overview, as an intermediate representation, and for calculating the waveform overview. 16 bits should be adequate. of course, you'll have to convert to CGFloat when passing to CG calls.

您需要配置文件来找出你的时间都花在 - 重点放在最耗时的部分。此外,请你确定你只画什么,你必须,当你必须避免叠加/动画在可能的情况。如果你需要覆盖,这是更好地呈现给需要的图像/缓冲和更新。有时它有助于打破了显示器为多个绘图面时面大。

you need to profile to find out where your time is spent -- focus on the parts that take the most time. also, make you sure you only draw what you must, when you must and avoid overlays/animations where possible. if you need overlays, it's better to render to an image/buffer and update that as needed. sometimes it helps to break up the display into multiple drawing surfaces when the surface is large.

半OT:ABLETON的使用S + H值,这可以稍微快一点,但......我多preFER它作为一个选项。如果您实现使用线性插值(这可能是根据它的外观),考虑一个更直观的方法。线性插值是有点欺骗的,并且真的不,如果你正在开发一个应用程序的亲用户所期待的。

semi-OT: ableton's using s+h values this can be slightly faster but... i much prefer it as an option. if your implementation uses linear interpolation (which it may, based on its appearance), consider a more intuitive approach. linear interpolation is a bit of a cheat, and really not what the user would expect if you're developing a pro app.

这篇关于有效的方法来画一条线与数百万个点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆