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

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

问题描述

我正在 Cocoa 中编写一个具有多种缩放选项的音频波形编辑器.在最宽的范围内,它显示了整首歌曲的波形(可查看约 1000 万个样本).在最窄处,它显示了声波的像素精确表示(视图中大约有 1000 个样本).我希望能够在这些缩放级别之间平滑过渡.一些像 Ableton Live 这样的商业编辑器似乎以一种非常便宜的方式来做到这一点.

我当前的实现满足我想要的缩放范围,但效率低下且断断续续.该设计很大程度上受到这篇关于用石英绘制波形的优秀文章的启发:

解决方案

我在我的应用中使用 CGContextMoveToPoint+CGContextAddLineToPoint+CGContextStrokePath.使用预先计算的后备缓冲区为概览绘制每个屏幕点一个点.缓冲区包含要绘制的确切点,并使用信号的内插表示(基于缩放/比例).虽然如果我渲染到图像缓冲区它可能会更快并且看起来更好,但我从来没有抱怨过.如果设置正确,您可以从辅助线程计算和渲染所有这些.

抗锯齿与图形上下文有关.

CGFloat(CGPaths 的本机输入)对于概览、作为中间表示和计算波形概览来说太过分了.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天全站免登陆