Java - 如何将频率变为复数

时间:2018-02-24 10:53:28

标签: java audio fft frequency frequency-analysis

我正在从wav音频中读取每帧的字节数。我有一个采样率= 44100,通道= 2的格式。

     byte[] buffer = new byte[(int) 1024];
     while (running)                                    {
     n++;
     if (n > 400000){break;}                  
     int count = 0;
     count = outDinSound.read(buffer, 0, 1024);
     if (count > 0) {out.write(buffer, 0, count);}      }
     byte b[] = out.toByteArray();
     final int totalSize = b.length;
     int amountPossible = totalSize / 1024;
                                                      *so far all is good*

下一步是从我的数组中的每个值创建一个复数,然后我为这些复数调用快速傅里叶变换

          Complex[][] results = new Complex[amountPossible][];
          for (int times = 0; times < amountPossible; times++) {
                    Complex[] complex = new Complex[1024]; 
                    for (int i = 0; i < 1024; i++)      {
                    complex[i] = new Complex(b[(times * 1024) + i], 0); }
          results[times] = FFT.fft(complex);
                                                                     }

现在我可以找出每个信号的幅度

            for (int t = 0; t < results.length; t++) {    
                   for (int freq = 1; freq < 1024; freq++)  {
                       magnitude =results[t][freq].abs();   }
                                                       }

但我的最终目标是找出频率(或该信号存在的频率_)。

我使用的复杂类是

            public class Complex {
            private final double re; // the real part
private final double im; // the imaginary part

public Complex(double real, double imag) {// create a new object with the given real and imaginary parts
re = real;
im = imag;  }

   public String toString() {   // return a string representation of the invoking Complex object
    if (im == 0)    return re + "";
    if (re == 0)    return im + "i";
    if (im < 0) return re + " - " + (-im) + "i";
    return re + " + " + im + "i";   }
           //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     public double abs() {   // return abs/modulus/magnitude and angle/phase/argument
     return Math.hypot(re, im); } // Math.sqrt(re*re + im*im)
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public double phase() {
       return Math.atan2(im, re);   } // between -pi and pi
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public Complex plus(Complex b) {// return a new Complex object whose value is (this + b)
       Complex a = this; // invoking object
       double real = a.re + b.re;
       double imag = a.im + b.im;
       return new Complex(real, imag);  }
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public Complex minus(Complex b) {// return a new Complex object whose value is (this - b)
       Complex a = this;
       double real = a.re - b.re;
       double imag = a.im - b.im;
       return new Complex(real, imag);  }
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public Complex times(Complex b) {// return a new Complex object whose value is (this * b)
       Complex a = this;
       double real = a.re * b.re - a.im * b.im;
       double imag = a.re * b.im + a.im * b.re;
       return new Complex(real, imag);  }

       public Complex times(double alpha) {// scalar multiplication// scalar multiplication// return a new object whose value is (this * alpha)
       return new Complex(alpha * re, alpha * im);  }
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public Complex conjugate() {// return a new Complex object whose value is the conjugate of this
       return new Complex(re, -im); }
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public Complex reciprocal() {// return a new Complex object whose value is the reciprocal of this
       double scale = re * re + im * im;
       return new Complex(re / scale, -im / scale); }
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public double re() { 
       return re;   }
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public double im() {
       return im;   }

       public Complex divides(Complex b) {// return a / b
       Complex a = this;
       return a.times(b.reciprocal());  }
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      public Complex exp() {//return a new Complex object whose value is the complex exponential of
return new Complex(Math.exp(re) * Math.cos(im), Math.exp(re)* Math.sin(im));    }
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public Complex sin() {// return a new Complex object whose value is the complex sine of this
       return new Complex(Math.sin(re) * Math.cosh(im), Math.cos(re)* Math.sinh(im));   }
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public Complex cos() {// return a new Complex object whose value is the complex cosine of this
       return new Complex(Math.cos(re) * Math.cosh(im), -Math.sin(re)* Math.sinh(im)); }
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public Complex tan() {// return a new Complex object whose value is the complex tangent of this
       return sin().divides(cos()); }
   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public static Complex plus(Complex a, Complex b) {// a static version of plus
double real = a.re + b.re;
double imag = a.im + b.im;
Complex sum = new Complex(real, imag);
return sum; }

   }

有什么想法吗?我试图接受信号的罪,但钢铁我不能去频率部分。

1 个答案:

答案 0 :(得分:0)

FFT_SIZE =您的FFT的长度,在您的情况下complex.lengthresults[x].length1024

FFT频率区数,FFT_BIN_SIZE = FFT_SIZE / 2

FFT_BIN_WIDTH =采样率/ FFT_SIZE或奈奎斯特频率/ FFT_BIN_SIZE

for (int i = 0; i < results.length; i++) {
    for (int j = 0; j < results[i].length / 2; j++) {
          Frequency = j * FFT_BIN_WIDTH;
          Magnitude = results[i][j].abs();
    }
}

请注意,您可以获得的最大频率是奈奎斯特频率,它是采样率的一半,而FFT输出的后半部分是上半部分的复共轭。