public CreateAWaterfall3DChart() { InitializeComponent(); _transform = new FFT2(); Loaded += OnLoaded; }
public void AnalyzeData() { print("AnalyzeData"); total_Acc = new double[raw_data.Count]; textMesh.text = "Calculating total acceleration on " + raw_data.Count.ToString() + " values"; for (int i = 0; i < raw_data.Count; i++) { //calculate total acceleration of the 3 axis total_Acc[i] = Mathf.Sqrt(Mathf.Pow((raw_data.ElementAt(i).x), 2) + Mathf.Pow((raw_data.ElementAt(i).y), 2) + Mathf.Pow((raw_data.ElementAt(i).z), 2)); //print("\t" + total_Acc[i]); } FFT2 fft2 = new FFT2(); /** * Initialize class to perform FFT of specified size. * * @param logN Log2 of FFT length. e.g. for 512 pt FFT, logN = 9. */ textMesh.text = "starting FFT"; fft2.init((uint)Mathf.Log(total_Acc.Length)); //create array of double for Im part-----> array should be compsed by 0 y_fft = new double[total_Acc.Length]; for (int i = 0; i < total_Acc.Length; i++) { y_fft[i] = 0; } //run the fft fft2.run(total_Acc, y_fft); StartCoroutine(ShowResult()); }
public RealtimeWaterfall3DChart() { InitializeComponent(); _random = new Random(); _transform = new FFT2(); Loaded += OnLoaded; }
public ManipulateSeries3DMvvmViewModel() { _random = new FasterRandom(); _transform = new FFT2(); _columnSeries = new ColumnRenderableSeries3DViewModel { ColumnShape = typeof(CylinderPointMarker3D), DataPointWidthX = 0.5, Opacity = 1.0, DataSeries = GetColumnDataSeries() }; _impulseSeries = new ImpulseRenderableSeries3DViewModel { PointMarker = new EllipsePointMarker3D { Fill = Colors.White, Size = 4, Opacity = 1 }, Opacity = 1.0, DataSeries = GetImpulseDataSeries() }; _pointLineSeries = new PointLineRenderableSeries3DViewModel { IsAntialiased = true, PointMarker = new EllipsePointMarker3D { Fill = Colors.LimeGreen, Size = 2.0f, Opacity = 1 }, DataSeries = GetPointLineDataSeries() }; _surfaceMeshSeries = new SurfaceMeshRenderableSeries3DViewModel { StyleKey = "SurfaceMeshStyle", DrawMeshAs = DrawMeshAs.SolidWireFrame, StrokeThickness = 2, DrawSkirt = false, Opacity = 1, DataSeries = GetSurfaceMeshDataSeries() }; _waterfallSeries = new WaterfallRenderableSeries3DViewModel { StyleKey = "WaterfallStyle", Stroke = Colors.Blue, Opacity = 0.8, StrokeThickness = 1, SliceThickness = 0, DataSeries = GetWaterfallDataSeries() }; _scatterSeries = new ScatterRenderableSeries3DViewModel { PointMarker = new EllipsePointMarker3D { Fill = Colors.LimeGreen, Size = 2.0f, Opacity = 1 }, DataSeries = GetScatterDataSeries() }; _mountainSeries = new MountainRenderableSeries3DViewModel { DataSeries = GetColumnDataSeries() }; RenderableSeries = new ObservableCollection <IRenderableSeries3DViewModel>(); SeriesTypes = new ObservableCollection <string> { "Column Series", "Impulse Series", "Mountain Series", "PointLine Series", "SurfaceMesh Series", // "Waterfall Series", "Scatter Series" }; RenderableSeries.Add(_waterfallSeries); }
private void LoadFile(string path, ArrayViewer waveViewer, ArrayViewer fftViewer) { FileStream fileStream = new FileStream(path, FileMode.Open); BinaryReader binaryReader = new BinaryReader(fileStream); short[] wave = new short[binaryReader.BaseStream.Length / 2]; int i = 0; while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) { uint a = binaryReader.ReadByte(); uint b = binaryReader.ReadByte(); wave[i] = (short)((a << 8) | b); i++; } fileStream.Close(); fileStream.Dispose(); waveViewer.DrawWave(wave); Application.DoEvents(); FFT2 fft2 = new FFT2(); fft2.init((uint)Math.Log((double)wave.Length, 2.0)); double[] re = new double[wave.Length]; double[] img = new double[wave.Length]; for (int j = 0; j < wave.Length; j++) { re[j] = wave[j]; img[j] = 0.0F; } fft2.run(re, img); double[] modulo = new double[re.Length / 2]; for (int j = 0; j < modulo.Length; j++) { modulo[j] = Math.Sqrt((re[j] * re[j]) + (img[j] * img[j])); } int number = (int)(2048.0F*(float) modulo.Length/8000.0F); fftViewer.DrawWave(modulo.Take(number).ToArray()); }
//public int numPartitions = 10000; //public float overlapPercent = 0.5f; //public float threshold = 1 - 0.75f; //larger float values are more strict //public float beatDetectionOverlapPercent = 0.5f; /// <summary> /// Processes raw audio data to find average energy for overlapping partitions. /// </summary> /// <returns>The FFT data array.</returns> /// <param name="clip">Audio clip to process.</param> /// <param name="numPartitions">Number of pieces to split the song into for analysis</param> /// <param name="overlapPercent">The percentage which the partitions overlap each other</param> public double[] ProcessAudio(AudioClip clip, int numPartitions, float overlapPercent) { _averages = new double[(int)(numPartitions / overlapPercent) - 1]; int samplesPerPartition = (int)(clip.samples / numPartitions); int numDivisions = (int)(numPartitions / overlapPercent) - 1; //Because the partitions overlap, the number of iterations is the number of partitions multiplied by the inverse of the overlap percent for (int i = 0; i < numDivisions; i++) { float[] samples = new float[samplesPerPartition]; int input = i * ((int)(samples.Length * overlapPercent)); //the offset to start getting song data increases by overlapPercent as i is incremented clip.GetData(samples, input); //the raw partition data is run through the Blackman-Harris windowing function for (int n = 0; n < samples.Length; n++) { samples [n] *= _a0 - _a1 * Mathf.Cos((2 * Mathf.PI * n) / samples.Length - 1) + _a2 * Mathf.Cos((4 * Mathf.PI * n) / samples.Length - 1) - _a3 * Mathf.Cos((6 * Mathf.PI * n) / samples.Length - 1); } FFT2 FFT = new FFT2(); FFT.init((uint)Mathf.Log(samplesPerPartition, 2)); //our array of floats is converted to an array of doubles for use in the FFT function double[] double_samples = samples.ToList().ConvertAll <double> (new System.Converter <float, double> (F2D)).ToArray(); //runs our sample data through a Fast Fourier Transform to convert it to the frequency domain FFT.run(double_samples, new double[samples.Length], false); //gets the average value for this partition and adds it to an array. //when all of the partitions are completed, averages will contain data for the entire song double avg = double_samples.Average(); _averages[i] = avg; } return(_averages); }
//public int numPartitions = 10000; //public float overlapPercent = 0.5f; //public float threshold = 1 - 0.75f; //larger float values are more strict //public float beatDetectionOverlapPercent = 0.5f; /// <summary> /// Processes raw audio data to find average energy for overlapping partitions. /// </summary> /// <returns>The FFT data array.</returns> /// <param name="clip">Audio clip to process.</param> /// <param name="numPartitions">Number of pieces to split the song into for analysis</param> /// <param name="overlapPercent">The percentage which the partitions overlap each other</param> public double[] ProcessAudio(AudioClip clip, int numPartitions, float overlapPercent) { _averages = new double[(int)(numPartitions / overlapPercent) - 1]; int samplesPerPartition = (int)(clip.samples / numPartitions); int numDivisions = (int)(numPartitions / overlapPercent) - 1; //Because the partitions overlap, the number of iterations is the number of partitions multiplied by the inverse of the overlap percent for (int i = 0; i < numDivisions; i++) { float[] samples = new float[samplesPerPartition]; int input = i * ((int) (samples.Length * overlapPercent)); //the offset to start getting song data increases by overlapPercent as i is incremented clip.GetData(samples, input); //the raw partition data is run through the Blackman-Harris windowing function for (int n = 0; n < samples.Length; n++) { samples [n] *= _a0 - _a1 * Mathf.Cos ((2 * Mathf.PI * n) / samples.Length - 1) + _a2 * Mathf.Cos ((4 * Mathf.PI * n) / samples.Length - 1) - _a3 * Mathf.Cos ((6 * Mathf.PI * n) / samples.Length - 1); } FFT2 FFT = new FFT2 (); FFT.init ((uint)Mathf.Log(samplesPerPartition,2)); //our array of floats is converted to an array of doubles for use in the FFT function double[] double_samples = samples.ToList ().ConvertAll<double> (new System.Converter<float, double> (F2D)).ToArray (); //runs our sample data through a Fast Fourier Transform to convert it to the frequency domain FFT.run (double_samples, new double[samples.Length], false); //gets the average value for this partition and adds it to an array. //when all of the partitions are completed, averages will contain data for the entire song double avg = double_samples.Average (); _averages[i] = avg; } return _averages; }
private void but_fftimu13_Click(object sender, EventArgs e) { Utilities.FFT2 fft = new FFT2(); using ( OpenFileDialog ofd = new OpenFileDialog()) { ofd.Filter = "*.log;*.bin|*.log;*.bin;*.BIN;*.LOG"; ofd.ShowDialog(); if (!File.Exists(ofd.FileName)) { return; } var file = new DFLogBuffer(File.OpenRead(ofd.FileName)); int bins = (int)NUM_bins.Value; int N = 1 << bins; Color[] color = new Color[] { Color.Red, Color.Green, Color.Blue, Color.Black, Color.Violet, Color.Orange }; ZedGraphControl[] ctls = new ZedGraphControl[] { zedGraphControl1, zedGraphControl2, zedGraphControl3, zedGraphControl4, zedGraphControl5, zedGraphControl6 }; // 3 imus * 2 sets of measurements(gyr/acc) FFT2.datastate[] alldata = new FFT2.datastate[3 * 2]; for (int a = 0; a < alldata.Length; a++) { alldata[a] = new FFT2.datastate(); } foreach (var item in file.GetEnumeratorType(new string[] { "IMU", "IMU2", "IMU3" })) { if (item.msgtype == null) { continue; } if (item.msgtype.StartsWith("IMU")) { int sensorno = 0; if (item.msgtype == "IMU") { sensorno = 0; } if (item.msgtype == "IMU2") { sensorno = 1; } if (item.msgtype == "IMU3") { sensorno = 2; } alldata[sensorno + 3].type = item.msgtype + " ACC"; int offsetAX = file.dflog.FindMessageOffset(item.msgtype, "AccX"); int offsetAY = file.dflog.FindMessageOffset(item.msgtype, "AccY"); int offsetAZ = file.dflog.FindMessageOffset(item.msgtype, "AccZ"); int offsetTime = file.dflog.FindMessageOffset(item.msgtype, "TimeUS"); double time = double.Parse(item.items[offsetTime], CultureInfo.InvariantCulture) / 1000.0; if (time != alldata[sensorno + 3].lasttime) { alldata[sensorno + 3].timedelta = alldata[sensorno + 3].timedelta * 0.99 + (time - alldata[sensorno + 3].lasttime) * 0.01; } alldata[sensorno + 3].lasttime = time; alldata[sensorno + 3].datax.Add(double.Parse(item.items[offsetAX], CultureInfo.InvariantCulture)); alldata[sensorno + 3].datay.Add(double.Parse(item.items[offsetAY], CultureInfo.InvariantCulture)); alldata[sensorno + 3].dataz.Add(double.Parse(item.items[offsetAZ], CultureInfo.InvariantCulture)); //gyro alldata[sensorno].type = item.msgtype + " GYR"; int offsetGX = file.dflog.FindMessageOffset(item.msgtype, "GyrX"); int offsetGY = file.dflog.FindMessageOffset(item.msgtype, "GyrY"); int offsetGZ = file.dflog.FindMessageOffset(item.msgtype, "GyrZ"); if (time != alldata[sensorno].lasttime) { alldata[sensorno].timedelta = alldata[sensorno].timedelta * 0.99 + (time - alldata[sensorno].lasttime) * 0.01; } alldata[sensorno].lasttime = time; alldata[sensorno].datax.Add(double.Parse(item.items[offsetGX], CultureInfo.InvariantCulture)); alldata[sensorno].datay.Add(double.Parse(item.items[offsetGY], CultureInfo.InvariantCulture)); alldata[sensorno].dataz.Add(double.Parse(item.items[offsetGZ], CultureInfo.InvariantCulture)); } } int controlindex = 0; foreach (var sensordata in alldata) { if (sensordata.datax.Count <= N) { continue; } double samplerate = 0; samplerate = Math.Round(1000 / sensordata.timedelta, 1); double[] freqt = fft.FreqTable(N, (int)samplerate); double[] avgx = new double[N / 2]; double[] avgy = new double[N / 2]; double[] avgz = new double[N / 2]; int totalsamples = sensordata.datax.Count; int count = totalsamples / N; int done = 0; while (count > 1) // skip last part { var fftanswerx = fft.rin(sensordata.datax.AsSpan().Slice(N * done, N), (uint)bins, indB); var fftanswery = fft.rin(sensordata.datay.AsSpan().Slice(N * done, N), (uint)bins, indB); var fftanswerz = fft.rin(sensordata.dataz.AsSpan().Slice(N * done, N), (uint)bins, indB); for (int b = 0; b < N / 2; b++) { if (freqt[b] < (double)NUM_startfreq.Value) { continue; } avgx[b] += fftanswerx[b] / (done + count); avgy[b] += fftanswery[b] / (done + count); avgz[b] += fftanswerz[b] / (done + count); } count--; done++; } ZedGraph.PointPairList pplx = new ZedGraph.PointPairList(freqt, avgx); ZedGraph.PointPairList pply = new ZedGraph.PointPairList(freqt, avgy); ZedGraph.PointPairList pplz = new ZedGraph.PointPairList(freqt, avgz); var curvex = new LineItem(sensordata.type + " x", pplx, color[0], SymbolType.None); var curvey = new LineItem(sensordata.type + " y", pply, color[1], SymbolType.None); var curvez = new LineItem(sensordata.type + " z", pplz, color[2], SymbolType.None); ctls[controlindex].GraphPane.Legend.IsVisible = true; ctls[controlindex].GraphPane.XAxis.Title.Text = "Freq Hz"; ctls[controlindex].GraphPane.YAxis.Title.Text = "Amplitude"; ctls[controlindex].GraphPane.Title.Text = "FFT " + sensordata.type + " - " + Path.GetFileName(ofd.FileName) + " - " + samplerate + "hz input"; ctls[controlindex].GraphPane.CurveList.Clear(); ctls[controlindex].GraphPane.CurveList.Add(curvex); ctls[controlindex].GraphPane.CurveList.Add(curvey); ctls[controlindex].GraphPane.CurveList.Add(curvez); ctls[controlindex].Invalidate(); ctls[controlindex].AxisChange(); ctls[controlindex].GraphPane.XAxis.Scale.Max = samplerate / 2; ctls[controlindex].Refresh(); controlindex++; } SetScale(ctls); } }
double[] DoFFT(double[] values) { double[] real = new double[values.Length]; double[] imaginary = new double[values.Length]; for (int i = 0; i < values.Length; i++) { imaginary[i] = 0f; real[i] = values[i]; } FFT2 fft = new FFT2(); fft.init((uint)Mathf.Log ((float)values.Length)); fft.run (real, imaginary, false); return real; }