java - 如何从我的 wav 文件中提取声音数据?

标签 java audio drawing wav javasound

首先,这是为了家庭作业或...项目。

我无法理解如何将声音数据波绘制到项目的 Java 图形背后的想法。 我必须完全从头开始使用 UI 和所有内容来完成这项任务,所以基本上是制作一个 .wav 文件编辑器。 我遇到的主要问题是将声音数据放入要绘制的图表中。目前我有一个随机生成的值数组,现在正在绘制。

到目前为止,我有一个小程序在运行并验证 wav 文件是否真的是一个 wav 文件。

我正在使用 FileInputStream 读取它并验证:RIFF 字节 (0-3)、FileLength(4-7)、WAVE 字节 (8-11),然后是格式 block 格式(从末尾开始RIFF block ;并将索引定位到它的末尾并给出格式 0-3、格式 block 的长度 4-7,然后是接下来的 16 个字节用于 wave 文件的所有规范并将它们存储在它们适当的命名变量中。

一旦我到达 DATA block ,它的长度超过了我所有的声音数据,这就是我不确定如何为声音数据字节存储每个字节,或者甚至将它转换为与声音的振幅。我认为验证是相似的,所以它会是一样的,但它似乎不是那样的......要么那样,要么我一直在把一些 super 简单的东西复杂化,因为我已经盯着它看了几天了。

感谢任何帮助。

最佳答案

我不是 Java 程序员,但我对渲染音频有一定的了解,所以希望以下内容对您有所帮助...

鉴于您几乎总是拥有比可用像素多得多的样本,明智的做法是从样本数据的缓存缩减或“摘要”中提取。这通常是音频编辑器(例如 Audacity )呈现音频数据的方式。事实上,最常见的策略是计算每个像素的样本数,然后为大小为 SamplesPerPixel 的每个 block 找到最大和最小样本,然后在每个最大-最小对之间画一条垂直线。您可能希望缓存这种缩小,或者针对不同的缩放级别缓存一系列此类缩小。 Audacity 缓存到磁盘上的临时文件(“ block 文件”)。

上面的内容可能过于简单化了,但是,因为在现实中您会希望从固定大小的 block (比如 256 个样本)而不是从一个大小 SamplesPerPixel。然后,您可以根据缓存的缩减计算进一步的“即时”缩减。关键是 SamplesPerPixel 通常是一个动态量 - 因为用户可能会随时调整 Canvas 的大小(希望这是有意义的...)。

另请记住,当您在 Canvas 上绘图时,您需要根据 Canvas 的宽度和高度来缩放样本值。最好的方法(至少在垂直方向上)是标准化样本,然后乘以 Canvas 高度。 16 位音频由 [-32768, 32767] 范围内的样本组成,因此要标准化只需将 float 除以 32768。然后反转符号(将波形翻转到 Canvas 坐标),加 1(补偿对于负值)并乘以 Canvas 高度的一半。无论如何,我就是这样做的。

This页面显示了如何使用 Java Swing 构建基本的波形显示。我没有详细查看它,但我认为它只是对数据进行下采样,而不是计算最大-最小对。当然,这不会像最大-最小方法那样提供精确的缩减,但它更容易计算。

如果您想知道如何正确地做事,您应该深入研究 Audacity 源代码(但是请注意 - 它是相当粗糙的 C++)。要获得一般概述,您可以查看 'A Fast Data Structure for Disk-Based Audio Editing' ,由 Audacity 的原作者 Dominic Mazzoni 撰写。您需要从 CMJ 购买, 然而。

关于java - 如何从我的 wav 文件中提取声音数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12879210/

相关文章:

python - 如何在 python 中将 16 位 PCM 数据转换为 float ?

android - 在 Canvas 上绘制虚线

java - 仅打印多页 pdf 中的一页

ios - 使用url播放音频在iOS7上不起作用

Java 对象引用机制

HTML5 视频 - 仅从视频中获取配乐

iphone - iOS : Core Text - loosing context when drawing image inside a block

javascript - 在绘制之前剪裁上下文可以帮助提高 HTML5 Canvas 性能吗?

java - 使用泛型实现方法

java - 调用notify()时出现IllegalMonitorStateException