我有兴趣在Windows和Linux上用C或C++实现音频编辑器。我无法弄清楚如何在完全缩小的视图中足够快地显示波形。我不在寻找有关快速帧缓冲技术的信息。这是一个关于算法和数据结构的问题,可以有效地确定要显示的内容。在C/C++中快速显示波形
假设我想要编辑2个小时长的5声道48KHz 24位声音。这是5千兆字节的示例数据。我希望能够从每个样本一个像素一直缩小,直到所有样本数据一次都可见。我希望应用程序能够感觉到响应,即使是在慢速的机器上,例如为了争辩,1GHz的Atom。当我说响应时,我希望GUI更新通常在用户输入的1/30秒内发生。
一个幼稚的实现会在决定为完全缩小的视图渲染什么时扫描整个波形中的每个样本 - 它需要为所有样本“覆盖”每个像素宽度的最大和最小样本值显示。我写了一个简单的应用程序来测试这种方法的速度。我在2015年3.5 GHz Xeon上测试了1小时长,单声道,16位,44.1 KHz采样。它需要0.12秒。这是数百倍太慢。
你可以想象维护一个缩小数据的缓存,但我看不到如何避免在大多数插入或删除操作后重新计算整个缓存。感觉好像有一个更好的方法。
这里展示我想达到什么图:
这是如何在最流行可用音频编辑作品的显示。用户可能会期待这种行为。我使用Audacity进行了测试,并且以这种方式工作(尽管它也显示了颜色较浅的样本的平均值)。它可以处理任意插入大声音,看似瞬间。我不打算阅读75兆字节的源代码来了解它是如何实现的。
编辑:
各种人提议表示缩小视图时涉及只考虑样本的一个子集方案。我得出的结论是,我不想这样做,因为它失去了太多有用的信息。例如,如果您正在寻找声音中的故障(如乙烯基转换中的单击),则包括所有样本都很重要。在最坏的情况下,如果毛刺只有一个样本长度,我仍然希望保证它在完全缩小视图中显示。
降采样!采样! 1/30秒是旧机器上的梦想,但你可以用更好的硬件获得好的结果。另外请记住,图形和IO将是缓慢的部分,除非你非常小心。未压缩的波可以试图读取每个n的1个样本(不准确但响应),然后在背景读取和下采样。一切完成后缓存并接受你将不会有你想要的性能。这不是一种算法或一种数据结构,而是一系列给予*印象*的技术。 –
下采样是什么意思?根据我从这个术语的理解,如果我下取样20 KHz方波,我会得到一个直流信号。而显示器仍应显示全幅信号。我可以看到,读取n个样本中的1个以获得不准确但响应性很高的显示是我原始问题的可能答案。顺便说一句,我已经可以快速将数据绘制到屏幕上了。我只是将所有的行绘制到RAM中的位图中,然后将整个事件呈现给屏幕。 –
反对票的任何解释? –