c++ - 绘制可以放大/缩小的声波

标签 c++ audio waveform bass

我正在为毕业设计一个声音编辑器。我正在使用 BASS从 MP3、WAV、OGG 等文件中提取样本,并添加 DSP 效果,如回声、镶边等。简单地说,我制作了我的框架,将效果从 position1 应用到 position2,剪切/粘贴管理。

现在我的问题是我想创建一个与 Cool Edit Pro 中的控件类似的控件绘制歌曲的波形表示并能够放大/缩小波形的选择部分等。选择后我可以做类似的事情:

TInterval EditZone = WaveForm->GetSelection();

其中 TInterval 具有以下形式:

struct TInterval
{
    long Start;
    long End;
}

对于复杂的绘图,我是初学者,所以任何关于如何使用 BASS 返回的示例数据创建歌曲的波形表示的提示,以及放大/缩小的能力,我将不胜感激。

我正在用 C++ 编写我的项目,但我可以理解 C#、Delphi 代码,所以如果你愿意,你也可以发布最后两种语言的代码片段:)

感谢 DrOptix

最佳答案

关于缩放,我认为您指的是水平缩放而不是垂直缩放。音频编辑器执行此操作的方法是扫描波形,将其分解为时间窗口,其中 X 中的每个像素代表一定数量的样本。它可以是一个小数,但您可以通过禁止小数缩放比例来逃脱,而不会太烦扰用户。缩小一点后,最大值始终为正整数,最小值始终为负整数。

对于屏幕上的每个像素,您需要知道该像素的最小样本值和最大样本值。因此,您需要一个函数来扫描 block 中的波形数据并跟踪该 block 的累积最大值和最小值。

这是一个缓慢的过程,因此专业的音频编辑器会保留一个预先计算好的最小值和最大值表,以某个固定的缩放比例。它可能位于 512/1 或 1024/1。当您使用 > 1024 个样本/像素的缩放比进行绘制时,您可以使用预先计算的表格。如果低于该比率,则直接从文件中获取数据。如果不这样做,您会发现在缩小时绘制代码变得太慢。

在进行这种扫描时,编写一次处理文件所有 channel 的代码是值得的,这里的缓慢会让你的整个程序感觉迟钝,这里重要的是磁盘 IO,CPU 没有问题保持向上,如此简单的 C++ 代码可以很好地构建最小/最大表,但您不想多次遍历文件,而是希望按顺序进行。

一旦你有了最小/最大表,就把它们放在身边。您希望尽可能少地返回到磁盘,并且许多想要重新绘制窗口的原因不会要求您重新扫描您的最小/最大表。与最初构建它们的磁盘 io 成本相比,保留它们的内存成本并没有那么高。

然后,通过在该像素表示的时间的最大值和最小值之间绘制一系列 1 像素宽的垂直线来绘制波形。如果您从预先构建的最小/最大表中绘制,这应该会非常快。

关于c++ - 绘制可以放大/缩小的声波,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2305299/

相关文章:

C++ Win32,用位图显示窗口的最简单方法

C++:升级到 GTX970 后 cv::gpu::GpuMat::upload 出现长时间延迟

c++ - const 引用如何绑定(bind)到右值

java - 音频在Eclipse中有效,但在.jar中不起作用

iPhone SDK : Is it possible to play audio playlist in the background in iOS 4

android - 如何使用 Visualizer 对象的 onWaveFormDataCapture 结果?

C++链表isEmpty函数

audio - 音乐可视化

方波上的android音频失真

java - 使用 jfreechart 绘制音频信号(幅度与时间)