Beispiel #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.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;
        }
Beispiel #2
0
        // Generates new measurements since the last time this was called.
        private void ProcessMeasurements()
        {
            // Declare the variables use in this method.
            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("Start time reset.");
                    }

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

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

                            m_data = WaveDataReader.FromFile(WavFileName);
                            m_dataIndex = 0;

                            m_startTime = timestamp;
                            sample = m_data.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(ex);
                }
            }
        }
Beispiel #3
0
 /// <summary>
 /// Attempts to close the file and release resources held by the adapter.
 /// </summary>
 protected override void AttemptDisconnection()
 {
     if (m_data != null)
     {
         m_data.Close();
         m_data.Dispose();
     }
     m_data = null;
 }
Beispiel #4
0
 /// <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 (m_data != null)
                 {
                     m_data.Close();
                     m_data.Dispose();
                 }
                 m_data = null;
             }
         }
         finally
         {
             m_disposed = true;          // Prevent duplicate dispose.
             base.Dispose(disposing);    // Call base class Dispose().
         }
     }
 }
Beispiel #5
0
        /// <summary>
        /// Attempts to open the file to start getting wave data.
        /// </summary>
        protected override void AttemptConnection()
        {
            WaveFile fileInfo = WaveFile.Load(WavFileName, false);

            m_channels = fileInfo.Channels;
            m_sampleRate = fileInfo.SampleRate;
            m_numSamples = fileInfo.DataChunk.ChunkSize / fileInfo.BlockAlignment;
            m_audioLength = fileInfo.AudioLength;

            m_data = WaveDataReader.FromFile(WavFileName);
            m_dataIndex = 0;

            //if (file.Channels != OutputMeasurements.Length)
            //    throw new ArgumentException(string.Format("The number of channels in the WAV file must match the number of output measurements. Channels: {0}, Measurements: {1}", file.Channels, OutputMeasurements.Length));

            m_startTime = DateTime.UtcNow.Ticks;
            (new Thread(ProcessMeasurements)).Start();
        }