public void configureOutputLogging(string prefix, SamplePackageFormat output) { // retrieve and prepare the logging of streams mLogDataStreams = parameters.getValue <bool>("LogDataStreams"); mLogDataStreamsRuntime = mLogDataStreams; if (mLogDataStreams) { // register the streams for (int channel = 0; channel < outputFormat.numChannels; channel++) { Data.registerDataStream((prefix + "Output_Ch" + (channel + 1)), output.numSamples); } } // retrieve and prepare the visualization of streams mEnableDataVisualization = Globals.getValue <bool>("EnableDataVisualization"); if (mEnableDataVisualization) { // register the streams to visualize for (int channel = 0; channel < outputFormat.numChannels; channel++) { Data.registerVisualizationStream((prefix + "Output_Ch" + (channel + 1)), output); // debug //logger.Warn((prefix + "Output_Ch" + (channel + 1))); } } }
/** * Configure the filter. Checks the values and application logic of the * parameters and, if valid, transfers the configuration parameters to local variables * (initialization of the filter is done later by the initialize function) **/ public bool configure(ref SamplePackageFormat input, out SamplePackageFormat output) { // check sample-major ordered input if (input.valueOrder != SamplePackageFormat.ValueOrder.SampleMajor) { logger.Error("This filter is designed to work only with sample-major ordered input"); output = null; return(false); } // retrieve the number of input channels if (input.numChannels <= 0) { logger.Error("Number of input channels cannot be 0"); output = null; return(false); } // the output package will be in the same format as the input package output = new SamplePackageFormat(input.numChannels, input.numSamples, input.packageRate, input.valueOrder); // store a references to the input and output format inputFormat = input; outputFormat = output; // check the values and application logic of the parameters if (!checkParameters(parameters)) { return(false); } // transfer the parameters to local variables transferParameters(parameters); // configure output logging for this filter configureOutputLogging(filterName + "_", output); // print configuration printLocalConfiguration(); // return success return(true); }
public bool configure(ref SamplePackageFormat input) { // check sample-major ordered input if (input.valueOrder != SamplePackageFormat.ValueOrder.SampleMajor) { logger.Error("This application is designed to work only with sample-major ordered input"); return(false); } // check if the number of input channels is higher than 0 if (input.numChannels <= 0) { logger.Error("Number of input channels cannot be 0"); return(false); } // store a reference to the input format inputFormat = input; // PARAMETER TRANSFER // transfer window settings windowLeft = parameters.getValue <int>("WindowLeft"); windowTop = parameters.getValue <int>("WindowTop"); windowWidth = parameters.getValue <int>("WindowWidth"); windowHeight = parameters.getValue <int>("WindowHeight"); windowRedrawFreqMax = parameters.getValue <int>("WindowRedrawFreqMax"); windowBackgroundColor = parameters.getValue <RGBColorFloat>("WindowBackgroundColor"); // transfer task specific values stimuli = parameters.getValue <string[][]>("Stimuli"); stimuliSequence = parameters.getValue <int[]>("StimuliSequence"); numberOfRepetitions = parameters.getValue <int>("NumberOfRepetitions"); firstSequenceWait = parameters.getValueInSamples("FirstSequenceWait"); betweenSequenceWait = parameters.getValueInSamples("BetweenSequenceWait"); startText = parameters.getValue <string>("StartText"); waitText = parameters.getValue <string>("WaitText"); endText = parameters.getValue <string>("EndText"); // PARAMETER CHECK // TODO: parameters.checkminimum, checkmaximum // check if stimuli are defined if (stimuli.Length != 4) { logger.Error("Stimuli not defined (correctly)."); return(false); } else { // if stimuli are defined, check if duration is defined for each stimulus for (int i = 0; i < stimuli[3].Length; i++) { if (string.IsNullOrEmpty(stimuli[3][i]) || stimuli[3][i] == " ") { logger.Error("Timing of stimulus " + (i + 1).ToString() + " is not defined."); return(false); } else { // if timing is defined, see if it is parsable to integer int timing = 0; if (!int.TryParse(stimuli[3][i], out timing)) { logger.Error("The timing given for stimulus " + (i + 1).ToString() + " (\"" + stimuli[3][i] + "\") is not a valid value, should be a positive integer."); return(false); } // if timing is parsable, check if larger than 0 else if (timing <= 0) { logger.Error("The timing given for stimulus " + (i + 1).ToString() + " (" + stimuli[3][i] + ") is too short. The value should be a positive integer."); return(false); } } } } // check if stimulus sequence is defined if (stimuliSequence.Length <= 0) { logger.Error("No stimuli sequence given."); return(false); } // determine maximal stimulus defined in stimulus sequence int stimMax = 0; for (int i = 0; i < stimuliSequence.Length; i++) { if (stimuliSequence[i] > stimMax) { stimMax = stimuliSequence[i]; } } // check if there are stimuli defined that are not included in stimuli definition if (stimMax > stimuli[0].Length) { logger.Error("In stimuli sequence, stimulus " + stimMax + " is defined. This stimulus can not be found in stimuli definition, as there are only " + stimuli[0].Length + " stimuli defined."); return(false); } // check if amount of repetitions is higher than 0 if (numberOfRepetitions <= 0) { logger.Error("Amount of repetitions should be a positive integer."); return(false); } // check if first sequence wait is not smaller than 0 if (firstSequenceWait < 0) { logger.Error("The time to wait before the start of the first sequence can not be lower than 0."); return(false); } // check if sequence wait is not smaller than 0 if (betweenSequenceWait < 0) { logger.Error("The time to wait before the start of the subsequent sequence can not be lower than 0."); return(false); } // view checks if (windowRedrawFreqMax < 0) { logger.Error("The maximum window redraw frequency can be no smaller then 0"); return(false); } if (windowWidth < 1) { logger.Error("The window width can be no smaller then 1"); return(false); } if (windowHeight < 1) { logger.Error("The window height can be no smaller then 1"); return(false); } return(true); }
public bool configure(out SamplePackageFormat output) { // retrieve the number of output channels outputChannels = parameters.getValue <int>("Channels"); if (outputChannels <= 0) { logger.Error("Number of output channels cannot be 0"); output = null; return(false); } // retrieve the sample-package rate samplePackageRate = parameters.getValue <double>("PackageRate"); if (samplePackageRate <= 0) { logger.Error("The sample-package rate cannot be 0 or lower"); output = null; return(false); } // retrieve the high precision setting highPrecision = parameters.getValue <bool>("HighPrecision"); // retrieve the number of output channels samplesPerPackage = parameters.getValue <int>("SamplesPerPackage"); if (samplesPerPackage <= 0) { logger.Error("Number of samples per package cannot be 0"); output = null; return(false); } if (samplesPerPackage > 65535) { logger.Error("Number of samples per package cannot be higher than 65535"); output = null; return(false); } // retrieve the sample value order //sampleValueOrder = (parameters.getValue<int>("ValueOrder") == 0 ? ValueOrder.ChannelMajor : ValueOrder.SampleMajor); sampleValueOrder = ValueOrder.SampleMajor; // create a sampleformat output = new SamplePackageFormat(outputChannels, samplesPerPackage, samplePackageRate, sampleValueOrder); // calculate the sample-package interval samplePackageIntervalMs = (int)Math.Floor(1000.0 / samplePackageRate); // check if the sample-package rate is above 1000hz if (samplePackageRate > 1000) { // enable the high precision timing highPrecision = true; // message logger.Warn("Because the sample-package rate is larger than 1000hz, the high precision timer will be used"); } // check if high precision timing is enabled if (highPrecision) { // calculate the sample-package interval for the high precision timing samplePackageIntervalTicks = (long)Math.Round(Stopwatch.Frequency * (1.0 / samplePackageRate)); // message logger.Warn("High precision timer enabled. The majority of the Palmtree OS-process will be claimed by the source-module, this might have consequences for the pipeline performance and/or your system performance"); } // TODO: debug, log as sourceinput //for (int i = 0; i < outputChannels; i++) // Data.registerSourceInputStream(("Ch" + i), samplesPerPackage, samplePackageRate); // flag as configured configured = true; // return success return(true); }
public bool configure(out SamplePackageFormat output) { #pragma warning disable 0162 // for constant checks, conscious ignore // retrieve whether the file should be read into memory readEntireFileInMemory = parameters.getValue <bool>("ReadEntireFileInMemory"); // retrieve the input file and remove the extension inputFile = parameters.getValue <string>("Input"); int extIndex = inputFile.LastIndexOf('.'); if (extIndex != -1) { inputFile = inputFile.Substring(0, extIndex); } // check if the .dat file exists string inputDatFile = inputFile + ".dat"; if (string.IsNullOrEmpty(inputDatFile) || !File.Exists(inputDatFile)) { // message logger.Error("Could not find playback input .dat file '" + inputDatFile + "'"); // return output = null; return(false); } // thread safety lock (lockInputReader) { lock (lockInputBuffer) { // check if there is still an inputreader open, if so close if (inputReader != null) { inputReader.close(); inputReader = null; inputHeader = null; inputBufferRowSize = 0; } // read the data header DataHeader header = DataReader.readHeader(inputDatFile); if (header == null) { // message logger.Error("Could not read header data from input .dat file '" + inputDatFile + "'"); // return output = null; return(false); } // check version if (header.version != 1) { // message logger.Error("Currently only .dat files stored in the V1 format can be playbacked. Higher versions are not implemented yet."); // return output = null; return(false); } // check if the internal code is 'dat' if (string.Compare(header.code, "dat") != 0) { // message logger.Error("The input .dat file is internally marked as '" + header.code + "', while a data stream ('dat') file is required"); // return output = null; return(false); } // check if the number of playback input streams in the .dat is higher than 0 if (header.numPlaybackStreams <= 0) { // message logger.Error("The input .dat file has no playback input streams, these are required for playback, make sure the LogPipelineInputStream setting (data tab) is switched on while recording data for replay"); // return output = null; return(false); } // retrieve the redistribution of channels redistributeChannels = parameters.getValue <int[]>("RedistributeChannels"); redistributeEnabled = redistributeChannels.Length > 0; for (int i = 0; i < redistributeChannels.Length; i++) { if (redistributeChannels[i] < 1 || redistributeChannels[i] % 1 != 0) { logger.Error("The values in the RedistributeChannels parameter should be positive integers (note that the channel numbering is 1-based)"); output = null; return(false); } if (redistributeChannels[i] > header.numPlaybackStreams) { logger.Error("One of the values in the RedistributeChannels parameter exceeds the number of playback (input) streams in the data file (#playbackStreams: " + header.numPlaybackStreams + ")"); output = null; return(false); } // lower each channel value (1-based), so it can be used immediately to point to the right value in the input stream array (0-based) redistributeChannels[i]--; } // check if the channels are redistributed if (redistributeEnabled) { // set the number of output channels to the number of redistributed channels outputChannels = redistributeChannels.Length; } else { // set the number of output channels for this source based on the playback streams in the .dat file outputChannels = header.numPlaybackStreams; } // set the sample rate for this source based on the .dat file sampleRate = header.sampleRate; // check the sample rate if (sampleRate <= 0) { logger.Error("The sample rate in the (header of the) .dat file is 0 or lower, invalid sample rate"); output = null; return(false); } // create a sampleformat // (at this point we can only playback .dat files with the pipeline input streams, these always have 1 sample per package. // since the number of samples is 1 per package, the given samplerate is the packagerate) // TODO: support more samples per package output = new SamplePackageFormat(outputChannels, 1, sampleRate, SamplePackageFormat.ValueOrder.SampleMajor); // check the constants (buffer size in combination with buffer min read) if (INPUT_BUFFER_MIN_READ_SECONDS < 2) { logger.Error("The buffer minimum-till-read should not be less than two seconds, provide a larger value for INPUT_BUFFER_MIN_READ_SECONDS"); return(false); } if (INPUT_BUFFER_MIN_READ_SECONDS > INPUT_BUFFER_SIZE_SECONDS) { logger.Error("The buffer minimum-till-read is larger than the buffer, either adjust INPUT_BUFFER_SIZE_SECONDS or INPUT_BUFFER_MIN_READ_SECONDS"); return(false); } // calculate the input buffer size (the size of the inputbuffer is defined as number of seconds of data to hold) inputBufferSize = (long)Math.Floor(INPUT_BUFFER_SIZE_SECONDS * header.sampleRate); if (inputBufferSize == 0) { logger.Error("The buffer size is too small when combined with the sample rate, provide a larger value for INPUT_BUFFER_SIZE_SECONDS"); return(false); } // calculate the minimum amount of rows until additional read inputBufferMinTillRead = (long)Math.Floor(INPUT_BUFFER_MIN_READ_SECONDS * header.sampleRate); if (inputBufferMinTillRead == 0) { logger.Error("The buffer minimum-till-read is too small when combined with the sample rate, provide a larger value for INPUT_BUFFER_MIN_READ_SECONDS"); return(false); } if (inputBufferMinTillRead >= inputBufferSize) { logger.Error("The buffer minimum-till-read should be smaller than the input buffer size, provide a smaller value for INPUT_BUFFER_MIN_READ_SECONDS"); return(false); } // calculate the number of rows to read when the minimum is reached // (note: a smaller read step is also possible; current just refilling the buffer by taking the difference between the minimum-till-read and total buffer size) inputBufferRowsPerRead = inputBufferSize - inputBufferMinTillRead; // the entire file should be read into memory, or if the number of rows in the file are equal to or smaller than the input buffer rows, // then the buffer size will be based on the file row-size if (readEntireFileInMemory || header.numRows <= inputBufferSize) { // input buffer will be the same size as the data in the input file inputBufferSize = header.numRows; // not necessary as the entire file will be read in on initialize inputBufferMinTillRead = 1; inputBufferRowsPerRead = 1; } // check if the number of rows per read is not too big // note: should not happen since it is calculated based on the buffer size and min-till-read, just in case) if (inputBufferRowsPerRead > inputBufferSize - inputBufferMinTillRead) { logger.Error("Number of rows per read (" + inputBufferRowsPerRead + ") should be smaller than the space in the buffer that is open when the buffer min-till-read is reached ('" + (inputBufferSize - inputBufferMinTillRead) + ")"); return(false); } // write some playback information logger.Info("Playback data file: " + inputDatFile); logger.Info("Data file version: " + header.version); logger.Info("Pipeline sample rate: " + sampleRate); logger.Info("Number of input streams in file: " + header.numPlaybackStreams); logger.Info("Number of output channels: " + outputChannels); logger.Info("Number of rows: " + header.numRows); } // end lock } // end lock // retrieve the timing by file setting timingByFile = parameters.getValue <bool>("TimingByFile"); // retrieve the high precision setting highPrecision = parameters.getValue <bool>("HighPrecision"); // calculate the sample interval sampleIntervalMs = (int)Math.Floor(1000.0 / sampleRate); // check if the samplerate is above 1000hz if (sampleRate > 1000) { // enable the high precision timing highPrecision = true; // message logger.Warn("Because the sample rate is larger than 1000hz, the high precision timer is used"); } // check if high precision timing is enabled if (highPrecision) { // calculate the sample interval for the high precision timing sampleIntervalTicks = (long)Math.Round(Stopwatch.Frequency * (1.0 / sampleRate)); // message logger.Warn("High precision timer enabled, as one core will be claimed entirely this might have consequences for your system performance"); } // flag as configured configured = true; // return success return(true); }
public bool configure(ref SamplePackageFormat input) { return(true); }
public bool configure(out SamplePackageFormat output) { // retrieve the number of output channels outputChannels = parameters.getValue <int>("Channels"); if (outputChannels <= 0) { logger.Error("Number of output channels cannot be 0"); output = null; return(false); } // retrieve the sample-package rate samplePackageRate = parameters.getValue <double>("SamplePackageRate"); if (samplePackageRate <= 0) { logger.Error("The sample-package rate cannot be 0 or lower"); output = null; return(false); } // retrieve the high precision setting highPrecision = parameters.getValue <bool>("HighPrecision"); // retrieve the number of output channels samplesPerPackage = parameters.getValue <int>("SamplesPerPackage"); if (samplesPerPackage <= 0) { logger.Error("Number of samples per package cannot be 0"); output = null; return(false); } if (samplesPerPackage > 65535) { logger.Error("Number of samples per package cannot be higher than 65535"); output = null; return(false); } // retrieve the sample value order //sampleValueOrder = (parameters.getValue<int>("ValueOrder") == 0 ? ValueOrder.ChannelMajor : ValueOrder.SampleMajor); sampleValueOrder = ValueOrder.SampleMajor; // create a sampleformat output = new SamplePackageFormat(outputChannels, samplesPerPackage, samplePackageRate, sampleValueOrder); // calculate the sample-package interval samplePackageIntervalMs = (int)Math.Floor(1000.0 / samplePackageRate); // check if the sample-package rate is above 1000hz if (samplePackageRate > 1000) { // enable the high precision timing highPrecision = true; // message logger.Warn("Because the sample-package rate is larger than 1000hz, the high precision timer will be used"); } // check if high precision timing is enabled if (highPrecision) { // calculate the sample-package interval for the high precision timing samplePackageIntervalTicks = (long)Math.Round(Stopwatch.Frequency * (1.0 / samplePackageRate)); // message logger.Warn("High precision timer enabled. The majority of the Palmtree OS-process will be claimed by the source-module, this might have consequences for the pipeline performance and/or your system performance"); } // retrieve key settings string[][] keys = parameters.getValue <string[][]>("Keys"); if (keys == null || keys.Length == 0) { // no keys specified mConfigKeys = new Keys[0]; mConfigOutputChannels = new int[0]; mConfigPressed = new double[0]; mConfigNotPressed = new double[0]; } else { // keys present if (keys.Length != 4) { logger.Error("Keys parameter must have 4 columns (Key, Output channel, Pressed, Not-pressed)"); return(false); } // resize the variables mConfigKeys = new Keys[keys[0].Length]; // char converted to virtual key mConfigOutputChannels = new int[keys[0].Length]; // for the values stored in this array: value 0 = channel 1 mConfigPressed = new double[keys[0].Length]; mConfigNotPressed = new double[keys[0].Length]; // loop through the rows for (int row = 0; row < keys[0].Length; ++row) { // try to convert the key character to an int string key = keys[0][row].ToUpper(); if (key.Length != 1 || !(new Regex(@"^[A-Z0-9]*$")).IsMatch(key)) { logger.Error("The key value '" + key + "' is not a valid key (should be a single character, a-z or 0-9)"); return(false); } mConfigKeys[row] = (Keys)key[0]; // capital characters A-Z and numbers can be directly saved as int (directly used/emulated as virtual keys) // try to parse the channel number int channel = 0; if (!int.TryParse(keys[1][row], out channel)) { logger.Error("The value '" + keys[1][row] + "' is not a valid output channel value (should be a positive integer)"); return(false); } if (channel < 1) { logger.Error("Output channels must be positive integers"); return(false); } if (channel > outputChannels) { logger.Error("The output channel value '" + keys[1][row] + "' exceeds the number of channels coming out of the filter (#outputChannels: " + outputChannels + ")"); return(false); } mConfigOutputChannels[row] = channel - 1; // -1 since the user input the channel 1-based and we use a 0-based array // try to parse the pressed value double doubleValue = 0; if (!double.TryParse(keys[2][row], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, Parameters.NumberCulture, out doubleValue)) { logger.Error("The value '" + keys[2][row] + "' is not a valid double value"); return(false); } mConfigPressed[row] = doubleValue; // try to parse the not-pressed value doubleValue = 0; if (!double.TryParse(keys[3][row], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, Parameters.NumberCulture, out doubleValue)) { logger.Error("The value '" + keys[3][row] + "' is not a valid double value"); return(false); } mConfigNotPressed[row] = doubleValue; } } // flag as configured configured = true; // return success return(true); }
/** * Configure the filter. Checks the values and application logic of the * parameters and, if valid, transfers the configuration parameters to local variables * (initialization of the filter is done later by the initialize function) **/ public bool configure(ref SamplePackageFormat input, out SamplePackageFormat output) { // check sample-major ordered input if (input.valueOrder != SamplePackageFormat.ValueOrder.SampleMajor) { logger.Error("This filter is designed to work only with sample-major ordered input"); output = null; return(false); } // retrieve and check the number of input channels if (input.numChannels <= 0) { logger.Error("Number of input channels cannot be 0"); output = null; return(false); } // store a references to the input format (here so checkParameters can use it) inputFormat = input; // check the values and application logic of the parameters if (!checkParameters(parameters)) { output = null; return(false); } // transfer the parameters to local variables transferParameters(parameters); // determine the number of output channels int outputChannels; if (mEnableFilter) { // determine the highest output channel from the configuration and set this as the number of output channels int highestOutputChannel = 0; for (int row = 0; row < mConfigOutputChannels.Length; ++row) { if (mConfigOutputChannels[row] > highestOutputChannel) { highestOutputChannel = mConfigOutputChannels[row]; } } outputChannels = highestOutputChannel; } else { // filter will pass the input straight through, so same number of channels as output outputChannels = inputFormat.numChannels; } // create an output sampleformat and store a references to the output format output = new SamplePackageFormat(outputChannels, input.numSamples, input.packageRate, input.valueOrder); outputFormat = output; // configure output logging for this filter configureOutputLogging(filterName + "_", output); // print configuration printLocalConfiguration(); // return success return(true); }