FFT 音频输入

Posted

技术标签:

【中文标题】FFT 音频输入【英文标题】:FFT audio input 【发布时间】:2014-06-23 15:09:25 【问题描述】:

我想对 AudioRecorder 录制并保存到 wav 文件的信号应用 FFT。我使用的 FFT 有一个 Complex[] 输入参数。我很困惑,从字节转换为复数除以 32768 和只在虚部加 0 并将实部作为字节进行转换有区别吗?

编辑:

public Complex[] convertToComplex(byte[] file)



    int size= file.length;
    double[]x=new double[size];
    Complex[]data= new Complex[size];
    for(int i=0;i<size;i++)
    
        x[i]=file[i]/32768.0;
        data[i]=new Complex(x[i],0);
        //  Log.d("tag", "indice"+i+":"+data[i]);
    
    return data;

【问题讨论】:

只是为了确认您的音频是 16 位 PCM 对吗?如果是这样,那么不幸的是你的转换是错误的,看看我是如何在我的代码中进行转换的。 是的,它是 16 位 PCM。我不明白你为什么使用short。 myAudiosamples 的长度是 1/2 myAudioBytes? 是的,myAudioSamples 的长度是 1/2 myAudioBytes。我使用“short”是因为它正好有 16 位,您也可以使用双精度(64 位)或浮点型(32 位),因为您的样本仍然适合在。 【参考方案1】:

如果您正在处理位深为 16 位的音频(每个样本有 16 位),那么每个字节将只有一半样本。您需要做的是将字节转换为 16 位样本,然后除以得到的数字乘以 32768(这是 2 的补码 16 位数字可以存储的最小数字的大小,即 2^15)以获得实际的音频样本,它是介于 -1 和 1 之间的数字。然后您将把这个数字转换为通过将其虚部设置为 0 来获得复数。

可以在下面看到一个小的 C# 示例(指示性代码):

    byte[] myAudioBytes = readAudio();
    int numBytes = myAudioBytes.Length;

    var myAudioSamples = new List<short>();

    for( int i = 0; i < numBytes; i = i + 2)
    
      //Cast to 16 bit audio and then add sample
       short sample = (short) ((myAudioBytes[i] << 8 | myAudioBytes[i + 1]) / 32768 ); 
       myAudioSamples.Add(sample);
    

    //Change real audio to Complex audio

    var complexAudio = new Complex[myAudioSamples.Length];

    int i = 0;
    foreach(short sample in myAudioSamples)
       complexAudio[i++] = new Complex() Real = sample, Imaginary = 0 ;

   //Now you can proceed to getting the FFT of your Audio here

希望代码能够指导您如何处理音频。

【讨论】:

谢谢你们。我编辑了我的问题以添加我所做的转换。我希望它没有错。【参考方案2】:

通用 FFT 函数,例如处理复杂输入和输出的数组。因此,对于输入,您可能需要创建一个复数数组,该数组符合 FFT 库所需的复杂数据结构。这可能由每个的实部和虚部组成。只需将虚部设置为 0。实部可能是一个带符号的浮点数,预计在 -1.0..1.0 之间,因此您在除以整数 PCM 样本的正确轨道上。但是,当您编写“转换 bytes”时,会引发危险信号。这些可能是有符号的、小端序的、16 位整数 PCM 样本,因此请务必在除以 32768 之前相应地转换它们(但这是 Java,因此无论如何都会对类型进行更严格的强制)。

【讨论】:

以上是关于FFT 音频输入的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中使用 FFT 算法进行音频频谱分析

OS X 环境中的音频文件 FFT

如何从 Tizen 上的实时 FFT 获得最准确的音频数据?

采样率和可变长度输入样本与固定大小的 FFT 输入有何关系?

如何正确 FFT 声音阵列?

将音频流写入循环缓冲区但分段错误读取值