Java - 如何将频率转换为复数
Posted
技术标签:
【中文标题】Java - 如何将频率转换为复数【英文标题】:Java - How to turn in frequency a complex number 【发布时间】:2018-02-24 10:53:28 【问题描述】:我正在从 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;
有什么想法吗?我试图把信号的罪孽,但我不能去频率部分。
【问题讨论】:
许多重复项,例如***.com/questions/16060134/… 和 ***.com/questions/7674877/… 【参考方案1】:FFT_SIZE = FFT 的长度,在您的情况下为 complex.length
或 results[x].length
或 1024
FFT 频率 bin 的数量,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 输出的后半部分是前半部分的复共轭。
【讨论】:
以上是关于Java - 如何将频率转换为复数的主要内容,如果未能解决你的问题,请参考以下文章