java - 音频处理 - 数字分块和前向傅里叶变换?

标签 java audio fft processing

我无法理解老师教给我的概念,并且同学之间的答案也不一致。我想知道是否有人可以帮助澄清这个想法或概念?

这在音频处理中被称为数字分块。 我们只需要处理 WAV 文件。因此我们假设我们的音频数据未压缩。

numChunking 与音频正弦波上的傅里叶变换有关。

为了确定 numChunks 的数量,我们做了类似的事情

方法1:

int numChunks = totalNumOfSamples/chunkSize

但与我交谈过的其他人也很少这么说

方法2:

int numChunks = totalNumOfSamples/binSize

区别在于,chunkSize只是一些指定的数字或硬编码的数字,如 1024 或 2000 等。另一方面,binSize 是我们对样本应用傅里叶变换后绘制的频率数。我们通常绘制的 bin 数量(面板上的条形图/频率条形图)约为 50-100 个,若要再显示在屏幕上,则需要很长时间。

在方法 1 中,我们从 47988 个样本/2000 = 23 个 numChunk 中获取一些 numChunk。然后我们将这些 block 发送到 for 循环中,并将声音数据的每个样本添加到每个 block 中,因此,如果我们将所有 23 个 numChunk 放在一起,我们几乎就拥有了整个声音数据,但由于无法容纳划分中的每个样本,因此精度有所损失。然后,我们将它们添加到数组或 ArrayList 中,稍后发送到离散傅里叶变换(前向傅里叶函数),我们得到结果并将它们放入容器中,并将结果绘制/绘制为条形图。

我不确定的最后一个细节是傅里叶变换是否除以整个声音中的 TOTAL 样本,或者只是除以 numChunk 中的 TOTAL 样本数。

在方法 2 中,该方法的工作方式是 numChunks = 样本总数/binSize 例如,我们将使用相同的示例。 47988/30bins = 1599 numChunks。 在这个想法中,我的同学向我解释说 numChunks 是多个子数组。因此,我制作了一个 2D 数组,其中有 1599 个数组,每个数组的长度为 binSize,因此当我们通过前向傅里叶变换处理每个子数组时,我们会得到结果幅度值或频率然后,我们通过前向傅里叶变换运行每个子数组,将该值除以整个声音的总样本大小。

这两种想法的结果截然不同。方法 1 生成的第一个值约为 37.5,方法 2 生成的值约为 3689。他们的以下值似乎总体上都是正确的,因此我不确定哪种方法是正确的,或者是否有任何方法是正确的。

这是用 Java 编写的

这个问题很令人困惑,你可以看出我自己也很困惑。我希望有人能帮助澄清哪个是正确的或不正确的或解释这个概念。

最佳答案

哇,你有点困惑。我会尽力尝试帮助解释一下。

您使用 DFT(离散傅里叶变换)所做的是获取多个样本 N 并将它们从时域转换到频域。您在频域中得到的数组的大小与您在时域中放入的数组的大小相同。因此,您可以根据输出数组中所需的频率分辨率将 numChunks 设置为您想要的任何值,因为频率分辨率将是sampleRate/numChunks。因此,如果您想要输出 80 个频率值,请使用 block 大小 80。将您的声音文件分为 TotalNumSamples/80 个 block ,您将依次获得每个 block 的频率内容。

要回答您的另一个问题,整个声音中的样本总数并不重要 - 您所做的每个 DFT 都是完全独立的,因此重要的是您放入每个 DFT 中的样本数量。

希望对您有一点帮助。

关于java - 音频处理 - 数字分块和前向傅里叶变换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13651526/

相关文章:

Python 将 CD 文件翻录为 WAV

winapi - 在Windows 7中模拟PC Speaker?

python - numpy.fft numpy.fft2 和 FFTW 用于二维数组

python - fft 除法用于快速多项式除法

java - 无法连接到本地 DynamoDB

java - 将字符串更改为 byte[] - 无需实际转换

ios - 在iOS 9中使用AVFoundation合并2个音频文件CAF

java - 功率谱自相关

java - geronimo-web.xml 在 WebSphere 中做什么?

java - java中的项目依赖