diff --git a/README.md b/README.md
index fe3f455..815000d 100644
--- a/README.md
+++ b/README.md
@@ -15,11 +15,11 @@ var window = new FftSharp.Windows.Hanning();
window.ApplyInPlace(signal);
// Calculate the FFT as an array of complex numbers
-Complex[] fftRaw = FftSharp.Transform.FFT(signal);
+System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(signal);
// or get the magnitude (units²) or power (dB) as real numbers
-double[] fftMag = FftSharp.Transform.FFTmagnitude(signal);
-double[] fftPwr = FftSharp.Transform.FFTpower(signal);
+double[] magnitude = FftSharp.FFT.Magnitude(spectrum);
+double[] power = FftSharp.FFT.Power(spectrum);
```
Signal | Windowed Signal | FFT
@@ -32,12 +32,12 @@ Signal | Windowed Signal | FFT
// sample audio with tones at 2, 10, and 20 kHz plus white noise
double[] signal = FftSharp.SampleData.SampleAudio1();
int sampleRate = 48_000;
+double samplePeriod = sampleRate / 1000.0;
// plot the sample audio
-var plt = new ScottPlot.Plot(400, 200);
-plt.AddSignal(signal, sampleRate / 1000.0);
+ScottPlot.Plot plt = new();
+plt.AddSignal(signal, samplePeriod);
plt.YLabel("Amplitude");
-plt.Margins(0);
plt.SaveFig("time-series.png");
```
@@ -59,15 +59,15 @@ double[] signal = FftSharp.SampleData.SampleAudio1();
int sampleRate = 48_000;
// calculate the power spectral density using FFT
-double[] psd = FftSharp.Transform.FFTpower(signal);
-double[] freq = FftSharp.Transform.FFTfreq(sampleRate, psd.Length);
+System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(audio);
+double[] psd = FftSharp.FFT.Power(spectrum);
+double[] freq = FftSharp.FFT.FrequencyScale(psd.Length, sampleRate);
// plot the sample audio
-var plt = new ScottPlot.Plot(400, 200);
+ScottPlot.Plot plt = new ScottPlot.Plot();
plt.AddScatterLines(freq, psd);
plt.YLabel("Power (dB)");
plt.XLabel("Frequency (Hz)");
-plt.Margins(0);
plt.SaveFig("periodogram.png");
```
@@ -82,12 +82,12 @@ plt.SaveFig("periodogram.png");
If you are writing a performance application or just enjoy working with real and imaginary components of complex numbers, you can build your own complex array perform FFT operations on it in place:
```cs
-Complex[] buffer =
+System.Numerics.Complex[] buffer =
{
- new Complex(42, 0),
- new Complex(96, 0),
- new Complex(13, 0),
- new Complex(99, 0),
+ new(real: 42, imaginary: 12),
+ new(real: 96, imaginary: 34),
+ new(real: 13, imaginary: 56),
+ new(real: 99, imaginary: 78),
};
FftSharp.Transform.FFT(buffer);
diff --git a/src/FftSharp.Demo/FftSharp.Demo.csproj b/src/FftSharp.Demo/FftSharp.Demo.csproj
index 6af234d..37f462d 100644
--- a/src/FftSharp.Demo/FftSharp.Demo.csproj
+++ b/src/FftSharp.Demo/FftSharp.Demo.csproj
@@ -20,9 +20,9 @@
-
-
+
+
-
+
\ No newline at end of file
diff --git a/src/FftSharp.Demo/FormAudio.cs b/src/FftSharp.Demo/FormAudio.cs
index db1343b..5831706 100644
--- a/src/FftSharp.Demo/FormAudio.cs
+++ b/src/FftSharp.Demo/FormAudio.cs
@@ -1,4 +1,5 @@
-using System;
+using ScottPlot.Drawing.Colormaps;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
@@ -117,7 +118,8 @@ private void UpdateWindowed(double[] audio)
private void UpdateFFT(double[] audio)
{
- double[] ys = cbLog.Checked ? Transform.FFTpower(audio) : Transform.FFTmagnitude(audio);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(audio);
+ double[] ys = cbLog.Checked ? FftSharp.FFT.Power(spectrum) : FftSharp.FFT.Magnitude(spectrum);
string yLabel = cbLog.Checked ? "Power (dB)" : "Magnitude (RMS²)";
plotFFT.Plot.Clear();
diff --git a/src/FftSharp.Demo/FormMicrophone.Designer.cs b/src/FftSharp.Demo/FormMicrophone.Designer.cs
index 2a737de..d7982bd 100644
--- a/src/FftSharp.Demo/FormMicrophone.Designer.cs
+++ b/src/FftSharp.Demo/FormMicrophone.Designer.cs
@@ -28,150 +28,160 @@ protected override void Dispose(bool disposing)
///
private void InitializeComponent()
{
- this.components = new System.ComponentModel.Container();
- this.cbDevices = new System.Windows.Forms.ComboBox();
- this.label1 = new System.Windows.Forms.Label();
- this.formsPlot1 = new ScottPlot.FormsPlot();
- this.timer1 = new System.Windows.Forms.Timer(this.components);
- this.cbAutoAxis = new System.Windows.Forms.CheckBox();
- this.cbDecibel = new System.Windows.Forms.CheckBox();
- this.label3 = new System.Windows.Forms.Label();
- this.label4 = new System.Windows.Forms.Label();
- this.label5 = new System.Windows.Forms.Label();
- this.lblPeak = new System.Windows.Forms.Label();
- this.cbPeak = new System.Windows.Forms.CheckBox();
- this.SuspendLayout();
+ components = new System.ComponentModel.Container();
+ cbDevices = new System.Windows.Forms.ComboBox();
+ label1 = new System.Windows.Forms.Label();
+ formsPlot1 = new ScottPlot.FormsPlot();
+ timer1 = new System.Windows.Forms.Timer(components);
+ cbAutoAxis = new System.Windows.Forms.CheckBox();
+ cbDecibel = new System.Windows.Forms.CheckBox();
+ label3 = new System.Windows.Forms.Label();
+ label4 = new System.Windows.Forms.Label();
+ label5 = new System.Windows.Forms.Label();
+ lblPeak = new System.Windows.Forms.Label();
+ cbPeak = new System.Windows.Forms.CheckBox();
+ SuspendLayout();
//
// cbDevices
//
- this.cbDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
- this.cbDevices.FormattingEnabled = true;
- this.cbDevices.Location = new System.Drawing.Point(12, 25);
- this.cbDevices.Name = "cbDevices";
- this.cbDevices.Size = new System.Drawing.Size(121, 21);
- this.cbDevices.TabIndex = 0;
- this.cbDevices.SelectedIndexChanged += new System.EventHandler(this.cbDevices_SelectedIndexChanged);
+ cbDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ cbDevices.FormattingEnabled = true;
+ cbDevices.Location = new System.Drawing.Point(14, 29);
+ cbDevices.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ cbDevices.Name = "cbDevices";
+ cbDevices.Size = new System.Drawing.Size(140, 23);
+ cbDevices.TabIndex = 0;
+ cbDevices.SelectedIndexChanged += cbDevices_SelectedIndexChanged;
//
// label1
//
- this.label1.AutoSize = true;
- this.label1.Location = new System.Drawing.Point(12, 9);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(71, 13);
- this.label1.TabIndex = 1;
- this.label1.Text = "Audio Device";
+ label1.AutoSize = true;
+ label1.Location = new System.Drawing.Point(14, 10);
+ label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ label1.Name = "label1";
+ label1.Size = new System.Drawing.Size(77, 15);
+ label1.TabIndex = 1;
+ label1.Text = "Audio Device";
//
// formsPlot1
//
- this.formsPlot1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
- | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.formsPlot1.Location = new System.Drawing.Point(12, 52);
- this.formsPlot1.Name = "formsPlot1";
- this.formsPlot1.Size = new System.Drawing.Size(776, 386);
- this.formsPlot1.TabIndex = 2;
+ formsPlot1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
+ formsPlot1.Location = new System.Drawing.Point(14, 60);
+ formsPlot1.Margin = new System.Windows.Forms.Padding(5, 3, 5, 3);
+ formsPlot1.Name = "formsPlot1";
+ formsPlot1.Size = new System.Drawing.Size(905, 445);
+ formsPlot1.TabIndex = 2;
//
// timer1
//
- this.timer1.Enabled = true;
- this.timer1.Interval = 20;
- this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
+ timer1.Enabled = true;
+ timer1.Interval = 20;
+ timer1.Tick += timer1_Tick;
//
// cbAutoAxis
//
- this.cbAutoAxis.AutoSize = true;
- this.cbAutoAxis.Checked = true;
- this.cbAutoAxis.CheckState = System.Windows.Forms.CheckState.Checked;
- this.cbAutoAxis.Location = new System.Drawing.Point(139, 27);
- this.cbAutoAxis.Name = "cbAutoAxis";
- this.cbAutoAxis.Size = new System.Drawing.Size(70, 17);
- this.cbAutoAxis.TabIndex = 3;
- this.cbAutoAxis.Text = "Auto-Axis";
- this.cbAutoAxis.UseVisualStyleBackColor = true;
+ cbAutoAxis.AutoSize = true;
+ cbAutoAxis.Checked = true;
+ cbAutoAxis.CheckState = System.Windows.Forms.CheckState.Checked;
+ cbAutoAxis.Location = new System.Drawing.Point(162, 31);
+ cbAutoAxis.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ cbAutoAxis.Name = "cbAutoAxis";
+ cbAutoAxis.Size = new System.Drawing.Size(79, 19);
+ cbAutoAxis.TabIndex = 3;
+ cbAutoAxis.Text = "Auto-Axis";
+ cbAutoAxis.UseVisualStyleBackColor = true;
+ cbAutoAxis.CheckedChanged += cbAutoAxis_CheckedChanged;
//
// cbDecibel
//
- this.cbDecibel.AutoSize = true;
- this.cbDecibel.Location = new System.Drawing.Point(215, 27);
- this.cbDecibel.Name = "cbDecibel";
- this.cbDecibel.Size = new System.Drawing.Size(39, 17);
- this.cbDecibel.TabIndex = 4;
- this.cbDecibel.Text = "dB";
- this.cbDecibel.UseVisualStyleBackColor = true;
+ cbDecibel.AutoSize = true;
+ cbDecibel.Location = new System.Drawing.Point(251, 31);
+ cbDecibel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ cbDecibel.Name = "cbDecibel";
+ cbDecibel.Size = new System.Drawing.Size(40, 19);
+ cbDecibel.TabIndex = 4;
+ cbDecibel.Text = "dB";
+ cbDecibel.UseVisualStyleBackColor = true;
+ cbDecibel.CheckedChanged += cbDecibel_CheckedChanged;
//
// label3
//
- this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.label3.AutoSize = true;
- this.label3.ForeColor = System.Drawing.SystemColors.ControlDark;
- this.label3.Location = new System.Drawing.Point(676, 22);
- this.label3.Name = "label3";
- this.label3.Size = new System.Drawing.Size(95, 13);
- this.label3.TabIndex = 6;
- this.label3.Text = "Left-click-drag pan";
+ label3.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
+ label3.AutoSize = true;
+ label3.ForeColor = System.Drawing.SystemColors.ControlDark;
+ label3.Location = new System.Drawing.Point(789, 25);
+ label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ label3.Name = "label3";
+ label3.Size = new System.Drawing.Size(108, 15);
+ label3.TabIndex = 6;
+ label3.Text = "Left-click-drag pan";
//
// label4
//
- this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.label4.AutoSize = true;
- this.label4.ForeColor = System.Drawing.SystemColors.ControlDark;
- this.label4.Location = new System.Drawing.Point(676, 35);
- this.label4.Name = "label4";
- this.label4.Size = new System.Drawing.Size(109, 13);
- this.label4.TabIndex = 7;
- this.label4.Text = "Right-click-drag zoom";
+ label4.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
+ label4.AutoSize = true;
+ label4.ForeColor = System.Drawing.SystemColors.ControlDark;
+ label4.Location = new System.Drawing.Point(789, 40);
+ label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ label4.Name = "label4";
+ label4.Size = new System.Drawing.Size(126, 15);
+ label4.TabIndex = 7;
+ label4.Text = "Right-click-drag zoom";
//
// label5
//
- this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.label5.AutoSize = true;
- this.label5.ForeColor = System.Drawing.SystemColors.ControlDark;
- this.label5.Location = new System.Drawing.Point(676, 9);
- this.label5.Name = "label5";
- this.label5.Size = new System.Drawing.Size(108, 13);
- this.label5.TabIndex = 8;
- this.label5.Text = "Middle-click auto-axis";
+ label5.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
+ label5.AutoSize = true;
+ label5.ForeColor = System.Drawing.SystemColors.ControlDark;
+ label5.Location = new System.Drawing.Point(789, 10);
+ label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ label5.Name = "label5";
+ label5.Size = new System.Drawing.Size(125, 15);
+ label5.TabIndex = 8;
+ label5.Text = "Middle-click auto-axis";
//
// lblPeak
//
- this.lblPeak.AutoSize = true;
- this.lblPeak.Location = new System.Drawing.Point(260, 9);
- this.lblPeak.Name = "lblPeak";
- this.lblPeak.Size = new System.Drawing.Size(131, 13);
- this.lblPeak.TabIndex = 9;
- this.lblPeak.Text = "Peak Frequency: 1234 Hz";
+ lblPeak.AutoSize = true;
+ lblPeak.Location = new System.Drawing.Point(303, 10);
+ lblPeak.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+ lblPeak.Name = "lblPeak";
+ lblPeak.Size = new System.Drawing.Size(137, 15);
+ lblPeak.TabIndex = 9;
+ lblPeak.Text = "Peak Frequency: 1234 Hz";
//
// cbPeak
//
- this.cbPeak.AutoSize = true;
- this.cbPeak.Location = new System.Drawing.Point(263, 27);
- this.cbPeak.Name = "cbPeak";
- this.cbPeak.Size = new System.Drawing.Size(78, 17);
- this.cbPeak.TabIndex = 10;
- this.cbPeak.Text = "show peak";
- this.cbPeak.UseVisualStyleBackColor = true;
+ cbPeak.AutoSize = true;
+ cbPeak.Location = new System.Drawing.Point(307, 31);
+ cbPeak.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ cbPeak.Name = "cbPeak";
+ cbPeak.Size = new System.Drawing.Size(82, 19);
+ cbPeak.TabIndex = 10;
+ cbPeak.Text = "show peak";
+ cbPeak.UseVisualStyleBackColor = true;
//
// FormMicrophone
//
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(800, 450);
- this.Controls.Add(this.lblPeak);
- this.Controls.Add(this.label5);
- this.Controls.Add(this.label4);
- this.Controls.Add(this.label3);
- this.Controls.Add(this.cbPeak);
- this.Controls.Add(this.cbDecibel);
- this.Controls.Add(this.cbAutoAxis);
- this.Controls.Add(this.formsPlot1);
- this.Controls.Add(this.label1);
- this.Controls.Add(this.cbDevices);
- this.Name = "FormMicrophone";
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
- this.Text = "FftSharp Microphone Demo";
- this.ResumeLayout(false);
- this.PerformLayout();
-
+ AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ ClientSize = new System.Drawing.Size(933, 519);
+ Controls.Add(lblPeak);
+ Controls.Add(label5);
+ Controls.Add(label4);
+ Controls.Add(label3);
+ Controls.Add(cbPeak);
+ Controls.Add(cbDecibel);
+ Controls.Add(cbAutoAxis);
+ Controls.Add(formsPlot1);
+ Controls.Add(label1);
+ Controls.Add(cbDevices);
+ Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ Name = "FormMicrophone";
+ StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ Text = "FftSharp Microphone Demo";
+ ResumeLayout(false);
+ PerformLayout();
}
#endregion
diff --git a/src/FftSharp.Demo/FormMicrophone.cs b/src/FftSharp.Demo/FormMicrophone.cs
index 05abec0..f1bebaa 100644
--- a/src/FftSharp.Demo/FormMicrophone.cs
+++ b/src/FftSharp.Demo/FormMicrophone.cs
@@ -1,4 +1,5 @@
-using System;
+using ScottPlot;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
@@ -15,14 +16,16 @@ namespace FftSharp.Demo
{
public partial class FormMicrophone : Form
{
- private const int SAMPLE_RATE = 48000;
- private NAudio.Wave.WaveInEvent wvin;
+ const int SAMPLE_RATE = 48000;
+ NAudio.Wave.WaveInEvent wvin;
+ double MaxLevel = 0;
public FormMicrophone()
{
InitializeComponent();
formsPlot1.Plot.Margins(0);
+ formsPlot1.Plot.Layout(left: 50);
cbDevices.Items.Clear();
for (int i = 0; i < NAudio.Wave.WaveIn.DeviceCount; i++)
@@ -65,10 +68,11 @@ private void timer1_Tick(object sender, EventArgs e)
var window = new Windows.Hanning();
double[] windowed = window.Apply(lastBuffer);
double[] zeroPadded = FftSharp.Pad.ZeroPad(windowed);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(zeroPadded);
double[] fftPower = cbDecibel.Checked ?
- FftSharp.Transform.FFTpower(zeroPadded) :
- FftSharp.Transform.FFTmagnitude(zeroPadded);
- double[] fftFreq = FftSharp.Transform.FFTfreq(SAMPLE_RATE, fftPower.Length);
+ FftSharp.FFT.Power(spectrum) :
+ FftSharp.FFT.Magnitude(spectrum);
+ double[] fftFreq = FftSharp.FFT.FrequencyScale(fftPower.Length, SAMPLE_RATE);
// determine peak frequency
double peakFreq = 0;
@@ -86,7 +90,7 @@ private void timer1_Tick(object sender, EventArgs e)
formsPlot1.Plot.XLabel("Frequency Hz");
// make the plot for the first time, otherwise update the existing plot
- if (formsPlot1.Plot.GetPlottables().Count() == 0)
+ if (formsPlot1.Plot.GetPlottables().Length == 0)
{
signalPlot = formsPlot1.Plot.AddSignal(fftPower, 2.0 * fftPower.Length / SAMPLE_RATE);
peakLine = formsPlot1.Plot.AddVerticalLine(peakFreq, ColorTranslator.FromHtml("#66FF0000"), 2);
@@ -103,6 +107,8 @@ private void timer1_Tick(object sender, EventArgs e)
try
{
formsPlot1.Plot.AxisAuto(horizontalMargin: 0);
+ MaxLevel = Math.Max(MaxLevel, formsPlot1.Plot.GetAxisLimits().YMax);
+ formsPlot1.Plot.SetAxisLimitsY(-MaxLevel / 100, MaxLevel);
}
catch (Exception ex)
{
@@ -119,5 +125,15 @@ private void timer1_Tick(object sender, EventArgs e)
System.Diagnostics.Debug.WriteLine(ex);
}
}
+
+ private void cbAutoAxis_CheckedChanged(object sender, EventArgs e)
+ {
+ MaxLevel = 0;
+ }
+
+ private void cbDecibel_CheckedChanged(object sender, EventArgs e)
+ {
+ MaxLevel = 0;
+ }
}
}
diff --git a/src/FftSharp.Demo/FormMicrophone.resx b/src/FftSharp.Demo/FormMicrophone.resx
index 1f666f2..d731088 100644
--- a/src/FftSharp.Demo/FormMicrophone.resx
+++ b/src/FftSharp.Demo/FormMicrophone.resx
@@ -1,64 +1,4 @@
-
-
-
+
diff --git a/src/FftSharp.Demo/FormQuickstart.cs b/src/FftSharp.Demo/FormQuickstart.cs
index 5109b21..117a5db 100644
--- a/src/FftSharp.Demo/FormQuickstart.cs
+++ b/src/FftSharp.Demo/FormQuickstart.cs
@@ -28,7 +28,8 @@ private void trackBar1_Scroll(object sender, EventArgs e)
private void UpdateFFT(double[] input)
{
// calculate FFT
- double[] fft = FftSharp.Transform.FFTmagnitude(input);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(input);
+ double[] fft = FftSharp.FFT.Magnitude(spectrum);
// plot the input signal
formsPlot1.Plot.Clear();
diff --git a/src/FftSharp.Demo/FormWindowInspector.cs b/src/FftSharp.Demo/FormWindowInspector.cs
index aee9bc8..69fa366 100644
--- a/src/FftSharp.Demo/FormWindowInspector.cs
+++ b/src/FftSharp.Demo/FormWindowInspector.cs
@@ -48,7 +48,8 @@ private void UpdateFrequencyPlot(IWindow window)
double[] xs = ScottPlot.DataGen.Consecutive(fftSize);
double[] ys = xs.Select(x => Math.Sin(x / fftSize * Math.PI * fftSize / 2)).ToArray();
double[] windowed = window.Apply(ys);
- double[] power = Transform.FFTpower(windowed);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(windowed);
+ double[] power = FFT.Power(spectrum);
// hide DC component
power[0] = power[1];
diff --git a/src/FftSharp.Tests/ComplexTests.cs b/src/FftSharp.Tests/ComplexTests.cs
index c651beb..db8fd1c 100644
--- a/src/FftSharp.Tests/ComplexTests.cs
+++ b/src/FftSharp.Tests/ComplexTests.cs
@@ -5,6 +5,7 @@
namespace FftSharp.Tests
{
+ [Obsolete("Use methods which consume System.Numerics.Complex")]
class ComplexTests
{
[Test]
diff --git a/src/FftSharp.Tests/FftFreqTests.cs b/src/FftSharp.Tests/FftFreqTests.cs
index 03e5dbf..baf0f01 100644
--- a/src/FftSharp.Tests/FftFreqTests.cs
+++ b/src/FftSharp.Tests/FftFreqTests.cs
@@ -20,16 +20,15 @@ public void Test_FftFreq_KnownValues()
.ToArray();
// get FFT
- double[] fft = FftSharp.Transform.FFTmagnitude(samples);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(samples);
+ double[] fft = FftSharp.FFT.Magnitude(spectrum);
double[] fftKnown = { 0, 0, 1, 0, 0, 0, 0, 0, 0 };
Assert.That(fft, Is.EqualTo(fftKnown).Within(1e-10));
// calculate FFT frequencies both ways
double[] fftFreqKnown = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
- double[] fftFreq = FftSharp.Transform.FFTfreq(sampleRateHz, fft.Length);
- double[] fftFreq2 = FftSharp.Transform.FFTfreq(sampleRateHz, fft);
+ double[] fftFreq = FftSharp.FFT.FrequencyScale(fft.Length, sampleRateHz);
Assert.That(fftFreq, Is.EqualTo(fftFreqKnown));
- Assert.That(fftFreq2, Is.EqualTo(fftFreqKnown));
ScottPlot.Plot plt1 = new(400, 200);
plt1.AddSignal(samples, sampleRateHz);
@@ -55,24 +54,22 @@ public void Test_Freq_Lookup()
int sampleRate = 16000;
int pointCount = 16;
double[] signal = new double[pointCount];
- double[] fft = FftSharp.Transform.FFTmagnitude(signal);
+
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(signal);
+ double[] fft = FftSharp.FFT.Magnitude(spectrum);
double[] freqsFullKnown = {
0, 1000, 2000, 3000, 4000, 5000, 6000, 7000,
-8000, -7000, -6000, -5000, -4000, -3000, -2000, -1000
};
- double[] freqsFull = FftSharp.Transform.FFTfreq(sampleRate, signal, oneSided: false);
- double[] freqsFull2 = FftSharp.Transform.FFTfreq(sampleRate, signal.Length, oneSided: false);
+ double[] freqsFull = FftSharp.FFT.FrequencyScale(signal.Length, sampleRate, false);
Assert.That(freqsFull, Is.EqualTo(freqsFullKnown));
- Assert.That(freqsFull2, Is.EqualTo(freqsFullKnown));
double[] freqsHalfKnown = {
0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000
};
- double[] freqsHalf = FftSharp.Transform.FFTfreq(sampleRate, fft, oneSided: true);
- double[] freqsHalf2 = FftSharp.Transform.FFTfreq(sampleRate, fft.Length, oneSided: true);
+ double[] freqsHalf = FftSharp.FFT.FrequencyScale(fft.Length, sampleRate, true);
Assert.That(freqsHalf, Is.EqualTo(freqsHalfKnown));
- Assert.That(freqsHalf2, Is.EqualTo(freqsHalfKnown));
}
}
}
diff --git a/src/FftSharp.Tests/FftTests.cs b/src/FftSharp.Tests/FftTests.cs
index 857b6f1..6f87c15 100644
--- a/src/FftSharp.Tests/FftTests.cs
+++ b/src/FftSharp.Tests/FftTests.cs
@@ -10,7 +10,7 @@ public void Test_FFT_Forward()
double[] sample = LoadData.Double("sample.txt");
System.Numerics.Complex[] fft = FftSharp.FFT.Forward(sample);
- Complex[] numpyFft = LoadData.Complex("fft.txt");
+ System.Numerics.Complex[] numpyFft = LoadData.Complex("fft.txt");
Assert.AreEqual(numpyFft.Length, fft.Length);
for (int i = 0; i < fft.Length; i++)
diff --git a/src/FftSharp.Tests/LoadData.cs b/src/FftSharp.Tests/LoadData.cs
index 9678346..1e07d51 100644
--- a/src/FftSharp.Tests/LoadData.cs
+++ b/src/FftSharp.Tests/LoadData.cs
@@ -12,11 +12,11 @@ public static class LoadData
.Select(x => double.Parse(x))
.ToArray();
- public static Complex[] Complex(string fileName) =>
+ public static System.Numerics.Complex[] Complex(string fileName) =>
File.ReadLines($"../../../../../dev/data/{fileName}")
.Select(x => x.Trim('(').Trim(')').Trim('j'))
.Select(x => x.Replace("-", " -").Replace("+", " +").Trim())
- .Select(x => new Complex(double.Parse(x.Split(' ')[0]), double.Parse(x.Split(' ')[1])))
+ .Select(x => new System.Numerics.Complex(double.Parse(x.Split(' ')[0]), double.Parse(x.Split(' ')[1])))
.ToArray();
}
}
diff --git a/src/FftSharp.Tests/Mel.cs b/src/FftSharp.Tests/Mel.cs
index bd6acb7..d6b222e 100644
--- a/src/FftSharp.Tests/Mel.cs
+++ b/src/FftSharp.Tests/Mel.cs
@@ -6,7 +6,7 @@
namespace FftSharp.Tests
{
- #pragma warning disable 618
+#pragma warning disable 618
class Mel
{
[Test]
diff --git a/src/FftSharp.Tests/Padding.cs b/src/FftSharp.Tests/Padding.cs
index 8118b33..390004d 100644
--- a/src/FftSharp.Tests/Padding.cs
+++ b/src/FftSharp.Tests/Padding.cs
@@ -11,12 +11,12 @@ class Padding
[Test]
public void Test_FFT_AllLengthInput()
{
- for (int i = 1; i < 200; i++)
+ for (int i = 2; i < 200; i++)
{
- Complex[] input = new Complex[i];
- Complex[] padded = FftSharp.Pad.ZeroPad(input);
+ System.Numerics.Complex[] input = new System.Numerics.Complex[i];
+ System.Numerics.Complex[] padded = FftSharp.Pad.ZeroPad(input);
Console.WriteLine($"Length {input.Length} -> {padded.Length}");
- FftSharp.Transform.FFT(padded);
+ FftSharp.FFT.Forward(padded);
}
}
}
diff --git a/src/FftSharp.Tests/PeakFrequencyDetection.cs b/src/FftSharp.Tests/PeakFrequencyDetection.cs
index 6d596b3..2ab925d 100644
--- a/src/FftSharp.Tests/PeakFrequencyDetection.cs
+++ b/src/FftSharp.Tests/PeakFrequencyDetection.cs
@@ -15,8 +15,9 @@ public void Test_PeakFrequency_MatchesExpectation()
double sampleRate = 48_000;
double[] signal = FftSharp.SampleData.SampleAudio1(); // 2 kHz peak frequency
- double[] fftMag = FftSharp.Transform.FFTmagnitude(signal);
- double[] fftFreq = FftSharp.Transform.FFTfreq(sampleRate, fftMag);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(signal);
+ double[] fftMag = FftSharp.FFT.Magnitude(spectrum);
+ double[] fftFreq = FftSharp.FFT.FrequencyScale(fftMag.Length, sampleRate);
int peakIndex = 0;
double peakValue = fftMag[0];
diff --git a/src/FftSharp.Tests/Quickstart.cs b/src/FftSharp.Tests/Quickstart.cs
index 4ac5ba3..d943bc9 100644
--- a/src/FftSharp.Tests/Quickstart.cs
+++ b/src/FftSharp.Tests/Quickstart.cs
@@ -31,13 +31,13 @@ public static void Test_SimpleFftWithGraphs(bool useWindow)
}
// You could get the FFT as a complex result
- Complex[] fft = FftSharp.Transform.FFT(audio);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(audio);
// For audio we typically want the FFT amplitude (in dB)
- double[] fftPower = FftSharp.Transform.FFTpower(audio);
+ double[] fftPower = FftSharp.FFT.Power(spectrum);
// Create an array of frequencies for each point of the FFT
- double[] freqs = FftSharp.Transform.FFTfreq(sampleRate, fftPower.Length);
+ double[] freqs = FftSharp.FFT.FrequencyScale(fftPower.Length, sampleRate);
// create an array of audio sample times to aid plotting
double[] times = ScottPlot.DataGen.Consecutive(audio.Length, 1000d / sampleRate);
diff --git a/src/FftSharp.Tests/Readme.cs b/src/FftSharp.Tests/Readme.cs
index 49e4b0f..ce07b54 100644
--- a/src/FftSharp.Tests/Readme.cs
+++ b/src/FftSharp.Tests/Readme.cs
@@ -18,11 +18,11 @@ public void Test_Readme_Quickstart()
window.ApplyInPlace(signal);
// Calculate the FFT as an array of complex numbers
- Complex[] fft = FftSharp.Transform.FFT(signal);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(signal);
// Or get the spectral power (dB) or magnitude (RMS²) as real numbers
- double[] fftPwr = FftSharp.Transform.FFTpower(signal);
- double[] fftMag = FftSharp.Transform.FFTmagnitude(signal);
+ double[] fftPower = FftSharp.FFT.Power(spectrum);
+ double[] fftMagnitude = FftSharp.FFT.Magnitude(spectrum);
}
[Test]
@@ -49,8 +49,9 @@ public void Test_Plot_MagnitudePowerFreq()
int sampleRate = 48_000;
// calculate the power spectral density using FFT
- double[] psd = FftSharp.Transform.FFTpower(signal);
- double[] freq = FftSharp.Transform.FFTfreq(sampleRate, psd.Length);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(signal);
+ double[] psd = FftSharp.FFT.Power(spectrum);
+ double[] freq = FftSharp.FFT.FrequencyScale(psd.Length, sampleRate);
// plot the sample audio
var plt = new ScottPlot.Plot(400, 200);
@@ -62,20 +63,6 @@ public void Test_Plot_MagnitudePowerFreq()
plt.SaveFig(Path.Combine(OUTPUT_FOLDER, "periodogram.png"));
}
- [Test]
- public void Test_Complex()
- {
- Complex[] buffer =
- {
- new Complex(42, 0),
- new Complex(96, 0),
- new Complex(13, 0),
- new Complex(99, 0),
- };
-
- FftSharp.Transform.FFT(buffer);
- }
-
[Test]
public void Test_Window()
{
diff --git a/src/FftSharp.Tests/Value.cs b/src/FftSharp.Tests/Value.cs
index 24de115..ed02314 100644
--- a/src/FftSharp.Tests/Value.cs
+++ b/src/FftSharp.Tests/Value.cs
@@ -18,7 +18,7 @@ public void Test_FFT_ValuesMatchNumpy()
// https://numpy.org/doc/1.18/reference/generated/numpy.fft.fft.html
// This test assserts our FFT results match Numpy's
- Complex[] fft = FftSharp.Transform.FFT(audio);
+ System.Numerics.Complex[] fft = FftSharp.FFT.Forward(audio);
for (int i = 0; i < fft.Length; i++)
{
Assert.AreEqual(numpyFFT[i].Real, fft[i].Real, 1e-12);
@@ -34,13 +34,14 @@ public void Test_RFFT_ValuesMatchNumpy()
// https://numpy.org/doc/1.18/reference/generated/numpy.fft.rfft.html
// This test assserts our FFT results match Numpy's
- Complex[] rfft = FftSharp.Transform.RFFT(audio);
- Assert.AreEqual(NumpyRFFT.Length, rfft.Length);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.ForwardReal(audio);
- for (int i = 0; i < rfft.Length; i++)
+ Assert.AreEqual(NumpyRFFT.Length, spectrum.Length);
+
+ for (int i = 0; i < spectrum.Length; i++)
{
- Assert.AreEqual(NumpyRFFT[i].Real, rfft[i].Real, 1e-12);
- Assert.AreEqual(NumpyRFFT[i].Imaginary, rfft[i].Imaginary, 1e-12);
+ Assert.AreEqual(NumpyRFFT[i].Real, spectrum[i].Real, 1e-12);
+ Assert.AreEqual(NumpyRFFT[i].Imaginary, spectrum[i].Imaginary, 1e-12);
}
}
@@ -52,15 +53,14 @@ public void Test_Absolute_ValuesMatchNumpy()
// https://numpy.org/doc/1.18/reference/generated/numpy.fft.rfft.html
// This test assserts our FFT results match Numpy's
- Complex[] rfft = FftSharp.Transform.RFFT(audio);
- double[] rfftAbs = FftSharp.Transform.Absolute(rfft);
+ System.Numerics.Complex[] real = FftSharp.FFT.ForwardReal(audio);
+ double[] magnitudes = real.Select(x => x.Magnitude).ToArray();
- Assert.AreEqual(rfftAbs.Length, rfft.Length);
+ Assert.AreEqual(NumpyRFFTabs.Length, magnitudes.Length);
- for (int i = 0; i < rfftAbs.Length; i++)
+ for (int i = 0; i < NumpyRFFTabs.Length; i++)
{
- Assert.AreEqual(NumpyRFFTabs[i], rfftAbs[i], 1e-12);
- Assert.AreEqual(NumpyRFFTabs[i], rfftAbs[i], 1e-12);
+ Assert.AreEqual(NumpyRFFTabs[i], magnitudes[i], 1e-12);
}
}
@@ -72,10 +72,10 @@ public void Test_FFTfast_ValuesMatchNumpy()
// https://numpy.org/doc/1.18/reference/generated/numpy.fft.fft.html
// This test assserts our FFT results match Numpy's
- Complex[] fft = new Complex[audio.Length];
+ System.Numerics.Complex[] fft = new System.Numerics.Complex[audio.Length];
for (int i = 0; i < audio.Length; i++)
- fft[i] = new Complex(audio[i], 0);
- FftSharp.Transform.FFT(fft);
+ fft[i] = new(audio[i], 0);
+ FftSharp.FFT.Forward(fft);
for (int i = 0; i < fft.Length; i++)
{
@@ -92,12 +92,12 @@ public void Test_FftFromDoubleArray_MatchesFftResult()
// https://numpy.org/doc/1.18/reference/generated/numpy.fft.fft.html
// This test assserts our FFT results match Numpy's
- Complex[] fft = new Complex[audio.Length];
+ System.Numerics.Complex[] fft = new System.Numerics.Complex[audio.Length];
for (int i = 0; i < audio.Length; i++)
- fft[i] = new Complex(audio[i], 0);
- FftSharp.Transform.FFT(fft);
+ fft[i] = new(audio[i], 0);
+ FftSharp.FFT.Forward(fft);
- Complex[] fft2 = FftSharp.Transform.FFT(audio);
+ System.Numerics.Complex[] fft2 = FftSharp.FFT.Forward(audio);
for (int i = 0; i < fft.Length; i++)
{
@@ -108,837 +108,837 @@ public void Test_FftFromDoubleArray_MatchesFftResult()
private readonly double[] audio =
{
-0.330, 2.150, 1.440, 1.370, 0.240, 2.600, 3.510, 1.980, 1.880, 0.080,
-1.820, 1.300, 0.230, -1.160, -1.350, -0.580, -0.840, -1.350, -2.720, -2.530,
--0.020, -0.760, -0.480, -2.100, 0.300, 1.860, 1.600, 1.490, 0.580, 2.120,
-2.790, 1.990, 1.200, 0.800, 2.180, 1.600, -0.370, -1.250, -1.990, 0.350,
--1.190, -1.620, -3.280, -2.570, 0.070, -0.810, -1.130, -1.680, -0.250, 1.550,
-1.080, 1.530, 0.650, 2.530, 2.790, 2.420, 1.720, 0.540, 2.390, 1.510,
-0.220, -1.420, -1.440, 0.290, -1.610, -1.500, -3.230, -2.200, -0.010, -1.390,
--0.470, -1.650, 0.250, 2.050, 1.480, 0.910, 0.760, 2.760, 2.730, 2.450,
-1.090, 0.280, 2.070, 1.160, 0.270, -1.170, -1.500, 0.200, -0.910, -1.580,
--2.460, -2.550, -0.310, -0.940, -1.130, -1.850, 0.420, 1.560, 0.850, 0.880,
-0.660, 2.730, 3.230, 2.470, 1.120, 0.740, 1.600, 1.730, 0.280, -1.540,
--2.180, -0.500, -1.090, -1.390, -2.910, -2.690, -0.160, -1.040, -1.240, -1.520,
--0.390, 1.690, 1.520, 0.870, 0.310, 2.750, 3.560, 2.530, 1.290, 0.330,
-1.810, 1.340, 0.130, -1.580, -2.050, -0.110, -0.850, -1.730, -3.300, -2.100,
--0.430, -0.670, -1.340, -1.430, 0.220, 2.160, 1.350, 1.380, 0.210, 2.230,
-3.210, 1.790, 1.900, 0.380, 1.600, 1.100, 0.440, -1.070, -1.690, -0.090,
--0.730, -2.260, -2.890, -2.680, -0.020, -0.960, -0.890, -1.580, 0.270, 2.330,
-0.970, 0.870, 0.500, 2.520, 2.820, 1.610, 1.130, -0.040, 1.980, 1.280,
--0.380, -1.240, -1.520, -0.400, -0.790, -2.310, -2.890, -1.880, 0.160, -1.590,
--0.810, -1.860, 0.570, 1.920, 1.440, 1.130, 0.450, 3.020, 3.490, 2.510,
-1.150, -0.060, 2.430, 1.010, 0.480, -1.090, -1.550, -0.090, -1.350, -1.350,
--3.370, -2.150, -0.710, -1.410, -0.970, -1.550, -0.140, 1.640, 0.910, 1.590,
-0.170, 2.650, 3.160, 2.200, 1.240, -0.170, 1.630, 1.710, 0.310, -0.740,
--1.680, -0.350, -1.430, -1.870, -3.200, -1.950, -0.340, -0.970, -1.150, -1.760,
--0.160, 2.330, 1.280, 0.810, 1.020, 3.000, 2.760, 2.310, 0.990, -0.000,
-1.600, 0.940, 0.330, -1.530, -1.490, 0.040, -1.130, -2.100, -2.560, -1.980,
--0.390, -0.700, -0.660, -1.670, -0.060, 2.110, 1.090, 1.450, 1.030, 2.650,
-2.690, 2.160, 1.890, 0.680, 2.070, 0.970, -0.400, -1.080, -1.660, -0.230,
--0.830, -2.020, -2.610, -2.320, -0.000, -1.070, -0.940, -1.970, 0.230, 1.890,
-0.980, 1.060, 0.830, 2.500, 3.520, 1.880, 1.090, -0.040, 2.190, 1.040,
-0.130, -1.120, -1.560, -0.120, -1.600, -1.900, -3.280, -1.980, -0.270, -0.900,
--0.830, -2.120, 0.170, 1.790, 1.660, 0.930, 0.150, 2.320, 3.230, 2.340,
-1.150, 0.070, 1.550, 1.280, -0.110, -0.790, -1.510, -0.080, -0.750, -2.140,
--2.450, -1.990, 0.060, -1.140, -0.620, -1.780, 0.150, 1.640, 1.090, 1.200,
-0.450, 2.700, 3.200, 2.470, 1.810, 0.110, 2.210, 1.180, 0.070, -0.830,
--2.120, 0.300, -1.180, -1.480, -2.450, -2.570, -0.340, -1.280, -1.280, -1.870,
-0.220, 1.920, 1.580, 1.170, 0.790, 2.830, 2.720, 1.640, 1.510, 0.440,
-2.100, 1.650, 0.460, -1.390, -1.960, -0.010, -1.040, -2.260, -2.870, -1.850,
--0.670, -1.130, -1.400, -1.980, 0.590, 1.370, 1.000, 0.840, 0.550, 2.610,
-3.460, 1.760, 1.020, -0.040, 2.310, 1.670, 0.350, -1.390, -2.160, -0.480,
--1.520, -1.760, -2.670, -2.010, -0.600, -1.210, -1.420, -1.850, 0.080, 1.690,
-1.270, 1.220, 0.830, 2.230, 2.700, 1.680, 1.420, 0.560, 1.910, 1.550,
-0.060, -1.550, -1.750, -0.570, -0.920, -1.990, -2.700, -2.130, -0.370, -1.060,
--0.630, -1.710, 0.510, 1.740, 1.480, 1.390, 0.780, 2.270, 3.520, 2.130,
-1.890, -0.140, 2.080, 0.990, 0.570, -1.190, -1.900, 0.320, -1.640, -1.700,
--3.090, -1.840, 0.030, -1.150, -0.800, -2.040, 0.590, 2.020, 0.720, 1.690,
-0.730, 2.380, 3.420, 2.480, 1.420, -0.010, 2.040, 1.220, -0.020, -1.110,
--1.950, -0.320, -0.870, -1.550, -2.670, -2.440, -0.300, -1.180, -1.390, -1.800,
-0.520, 2.110, 1.320, 1.630, 0.270, 2.880, 3.160, 1.990, 1.640, 0.530,
-2.120, 0.900, -0.220, -1.590, -1.450, 0.050, -1.460, -1.730, -2.760, -2.060,
-0.100, -1.560, -0.920, -1.600, -0.140, 1.350, 0.830, 0.880, 0.760, 2.300,
-3.160, 2.110,
-};
+ 0.330, 2.150, 1.440, 1.370, 0.240, 2.600, 3.510, 1.980, 1.880, 0.080,
+ 1.820, 1.300, 0.230, -1.160, -1.350, -0.580, -0.840, -1.350, -2.720, -2.530,
+ -0.020, -0.760, -0.480, -2.100, 0.300, 1.860, 1.600, 1.490, 0.580, 2.120,
+ 2.790, 1.990, 1.200, 0.800, 2.180, 1.600, -0.370, -1.250, -1.990, 0.350,
+ -1.190, -1.620, -3.280, -2.570, 0.070, -0.810, -1.130, -1.680, -0.250, 1.550,
+ 1.080, 1.530, 0.650, 2.530, 2.790, 2.420, 1.720, 0.540, 2.390, 1.510,
+ 0.220, -1.420, -1.440, 0.290, -1.610, -1.500, -3.230, -2.200, -0.010, -1.390,
+ -0.470, -1.650, 0.250, 2.050, 1.480, 0.910, 0.760, 2.760, 2.730, 2.450,
+ 1.090, 0.280, 2.070, 1.160, 0.270, -1.170, -1.500, 0.200, -0.910, -1.580,
+ -2.460, -2.550, -0.310, -0.940, -1.130, -1.850, 0.420, 1.560, 0.850, 0.880,
+ 0.660, 2.730, 3.230, 2.470, 1.120, 0.740, 1.600, 1.730, 0.280, -1.540,
+ -2.180, -0.500, -1.090, -1.390, -2.910, -2.690, -0.160, -1.040, -1.240, -1.520,
+ -0.390, 1.690, 1.520, 0.870, 0.310, 2.750, 3.560, 2.530, 1.290, 0.330,
+ 1.810, 1.340, 0.130, -1.580, -2.050, -0.110, -0.850, -1.730, -3.300, -2.100,
+ -0.430, -0.670, -1.340, -1.430, 0.220, 2.160, 1.350, 1.380, 0.210, 2.230,
+ 3.210, 1.790, 1.900, 0.380, 1.600, 1.100, 0.440, -1.070, -1.690, -0.090,
+ -0.730, -2.260, -2.890, -2.680, -0.020, -0.960, -0.890, -1.580, 0.270, 2.330,
+ 0.970, 0.870, 0.500, 2.520, 2.820, 1.610, 1.130, -0.040, 1.980, 1.280,
+ -0.380, -1.240, -1.520, -0.400, -0.790, -2.310, -2.890, -1.880, 0.160, -1.590,
+ -0.810, -1.860, 0.570, 1.920, 1.440, 1.130, 0.450, 3.020, 3.490, 2.510,
+ 1.150, -0.060, 2.430, 1.010, 0.480, -1.090, -1.550, -0.090, -1.350, -1.350,
+ -3.370, -2.150, -0.710, -1.410, -0.970, -1.550, -0.140, 1.640, 0.910, 1.590,
+ 0.170, 2.650, 3.160, 2.200, 1.240, -0.170, 1.630, 1.710, 0.310, -0.740,
+ -1.680, -0.350, -1.430, -1.870, -3.200, -1.950, -0.340, -0.970, -1.150, -1.760,
+ -0.160, 2.330, 1.280, 0.810, 1.020, 3.000, 2.760, 2.310, 0.990, -0.000,
+ 1.600, 0.940, 0.330, -1.530, -1.490, 0.040, -1.130, -2.100, -2.560, -1.980,
+ -0.390, -0.700, -0.660, -1.670, -0.060, 2.110, 1.090, 1.450, 1.030, 2.650,
+ 2.690, 2.160, 1.890, 0.680, 2.070, 0.970, -0.400, -1.080, -1.660, -0.230,
+ -0.830, -2.020, -2.610, -2.320, -0.000, -1.070, -0.940, -1.970, 0.230, 1.890,
+ 0.980, 1.060, 0.830, 2.500, 3.520, 1.880, 1.090, -0.040, 2.190, 1.040,
+ 0.130, -1.120, -1.560, -0.120, -1.600, -1.900, -3.280, -1.980, -0.270, -0.900,
+ -0.830, -2.120, 0.170, 1.790, 1.660, 0.930, 0.150, 2.320, 3.230, 2.340,
+ 1.150, 0.070, 1.550, 1.280, -0.110, -0.790, -1.510, -0.080, -0.750, -2.140,
+ -2.450, -1.990, 0.060, -1.140, -0.620, -1.780, 0.150, 1.640, 1.090, 1.200,
+ 0.450, 2.700, 3.200, 2.470, 1.810, 0.110, 2.210, 1.180, 0.070, -0.830,
+ -2.120, 0.300, -1.180, -1.480, -2.450, -2.570, -0.340, -1.280, -1.280, -1.870,
+ 0.220, 1.920, 1.580, 1.170, 0.790, 2.830, 2.720, 1.640, 1.510, 0.440,
+ 2.100, 1.650, 0.460, -1.390, -1.960, -0.010, -1.040, -2.260, -2.870, -1.850,
+ -0.670, -1.130, -1.400, -1.980, 0.590, 1.370, 1.000, 0.840, 0.550, 2.610,
+ 3.460, 1.760, 1.020, -0.040, 2.310, 1.670, 0.350, -1.390, -2.160, -0.480,
+ -1.520, -1.760, -2.670, -2.010, -0.600, -1.210, -1.420, -1.850, 0.080, 1.690,
+ 1.270, 1.220, 0.830, 2.230, 2.700, 1.680, 1.420, 0.560, 1.910, 1.550,
+ 0.060, -1.550, -1.750, -0.570, -0.920, -1.990, -2.700, -2.130, -0.370, -1.060,
+ -0.630, -1.710, 0.510, 1.740, 1.480, 1.390, 0.780, 2.270, 3.520, 2.130,
+ 1.890, -0.140, 2.080, 0.990, 0.570, -1.190, -1.900, 0.320, -1.640, -1.700,
+ -3.090, -1.840, 0.030, -1.150, -0.800, -2.040, 0.590, 2.020, 0.720, 1.690,
+ 0.730, 2.380, 3.420, 2.480, 1.420, -0.010, 2.040, 1.220, -0.020, -1.110,
+ -1.950, -0.320, -0.870, -1.550, -2.670, -2.440, -0.300, -1.180, -1.390, -1.800,
+ 0.520, 2.110, 1.320, 1.630, 0.270, 2.880, 3.160, 1.990, 1.640, 0.530,
+ 2.120, 0.900, -0.220, -1.590, -1.450, 0.050, -1.460, -1.730, -2.760, -2.060,
+ 0.100, -1.560, -0.920, -1.600, -0.140, 1.350, 0.830, 0.880, 0.760, 2.300,
+ 3.160, 2.110,
+ };
// generated with python/Numpy: fft = numpy.fft.fft(sampleAudio1)
- private readonly Complex[] numpyFFT =
+ private readonly System.Numerics.Complex[] numpyFFT =
{
-new Complex(71.52, 0.0),
-new Complex(16.292599219664993, -1.650266240953031),
-new Complex(16.58819220541474, -4.456837908626264),
-new Complex(11.867798701774102, 0.7429551118770812),
-new Complex(6.339252942386048, 1.3944730123175706),
-new Complex(5.091353556901778, -4.23187134652945),
-new Complex(18.814490506606102, -8.665625451587731),
-new Complex(16.81258122144206, 1.5049383063313775),
-new Complex(16.250262936175652, -10.898983835764772),
-new Complex(9.653138749580403, -3.4907810508138843),
-new Complex(13.307669165815344, -4.967069973560199),
-new Complex(14.963784782916647, -12.000161985633959),
-new Complex(11.96745034011839, -6.99870154432028),
-new Complex(20.457611574040772, -7.503111641685473),
-new Complex(16.65888595885314, -13.091972828691972),
-new Complex(21.507612856521956, -0.699201769934322),
-new Complex(26.771895548958383, -16.35220257819907),
-new Complex(31.077223230796143, -16.494436421460076),
-new Complex(45.10852008979767, -20.58984095476262),
-new Complex(59.25922110005847, -29.04396354790871),
-new Complex(94.30531062507758, -51.976078289996565),
-new Complex(366.88585732605077, -205.12349027793272),
-new Complex(-177.8491671506428, 105.09540721761974),
-new Complex(-71.83350266181674, 50.22287606700222),
-new Complex(-45.553168448188615, 26.10712988794811),
-new Complex(-20.986245062901816, 15.999954756852027),
-new Complex(-24.858594932136125, 13.645918510329325),
-new Complex(-19.173373012705525, 16.449007609589398),
-new Complex(-8.537098037860998, 8.88530912169331),
-new Complex(-11.266585527651117, 8.094594399106153),
-new Complex(-9.241923204154396, -1.847317739378453),
-new Complex(-10.46615838300978, 4.64345496924585),
-new Complex(-12.27027085039127, 5.87765864860703),
-new Complex(-7.370274298222351, 6.341810090314409),
-new Complex(-1.2131051366901628, 6.993893647840464),
-new Complex(-6.1359988292690755, 7.692984484782312),
-new Complex(4.091706423869168, 1.365798023974214),
-new Complex(-4.655458008198221, -0.7217109700711242),
-new Complex(-4.463444898038833, 2.2094751854192),
-new Complex(-2.4342160634907675, 11.254011503392162),
-new Complex(5.098783312195228, 4.827669742579822),
-new Complex(-5.831778282084546, 4.025856294966041),
-new Complex(3.665136034495667, 5.806578149334394),
-new Complex(-6.782761994698575, 12.087457969879013),
-new Complex(-0.454577044366566, 8.989165374120152),
-new Complex(1.1190972614148489, 7.3826047223482005),
-new Complex(-5.300512604596365, 3.3787295501896804),
-new Complex(-5.303638228818758, 0.663150420740581),
-new Complex(-1.402392307772061, 4.385841205789253),
-new Complex(2.839320733358291, 6.177222092996357),
-new Complex(-5.471846454174141, -3.646041429888425),
-new Complex(-0.1825607735763244, 4.335020541082649),
-new Complex(0.23366490444061006, 12.53115614224979),
-new Complex(-4.607834909859168, 2.731226568868507),
-new Complex(0.4407190353942614, 5.867753191224533),
-new Complex(-0.6346634815558851, 5.2502903349451495),
-new Complex(-4.644687701252085, 13.308500752662315),
-new Complex(-4.186255039897505, 1.883033665479715),
-new Complex(3.1011324895272105, 6.889303301004),
-new Complex(-5.994624072627106, 3.0893738437673104),
-new Complex(2.148665980983523, -2.165175261206472),
-new Complex(8.120784577044827, -1.026413324380261),
-new Complex(-2.736075709061385, 8.309850036461317),
-new Complex(-1.122976392687268, 1.3868358039512898),
-new Complex(-0.4420963209812834, 3.394939033455901),
-new Complex(10.571135745703966, -7.214497105214868),
-new Complex(-0.6361813663828921, 6.457986031215809),
-new Complex(-0.0025957626844732573, 9.037941129554671),
-new Complex(-2.797973427324928, -1.3949959065210518),
-new Complex(0.32042128744426146, 5.166759010512948),
-new Complex(1.8672167221767477, 3.7484970064639),
-new Complex(4.284785289539634, 11.97800470285899),
-new Complex(-1.9130289340345799, 4.890086838063299),
-new Complex(-8.063646970616297, 7.70671282524425),
-new Complex(-2.5076616550924244, -0.5616066179697525),
-new Complex(4.848590964002215, 0.4155821028619835),
-new Complex(0.6519047716752894, 8.365467739744268),
-new Complex(5.925896594814173, 1.6214148805227862),
-new Complex(-0.11732472297714991, 2.084514460872517),
-new Complex(3.1379824354268417, -6.2577633910536195),
-new Complex(6.774385287871493, 9.629330590835693),
-new Complex(5.4393155868096645, -6.121406497914311),
-new Complex(1.0174178671562233, -8.607714904038465),
-new Complex(5.398310408984056, -7.203490766128718),
-new Complex(-3.785148744276335, 3.9182113455816534),
-new Complex(7.557346542357081, 6.081240307670624),
-new Complex(-8.76993242973248, 5.33687737351268),
-new Complex(-0.30138424584816725, 2.3135609200854255),
-new Complex(6.9465856216898105, 8.502927040297298),
-new Complex(-8.363128478889873, 9.156259453584855),
-new Complex(9.67066074018313, 4.95686087152842),
-new Complex(8.861238026483612, -0.9840687253038303),
-new Complex(10.426812822364912, -3.327862985228994),
-new Complex(7.296132588971696, 4.341249905128431),
-new Complex(2.513188500291645, 5.861603466455876),
-new Complex(-1.0480377808580927, 3.4893475665297666),
-new Complex(7.821845003550149, -1.9841378599467063),
-new Complex(-1.6324823820087873, 7.790777253754385),
-new Complex(8.970903795772337, 4.066014902164978),
-new Complex(-1.6707970781871344, 2.136015162752384),
-new Complex(7.25823248662058, 2.7652788765225464),
-new Complex(18.74397062908053, 8.896718444008549),
-new Complex(2.1660703208919037, -0.16068219834732878),
-new Complex(13.825097858675338, 8.427493951505237),
-new Complex(18.47832853222178, 12.667650849412713),
-new Complex(37.569125833815264, 21.578994508186412),
-new Complex(90.94566028906655, 50.697370827337764),
-new Complex(-191.4717302736666, -117.08331011378777),
-new Complex(-51.32832640613284, -23.124699639369688),
-new Complex(-23.500774862545306, -12.60161060026162),
-new Complex(-23.59827162418354, -16.220434411970672),
-new Complex(-21.623922884263543, -12.128429398236538),
-new Complex(-8.156016294103669, -2.0796298320611637),
-new Complex(-3.320934257799828, -4.826944007044764),
-new Complex(-8.966686390330285, 2.8174321266953233),
-new Complex(-4.036510916197747, -8.306905035682055),
-new Complex(-9.118052343426735, -0.7998264524711765),
-new Complex(1.7056006968282986, 2.48014371582694),
-new Complex(-0.4317759856237964, -2.0729669596807687),
-new Complex(1.3875511565884053, -2.3921170941765446),
-new Complex(-7.976980514611284, 4.704983072668933),
-new Complex(-1.0412939420119793, 2.0304346948254044),
-new Complex(-0.4712297547813127, -1.8877908393403056),
-new Complex(-12.834400468053518, -1.928010984003001),
-new Complex(-0.4020716349072191, -4.708004655448063),
-new Complex(-8.267438571150924, -3.7039764685576895),
-new Complex(-4.8684310845372405, -5.189260677129305),
-new Complex(0.4631251388647053, 1.0836107137372681),
-new Complex(0.9899999999999949, -2.049999999999997),
-new Complex(-4.84931978116202, -0.23933081088023878),
-new Complex(-9.934189775670093, 0.7971585720723557),
-new Complex(-2.600011910104527, -0.9923343205338109),
-new Complex(-2.160469164514625, -5.322803319988892),
-new Complex(-8.342213173106142, -0.17252901564132728),
-new Complex(-4.196598202151177, -4.7274680682126755),
-new Complex(-4.944944633762713, -1.4791201736168527),
-new Complex(-6.434479741808574, 6.482812912010042),
-new Complex(-5.158937174706397, 3.713563429843517),
-new Complex(-2.5917604439233597, -1.074410553473996),
-new Complex(1.6430036734162927, -0.26848993074113725),
-new Complex(-4.68619932790007, 3.5540911138722024),
-new Complex(-9.114112417604312, -5.863251584381021),
-new Complex(-1.511010285838398, 0.5916676752843228),
-new Complex(-1.0248996347649997, -5.221535985301575),
-new Complex(-5.907774632673288, 3.6263871521782516),
-new Complex(-0.8134349081877801, -2.8827110905821716),
-new Complex(-3.8883597256888898, 6.5096521647811105),
-new Complex(3.6028695146052687, 4.906754934650181),
-new Complex(-1.43392165399176, 0.09877393185500516),
-new Complex(2.5399337102167436, -2.6091846772843255),
-new Complex(-2.4029291340916004, 4.978313193479735),
-new Complex(-3.715287570789176, -4.39451837716846),
-new Complex(-10.306371528157012, -2.7488670997481837),
-new Complex(-0.024313261096906125, -5.986905188653612),
-new Complex(-2.8298389130063915, 3.448368650672101),
-new Complex(4.7341520993712995, -11.062510314288573),
-new Complex(-5.3829294937018854, -2.783057603406332),
-new Complex(0.0026383233212190493, -0.18978654624226898),
-new Complex(-1.8812828884644066, 4.871022697842905),
-new Complex(-3.2509005555527533, 1.4393838886348913),
-new Complex(-2.3369676800222434, 2.482582201564716),
-new Complex(-1.2142355119041524, 0.1834635506672304),
-new Complex(-9.582245656802916, -0.027020924935291735),
-new Complex(-6.581883483527928, -0.9168370285871652),
-new Complex(2.23633907309973, -2.3021508943840727),
-new Complex(-2.0748219655573625, -2.0037979487038773),
-new Complex(-3.765563906978262, 3.088432721629983),
-new Complex(5.332530718835812, -2.0516059158581865),
-new Complex(-0.2549012255641858, -0.6932903665209049),
-new Complex(-7.277178212857739, 2.9116631246832343),
-new Complex(-2.1936009994012435, 0.4001679051474425),
-new Complex(-8.794157662232939, 3.5717135906207176),
-new Complex(9.191032309546063, -1.9398929261634499),
-new Complex(-3.869682067783085, 0.5152936097585425),
-new Complex(3.147392558038452, 2.216334156350135),
-new Complex(4.337683896574441, 0.82997589223395),
-new Complex(5.8600818792670735, 0.02923610475152838),
-new Complex(-2.7839860346841525, 2.4914655265099466),
-new Complex(-1.903842415258608, 1.4113411741607438),
-new Complex(-9.894054706023422, 4.9668960901740284),
-new Complex(-0.8081382242155792, 11.349170741938877),
-new Complex(8.373197781633165, 2.1638002986517635),
-new Complex(-2.4852724753585846, 4.218258048332267),
-new Complex(-3.755737925182469, -4.490350833996583),
-new Complex(-2.879274257660312, 2.1626921190768043),
-new Complex(0.7024288556739815, -0.03525952952816347),
-new Complex(-2.673777491391463, 2.058724091865224),
-new Complex(2.1942581278786912, -4.751521874754496),
-new Complex(3.8112923807165675, 3.5946006951844867),
-new Complex(4.095532859213184, -0.28973422842765917),
-new Complex(-6.83825512481851, -9.6297170417451),
-new Complex(-1.9910301634396683, -10.188877845696899),
-new Complex(-1.4179036790187196, -3.8050609665441018),
-new Complex(-4.500591208775358, 2.5115489328726808),
-new Complex(2.5605067559698993, -1.0184596329131184),
-new Complex(6.717336341148254, -1.1098887472444834),
-new Complex(-3.6308727316719613, -2.930509025563401),
-new Complex(-1.2800687813817113, -5.2293267918825705),
-new Complex(-0.24178054270822846, -0.34674641143824747),
-new Complex(-3.5825821902320762, -6.877312499750982),
-new Complex(-2.602886071425474, -6.86407264784425),
-new Complex(-1.2785892290938932, -1.6397567663004344),
-new Complex(-8.675100612964963, -7.055963310707158),
-new Complex(8.84974247542792, -6.56325254726892),
-new Complex(2.885016983143895, -6.95362008379264),
-new Complex(6.918222156603157, 9.497082265446183),
-new Complex(4.10405309937396, -7.9120673382156275),
-new Complex(-1.584044627114519, -3.1949874308238275),
-new Complex(0.3670925294266434, -1.6673485244636947),
-new Complex(0.29461814038296197, -10.528089110189706),
-new Complex(10.194833330276264, -7.1146946624422025),
-new Complex(17.627086740678745, -7.638274663697334),
-new Complex(22.6731707587984, -11.536058001405237),
-new Complex(90.79168081510915, -41.13328830004425),
-new Complex(-43.229531626011074, 23.294890907589057),
-new Complex(-17.52387246706339, 7.853673956180025),
-new Complex(-15.806202527275513, -0.5183772215827949),
-new Complex(-25.289765401997723, 13.089544474677414),
-new Complex(-7.587901316147817, 6.612185770225549),
-new Complex(-7.7510301280002984, -4.450483522400161),
-new Complex(3.0154490825863447, 4.85718259595836),
-new Complex(-5.588006589467025, 1.8753775661904744),
-new Complex(-4.522700439505712, -6.941653406278663),
-new Complex(-9.29990757512051, 7.73164297352557),
-new Complex(-15.054606473136637, -4.415621289881546),
-new Complex(-5.649212036777634, -3.004224743561956),
-new Complex(-5.3245866110889075, -2.3232079416455855),
-new Complex(-6.09582893633526, -2.833602503098011),
-new Complex(2.3719671688372457, 7.823224635184997),
-new Complex(-4.378899544434763, -2.1004484536234473),
-new Complex(-1.847804254120236, -1.2174634584260025),
-new Complex(-7.151969645971247, 5.608493469097141),
-new Complex(-6.962043610144818, 2.4741041607524394),
-new Complex(-0.9411822402381276, 6.274216197339793),
-new Complex(0.501900088529041, -4.787955462633128),
-new Complex(-1.1594019555348325, -3.84174782623154),
-new Complex(3.3001766896560056, 2.9594456628498946),
-new Complex(-10.066436810536924, 0.6384104860672224),
-new Complex(-7.19567825040399, -3.2261296085795568),
-new Complex(-4.691470830071458, 2.9464762422417987),
-new Complex(-0.14727201097456977, -4.859280838128437),
-new Complex(-14.56692223701291, -7.90084256027122),
-new Complex(-4.324446487468897, 0.004185311431190719),
-new Complex(-1.0407514948403307, 2.059605296404119),
-new Complex(-2.98340696573519, -3.1029075652331937),
-new Complex(-4.636760771943916, 10.373963334679214),
-new Complex(-8.26960957572124, 0.7354864925759217),
-new Complex(-4.979951151973244, 2.4789920137824786),
-new Complex(1.4400641578399824, 0.8869891013658968),
-new Complex(0.6818750261182362, 2.470099039214686),
-new Complex(8.336841493956832, 7.404955214008821),
-new Complex(2.8157431492244953, -6.567660517080393),
-new Complex(-5.878260543893631, 8.516509649574305),
-new Complex(2.879678032286943, -3.1017131232821384),
-new Complex(-3.801558789466788, -2.7381256767431728),
-new Complex(-0.27745160787512013, -7.4993828895293335),
-new Complex(11.019999999999996, 0.0),
-new Complex(-0.2774516078751077, 7.499382889529332),
-new Complex(-3.801558789466789, 2.738125676743172),
-new Complex(2.8796780322869546, 3.101713123282132),
-new Complex(-5.87826054389363, -8.516509649574308),
-new Complex(2.8157431492244895, 6.567660517080403),
-new Complex(8.336841493956836, -7.404955214008817),
-new Complex(0.6818750261182362, -2.470099039214685),
-new Complex(1.4400641578399824, -0.8869891013658968),
-new Complex(-4.979951151973249, -2.4789920137824777),
-new Complex(-8.269609575721244, -0.7354864925759133),
-new Complex(-4.636760771943918, -10.373963334679196),
-new Complex(-2.9834069657351927, 3.1029075652331986),
-new Complex(-1.0407514948403325, -2.0596052964041296),
-new Complex(-4.324446487468897, -0.004185311431191607),
-new Complex(-14.566922237012907, 7.900842560271221),
-new Complex(-0.14727201097457154, 4.85928083812844),
-new Complex(-4.691470830071458, -2.9464762422418005),
-new Complex(-7.195678250403994, 3.2261296085795585),
-new Complex(-10.066436810536924, -0.6384104860672206),
-new Complex(3.3001766896559985, -2.9594456628499017),
-new Complex(-1.1594019555349178, 3.84174782623154),
-new Complex(0.5019000885290694, 4.787955462633128),
-new Complex(-0.9411822402381276, -6.274216197339783),
-new Complex(-6.962043610144818, -2.4741041607524394),
-new Complex(-7.151969645971249, -5.608493469097138),
-new Complex(-1.8478042541202342, 1.2174634584260051),
-new Complex(-4.378899544434763, 2.100448453623444),
-new Complex(2.3719671688372457, -7.8232246351849986),
-new Complex(-6.09582893633526, 2.833602503098014),
-new Complex(-5.324586611088915, 2.3232079416455873),
-new Complex(-5.649212036777634, 3.0042247435619593),
-new Complex(-15.054606473136637, 4.415621289881546),
-new Complex(-9.299907575120518, -7.731642973525572),
-new Complex(-4.522700439505707, 6.941653406278663),
-new Complex(-5.58800658946703, -1.8753775661904735),
-new Complex(3.015449082586345, -4.85718259595836),
-new Complex(-7.751030128000305, 4.45048352240015),
-new Complex(-7.587901316147819, -6.612185770225553),
-new Complex(-25.289765401997727, -13.089544474677405),
-new Complex(-15.806202527275513, 0.5183772215827931),
-new Complex(-17.523872467063388, -7.853673956180031),
-new Complex(-43.229531626011074, -23.294890907589064),
-new Complex(90.79168081510915, 41.13328830004425),
-new Complex(22.6731707587984, 11.536058001405241),
-new Complex(17.62708674067875, 7.6382746636973495),
-new Complex(10.194833330276262, 7.114694662442204),
-new Complex(0.2946181403829593, 10.528089110189704),
-new Complex(0.3670925294266425, 1.6673485244636956),
-new Complex(-1.584044627114522, 3.1949874308238337),
-new Complex(4.104053099373957, 7.912067338215623),
-new Complex(6.918222156603163, -9.497082265446183),
-new Complex(2.8850169831438968, 6.953620083792638),
-new Complex(8.849742475427908, 6.563252547268917),
-new Complex(-8.675100612964956, 7.0559633107071535),
-new Complex(-1.2785892290938947, 1.6397567663004302),
-new Complex(-2.602886071425475, 6.86407264784425),
-new Complex(-3.5825821902320816, 6.877312499750978),
-new Complex(-0.2417805427082258, 0.346746411438247),
-new Complex(-1.280068781381706, 5.229326791882579),
-new Complex(-3.6308727316719613, 2.930509025563401),
-new Complex(6.717336341148264, 1.1098887472444712),
-new Complex(2.560506755969895, 1.0184596329131175),
-new Complex(-4.500591208775362, -2.511548932872677),
-new Complex(-1.4179036790187196, 3.8050609665441018),
-new Complex(-1.9910301634396674, 10.1888778456969),
-new Complex(-6.838255124818515, 9.629717041745097),
-new Complex(4.095532859213191, 0.28973422842765384),
-new Complex(3.8112923807165693, -3.5946006951844875),
-new Complex(2.194258127878689, 4.751521874754488),
-new Complex(-2.6737774913914603, -2.0587240918652236),
-new Complex(0.7024288556739806, 0.03525952952816347),
-new Complex(-2.8792742576603123, -2.162692119076805),
-new Complex(-3.7557379251824736, 4.490350833996582),
-new Complex(-2.4852724753585793, -4.21825804833226),
-new Complex(8.373197781633138, -2.1638002986517675),
-new Complex(-0.8081382242155787, -11.349170741938874),
-new Complex(-9.894054706023425, -4.966896090174037),
-new Complex(-1.9038424152586149, -1.4113411741607438),
-new Complex(-2.78398603468415, -2.491465526509942),
-new Complex(5.8600818792670735, -0.029236104751530156),
-new Complex(4.337683896574438, -0.8299758922339566),
-new Complex(3.147392558038458, -2.216334156350134),
-new Complex(-3.869682067783092, -0.5152936097585532),
-new Complex(9.191032309546063, 1.9398929261634485),
-new Complex(-8.79415766223292, -3.5717135906207194),
-new Complex(-2.193600999401239, -0.40016790514745004),
-new Complex(-7.277178212857741, -2.911663124683228),
-new Complex(-0.2549012255641854, 0.6932903665209089),
-new Complex(5.3325307188358035, 2.0516059158581808),
-new Complex(-3.765563906978266, -3.0884327216299763),
-new Complex(-2.0748219655573683, 2.0037979487038813),
-new Complex(2.236339073099729, 2.3021508943840754),
-new Complex(-6.581883483527934, 0.9168370285871648),
-new Complex(-9.582245656802918, 0.027020924935293067),
-new Complex(-1.2142355119041532, -0.18346355066723263),
-new Complex(-2.3369676800222434, -2.482582201564716),
-new Complex(-3.2509005555527524, -1.439383888634893),
-new Complex(-1.881282888464412, -4.871022697842905),
-new Complex(0.002638323321221492, 0.18978654624225966),
-new Complex(-5.3829294937018854, 2.7830576034063332),
-new Complex(4.734152099371303, 11.062510314288577),
-new Complex(-2.8298389130063937, -3.448368650672099),
-new Complex(-0.024313261096907013, 5.986905188653619),
-new Complex(-10.306371528157014, 2.7488670997481854),
-new Complex(-3.715287570789169, 4.394518377168463),
-new Complex(-2.402929134091579, -4.978313193479721),
-new Complex(2.539933710216687, 2.609184677284304),
-new Complex(-1.4339216539917672, -0.09877393185499805),
-new Complex(3.602869514605274, -4.906754934650175),
-new Complex(-3.8883597256888915, -6.509652164781107),
-new Complex(-0.8134349081877765, 2.8827110905821733),
-new Complex(-5.907774632673294, -3.6263871521782534),
-new Complex(-1.0248996347650001, 5.221535985301575),
-new Complex(-1.5110102858383998, -0.5916676752843197),
-new Complex(-9.114112417604304, 5.863251584381027),
-new Complex(-4.6861993279000735, -3.5540911138722056),
-new Complex(1.643003673416314, 0.26848993074112837),
-new Complex(-2.5917604439233606, 1.0744105534739878),
-new Complex(-5.1589371747064, -3.713563429843524),
-new Complex(-6.434479741808579, -6.482812912010042),
-new Complex(-4.944944633762709, 1.4791201736168564),
-new Complex(-4.196598202151179, 4.72746806821267),
-new Complex(-8.342213173106137, 0.17252901564131817),
-new Complex(-2.160469164514622, 5.322803319988891),
-new Complex(-2.600011910104522, 0.9923343205338124),
-new Complex(-9.934189775670099, -0.7971585720723513),
-new Complex(-4.8493197811620155, 0.23933081088024055),
-new Complex(0.9899999999999949, 2.049999999999997),
-new Complex(0.46312513886469997, -1.083610713737262),
-new Complex(-4.8684310845372405, 5.189260677129301),
-new Complex(-8.26743857115093, 3.7039764685576912),
-new Complex(-0.4020716349072171, 4.7080046554480655),
-new Complex(-12.834400468053516, 1.9280109840029835),
-new Complex(-0.471229754781314, 1.8877908393403002),
-new Complex(-1.0412939420119778, -2.030434694825405),
-new Complex(-7.976980514611285, -4.704983072668933),
-new Complex(1.3875511565884113, 2.3921170941765437),
-new Complex(-0.43177598562379993, 2.072966959680773),
-new Complex(1.7056006968282746, -2.4801437158269524),
-new Complex(-9.118052343426733, 0.7998264524711733),
-new Complex(-4.03651091619774, 8.306905035682062),
-new Complex(-8.966686390330285, -2.8174321266953237),
-new Complex(-3.3209342577998275, 4.826944007044759),
-new Complex(-8.156016294103669, 2.0796298320611637),
-new Complex(-21.623922884263532, 12.12842939823654),
-new Complex(-23.59827162418354, 16.220434411970665),
-new Complex(-23.5007748625453, 12.601610600261623),
-new Complex(-51.32832640613283, 23.124699639369688),
-new Complex(-191.47173027366654, 117.08331011378777),
-new Complex(90.94566028906652, -50.697370827337764),
-new Complex(37.569125833815264, -21.57899450818642),
-new Complex(18.47832853222178, -12.667650849412711),
-new Complex(13.825097858675331, -8.427493951505243),
-new Complex(2.1660703208919014, 0.160682198347327),
-new Complex(18.743970629080533, -8.896718444008545),
-new Complex(7.258232486620578, -2.765278876522548),
-new Complex(-1.67079707818714, -2.1360151627523862),
-new Complex(8.970903795772342, -4.066014902164978),
-new Complex(-1.63248238200879, -7.790777253754383),
-new Complex(7.821845003550149, 1.9841378599467063),
-new Complex(-1.0480377808580839, -3.489347566529763),
-new Complex(2.5131885002916463, -5.861603466455877),
-new Complex(7.296132588971693, -4.341249905128436),
-new Complex(10.426812822364907, 3.327862985228995),
-new Complex(8.861238026483615, 0.9840687253038444),
-new Complex(9.670660740183134, -4.95686087152842),
-new Complex(-8.363128478889875, -9.156259453584862),
-new Complex(6.946585621689808, -8.5029270402973),
-new Complex(-0.30138424584816637, -2.313560920085428),
-new Complex(-8.769932429732478, -5.336877373512683),
-new Complex(7.557346542357086, -6.081240307670633),
-new Complex(-3.785148744276337, -3.918211345581653),
-new Complex(5.398310408984054, 7.203490766128711),
-new Complex(1.0174178671562275, 8.607714904038463),
-new Complex(5.439315586809667, 6.121406497914306),
-new Complex(6.774385287871493, -9.629330590835693),
-new Complex(3.1379824354268426, 6.257763391053615),
-new Complex(-0.11732472297715368, -2.0845144608725157),
-new Complex(5.925896594814177, -1.6214148805227864),
-new Complex(0.6519047716752884, -8.365467739744261),
-new Complex(4.848590964002236, -0.4155821028619928),
-new Complex(-2.5076616550924316, 0.5616066179697503),
-new Complex(-8.0636469706163, -7.706712825244248),
-new Complex(-1.9130289340345779, -4.890086838063298),
-new Complex(4.2847852895396334, -11.97800470285899),
-new Complex(1.8672167221767484, -3.748497006463906),
-new Complex(0.3204212874442627, -5.166759010512947),
-new Complex(-2.797973427324931, 1.3949959065210518),
-new Complex(-0.002595762684481251, -9.037941129554675),
-new Complex(-0.6361813663828864, -6.4579860312158095),
-new Complex(10.57113574570397, 7.214497105214866),
-new Complex(-0.4420963209812834, -3.394939033455901),
-new Complex(-1.1229763926872622, -1.3868358039512907),
-new Complex(-2.7360757090613825, -8.309850036461313),
-new Complex(8.120784577044823, 1.026413324380274),
-new Complex(2.1486659809835205, 2.165175261206473),
-new Complex(-5.99462407262711, -3.089373843767308),
-new Complex(3.1011324895272074, -6.8893033010039995),
-new Complex(-4.186255039897514, -1.883033665479715),
-new Complex(-4.644687701252083, -13.308500752662315),
-new Complex(-0.6346634815558894, -5.25029033494515),
-new Complex(0.4407190353942614, -5.8677531912245335),
-new Complex(-4.607834909859174, -2.7312265688684985),
-new Complex(0.23366490444060828, -12.531156142249792),
-new Complex(-0.18256077357631373, -4.335020541082644),
-new Complex(-5.471846454174138, 3.6460414298884283),
-new Complex(2.839320733358294, -6.1772220929963595),
-new Complex(-1.402392307772061, -4.385841205789253),
-new Complex(-5.303638228818758, -0.6631504207405765),
-new Complex(-5.3005126045963635, -3.37872955018968),
-new Complex(1.119097261414847, -7.382604722348194),
-new Complex(-0.45457704436656776, -8.989165374120152),
-new Complex(-6.782761994698582, -12.08745796987899),
-new Complex(3.6651360344956814, -5.806578149334387),
-new Complex(-5.831778282084541, -4.025856294966035),
-new Complex(5.098783312195226, -4.827669742579823),
-new Complex(-2.434216063490762, -11.25401150339216),
-new Complex(-4.463444898038834, -2.2094751854191976),
-new Complex(-4.655458008198199, 0.7217109700711257),
-new Complex(4.091706423869164, -1.3657980239742185),
-new Complex(-6.135998829269078, -7.692984484782302),
-new Complex(-1.213105136690158, -6.993893647840464),
-new Complex(-7.3702742982223475, -6.341810090314407),
-new Complex(-12.27027085039127, -5.87765864860703),
-new Complex(-10.466158383009784, -4.64345496924585),
-new Complex(-9.241923204154393, 1.8473177393784537),
-new Complex(-11.266585527651117, -8.094594399106146),
-new Complex(-8.537098037861002, -8.885309121693309),
-new Complex(-19.17337301270554, -16.4490076095894),
-new Complex(-24.85859493213612, -13.64591851032932),
-new Complex(-20.98624506290183, -15.99995475685203),
-new Complex(-45.553168448188615, -26.107129887948112),
-new Complex(-71.83350266181674, -50.22287606700222),
-new Complex(-177.8491671506428, -105.09540721761977),
-new Complex(366.88585732605077, 205.12349027793272),
-new Complex(94.3053106250776, 51.97607828999656),
-new Complex(59.25922110005847, 29.043963547908717),
-new Complex(45.108520089797665, 20.58984095476262),
-new Complex(31.077223230796157, 16.494436421460072),
-new Complex(26.77189554895839, 16.352202578199066),
-new Complex(21.50761285652196, 0.6992017699343238),
-new Complex(16.65888595885314, 13.091972828691969),
-new Complex(20.457611574040776, 7.5031116416854715),
-new Complex(11.967450340118393, 6.99870154432028),
-new Complex(14.963784782916644, 12.000161985633948),
-new Complex(13.307669165815334, 4.967069973560196),
-new Complex(9.653138749580414, 3.490781050813886),
-new Complex(16.250262936175652, 10.898983835764772),
-new Complex(16.81258122144206, -1.5049383063313797),
-new Complex(18.814490506606106, 8.665625451587735),
-new Complex(5.0913535569017805, 4.231871346529461),
-new Complex(6.3392529423860475, -1.3944730123175701),
-new Complex(11.867798701774106, -0.7429551118770841),
-new Complex(16.588192205414742, 4.456837908626263),
-new Complex(16.292599219664993, 1.6502662409530293),
-};
+ new(71.52, 0.0),
+ new(16.292599219664993, -1.650266240953031),
+ new(16.58819220541474, -4.456837908626264),
+ new(11.867798701774102, 0.7429551118770812),
+ new(6.339252942386048, 1.3944730123175706),
+ new(5.091353556901778, -4.23187134652945),
+ new(18.814490506606102, -8.665625451587731),
+ new(16.81258122144206, 1.5049383063313775),
+ new(16.250262936175652, -10.898983835764772),
+ new(9.653138749580403, -3.4907810508138843),
+ new(13.307669165815344, -4.967069973560199),
+ new(14.963784782916647, -12.000161985633959),
+ new(11.96745034011839, -6.99870154432028),
+ new(20.457611574040772, -7.503111641685473),
+ new(16.65888595885314, -13.091972828691972),
+ new(21.507612856521956, -0.699201769934322),
+ new(26.771895548958383, -16.35220257819907),
+ new(31.077223230796143, -16.494436421460076),
+ new(45.10852008979767, -20.58984095476262),
+ new(59.25922110005847, -29.04396354790871),
+ new(94.30531062507758, -51.976078289996565),
+ new(366.88585732605077, -205.12349027793272),
+ new(-177.8491671506428, 105.09540721761974),
+ new(-71.83350266181674, 50.22287606700222),
+ new(-45.553168448188615, 26.10712988794811),
+ new(-20.986245062901816, 15.999954756852027),
+ new(-24.858594932136125, 13.645918510329325),
+ new(-19.173373012705525, 16.449007609589398),
+ new(-8.537098037860998, 8.88530912169331),
+ new(-11.266585527651117, 8.094594399106153),
+ new(-9.241923204154396, -1.847317739378453),
+ new(-10.46615838300978, 4.64345496924585),
+ new(-12.27027085039127, 5.87765864860703),
+ new(-7.370274298222351, 6.341810090314409),
+ new(-1.2131051366901628, 6.993893647840464),
+ new(-6.1359988292690755, 7.692984484782312),
+ new(4.091706423869168, 1.365798023974214),
+ new(-4.655458008198221, -0.7217109700711242),
+ new(-4.463444898038833, 2.2094751854192),
+ new(-2.4342160634907675, 11.254011503392162),
+ new(5.098783312195228, 4.827669742579822),
+ new(-5.831778282084546, 4.025856294966041),
+ new(3.665136034495667, 5.806578149334394),
+ new(-6.782761994698575, 12.087457969879013),
+ new(-0.454577044366566, 8.989165374120152),
+ new(1.1190972614148489, 7.3826047223482005),
+ new(-5.300512604596365, 3.3787295501896804),
+ new(-5.303638228818758, 0.663150420740581),
+ new(-1.402392307772061, 4.385841205789253),
+ new(2.839320733358291, 6.177222092996357),
+ new(-5.471846454174141, -3.646041429888425),
+ new(-0.1825607735763244, 4.335020541082649),
+ new(0.23366490444061006, 12.53115614224979),
+ new(-4.607834909859168, 2.731226568868507),
+ new(0.4407190353942614, 5.867753191224533),
+ new(-0.6346634815558851, 5.2502903349451495),
+ new(-4.644687701252085, 13.308500752662315),
+ new(-4.186255039897505, 1.883033665479715),
+ new(3.1011324895272105, 6.889303301004),
+ new(-5.994624072627106, 3.0893738437673104),
+ new(2.148665980983523, -2.165175261206472),
+ new(8.120784577044827, -1.026413324380261),
+ new(-2.736075709061385, 8.309850036461317),
+ new(-1.122976392687268, 1.3868358039512898),
+ new(-0.4420963209812834, 3.394939033455901),
+ new(10.571135745703966, -7.214497105214868),
+ new(-0.6361813663828921, 6.457986031215809),
+ new(-0.0025957626844732573, 9.037941129554671),
+ new(-2.797973427324928, -1.3949959065210518),
+ new(0.32042128744426146, 5.166759010512948),
+ new(1.8672167221767477, 3.7484970064639),
+ new(4.284785289539634, 11.97800470285899),
+ new(-1.9130289340345799, 4.890086838063299),
+ new(-8.063646970616297, 7.70671282524425),
+ new(-2.5076616550924244, -0.5616066179697525),
+ new(4.848590964002215, 0.4155821028619835),
+ new(0.6519047716752894, 8.365467739744268),
+ new(5.925896594814173, 1.6214148805227862),
+ new(-0.11732472297714991, 2.084514460872517),
+ new(3.1379824354268417, -6.2577633910536195),
+ new(6.774385287871493, 9.629330590835693),
+ new(5.4393155868096645, -6.121406497914311),
+ new(1.0174178671562233, -8.607714904038465),
+ new(5.398310408984056, -7.203490766128718),
+ new(-3.785148744276335, 3.9182113455816534),
+ new(7.557346542357081, 6.081240307670624),
+ new(-8.76993242973248, 5.33687737351268),
+ new(-0.30138424584816725, 2.3135609200854255),
+ new(6.9465856216898105, 8.502927040297298),
+ new(-8.363128478889873, 9.156259453584855),
+ new(9.67066074018313, 4.95686087152842),
+ new(8.861238026483612, -0.9840687253038303),
+ new(10.426812822364912, -3.327862985228994),
+ new(7.296132588971696, 4.341249905128431),
+ new(2.513188500291645, 5.861603466455876),
+ new(-1.0480377808580927, 3.4893475665297666),
+ new(7.821845003550149, -1.9841378599467063),
+ new(-1.6324823820087873, 7.790777253754385),
+ new(8.970903795772337, 4.066014902164978),
+ new(-1.6707970781871344, 2.136015162752384),
+ new(7.25823248662058, 2.7652788765225464),
+ new(18.74397062908053, 8.896718444008549),
+ new(2.1660703208919037, -0.16068219834732878),
+ new(13.825097858675338, 8.427493951505237),
+ new(18.47832853222178, 12.667650849412713),
+ new(37.569125833815264, 21.578994508186412),
+ new(90.94566028906655, 50.697370827337764),
+ new(-191.4717302736666, -117.08331011378777),
+ new(-51.32832640613284, -23.124699639369688),
+ new(-23.500774862545306, -12.60161060026162),
+ new(-23.59827162418354, -16.220434411970672),
+ new(-21.623922884263543, -12.128429398236538),
+ new(-8.156016294103669, -2.0796298320611637),
+ new(-3.320934257799828, -4.826944007044764),
+ new(-8.966686390330285, 2.8174321266953233),
+ new(-4.036510916197747, -8.306905035682055),
+ new(-9.118052343426735, -0.7998264524711765),
+ new(1.7056006968282986, 2.48014371582694),
+ new(-0.4317759856237964, -2.0729669596807687),
+ new(1.3875511565884053, -2.3921170941765446),
+ new(-7.976980514611284, 4.704983072668933),
+ new(-1.0412939420119793, 2.0304346948254044),
+ new(-0.4712297547813127, -1.8877908393403056),
+ new(-12.834400468053518, -1.928010984003001),
+ new(-0.4020716349072191, -4.708004655448063),
+ new(-8.267438571150924, -3.7039764685576895),
+ new(-4.8684310845372405, -5.189260677129305),
+ new(0.4631251388647053, 1.0836107137372681),
+ new(0.9899999999999949, -2.049999999999997),
+ new(-4.84931978116202, -0.23933081088023878),
+ new(-9.934189775670093, 0.7971585720723557),
+ new(-2.600011910104527, -0.9923343205338109),
+ new(-2.160469164514625, -5.322803319988892),
+ new(-8.342213173106142, -0.17252901564132728),
+ new(-4.196598202151177, -4.7274680682126755),
+ new(-4.944944633762713, -1.4791201736168527),
+ new(-6.434479741808574, 6.482812912010042),
+ new(-5.158937174706397, 3.713563429843517),
+ new(-2.5917604439233597, -1.074410553473996),
+ new(1.6430036734162927, -0.26848993074113725),
+ new(-4.68619932790007, 3.5540911138722024),
+ new(-9.114112417604312, -5.863251584381021),
+ new(-1.511010285838398, 0.5916676752843228),
+ new(-1.0248996347649997, -5.221535985301575),
+ new(-5.907774632673288, 3.6263871521782516),
+ new(-0.8134349081877801, -2.8827110905821716),
+ new(-3.8883597256888898, 6.5096521647811105),
+ new(3.6028695146052687, 4.906754934650181),
+ new(-1.43392165399176, 0.09877393185500516),
+ new(2.5399337102167436, -2.6091846772843255),
+ new(-2.4029291340916004, 4.978313193479735),
+ new(-3.715287570789176, -4.39451837716846),
+ new(-10.306371528157012, -2.7488670997481837),
+ new(-0.024313261096906125, -5.986905188653612),
+ new(-2.8298389130063915, 3.448368650672101),
+ new(4.7341520993712995, -11.062510314288573),
+ new(-5.3829294937018854, -2.783057603406332),
+ new(0.0026383233212190493, -0.18978654624226898),
+ new(-1.8812828884644066, 4.871022697842905),
+ new(-3.2509005555527533, 1.4393838886348913),
+ new(-2.3369676800222434, 2.482582201564716),
+ new(-1.2142355119041524, 0.1834635506672304),
+ new(-9.582245656802916, -0.027020924935291735),
+ new(-6.581883483527928, -0.9168370285871652),
+ new(2.23633907309973, -2.3021508943840727),
+ new(-2.0748219655573625, -2.0037979487038773),
+ new(-3.765563906978262, 3.088432721629983),
+ new(5.332530718835812, -2.0516059158581865),
+ new(-0.2549012255641858, -0.6932903665209049),
+ new(-7.277178212857739, 2.9116631246832343),
+ new(-2.1936009994012435, 0.4001679051474425),
+ new(-8.794157662232939, 3.5717135906207176),
+ new(9.191032309546063, -1.9398929261634499),
+ new(-3.869682067783085, 0.5152936097585425),
+ new(3.147392558038452, 2.216334156350135),
+ new(4.337683896574441, 0.82997589223395),
+ new(5.8600818792670735, 0.02923610475152838),
+ new(-2.7839860346841525, 2.4914655265099466),
+ new(-1.903842415258608, 1.4113411741607438),
+ new(-9.894054706023422, 4.9668960901740284),
+ new(-0.8081382242155792, 11.349170741938877),
+ new(8.373197781633165, 2.1638002986517635),
+ new(-2.4852724753585846, 4.218258048332267),
+ new(-3.755737925182469, -4.490350833996583),
+ new(-2.879274257660312, 2.1626921190768043),
+ new(0.7024288556739815, -0.03525952952816347),
+ new(-2.673777491391463, 2.058724091865224),
+ new(2.1942581278786912, -4.751521874754496),
+ new(3.8112923807165675, 3.5946006951844867),
+ new(4.095532859213184, -0.28973422842765917),
+ new(-6.83825512481851, -9.6297170417451),
+ new(-1.9910301634396683, -10.188877845696899),
+ new(-1.4179036790187196, -3.8050609665441018),
+ new(-4.500591208775358, 2.5115489328726808),
+ new(2.5605067559698993, -1.0184596329131184),
+ new(6.717336341148254, -1.1098887472444834),
+ new(-3.6308727316719613, -2.930509025563401),
+ new(-1.2800687813817113, -5.2293267918825705),
+ new(-0.24178054270822846, -0.34674641143824747),
+ new(-3.5825821902320762, -6.877312499750982),
+ new(-2.602886071425474, -6.86407264784425),
+ new(-1.2785892290938932, -1.6397567663004344),
+ new(-8.675100612964963, -7.055963310707158),
+ new(8.84974247542792, -6.56325254726892),
+ new(2.885016983143895, -6.95362008379264),
+ new(6.918222156603157, 9.497082265446183),
+ new(4.10405309937396, -7.9120673382156275),
+ new(-1.584044627114519, -3.1949874308238275),
+ new(0.3670925294266434, -1.6673485244636947),
+ new(0.29461814038296197, -10.528089110189706),
+ new(10.194833330276264, -7.1146946624422025),
+ new(17.627086740678745, -7.638274663697334),
+ new(22.6731707587984, -11.536058001405237),
+ new(90.79168081510915, -41.13328830004425),
+ new(-43.229531626011074, 23.294890907589057),
+ new(-17.52387246706339, 7.853673956180025),
+ new(-15.806202527275513, -0.5183772215827949),
+ new(-25.289765401997723, 13.089544474677414),
+ new(-7.587901316147817, 6.612185770225549),
+ new(-7.7510301280002984, -4.450483522400161),
+ new(3.0154490825863447, 4.85718259595836),
+ new(-5.588006589467025, 1.8753775661904744),
+ new(-4.522700439505712, -6.941653406278663),
+ new(-9.29990757512051, 7.73164297352557),
+ new(-15.054606473136637, -4.415621289881546),
+ new(-5.649212036777634, -3.004224743561956),
+ new(-5.3245866110889075, -2.3232079416455855),
+ new(-6.09582893633526, -2.833602503098011),
+ new(2.3719671688372457, 7.823224635184997),
+ new(-4.378899544434763, -2.1004484536234473),
+ new(-1.847804254120236, -1.2174634584260025),
+ new(-7.151969645971247, 5.608493469097141),
+ new(-6.962043610144818, 2.4741041607524394),
+ new(-0.9411822402381276, 6.274216197339793),
+ new(0.501900088529041, -4.787955462633128),
+ new(-1.1594019555348325, -3.84174782623154),
+ new(3.3001766896560056, 2.9594456628498946),
+ new(-10.066436810536924, 0.6384104860672224),
+ new(-7.19567825040399, -3.2261296085795568),
+ new(-4.691470830071458, 2.9464762422417987),
+ new(-0.14727201097456977, -4.859280838128437),
+ new(-14.56692223701291, -7.90084256027122),
+ new(-4.324446487468897, 0.004185311431190719),
+ new(-1.0407514948403307, 2.059605296404119),
+ new(-2.98340696573519, -3.1029075652331937),
+ new(-4.636760771943916, 10.373963334679214),
+ new(-8.26960957572124, 0.7354864925759217),
+ new(-4.979951151973244, 2.4789920137824786),
+ new(1.4400641578399824, 0.8869891013658968),
+ new(0.6818750261182362, 2.470099039214686),
+ new(8.336841493956832, 7.404955214008821),
+ new(2.8157431492244953, -6.567660517080393),
+ new(-5.878260543893631, 8.516509649574305),
+ new(2.879678032286943, -3.1017131232821384),
+ new(-3.801558789466788, -2.7381256767431728),
+ new(-0.27745160787512013, -7.4993828895293335),
+ new(11.019999999999996, 0.0),
+ new(-0.2774516078751077, 7.499382889529332),
+ new(-3.801558789466789, 2.738125676743172),
+ new(2.8796780322869546, 3.101713123282132),
+ new(-5.87826054389363, -8.516509649574308),
+ new(2.8157431492244895, 6.567660517080403),
+ new(8.336841493956836, -7.404955214008817),
+ new(0.6818750261182362, -2.470099039214685),
+ new(1.4400641578399824, -0.8869891013658968),
+ new(-4.979951151973249, -2.4789920137824777),
+ new(-8.269609575721244, -0.7354864925759133),
+ new(-4.636760771943918, -10.373963334679196),
+ new(-2.9834069657351927, 3.1029075652331986),
+ new(-1.0407514948403325, -2.0596052964041296),
+ new(-4.324446487468897, -0.004185311431191607),
+ new(-14.566922237012907, 7.900842560271221),
+ new(-0.14727201097457154, 4.85928083812844),
+ new(-4.691470830071458, -2.9464762422418005),
+ new(-7.195678250403994, 3.2261296085795585),
+ new(-10.066436810536924, -0.6384104860672206),
+ new(3.3001766896559985, -2.9594456628499017),
+ new(-1.1594019555349178, 3.84174782623154),
+ new(0.5019000885290694, 4.787955462633128),
+ new(-0.9411822402381276, -6.274216197339783),
+ new(-6.962043610144818, -2.4741041607524394),
+ new(-7.151969645971249, -5.608493469097138),
+ new(-1.8478042541202342, 1.2174634584260051),
+ new(-4.378899544434763, 2.100448453623444),
+ new(2.3719671688372457, -7.8232246351849986),
+ new(-6.09582893633526, 2.833602503098014),
+ new(-5.324586611088915, 2.3232079416455873),
+ new(-5.649212036777634, 3.0042247435619593),
+ new(-15.054606473136637, 4.415621289881546),
+ new(-9.299907575120518, -7.731642973525572),
+ new(-4.522700439505707, 6.941653406278663),
+ new(-5.58800658946703, -1.8753775661904735),
+ new(3.015449082586345, -4.85718259595836),
+ new(-7.751030128000305, 4.45048352240015),
+ new(-7.587901316147819, -6.612185770225553),
+ new(-25.289765401997727, -13.089544474677405),
+ new(-15.806202527275513, 0.5183772215827931),
+ new(-17.523872467063388, -7.853673956180031),
+ new(-43.229531626011074, -23.294890907589064),
+ new(90.79168081510915, 41.13328830004425),
+ new(22.6731707587984, 11.536058001405241),
+ new(17.62708674067875, 7.6382746636973495),
+ new(10.194833330276262, 7.114694662442204),
+ new(0.2946181403829593, 10.528089110189704),
+ new(0.3670925294266425, 1.6673485244636956),
+ new(-1.584044627114522, 3.1949874308238337),
+ new(4.104053099373957, 7.912067338215623),
+ new(6.918222156603163, -9.497082265446183),
+ new(2.8850169831438968, 6.953620083792638),
+ new(8.849742475427908, 6.563252547268917),
+ new(-8.675100612964956, 7.0559633107071535),
+ new(-1.2785892290938947, 1.6397567663004302),
+ new(-2.602886071425475, 6.86407264784425),
+ new(-3.5825821902320816, 6.877312499750978),
+ new(-0.2417805427082258, 0.346746411438247),
+ new(-1.280068781381706, 5.229326791882579),
+ new(-3.6308727316719613, 2.930509025563401),
+ new(6.717336341148264, 1.1098887472444712),
+ new(2.560506755969895, 1.0184596329131175),
+ new(-4.500591208775362, -2.511548932872677),
+ new(-1.4179036790187196, 3.8050609665441018),
+ new(-1.9910301634396674, 10.1888778456969),
+ new(-6.838255124818515, 9.629717041745097),
+ new(4.095532859213191, 0.28973422842765384),
+ new(3.8112923807165693, -3.5946006951844875),
+ new(2.194258127878689, 4.751521874754488),
+ new(-2.6737774913914603, -2.0587240918652236),
+ new(0.7024288556739806, 0.03525952952816347),
+ new(-2.8792742576603123, -2.162692119076805),
+ new(-3.7557379251824736, 4.490350833996582),
+ new(-2.4852724753585793, -4.21825804833226),
+ new(8.373197781633138, -2.1638002986517675),
+ new(-0.8081382242155787, -11.349170741938874),
+ new(-9.894054706023425, -4.966896090174037),
+ new(-1.9038424152586149, -1.4113411741607438),
+ new(-2.78398603468415, -2.491465526509942),
+ new(5.8600818792670735, -0.029236104751530156),
+ new(4.337683896574438, -0.8299758922339566),
+ new(3.147392558038458, -2.216334156350134),
+ new(-3.869682067783092, -0.5152936097585532),
+ new(9.191032309546063, 1.9398929261634485),
+ new(-8.79415766223292, -3.5717135906207194),
+ new(-2.193600999401239, -0.40016790514745004),
+ new(-7.277178212857741, -2.911663124683228),
+ new(-0.2549012255641854, 0.6932903665209089),
+ new(5.3325307188358035, 2.0516059158581808),
+ new(-3.765563906978266, -3.0884327216299763),
+ new(-2.0748219655573683, 2.0037979487038813),
+ new(2.236339073099729, 2.3021508943840754),
+ new(-6.581883483527934, 0.9168370285871648),
+ new(-9.582245656802918, 0.027020924935293067),
+ new(-1.2142355119041532, -0.18346355066723263),
+ new(-2.3369676800222434, -2.482582201564716),
+ new(-3.2509005555527524, -1.439383888634893),
+ new(-1.881282888464412, -4.871022697842905),
+ new(0.002638323321221492, 0.18978654624225966),
+ new(-5.3829294937018854, 2.7830576034063332),
+ new(4.734152099371303, 11.062510314288577),
+ new(-2.8298389130063937, -3.448368650672099),
+ new(-0.024313261096907013, 5.986905188653619),
+ new(-10.306371528157014, 2.7488670997481854),
+ new(-3.715287570789169, 4.394518377168463),
+ new(-2.402929134091579, -4.978313193479721),
+ new(2.539933710216687, 2.609184677284304),
+ new(-1.4339216539917672, -0.09877393185499805),
+ new(3.602869514605274, -4.906754934650175),
+ new(-3.8883597256888915, -6.509652164781107),
+ new(-0.8134349081877765, 2.8827110905821733),
+ new(-5.907774632673294, -3.6263871521782534),
+ new(-1.0248996347650001, 5.221535985301575),
+ new(-1.5110102858383998, -0.5916676752843197),
+ new(-9.114112417604304, 5.863251584381027),
+ new(-4.6861993279000735, -3.5540911138722056),
+ new(1.643003673416314, 0.26848993074112837),
+ new(-2.5917604439233606, 1.0744105534739878),
+ new(-5.1589371747064, -3.713563429843524),
+ new(-6.434479741808579, -6.482812912010042),
+ new(-4.944944633762709, 1.4791201736168564),
+ new(-4.196598202151179, 4.72746806821267),
+ new(-8.342213173106137, 0.17252901564131817),
+ new(-2.160469164514622, 5.322803319988891),
+ new(-2.600011910104522, 0.9923343205338124),
+ new(-9.934189775670099, -0.7971585720723513),
+ new(-4.8493197811620155, 0.23933081088024055),
+ new(0.9899999999999949, 2.049999999999997),
+ new(0.46312513886469997, -1.083610713737262),
+ new(-4.8684310845372405, 5.189260677129301),
+ new(-8.26743857115093, 3.7039764685576912),
+ new(-0.4020716349072171, 4.7080046554480655),
+ new(-12.834400468053516, 1.9280109840029835),
+ new(-0.471229754781314, 1.8877908393403002),
+ new(-1.0412939420119778, -2.030434694825405),
+ new(-7.976980514611285, -4.704983072668933),
+ new(1.3875511565884113, 2.3921170941765437),
+ new(-0.43177598562379993, 2.072966959680773),
+ new(1.7056006968282746, -2.4801437158269524),
+ new(-9.118052343426733, 0.7998264524711733),
+ new(-4.03651091619774, 8.306905035682062),
+ new(-8.966686390330285, -2.8174321266953237),
+ new(-3.3209342577998275, 4.826944007044759),
+ new(-8.156016294103669, 2.0796298320611637),
+ new(-21.623922884263532, 12.12842939823654),
+ new(-23.59827162418354, 16.220434411970665),
+ new(-23.5007748625453, 12.601610600261623),
+ new(-51.32832640613283, 23.124699639369688),
+ new(-191.47173027366654, 117.08331011378777),
+ new(90.94566028906652, -50.697370827337764),
+ new(37.569125833815264, -21.57899450818642),
+ new(18.47832853222178, -12.667650849412711),
+ new(13.825097858675331, -8.427493951505243),
+ new(2.1660703208919014, 0.160682198347327),
+ new(18.743970629080533, -8.896718444008545),
+ new(7.258232486620578, -2.765278876522548),
+ new(-1.67079707818714, -2.1360151627523862),
+ new(8.970903795772342, -4.066014902164978),
+ new(-1.63248238200879, -7.790777253754383),
+ new(7.821845003550149, 1.9841378599467063),
+ new(-1.0480377808580839, -3.489347566529763),
+ new(2.5131885002916463, -5.861603466455877),
+ new(7.296132588971693, -4.341249905128436),
+ new(10.426812822364907, 3.327862985228995),
+ new(8.861238026483615, 0.9840687253038444),
+ new(9.670660740183134, -4.95686087152842),
+ new(-8.363128478889875, -9.156259453584862),
+ new(6.946585621689808, -8.5029270402973),
+ new(-0.30138424584816637, -2.313560920085428),
+ new(-8.769932429732478, -5.336877373512683),
+ new(7.557346542357086, -6.081240307670633),
+ new(-3.785148744276337, -3.918211345581653),
+ new(5.398310408984054, 7.203490766128711),
+ new(1.0174178671562275, 8.607714904038463),
+ new(5.439315586809667, 6.121406497914306),
+ new(6.774385287871493, -9.629330590835693),
+ new(3.1379824354268426, 6.257763391053615),
+ new(-0.11732472297715368, -2.0845144608725157),
+ new(5.925896594814177, -1.6214148805227864),
+ new(0.6519047716752884, -8.365467739744261),
+ new(4.848590964002236, -0.4155821028619928),
+ new(-2.5076616550924316, 0.5616066179697503),
+ new(-8.0636469706163, -7.706712825244248),
+ new(-1.9130289340345779, -4.890086838063298),
+ new(4.2847852895396334, -11.97800470285899),
+ new(1.8672167221767484, -3.748497006463906),
+ new(0.3204212874442627, -5.166759010512947),
+ new(-2.797973427324931, 1.3949959065210518),
+ new(-0.002595762684481251, -9.037941129554675),
+ new(-0.6361813663828864, -6.4579860312158095),
+ new(10.57113574570397, 7.214497105214866),
+ new(-0.4420963209812834, -3.394939033455901),
+ new(-1.1229763926872622, -1.3868358039512907),
+ new(-2.7360757090613825, -8.309850036461313),
+ new(8.120784577044823, 1.026413324380274),
+ new(2.1486659809835205, 2.165175261206473),
+ new(-5.99462407262711, -3.089373843767308),
+ new(3.1011324895272074, -6.8893033010039995),
+ new(-4.186255039897514, -1.883033665479715),
+ new(-4.644687701252083, -13.308500752662315),
+ new(-0.6346634815558894, -5.25029033494515),
+ new(0.4407190353942614, -5.8677531912245335),
+ new(-4.607834909859174, -2.7312265688684985),
+ new(0.23366490444060828, -12.531156142249792),
+ new(-0.18256077357631373, -4.335020541082644),
+ new(-5.471846454174138, 3.6460414298884283),
+ new(2.839320733358294, -6.1772220929963595),
+ new(-1.402392307772061, -4.385841205789253),
+ new(-5.303638228818758, -0.6631504207405765),
+ new(-5.3005126045963635, -3.37872955018968),
+ new(1.119097261414847, -7.382604722348194),
+ new(-0.45457704436656776, -8.989165374120152),
+ new(-6.782761994698582, -12.08745796987899),
+ new(3.6651360344956814, -5.806578149334387),
+ new(-5.831778282084541, -4.025856294966035),
+ new(5.098783312195226, -4.827669742579823),
+ new(-2.434216063490762, -11.25401150339216),
+ new(-4.463444898038834, -2.2094751854191976),
+ new(-4.655458008198199, 0.7217109700711257),
+ new(4.091706423869164, -1.3657980239742185),
+ new(-6.135998829269078, -7.692984484782302),
+ new(-1.213105136690158, -6.993893647840464),
+ new(-7.3702742982223475, -6.341810090314407),
+ new(-12.27027085039127, -5.87765864860703),
+ new(-10.466158383009784, -4.64345496924585),
+ new(-9.241923204154393, 1.8473177393784537),
+ new(-11.266585527651117, -8.094594399106146),
+ new(-8.537098037861002, -8.885309121693309),
+ new(-19.17337301270554, -16.4490076095894),
+ new(-24.85859493213612, -13.64591851032932),
+ new(-20.98624506290183, -15.99995475685203),
+ new(-45.553168448188615, -26.107129887948112),
+ new(-71.83350266181674, -50.22287606700222),
+ new(-177.8491671506428, -105.09540721761977),
+ new(366.88585732605077, 205.12349027793272),
+ new(94.3053106250776, 51.97607828999656),
+ new(59.25922110005847, 29.043963547908717),
+ new(45.108520089797665, 20.58984095476262),
+ new(31.077223230796157, 16.494436421460072),
+ new(26.77189554895839, 16.352202578199066),
+ new(21.50761285652196, 0.6992017699343238),
+ new(16.65888595885314, 13.091972828691969),
+ new(20.457611574040776, 7.5031116416854715),
+ new(11.967450340118393, 6.99870154432028),
+ new(14.963784782916644, 12.000161985633948),
+ new(13.307669165815334, 4.967069973560196),
+ new(9.653138749580414, 3.490781050813886),
+ new(16.250262936175652, 10.898983835764772),
+ new(16.81258122144206, -1.5049383063313797),
+ new(18.814490506606106, 8.665625451587735),
+ new(5.0913535569017805, 4.231871346529461),
+ new(6.3392529423860475, -1.3944730123175701),
+ new(11.867798701774106, -0.7429551118770841),
+ new(16.588192205414742, 4.456837908626263),
+ new(16.292599219664993, 1.6502662409530293),
+ };
- private readonly Complex[] NumpyRFFT =
+ private readonly System.Numerics.Complex[] NumpyRFFT =
{
-new Complex(71.52, 0.0),
-new Complex(16.292599219664986, -1.650266240953031),
-new Complex(16.588192205414742, -4.456837908626266),
-new Complex(11.867798701774108, 0.7429551118770739),
-new Complex(6.339252942386047, 1.3944730123175706),
-new Complex(5.091353556901781, -4.231871346529461),
-new Complex(18.8144905066061, -8.665625451587735),
-new Complex(16.81258122144206, 1.5049383063313806),
-new Complex(16.250262936175655, -10.898983835764774),
-new Complex(9.65313874958041, -3.49078105081389),
-new Complex(13.307669165815337, -4.967069973560201),
-new Complex(14.963784782916647, -12.000161985633948),
-new Complex(11.96745034011839, -6.998701544320284),
-new Complex(20.457611574040772, -7.503111641685466),
-new Complex(16.658885958853144, -13.091972828691969),
-new Complex(21.507612856521952, -0.6992017699343278),
-new Complex(26.771895548958383, -16.35220257819907),
-new Complex(31.077223230796147, -16.494436421460072),
-new Complex(45.10852008979767, -20.589840954762618),
-new Complex(59.259221100058475, -29.043963547908714),
-new Complex(94.30531062507757, -51.97607828999656),
-new Complex(366.8858573260508, -205.12349027793277),
-new Complex(-177.84916715064278, 105.09540721761974),
-new Complex(-71.83350266181674, 50.22287606700222),
-new Complex(-45.553168448188615, 26.10712988794811),
-new Complex(-20.986245062901823, 15.999954756852036),
-new Complex(-24.85859493213612, 13.645918510329333),
-new Complex(-19.17337301270553, 16.449007609589387),
-new Complex(-8.537098037861, 8.88530912169331),
-new Complex(-11.266585527651117, 8.094594399106143),
-new Complex(-9.241923204154396, -1.8473177393784619),
-new Complex(-10.466158383009773, 4.643454969245847),
-new Complex(-12.27027085039127, 5.877658648607031),
-new Complex(-7.370274298222345, 6.341810090314407),
-new Complex(-1.213105136690162, 6.993893647840459),
-new Complex(-6.1359988292690755, 7.692984484782306),
-new Complex(4.091706423869168, 1.3657980239742202),
-new Complex(-4.655458008198215, -0.7217109700711151),
-new Complex(-4.4634448980388335, 2.2094751854191967),
-new Complex(-2.434216063490762, 11.25401150339216),
-new Complex(5.098783312195228, 4.827669742579822),
-new Complex(-5.831778282084553, 4.025856294966037),
-new Complex(3.6651360344956743, 5.806578149334403),
-new Complex(-6.782761994698575, 12.087457969879019),
-new Complex(-0.45457704436657487, 8.989165374120159),
-new Complex(1.1190972614148507, 7.382604722348191),
-new Complex(-5.300512604596362, 3.378729550189676),
-new Complex(-5.3036382288187545, 0.6631504207405756),
-new Complex(-1.402392307772061, 4.385841205789253),
-new Complex(2.8393207333582873, 6.177222092996363),
-new Complex(-5.471846454174142, -3.6460414298884287),
-new Complex(-0.1825607735763195, 4.335020541082642),
-new Complex(0.23366490444060628, 12.531156142249785),
-new Complex(-4.607834909859171, 2.7312265688685136),
-new Complex(0.4407190353942596, 5.867753191224537),
-new Complex(-0.6346634815558827, 5.250290334945159),
-new Complex(-4.644687701252086, 13.308500752662315),
-new Complex(-4.186255039897507, 1.883033665479711),
-new Complex(3.101132489527204, 6.889303301004002),
-new Complex(-5.9946240726271025, 3.0893738437673117),
-new Complex(2.148665980983527, -2.1651752612064716),
-new Complex(8.120784577044823, -1.0264133243802687),
-new Complex(-2.7360757090613825, 8.309850036461313),
-new Complex(-1.1229763926872607, 1.3868358039512911),
-new Complex(-0.4420963209812834, 3.394939033455901),
-new Complex(10.571135745703966, -7.214497105214872),
-new Complex(-0.6361813663828926, 6.457986031215812),
-new Complex(-0.0025957626844785864, 9.037941129554667),
-new Complex(-2.79797342732493, -1.3949959065210513),
-new Complex(0.3204212874442537, 5.1667590105129415),
-new Complex(1.8672167221767446, 3.7484970064638996),
-new Complex(4.284785289539631, 11.978004702858989),
-new Complex(-1.9130289340345774, 4.890086838063301),
-new Complex(-8.0636469706163, 7.706712825244253),
-new Complex(-2.507661655092423, -0.5616066179697499),
-new Complex(4.848590964002231, 0.4155821028619948),
-new Complex(0.6519047716752902, 8.365467739744261),
-new Complex(5.925896594814184, 1.6214148805227837),
-new Complex(-0.11732472297715268, 2.084514460872518),
-new Complex(3.1379824354268404, -6.257763391053611),
-new Complex(6.774385287871493, 9.629330590835693),
-new Complex(5.4393155868096645, -6.121406497914308),
-new Complex(1.017417867156226, -8.607714904038467),
-new Complex(5.398310408984063, -7.203490766128716),
-new Complex(-3.7851487442763334, 3.9182113455816596),
-new Complex(7.557346542357088, 6.08124030767064),
-new Complex(-8.769932429732474, 5.336877373512683),
-new Complex(-0.3013842458481659, 2.313560920085437),
-new Complex(6.946585621689808, 8.502927040297298),
-new Complex(-8.363128478889877, 9.156259453584862),
-new Complex(9.670660740183127, 4.956860871528423),
-new Complex(8.861238026483619, -0.9840687253038265),
-new Complex(10.426812822364909, -3.3278629852289914),
-new Complex(7.296132588971698, 4.341249905128432),
-new Complex(2.513188500291643, 5.861603466455874),
-new Complex(-1.048037780858094, 3.489347566529764),
-new Complex(7.821845003550148, -1.984137859946705),
-new Complex(-1.6324823820087966, 7.790777253754383),
-new Complex(8.970903795772337, 4.066014902164974),
-new Complex(-1.6707970781871395, 2.136015162752383),
-new Complex(7.2582324866205825, 2.765278876522548),
-new Complex(18.743970629080543, 8.896718444008545),
-new Complex(2.1660703208919028, -0.16068219834732655),
-new Complex(13.825097858675331, 8.427493951505237),
-new Complex(18.478328532221784, 12.667650849412713),
-new Complex(37.569125833815264, 21.578994508186412),
-new Complex(90.94566028906652, 50.697370827337764),
-new Complex(-191.47173027366662, -117.0833101137878),
-new Complex(-51.32832640613284, -23.124699639369688),
-new Complex(-23.500774862545306, -12.601610600261623),
-new Complex(-23.598271624183546, -16.220434411970665),
-new Complex(-21.623922884263536, -12.128429398236536),
-new Complex(-8.156016294103667, -2.079629832061165),
-new Complex(-3.3209342577998284, -4.826944007044762),
-new Complex(-8.966686390330285, 2.8174321266953246),
-new Complex(-4.036510916197741, -8.306905035682057),
-new Complex(-9.118052343426735, -0.7998264524711769),
-new Complex(1.705600696828284, 2.4801437158269257),
-new Complex(-0.4317759856237946, -2.0729669596807727),
-new Complex(1.3875511565884089, -2.3921170941765446),
-new Complex(-7.976980514611284, 4.704983072668934),
-new Complex(-1.0412939420119758, 2.0304346948254097),
-new Complex(-0.471229754781314, -1.8877908393403056),
-new Complex(-12.834400468053524, -1.9280109840030062),
-new Complex(-0.40207163490721864, -4.708004655448063),
-new Complex(-8.26743857115093, -3.7039764685576984),
-new Complex(-4.868431084537242, -5.189260677129303),
-new Complex(0.4631251388647035, 1.0836107137372712),
-new Complex(0.9899999999999949, -2.049999999999997),
-new Complex(-4.849319781162014, -0.2393308108802369),
-new Complex(-9.934189775670095, 0.7971585720723549),
-new Complex(-2.6000119101045227, -0.9923343205338122),
-new Complex(-2.1604691645146215, -5.322803319988891),
-new Complex(-8.342213173106131, -0.17252901564132417),
-new Complex(-4.19659820215117, -4.727468068212671),
-new Complex(-4.944944633762708, -1.4791201736168522),
-new Complex(-6.434479741808575, 6.482812912010042),
-new Complex(-5.1589371747063995, 3.7135634298435116),
-new Complex(-2.5917604439233606, -1.0744105534739985),
-new Complex(1.6430036734163007, -0.2684899307411228),
-new Complex(-4.686199327900066, 3.554091113872207),
-new Complex(-9.114112417604307, -5.863251584381021),
-new Complex(-1.5110102858383967, 0.5916676752843237),
-new Complex(-1.0248996347650015, -5.221535985301577),
-new Complex(-5.90777463267329, 3.6263871521782503),
-new Complex(-0.8134349081877801, -2.882711090582175),
-new Complex(-3.8883597256888844, 6.509652164781103),
-new Complex(3.6028695146052705, 4.9067549346501815),
-new Complex(-1.43392165399176, 0.0987739318549945),
-new Complex(2.539933710216701, -2.609184677284297),
-new Complex(-2.4029291340916075, 4.978313193479746),
-new Complex(-3.7152875707891617, -4.394518377168467),
-new Complex(-10.306371528157012, -2.7488670997481854),
-new Complex(-0.02431326109690435, -5.986905188653616),
-new Complex(-2.829838913006398, 3.4483686506720996),
-new Complex(4.734152099371297, -11.06251031428857),
-new Complex(-5.382929493701886, -2.783057603406332),
-new Complex(0.0026383233212212698, -0.18978654624226154),
-new Complex(-1.881282888464411, 4.871022697842906),
-new Complex(-3.25090055555276, 1.439383888634893),
-new Complex(-2.3369676800222425, 2.4825822015647154),
-new Complex(-1.2142355119041537, 0.18346355066723175),
-new Complex(-9.582245656802915, -0.02702092493529351),
-new Complex(-6.581883483527932, -0.9168370285871694),
-new Complex(2.2363390730997272, -2.3021508943840754),
-new Complex(-2.0748219655573523, -2.0037979487038737),
-new Complex(-3.7655639069782607, 3.0884327216299807),
-new Complex(5.332530718835811, -2.05160591585819),
-new Complex(-0.2549012255641827, -0.6932903665209045),
-new Complex(-7.277178212857729, 2.9116631246832334),
-new Complex(-2.19360099940124, 0.40016790514743894),
-new Complex(-8.794157662232948, 3.571713590620707),
-new Complex(9.191032309546067, -1.9398929261634494),
-new Complex(-3.869682067783092, 0.5152936097585563),
-new Complex(3.1473925580384554, 2.2163341563501353),
-new Complex(4.3376838965744415, 0.829975892233958),
-new Complex(5.8600818792670735, 0.029236104751530156),
-new Complex(-2.7839860346841467, 2.4914655265099475),
-new Complex(-1.9038424152586106, 1.4113411741607425),
-new Complex(-9.894054706023423, 4.966896090174032),
-new Complex(-0.8081382242155761, 11.349170741938874),
-new Complex(8.373197781633154, 2.163800298651763),
-new Complex(-2.4852724753585824, 4.218258048332261),
-new Complex(-3.755737925182478, -4.490350833996587),
-new Complex(-2.8792742576603123, 2.1626921190768047),
-new Complex(0.7024288556739773, -0.035259529528166134),
-new Complex(-2.673777491391459, 2.058724091865225),
-new Complex(2.194258127878678, -4.751521874754496),
-new Complex(3.8112923807165657, 3.594600695184486),
-new Complex(4.095532859213183, -0.28973422842766006),
-new Complex(-6.838255124818513, -9.629717041745101),
-new Complex(-1.9910301634396719, -10.188877845696904),
-new Complex(-1.4179036790187196, -3.8050609665441018),
-new Complex(-4.500591208775357, 2.5115489328726808),
-new Complex(2.5605067559698993, -1.0184596329131206),
-new Complex(6.717336341148265, -1.109888747244478),
-new Complex(-3.630872731671961, -2.9305090255634014),
-new Complex(-1.2800687813817038, -5.229326791882572),
-new Complex(-0.2417805427082249, -0.34674641143824525),
-new Complex(-3.582582190232076, -6.877312499750984),
-new Complex(-2.6028860714254742, -6.864072647844253),
-new Complex(-1.278589229093891, -1.639756766300434),
-new Complex(-8.67510061296496, -7.05596331070716),
-new Complex(8.849742475427906, -6.5632525472689105),
-new Complex(2.8850169831438945, -6.953620083792635),
-new Complex(6.918222156603155, 9.497082265446181),
-new Complex(4.104053099373963, -7.912067338215625),
-new Complex(-1.5840446271145168, -3.1949874308238315),
-new Complex(0.3670925294266435, -1.6673485244636947),
-new Complex(0.2946181403829611, -10.528089110189708),
-new Complex(10.194833330276262, -7.114694662442203),
-new Complex(17.62708674067874, -7.638274663697333),
-new Complex(22.6731707587984, -11.536058001405237),
-new Complex(90.79168081510915, -41.13328830004425),
-new Complex(-43.22953162601108, 23.29489090758906),
-new Complex(-17.523872467063395, 7.853673956180025),
-new Complex(-15.806202527275513, -0.5183772215827918),
-new Complex(-25.289765401997723, 13.089544474677407),
-new Complex(-7.587901316147816, 6.612185770225552),
-new Complex(-7.751030128000307, -4.450483522400161),
-new Complex(3.0154490825863447, 4.857182595958358),
-new Complex(-5.58800658946703, 1.8753775661904708),
-new Complex(-4.522700439505712, -6.9416534062786655),
-new Complex(-9.299907575120514, 7.73164297352557),
-new Complex(-15.054606473136637, -4.415621289881547),
-new Complex(-5.649212036777629, -3.004224743561953),
-new Complex(-5.324586611088913, -2.3232079416455873),
-new Complex(-6.095828936335264, -2.8336025030980143),
-new Complex(2.3719671688372443, 7.8232246351849986),
-new Complex(-4.378899544434765, -2.1004484536234376),
-new Complex(-1.8478042541202289, -1.2174634584260051),
-new Complex(-7.151969645971242, 5.608493469097139),
-new Complex(-6.962043610144821, 2.474104160752436),
-new Complex(-0.9411822402381418, 6.274216197339786),
-new Complex(0.5019000885290552, -4.787955462633121),
-new Complex(-1.159401955534861, -3.8417478262315257),
-new Complex(3.3001766896560056, 2.9594456628498946),
-new Complex(-10.06643681053692, 0.638410486067226),
-new Complex(-7.195678250403994, -3.226129608579562),
-new Complex(-4.691470830071456, 2.946476242241795),
-new Complex(-0.14727201097456977, -4.85928083812844),
-new Complex(-14.566922237012909, -7.900842560271224),
-new Complex(-4.3244464874689, 0.004185311431188055),
-new Complex(-1.040751494840329, 2.0596052964041256),
-new Complex(-2.9834069657351936, -3.1029075652331937),
-new Complex(-4.636760771943913, 10.373963334679232),
-new Complex(-8.269609575721237, 0.7354864925759204),
-new Complex(-4.9799511519732516, 2.478992013782473),
-new Complex(1.4400641578399807, 0.8869891013658959),
-new Complex(0.6818750261182345, 2.4700990392146815),
-new Complex(8.336841493956832, 7.404955214008821),
-new Complex(2.815743149224481, -6.567660517080393),
-new Complex(-5.87826054389363, 8.516509649574305),
-new Complex(2.8796780322869413, -3.1017131232821358),
-new Complex(-3.801558789466787, -2.7381256767431754),
-new Complex(-0.2774516078751166, -7.499382889529337),
-new Complex(11.019999999999996, 0.0)
-};
+ new(71.52, 0.0),
+ new(16.292599219664986, -1.650266240953031),
+ new(16.588192205414742, -4.456837908626266),
+ new(11.867798701774108, 0.7429551118770739),
+ new(6.339252942386047, 1.3944730123175706),
+ new(5.091353556901781, -4.231871346529461),
+ new(18.8144905066061, -8.665625451587735),
+ new(16.81258122144206, 1.5049383063313806),
+ new(16.250262936175655, -10.898983835764774),
+ new(9.65313874958041, -3.49078105081389),
+ new(13.307669165815337, -4.967069973560201),
+ new(14.963784782916647, -12.000161985633948),
+ new(11.96745034011839, -6.998701544320284),
+ new(20.457611574040772, -7.503111641685466),
+ new(16.658885958853144, -13.091972828691969),
+ new(21.507612856521952, -0.6992017699343278),
+ new(26.771895548958383, -16.35220257819907),
+ new(31.077223230796147, -16.494436421460072),
+ new(45.10852008979767, -20.589840954762618),
+ new(59.259221100058475, -29.043963547908714),
+ new(94.30531062507757, -51.97607828999656),
+ new(366.8858573260508, -205.12349027793277),
+ new(-177.84916715064278, 105.09540721761974),
+ new(-71.83350266181674, 50.22287606700222),
+ new(-45.553168448188615, 26.10712988794811),
+ new(-20.986245062901823, 15.999954756852036),
+ new(-24.85859493213612, 13.645918510329333),
+ new(-19.17337301270553, 16.449007609589387),
+ new(-8.537098037861, 8.88530912169331),
+ new(-11.266585527651117, 8.094594399106143),
+ new(-9.241923204154396, -1.8473177393784619),
+ new(-10.466158383009773, 4.643454969245847),
+ new(-12.27027085039127, 5.877658648607031),
+ new(-7.370274298222345, 6.341810090314407),
+ new(-1.213105136690162, 6.993893647840459),
+ new(-6.1359988292690755, 7.692984484782306),
+ new(4.091706423869168, 1.3657980239742202),
+ new(-4.655458008198215, -0.7217109700711151),
+ new(-4.4634448980388335, 2.2094751854191967),
+ new(-2.434216063490762, 11.25401150339216),
+ new(5.098783312195228, 4.827669742579822),
+ new(-5.831778282084553, 4.025856294966037),
+ new(3.6651360344956743, 5.806578149334403),
+ new(-6.782761994698575, 12.087457969879019),
+ new(-0.45457704436657487, 8.989165374120159),
+ new(1.1190972614148507, 7.382604722348191),
+ new(-5.300512604596362, 3.378729550189676),
+ new(-5.3036382288187545, 0.6631504207405756),
+ new(-1.402392307772061, 4.385841205789253),
+ new(2.8393207333582873, 6.177222092996363),
+ new(-5.471846454174142, -3.6460414298884287),
+ new(-0.1825607735763195, 4.335020541082642),
+ new(0.23366490444060628, 12.531156142249785),
+ new(-4.607834909859171, 2.7312265688685136),
+ new(0.4407190353942596, 5.867753191224537),
+ new(-0.6346634815558827, 5.250290334945159),
+ new(-4.644687701252086, 13.308500752662315),
+ new(-4.186255039897507, 1.883033665479711),
+ new(3.101132489527204, 6.889303301004002),
+ new(-5.9946240726271025, 3.0893738437673117),
+ new(2.148665980983527, -2.1651752612064716),
+ new(8.120784577044823, -1.0264133243802687),
+ new(-2.7360757090613825, 8.309850036461313),
+ new(-1.1229763926872607, 1.3868358039512911),
+ new(-0.4420963209812834, 3.394939033455901),
+ new(10.571135745703966, -7.214497105214872),
+ new(-0.6361813663828926, 6.457986031215812),
+ new(-0.0025957626844785864, 9.037941129554667),
+ new(-2.79797342732493, -1.3949959065210513),
+ new(0.3204212874442537, 5.1667590105129415),
+ new(1.8672167221767446, 3.7484970064638996),
+ new(4.284785289539631, 11.978004702858989),
+ new(-1.9130289340345774, 4.890086838063301),
+ new(-8.0636469706163, 7.706712825244253),
+ new(-2.507661655092423, -0.5616066179697499),
+ new(4.848590964002231, 0.4155821028619948),
+ new(0.6519047716752902, 8.365467739744261),
+ new(5.925896594814184, 1.6214148805227837),
+ new(-0.11732472297715268, 2.084514460872518),
+ new(3.1379824354268404, -6.257763391053611),
+ new(6.774385287871493, 9.629330590835693),
+ new(5.4393155868096645, -6.121406497914308),
+ new(1.017417867156226, -8.607714904038467),
+ new(5.398310408984063, -7.203490766128716),
+ new(-3.7851487442763334, 3.9182113455816596),
+ new(7.557346542357088, 6.08124030767064),
+ new(-8.769932429732474, 5.336877373512683),
+ new(-0.3013842458481659, 2.313560920085437),
+ new(6.946585621689808, 8.502927040297298),
+ new(-8.363128478889877, 9.156259453584862),
+ new(9.670660740183127, 4.956860871528423),
+ new(8.861238026483619, -0.9840687253038265),
+ new(10.426812822364909, -3.3278629852289914),
+ new(7.296132588971698, 4.341249905128432),
+ new(2.513188500291643, 5.861603466455874),
+ new(-1.048037780858094, 3.489347566529764),
+ new(7.821845003550148, -1.984137859946705),
+ new(-1.6324823820087966, 7.790777253754383),
+ new(8.970903795772337, 4.066014902164974),
+ new(-1.6707970781871395, 2.136015162752383),
+ new(7.2582324866205825, 2.765278876522548),
+ new(18.743970629080543, 8.896718444008545),
+ new(2.1660703208919028, -0.16068219834732655),
+ new(13.825097858675331, 8.427493951505237),
+ new(18.478328532221784, 12.667650849412713),
+ new(37.569125833815264, 21.578994508186412),
+ new(90.94566028906652, 50.697370827337764),
+ new(-191.47173027366662, -117.0833101137878),
+ new(-51.32832640613284, -23.124699639369688),
+ new(-23.500774862545306, -12.601610600261623),
+ new(-23.598271624183546, -16.220434411970665),
+ new(-21.623922884263536, -12.128429398236536),
+ new(-8.156016294103667, -2.079629832061165),
+ new(-3.3209342577998284, -4.826944007044762),
+ new(-8.966686390330285, 2.8174321266953246),
+ new(-4.036510916197741, -8.306905035682057),
+ new(-9.118052343426735, -0.7998264524711769),
+ new(1.705600696828284, 2.4801437158269257),
+ new(-0.4317759856237946, -2.0729669596807727),
+ new(1.3875511565884089, -2.3921170941765446),
+ new(-7.976980514611284, 4.704983072668934),
+ new(-1.0412939420119758, 2.0304346948254097),
+ new(-0.471229754781314, -1.8877908393403056),
+ new(-12.834400468053524, -1.9280109840030062),
+ new(-0.40207163490721864, -4.708004655448063),
+ new(-8.26743857115093, -3.7039764685576984),
+ new(-4.868431084537242, -5.189260677129303),
+ new(0.4631251388647035, 1.0836107137372712),
+ new(0.9899999999999949, -2.049999999999997),
+ new(-4.849319781162014, -0.2393308108802369),
+ new(-9.934189775670095, 0.7971585720723549),
+ new(-2.6000119101045227, -0.9923343205338122),
+ new(-2.1604691645146215, -5.322803319988891),
+ new(-8.342213173106131, -0.17252901564132417),
+ new(-4.19659820215117, -4.727468068212671),
+ new(-4.944944633762708, -1.4791201736168522),
+ new(-6.434479741808575, 6.482812912010042),
+ new(-5.1589371747063995, 3.7135634298435116),
+ new(-2.5917604439233606, -1.0744105534739985),
+ new(1.6430036734163007, -0.2684899307411228),
+ new(-4.686199327900066, 3.554091113872207),
+ new(-9.114112417604307, -5.863251584381021),
+ new(-1.5110102858383967, 0.5916676752843237),
+ new(-1.0248996347650015, -5.221535985301577),
+ new(-5.90777463267329, 3.6263871521782503),
+ new(-0.8134349081877801, -2.882711090582175),
+ new(-3.8883597256888844, 6.509652164781103),
+ new(3.6028695146052705, 4.9067549346501815),
+ new(-1.43392165399176, 0.0987739318549945),
+ new(2.539933710216701, -2.609184677284297),
+ new(-2.4029291340916075, 4.978313193479746),
+ new(-3.7152875707891617, -4.394518377168467),
+ new(-10.306371528157012, -2.7488670997481854),
+ new(-0.02431326109690435, -5.986905188653616),
+ new(-2.829838913006398, 3.4483686506720996),
+ new(4.734152099371297, -11.06251031428857),
+ new(-5.382929493701886, -2.783057603406332),
+ new(0.0026383233212212698, -0.18978654624226154),
+ new(-1.881282888464411, 4.871022697842906),
+ new(-3.25090055555276, 1.439383888634893),
+ new(-2.3369676800222425, 2.4825822015647154),
+ new(-1.2142355119041537, 0.18346355066723175),
+ new(-9.582245656802915, -0.02702092493529351),
+ new(-6.581883483527932, -0.9168370285871694),
+ new(2.2363390730997272, -2.3021508943840754),
+ new(-2.0748219655573523, -2.0037979487038737),
+ new(-3.7655639069782607, 3.0884327216299807),
+ new(5.332530718835811, -2.05160591585819),
+ new(-0.2549012255641827, -0.6932903665209045),
+ new(-7.277178212857729, 2.9116631246832334),
+ new(-2.19360099940124, 0.40016790514743894),
+ new(-8.794157662232948, 3.571713590620707),
+ new(9.191032309546067, -1.9398929261634494),
+ new(-3.869682067783092, 0.5152936097585563),
+ new(3.1473925580384554, 2.2163341563501353),
+ new(4.3376838965744415, 0.829975892233958),
+ new(5.8600818792670735, 0.029236104751530156),
+ new(-2.7839860346841467, 2.4914655265099475),
+ new(-1.9038424152586106, 1.4113411741607425),
+ new(-9.894054706023423, 4.966896090174032),
+ new(-0.8081382242155761, 11.349170741938874),
+ new(8.373197781633154, 2.163800298651763),
+ new(-2.4852724753585824, 4.218258048332261),
+ new(-3.755737925182478, -4.490350833996587),
+ new(-2.8792742576603123, 2.1626921190768047),
+ new(0.7024288556739773, -0.035259529528166134),
+ new(-2.673777491391459, 2.058724091865225),
+ new(2.194258127878678, -4.751521874754496),
+ new(3.8112923807165657, 3.594600695184486),
+ new(4.095532859213183, -0.28973422842766006),
+ new(-6.838255124818513, -9.629717041745101),
+ new(-1.9910301634396719, -10.188877845696904),
+ new(-1.4179036790187196, -3.8050609665441018),
+ new(-4.500591208775357, 2.5115489328726808),
+ new(2.5605067559698993, -1.0184596329131206),
+ new(6.717336341148265, -1.109888747244478),
+ new(-3.630872731671961, -2.9305090255634014),
+ new(-1.2800687813817038, -5.229326791882572),
+ new(-0.2417805427082249, -0.34674641143824525),
+ new(-3.582582190232076, -6.877312499750984),
+ new(-2.6028860714254742, -6.864072647844253),
+ new(-1.278589229093891, -1.639756766300434),
+ new(-8.67510061296496, -7.05596331070716),
+ new(8.849742475427906, -6.5632525472689105),
+ new(2.8850169831438945, -6.953620083792635),
+ new(6.918222156603155, 9.497082265446181),
+ new(4.104053099373963, -7.912067338215625),
+ new(-1.5840446271145168, -3.1949874308238315),
+ new(0.3670925294266435, -1.6673485244636947),
+ new(0.2946181403829611, -10.528089110189708),
+ new(10.194833330276262, -7.114694662442203),
+ new(17.62708674067874, -7.638274663697333),
+ new(22.6731707587984, -11.536058001405237),
+ new(90.79168081510915, -41.13328830004425),
+ new(-43.22953162601108, 23.29489090758906),
+ new(-17.523872467063395, 7.853673956180025),
+ new(-15.806202527275513, -0.5183772215827918),
+ new(-25.289765401997723, 13.089544474677407),
+ new(-7.587901316147816, 6.612185770225552),
+ new(-7.751030128000307, -4.450483522400161),
+ new(3.0154490825863447, 4.857182595958358),
+ new(-5.58800658946703, 1.8753775661904708),
+ new(-4.522700439505712, -6.9416534062786655),
+ new(-9.299907575120514, 7.73164297352557),
+ new(-15.054606473136637, -4.415621289881547),
+ new(-5.649212036777629, -3.004224743561953),
+ new(-5.324586611088913, -2.3232079416455873),
+ new(-6.095828936335264, -2.8336025030980143),
+ new(2.3719671688372443, 7.8232246351849986),
+ new(-4.378899544434765, -2.1004484536234376),
+ new(-1.8478042541202289, -1.2174634584260051),
+ new(-7.151969645971242, 5.608493469097139),
+ new(-6.962043610144821, 2.474104160752436),
+ new(-0.9411822402381418, 6.274216197339786),
+ new(0.5019000885290552, -4.787955462633121),
+ new(-1.159401955534861, -3.8417478262315257),
+ new(3.3001766896560056, 2.9594456628498946),
+ new(-10.06643681053692, 0.638410486067226),
+ new(-7.195678250403994, -3.226129608579562),
+ new(-4.691470830071456, 2.946476242241795),
+ new(-0.14727201097456977, -4.85928083812844),
+ new(-14.566922237012909, -7.900842560271224),
+ new(-4.3244464874689, 0.004185311431188055),
+ new(-1.040751494840329, 2.0596052964041256),
+ new(-2.9834069657351936, -3.1029075652331937),
+ new(-4.636760771943913, 10.373963334679232),
+ new(-8.269609575721237, 0.7354864925759204),
+ new(-4.9799511519732516, 2.478992013782473),
+ new(1.4400641578399807, 0.8869891013658959),
+ new(0.6818750261182345, 2.4700990392146815),
+ new(8.336841493956832, 7.404955214008821),
+ new(2.815743149224481, -6.567660517080393),
+ new(-5.87826054389363, 8.516509649574305),
+ new(2.8796780322869413, -3.1017131232821358),
+ new(-3.801558789466787, -2.7381256767431754),
+ new(-0.2774516078751166, -7.499382889529337),
+ new(11.019999999999996, 0.0),
+ };
public readonly double[] NumpyFFTabs =
{
diff --git a/src/FftSharp.Tests/VsNumpy.cs b/src/FftSharp.Tests/VsNumpy.cs
index 2e12d0c..73c940c 100644
--- a/src/FftSharp.Tests/VsNumpy.cs
+++ b/src/FftSharp.Tests/VsNumpy.cs
@@ -25,8 +25,8 @@ public void LoadAndVerifyData()
[Test]
public void Test_VsNumpy_Fft()
{
- Complex[] fft = FftSharp.Transform.FFT(values);
- Complex[] numpyFft = LoadData.Complex("fft.txt");
+ System.Numerics.Complex[] fft = FftSharp.FFT.Forward(values);
+ System.Numerics.Complex[] numpyFft = LoadData.Complex("fft.txt");
Assert.AreEqual(numpyFft.Length, fft.Length);
@@ -44,9 +44,9 @@ public void Test_VsNumpy_Fft_SystemNumericsComplex()
for (int i = 0; i < values.Length; i++)
buffer[i] = new System.Numerics.Complex(real: values[i], imaginary: 0);
- FftSharp.Transform.FFT(buffer);
+ FftSharp.FFT.Forward(buffer);
- Complex[] numpyFft = LoadData.Complex("fft.txt");
+ System.Numerics.Complex[] numpyFft = LoadData.Complex("fft.txt");
Assert.AreEqual(numpyFft.Length, buffer.Length);
@@ -60,8 +60,8 @@ public void Test_VsNumpy_Fft_SystemNumericsComplex()
[Test]
public void Test_VsNumpy_Rfft()
{
- Complex[] rfft = FftSharp.Transform.RFFT(values);
- Complex[] numpyRfft = LoadData.Complex("fftReal.txt");
+ System.Numerics.Complex[] rfft = FftSharp.FFT.ForwardReal(values);
+ System.Numerics.Complex[] numpyRfft = LoadData.Complex("fftReal.txt");
Assert.AreEqual(numpyRfft.Length, rfft.Length);
@@ -75,7 +75,8 @@ public void Test_VsNumpy_Rfft()
[Test]
public void Test_VsNumpy_FftMag()
{
- double[] fftMag = FftSharp.Transform.FFTmagnitude(values);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(values);
+ double[] fftMag = FftSharp.FFT.Magnitude(spectrum);
double[] numpyFftMag = LoadData.Double("fftMag.txt");
Assert.AreEqual(numpyFftMag.Length, fftMag.Length);
@@ -87,7 +88,8 @@ public void Test_VsNumpy_FftMag()
[Test]
public void Test_VsNumpy_FftDB()
{
- double[] fftDB = FftSharp.Transform.FFTpower(values);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(values);
+ double[] fftDB = FftSharp.FFT.Power(spectrum);
double[] numpyFftDB = LoadData.Double("fftDB.txt");
Assert.AreEqual(numpyFftDB.Length, fftDB.Length);
@@ -99,7 +101,8 @@ public void Test_VsNumpy_FftDB()
[Test]
public void Test_VsNumpy_FftPhase()
{
- double[] phases = FftSharp.Transform.FFTphase(values);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(values);
+ double[] phases = FftSharp.FFT.Phase(spectrum);
double[] numpyFftPhase = LoadData.Double("fftPhase.txt");
Assert.AreEqual(numpyFftPhase.Length, phases.Length);
@@ -111,7 +114,7 @@ public void Test_VsNumpy_FftPhase()
[Test]
public void Test_VsNumpy_FftFreq()
{
- double[] fftFreq = FftSharp.Transform.FFTfreq(sampleRate: 48_000, pointCount: values.Length, oneSided: false);
+ double[] fftFreq = FftSharp.FFT.FrequencyScale(values.Length, 48_000, false);
double[] numpyFftFreq = LoadData.Double("fftFreq.txt");
Assert.AreEqual(numpyFftFreq.Length, fftFreq.Length);
@@ -134,7 +137,8 @@ public void Test_VsNumpy_Fft_Length32()
0.12648992889321545, 0.17946592505602227, 0.08145444884938172, 0.1681978420275756, 0.2919426435801102,
0.35936842267425245, 0.2704107530566828, 0.05312499999999987 };
- double[] mag = FftSharp.Transform.FFTmagnitude(values);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(values);
+ double[] mag = FftSharp.FFT.Magnitude(spectrum);
Assert.AreEqual(numpyFftMag.Length, mag.Length);
for (int i = 0; i < numpyFftMag.Length; i++)
@@ -153,7 +157,8 @@ public void Test_VsNumpy_Fft_Length16()
double[] numpyFftMag = { 0.99, 1.3848691625350331, 0.3643928332909465, 1.0042721499156904,
0.34613039450473, 0.1401344145671993, 0.2637216582804615, 0.5006617594915167, 0.04499999999999993 };
- double[] mag = FftSharp.Transform.FFTmagnitude(values);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(values);
+ double[] mag = FftSharp.FFT.Magnitude(spectrum);
Assert.AreEqual(numpyFftMag.Length, mag.Length);
for (int i = 0; i < numpyFftMag.Length; i++)
@@ -171,7 +176,8 @@ public void Test_VsNumpy_Fft_Length8()
double[] numpyFftMag = { 1.7025, 0.706710339966861, 1.1495760087962865, 0.33016737480242325, 0.645 };
- double[] mag = FftSharp.Transform.FFTmagnitude(values);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(values);
+ double[] mag = FftSharp.FFT.Magnitude(spectrum);
Assert.AreEqual(numpyFftMag.Length, mag.Length);
for (int i = 0; i < numpyFftMag.Length; i++)
@@ -189,7 +195,8 @@ public void Test_VsNumpy_Fft_Length4()
double[] numpyFftMag = { 1.3225, 0.6783251432757007, 0.875 };
- double[] mag = FftSharp.Transform.FFTmagnitude(values);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(values);
+ double[] mag = FftSharp.FFT.Magnitude(spectrum);
Assert.AreEqual(numpyFftMag.Length, mag.Length);
for (int i = 0; i < numpyFftMag.Length; i++)
@@ -207,7 +214,8 @@ public void Test_VsNumpy_Fft_Length2()
double[] numpyFftMag = { 1.24, 1.8199999999999998 };
- double[] mag = FftSharp.Transform.FFTmagnitude(values);
+ System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(values);
+ double[] mag = FftSharp.FFT.Magnitude(spectrum);
Assert.AreEqual(numpyFftMag.Length, mag.Length);
for (int i = 0; i < numpyFftMag.Length; i++)
@@ -220,14 +228,14 @@ public void Test_VsNumpy_Fft_Length2()
public void Test_VsNumpy_Fft_Length1()
{
double[] values = { 0.33 };
- Assert.Throws(() => { FftSharp.Transform.FFTmagnitude(values); });
+ Assert.Throws(() => { FftSharp.FFT.Forward(values); });
}
[Test]
public void Test_VsNumpy_Fft_Length0()
{
double[] values = { };
- Assert.Throws(() => { FftSharp.Transform.FFTmagnitude(values); });
+ Assert.Throws(() => { FftSharp.FFT.Forward(values); });
}
}
}
diff --git a/src/FftSharp/Complex.cs b/src/FftSharp/Complex.cs
index a92d09c..a5daac8 100644
--- a/src/FftSharp/Complex.cs
+++ b/src/FftSharp/Complex.cs
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Text;
namespace FftSharp
{
+ [Obsolete("Use System.Numerics.Complex")]
public struct Complex
{
public double Real;
@@ -63,5 +65,15 @@ public static double[] GetMagnitudes(Complex[] input)
output[i] = input[i].Magnitude;
return output;
}
+
+ public System.Numerics.Complex ToNumerics()
+ {
+ return new(Real, Imaginary);
+ }
+
+ public static System.Numerics.Complex[] ToNumerics(Complex[] values)
+ {
+ return values.Select(x => x.ToNumerics()).ToArray();
+ }
}
}
diff --git a/src/FftSharp/FFT.cs b/src/FftSharp/FFT.cs
index a2b68a9..42f2755 100644
--- a/src/FftSharp/FFT.cs
+++ b/src/FftSharp/FFT.cs
@@ -2,49 +2,99 @@
namespace FftSharp;
-// TODO: support spans
-
///
/// Fast Fourier Transform (FFT) operations using System.Numerics.Complex data types.
///
public static class FFT
{
///
- /// Apply the Fast Fourier Transform (FFT) to the Complex array in place.
- /// Length of the array must be a power of 2.
+ /// Compute the discrete Fourier Transform (in-place) using the FFT algorithm.
///
+ /// Data to transform in-place. Length must be a power of 2.
public static void Forward(System.Numerics.Complex[] samples)
{
- if (!Transform.IsPowerOfTwo(samples.Length))
+ if (samples is null)
+ throw new ArgumentNullException(nameof(samples));
+
+ Forward(samples.AsSpan());
+ }
+
+ ///
+ /// Compute the discrete Fourier Transform (in-place) using the FFT algorithm.
+ ///
+ /// Data to transform in-place. Length must be a power of 2.
+ public static System.Numerics.Complex[] Forward(double[] samples)
+ {
+ if (samples is null)
+ throw new ArgumentNullException(nameof(samples));
+
+ System.Numerics.Complex[] buffer = samples.ToComplexArray();
+ Forward(buffer);
+ return buffer;
+ }
+
+ ///
+ /// Compute the discrete Fourier Transform (in-place) using the FFT algorithm.
+ ///
+ /// Data to transform in-place. Length must be a power of 2.
+ public static void Forward(Span samples)
+ {
+ if (!FftOperations.IsPowerOfTwo(samples.Length))
throw new ArgumentException($"{nameof(samples)} length must be a power of 2");
+ if (samples.Length < 2)
+ throw new ArgumentException($"FFT requires at least 2 samples but sample length was {samples.Length}");
+
FftOperations.FFT_WithoutChecks(samples);
}
///
- /// Create a Complex array from the given data, apply the FFT, and return the result.
+ /// Calculate FFT and return just the real component of the spectrum
+ ///
+ public static System.Numerics.Complex[] ForwardReal(System.Numerics.Complex[] samples)
+ {
+ if (!FftOperations.IsPowerOfTwo(samples.Length))
+ throw new ArgumentException($"{nameof(samples)} length must be a power of 2");
+
+ System.Numerics.Complex[] realBuffer = new System.Numerics.Complex[samples.Length / 2 + 1];
+ FftOperations.RFFT_WithoutChecks(realBuffer, samples);
+ return realBuffer;
+ }
+
+ ///
+ /// Calculate FFT and return just the real component of the spectrum
+ ///
+ public static System.Numerics.Complex[] ForwardReal(double[] samples)
+ {
+ System.Numerics.Complex[] buffer = samples.ToComplexArray();
+ Forward(buffer);
+ System.Numerics.Complex[] real = new System.Numerics.Complex[samples.Length / 2 + 1];
+ Array.Copy(buffer, 0, real, 0, real.Length);
+ return real;
+ }
+
+ ///
+ /// Apply the inverse Fast Fourier Transform (iFFT) to the Complex array in place.
/// Length of the array must be a power of 2.
///
- public static System.Numerics.Complex[] Forward(double[] real)
+ public static void Inverse(System.Numerics.Complex[] spectrum)
{
- if (!Transform.IsPowerOfTwo(real.Length))
- throw new ArgumentException($"{nameof(real)} length must be a power of 2");
+ if (spectrum is null)
+ throw new ArgumentNullException(nameof(spectrum));
- System.Numerics.Complex[] samples = real.ToComplexArray();
- FftOperations.FFT_WithoutChecks(samples);
- return samples;
+ Inverse(spectrum.AsSpan());
}
///
/// Apply the inverse Fast Fourier Transform (iFFT) to the Complex array in place.
/// Length of the array must be a power of 2.
///
- public static void Inverse(System.Numerics.Complex[] samples)
+ public static void Inverse(Span spectrum)
{
- if (!Transform.IsPowerOfTwo(samples.Length))
- throw new ArgumentException($"{nameof(samples)} length must be a power of 2");
+ if (!FftOperations.IsPowerOfTwo(spectrum.Length))
+ throw new ArgumentException($"{nameof(spectrum)} length must be a power of 2");
- FftOperations.IFFT_WithoutChecks(samples);
+ FftOperations.IFFT_WithoutChecks(spectrum);
}
///
@@ -52,6 +102,87 @@ public static void Inverse(System.Numerics.Complex[] samples)
///
public static double[] FrequencyScale(int length, double sampleRate, bool positiveOnly = true)
{
- return Transform.FFTfreq(sampleRate: sampleRate, pointCount: length, oneSided: positiveOnly);
+ double[] freqs = new double[length];
+
+ if (positiveOnly)
+ {
+ double fftPeriodHz = sampleRate / (length - 1) / 2;
+
+ // freqs start at 0 and approach maxFreq
+ for (int i = 0; i < length; i++)
+ freqs[i] = i * fftPeriodHz;
+
+ return freqs;
+ }
+ else
+ {
+ double fftPeriodHz = sampleRate / length;
+
+ // first half: freqs start a 0 and approach maxFreq
+ int halfIndex = length / 2;
+ for (int i = 0; i < halfIndex; i++)
+ freqs[i] = i * fftPeriodHz;
+
+ // second half: then start at -maxFreq and approach 0
+ for (int i = halfIndex; i < length; i++)
+ freqs[i] = -(length - i) * fftPeriodHz;
+
+ return freqs;
+ }
+ }
+
+ ///
+ /// Return the resolution (distance between each frequency) of the FFT in Hz
+ ///
+ public static double FrequencyResolution(int length, double sampleRate, bool positiveOnly = true)
+ {
+ return positiveOnly
+ ? sampleRate / (length - 1) / 2
+ : sampleRate / length;
+ }
+
+ ///
+ /// Return the phase for each point in a Complex array
+ ///
+ public static double[] Phase(System.Numerics.Complex[] spectrum)
+ {
+ double[] phase = new double[spectrum.Length];
+
+ for (int i = 0; i < spectrum.Length; i++)
+ phase[i] = spectrum[i].Phase;
+
+ return phase;
+ }
+
+ ///
+ /// Calculate power spectrum density (PSD) in RMS units
+ ///
+ public static double[] Magnitude(System.Numerics.Complex[] spectrum, bool positiveOnly = true)
+ {
+ int length = positiveOnly ? spectrum.Length / 2 + 1 : spectrum.Length;
+
+ double[] output = new double[length];
+
+ // first point (DC component) is not doubled
+ output[0] = spectrum[0].Magnitude / spectrum.Length;
+
+ // subsequent points are doubled to account for combined positive and negative frequencies
+ for (int i = 1; i < output.Length; i++)
+ output[i] = 2 * spectrum[i].Magnitude / spectrum.Length;
+
+ return output;
+ }
+
+ ///
+ /// Calculate power spectrum density (PSD) in dB units
+ ///
+ public static double[] Power(System.Numerics.Complex[] spectrum, bool positiveOnly = true)
+ {
+ double[] output = Magnitude(spectrum, positiveOnly);
+
+ for (int i = 0; i < output.Length; i++)
+ output[i] = 20 * Math.Log10(output[i]);
+
+ return output;
}
}
\ No newline at end of file
diff --git a/src/FftSharp/FftOperations.cs b/src/FftSharp/FftOperations.cs
index 517f6d2..3c5ee1c 100644
--- a/src/FftSharp/FftOperations.cs
+++ b/src/FftSharp/FftOperations.cs
@@ -1,4 +1,5 @@
using System;
+using System.Buffers;
namespace FftSharp;
@@ -7,12 +8,21 @@ namespace FftSharp;
///
internal class FftOperations
{
+ ///
+ /// Returns true if the given number is evenly divisible by a power of 2
+ ///
+ public static bool IsPowerOfTwo(int x)
+ {
+ return ((x & (x - 1)) == 0) && (x > 0);
+ }
+
///
/// High performance FFT function.
/// Complex input will be transformed in place.
/// Input array length must be a power of two. This length is NOT validated.
/// Running on an array with an invalid length may throw an invalid index exception.
///
+ [Obsolete("Use methods which consume System.Numerics.Complex")]
public static void FFT_WithoutChecks(Span buffer)
{
for (int i = 1; i < buffer.Length; i++)
@@ -73,24 +83,64 @@ public static void FFT_WithoutChecks(Span buffer)
}
}
+ ///
+ /// Calculate FFT of the input and return just the real component
+ /// Input array length must be a power of two. This length is NOT validated.
+ /// Running on an array with an invalid length may throw an invalid index exception.
+ ///
+ public static void RFFT_WithoutChecks(Span destination, Span input)
+ {
+ System.Numerics.Complex[] temp = ArrayPool.Shared.Rent(input.Length);
+
+ Span buffer = temp.AsSpan(0, input.Length);
+
+ FFT_WithoutChecks(buffer);
+ buffer.Slice(0, destination.Length).CopyTo(destination);
+
+ ArrayPool.Shared.Return(temp);
+ }
+
///
/// High performance inverse FFT function.
/// Complex input will be transformed in place.
/// Input array length must be a power of two. This length is NOT validated.
/// Running on an array with an invalid length may throw an invalid index exception.
///
- public static void IFFT_WithoutChecks(Complex[] buffer)
+ [Obsolete("Use methods which consume System.Numerics.Complex")]
+ public static void IFFT_WithoutChecks(Span buffer)
{
// invert the imaginary component
for (int i = 0; i < buffer.Length; i++)
- buffer[i] = new Complex(buffer[i].Real, -buffer[i].Imaginary);
+ buffer[i] = new(buffer[i].Real, -buffer[i].Imaginary);
// perform a forward Fourier transform
FFT_WithoutChecks(buffer);
// invert the imaginary component again and scale the output
for (int i = 0; i < buffer.Length; i++)
- buffer[i] = new Complex(
+ buffer[i] = new(
+ real: buffer[i].Real / buffer.Length,
+ imaginary: -buffer[i].Imaginary / buffer.Length);
+ }
+
+ ///
+ /// High performance inverse FFT function.
+ /// Complex input will be transformed in place.
+ /// Input array length must be a power of two. This length is NOT validated.
+ /// Running on an array with an invalid length may throw an invalid index exception.
+ ///
+ public static void IFFT_WithoutChecks(Span buffer)
+ {
+ // invert the imaginary component
+ for (int i = 0; i < buffer.Length; i++)
+ buffer[i] = new(buffer[i].Real, -buffer[i].Imaginary);
+
+ // perform a forward Fourier transform
+ FFT_WithoutChecks(buffer);
+
+ // invert the imaginary component again and scale the output
+ for (int i = 0; i < buffer.Length; i++)
+ buffer[i] = new(
real: buffer[i].Real / buffer.Length,
imaginary: -buffer[i].Imaginary / buffer.Length);
}
diff --git a/src/FftSharp/FftSharp.csproj b/src/FftSharp/FftSharp.csproj
index 33dfe15..20f49fa 100644
--- a/src/FftSharp/FftSharp.csproj
+++ b/src/FftSharp/FftSharp.csproj
@@ -16,9 +16,9 @@
https://github.com/swharden/FftSharp/releases
true
FftSharp.xml
- 1.1.6
- 1.1.6.0
- 1.1.6.0
+ 2.0.0
+ 2.0.0.0
+ 2.0.0.0
1591
portable
true
diff --git a/src/FftSharp/Filter.cs b/src/FftSharp/Filter.cs
index 13faec0..442ebda 100644
--- a/src/FftSharp/Filter.cs
+++ b/src/FftSharp/Filter.cs
@@ -21,15 +21,14 @@ public static class Filter
///
public static double[] BandPass(double[] values, double sampleRate, double minFrequency, double maxFrequency)
{
- Complex[] fft = Transform.FFT(values);
- double[] fftFreqs = Transform.FFTfreq(sampleRate, fft.Length, oneSided: false);
+ System.Numerics.Complex[] fft = FFT.Forward(values);
+ double[] fftFreqs = FFT.FrequencyScale(fft.Length, sampleRate, false);
for (int i = 0; i < fft.Length; i++)
{
double freq = Math.Abs(fftFreqs[i]);
if ((freq > maxFrequency) || (freq < minFrequency))
{
- fft[i].Real = 0;
- fft[i].Imaginary = 0;
+ fft[i] = new(0, 0);
}
}
return InverseReal(fft);
@@ -40,23 +39,22 @@ public static double[] BandPass(double[] values, double sampleRate, double minFr
///
public static double[] BandStop(double[] values, double sampleRate, double minFrequency, double maxFrequency)
{
- Complex[] fft = Transform.FFT(values);
- double[] fftFreqs = Transform.FFTfreq(sampleRate, fft.Length, oneSided: false);
+ System.Numerics.Complex[] fft = FFT.Forward(values);
+ double[] fftFreqs = FFT.FrequencyScale(fft.Length, sampleRate, false);
for (int i = 0; i < fft.Length; i++)
{
double freq = Math.Abs(fftFreqs[i]);
if ((freq <= maxFrequency) && (freq >= minFrequency))
{
- fft[i].Real = 0;
- fft[i].Imaginary = 0;
+ fft[i] = new(0, 0);
}
}
return InverseReal(fft);
}
- private static double[] InverseReal(Complex[] fft)
+ private static double[] InverseReal(System.Numerics.Complex[] fft)
{
- Transform.IFFT(fft);
+ FFT.Inverse(fft);
double[] Filtered = new double[fft.Length];
for (int i = 0; i < fft.Length; i++)
Filtered[i] = fft[i].Real;
diff --git a/src/FftSharp/Mel.cs b/src/FftSharp/Mel.cs
new file mode 100644
index 0000000..bc39797
--- /dev/null
+++ b/src/FftSharp/Mel.cs
@@ -0,0 +1,46 @@
+using System;
+
+namespace FftSharp;
+
+///
+/// Methods for conversion to/from Mel scaling
+///
+public static class Mel
+{
+ public static double ToFreq(double mel) => 700 * (Math.Pow(10, mel / 2595d) - 1);
+
+ public static double FromFreq(double frequencyHz) => 2595 * Math.Log10(1 + frequencyHz / 700);
+
+ public static double[] Scale(double[] fft, int sampleRate, int melBinCount)
+ {
+ double freqMax = sampleRate / 2;
+ double maxMel = FromFreq(freqMax);
+
+ double[] fftMel = new double[melBinCount];
+ double melPerBin = maxMel / (melBinCount + 1);
+ for (int binIndex = 0; binIndex < melBinCount; binIndex++)
+ {
+ double melLow = melPerBin * binIndex;
+ double melHigh = melPerBin * (binIndex + 2);
+
+ double freqLow = ToFreq(melLow);
+ double freqHigh = ToFreq(melHigh);
+
+ int indexLow = (int)(fft.Length * freqLow / freqMax);
+ int indexHigh = (int)(fft.Length * freqHigh / freqMax);
+ int indexSpan = indexHigh - indexLow;
+
+ double binScaleSum = 0;
+ for (int i = 0; i < indexSpan; i++)
+ {
+ double binFrac = (double)i / indexSpan;
+ double indexScale = (binFrac < .5) ? binFrac * 2 : 1 - binFrac;
+ binScaleSum += indexScale;
+ fftMel[binIndex] += fft[indexLow + i] * indexScale;
+ }
+ fftMel[binIndex] /= binScaleSum;
+ }
+
+ return fftMel;
+ }
+}
diff --git a/src/FftSharp/Pad.cs b/src/FftSharp/Pad.cs
index 643a802..e98912d 100644
--- a/src/FftSharp/Pad.cs
+++ b/src/FftSharp/Pad.cs
@@ -7,18 +7,35 @@ namespace FftSharp
public static class Pad
{
///
- /// Test if a number is an even power of 2
+ /// Return the input array (or a new zero-padded new one) ensuring length is a power of 2
///
- public static bool IsPowerOfTwo(int x) => ((x & (x - 1)) == 0) && (x > 0);
+ /// array of any length
+ /// the input array or a zero-padded copy
+ [Obsolete("Use methods which consume System.Numerics.Complex")]
+ public static Complex[] ZeroPad(Complex[] input)
+ {
+ if (FftOperations.IsPowerOfTwo(input.Length))
+ return input;
+
+ int targetLength = 1;
+ while (targetLength < input.Length)
+ targetLength *= 2;
+
+ int difference = targetLength - input.Length;
+ Complex[] padded = new Complex[targetLength];
+ Array.Copy(input, 0, padded, difference / 2, input.Length);
+
+ return padded;
+ }
///
/// Return the input array (or a new zero-padded new one) ensuring length is a power of 2
///
/// array of any length
/// the input array or a zero-padded copy
- public static Complex[] ZeroPad(Complex[] input)
+ public static System.Numerics.Complex[] ZeroPad(System.Numerics.Complex[] input)
{
- if (IsPowerOfTwo(input.Length))
+ if (FftOperations.IsPowerOfTwo(input.Length))
return input;
int targetLength = 1;
@@ -26,7 +43,7 @@ public static Complex[] ZeroPad(Complex[] input)
targetLength *= 2;
int difference = targetLength - input.Length;
- Complex[] padded = new Complex[targetLength];
+ System.Numerics.Complex[] padded = new System.Numerics.Complex[targetLength];
Array.Copy(input, 0, padded, difference / 2, input.Length);
return padded;
@@ -39,7 +56,7 @@ public static Complex[] ZeroPad(Complex[] input)
/// the input array or a zero-padded copy
public static double[] ZeroPad(double[] input)
{
- if (IsPowerOfTwo(input.Length))
+ if (FftOperations.IsPowerOfTwo(input.Length))
return input;
int targetLength = 1;
@@ -59,6 +76,7 @@ public static double[] ZeroPad(double[] input)
/// array of any length
/// pad the array with zeros a the end to achieve this final length
/// a zero-padded copy of the input array
+ [Obsolete("Use methods which consume System.Numerics.Complex")]
public static Complex[] ZeroPad(Complex[] input, int finalLength)
{
int difference = finalLength - input.Length;
diff --git a/src/FftSharp/README.md b/src/FftSharp/README.md
index aeec22c..6ecd210 100644
--- a/src/FftSharp/README.md
+++ b/src/FftSharp/README.md
@@ -11,9 +11,9 @@ var window = new FftSharp.Windows.Hanning();
window.ApplyInPlace(signal);
// Calculate the FFT as an array of complex numbers
-Complex[] fftRaw = FftSharp.Transform.FFT(signal);
+System.Numerics.Complex[] spectrum = FftSharp.FFT.Forward(signal);
// or get the magnitude (units²) or power (dB) as real numbers
-double[] fftMag = FftSharp.Transform.FFTmagnitude(signal);
-double[] fftPwr = FftSharp.Transform.FFTpower(signal);
+double[] magnitude = FftSharp.FFT.Magnitude(spectrum);
+double[] power = FftSharp.FFT.Power(spectrum);
```
\ No newline at end of file
diff --git a/src/FftSharp/Transform.cs b/src/FftSharp/Transform.cs
index 5624a2a..5b536d1 100644
--- a/src/FftSharp/Transform.cs
+++ b/src/FftSharp/Transform.cs
@@ -1,17 +1,17 @@
using System;
using System.Buffers;
+using System.Linq;
namespace FftSharp;
-///
-/// FFT operations and helper methods
-///
+//[Obsolete("Use methods in the FftSharp.FFT class")]
public static class Transform
{
///
/// Compute the discrete Fourier Transform (in-place) using the FFT algorithm.
///
/// Data to transform in-place. Length must be a power of 2.
+ [Obsolete("Use FftSharp.FFT.Forward()")]
public static void FFT(Complex[] buffer)
{
if (buffer is null)
@@ -24,18 +24,7 @@ public static void FFT(Complex[] buffer)
/// Compute the discrete Fourier Transform (in-place) using the FFT algorithm.
///
/// Data to transform in-place. Length must be a power of 2.
- public static void FFT(System.Numerics.Complex[] buffer)
- {
- if (buffer is null)
- throw new ArgumentNullException(nameof(buffer));
-
- FFT(buffer.AsSpan());
- }
-
- ///
- /// Compute the discrete Fourier Transform (in-place) using the FFT algorithm.
- ///
- /// Data to transform in-place. Length must be a power of 2.
+ [Obsolete("Use FftSharp.FFT.Forward()")]
public static void FFT(Span buffer)
{
if (buffer.Length == 0)
@@ -47,85 +36,43 @@ public static void FFT(Span buffer)
FftOperations.FFT_WithoutChecks(buffer);
}
- ///
- /// Compute the discrete Fourier Transform (in-place) using the FFT algorithm.
- ///
- /// Data to transform in-place. Length must be a power of 2.
- public static void FFT(Span buffer)
- {
- if (buffer.Length == 0)
- throw new ArgumentException("Buffer must not be empty");
-
- if (!IsPowerOfTwo(buffer.Length))
- throw new ArgumentException("Buffer length must be a power of 2");
-
- FftOperations.FFT_WithoutChecks(buffer);
- }
-
///
/// Calculate sample frequency for each point in a FFT
///
/// Sample rate (Hz) of the original signal
/// Number of points to generate (typically the length of the FFT)
/// Whether or not frequencies are for a one-sided FFT (containing only real numbers)
+ [Obsolete("Use FftSharp.FFT.FrequencyScale()")]
public static double[] FFTfreq(double sampleRate, int pointCount, bool oneSided = true)
{
- double[] freqs = new double[pointCount];
-
- if (oneSided)
- {
- double fftPeriodHz = sampleRate / (pointCount - 1) / 2;
-
- // freqs start at 0 and approach maxFreq
- for (int i = 0; i < pointCount; i++)
- freqs[i] = i * fftPeriodHz;
- return freqs;
- }
- else
- {
- double fftPeriodHz = sampleRate / pointCount;
-
- // first half: freqs start a 0 and approach maxFreq
- int halfIndex = pointCount / 2;
- for (int i = 0; i < halfIndex; i++)
- freqs[i] = i * fftPeriodHz;
-
- // second half: then start at -maxFreq and approach 0
- for (int i = halfIndex; i < pointCount; i++)
- freqs[i] = -(pointCount - i) * fftPeriodHz;
- return freqs;
- }
+ return FftSharp.FFT.FrequencyScale(pointCount, sampleRate, oneSided);
}
///
- /// Return the phase for each point in a Complex array
+ /// Calculate sample frequency for each point in a FFT
///
- public static double[] FFTphase(Complex[] values)
+ /// Sample rate (Hz) of the original signal
+ /// FFT array for which frequencies should be generated
+ /// Whether or not frequencies are for a one-sided FFT (containing only real numbers)
+ [Obsolete("Use FftSharp.FFT.FrequencyScale()")]
+ public static double[] FFTfreq(double sampleRate, double[] fft, bool oneSided = true)
{
- double[] phase = new double[values.Length];
-
- for (int i = 0; i < values.Length; i++)
- phase[i] = values[i].Phase;
-
- return phase;
+ return FFTfreq(sampleRate, fft.Length, oneSided);
}
///
/// Return the phase for each point in a Complex array
///
- public static double[] FFTphase(System.Numerics.Complex[] values)
+ [Obsolete("Use FftSharp.FFT.Phase()")]
+ public static double[] FFTphase(Complex[] values)
{
- double[] phase = new double[values.Length];
-
- for (int i = 0; i < values.Length; i++)
- phase[i] = values[i].Phase;
-
- return phase;
+ return FftSharp.FFT.Phase(Complex.ToNumerics(values));
}
///
/// Take the FFT of the given array and return its phase
///
+ [Obsolete("Use FftSharp.FFT.Phase()")]
public static double[] FFTphase(double[] values)
{
Complex[] fft = FFT(values);
@@ -133,20 +80,10 @@ public static double[] FFTphase(double[] values)
return phase;
}
- ///
- /// Calculate sample frequency for each point in a FFT
- ///
- /// Sample rate (Hz) of the original signal
- /// FFT array for which frequencies should be generated
- /// Whether or not frequencies are for a one-sided FFT (containing only real numbers)
- public static double[] FFTfreq(double sampleRate, double[] fft, bool oneSided = true)
- {
- return FFTfreq(sampleRate, fft.Length, oneSided);
- }
-
///
/// Return the distance between each FFT point in frequency units (Hz)
///
+ [Obsolete("Use FftSharp.FFT.FrequencyResolution()")]
public static double FFTfreqPeriod(int sampleRate, int pointCount)
{
return .5 * sampleRate / pointCount;
@@ -155,14 +92,13 @@ public static double FFTfreqPeriod(int sampleRate, int pointCount)
///
/// Returns true if the given number is evenly divisible by a power of 2
///
- public static bool IsPowerOfTwo(int x)
- {
- return ((x & (x - 1)) == 0) && (x > 0);
- }
+ [Obsolete("Use FftSharp.FftOperations.IsPowerOfTwo()")]
+ public static bool IsPowerOfTwo(int x) => FftOperations.IsPowerOfTwo(x);
///
/// Create an array of Complex data given the real component
///
+ [Obsolete("Use System.Numerics.Complex data structures instead")]
public static Complex[] MakeComplex(double[] real)
{
Complex[] com = new Complex[real.Length];
@@ -173,6 +109,7 @@ public static Complex[] MakeComplex(double[] real)
///
/// Create an array of Complex data given the real component
///
+ [Obsolete("Use System.Numerics.Complex data structures instead")]
public static void MakeComplex(Span com, Span real)
{
if (com.Length != real.Length)
@@ -182,23 +119,12 @@ public static void MakeComplex(Span com, Span real)
com[i] = new Complex(real[i], 0);
}
- ///
- /// Create an array of Complex data given the real component
- ///
- internal static void MakeComplexNumeric(Span com, Span real)
- {
- if (com.Length != real.Length)
- throw new ArgumentOutOfRangeException("Input length must match");
-
- for (int i = 0; i < real.Length; i++)
- com[i] = new System.Numerics.Complex(real[i], 0);
- }
-
///
/// Compute the 1D discrete Fourier Transform using the Fast Fourier Transform (FFT) algorithm
///
/// real input (must be an array with length that is a power of 2)
/// transformed input
+ [Obsolete("Use FftSharp.FFT.Forward()")]
public static Complex[] FFT(double[] input)
{
if (input is null)
@@ -220,6 +146,7 @@ public static Complex[] FFT(double[] input)
///
/// real input (must be an array with length that is a power of 2)
/// real component of transformed input
+ [Obsolete("Use FftSharp.FFT.ForwardReal()")]
public static Complex[] RFFT(double[] input)
{
if (input is null)
@@ -242,6 +169,7 @@ public static Complex[] RFFT(double[] input)
/// Memory location of the results (must be an equal to input length / 2 + 1)
/// real input (must be an array with length that is a power of 2)
/// real component of transformed input
+ [Obsolete("Use FftSharp.FFT.ForwardReal()")]
public static void RFFT(Span destination, Span input)
{
if (!IsPowerOfTwo(input.Length))
@@ -273,6 +201,7 @@ public static void RFFT(Span destination, Span input)
/// Compute the inverse discrete Fourier Transform (in-place) using the FFT algorithm.
///
/// Data to transform in-place. Length must be a power of 2.
+ [Obsolete("Use FftSharp.FFT.Inverse()")]
public static void IFFT(Complex[] buffer)
{
if (buffer is null)
@@ -292,6 +221,7 @@ public static void IFFT(Complex[] buffer)
///
///
///
+ [Obsolete("Use FftSharp.FFT.Magnitude()")]
public static double[] Absolute(Complex[] input)
{
double[] output = new double[input.Length];
@@ -304,6 +234,7 @@ public static double[] Absolute(Complex[] input)
/// Calculate power spectrum density (PSD) original (RMS) units
///
/// real input
+ [Obsolete("Use FftSharp.FFT.Forward() then FftSharp.FFT.Magnitude()")]
public static double[] FFTmagnitude(double[] input)
{
double[] output = new double[input.Length / 2 + 1];
@@ -316,6 +247,7 @@ public static double[] FFTmagnitude(double[] input)
///
/// Memory location of the results.
/// real input
+ [Obsolete("Use FftSharp.FFT.Magnitude()")]
public static void FFTmagnitude(Span destination, Span input)
{
if (input.Length < 2)
@@ -353,6 +285,7 @@ public static void FFTmagnitude(Span destination, Span input)
/// Calculate power spectrum density (PSD) in dB units
///
/// real input
+ [Obsolete("Use FftSharp.FFT.Forward() then FftSharp.FFT.Power()")]
public static double[] FFTpower(double[] input)
{
if (!IsPowerOfTwo(input.Length))
@@ -369,6 +302,7 @@ public static double[] FFTpower(double[] input)
///
/// Memory location of the results.
/// real input
+ [Obsolete("Use FftSharp.FFT.Power()")]
public static void FFTpower(Span destination, double[] input)
{
if (!IsPowerOfTwo(input.Length))
@@ -379,46 +313,27 @@ public static void FFTpower(Span destination, double[] input)
destination[i] = 2 * 10 * Math.Log10(destination[i]);
}
+ ///
+ /// Convert a Mel bin to frequency (Hz)
+ ///
+ [Obsolete("use FftSharp.Mel.ToFreq()")]
public static double MelToFreq(double mel)
{
- return 700 * (Math.Pow(10, mel / 2595d) - 1);
+ return Mel.ToFreq(mel);
}
+ ///
+ /// Convert a frequency (Hz) to a Mel bin
+ ///
+ [Obsolete("use FftSharp.Mel.FromFreq()")]
public static double MelFromFreq(double frequencyHz)
{
- return 2595 * Math.Log10(1 + frequencyHz / 700);
+ return Mel.FromFreq(frequencyHz);
}
+ [Obsolete("use FftSharp.Mel.FrequencyScale()")]
public static double[] MelScale(double[] fft, int sampleRate, int melBinCount)
{
- double freqMax = sampleRate / 2;
- double maxMel = MelFromFreq(freqMax);
-
- double[] fftMel = new double[melBinCount];
- double melPerBin = maxMel / (melBinCount + 1);
- for (int binIndex = 0; binIndex < melBinCount; binIndex++)
- {
- double melLow = melPerBin * binIndex;
- double melHigh = melPerBin * (binIndex + 2);
-
- double freqLow = MelToFreq(melLow);
- double freqHigh = MelToFreq(melHigh);
-
- int indexLow = (int)(fft.Length * freqLow / freqMax);
- int indexHigh = (int)(fft.Length * freqHigh / freqMax);
- int indexSpan = indexHigh - indexLow;
-
- double binScaleSum = 0;
- for (int i = 0; i < indexSpan; i++)
- {
- double binFrac = (double)i / indexSpan;
- double indexScale = (binFrac < .5) ? binFrac * 2 : 1 - binFrac;
- binScaleSum += indexScale;
- fftMel[binIndex] += fft[indexLow + i] * indexScale;
- }
- fftMel[binIndex] /= binScaleSum;
- }
-
- return fftMel;
+ return Mel.Scale(fft, sampleRate, melBinCount);
}
}