Exemple #1
0
 /// <summary>
 /// Generic raw data server for multichannel data streams. The main data buffer that this class updates i
 /// 'dataBuffer', itself a RawMultiChannelBuffer object. The class has one method that the user should worry about
 /// called, ReadFromDataBuffer. This method accepts a time range (in seconds referenced to the start of the recording)
 /// as input and will copy the portion of the current data buffer that is within that range to the user as a
 /// RawMultiChannelBuffer object. If there is no data in the time range provided, the method returns a null object.
 /// </summary>
 /// <param name="numChannels"> Number of channels in the raw data stream</param>
 /// <param name="bufferSizeSec"> The history of the channels that should be kept, in seconds</param>
 /// <param name="sampleFrequencyHz"> The sampling frequency of an individual channel in the stream</param>
 /// <param name="numSamplesPerWrite"> The number of samples to be written each time the DAQ is polled and the dataBuffer is updated.</param>
 /// <param name="numDataCollectionTasks"> The number of external processes that can asynchronously add data to the buffer</param>
 public RawDataSrv(double sampleFrequencyHz, int numChannels, double bufferSizeSec, int numSamplesPerWrite, int numDataCollectionTasks)
 {
     this.sampleFrequencyHz  = sampleFrequencyHz;
     this.dataBuffer         = new RawMultiChannelBuffer(sampleFrequencyHz, numChannels / numDataCollectionTasks, (int)Math.Ceiling(bufferSizeSec * sampleFrequencyHz), numDataCollectionTasks);
     this.numSamplesPerWrite = numSamplesPerWrite;
     this.numTasks           = numDataCollectionTasks;
     this.channelCount       = numChannels;
 }
Exemple #2
0
        /// <summary>
        /// Read data from buffer. This method will attempt to retrieve samples within the range
        /// specified by the input arguements. The object that is returned
        /// will contain information on the true sample bounds. You can use the EstimateAvailableTimeRange
        /// method to get a (time-sensitive) estimate for good-arguments for this method.
        /// </summary>
        /// <param name="desiredStartIndex">Earliest sample (inclusive), referenced to 0, that should be returned</param>
        /// <param name="desiredStopIndex">Latest sample (inclusive), referenced to 0, that should be returned</param>
        /// <returns>RawMultiChannelBuffer</returns>
        public RawMultiChannelBuffer ReadFromBuffer(ulong desiredStartIndex, ulong desiredStopIndex)
        {
            // Enforce a read lock
            //bufferLock.EnterReadLock();
            //try
            //{
            lock (lockObj)
            {
                // Make sure the desiredSampleRange is correctly formatted
                if (desiredStartIndex > desiredStopIndex)
                {
                    throw new FormatException("The first element of desiredSampleRange must be smaller or equal to the last element.");
                }

                // Make space for the returnBuffer
                int startIndex; // Where to start taking samples
                int stopIndex;  // where to stop taking samples
                RawMultiChannelBuffer returnBuffer = null;

                // First make sure that there are samples available within the desired range
                if (dataBuffer.StartAndEndSample[0] <= desiredStartIndex ||
                    dataBuffer.StartAndEndSample[1] >= desiredStopIndex)
                {
                    // Figure out what part of the buffer we want in reference to the leastCurrentSample
                    // Lower bound
                    ulong absStart;
                    ulong absStop;
                    if (desiredStartIndex <= dataBuffer.StartAndEndSample[0])
                    {
                        startIndex = dataBuffer.netLeastAndMostCurrentCircular[0];
                        absStart   = dataBuffer.StartAndEndSample[0];
                    }
                    else
                    {
                        startIndex = dataBuffer.FindSampleIndex(desiredStartIndex);
                        absStart   = desiredStartIndex;
                    }

                    // Upper bound
                    if (desiredStopIndex >= dataBuffer.StartAndEndSample[1])
                    {
                        stopIndex = dataBuffer.netLeastAndMostCurrentCircular[1];
                        absStop   = dataBuffer.StartAndEndSample[1];
                    }
                    else
                    {
                        stopIndex = dataBuffer.FindSampleIndex(desiredStopIndex);
                        absStop   = desiredStopIndex;
                    }

                    // Instantiate the returnBuffer
                    returnBuffer = new RawMultiChannelBuffer(dataBuffer.SampleFrequencyHz, dataBuffer.NumChannels, (int)(absStop - absStart + 1), numTasks);
                    returnBuffer.StartAndEndSample = new ulong[] { absStart, absStop };

                    for (ulong j = absStart; j < absStop + 1; ++j)
                    {
                        int circSample = dataBuffer.FindSampleIndex(j);
                        for (int i = 0; i < dataBuffer.NumChannels; ++i)
                        {
                            returnBuffer.Buffer[i][j - absStart] = dataBuffer.Buffer[i][circSample];
                        }
                    }
                }
                // Return the data
                return(returnBuffer);
            }
        }