Example #1
0
        /// <summary>
        /// Creates a <see cref="WaveDataReader"/> instance created from a WAV stream.
        /// </summary>
        /// <param name="waveStream">The WAV stream. The data in the stream must include all headers that would be present in a WAV file.</param>
        /// <returns>The WaveData instance created from a WAV stream.</returns>
        /// <remarks>
        /// This method is similar to the <see cref="WaveDataReader(Stream)"/> constructor,
        /// however this method will first search the stream for a format chunk in order to set
        /// up the WaveData object with proper format info.
        /// </remarks>
        public static WaveDataReader FromStream(Stream waveStream)
        {
            RiffChunk       riffChunk;
            WaveFormatChunk waveFormat = null;
            WaveDataReader  waveData   = null;

            while ((object)waveData == null)
            {
                riffChunk = RiffChunk.ReadNext(waveStream);

                switch (riffChunk.TypeID)
                {
                case RiffHeaderChunk.RiffTypeID:
                    // ReSharper disable once ObjectCreationAsStatement
                    new RiffHeaderChunk(riffChunk, waveStream, "WAVE");
                    break;

                case WaveFormatChunk.RiffTypeID:
                    waveFormat = new WaveFormatChunk(riffChunk, waveStream);
                    break;

                case WaveDataChunk.RiffTypeID:
                    waveData = new WaveDataReader(waveFormat, waveStream);
                    break;

                default:
                    // Skip unnecessary sections
                    waveStream.Seek(riffChunk.ChunkSize, SeekOrigin.Current);
                    break;
                }
            }

            return(waveData);
        }
Example #2
0
        /// <summary>
        /// Creates a <see cref="WaveDataReader"/> instance created from a WAV stream.
        /// </summary>
        /// <param name="waveStream">The WAV stream. The data in the stream must include all headers that would be present in a WAV file.</param>
        /// <returns>The WaveData instance created from a WAV stream.</returns>
        /// <remarks>
        /// This method is similar to the <see cref="WaveDataReader.WaveDataReader(Stream)"/> constructor,
        /// however this method will first search the stream for a format chunk in order to set
        /// up the WaveData object with proper format info.
        /// </remarks>
        public static WaveDataReader FromStream(Stream waveStream)
        {
            RiffChunk riffChunk;
            WaveFormatChunk waveFormat = null;
            WaveDataReader waveData = null;

            while ((object)waveData == null)
            {
                riffChunk = RiffChunk.ReadNext(waveStream);

                switch (riffChunk.TypeID)
                {
                    case RiffHeaderChunk.RiffTypeID:
                        new RiffHeaderChunk(riffChunk, waveStream, "WAVE");
                        break;
                    case WaveFormatChunk.RiffTypeID:
                        waveFormat = new WaveFormatChunk(riffChunk, waveStream);
                        break;
                    case WaveDataChunk.RiffTypeID:
                        waveData = new WaveDataReader(waveFormat, waveStream);
                        break;
                    default:
                        // Skip unnecessary sections
                        waveStream.Seek(riffChunk.ChunkSize, SeekOrigin.Current);
                        break;
                }
            }

            return waveData;
        }
        private void ProcessMeasurements()
        {
            List<IMeasurement> measurements = new List<IMeasurement>((int)(Ticks.ToSeconds(GapThreshold) * m_sampleRate * m_channels * 1.1D));
            LittleBinaryValue[] sample;

            while (Enabled)
            {
                try
                {
                    SpinWait spinner = new SpinWait();

                    // Determine what time it is now
                    long now = DateTime.UtcNow.Ticks;

                    // Assign a timestamp to the next sample based on its location
                    // in the file relative to the other samples in the file
                    long timestamp = m_startTime + (m_dataIndex * Ticks.PerSecond / m_sampleRate);

                    if (now - timestamp > GapThreshold)
                    {
                        // Reset the start time and delay next transmission in an attempt to catch up
                        m_startTime = now - (m_dataIndex * Ticks.PerSecond / m_sampleRate) + Ticks.FromSeconds(RecoveryDelay);
                        timestamp = now;
                        OnStatusMessage(MessageLevel.Info, "Start time reset.");
                    }

                    // Keep generating measurements until
                    // we catch up to the current time.
                    while (timestamp < now)
                    {
                        sample = m_dataReader.GetNextSample();

                        // If the sample is null, we've reached the end of the file - close and reopen,
                        // resetting the data index and start time
                        if (sample == null)
                        {
                            m_dataReader.Close();
                            m_dataReader.Dispose();

                            m_dataReader = OpenWaveDataReader();
                            m_dataIndex = 0;

                            m_startTime = timestamp;
                            sample = m_dataReader.GetNextSample();
                        }

                        // Create new measurements, one for each channel, and add them to the measurements list
                        for (int i = 0; i < m_channels; i++)
                            measurements.Add(Measurement.Clone(OutputMeasurements[i], sample[i].ConvertToType(TypeCode.Double), timestamp));

                        // Update the data index and recalculate the assigned timestamp for the next sample
                        m_dataIndex++;
                        timestamp = m_startTime + (m_dataIndex * Ticks.PerSecond / m_sampleRate);
                    }

                    OnNewMeasurements(measurements);
                    measurements.Clear();

                    while (DateTime.UtcNow.Ticks - timestamp <= GapThreshold / 100)
                    {
                        // Ahead of schedule -- pause for a moment
                        spinner.SpinOnce();
                    }
                }
                catch (Exception ex)
                {
                    OnProcessException(MessageLevel.Warning, ex);
                }
            }
        }
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="WavInputAdapter"/> object and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        if ((object)m_dataReader != null)
                        {
                            m_dataReader.Close();
                            m_dataReader.Dispose();
                            m_dataReader = null;
                        }

                        if ((object)m_dataCache != null)
                            m_dataCache.Dispose();
                    }
                }
                finally
                {
                    m_disposed = true;          // Prevent duplicate dispose.
                    base.Dispose(disposing);    // Call base class Dispose().
                }
            }
        }
 /// <summary>
 /// Attempts to close the file and release resources held by the adapter.
 /// </summary>
 protected override void AttemptDisconnection()
 {
     if ((object)m_dataReader != null)
     {
         m_dataReader.Close();
         m_dataReader.Dispose();
         m_dataReader = null;
     }
 }
        /// <summary>
        /// Attempts to open the file to start getting wave data.
        /// </summary>
        protected override void AttemptConnection()
        {
            m_dataReader = OpenWaveDataReader();
            m_dataIndex = 0;

            m_startTime = DateTime.UtcNow.Ticks;

            new Thread(ProcessMeasurements) { IsBackground = true }.Start();
        }