C/C++波形快速显示

2024-03-24

我有兴趣在 Windows 和 Linux 上用 C 或 C++ 实现音频编辑器。我不知道如何在完全缩小的视图中足够快地显示波形。我不是在寻找有关快速帧缓冲区技术的信息。这是一个关于有效确定显示内容的算法和数据结构的问题。

假设我希望能够编辑 2 小时长的 5 通道、48 KHz、24 位声音。这是 5 GB 的示例数据。我希望能够从每个样本一个像素一直缩小,直到所有样本数据一次可见。我希望应用程序具有响应能力,即使是在一台速度较慢的机器上,例如 1 GHz Atom。当我说响应式时,我希望 GUI 更新通常在用户输入后的 1/30 秒内发生。

在决定为完全缩小的视图渲染什么时,简单的实现会扫描整个波形中的每个样本 - 它需要找到显示器每个像素宽度“覆盖”的所有样本的最大和最小样本值。我编写了一个简单的应用程序来测试这种方法的速度。我在我的 2015 3.5 GHz Xeon 上使用 1 小时长的单声道 16 位 44.1 KHz 样本进行了测试。需要0.12秒。这太慢了数百倍。

您可以想象维护缩小数据的缓存,但我不知道如何避免在大多数插入或删除后重新计算整个缓存。感觉一定有更好的办法。

这是显示我想要实现的目标的图表:

这就是当前大多数可用音频编辑器中的显示方式。用户可能会预料到这种行为。我用 Audacity 进行了测试,它是这样工作的(尽管它也以较浅的颜色显示了样本的平均值)。它可以处理任意插入大声音,似乎是瞬间的。我不会阅读 75 MB 的源代码来了解它是如何实现的。

EDIT:

许多人提出了在显示缩小视图时仅考虑样本子集的方案。我得出的结论是我不想这样做,因为它丢失了太多有用的信息。例如,如果您正在寻找声音中的故障(例如黑胶唱片转换中的咔嗒声),则包含所有样本非常重要。在最坏的情况下,如果故障只有一个样本长,我仍然希望保证它显示在完全缩小的视图中。


阅读 Peter Stock 的回答后,我提出了以下方案。我认为它的显示计算速度比简单方案快大约 500 倍,并且不会为插入或删除增加任何明显的成本。内存开销小于1%。

声音数据将分配在 131072 个样本的块中,因此插入和删除不需要重新分配和复制整个声音。当声音第一次加载时,每个块都将被完全填充(可能除了最后一个)。插入和删除会导致一种碎片。为简单起见,我将安排每个块的开头始终包含有效的样本数据,并且任何间隙都将位于块的末尾。

每个块都有两个与其关联的查找表,一个用于最大值,一个用于最小值。查找表中的每一项对应1024个样本。

下图显示了如何计算显示器一个像素宽度的最大值。它显示了一些与计算相关的块。它假设不存在“碎片”。

