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

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

问题描述

我在Cocoa中编写了一个音频波形编辑器,提供了各种缩放选项。在最宽的情况下,它显示了整首歌曲的波形(约1000万个样本)。在其最窄处,其示出了声波的像素精确表示(在视图中〜1千个样本)。我想要能够在这些缩放级别之间平滑过渡。一些商业编辑像Ableton Live似乎以非常便宜的方式做到这一点。



我当前的实现满足我想要的缩放范围,但效率低下。这个设计很大程度上源于这篇有关用石英绘制波形的精彩文章:



解决方案

我在我的应用程序中使用CGContextMoveToPoint + CGContextAddLineToPoint + CGContextStrokePath。每个屏幕上的点使用预先计算的后备缓冲区绘制一个点用于概览。缓冲区包含要绘制的精确点,并使用信号的内插表示(基于缩放/缩放)。虽然它可以更快,看起来更好,如果我渲染到一个图像缓冲区,我从来没有投诉。



抗锯齿属于图形上下文。



CGFloat(CGPath的本机输入)对于概述,中间表示以及计算波形概览都是过度的。 16位应该足够了。当然,在传递到CG调用时,您必须转换为CGFloat。



您需要配置文件以找出您的时间花在哪里 - 专注于零件这需要最多的时间。也让你确定你只画你必须的,当你必须和避免覆盖/动画,如果可能的话。如果你需要覆盖,最好渲染到一个图像/缓冲区,并根据需要更新。有时候当表面很大时,有助于将显示分解成多个绘图表面。



semi-OT:ableton使用s + h值,我更喜欢它作为一个选择。如果你的实现使用线性插值(它可能基于其外观),考虑一个更直观的方法。线性插值是一个骗子,真的不是用户期望的,如果你正在开发一个专业的应用程序。


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/drawing-waveforms/

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.

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).

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?

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

解决方案

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 (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.

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天全站免登陆