public void FourierLinearity() { foreach (int n in sizes) { Console.WriteLine(n); FourierTransformer ft = new FourierTransformer(n); Random rng = new Random(1); Complex[] x = TestUtilities.GenerateComplexValues(0.1, 10.0, n, rng); Complex[] y = TestUtilities.GenerateComplexValues(0.1, 10.0, n, rng); Complex[] z = new Complex[n]; for (int i = 0; i < n; i++) { z[i] = x[i] + y[i]; } Complex[] xt = ft.Transform(x); Complex[] yt = ft.Transform(y); Complex[] zt = ft.Transform(z); for (int i = 0; i < n; i++) { Assert.IsTrue(TestUtilities.IsSumNearlyEqual(xt[i], yt[i], zt[i])); } } }
private void MakeVelo() { List <SignalPoint> sourceSignal = new List <SignalPoint>(); string path = @"D:\stud_repo\astu\DS\FourierTransform\FourierTransform\test\velo\velo04.txt"; sourceSignal = ReadData(path, "velo"); var cs = sourceSignal.Select(p => new Complex(p.Y, 0)).ToArray(); var transform = FourierTransformer.DFT(cs, false); double hc = _profiles["velo"].Frequency / sourceSignal.Count; int targetIndex = (int)Math.Floor(3.0 / hc + 0.5); for (int i = 0; i < targetIndex; i++) { transform[i] = transform[transform.Length - i - 1] = 0; } var result = FourierTransformer.DFT(transform, true) .Select((c, index) => new SignalPoint { X = index / 360.0, Y = c.Real }).ToList(); ShowCharts(sourceSignal, result, "reo"); }
/// <summary> /// Computes the power spectrum of the time series. /// </summary> /// <param name="series">The data series.</param> /// <returns>An array giving the power in each frequency bin.</returns> /// <remarks> /// <para>For a time series of length n, the index k gives the /// power near period n / k, or frequency k / n. (For example, /// for a year-long monthly time series, the value at index 1 /// is proportional to the yearly variation, the value at the index 4 /// is proportional to the quarterly variation, and the value at index 12 /// is proportional to the monthly variation.) The zeroth /// entry is proportional to the unfluctuating component of /// the signal, i.e. the mean.</para> /// </remarks> public static double[] PowerSpectrum(this IReadOnlyList <double> series) { if (series == null) { throw new ArgumentNullException(nameof(series)); } Complex[] s = new Complex[series.Count]; for (int i = 0; i < series.Count; i++) { s[i] = series[i]; } FourierTransformer fft = new FourierTransformer(s.Length); Complex[] t = fft.Transform(s); double[] u = new double[series.Count / 2]; u[0] = MoreMath.Sqr(t[0].Re) + MoreMath.Sqr(t[0].Im); for (int i = 1; i < u.Length; i++) { u[i] = MoreMath.Sqr(t[i].Re) + MoreMath.Sqr(t[i].Im) + MoreMath.Sqr(t[series.Count - i].Re) + MoreMath.Sqr(t[series.Count - i].Im); } return(u); }
/// <summary> /// Computes the auto-covariance for all lags. /// </summary> /// <param name="series">The data series.</param> /// <returns>An array of auto-covariance values, with the array index equal to the lag index.</returns> /// <remarks> /// <para>The computation of the auto-covariance for a given lag is an O(N) operation. /// Naively, the computation of the auto-covariance for all N possible lags is therefore an /// O(N^2) operation; this is in fact the cost of N invocations of /// <see cref="Autocovariance(IReadOnlyList{double},int)"/>. /// However, using Fourier techniques, it is possible to simultaneously compute /// the auto-covariance for all possible lags in O(N log N) operations. This method /// uses the Fourier technique and should be called if you require the auto-covariance /// for more than a handful of lag values.</para> /// </remarks> /// <seealso cref="Autocovariance(IReadOnlyList{double},int)"/> /// <see href="https://en.wikipedia.org/wiki/Autocovariance"/> public static double[] Autocovariance(this IReadOnlyList <double> series) { if (series == null) { throw new ArgumentNullException(nameof(series)); } // To avoid aliasing, we must zero-pad with n zeros. Complex[] s = new Complex[2 * series.Count]; for (int i = 0; i < series.Count; i++) { s[i] = series[i] - series.Mean(); } FourierTransformer fft = new FourierTransformer(s.Length); Complex[] t = fft.Transform(s); for (int i = 0; i < t.Length; i++) { t[i] = MoreMath.Sqr(t[i].Re) + MoreMath.Sqr(t[i].Im); } Complex[] u = fft.InverseTransform(t); double[] c = new double[series.Count]; for (int i = 0; i < c.Length; i++) { c[i] = u[i].Re / series.Count; } return(c); }
private void button4_Click(object sender, EventArgs e) { int p = (int)Math.Floor(Math.Log(_transformedSource.Count, 2)); var range = _transformedSource.GetRange(0, (int)Math.Pow(2, p)); var signalCut = range.Select(pt => new Complex(pt.Y, 0)).ToArray(); Stopwatch sw = new Stopwatch(); sw.Start(); var transform = FourierTransformer.FFT(signalCut, false); sw.Stop(); TimeSpan timeSpan = sw.Elapsed; label1.Text = string.Format("Time: {0}m {1}s {2}ms", timeSpan.Minutes, timeSpan.Seconds, timeSpan.Milliseconds); var fft = FourierTransformer.CalculateSpecs(transform); sourceChart.DataSource = range; sourceChart.DataBind(); ampSpec.DataSource = fft.amplitudeSpec.GetRange(0, fft.amplitudeSpec.Count / 2); ampSpec.Series[0].XValueMember = "X"; ampSpec.Series[0].YValueMembers = "Y"; ampSpec.ChartAreas[0].AxisX.Title = "Гц"; ampSpec.DataBind(); phaseSpec.DataSource = fft.phaseSpec.GetRange(0, fft.phaseSpec.Count / 2); phaseSpec.Series[0].XValueMember = "X"; phaseSpec.Series[0].YValueMembers = "Y"; phaseSpec.ChartAreas[0].AxisX.Title = "Гц"; phaseSpec.DataBind(); }
/// <summary> /// Computes the autocovariance for all lags. /// </summary> /// <returns>An array of autocovariance values, with the array index equal to the lag index.</returns> /// <remarks> /// <para>The computation of the autocovariance for a given lag is an O(N) operation. /// Naively, the computation of the autocovariance for all N possible lags is an /// O(N^2) operation; this is in fact the cost of N invoations of <see cref="Autocovariance(int)"/>. /// However, it is possible using Fourier techniques to simultaneously compute /// the autocovariance for all possible lags in O(N log N) operations. This method /// uses this Fourier technique and should be called if you require the autocovariance /// for more than a handfull of lag values.</para> /// </remarks> /// <seealso cref="Autocovariance(int)"/> public double[] Autocovariance() { // To avoid aliasing, we must zero-pad with n zeros. Complex[] s = new Complex[2 * data.Count]; for (int i = 0; i < data.Count; i++) { s[i] = data[i] - data.Mean; } FourierTransformer fft = new FourierTransformer(s.Length); Complex[] t = fft.Transform(s); for (int i = 0; i < t.Length; i++) { t[i] = MoreMath.Sqr(t[i].Re) + MoreMath.Sqr(t[i].Im); } Complex[] u = fft.InverseTransform(t); double[] c = new double[data.Count]; for (int i = 0; i < c.Length; i++) { c[i] = u[i].Re / data.Count; } return(c); }
public void FourierParseval() { foreach (int n in sizes) { //int n = 15; Console.WriteLine(n); FourierTransformer ft = new FourierTransformer(n); Random rng = new Random(1); Complex[] x = TestUtilities.GenerateComplexValues(0.1, 10.0, n, rng); Complex[] y = TestUtilities.GenerateComplexValues(0.1, 10.0, n, rng); Complex s = 0.0; for (int i = 0; i < n; i++) { s += x[i] * y[i].Conjugate; } Complex[] xt = ft.Transform(x); Complex[] yt = ft.Transform(y); Complex st = 0.0; for (int i = 0; i < n; i++) { st += xt[i] * yt[i].Conjugate; } st /= n; Console.WriteLine("{0} {1}", s, st); Assert.IsTrue(TestUtilities.IsNearlyEqual(s, st)); } }
public static MyPoint[] FourierTransform(MyPoint[] data) { FourierTransformer ft = new FourierTransformer(data.Length); Complex[] x = data.Select(p => (Complex)p.Y).ToArray(); Complex[] xt = ft.Transform(x); double[] result = xt.Select(c => ZComplex(c)).ToArray(); return(result.Select((value, i) => new MyPoint(i, value)).ToArray()); }
private void button3_Click(object sender, EventArgs e) { var lff = FourierTransformer.LFF(fft, wav.Frequency, Convert.ToDouble(textBox2.Text)); var data = lff.Select((c, i) => new SignalPoint { X = i, Y = c.Real }); SaveWav(@"D:\stud_repo\astu\DS\FourierTransform\FourierTransform\wav\lff_test.wav" , data.Select(p => (int)p.Y).ToArray()); chart5.DataSource = data; chart5.Series[0].XValueMember = "X"; chart5.Series[0].YValueMembers = "Y"; chart5.DataBind(); }
public static (double[] result, double[] simpleAFC, double[] dbAFC) CalculateAFC(double fc, int N, WindowType window) { double[] testSignal = new double[1 << 13]; testSignal[0] = 1; double[] resultSignal = ApplyLowFilter(testSignal, fc, N, window); var fft = FourierTransformer.FFT(resultSignal.Select(d => new Complex(d, 0)).ToArray(), false); var afc = FourierTransformer.CalculateSpecs(fft); var db = afc.amplitudeSpec.Select(d => 20 * Log10(d.Y)).ToArray(); return(resultSignal, afc.amplitudeSpec.Select(p => p.Y).ToArray(), db); }
//[TestMethod] public void FourierTiming() { int n = 10020; FourierTransformer ft = new FourierTransformer(n); Complex[] x = new Complex[n]; x[1] = 1.0; Stopwatch t = Stopwatch.StartNew(); Complex[] xt = ft.Transform(x); t.Stop(); Console.WriteLine("{0} {1}", n, t.ElapsedMilliseconds); }
public void TestMethod1() { int N = 49 * 2; FourierTransformer ft = new FourierTransformer(N); Complex[] x = new Complex[N]; x[1] = 1.0; Complex[] y = ft.Transform(x); Complex[] z = ft.InverseTransform(y); //Complex[] z = new Complex[N]; for (int i = 0; i < x.Length; i++) { double t = -2.0 * Math.PI / x.Length * i; Console.WriteLine("{0} -> {1} {2} -> {3}", x[i], y[i], new Complex(Math.Cos(t), Math.Sin(t)), z[i]); } }
public void FourierInverse() { foreach (int n in sizes) { Console.WriteLine(n); FourierTransformer ft = new FourierTransformer(n); Complex[] x = TestUtilities.GenerateComplexValues(0.1, 10.0, n); Complex[] y = ft.Transform(x); Complex[] z = ft.InverseTransform(y); for (int i = 0; i < n; i++) { Assert.IsTrue(TestUtilities.IsNearlyEqual(x[i], z[i])); } } }
private void button2_Click(object sender, EventArgs e) { var cs = _transformedSource.Select(p => new Complex(p.Y, 0)).ToList().GetRange(0, 512).ToArray(); var transform = FourierTransformer.FFT(cs, false); var allHarms = FourierTransformer.FFT(transform, true); chart2.DataSource = allHarms.Select((c, index) => new SignalPoint { X = 1.0 * index / 360, Y = c.Real }).ToList(); chart2.Series[0].XValueMember = "X"; chart2.Series[0].YValueMembers = "Y"; chart2.DataBind(); for (int i = High; i < transform.Length - High; i++) { transform[i] = transform[i] = 0; } var resultHigh = FourierTransformer.FFT(transform, true); chart3.DataSource = resultHigh.Select((c, index) => new SignalPoint { X = 1.0 * index / 360, Y = c.Real }).ToList();; chart3.Series[0].XValueMember = "X"; chart3.Series[0].YValueMembers = "Y"; chart3.DataBind(); for (int i = Low; i < transform.Length - Low; i++) { transform[i] = transform[i] = 0; } var resultLow = FourierTransformer.FFT(transform, true); chart4.DataSource = resultLow.Select((c, index) => new SignalPoint { X = 1.0 * index / 360, Y = c.Real }).ToList();; chart4.Series[0].XValueMember = "X"; chart4.Series[0].YValueMembers = "Y"; chart4.DataBind(); }
/// <summary> /// Computes the power spectrum of the time series. /// </summary> /// <returns>An array giving the power in each frequency bin.</returns> /// <remarks> /// <para>For a time series of length n, the index k gives the /// power near period n / k, or frequency k / n. (For example, /// for a year-long monthly time series, the value at index 1 /// is proportional to the yearly variation, the value at the index 4 /// is proportional to the quarterly variation, and the value at index 12 /// is proportional to the monthly variation.) The zeroth /// entry is proportional to the unfluctuating component of /// the signal, i.e. the mean.</para> /// </remarks> public double[] PowerSpectrum() { Complex[] s = new Complex[data.Count]; for (int i = 0; i < data.Count; i++) { s[i] = data[i]; } FourierTransformer fft = new FourierTransformer(s.Length); Complex[] t = fft.Transform(s); double[] u = new double[data.Count / 2]; u[0] = MoreMath.Sqr(t[0].Re) + MoreMath.Sqr(t[0].Im); for (int i = 1; i < u.Length; i++) { u[i] = MoreMath.Sqr(t[i].Re) + MoreMath.Sqr(t[i].Im) + MoreMath.Sqr(t[data.Count - i].Re) + MoreMath.Sqr(t[data.Count - i].Im); } return(u); }
public void FourierSpecialCases() { for (int n = 2; n <= 10; n++) { FourierTransformer ft = new FourierTransformer(n); Assert.IsTrue(ft.Length == n); // transform of uniform is zero frequency only Complex[] x1 = new Complex[n]; for (int i = 0; i < n; i++) { x1[i] = 1.0; } Complex[] y1 = ft.Transform(x1); Assert.IsTrue(TestUtilities.IsNearlyEqual(y1[0], n)); for (int i = 1; i < n; i++) { Assert.IsTrue(ComplexMath.Abs(y1[i]) < TestUtilities.TargetPrecision); } Complex[] z1 = ft.InverseTransform(y1); for (int i = 0; i < n; i++) { Assert.IsTrue(TestUtilities.IsNearlyEqual(z1[i], 1.0)); } // transform of pulse at 1 are nth roots of unity, read clockwise Complex[] x2 = new Complex[n]; x2[1] = 1.0; Complex[] y2 = ft.Transform(x2); for (int i = 0; i < n; i++) { double t = -2.0 * Math.PI / n * i; Assert.IsTrue(TestUtilities.IsNearlyEqual(y2[i], new Complex(Math.Cos(t), Math.Sin(t)))); } } }
private void MakeCardio() { List <SignalPoint> sourceSignal = new List <SignalPoint>(); string path = @"D:\stud_repo\astu\DS\FourierTransform\FourierTransform\test\car\cardio05.txt"; sourceSignal = ReadData(path, "cardio"); //var ab = Fourier.FourierTransformer.CalculateAB(sourceSignal); var cs = sourceSignal.Select(p => new Complex(p.Y, 0)).ToArray(); var transform = FourierTransformer.DFT(cs, false); double hc = _profiles["cardio"].Frequency / sourceSignal.Count; int targetIndex = (int)Math.Floor(50.0 / hc + 0.5); transform[targetIndex - 1] = transform[targetIndex] = transform[targetIndex + 1] = 0; //ab.b[targetIndex - 1] = ab.b[targetIndex] = ab.b[targetIndex + 1] = 0; var result = FourierTransformer.DFT(transform, true) .Select((c, index) => new SignalPoint { X = index / 360.0, Y = c.Real }).ToList(); ShowCharts(sourceSignal, result, "cardio"); }
public bool MakeSnaps(int snapsize, int snapcount, string path) { try { SnapSize = snapsize; SnapCount = snapcount; Path = path; using (var pcm = new Mp3FileReader(path)) { Length = pcm.TotalTime.Seconds; TotalSamples = pcm.Length; int samplesDesired = snapsize; int blockscount = snapcount; if ((pcm.WaveFormat.SampleRate != 44100) || (pcm.WaveFormat.BitsPerSample != 16)) { return(false); } for (int i = 0; i < blockscount; i++) { var buffer = new byte[samplesDesired * 4]; var left = new short[samplesDesired]; var right = new short[samplesDesired]; var leftd = new double[samplesDesired]; var rightd = new double[samplesDesired]; int seekCounter = 0; while (seekCounter <= 5) { pcm.Seek((i + 1) * (i + 1) * (i + 1) * blockscount * samplesDesired % (TotalSamples - samplesDesired), SeekOrigin.Begin); seekCounter++; var bytesRead = pcm.Read(buffer, 0, 4 * samplesDesired); int index = 0; for (int sample = 0; sample < bytesRead / 4; sample++) { left[sample] = BitConverter.ToInt16(buffer, index + 0); right[sample] = BitConverter.ToInt16(buffer, index + 2); index += 4; } if (left.Average(t => Math.Abs(t)) != 0) { break; } } leftd = Utility.Normalize(left, left.Length); rightd = Utility.Normalize(right, right.Length); var ft = new FourierTransformer(samplesDesired); var xxa = new Complex[samplesDesired]; for (int j = 0; j < samplesDesired; j++) { xxa[j] = new Complex(leftd[j], rightd[j]); } var ftt = ft.Transform(xxa); var pow_re_im = new List <double>(ftt.Length); for (int j = 0; j < ftt.Length; ++j) { pow_re_im.Add(ComplexMath.Abs(ftt[j])); } fft_snaps.Add(pow_re_im); } pcm.Close(); } } catch (Exception) { return(false); } return(true); }
public general() { InitializeComponent(); // Scale chart to overlay the fourier graph List <Entry> scaleEntries = new List <Entry>(); for (int j = 0; j < 125; j++) { if (j % 25 == 0 && j > 0) { scaleEntries.Add(new Entry((int)(j / 2.5)) { ValueLabel = ((int)(j / 2.5)).ToString(), Color = SKColor.FromHsl(1, 100, 100, 255) }); } else { scaleEntries.Add(new Entry((int)(j / 2.5))); } } var scaleChart = new LineChart() { Entries = scaleEntries, LineMode = LineMode.None, PointMode = PointMode.None, LabelTextSize = 50, PointSize = 0, BackgroundColor = SKColor.FromHsl(243, 100, 50, 0) }; this.fourierScaleChart.Chart = scaleChart; FourierTransformer ft = new FourierTransformer(250); List <Complex> headBandInput = new List <Complex>(); //double Fs = 100; // Headband entries List <Entry> entries = new List <Entry>(); List <Entry> chartEntries = new List <Entry>(); // The list that will contain all the fourier data List <Entry> fourierTransform = new List <Entry>(); List <Entry> barEntries = new List <Entry>(); // Headset entries List <Entry> temperatureEntries = new List <Entry>(); List <Entry> accelXEntries = new List <Entry>(); List <Entry> accelYEntries = new List <Entry>(); List <Entry> accelZEntries = new List <Entry>(); List <Entry> gyXEntries = new List <Entry>(); List <Entry> gyYEntries = new List <Entry>(); List <Entry> gyZEntries = new List <Entry>(); List <Entry> presEntries = new List <Entry>(); List <Entry> speedEntries = new List <Entry>(); // First pass to properly remove the correct value of fourier bool firstpass = false; int packetCount = 0; int packetHSCount = 0; int elect1_0 = 0; int elect2_0 = 0; int elect1_1 = 0; int elect2_1 = 0; int elect1_2 = 0; int elect2_2 = 0; int elect1_3 = 0; int elect2_3 = 0; float thetaWave = 0; float alphaWave = 0; float betaWave = 0; float totalPower = 0; CrossBluetoothLE.Current.Adapter.DeviceAdvertised += (s, e) => { // Check if we are connected to our devices and workout is running if ((Guids._guids.HBConnected == true || Guids._guids.HSConnected == true) && finishBtn.IsEnabled) { // Check if device is headband, headset, or not one of our devices if (Guids._guids.HBConnected == true && Guids._guids.HeadbandGuid == e.Device.Id) { // Grab advertisements and process Plugin.BLE.Abstractions.AdvertisementRecord[] advertisement = e.Device.AdvertisementRecords.ToArray(); //var temp = advertisement[3].Data[0]; if (advertisement.Length == 4) { elect1_0 = advertisement[3].Data[0] | (advertisement[3].Data[1] << 8); elect2_0 = advertisement[3].Data[2] | (advertisement[3].Data[3] << 8); elect1_1 = advertisement[3].Data[4] | (advertisement[3].Data[5] << 8); elect2_1 = advertisement[3].Data[6] | (advertisement[3].Data[7] << 8); elect1_2 = advertisement[3].Data[8] | (advertisement[3].Data[9] << 8); elect2_2 = advertisement[3].Data[10] | (advertisement[3].Data[11] << 8); elect1_3 = advertisement[3].Data[12] | (advertisement[3].Data[13] << 8); elect2_3 = advertisement[3].Data[14] | (advertisement[3].Data[15] << 8); } else { elect1_0 = advertisement[1].Data[0] | (advertisement[1].Data[1] << 8); elect2_0 = advertisement[1].Data[2] | (advertisement[1].Data[3] << 8); elect1_1 = advertisement[1].Data[4] | (advertisement[1].Data[5] << 8); elect2_1 = advertisement[1].Data[6] | (advertisement[1].Data[7] << 8); elect1_2 = advertisement[1].Data[8] | (advertisement[1].Data[9] << 8); elect2_2 = advertisement[1].Data[10] | (advertisement[1].Data[11] << 8); elect1_3 = advertisement[1].Data[12] | (advertisement[1].Data[13] << 8); elect2_3 = advertisement[1].Data[14] | (advertisement[1].Data[15] << 8); } int input0 = elect1_0 + elect2_0; int input1 = elect1_1 + elect2_1; int input2 = elect1_2 + elect2_2; int input3 = elect1_3 + elect2_3; // Remove at 0 position for our chart if (chartEntries.Count > 100) { chartEntries.RemoveAt(0); } if (packetCount == 10) { // Add an entry with a title entries.Add(new Entry(input0) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = input0.ToString() }); chartEntries.Add(new Entry(input0) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = input0.ToString() }); // Add the rest of the entries entries.Add(new Entry(input1) { Color = SKColor.FromHsl(1, 100, 100, 255) }); chartEntries.Add(new Entry(input1) { Color = SKColor.FromHsl(1, 100, 100, 255) }); entries.Add(new Entry(input2) { Color = SKColor.FromHsl(1, 100, 100, 255) }); chartEntries.Add(new Entry(input2) { Color = SKColor.FromHsl(1, 100, 100, 255) }); entries.Add(new Entry(input3) { Color = SKColor.FromHsl(1, 100, 100, 255) }); chartEntries.Add(new Entry(input3) { Color = SKColor.FromHsl(1, 100, 100, 255) }); packetCount = 0; } else { entries.Add(new Entry(input0) { Color = SKColor.FromHsl(1, 100, 100, 255) }); chartEntries.Add(new Entry(input0) { Color = SKColor.FromHsl(1, 100, 100, 255) }); entries.Add(new Entry(input1) { Color = SKColor.FromHsl(1, 100, 100, 255) }); chartEntries.Add(new Entry(input1) { Color = SKColor.FromHsl(1, 100, 100, 255) }); entries.Add(new Entry(input2) { Color = SKColor.FromHsl(1, 100, 100, 255) }); chartEntries.Add(new Entry(input2) { Color = SKColor.FromHsl(1, 100, 100, 255) }); entries.Add(new Entry(input3) { Color = SKColor.FromHsl(1, 100, 100, 255) }); chartEntries.Add(new Entry(input3) { Color = SKColor.FromHsl(1, 100, 100, 255) }); packetCount++; } // Add values to our fourier list headBandInput.Add(input0); headBandInput.Add(input1); headBandInput.Add(input2); headBandInput.Add(input3); var chart = new LineChart() { Entries = chartEntries, LabelTextSize = 100, LineSize = 10, LineMode = LineMode.Straight, PointSize = 20, BackgroundColor = SKColor.Parse("#393E46") }; this.chartView.Chart = chart; // Entries has reached max size if (entries.Count > 250) { // Remove oldest values while (headBandInput.Count > 250) { headBandInput.RemoveAt(0); entries.RemoveAt(0); chartEntries.RemoveAt(0); } // Perform fourier Complex[] xt = ft.Transform(headBandInput); for (int i = 1; i < 125; i++) { xt[i] = Meta.Numerics.ComplexMath.Abs(xt[i] * 2 / 250); // Needed to not stack up fourier graphs if (firstpass == true) { fourierTransform.RemoveAt(0); } fourierTransform.Add(new Entry((float)xt[i]) { Color = SKColor.FromHsl(1, 100, 100, 255) }); } // Makes it so it doesn't remove the first value while it doesn't exsist. firstpass = true; var fChart = new LineChart() { Entries = fourierTransform, LabelTextSize = 100, LineSize = 10, LineMode = LineMode.Straight, PointSize = 20, BackgroundColor = SKColor.Parse("#393E46") }; this.fourierChart.Chart = fChart; totalPower = 0; thetaWave = 0; alphaWave = 0; betaWave = 0; for (int n = 1; n < 125; n++) { if (n >= 30 && n <= 75) { betaWave += (float)xt[n]; } else if (n >= 20 && n < 30) { alphaWave += (float)xt[n]; } else if (n >= 5 && n < 20) { thetaWave += (float)xt[n]; } else { totalPower += (float)xt[n]; } } if (barEntries.Count > 0) { barEntries.RemoveAt(0); barEntries.RemoveAt(0); barEntries.RemoveAt(0); barEntries.RemoveAt(0); } barEntries.Add(new Entry(thetaWave) { Color = SKColor.Parse("#8B4B62"), ValueLabel = betaWave.ToString(), Label = "Sleepiness" }); barEntries.Add(new Entry(alphaWave) { Color = SKColor.Parse("#BB6F6B"), ValueLabel = betaWave.ToString(), Label = "Relaxation" }); barEntries.Add(new Entry(betaWave) { Color = SKColor.Parse("#FCBC80"), ValueLabel = betaWave.ToString(), Label = "Concentration" }); barEntries.Add(new Entry(totalPower) { Color = SKColor.Parse("#EA9674"), ValueLabel = totalPower.ToString(), Label = "Other" }); var barChart = new DonutChart { Entries = barEntries, BackgroundColor = SKColor.Parse("#393E46"), LabelTextSize = 40, }; this.barGraphChart.Chart = barChart; } } else if (Guids._guids.HSConnected == true && Guids._guids.HeadsetGuid == e.Device.Id) { Plugin.BLE.Abstractions.AdvertisementRecord[] advertisementHS = e.Device.AdvertisementRecords.ToArray(); // Geolocator //packetTemp++; //if (CrossGeolocator.IsSupported && IsLocationAvailable() && CrossGeolocator.Current.IsGeolocationEnabled && packetTemp == 10) //{ // double speed = await getSpeed(); // speedEntries.Add(new Entry((float)speed) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = speed.ToString() }); // packetTemp = 0; // var speedChart = new LineChart() // { // Entries = speedEntries, // LabelTextSize = 100, // LineSize = 10, // LineMode = LineMode.Straight, // PointSize = 20, // BackgroundColor = SKColor.Parse("#393E46") // }; // this.speedChart.Chart = speedChart; //} // Data variables int tempHS = 0; //int presHS = 0; float accelX = 0; float accelY = 0; float accelZ = 0; float gyX = 0; float gyY = 0; float gyZ = 0; if (advertisementHS.Length == 3) { tempHS = advertisementHS[2].Data[3] | (advertisementHS[2].Data[4] << 8); accelX = advertisementHS[2].Data[5] | (advertisementHS[2].Data[6] << 8) | (advertisementHS[2].Data[7] << 16) | (advertisementHS[2].Data[8] << 24); accelY = advertisementHS[2].Data[9] | (advertisementHS[2].Data[10] << 8) | (advertisementHS[2].Data[11] << 16) | (advertisementHS[2].Data[12] << 24); accelZ = advertisementHS[2].Data[13] | (advertisementHS[2].Data[14] << 8) | (advertisementHS[2].Data[15] << 16) | (advertisementHS[2].Data[16] << 24); gyX = advertisementHS[2].Data[17] | (advertisementHS[2].Data[18] << 8) | (advertisementHS[2].Data[18] << 16) | (advertisementHS[2].Data[19] << 24); gyY = advertisementHS[2].Data[21] | (advertisementHS[2].Data[22] << 8) | (advertisementHS[2].Data[23] << 16) | (advertisementHS[2].Data[24] << 24); gyZ = advertisementHS[2].Data[25] | (advertisementHS[2].Data[26] << 8) | (advertisementHS[2].Data[27] << 16) | (advertisementHS[2].Data[28] << 24); // presHS = advertisementHS[2].Data[29] | (advertisementHS[2].Data[30] << 8); } else { tempHS = advertisementHS[0].Data[3] | (advertisementHS[0].Data[4] << 8); accelX = advertisementHS[0].Data[5] | (advertisementHS[0].Data[6] << 8) | (advertisementHS[0].Data[7] << 16) | (advertisementHS[0].Data[8] << 24); accelY = advertisementHS[0].Data[9] | (advertisementHS[0].Data[10] << 8) | (advertisementHS[0].Data[11] << 16) | (advertisementHS[0].Data[12] << 24); accelZ = advertisementHS[0].Data[13] | (advertisementHS[0].Data[14] << 8) | (advertisementHS[0].Data[15] << 16) | (advertisementHS[0].Data[16] << 24); gyX = advertisementHS[0].Data[17] | (advertisementHS[0].Data[18] << 8) | (advertisementHS[0].Data[18] << 16) | (advertisementHS[0].Data[19] << 24); gyY = advertisementHS[0].Data[21] | (advertisementHS[0].Data[22] << 8) | (advertisementHS[0].Data[23] << 16) | (advertisementHS[0].Data[24] << 24); gyZ = advertisementHS[0].Data[25] | (advertisementHS[0].Data[26] << 8) | (advertisementHS[0].Data[27] << 16) | (advertisementHS[0].Data[28] << 24); // presHS = advertisementHS[0].Data[29] | (advertisementHS[0].Data[30] << 8); } // Bit parsing tempHS = tempHS / 100; // presHS = ((0x0142EE << 8) | presHS)/256; accelX = accelX / 1000; accelY = accelY / 1000; accelZ = accelZ / 1000; gyX = gyX / 1000; gyY = gyY / 1000; gyZ = gyZ / 1000; // When temperatureEntries is > 50 every HS data is >50 so remove first value if (temperatureEntries.Count > 50) { temperatureEntries.RemoveAt(0); accelXEntries.RemoveAt(0); accelYEntries.RemoveAt(0); accelZEntries.RemoveAt(0); gyXEntries.RemoveAt(0); gyYEntries.RemoveAt(0); gyZEntries.RemoveAt(0); } // Adds data to each entry. If it is the 10th entry it adds a display value if (packetHSCount == 10) { temperatureEntries.Add(new Entry(tempHS) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = (tempHS).ToString() }); accelXEntries.Add(new Entry((float)accelX) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = ((float)accelX).ToString() }); accelYEntries.Add(new Entry((float)accelY) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = ((float)accelY).ToString() }); accelZEntries.Add(new Entry((float)accelZ) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = ((float)accelZ).ToString() }); gyXEntries.Add(new Entry((float)gyX) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = ((float)gyX).ToString() }); gyYEntries.Add(new Entry((float)gyY) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = ((float)gyY).ToString() }); gyZEntries.Add(new Entry((float)gyZ) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = ((float)gyZ).ToString() }); // presEntries.Add(new Entry(presHS) { Color = SKColor.FromHsl(1, 100, 100, 255), ValueLabel = (presHS).ToString() }); packetHSCount = 0; } else { temperatureEntries.Add(new Entry(tempHS) { Color = SKColor.FromHsl(1, 100, 100, 255) }); accelXEntries.Add(new Entry((float)accelX) { Color = SKColor.FromHsl(1, 100, 100, 255) }); accelYEntries.Add(new Entry((float)accelY) { Color = SKColor.FromHsl(1, 100, 100, 255) }); accelZEntries.Add(new Entry((float)accelZ) { Color = SKColor.FromHsl(1, 100, 100, 255) }); gyXEntries.Add(new Entry((float)gyX) { Color = SKColor.FromHsl(1, 100, 100, 255) }); gyYEntries.Add(new Entry((float)gyY) { Color = SKColor.FromHsl(1, 100, 100, 255) }); gyZEntries.Add(new Entry((float)gyZ) { Color = SKColor.FromHsl(1, 100, 100, 255) }); // presEntries.Add(new Entry(presHS) { Color = SKColor.FromHsl(1, 100, 100, 255) }); packetHSCount++; } // Declares the temperature chart var tempChart = new LineChart() { Entries = temperatureEntries, LabelTextSize = 100, LineSize = 10, LineMode = LineMode.Straight, PointSize = 20, BackgroundColor = SKColor.Parse("#393E46") }; this.temperatureChart.Chart = tempChart; // Declares the accel x chart var accelXChart = new LineChart() { Entries = accelXEntries, LabelTextSize = 100, LineSize = 10, LineMode = LineMode.Straight, PointSize = 20, BackgroundColor = SKColor.Parse("#393E46") }; this.accelXChart.Chart = accelXChart; var accelYChart = new LineChart() { Entries = accelYEntries, LabelTextSize = 100, LineSize = 10, LineMode = LineMode.Straight, PointSize = 20, BackgroundColor = SKColor.Parse("#393E46") }; this.accelYChart.Chart = accelYChart; var accelZChart = new LineChart() { Entries = accelZEntries, LabelTextSize = 100, LineSize = 10, LineMode = LineMode.Straight, PointSize = 20, BackgroundColor = SKColor.Parse("#393E46") }; this.accelZChart.Chart = accelZChart; var gyXChart = new LineChart() { Entries = gyXEntries, LabelTextSize = 100, LineSize = 10, LineMode = LineMode.Straight, PointSize = 20, BackgroundColor = SKColor.Parse("#393E46") }; this.gyXChart.Chart = gyXChart; var gyYChart = new LineChart() { Entries = gyYEntries, LabelTextSize = 100, LineSize = 10, LineMode = LineMode.Straight, PointSize = 20, BackgroundColor = SKColor.Parse("#393E46") }; this.gyYChart.Chart = gyYChart; var gyZChart = new LineChart() { Entries = gyZEntries, LabelTextSize = 100, LineSize = 10, LineMode = LineMode.Straight, PointSize = 20, BackgroundColor = SKColor.Parse("#393E46") }; this.gyZChart.Chart = gyZChart; } } }; BindingContext = this; }
static TransferDataSong ReadAndProcess(AudioFileReader reader, string SongPath) { FourierTransformer ft = new FourierTransformer(_FrameSize); Complex[] temp = new Complex[_FrameSize]; double[] Amp = new double[_FrameSize]; double[] F = new double[_FrameSize]; double[] sBass = LinSpace(16, 60, _NumberOfFreqIntervals).ToArray(); double[] Bass = LinSpace(60, 250, _NumberOfFreqIntervals).ToArray(); double[] Mid = LinSpace(250, 2000, _NumberOfFreqIntervals).ToArray(); double[] HighMid = LinSpace(2000, 6000, _NumberOfFreqIntervals).ToArray(); double[] High = LinSpace(6000, 15000, _NumberOfFreqIntervals).ToArray(); double[] MainFreqs = sBass.Concat(Bass).Concat(Mid).Concat(HighMid).Concat(High).Distinct().ToArray(); double[] MeanFreqs = new double[MainFreqs.Length - 1]; double[] MedianFreqs = new double[MainFreqs.Length - 1]; double[] StdFreqs = new double[MainFreqs.Length - 1]; Sample FreqSample = new Sample(); double sum; for (int i = 0; i < _FrameSize; i++) { F[i] = (double)i / (_FrameSize / 2 + 1) * reader.WaveFormat.SampleRate / 2; } int[] FreqIndRange = new int[MainFreqs.Length]; for (int i = 0; i < MainFreqs.Length; i++) { int j = 0; while (F[j] < MainFreqs[i]) { j++; } FreqIndRange[i] = j; } // Create mediumsize array for reading from stream int sampleCount = Math.Min(Convert.ToInt32(reader.Length / sizeof(float) / _NumberOfFrames), Convert.ToInt32(reader.WaveFormat.SampleRate * _TimeToProcess * 2 / _NumberOfFrames)); if (sampleCount < _FrameSize * 2) { sampleCount = _FrameSize * 2; } float[] buffer = new float[sampleCount]; for (int m = 0; m < _NumberOfFrames; m++) { reader.Read(buffer, 0, sampleCount); for (int k = 0; k < temp.Length; k++) { temp[k] = buffer[2 * k]; } Complex[] FFTresults = ft.Transform(temp); for (int i = 0; i < _FrameSize; i++) { Amp[i] = Meta.Numerics.ComplexMath.Abs(FFTresults[i]); } sum = Amp.Sum(); Amp = Amp.Select(x => x / sum).ToArray(); for (int s = 0; s < MainFreqs.Length - 1; s++) { FreqSample.Clear(); double[] PartAmp = new double[FreqIndRange[s + 1] - FreqIndRange[s]]; Array.Copy(Amp, FreqIndRange[s], PartAmp, 0, PartAmp.Length); FreqSample.Add(PartAmp); MeanFreqs[s] += FreqSample.Mean / _NumberOfFrames; MedianFreqs[s] += FreqSample.Median / _NumberOfFrames; StdFreqs[s] += FreqSample.StandardDeviation / _NumberOfFrames; } } for (int i = 0; i < MeanFreqs.Length; i++) { if (Double.IsNaN(MeanFreqs[i])) { throw new System.Exception("Results of FFT is NaN"); } } MemoryStream DataStream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(DataStream, new TransferDataFFT(MeanFreqs, MedianFreqs, StdFreqs)); //DataStream.Position = 0; //TransferDataFFT TransferStruct2 = (TransferDataFFT)formatter.Deserialize(DataStream); TransferDataSong tds = new TransferDataSong(); tds.data = DataStream.ToArray(); tds.path = SongPath; TimeSpan t = TimeSpan.FromSeconds(reader.TotalTime.TotalSeconds); tds.duration = string.Format("{0:D2}:{1:D2}", t.Minutes, t.Seconds); TagLib.ByteVector.UseBrokenLatin1Behavior = true; using (TagLib.File tagFile = TagLib.File.Create(SongPath)) { tds.title = tagFile.Tag.Title; tds.artist = tagFile.Tag.FirstPerformer; } DataStream.Close(); return(tds); }
public bool MakeSnaps(int _snapsize, int _snapcount, string _path, int smooth_size) { try { using (Mp3FileReader pcm = new Mp3FileReader(_path)) { int samplesDesired = _snapsize; int blockscount = _snapcount; snap_size = _snapsize; snap_count = _snapcount; total_samples = pcm.Length; length = pcm.TotalTime.Seconds; path = _path; if ((pcm.WaveFormat.SampleRate != 44100) || (pcm.WaveFormat.BitsPerSample != 16)) { return(false); } for (int i = 0; i < blockscount; i++) { byte[] buffer = new byte[samplesDesired * 4]; short[] left = new short[samplesDesired]; short[] right = new short[samplesDesired]; double[] leftd = new double[samplesDesired]; double[] rightd = new double[samplesDesired]; int bytesRead = 0; //for (int j = 0; j < 1; j++) /////////// int seek_counter = 0; seek : pcm.Seek((i + 1) * (i + 1) * (i + 1) * blockscount * samplesDesired % (total_samples - samplesDesired), SeekOrigin.Begin); seek_counter++; bytesRead = pcm.Read(buffer, 0, 4 * samplesDesired); int index = 0; for (int sample = 0; sample < bytesRead / 4; sample++) { left[sample] = BitConverter.ToInt16(buffer, index); index += 2; right[sample] = BitConverter.ToInt16(buffer, index); index += 2; } if (left.Average(t => Math.Abs(t)) == 0) { if (seek_counter > 5) { return(false); } else { goto seek; } } //snap_log10_energy.Add(Math.Log10(left.Average(t => Math.Abs(t)))); leftd = Normalize(left, left.Length); rightd = Normalize(right, right.Length); //alglib.complex[] fl; //alglib.fftr1d(leftd, out fl); //fl[0].x; FourierTransformer ft = new FourierTransformer(samplesDesired); var xxa = new Complex[leftd.Length]; for (int j = 0; j < leftd.Length; j++) { xxa[j] = new Complex(leftd[j], rightd[j]); } var ftt = ft.Transform(xxa); List <double> pow_re_im = new List <double>(); //List<double> arg_re_im = new List<double>(); ftt.ToList().ForEach(t => pow_re_im.Add(ComplexMath.Abs(t))); //ftt.ToList().ForEach(t => arg_re_im.Add(ComplexMath.Arg(t))); /*if (Double.IsNaN(MC_Log10_Energy(pow_re_im))) * if (seek_counter > 5) * return false; * else * goto seek;*/ fft_snaps.Add(pow_re_im); //fft_smoothed_snaps.Add(Smoothen(pow_re_im, smooth_size)); //pow_re_im = Normalize(pow_re_im); /* * var f_pwri = pow_re_im.Average(t => Math.Abs(t)); * for (int k = 0; k < pow_re_im.Count; k++) * pow_re_im[k] = (Math.Abs(pow_re_im[k]) >= f_pwri * 1.5) ? pow_re_im[k] : 0; */ /* * FourierTransformer ft2 = new FourierTransformer(samplesDesired); * var xx2 = new List<Complex>(); * for (int j = 0; j < pow_re_im.Count; j++) * { * xx2.Add(new Complex(pow_re_im[j], arg_re_im[j])); * } * var ftt2 = ft2.Transform(xx2); * //var ftt2 = ft2.Transform(ftt); * * List<double> pow_re_im2 = new List<double>(); * ftt2.ToList().ForEach(t => pow_re_im2.Add(ComplexMath.Abs(t))); * pow_re_im2 = Normalize(pow_re_im2); * fft2_snaps.Add(pow_re_im2); * fft2_smoothed_snaps.Add(Smoothen(pow_re_im2, smooth_size)); */ } pcm.Close(); } } catch (Exception e) { return(false); } return(true); }