插入后,情况稍微复杂一些。现在,两个块的末端都有无效区域。最大查找表中的条目现在对应于样本的部分空区域。这些条目的值只需取最大样本即可找到are展示。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C/C++波形快速显示 的相关文章

  • 如何通过MFC将应用程序设置保存到注册表中?

    我有一个由 MFC 项目向导创建的 MFC 应用程序 我想在注册表中保存 读取应用程序设置 所以问了这个question https stackoverflow com questions 1880275 good c registry w
  • 如何让 CMake 为目标安装 PDB 文件

    如何让 CMake 安装调试 Visual Studio 生成的 DLL 文件和 EXE 文件所需的配套 PDB 文件 我已经挣扎了一段时间 试图找到这个问题的一个好的答案 我现在认为我找到了一个 使用安装文件命令
  • C# 中的密码恢复工具不起作用

    嗨 我对此还很陌生 我创建了一个门户 用户可以登录并在其中查看我制作的其他程序 问题是密码恢复似乎不起作用 我没有收到任何错误消息 我只是收到消息 我们无法访问您的信息 请重试 我已经正确设置了 ASP NET 配置 并使用不同的用户和权限
  • 为什么 Chrome 审核建议我最小化 Cookie 大小?

    如何最小化请求的 cookie 大小 Chrome 似乎 警告我 我的 cookie 大小为 41B 这根本不是很多 但是它警告我有什么原因吗 这是一个 PHPSESSID cookie 我真的不知道如何最小化它 有任何想法吗 我的请求响应
  • 在 Eclipse 4.4.2 中使用 C 代码中的构建变量

    我有一个之前使用 Eclipse 3 5 2 创建的项目 在其中 我能够在项目属性中设置构建变量 在这种情况下 假设我设置了SW VERSION是 4403 现在这应该是一个十六进制数字 所以在构建设置中 我添加了一个符号 VERSION
  • ReportViewer“缺少 URL 参数:名称”

    在一个网络应用程序中 我正在处理 ReportViewer 时不断出现错误 缺少 URL 参数 名称 我找到了原因 但没有找到解决方案 导致报告查看器出现异常的 url Reserved ReportViewerWebControl axd
  • 无法将方法组分配给 asp.net、linq、c# 中的隐式类型局部变量

    public void selectqueryasso CustomerOrderResult cso new CustomerOrderResult var a from as1 in ds orders from as2 in ds o
  • 如何提高QNX6下Eclipse IDE的性能

    我们在 VMWare 环境中通过 QNX6 运行 Eclipse 速度非常慢 Eclipse 是这样启动的 usr qnx630 host qnx6 x86 usr qde eclipse eclipse data root workspa
  • 树结构的序列化/反序列化

    我试图找出保存 序列化 并稍后打开 反序列化 树结构的最佳方法 我的结构由具有不同属性的各种对象类型组成 但每个对象类型都继承自基本抽象 Node 类 每个节点都有唯一的 ID GUID 并且有一个 AddSuperNode Node nd
  • 在 C 中使用另一个结构中的二维结构数组的编码问题

    我正在使用一个二维结构数组 它是另一个结构的一部分 这不是我做过很多事的事情 所以我遇到了问题 该函数在接近末尾的 测试 for 循环后最终失败 它在出现段错误之前正确打印出一行 我的代码中将数据读入虚拟二维结构数组的部分工作得很好 所以它
  • 弹出窗口或弹出窗口显示附加信息

    我想在我的应用程序顶部显示带有附加信息的弹出窗口 我的信息是Listview大约 500 个项目我都尝试过 有问题flyout gt 它里面可能有scrollViewer 所以我的列表视图不能正确虚拟化 其他一切都可以 有我的代码 Flyo
  • 如何使用 Xamarin 应用程序开发自动注销

    我必须在 App xaml cs 上添加功能才能使其正常工作 我在 OnStart 上添加了功能 但现在它会间歇性地一次又一次地将我从应用程序中注销 根据下面的代码 我需要做什么才能让它停止这样做 或者我的代码有问题 这是我最新的代码 na
  • 在C中更改函数内的数组

    我正在学习 C 并且很困惑为什么在 main 中创建的数组不会在函数内部更改 我假设传递的数组是一个指针 并且更改指针应该更改数组 对吧 有人可以解释这种情况下发生了什么吗 谢谢你的帮助 int main int i length 10 i
  • 在源代码和预编译二进制文件之间切换

    我们的应用程序中有大量的库 库是用 C 或 C 编写的 平台 net Framework Windows 64 位 将所有内容编译为源代码需要花费大量时间 我们正在考虑切换到预构建的二进制文件 但我们仍然希望保留返回源代码的可能性 作为版本
  • 如何将 MouseDown 事件放入样式中?

    这有效 XAML
  • 使用 JSON.NET 反序列化一些 JSON

    我对 JSON 非常陌生 我需要解析 API 提供的一些内容 谷歌快速搜索出现了JSON NET http james newtonking com pages json net aspx 所以我现在尝试使用它将此 JSON 解析为列表对象
  • 稀疏矩阵中的最大和子矩形

    求一个子矩形中的最大和NxN矩阵可以完成O n 3 正如其他帖子中指出的 使用 2 d kadane 算法的时间 然而 如果矩阵是稀疏的 具体来说O n 非零条目 可以O n 3 时间被打败了吗 如果有帮助的话 对于我感兴趣的当前应用程序
  • 类型 '' 未映射

    我已经尝试修复这个错误有一段时间了 每当我的应用程序尝试创建数据上下文的实例时 我都会收到此错误 下面是代码 using System using System Collections Generic using System Linq u
  • 计算 .NET Core 项目的代码指标?

    我正在研究 ASP NET Core 和 NET Core 项目 对于经典的 C 项目 Visual Studio 2015 具有计算代码指标的功能 对于 NET Core 预览版 2 工具中缺少支持 在工具更加完整之前 有人知道解决方法吗
  • 如何包装实体框架以在执行前拦截 LINQ 表达式?

    我想在执行之前重写 LINQ 表达式的某些部分 我在将重写器注入正确的位置时遇到问题 实际上根本没有 查看实体框架源代码 在反射器中 它最终归结为IQueryProvider Execute在 EF 中 它通过以下方式耦合到表达式Objec

随机推荐