将音频样本的字节数组更改为频率

Posted

技术标签:

【中文标题】将音频样本的字节数组更改为频率【英文标题】:change an array of byte of audio sample to frequency 【发布时间】:2013-11-26 13:39:17 【问题描述】:

首先,我有一个项目来更改 WAVE 文件的频率,我需要在 Java 中这样做。

我在 java 中使用 Audiosystem 来获取音频数据的字节(不包括文件头)。现在我得到一个数据字节数组,我想将它从时域更改为频域,并且在操纵频率之后,我想将其更改回时域。代码如下:

public byte[] getWAVByte()
    ByteArrayOutputStream out = new ByteArrayOutputStream();

    try
        File f = new File("audio.wav");
        AudioInputStream in = AudioSystem.getAudioInputStream(f);

        int read;

        byte[] buff = new byte[(int)f.length()];
        while ((read = in.read(buff)) > 0)
        
            out.write(buff, 0, read);
        
        out.flush();
        byte[] audioBytes = out.toByteArray();

        return audioBytes;
    catch(Exception e)
        e.printStackTrace();
    


现在我在 audioBytes 中有一个字节数组,我想将其更改为频域中的另一个字节数组。我读过你可以用傅立叶变换来做到这一点,但我的老师说它真的很复杂,而且不在我的项目范围内。那么还有其他方法可以做到这一点吗?或者有没有什么java库可以帮我获取频域的字节数组?

【问题讨论】:

Processing Audio Data using Fourier Transforms in Java的可能重复 你说“我有一个项目来改变WAVE文件的频率”正确的做法并不简单,你似乎想要一个Pitch Shift,简单而不正确的方法是播放您的音频采用不同的采样率,但这会改变音频的速度,您可以在频域中执行此操作,并且您需要计算 FFT ... 是的,我已经尝试更改采样率,但它变得更快并且对我来说变得相当嘈杂。我还尝试通过将每两个字节更改为短类型并对其进行操作然后将其转换回字节来操作数据字节,但它似乎改变了幅度(如果我将它乘以 2 声音会变大,如果我把它分成了两份) 【参考方案1】:

Stephan M. Bernsee 在频域中写了如何做到这一点,你可以在 C 中找到你的源代码下载,一个人做了一个 Java 的移植到你的运气!

http://svn.assembla.com/svn/mm1ws08/Abgabe2/src/Effects/PitchShift.java

是的,如果您将一个值乘以或除以字节数组,您只是增加或减少幅度信号,要更改时域中的频率,您是否需要找到声门位置单击,在每个声门上应用一个居中窗口位置,现在将每个窗口移动到一个新的时间位置,在这一步你可以添加或排除一些窗口,这会改变信号的频率,最后在所有窗口化的声门上做一个 Overlap Add,这个方法称为@ 987654323@

【讨论】:

Java 代码似乎无法正常工作(看起来像是一个从未完成的学校项目)。你可以链接到这个:github.com/JorenSix/TarsosDSP/blob/master/src/core/be/tarsos/…【参考方案2】:

感谢ederwander 提供有关音高转换的建议。

TarsosDSP 将代码从Stephan M. Bernsee 移植到Java here,他们还提供了使用另一种方法here 的示例。

我最终使用了 Superpowered AdvancedAudioPlayer 类,因为我已经将它用于其他目的。您基本上使用PlayerExample 项目并在audioProcessing 回调的开头添加两行:

player->setTempo(1.0, true); // Needed for the pitch shifting to work
player->setPitchShift(-12); // Pitch shift one octave down

【讨论】:

以上是关于将音频样本的字节数组更改为频率的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 java 从 pcm 字节数组 .wav 文件中获取频率和音高?

如何正确将 16Bit 字节数组转换为音频剪辑数据?

将二进制位转换为字节数组

检测原始音频 (PCM) 中的特定频率/音调

更高效的decodeAudioData()?

从音频字节创建 wav 文件