public FileOutput(MultiChannelInput <IDataChannel> mci, string path) { this.directory = Path.GetDirectoryName(path); this.filename = Path.GetFileNameWithoutExtension(path); this.extension = Path.GetExtension(path); this.changedChannels = new HashSet <int>(); this.channelDataChanges = new List <Models.DataChangedEventArgs>(); mci.AllChannelsDataChanged += AllDataChanged; dataWriterTimer = new Timer(WriteDataFromBuffer, this, 0, latencyMs); }
public SimpleVTSFileOutput(MultiChannelInput <IDataChannel> mci, string path, bool createFileSeries = false) : base(mci, path) { this.fileWriteThreshold = 0.0f; this.createFileSeries = createFileSeries; PhysicalBoundaries boundaries = ChannelMapper.GetChannelInputBoundaries(mci); var filter = FilterManager.FindFilter <FFTWFilter>(mci.GetChannel(0)); if (filter == null) { throw new Exception("SimpleVTSFileOutput supports FFTWFilter only."); } var filterSettings = filter.GetSettings(); if (filterSettings.OutputFormat != FFTOutputFormat.Magnitude) { throw new InvalidDataException($"SimpleVTSFileOutput needs and FFT output format of 'Magnitude'. Your FFT filter has '{filterSettings.OutputFormat}'."); } this.fftSize = filterSettings.FFTSampleCount; zSize = fftSize / 2; channelCount = mci.ChannelCount; header = $"<VTKFile type=\"StructuredGrid\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">{Environment.NewLine}<StructuredGrid WholeExtent=\"0 {channelCount-1} 0 0 0 {zSize-1}\">{Environment.NewLine}<Piece Extent=\"0 {channelCount - 1} 0 0 0 {zSize - 1}\">{Environment.NewLine}"; footer = $"</Piece>{Environment.NewLine}</StructuredGrid>{Environment.NewLine}</VTKFile>{Environment.NewLine}"; cellData = $"<CellData>{Environment.NewLine}</CellData>{Environment.NewLine}"; sb = new StringBuilder(); lock (sb) { sb.AppendLine("<Points>"); sb.AppendLine("<DataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\" format=\"ascii\">"); for (int z = 0; z < zSize; z++) { for (int chIndex = 0; chIndex < channelCount; chIndex++) { PhysicalPosition pp = ChannelMapper.GetChannelPosition(mci.GetChannel(chIndex)); sb.AppendLine(pp.X.ToString("0.0000000000") + " " + pp.Y.ToString("0.0000000000") + " " + (pp.Z + (z * filter.FrequencyStep)).ToString("0.0000000000")); } } sb.AppendLine("</DataArray>"); sb.AppendLine("</Points>"); points = sb.ToString(); } }
public static MultiChannelInput <IDataChannel> ApplyFilters(MultiChannelInput <IDataChannel> mci, params IChannelFilter[] filters) { MultiChannelInput <IDataChannel> result = new MultiChannelInput <IDataChannel>(mci.SamplesPerSecond, mci.ChannelCount); for (int i = 0; i < mci.ChannelCount; i++) { IDataChannel dataChannel = mci.GetChannel(i); foreach (IChannelFilter filter in filters) { dataChannel = filter.Copy().Apply(dataChannel); } result.SetChannel(i, dataChannel); } return(result); }
public static PhysicalBoundaries GetChannelInputBoundaries(MultiChannelInput <IDataChannel> mci) { PhysicalBoundaries result = new PhysicalBoundaries() { MinX = Int32.MaxValue, MinY = Int32.MaxValue, MinZ = Int32.MaxValue, MaxX = Int32.MinValue, MaxY = Int32.MinValue, MaxZ = Int32.MinValue }; for (int i = 0; i < mci.ChannelCount; i++) { IDataChannel ch = mci.GetChannel(i); PhysicalPosition pp = ChannelMapper.GetChannelPosition(ch); if (pp.X < result.MinX) { result.MinX = pp.X; } if (pp.X > result.MaxX) { result.MaxX = pp.X; } if (pp.Y < result.MinY) { result.MinY = pp.Y; } if (pp.Y > result.MaxY) { result.MaxY = pp.Y; } if (pp.Z < result.MinZ) { result.MinZ = pp.Z; } if (pp.Z > result.MaxZ) { result.MaxZ = pp.Z; } } return(result); }
public static IDataChannel[,] Get2DChannelMatrix(MultiChannelInput <IDataChannel> mci) { IDataChannel[,] result; HashSet <float> xCoordinates = new HashSet <float>(); HashSet <float> yCoordinates = new HashSet <float>(); for (int i = 0; i < mci.ChannelCount; i++) { IDataChannel ch = mci.GetChannel(i); PhysicalPosition pp = ChannelMapper.GetChannelPosition(ch); xCoordinates.Add(pp.X); yCoordinates.Add(pp.Y); } result = new IDataChannel[xCoordinates.Count, yCoordinates.Count]; float[] xCoors = xCoordinates.ToArray(); float[] yCoors = yCoordinates.ToArray(); for (int i = 0; i < mci.ChannelCount; i++) { IDataChannel ch = mci.GetChannel(i); PhysicalPosition pp = ChannelMapper.GetChannelPosition(ch); int x = Array.IndexOf(xCoors, pp.X); int y = Array.IndexOf(yCoors, pp.Y); if (result[x, y] != null) { throw new ArgumentException("Two channels would have the same x and y coordinates, so the 2D channel matrix can't be generated!"); } result[x, y] = ch; } return(result); }
public static void StartSession(DataDisplayModes mode) { consoleSB = new StringBuilder(); //Console.SetOut(File.AppendText($"{workingDirectory}{SessionId}.log")); Console.WriteLine($"Session '{SessionId}' starts at {DateTime.Now.ToString("yyyy-MM-dd HH\\:mm\\:sszzz")} ({DateTime.UtcNow.ToString("yyyy-MM-dd HH\\:mm\\:ss")} UTC)"); try { Console.Write($"Checking if Mercury-16 is connected as PHDC USB device... "); BBDMercury16Input bbdMercury16Input = new BBDMercury16Input(); waveSourceDevice = bbdMercury16Input; waveSource = bbdMercury16Input; Console.WriteLine("OK"); } catch (System.IO.IOException) { Console.WriteLine("not connected"); } if (waveSource == null) { try { Console.Write($"Checking if Arduino is connected on port '{arduinoPort}', expecting The 8x8 Matrix as data-source... "); waveSource = new BBD8x8MatrixInput(arduinoPort, 64); Console.WriteLine("OK"); } catch (System.IO.IOException) { Console.WriteLine("not connected"); } } if (waveSource == null) { Console.Write($"No hardware source was detected, so creating an 8kHz 16ch sine signal generator as data-source... "); waveSource = new SineInput(8000, 16); Console.WriteLine("OK"); } int fftSize = 1024 * 16; frequencyStep = (float)waveSource.SamplesPerSecond / fftSize; MultiChannelInput <IDataChannel> normalizedSource = FilterManager.ApplyFilters(waveSource, new NormalizeFilter() { Settings = new NormalizeFilterSettings() { Enabled = true, SampleCount = waveSource.SamplesPerSecond * 3, Gain = 10.0f } }); //MultiChannelInput<IDataChannel> filteredSource = FilterManager.ApplyFilters(waveSource, new ByPassFilter() { Settings = new ByPassFilterSettings() { Enabled = true } }); //MultiChannelInput<IDataChannel> filteredSource = FilterManager.ApplyFilters(waveSource, new FillFilter() { Settings = new FillFilterSettings() { Enabled = true, ValueToFillWith = 0.75f } }); //MultiChannelInput<IDataChannel> averagedSource = FilterManager.ApplyFilters(normalizedSource, new MovingAverageFilter() { Settings = new MovingAverageFilterSettings() { Enabled = true, InputDataDimensions = 2, MovingAverageLength = 10 } }); wfo = new WaveFileOutput(normalizedSource, $"{workingDirectory}{SessionId}.wav"); wfo.DataWritten += Wfo_DataWritten; //vtkfo = new VTKFileOutput(filteredSource, $"{workingDirectory}{SessionId}.vts"); //vtkfo.DataWritten += Wfo_DataWritten; //vtsfo = new SimpleVTSFileOutput(filteredSource, $"{workingDirectory}{SessionId}.vts", true); //vtsfo.DataWritten += Vtsfo_DataWritten; MultiChannelInput <IDataChannel> filteredSource = null; switch (mode) { case DataDisplayModes.NormalizedWaveform: peakToPeakValues = null; vo = new VisualOutput(normalizedSource, 25, VisualOutputMode.Waveform); break; case DataDisplayModes.FilteredSpectogram: filteredSource = FilterManager.ApplyFilters(normalizedSource, new FFTWFilter() { Settings = new FFTWFilterSettings() { Enabled = true, FFTSampleCount = fftSize, IsBackward = false, PlanningRigor = FFTPlanningRigor.Estimate, IsRealTime = true, Timeout = 300, OutputFormat = FFTOutputFormat.Magnitude, BufferSize = fftSize * 16 } }); vo = new VisualOutput(filteredSource, 25, VisualOutputMode.Spectrum); break; case DataDisplayModes.DominanceMatrix: filteredSource = FilterManager.ApplyFilters(normalizedSource, new FFTWFilter() { Settings = new FFTWFilterSettings() { Enabled = true, FFTSampleCount = fftSize, IsBackward = false, PlanningRigor = FFTPlanningRigor.Estimate, IsRealTime = true, Timeout = 300, OutputFormat = FFTOutputFormat.FrequencyMagnitudePair } }); MultiChannelInput <IDataChannel> thresholdedSource = FilterManager.ApplyFilters(filteredSource, new ThresholdFilter() { Settings = new ThresholdFilterSettings() { Enabled = true, MinValue = 0.002f, MaxValue = Single.MaxValue } }); vo = new VisualOutput(thresholdedSource, 25, VisualOutputMode.DominanceMatrix); break; case DataDisplayModes.GoertzelValues: vo = new VisualOutput(waveSource, 25, VisualOutputMode.GoertzelTable); break; } if (vo != null) { vo.RefreshVisualOutput += Vo_RefreshVisualOutput; } firstActivity = DateTime.UtcNow; Console.OutputEncoding = System.Text.Encoding.Unicode; Console.SetBufferSize(200, 500); Console.SetWindowSize(200, 63); consoleRefreshAtY = Console.CursorTop; }
public VisualOutput(MultiChannelInput <IDataChannel> mci, int maxFramesPerSecond, VisualOutputMode mode) { this.mode = mode; if (mode == VisualOutputMode.Matrix) { channels = ChannelMapper.Get2DChannelMatrix(mci); dimensions = new int[3] { channels.GetLength(0), channels.GetLength(1), 1 }; values = new float[channels.GetLength(0), channels.GetLength(1), 1]; } else if (mode == VisualOutputMode.Waveform) { channels = new IDataChannel[mci.ChannelCount, 1]; for (int i = 0; i < mci.ChannelCount; i++) { channels[i, 0] = mci.GetChannel(i); } dimensions = new int[3] { mci.ChannelCount, mci.SamplesPerSecond, 1 }; values = new float[mci.ChannelCount, mci.SamplesPerSecond, 1]; } else if (mode == VisualOutputMode.Spectrum) { channels = new IDataChannel[mci.ChannelCount, 1]; int?blockSize = null; for (int i = 0; i < mci.ChannelCount; i++) { channels[i, 0] = mci.GetChannel(i); var filter = FilterManager.FindFilter <FFTWFilter>(channels[i, 0]); if (filter == null) { throw new Exception("VisualOutput's Spectrum mode supports FFTWFilter only."); } var filterSettings = filter.GetSettings(); if (filterSettings.OutputFormat != FFTOutputFormat.Magnitude) { throw new InvalidDataException($"VisualOutput's Spectrum mode needs and FFT output format of 'Magnitude'. Your FFT filter has '{filterSettings.OutputFormat}'."); } if (!blockSize.HasValue) { blockSize = filter.OutputBlockSize; } if (blockSize != filter.OutputBlockSize) { throw new Exception("All of the OutputBlockSizes of the filters of the multichannel input must be the same."); } } dimensions = new int[3] { mci.ChannelCount, blockSize.Value, 1 }; values = new float[mci.ChannelCount, blockSize.Value, 1]; } else if (mode == VisualOutputMode.DominanceMatrix) { channels = ChannelMapper.Get2DChannelMatrix(mci); var filter = FilterManager.FindFilter <FFTWFilter>(channels[0, 0]); if (filter == null) { throw new Exception("VisualOutput's DominanceMatrix mode supports FFTWFilter only."); } var filterSettings = filter.GetSettings(); if (filterSettings.OutputFormat != FFTOutputFormat.FrequencyMagnitudePair) { throw new InvalidDataException($"VisualOutput's DominanceMatrix mode needs and FFT output format of 'FrequencyMagnitudePair'. Your FFT filter has '{filterSettings.OutputFormat}'."); } dimensions = new int[3] { channels.GetLength(0), channels.GetLength(1), 5 * 2 }; // will containg the top 5 frequencies and their strength values = new float[channels.GetLength(0), channels.GetLength(1), 5 * 2]; } mci.DataChanged += DataChanged; refreshVisualOutputTimer = new Timer(UpdateVisualOutput, this, 0, 1000 / maxFramesPerSecond); }
public BinaryFileOutput(MultiChannelInput <IDataChannel> mci, string path) : base(mci, path) { }
public WaveFileOutput(MultiChannelInput <IDataChannel> mci, string path) : base(mci, path) { this.waveFileStream = new FileStream(Path.Combine(directory, filename + ".wav"), FileMode.Append, FileAccess.Write, FileShare.ReadWrite); this.waveWriter = new BinaryWriter(waveFileStream); WriteHeader(mci.SamplesPerSecond, 16, mci.ChannelCount); }
public WebSocketOutput(MultiChannelInput <IDataChannel> mci, string url) { //ClientWebSocket cws = new ClientWebSocket(); RunEchoServer().Start(); }